From 34c614b7e9dcb52a23063680f3622c842a9712ec Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Tue, 4 Jul 2023 21:10:00 +0800 Subject: VECT: Apply LEN_MASK_GATHER_LOAD/SCATTER_STORE into vectorizer Hi, Richard and Richi. Address comments from Richi. Make gs_info.ifn = LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE. I have fully tested these 4 format: length = vf is a dummpy length, mask = {-1,-1, ... } is a dummy mask. 1. no length, no mask LEN_MASK_GATHER_LOAD (..., length = vf, mask = {-1,-1,...}) 2. exist length, no mask LEN_MASK_GATHER_LOAD (..., len, mask = {-1,-1,...}) 3. exist mask, no length LEN_MASK_GATHER_LOAD (..., length = vf, mask) 4. both mask and length exist LEN_MASK_GATHER_LOAD (..., length, mask) All of these work fine in this patch. Here is the example: void f (int *restrict a, int *restrict b, int n, int base, int step, int *restrict cond) { for (int i = 0; i < n; ++i) { if (cond[i]) a[i * 4] = b[i]; } } Gimple IR: [local count: 105119324]: _58 = (unsigned long) n_13(D); [local count: 630715945]: # vectp_cond.7_45 = PHI # vectp_b.11_51 = PHI # vectp_a.14_55 = PHI # ivtmp_59 = PHI _61 = .SELECT_VL (ivtmp_59, POLY_INT_CST [2, 2]); ivtmp_44 = _61 * 4; vect__4.9_47 = .LEN_MASK_LOAD (vectp_cond.7_45, 32B, _61, 0, { -1, ... }); mask__24.10_49 = vect__4.9_47 != { 0, ... }; vect__8.13_53 = .LEN_MASK_LOAD (vectp_b.11_51, 32B, _61, 0, mask__24.10_49); ivtmp_54 = _61 * 16; .LEN_MASK_SCATTER_STORE (vectp_a.14_55, { 0, 16, 32, ... }, 1, vect__8.13_53, _61, 0, mask__24.10_49); vectp_cond.7_46 = vectp_cond.7_45 + ivtmp_44; vectp_b.11_52 = vectp_b.11_51 + ivtmp_44; vectp_a.14_56 = vectp_a.14_55 + ivtmp_54; ivtmp_60 = ivtmp_59 - _61; if (ivtmp_60 != 0) goto ; [83.33%] else goto ; [16.67%] Ok for trunk ? gcc/ChangeLog: * internal-fn.cc (internal_fn_len_index): Apply LEN_MASK_GATHER_LOAD/SCATTER_STORE into vectorizer. (internal_fn_mask_index): Ditto. * optabs-query.cc (supports_vec_gather_load_p): Ditto. (supports_vec_scatter_store_p): Ditto. * tree-vect-data-refs.cc (vect_gather_scatter_fn_p): Ditto. * tree-vect-patterns.cc (vect_recog_gather_scatter_pattern): Ditto. * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Ditto. (vect_get_strided_load_store_ops): Ditto. (vectorizable_store): Ditto. (vectorizable_load): Ditto. --- gcc/internal-fn.cc | 6 +-- gcc/optabs-query.cc | 2 + gcc/tree-vect-data-refs.cc | 18 ++++++- gcc/tree-vect-patterns.cc | 4 +- gcc/tree-vect-stmts.cc | 122 ++++++++++++++++++++++++++++++++++++++------- 5 files changed, 129 insertions(+), 23 deletions(-) (limited to 'gcc') diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 303df10..bec60cd 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -4472,7 +4472,7 @@ internal_fn_len_index (internal_fn fn) case IFN_LEN_MASK_GATHER_LOAD: case IFN_LEN_MASK_SCATTER_STORE: - return 4; + return 5; default: return -1; @@ -4497,11 +4497,9 @@ internal_fn_mask_index (internal_fn fn) case IFN_MASK_SCATTER_STORE: case IFN_LEN_MASK_LOAD: case IFN_LEN_MASK_STORE: - return 4; - case IFN_LEN_MASK_GATHER_LOAD: case IFN_LEN_MASK_SCATTER_STORE: - return 6; + return 4; default: return (conditional_internal_fn_code (fn) != ERROR_MARK diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc index 2fdd0d3..bf1f484 100644 --- a/gcc/optabs-query.cc +++ b/gcc/optabs-query.cc @@ -676,6 +676,7 @@ supports_vec_gather_load_p (machine_mode mode) this_fn_optabs->supports_vec_gather_load[mode] = (supports_vec_convert_optab_p (gather_load_optab, mode) || supports_vec_convert_optab_p (mask_gather_load_optab, mode) + || supports_vec_convert_optab_p (len_mask_gather_load_optab, mode) ? 1 : -1); return this_fn_optabs->supports_vec_gather_load[mode] > 0; @@ -692,6 +693,7 @@ supports_vec_scatter_store_p (machine_mode mode) this_fn_optabs->supports_vec_scatter_store[mode] = (supports_vec_convert_optab_p (scatter_store_optab, mode) || supports_vec_convert_optab_p (mask_scatter_store_optab, mode) + || supports_vec_convert_optab_p (len_mask_scatter_store_optab, mode) ? 1 : -1); return this_fn_optabs->supports_vec_scatter_store[mode] > 0; diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index ebe9383..ab2af10 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -3873,16 +3873,24 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p, bool masked_p, return false; /* Work out which function we need. */ - internal_fn ifn, alt_ifn; + internal_fn ifn, alt_ifn, alt_ifn2; if (read_p) { ifn = masked_p ? IFN_MASK_GATHER_LOAD : IFN_GATHER_LOAD; alt_ifn = IFN_MASK_GATHER_LOAD; + /* When target supports LEN_MASK_GATHER_LOAD, we always + use LEN_MASK_GATHER_LOAD regardless whether len and + mask are valid or not. */ + alt_ifn2 = IFN_LEN_MASK_GATHER_LOAD; } else { ifn = masked_p ? IFN_MASK_SCATTER_STORE : IFN_SCATTER_STORE; alt_ifn = IFN_MASK_SCATTER_STORE; + /* When target supports LEN_MASK_SCATTER_STORE, we always + use LEN_MASK_SCATTER_STORE regardless whether len and + mask are valid or not. */ + alt_ifn2 = IFN_LEN_MASK_SCATTER_STORE; } for (;;) @@ -3909,6 +3917,14 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p, bool masked_p, *offset_vectype_out = offset_vectype; return true; } + else if (internal_gather_scatter_fn_supported_p (alt_ifn2, vectype, + memory_type, + offset_vectype, scale)) + { + *ifn_out = alt_ifn2; + *offset_vectype_out = offset_vectype; + return true; + } if (TYPE_PRECISION (offset_type) >= POINTER_SIZE && TYPE_PRECISION (offset_type) >= element_bits) diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index de20e9d..1bc36b0 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -6075,7 +6075,9 @@ vect_recog_gather_scatter_pattern (vec_info *vinfo, mask = vect_convert_mask_for_vectype (mask, gs_vectype, stmt_info, loop_vinfo); else if (gs_info.ifn == IFN_MASK_SCATTER_STORE - || gs_info.ifn == IFN_MASK_GATHER_LOAD) + || gs_info.ifn == IFN_MASK_GATHER_LOAD + || gs_info.ifn == IFN_LEN_MASK_SCATTER_STORE + || gs_info.ifn == IFN_LEN_MASK_GATHER_LOAD) mask = build_int_cst (TREE_TYPE (truth_type_for (gs_vectype)), -1); /* Get the invariant base and non-invariant offset, converting the diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 161ad80..c10a4be 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1786,6 +1786,18 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype, gs_info->offset_vectype, gs_info->scale)) { + ifn = (is_load + ? IFN_LEN_MASK_GATHER_LOAD + : IFN_LEN_MASK_SCATTER_STORE); + if (internal_gather_scatter_fn_supported_p (ifn, vectype, + gs_info->memory_type, + gs_info->offset_vectype, + gs_info->scale)) + { + vec_loop_lens *lens = &LOOP_VINFO_LENS (loop_vinfo); + vect_record_loop_len (loop_vinfo, lens, nvectors, vectype, 1); + return; + } if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "can't operate on partial vectors because" @@ -3144,16 +3156,39 @@ vect_get_gather_scatter_ops (loop_vec_info loop_vinfo, static void vect_get_strided_load_store_ops (stmt_vec_info stmt_info, loop_vec_info loop_vinfo, + gimple_stmt_iterator *gsi, gather_scatter_info *gs_info, - tree *dataref_bump, tree *vec_offset) + tree *dataref_bump, tree *vec_offset, + vec_loop_lens *loop_lens) { struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); tree vectype = STMT_VINFO_VECTYPE (stmt_info); - tree bump = size_binop (MULT_EXPR, - fold_convert (sizetype, unshare_expr (DR_STEP (dr))), - size_int (TYPE_VECTOR_SUBPARTS (vectype))); - *dataref_bump = cse_and_gimplify_to_preheader (loop_vinfo, bump); + if (LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo)) + { + /* _31 = .SELECT_VL (ivtmp_29, POLY_INT_CST [4, 4]); + ivtmp_8 = _31 * 16 (step in bytes); + .LEN_MASK_SCATTER_STORE (vectp_a.9_7, ... ); + vectp_a.9_26 = vectp_a.9_7 + ivtmp_8; */ + tree loop_len + = vect_get_loop_len (loop_vinfo, gsi, loop_lens, 1, vectype, 0, 0); + tree tmp + = fold_build2 (MULT_EXPR, sizetype, + fold_convert (sizetype, unshare_expr (DR_STEP (dr))), + loop_len); + tree bump = make_temp_ssa_name (sizetype, NULL, "ivtmp"); + gassign *assign = gimple_build_assign (bump, tmp); + gsi_insert_before (gsi, assign, GSI_SAME_STMT); + *dataref_bump = bump; + } + else + { + tree bump + = size_binop (MULT_EXPR, + fold_convert (sizetype, unshare_expr (DR_STEP (dr))), + size_int (TYPE_VECTOR_SUBPARTS (vectype))); + *dataref_bump = cse_and_gimplify_to_preheader (loop_vinfo, bump); + } /* The offset given in GS_INFO can have pointer type, so use the element type of the vector instead. */ @@ -8700,8 +8735,8 @@ vectorizable_store (vec_info *vinfo, else if (memory_access_type == VMAT_GATHER_SCATTER) { aggr_type = elem_type; - vect_get_strided_load_store_ops (stmt_info, loop_vinfo, &gs_info, - &bump, &vec_offset); + vect_get_strided_load_store_ops (stmt_info, loop_vinfo, gsi, &gs_info, + &bump, &vec_offset, loop_lens); } else { @@ -8930,6 +8965,8 @@ vectorizable_store (vec_info *vinfo, unsigned HOST_WIDE_INT align; tree final_mask = NULL_TREE; + tree final_len = NULL_TREE; + tree bias = NULL_TREE; if (loop_masks) final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, vec_num * ncopies, @@ -8944,8 +8981,36 @@ vectorizable_store (vec_info *vinfo, if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) vec_offset = vec_offsets[vec_num * j + i]; tree scale = size_int (gs_info.scale); + + if (gs_info.ifn == IFN_LEN_MASK_SCATTER_STORE) + { + if (loop_lens) + final_len + = vect_get_loop_len (loop_vinfo, gsi, loop_lens, + vec_num * ncopies, vectype, + vec_num * j + i, 1); + else + final_len + = build_int_cst (sizetype, + TYPE_VECTOR_SUBPARTS (vectype)); + signed char biasval + = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); + bias = build_int_cst (intQI_type_node, biasval); + if (!final_mask) + { + mask_vectype = truth_type_for (vectype); + final_mask = build_minus_one_cst (mask_vectype); + } + } + gcall *call; - if (final_mask) + if (final_len && final_mask) + call + = gimple_build_call_internal (IFN_LEN_MASK_SCATTER_STORE, + 7, dataref_ptr, vec_offset, + scale, vec_oprnd, final_mask, + final_len, bias); + else if (final_mask) call = gimple_build_call_internal (IFN_MASK_SCATTER_STORE, 5, dataref_ptr, vec_offset, scale, vec_oprnd, final_mask); @@ -9062,9 +9127,6 @@ vectorizable_store (vec_info *vinfo, machine_mode vmode = TYPE_MODE (vectype); machine_mode new_vmode = vmode; internal_fn partial_ifn = IFN_LAST; - /* Produce 'len' and 'bias' argument. */ - tree final_len = NULL_TREE; - tree bias = NULL_TREE; if (loop_lens) { opt_machine_mode new_ovmode @@ -10192,8 +10254,8 @@ vectorizable_load (vec_info *vinfo, else if (memory_access_type == VMAT_GATHER_SCATTER) { aggr_type = elem_type; - vect_get_strided_load_store_ops (stmt_info, loop_vinfo, &gs_info, - &bump, &vec_offset); + vect_get_strided_load_store_ops (stmt_info, loop_vinfo, gsi, &gs_info, + &bump, &vec_offset, loop_lens); } else { @@ -10354,6 +10416,8 @@ vectorizable_load (vec_info *vinfo, for (i = 0; i < vec_num; i++) { tree final_mask = NULL_TREE; + tree final_len = NULL_TREE; + tree bias = NULL_TREE; if (loop_masks && memory_access_type != VMAT_INVARIANT) final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, @@ -10383,8 +10447,35 @@ vectorizable_load (vec_info *vinfo, vec_offset = vec_offsets[vec_num * j + i]; tree zero = build_zero_cst (vectype); tree scale = size_int (gs_info.scale); + + if (gs_info.ifn == IFN_LEN_MASK_GATHER_LOAD) + { + if (loop_lens) + final_len + = vect_get_loop_len (loop_vinfo, gsi, loop_lens, + vec_num * ncopies, vectype, + vec_num * j + i, 1); + else + final_len = build_int_cst (sizetype, + TYPE_VECTOR_SUBPARTS ( + vectype)); + signed char biasval + = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); + bias = build_int_cst (intQI_type_node, biasval); + if (!final_mask) + { + mask_vectype = truth_type_for (vectype); + final_mask = build_minus_one_cst (mask_vectype); + } + } + gcall *call; - if (final_mask) + if (final_len && final_mask) + call = gimple_build_call_internal ( + IFN_LEN_MASK_GATHER_LOAD, 7, dataref_ptr, + vec_offset, scale, zero, final_mask, final_len, + bias); + else if (final_mask) call = gimple_build_call_internal (IFN_MASK_GATHER_LOAD, 5, dataref_ptr, vec_offset, scale, zero, final_mask); @@ -10477,9 +10568,6 @@ vectorizable_load (vec_info *vinfo, machine_mode vmode = TYPE_MODE (vectype); machine_mode new_vmode = vmode; internal_fn partial_ifn = IFN_LAST; - /* Produce 'len' and 'bias' argument. */ - tree final_len = NULL_TREE; - tree bias = NULL_TREE; if (loop_lens) { opt_machine_mode new_ovmode -- cgit v1.1 From 429905d809bbf2398bf666d65322b87ac7381e43 Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Wed, 5 Jul 2023 14:42:21 +0200 Subject: RISC-V: Change truncate to float_truncate in narrowing patterns. This fixes a bug in the autovect FP narrowing patterns which resulted in a combine ICE. It would try to e.g. simplify a unary operation by simplify_const_unary_operation which obviously expects a float_truncate and not a truncate for a floating-point mode. gcc/ChangeLog: * config/riscv/autovec.md: Use float_truncate. --- gcc/config/riscv/autovec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 4ab0e9f..0fc2bf5 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -473,7 +473,7 @@ ;; ------------------------------------------------------------------------- (define_insn_and_split "trunc2" [(set (match_operand: 0 "register_operand" "=vr") - (truncate: + (float_truncate: (match_operand:VWEXTF_ZVFHMIN 1 "register_operand" " vr")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" @@ -493,7 +493,7 @@ ;; ------------------------------------------------------------------------- (define_expand "trunc2" [(set (match_operand: 0 "register_operand") - (truncate: + (float_truncate: (match_operand:VQEXTF 1 "register_operand")))] "TARGET_VECTOR && (TARGET_ZVFHMIN || TARGET_ZVFH)" { -- cgit v1.1 From 70b041684a2222b8f19200cc240a13d703b210a7 Mon Sep 17 00:00:00 2001 From: Pan Li Date: Tue, 4 Jul 2023 20:26:11 +0800 Subject: RISC-V: Use FRM_DYN when add the rounding mode operand This patch would like to take FRM_DYN const rtx as the rounding mode operand according to the RVV spec, which takes the dyn as the only rounding mode for floating-point. Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/riscv-vector-builtins.cc (function_expander::use_exact_insn): Use FRM_DYN instead of const0. Signed-off-by: Pan Li --- gcc/config/riscv/riscv-vector-builtins.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 648c765..3a53b56 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -3569,11 +3569,10 @@ function_expander::use_exact_insn (insn_code icode) if (base->has_rounding_mode_operand_p ()) add_input_operand (call_expr_nargs (exp) - 2); - /* TODO: Currently, we don't support intrinsic that is modeling rounding mode. - We add default rounding mode for the intrinsics that didn't model rounding - mode yet. */ + /* The RVV floating-point only support dynamic rounding mode in the + FRM register. */ if (opno != insn_data[icode].n_generator_args) - add_input_operand (Pmode, const0_rtx); + add_input_operand (Pmode, gen_int_mode (riscv_vector::FRM_DYN, Pmode)); return generate_insn (icode); } -- cgit v1.1 From df9a6cbb087d674ccee545d642e688f1979dcb3a Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Tue, 27 Jun 2023 16:22:55 +0200 Subject: RISC-V: Allow variable index for vec_set. This patch enables a variable index for vec_set and adjust the tests. gcc/ChangeLog: * config/riscv/autovec.md: Allow register index operand. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c: Adjust test. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-run.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-zvfh-run.c: Ditto. --- gcc/config/riscv/autovec.md | 17 ++- .../riscv/rvv/autovec/vls-vlmax/vec_set-1.c | 32 ++++- .../riscv/rvv/autovec/vls-vlmax/vec_set-2.c | 32 ++++- .../riscv/rvv/autovec/vls-vlmax/vec_set-3.c | 33 ++++- .../riscv/rvv/autovec/vls-vlmax/vec_set-4.c | 33 ++++- .../riscv/rvv/autovec/vls-vlmax/vec_set-run.c | 153 +++++++-------------- .../riscv/rvv/autovec/vls-vlmax/vec_set-zvfh-run.c | 49 ++++--- 7 files changed, 185 insertions(+), 164 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 0fc2bf5..7b457a5 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1022,7 +1022,7 @@ (define_expand "vec_set" [(match_operand:V 0 "register_operand") (match_operand: 1 "register_operand") - (match_operand 2 "immediate_operand")] + (match_operand 2 "nonmemory_operand")] "TARGET_VECTOR" { /* If we set the first element, emit an v(f)mv.s.[xf]. */ @@ -1039,12 +1039,17 @@ it at the proper position using vslideup with an "effective length" of 1 i.e. a VL 1 past the offset. */ - /* Slide offset = element index. */ - int offset = INTVAL (operands[2]); - - /* Only insert one element, i.e. VL = offset + 1. */ + /* Here we set VL = offset + 1. */ rtx length = gen_reg_rtx (Pmode); - emit_move_insn (length, GEN_INT (offset + 1)); + operands[2] = gen_lowpart (Pmode, operands[2]); + if (CONST_INT_P (operands[2])) + emit_move_insn (length, GEN_INT (INTVAL (operands[2]) + 1)); + else + { + rtx add = gen_rtx_PLUS (GET_MODE (operands[2]), + operands[2], GEN_INT (1)); + emit_move_insn (length, add); + } /* Move operands[1] into a vector register via vmv.v.x using the same VL we need for the slide. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c index 3d60e63..e97f6f5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c @@ -20,6 +20,15 @@ typedef double vnx2df __attribute__((vector_size (16))); return v; \ } +#define VEC_SET_VAR1(S,V) \ + V \ + __attribute__((noipa)) \ + vec_set_var_##V (V v, int8_t idx, S s) \ + { \ + v[idx] = s; \ + return v; \ + } \ + #define TEST_ALL1(T) \ T (_Float16, vnx8hf, 0) \ T (_Float16, vnx8hf, 3) \ @@ -43,20 +52,31 @@ typedef double vnx2df __attribute__((vector_size (16))); T (int8_t, vnx16qi, 11) \ T (int8_t, vnx16qi, 15) \ +#define TEST_ALL_VAR1(T) \ + T (_Float16, vnx8hf) \ + T (float, vnx4sf) \ + T (double, vnx2df) \ + T (int64_t, vnx2di) \ + T (int32_t, vnx4si) \ + T (int16_t, vnx8hi) \ + T (int8_t, vnx16qi) \ + TEST_ALL1 (VEC_SET) +TEST_ALL_VAR1 (VEC_SET_VAR1) /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*tu,\s*ma} 5 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*tu,\s*ma} 6 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*tu,\s*ma} 6 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*tu,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*tu,\s*ma} 4 } } */ -/* { dg-final { scan-assembler-times {\tvmv.v.x} 9 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.v.f} 5 } } */ +/* { dg-final { scan-assembler-times {\tvmv.v.x} 13 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.v.f} 8 } } */ /* { dg-final { scan-assembler-times {\tvslideup.vi} 14 } } */ +/* { dg-final { scan-assembler-times {\tvslideup.vx} 7 } } */ /* { dg-final { scan-assembler-times {\tvfmv.s.f} 3 } } */ /* { dg-final { scan-assembler-times {\tvmv.s.x} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c index 6929c17..6d077d6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c @@ -20,6 +20,15 @@ typedef double vnx4df __attribute__((vector_size (32))); return v; \ } +#define VEC_SET_VAR2(S,V) \ + V \ + __attribute__((noipa)) \ + vec_set_var_##V (V v, int16_t idx, S s) \ + { \ + v[idx] = s; \ + return v; \ + } \ + #define TEST_ALL2(T) \ T (_Float16, vnx16hf, 0) \ T (_Float16, vnx16hf, 3) \ @@ -55,20 +64,31 @@ typedef double vnx4df __attribute__((vector_size (32))); T (int8_t, vnx32qi, 16) \ T (int8_t, vnx32qi, 31) \ +#define TEST_ALL_VAR2(T) \ + T (_Float16, vnx16hf) \ + T (float, vnx8sf) \ + T (double, vnx4df) \ + T (int64_t, vnx4di) \ + T (int32_t, vnx8si) \ + T (int16_t, vnx16hi) \ + T (int8_t, vnx32qi) \ + TEST_ALL2 (VEC_SET) +TEST_ALL_VAR2 (VEC_SET_VAR2) /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m2,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m2,\s*tu,\s*ma} 5 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m2,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m2,\s*tu,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m2,\s*tu,\s*ma} 10 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m2,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m2,\s*tu,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m2,\s*tu,\s*ma} 10 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m2,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m2,\s*tu,\s*ma} 6 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m2,\s*tu,\s*ma} 8 } } */ -/* { dg-final { scan-assembler-times {\tvmv.v.x} 15 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.v.f} 11 } } */ +/* { dg-final { scan-assembler-times {\tvmv.v.x} 19 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.v.f} 14 } } */ /* { dg-final { scan-assembler-times {\tvslideup.vi} 26 } } */ +/* { dg-final { scan-assembler-times {\tvslideup.vx} 7 } } */ /* { dg-final { scan-assembler-times {\tvfmv.s.f} 3 } } */ /* { dg-final { scan-assembler-times {\tvmv.s.x} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c index 903deae..5f6cb32 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c @@ -20,6 +20,15 @@ typedef double vnx8df __attribute__((vector_size (64))); return v; \ } +#define VEC_SET_VAR3(S,V) \ + V \ + __attribute__((noipa)) \ + vec_set_var_##V (V v, int32_t idx, S s) \ + { \ + v[idx] = s; \ + return v; \ + } \ + #define TEST_ALL3(T) \ T (_Float16, vnx32hf, 0) \ T (_Float16, vnx32hf, 3) \ @@ -56,21 +65,31 @@ typedef double vnx8df __attribute__((vector_size (64))); T (int8_t, vnx64qi, 32) \ T (int8_t, vnx64qi, 63) \ +#define TEST_ALL_VAR3(T) \ + T (_Float16, vnx32hf) \ + T (float, vnx16sf) \ + T (double, vnx8df) \ + T (int64_t, vnx8di) \ + T (int32_t, vnx16si) \ + T (int16_t, vnx32hi) \ + T (int8_t, vnx64qi) \ + TEST_ALL3 (VEC_SET) +TEST_ALL_VAR3 (VEC_SET_VAR3) /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m4,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m4,\s*tu,\s*ma} 5 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m4,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m4,\s*tu,\s*ma} 9 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m4,\s*tu,\s*ma} 11 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m4,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m4,\s*tu,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m4,\s*tu,\s*ma} 10 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m4,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m4,\s*tu,\s*ma} 6 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m4,\s*tu,\s*ma} 8 } } */ -/* { dg-final { scan-assembler-times {\tvmv.v.x} 15 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.v.f} 12 } } */ +/* { dg-final { scan-assembler-times {\tvmv.v.x} 19 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.v.f} 15 } } */ /* { dg-final { scan-assembler-times {\tvslideup.vi} 25 } } */ -/* { dg-final { scan-assembler-times {\tvslideup.vx} 2 } } */ +/* { dg-final { scan-assembler-times {\tvslideup.vx} 9 } } */ /* { dg-final { scan-assembler-times {\tvfmv.s.f} 3 } } */ /* { dg-final { scan-assembler-times {\tvmv.s.x} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c index 7d73399..c6f6964 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c @@ -20,6 +20,15 @@ typedef double vnx16df __attribute__((vector_size (128))); return v; \ } +#define VEC_SET_VAR4(S,V) \ + V \ + __attribute__((noipa)) \ + vec_set_var_##V (V v, int64_t idx, S s) \ + { \ + v[idx] = s; \ + return v; \ + } \ + #define TEST_ALL4(T) \ T (_Float16, vnx64hf, 0) \ T (_Float16, vnx64hf, 3) \ @@ -59,21 +68,31 @@ typedef double vnx16df __attribute__((vector_size (128))); T (int8_t, vnx128qi, 64) \ T (int8_t, vnx128qi, 127) \ +#define TEST_ALL_VAR4(T) \ + T (_Float16, vnx64hf) \ + T (float, vnx32sf) \ + T (double, vnx16df) \ + T (int64_t, vnx16di) \ + T (int32_t, vnx32si) \ + T (int16_t, vnx64hi) \ + T (int8_t, vnx128qi) \ + TEST_ALL4 (VEC_SET) +TEST_ALL_VAR4 (VEC_SET_VAR4) /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m8,\s*tu,\s*ma} 5 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m8,\s*tu,\s*ma} 6 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m8,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m8,\s*tu,\s*ma} 11 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m8,\s*tu,\s*ma} 13 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m8,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m8,\s*tu,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m8,\s*tu,\s*ma} 10 } } */ /* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m8,\s*ta,\s*ma} 2 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m8,\s*tu,\s*ma} 6 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m8,\s*tu,\s*ma} 8 } } */ -/* { dg-final { scan-assembler-times {\tvmv.v.x} 16 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.v.f} 14 } } */ +/* { dg-final { scan-assembler-times {\tvmv.v.x} 20 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.v.f} 17 } } */ /* { dg-final { scan-assembler-times {\tvslideup.vi} 23 } } */ -/* { dg-final { scan-assembler-times {\tvslideup.vx} 7 } } */ +/* { dg-final { scan-assembler-times {\tvslideup.vx} 14 } } */ /* { dg-final { scan-assembler-times {\tvfmv.s.f} 3 } } */ /* { dg-final { scan-assembler-times {\tvmv.s.x} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-run.c index 6a08f26..44a0fd6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-run.c @@ -19,115 +19,24 @@ void check_##V##_##IDX () \ assert (res[i] == (i == IDX ? 77 : i)); \ } -#define CHECK_ALL(T) \ - T (float, vnx4sf, 0) \ - T (float, vnx4sf, 1) \ - T (float, vnx4sf, 3) \ - T (double, vnx2df, 0) \ - T (double, vnx2df, 1) \ - T (int64_t, vnx2di, 0) \ - T (int64_t, vnx2di, 1) \ - T (int32_t, vnx4si, 0) \ - T (int32_t, vnx4si, 1) \ - T (int32_t, vnx4si, 3) \ - T (int16_t, vnx8hi, 0) \ - T (int16_t, vnx8hi, 2) \ - T (int16_t, vnx8hi, 6) \ - T (int8_t, vnx16qi, 0) \ - T (int8_t, vnx16qi, 1) \ - T (int8_t, vnx16qi, 7) \ - T (int8_t, vnx16qi, 11) \ - T (int8_t, vnx16qi, 15) \ - T (float, vnx8sf, 0) \ - T (float, vnx8sf, 1) \ - T (float, vnx8sf, 3) \ - T (float, vnx8sf, 4) \ - T (float, vnx8sf, 7) \ - T (double, vnx4df, 0) \ - T (double, vnx4df, 1) \ - T (double, vnx4df, 2) \ - T (double, vnx4df, 3) \ - T (int64_t, vnx4di, 0) \ - T (int64_t, vnx4di, 1) \ - T (int64_t, vnx4di, 2) \ - T (int64_t, vnx4di, 3) \ - T (int32_t, vnx8si, 0) \ - T (int32_t, vnx8si, 1) \ - T (int32_t, vnx8si, 3) \ - T (int32_t, vnx8si, 4) \ - T (int32_t, vnx8si, 7) \ - T (int16_t, vnx16hi, 0) \ - T (int16_t, vnx16hi, 1) \ - T (int16_t, vnx16hi, 7) \ - T (int16_t, vnx16hi, 8) \ - T (int16_t, vnx16hi, 15) \ - T (int8_t, vnx32qi, 0) \ - T (int8_t, vnx32qi, 1) \ - T (int8_t, vnx32qi, 15) \ - T (int8_t, vnx32qi, 16) \ - T (int8_t, vnx32qi, 31) \ - T (float, vnx16sf, 0) \ - T (float, vnx16sf, 2) \ - T (float, vnx16sf, 6) \ - T (float, vnx16sf, 8) \ - T (float, vnx16sf, 14) \ - T (double, vnx8df, 0) \ - T (double, vnx8df, 2) \ - T (double, vnx8df, 4) \ - T (double, vnx8df, 6) \ - T (int64_t, vnx8di, 0) \ - T (int64_t, vnx8di, 2) \ - T (int64_t, vnx8di, 4) \ - T (int64_t, vnx8di, 6) \ - T (int32_t, vnx16si, 0) \ - T (int32_t, vnx16si, 2) \ - T (int32_t, vnx16si, 6) \ - T (int32_t, vnx16si, 8) \ - T (int32_t, vnx16si, 14) \ - T (int16_t, vnx32hi, 0) \ - T (int16_t, vnx32hi, 2) \ - T (int16_t, vnx32hi, 14) \ - T (int16_t, vnx32hi, 16) \ - T (int16_t, vnx32hi, 30) \ - T (int8_t, vnx64qi, 0) \ - T (int8_t, vnx64qi, 2) \ - T (int8_t, vnx64qi, 30) \ - T (int8_t, vnx64qi, 32) \ - T (int8_t, vnx64qi, 63) \ - T (float, vnx32sf, 0) \ - T (float, vnx32sf, 3) \ - T (float, vnx32sf, 12) \ - T (float, vnx32sf, 17) \ - T (float, vnx32sf, 14) \ - T (double, vnx16df, 0) \ - T (double, vnx16df, 4) \ - T (double, vnx16df, 8) \ - T (double, vnx16df, 12) \ - T (int64_t, vnx16di, 0) \ - T (int64_t, vnx16di, 4) \ - T (int64_t, vnx16di, 8) \ - T (int64_t, vnx16di, 12) \ - T (int32_t, vnx32si, 0) \ - T (int32_t, vnx32si, 4) \ - T (int32_t, vnx32si, 12) \ - T (int32_t, vnx32si, 16) \ - T (int32_t, vnx32si, 28) \ - T (int16_t, vnx64hi, 0) \ - T (int16_t, vnx64hi, 4) \ - T (int16_t, vnx64hi, 28) \ - T (int16_t, vnx64hi, 32) \ - T (int16_t, vnx64hi, 60) \ - T (int8_t, vnx128qi, 0) \ - T (int8_t, vnx128qi, 4) \ - T (int8_t, vnx128qi, 30) \ - T (int8_t, vnx128qi, 60) \ - T (int8_t, vnx128qi, 64) \ - T (int8_t, vnx128qi, 127) \ - -CHECK_ALL (CHECK) +#define CHECK_VAR(S, V) \ +__attribute__ ((noipa)) \ +void check_var_##V (int32_t idx) \ + { \ + V v; \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + v[i] = i; \ + V res = vec_set_var_##V (v, idx, 77); \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + assert (res[i] == (i == idx ? 77 : i)); \ + } #define RUN(S, V, IDX) \ - check_##V##_##IDX (); + check_##V##_##IDX (); \ + +#define RUN_VAR(S, V) \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + check_var_##V (i); \ #define RUN_ALL(T) \ T (float, vnx4sf, 0) \ @@ -234,7 +143,37 @@ CHECK_ALL (CHECK) T (int8_t, vnx128qi, 64) \ T (int8_t, vnx128qi, 127) \ +#define RUN_ALL_VAR(T) \ + T (float, vnx4sf) \ + T (double, vnx2df) \ + T (int64_t, vnx2di) \ + T (int32_t, vnx4si) \ + T (int16_t, vnx8hi) \ + T (int8_t, vnx16qi) \ + T (float, vnx8sf) \ + T (double, vnx4df) \ + T (int64_t, vnx4di) \ + T (int32_t, vnx8si) \ + T (int16_t, vnx16hi) \ + T (int8_t, vnx32qi) \ + T (float, vnx16sf) \ + T (double, vnx8df) \ + T (int64_t, vnx8di) \ + T (int32_t, vnx16si) \ + T (int16_t, vnx32hi) \ + T (int8_t, vnx64qi) \ + T (float, vnx32sf) \ + T (double, vnx16df) \ + T (int64_t, vnx16di) \ + T (int32_t, vnx32si) \ + T (int16_t, vnx64hi) \ + T (int8_t, vnx128qi) \ + +RUN_ALL (CHECK) +RUN_ALL_VAR (CHECK_VAR) + int main () { RUN_ALL (RUN); + RUN_ALL_VAR (RUN_VAR); } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-zvfh-run.c index df8363e..7e5a73a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-zvfh-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-zvfh-run.c @@ -19,35 +19,24 @@ void check_##V##_##IDX () \ assert (res[i] == (i == IDX ? 77 : i)); \ } -#define CHECK_ALL(T) \ - T (_Float16, vnx8hf, 0) \ - T (_Float16, vnx8hf, 3) \ - T (_Float16, vnx8hf, 7) \ - T (_Float16, vnx16hf, 0) \ - T (_Float16, vnx16hf, 3) \ - T (_Float16, vnx16hf, 7) \ - T (_Float16, vnx16hf, 8) \ - T (_Float16, vnx16hf, 15) \ - T (_Float16, vnx32hf, 0) \ - T (_Float16, vnx32hf, 3) \ - T (_Float16, vnx32hf, 7) \ - T (_Float16, vnx32hf, 8) \ - T (_Float16, vnx32hf, 16) \ - T (_Float16, vnx32hf, 31) \ - T (_Float16, vnx64hf, 0) \ - T (_Float16, vnx64hf, 3) \ - T (_Float16, vnx64hf, 7) \ - T (_Float16, vnx64hf, 8) \ - T (_Float16, vnx64hf, 16) \ - T (_Float16, vnx64hf, 31) \ - T (_Float16, vnx64hf, 42) \ - T (_Float16, vnx64hf, 63) \ - -CHECK_ALL (CHECK) +#define CHECK_VAR(S, V) \ +void check_var_##V (int32_t idx) \ + { \ + V v; \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + v[i] = i; \ + V res = vec_set_var_##V (v, idx, 77); \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + assert (res[i] == (i == idx ? 77 : i)); \ + } #define RUN(S, V, IDX) \ check_##V##_##IDX (); +#define RUN_VAR(S, V) \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + check_var_##V (i); \ + #define RUN_ALL(T) \ T (_Float16, vnx8hf, 0) \ T (_Float16, vnx8hf, 3) \ @@ -72,7 +61,17 @@ CHECK_ALL (CHECK) T (_Float16, vnx64hf, 42) \ T (_Float16, vnx64hf, 63) \ +#define RUN_ALL_VAR(T) \ + T (_Float16, vnx8hf) \ + T (_Float16, vnx16hf) \ + T (_Float16, vnx32hf) \ + T (_Float16, vnx64hf) \ + +RUN_ALL (CHECK) +RUN_ALL_VAR (CHECK_VAR) + int main () { RUN_ALL (RUN); + RUN_ALL_VAR (RUN_VAR); } -- cgit v1.1 From 573bb719bb82d1d61ca54eb4fddf82eccfd56470 Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Wed, 28 Jun 2023 16:00:46 +0200 Subject: RISC-V: Support variable index in vec_extract. This patch adds a gen_lowpart in the vec_extract expander so it properly works with a variable index and adds tests. gcc/ChangeLog: * config/riscv/autovec.md: Add gen_lowpart. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c: Add tests for variable index. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-run.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-zvfh-run.c: Ditto. --- gcc/config/riscv/autovec.md | 1 + .../riscv/rvv/autovec/vls-vlmax/vec_extract-1.c | 33 +++-- .../riscv/rvv/autovec/vls-vlmax/vec_extract-2.c | 32 ++++- .../riscv/rvv/autovec/vls-vlmax/vec_extract-3.c | 32 ++++- .../riscv/rvv/autovec/vls-vlmax/vec_extract-4.c | 32 ++++- .../riscv/rvv/autovec/vls-vlmax/vec_extract-run.c | 154 ++++++--------------- .../rvv/autovec/vls-vlmax/vec_extract-zvfh-run.c | 49 ++++--- 7 files changed, 171 insertions(+), 162 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 7b457a5..9e61b2e 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1088,6 +1088,7 @@ { /* Emit the slide down to index 0 in a new vector. */ tmp = gen_reg_rtx (mode); + operands[2] = gen_lowpart (Pmode, operands[2]); rtx ops[] = {tmp, RVV_VUNDEF (mode), operands[1], operands[2]}; riscv_vector::emit_vlmax_slide_insn (code_for_pred_slide (UNSPEC_VSLIDEDOWN, mode), ops); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c index 9cb167a..34a8212 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c @@ -11,7 +11,6 @@ typedef _Float16 vnx8hf __attribute__((vector_size (16))); typedef float vnx4sf __attribute__((vector_size (16))); typedef double vnx2df __attribute__((vector_size (16))); - #define VEC_EXTRACT(S,V,IDX) \ S \ __attribute__((noipa)) \ @@ -20,6 +19,14 @@ typedef double vnx2df __attribute__((vector_size (16))); return v[IDX]; \ } +#define VEC_EXTRACT_VAR1(S,V) \ + S \ + __attribute__((noipa)) \ + vec_extract_var_##V (V v, int8_t idx) \ + { \ + return v[idx]; \ + } + #define TEST_ALL1(T) \ T (_Float16, vnx8hf, 0) \ T (_Float16, vnx8hf, 3) \ @@ -43,17 +50,27 @@ typedef double vnx2df __attribute__((vector_size (16))); T (int8_t, vnx16qi, 11) \ T (int8_t, vnx16qi, 15) \ +#define TEST_ALL_VAR1(T) \ + T (_Float16, vnx8hf) \ + T (float, vnx4sf) \ + T (double, vnx2df) \ + T (int64_t, vnx2di) \ + T (int32_t, vnx4si) \ + T (int16_t, vnx8hi) \ + T (int8_t, vnx16qi) \ + TEST_ALL1 (VEC_EXTRACT) +TEST_ALL_VAR1 (VEC_EXTRACT_VAR1) -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*ta,\s*ma} 5 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*ta,\s*ma} 6 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*ta,\s*ma} 6 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m1,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m1,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m1,\s*ta,\s*ma} 6 } } */ /* { dg-final { scan-assembler-times {\tvslidedown.vi} 14 } } */ -/* { dg-final { scan-assembler-times {\tvslidedown.vx} 0 } } */ +/* { dg-final { scan-assembler-times {\tvslidedown.vx} 7 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.f.s} 8 } } */ -/* { dg-final { scan-assembler-times {\tvmv.x.s} 13 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.f.s} 11 } } */ +/* { dg-final { scan-assembler-times {\tvmv.x.s} 17 } } */ /* { dg-final { scan-assembler-not {\tsext} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c index 2837ff5..4288a6d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c @@ -19,6 +19,14 @@ typedef double vnx4df __attribute__((vector_size (32))); return v[IDX]; \ } +#define VEC_EXTRACT_VAR2(S,V) \ + S \ + __attribute__((noipa)) \ + vec_extract_var_##V (V v, int16_t idx) \ + { \ + return v[idx]; \ + } + #define TEST_ALL2(T) \ T (_Float16, vnx16hf, 0) \ T (_Float16, vnx16hf, 3) \ @@ -54,17 +62,27 @@ typedef double vnx4df __attribute__((vector_size (32))); T (int8_t, vnx32qi, 16) \ T (int8_t, vnx32qi, 31) \ +#define TEST_ALL_VAR2(T) \ + T (_Float16, vnx16hf) \ + T (float, vnx8sf) \ + T (double, vnx4df) \ + T (int64_t, vnx4di) \ + T (int32_t, vnx8si) \ + T (int16_t, vnx16hi) \ + T (int8_t, vnx32qi) \ + TEST_ALL2 (VEC_EXTRACT) +TEST_ALL_VAR2 (VEC_EXTRACT_VAR2) -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m2,\s*ta,\s*ma} 5 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m2,\s*ta,\s*ma} 10 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m2,\s*ta,\s*ma} 10 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m2,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m2,\s*ta,\s*ma} 12 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m2,\s*ta,\s*ma} 12 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m2,\s*ta,\s*ma} 10 } } */ /* { dg-final { scan-assembler-times {\tvslidedown.vi} 26 } } */ -/* { dg-final { scan-assembler-times {\tvslidedown.vx} 0 } } */ +/* { dg-final { scan-assembler-times {\tvslidedown.vx} 7 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.f.s} 14 } } */ -/* { dg-final { scan-assembler-times {\tvmv.x.s} 19 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.f.s} 17 } } */ +/* { dg-final { scan-assembler-times {\tvmv.x.s} 23 } } */ /* { dg-final { scan-assembler-not {\tsext} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c index 47f30ed..0102848 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c @@ -19,6 +19,14 @@ typedef double vnx8df __attribute__((vector_size (64))); return v[IDX]; \ } +#define VEC_EXTRACT_VAR3(S,V) \ + S \ + __attribute__((noipa)) \ + vec_extract_var_##V (V v, int32_t idx) \ + { \ + return v[idx]; \ + } + #define TEST_ALL3(T) \ T (_Float16, vnx32hf, 0) \ T (_Float16, vnx32hf, 3) \ @@ -55,17 +63,27 @@ typedef double vnx8df __attribute__((vector_size (64))); T (int8_t, vnx64qi, 32) \ T (int8_t, vnx64qi, 63) \ +#define TEST_ALL_VAR3(T) \ + T (_Float16, vnx32hf) \ + T (float, vnx16sf) \ + T (double, vnx8df) \ + T (int64_t, vnx8di) \ + T (int32_t, vnx16si) \ + T (int16_t, vnx32hi) \ + T (int8_t, vnx64qi) \ + TEST_ALL3 (VEC_EXTRACT) +TEST_ALL_VAR3 (VEC_EXTRACT_VAR3) -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m4,\s*ta,\s*ma} 5 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m4,\s*ta,\s*ma} 11 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m4,\s*ta,\s*ma} 10 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m4,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m4,\s*ta,\s*ma} 13 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m4,\s*ta,\s*ma} 12 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m4,\s*ta,\s*ma} 10 } } */ /* { dg-final { scan-assembler-times {\tvslidedown.vi} 25 } } */ -/* { dg-final { scan-assembler-times {\tvslidedown.vx} 2 } } */ +/* { dg-final { scan-assembler-times {\tvslidedown.vx} 9 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.f.s} 15 } } */ -/* { dg-final { scan-assembler-times {\tvmv.x.s} 19 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.f.s} 18 } } */ +/* { dg-final { scan-assembler-times {\tvmv.x.s} 23 } } */ /* { dg-final { scan-assembler-not {\tsext} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c index f7169f0..d8deb7d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c @@ -19,6 +19,14 @@ typedef double vnx16df __attribute__((vector_size (128))); return v[IDX]; \ } +#define VEC_EXTRACT_VAR4(S,V) \ + S \ + __attribute__((noipa)) \ + vec_extract_var_##V (V v, int64_t idx) \ + { \ + return v[idx]; \ + } + #define TEST_ALL4(T) \ T (_Float16, vnx64hf, 0) \ T (_Float16, vnx64hf, 3) \ @@ -58,17 +66,27 @@ typedef double vnx16df __attribute__((vector_size (128))); T (int8_t, vnx128qi, 64) \ T (int8_t, vnx128qi, 127) \ +#define TEST_ALL_VAR4(T) \ + T (_Float16, vnx64hf) \ + T (float, vnx32sf) \ + T (double, vnx16df) \ + T (int64_t, vnx16di) \ + T (int32_t, vnx32si) \ + T (int16_t, vnx64hi) \ + T (int8_t, vnx128qi) \ + TEST_ALL4 (VEC_EXTRACT) +TEST_ALL_VAR4 (VEC_EXTRACT_VAR4) -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m8,\s*ta,\s*ma} 13 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m8,\s*ta,\s*ma} 10 } } */ -/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m8,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e8,\s*m8,\s*ta,\s*ma} 7 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e16,\s*m8,\s*ta,\s*ma} 15 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e32,\s*m8,\s*ta,\s*ma} 12 } } */ +/* { dg-final { scan-assembler-times {vset[i]*vli\s+[a-z0-9,]+,\s*e64,\s*m8,\s*ta,\s*ma} 10 } } */ /* { dg-final { scan-assembler-times {\tvslidedown.vi} 23 } } */ -/* { dg-final { scan-assembler-times {\tvslidedown.vx} 7 } } */ +/* { dg-final { scan-assembler-times {\tvslidedown.vx} 14 } } */ -/* { dg-final { scan-assembler-times {\tvfmv.f.s} 17 } } */ -/* { dg-final { scan-assembler-times {\tvmv.x.s} 20 } } */ +/* { dg-final { scan-assembler-times {\tvfmv.f.s} 20 } } */ +/* { dg-final { scan-assembler-times {\tvmv.x.s} 24 } } */ /* { dg-final { scan-assembler-not {\tsext} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-run.c index 43110c0..c5ee270 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-run.c @@ -18,117 +18,25 @@ void check_##V##_##IDX () \ assert (res == v[IDX]); \ } -#define CHECK_ALL(T) \ - T (float, vnx4sf, 0) \ - T (float, vnx4sf, 1) \ - T (float, vnx4sf, 3) \ - T (double, vnx2df, 0) \ - T (double, vnx2df, 1) \ - T (int64_t, vnx2di, 0) \ - T (int64_t, vnx2di, 1) \ - T (int32_t, vnx4si, 0) \ - T (int32_t, vnx4si, 1) \ - T (int32_t, vnx4si, 3) \ - T (int16_t, vnx8hi, 0) \ - T (int16_t, vnx8hi, 2) \ - T (int16_t, vnx8hi, 6) \ - T (int8_t, vnx16qi, 0) \ - T (int8_t, vnx16qi, 1) \ - T (int8_t, vnx16qi, 7) \ - T (int8_t, vnx16qi, 11) \ - T (int8_t, vnx16qi, 15) \ - T (float, vnx8sf, 0) \ - T (float, vnx8sf, 1) \ - T (float, vnx8sf, 3) \ - T (float, vnx8sf, 4) \ - T (float, vnx8sf, 7) \ - T (double, vnx4df, 0) \ - T (double, vnx4df, 1) \ - T (double, vnx4df, 2) \ - T (double, vnx4df, 3) \ - T (int64_t, vnx4di, 0) \ - T (int64_t, vnx4di, 1) \ - T (int64_t, vnx4di, 2) \ - T (int64_t, vnx4di, 3) \ - T (int32_t, vnx8si, 0) \ - T (int32_t, vnx8si, 1) \ - T (int32_t, vnx8si, 3) \ - T (int32_t, vnx8si, 4) \ - T (int32_t, vnx8si, 7) \ - T (int16_t, vnx16hi, 0) \ - T (int16_t, vnx16hi, 1) \ - T (int16_t, vnx16hi, 7) \ - T (int16_t, vnx16hi, 8) \ - T (int16_t, vnx16hi, 15) \ - T (int8_t, vnx32qi, 0) \ - T (int8_t, vnx32qi, 1) \ - T (int8_t, vnx32qi, 15) \ - T (int8_t, vnx32qi, 16) \ - T (int8_t, vnx32qi, 31) \ - T (float, vnx16sf, 0) \ - T (float, vnx16sf, 2) \ - T (float, vnx16sf, 6) \ - T (float, vnx16sf, 8) \ - T (float, vnx16sf, 14) \ - T (double, vnx8df, 0) \ - T (double, vnx8df, 2) \ - T (double, vnx8df, 4) \ - T (double, vnx8df, 6) \ - T (int64_t, vnx8di, 0) \ - T (int64_t, vnx8di, 2) \ - T (int64_t, vnx8di, 4) \ - T (int64_t, vnx8di, 6) \ - T (int32_t, vnx16si, 0) \ - T (int32_t, vnx16si, 2) \ - T (int32_t, vnx16si, 6) \ - T (int32_t, vnx16si, 8) \ - T (int32_t, vnx16si, 14) \ - T (int16_t, vnx32hi, 0) \ - T (int16_t, vnx32hi, 2) \ - T (int16_t, vnx32hi, 14) \ - T (int16_t, vnx32hi, 16) \ - T (int16_t, vnx32hi, 30) \ - T (int8_t, vnx64qi, 0) \ - T (int8_t, vnx64qi, 2) \ - T (int8_t, vnx64qi, 30) \ - T (int8_t, vnx64qi, 32) \ - T (int8_t, vnx64qi, 63) \ - T (float, vnx32sf, 0) \ - T (float, vnx32sf, 3) \ - T (float, vnx32sf, 12) \ - T (float, vnx32sf, 17) \ - T (float, vnx32sf, 14) \ - T (double, vnx16df, 0) \ - T (double, vnx16df, 4) \ - T (double, vnx16df, 8) \ - T (double, vnx16df, 12) \ - T (int64_t, vnx16di, 0) \ - T (int64_t, vnx16di, 4) \ - T (int64_t, vnx16di, 8) \ - T (int64_t, vnx16di, 12) \ - T (int32_t, vnx32si, 0) \ - T (int32_t, vnx32si, 4) \ - T (int32_t, vnx32si, 12) \ - T (int32_t, vnx32si, 16) \ - T (int32_t, vnx32si, 28) \ - T (int16_t, vnx64hi, 0) \ - T (int16_t, vnx64hi, 4) \ - T (int16_t, vnx64hi, 28) \ - T (int16_t, vnx64hi, 32) \ - T (int16_t, vnx64hi, 60) \ - T (int8_t, vnx128qi, 0) \ - T (int8_t, vnx128qi, 4) \ - T (int8_t, vnx128qi, 30) \ - T (int8_t, vnx128qi, 60) \ - T (int8_t, vnx128qi, 64) \ - T (int8_t, vnx128qi, 127) \ - -CHECK_ALL (CHECK) +#define CHECK_VAR(S, V) \ +__attribute__ ((noipa)) \ +void check_var_##V (int32_t idx) \ + { \ + V v; \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + v[i] = i; \ + S res = vec_extract_var_##V (v, idx); \ + assert (res == v[idx]); \ + } -#define RUN(S, V, IDX) \ +#define RUN(S, V, IDX) \ check_##V##_##IDX (); -#define RUN_ALL(T) \ +#define RUN_VAR(S, V) \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + check_var_##V (i); \ + +#define RUN_ALL(T) \ T (float, vnx4sf, 0) \ T (float, vnx4sf, 1) \ T (float, vnx4sf, 3) \ @@ -233,7 +141,37 @@ CHECK_ALL (CHECK) T (int8_t, vnx128qi, 64) \ T (int8_t, vnx128qi, 127) \ +#define RUN_ALL_VAR(T) \ + T (float, vnx4sf) \ + T (double, vnx2df) \ + T (int64_t, vnx2di) \ + T (int32_t, vnx4si) \ + T (int16_t, vnx8hi) \ + T (int8_t, vnx16qi) \ + T (float, vnx8sf) \ + T (double, vnx4df) \ + T (int64_t, vnx4di) \ + T (int32_t, vnx8si) \ + T (int16_t, vnx16hi) \ + T (int8_t, vnx32qi) \ + T (float, vnx16sf) \ + T (double, vnx8df) \ + T (int64_t, vnx8di) \ + T (int32_t, vnx16si) \ + T (int16_t, vnx32hi) \ + T (int8_t, vnx64qi) \ + T (float, vnx32sf) \ + T (double, vnx16df) \ + T (int64_t, vnx16di) \ + T (int32_t, vnx32si) \ + T (int16_t, vnx64hi) \ + T (int8_t, vnx128qi) \ + +RUN_ALL (CHECK) +RUN_ALL_VAR (CHECK_VAR) + int main () { RUN_ALL (RUN); + RUN_ALL_VAR (RUN_VAR); } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-zvfh-run.c index db54acc..365480e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-zvfh-run.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-zvfh-run.c @@ -18,35 +18,24 @@ void check_##V##_##IDX () \ assert (res == v[IDX]); \ } -#define CHECK_ALL(T) \ - T (_Float16, vnx8hf, 0) \ - T (_Float16, vnx8hf, 3) \ - T (_Float16, vnx8hf, 7) \ - T (_Float16, vnx16hf, 0) \ - T (_Float16, vnx16hf, 3) \ - T (_Float16, vnx16hf, 7) \ - T (_Float16, vnx16hf, 8) \ - T (_Float16, vnx16hf, 15) \ - T (_Float16, vnx32hf, 0) \ - T (_Float16, vnx32hf, 3) \ - T (_Float16, vnx32hf, 7) \ - T (_Float16, vnx32hf, 8) \ - T (_Float16, vnx32hf, 16) \ - T (_Float16, vnx32hf, 31) \ - T (_Float16, vnx64hf, 0) \ - T (_Float16, vnx64hf, 3) \ - T (_Float16, vnx64hf, 7) \ - T (_Float16, vnx64hf, 8) \ - T (_Float16, vnx64hf, 16) \ - T (_Float16, vnx64hf, 31) \ - T (_Float16, vnx64hf, 42) \ - T (_Float16, vnx64hf, 63) \ - -CHECK_ALL (CHECK) +#define CHECK_VAR(S, V) \ +__attribute__ ((noipa)) \ +void check_var_##V (int32_t idx) \ + { \ + V v; \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + v[i] = i; \ + S res = vec_extract_var_##V (v, idx); \ + assert (res == v[idx]); \ + } #define RUN(S, V, IDX) \ check_##V##_##IDX (); +#define RUN_VAR(S, V) \ + for (int i = 0; i < sizeof (V) / sizeof (S); i++) \ + check_var_##V (i); \ + #define RUN_ALL(T) \ T (_Float16, vnx8hf, 0) \ T (_Float16, vnx8hf, 3) \ @@ -71,7 +60,17 @@ CHECK_ALL (CHECK) T (_Float16, vnx64hf, 42) \ T (_Float16, vnx64hf, 63) \ +#define RUN_ALL_VAR(T) \ + T (_Float16, vnx8hf) \ + T (_Float16, vnx16hf) \ + T (_Float16, vnx32hf) \ + T (_Float16, vnx64hf) \ + +RUN_ALL (CHECK) +RUN_ALL_VAR (CHECK_VAR) + int main () { RUN_ALL (RUN); + RUN_ALL_VAR (RUN_VAR) } -- cgit v1.1 From c30efd8cd634f8a59bc1bf52e71d8866bf52d56c Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Wed, 28 Jun 2023 15:48:55 +0200 Subject: gimple-isel: Recognize vec_extract pattern. In gimple-isel we already deduce a vec_set pattern from an ARRAY_REF(VIEW_CONVERT_EXPR). This patch does the same for a vec_extract. The code is largely similar to the vec_set one including the addition of a can_vec_extract_var_idx_p function in optabs.cc to check if the backend can handle a register operand as index. We already have can_vec_extract in optabs-query but that one checks whether we can extract specific modes. With the introduction of an internal function for vec_extract the expander must not FAIL. For vec_set this has already been the case so adjust the documentation accordingly. Additionally, clarify the wording of the vector-vector case for vec_extract. gcc/ChangeLog: * doc/md.texi: Document that vec_set and vec_extract must not fail. * gimple-isel.cc (gimple_expand_vec_set_expr): Rename this... (gimple_expand_vec_set_extract_expr): ...to this. (gimple_expand_vec_exprs): Call renamed function. * internal-fn.cc (vec_extract_direct): Add. (expand_vec_extract_optab_fn): New function to expand vec_extract optab. (direct_vec_extract_optab_supported_p): Add. * internal-fn.def (VEC_EXTRACT): Add. * optabs.cc (can_vec_extract_var_idx_p): New function. * optabs.h (can_vec_extract_var_idx_p): Declare. --- gcc/doc/md.texi | 7 +++- gcc/gimple-isel.cc | 99 ++++++++++++++++++++++++++++++++++++++--------------- gcc/internal-fn.cc | 39 +++++++++++++++++++++ gcc/internal-fn.def | 1 + gcc/optabs.cc | 24 +++++++++++++ gcc/optabs.h | 1 + 6 files changed, 143 insertions(+), 28 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index f14dd32..b30a824 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5091,6 +5091,8 @@ Mask elements @var{i} with @var{i} > (operand 5 + operand 6) are ignored. Set given field in the vector value. Operand 0 is the vector to modify, operand 1 is new value of field and operand 2 specify the field index. +This pattern is not allowed to @code{FAIL}. + @cindex @code{vec_extract@var{m}@var{n}} instruction pattern @item @samp{vec_extract@var{m}@var{n}} Extract given field from the vector value. Operand 1 is the vector, operand 2 @@ -5098,7 +5100,10 @@ specify field index and operand 0 place to store value into. The @var{n} mode is the mode of the field or vector of fields that should be extracted, should be either element mode of the vector mode @var{m}, or a vector mode with the same element mode and smaller number of elements. -If @var{n} is a vector mode, the index is counted in units of that mode. +If @var{n} is a vector mode the index is counted in multiples of +mode @var{n}. + +This pattern is not allowed to @code{FAIL}. @cindex @code{vec_init@var{m}@var{n}} instruction pattern @item @samp{vec_init@var{m}@var{n}} diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index ef688dd..e567064 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -42,17 +42,26 @@ along with GCC; see the file COPYING3. If not see /* Expand all ARRAY_REF(VIEW_CONVERT_EXPR) gimple assignments into calls to internal function based on vector type of selected expansion. - i.e.: + + For vec_set: + VIEW_CONVERT_EXPR(u)[_1] = i_4(D); => _7 = u; _8 = .VEC_SET (_7, i_4(D), _1); - u = _8; */ + u = _8; + + For vec_extract: + + _3 = VIEW_CONVERT_EXPR(vD.2208)[idx_2(D)]; + => + _4 = vD.2208; + _3 = .VEC_EXTRACT (_4, idx_2(D)); */ static bool -gimple_expand_vec_set_expr (struct function *fun, gimple_stmt_iterator *gsi) +gimple_expand_vec_set_extract_expr (struct function *fun, + gimple_stmt_iterator *gsi) { - enum tree_code code; gcall *new_stmt = NULL; gassign *ass_stmt = NULL; bool cfg_changed = false; @@ -62,49 +71,84 @@ gimple_expand_vec_set_expr (struct function *fun, gimple_stmt_iterator *gsi) if (!stmt) return false; + bool is_extract = false; + tree lhs = gimple_assign_lhs (stmt); - code = TREE_CODE (lhs); - if (code != ARRAY_REF) + tree rhs = gimple_assign_rhs1 (stmt); + tree val, ref; + if (TREE_CODE (lhs) == ARRAY_REF) + { + /* Assume it is a vec_set. */ + val = rhs; + ref = lhs; + } + else if (TREE_CODE (rhs) == ARRAY_REF) + { + /* vec_extract. */ + is_extract = true; + val = lhs; + ref = rhs; + } + else return false; - tree val = gimple_assign_rhs1 (stmt); - tree op0 = TREE_OPERAND (lhs, 0); + tree op0 = TREE_OPERAND (ref, 0); if (TREE_CODE (op0) == VIEW_CONVERT_EXPR && DECL_P (TREE_OPERAND (op0, 0)) && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))) - && TYPE_MODE (TREE_TYPE (lhs)) + && TYPE_MODE (TREE_TYPE (ref)) == TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0))))) { - tree pos = TREE_OPERAND (lhs, 1); + tree pos = TREE_OPERAND (ref, 1); + tree view_op0 = TREE_OPERAND (op0, 0); machine_mode outermode = TYPE_MODE (TREE_TYPE (view_op0)); + machine_mode extract_mode = TYPE_MODE (TREE_TYPE (ref)); + if (auto_var_in_fn_p (view_op0, fun->decl) - && !TREE_ADDRESSABLE (view_op0) && can_vec_set_var_idx_p (outermode)) + && !TREE_ADDRESSABLE (view_op0) + && ((!is_extract && can_vec_set_var_idx_p (outermode)) + || (is_extract + && can_vec_extract_var_idx_p (outermode, extract_mode)))) { location_t loc = gimple_location (stmt); tree var_src = make_ssa_name (TREE_TYPE (view_op0)); - tree var_dst = make_ssa_name (TREE_TYPE (view_op0)); ass_stmt = gimple_build_assign (var_src, view_op0); gimple_set_vuse (ass_stmt, gimple_vuse (stmt)); gimple_set_location (ass_stmt, loc); gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT); - new_stmt - = gimple_build_call_internal (IFN_VEC_SET, 3, var_src, val, pos); - gimple_call_set_lhs (new_stmt, var_dst); - gimple_set_location (new_stmt, loc); - gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); + if (!is_extract) + { + tree var_dst = make_ssa_name (TREE_TYPE (view_op0)); - ass_stmt = gimple_build_assign (view_op0, var_dst); - gimple_set_location (ass_stmt, loc); - gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT); + new_stmt = gimple_build_call_internal (IFN_VEC_SET, 3, var_src, + val, pos); + + gimple_call_set_lhs (new_stmt, var_dst); + gimple_set_location (new_stmt, loc); + gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); + + ass_stmt = gimple_build_assign (view_op0, var_dst); + gimple_set_location (ass_stmt, loc); + gimple_move_vops (ass_stmt, stmt); + gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT); - basic_block bb = gimple_bb (stmt); - gimple_move_vops (ass_stmt, stmt); - if (gsi_remove (gsi, true) - && gimple_purge_dead_eh_edges (bb)) - cfg_changed = true; - *gsi = gsi_for_stmt (ass_stmt); + basic_block bb = gimple_bb (stmt); + if (gsi_remove (gsi, true) + && gimple_purge_dead_eh_edges (bb)) + cfg_changed = true; + *gsi = gsi_for_stmt (ass_stmt); + } + else + { + new_stmt + = gimple_build_call_internal (IFN_VEC_EXTRACT, 2, var_src, pos); + gimple_call_set_lhs (new_stmt, lhs); + + gsi_replace (gsi, new_stmt, true); + cfg_changed = true; + } } } @@ -317,7 +361,8 @@ gimple_expand_vec_exprs (struct function *fun) gsi_replace (&gsi, g, false); } - cfg_changed |= gimple_expand_vec_set_expr (fun, &gsi); + cfg_changed |= gimple_expand_vec_set_extract_expr (fun, &gsi); + if (gsi_end_p (gsi)) break; } diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index bec60cd..278db7b 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -175,6 +175,7 @@ init_internal_fns () #define len_store_direct { 3, 3, false } #define len_maskstore_direct { 4, 5, false } #define vec_set_direct { 3, 3, false } +#define vec_extract_direct { 3, 3, false } #define unary_direct { 0, 0, true } #define unary_convert_direct { -1, 0, true } #define binary_direct { 0, 0, true } @@ -3107,6 +3108,43 @@ expand_vec_set_optab_fn (internal_fn, gcall *stmt, convert_optab optab) gcc_unreachable (); } +/* Expand VEC_EXTRACT optab internal function. */ + +static void +expand_vec_extract_optab_fn (internal_fn, gcall *stmt, convert_optab optab) +{ + tree lhs = gimple_call_lhs (stmt); + tree op0 = gimple_call_arg (stmt, 0); + tree op1 = gimple_call_arg (stmt, 1); + + rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); + + machine_mode outermode = TYPE_MODE (TREE_TYPE (op0)); + machine_mode extract_mode = TYPE_MODE (TREE_TYPE (lhs)); + + rtx src = expand_normal (op0); + rtx pos = expand_normal (op1); + + class expand_operand ops[3]; + enum insn_code icode = convert_optab_handler (optab, outermode, + extract_mode); + + if (icode != CODE_FOR_nothing) + { + create_output_operand (&ops[0], target, extract_mode); + create_input_operand (&ops[1], src, outermode); + create_convert_operand_from (&ops[2], pos, + TYPE_MODE (TREE_TYPE (op1)), true); + if (maybe_expand_insn (icode, 3, ops)) + { + if (!rtx_equal_p (target, ops[0].value)) + emit_move_insn (target, ops[0].value); + return; + } + } + gcc_unreachable (); +} + static void expand_ABNORMAL_DISPATCHER (internal_fn, gcall *) { @@ -3946,6 +3984,7 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types, #define direct_mask_fold_left_optab_supported_p direct_optab_supported_p #define direct_check_ptrs_optab_supported_p direct_optab_supported_p #define direct_vec_set_optab_supported_p direct_optab_supported_p +#define direct_vec_extract_optab_supported_p direct_optab_supported_p /* Return the optab used by internal function FN. */ diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index 9b73e54..238b7ee 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -180,6 +180,7 @@ DEF_INTERNAL_OPTAB_FN (VCONDEQ, 0, vcondeq, vec_cond) DEF_INTERNAL_OPTAB_FN (VCOND_MASK, 0, vcond_mask, vec_cond_mask) DEF_INTERNAL_OPTAB_FN (VEC_SET, 0, vec_set, vec_set) +DEF_INTERNAL_OPTAB_FN (VEC_EXTRACT, 0, vec_extract, vec_extract) DEF_INTERNAL_OPTAB_FN (LEN_STORE, 0, len_store, len_store) DEF_INTERNAL_OPTAB_FN (LEN_MASK_STORE, 0, len_maskstore, len_maskstore) diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 0a2bcf3..4e9f58f 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -4417,6 +4417,30 @@ can_vec_set_var_idx_p (machine_mode vec_mode) && insn_operand_matches (icode, 2, reg3); } +/* Return whether the backend can emit a vec_extract instruction with + a non-constant index. */ +bool +can_vec_extract_var_idx_p (machine_mode vec_mode, machine_mode extr_mode) +{ + if (!VECTOR_MODE_P (vec_mode)) + return false; + + rtx reg1 = alloca_raw_REG (extr_mode, LAST_VIRTUAL_REGISTER + 1); + rtx reg2 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 2); + + enum insn_code icode = convert_optab_handler (vec_extract_optab, + vec_mode, extr_mode); + + const struct insn_data_d *data = &insn_data[icode]; + machine_mode idx_mode = data->operand[2].mode; + + rtx reg3 = alloca_raw_REG (idx_mode, LAST_VIRTUAL_REGISTER + 3); + + return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1) + && insn_operand_matches (icode, 1, reg2) + && insn_operand_matches (icode, 2, reg3); +} + /* This function is called when we are going to emit a compare instruction that compares the values found in X and Y, using the rtl operator COMPARISON. diff --git a/gcc/optabs.h b/gcc/optabs.h index 781d554..c80b7f4 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -259,6 +259,7 @@ extern bool can_vcond_compare_p (enum rtx_code, machine_mode, machine_mode); /* Return whether the backend can emit vector set instructions for inserting element into vector at variable index position. */ extern bool can_vec_set_var_idx_p (machine_mode); +extern bool can_vec_extract_var_idx_p (machine_mode, machine_mode); extern rtx prepare_operand (enum insn_code, rtx, int, machine_mode, machine_mode, int); -- cgit v1.1 From a4778dbd935d4e26b41e5c0e6191b7311457b239 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 5 Jul 2023 13:22:18 +0200 Subject: sched: Change return type of predicate functions from int to bool Also change some internal variables to bool. gcc/ChangeLog: * sched-int.h (struct haifa_sched_info): Change can_schedule_ready_p, scehdule_more_p and contributes_to_priority indirect frunction type from int to bool. (no_real_insns_p): Change return type from int to bool. (contributes_to_priority): Ditto. * haifa-sched.cc (no_real_insns_p): Change return type from int to bool and adjust function body accordingly. * modulo-sched.cc (try_scheduling_node_in_cycle): Change "success" variable type from int to bool. (ps_insn_advance_column): Change return type from int to bool. (ps_has_conflicts): Ditto. Change "has_conflicts" variable type from int to bool. * sched-deps.cc (deps_may_trap_p): Change return type from int to bool. (conditions_mutex_p): Ditto. * sched-ebb.cc (schedule_more_p): Ditto. (ebb_contributes_to_priority): Change return type from int to bool and adjust function body accordingly. * sched-rgn.cc (is_cfg_nonregular): Ditto. (check_live_1): Ditto. (is_pfree): Ditto. (find_conditional_protection): Ditto. (is_conditionally_protected): Ditto. (is_prisky): Ditto. (is_exception_free): Ditto. (haifa_find_rgns): Change "unreachable" and "too_large_failure" variables from int to bool. (extend_rgns): Change "rescan" variable from int to bool. (check_live): Change return type from int to bool and adjust function body accordingly. (can_schedule_ready_p): Ditto. (schedule_more_p): Ditto. (contributes_to_priority): Ditto. --- gcc/haifa-sched.cc | 8 +-- gcc/modulo-sched.cc | 11 +-- gcc/sched-deps.cc | 16 ++--- gcc/sched-ebb.cc | 14 ++-- gcc/sched-int.h | 18 ++--- gcc/sched-rgn.cc | 189 +++++++++++++++++++++++++++------------------------- 6 files changed, 131 insertions(+), 125 deletions(-) (limited to 'gcc') diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc index 2c881ed..01a2a80 100644 --- a/gcc/haifa-sched.cc +++ b/gcc/haifa-sched.cc @@ -5033,18 +5033,18 @@ get_ebb_head_tail (basic_block beg, basic_block end, *tailp = end_tail; } -/* Return nonzero if there are no real insns in the range [ HEAD, TAIL ]. */ +/* Return true if there are no real insns in the range [ HEAD, TAIL ]. */ -int +bool no_real_insns_p (const rtx_insn *head, const rtx_insn *tail) { while (head != NEXT_INSN (tail)) { if (!NOTE_P (head) && !LABEL_P (head)) - return 0; + return false; head = NEXT_INSN (head); } - return 1; + return true; } /* Restore-other-notes: NOTE_LIST is the end of a chain of notes diff --git a/gcc/modulo-sched.cc b/gcc/modulo-sched.cc index 2675221..c5a392d 100644 --- a/gcc/modulo-sched.cc +++ b/gcc/modulo-sched.cc @@ -2119,7 +2119,7 @@ try_scheduling_node_in_cycle (partial_schedule_ptr ps, sbitmap must_follow) { ps_insn_ptr psi; - bool success = 0; + bool success = false; verify_partial_schedule (ps, sched_nodes); psi = ps_add_node_check_conflicts (ps, u, cycle, must_precede, must_follow); @@ -2127,7 +2127,7 @@ try_scheduling_node_in_cycle (partial_schedule_ptr ps, { SCHED_TIME (u) = cycle; bitmap_set_bit (sched_nodes, u); - success = 1; + success = true; *num_splits = 0; if (dump_file) fprintf (dump_file, "Scheduled w/o split in %d\n", cycle); @@ -3067,7 +3067,7 @@ ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i, in failure and true in success. Bit N is set in MUST_FOLLOW if the node with cuid N must be come after the node pointed to by PS_I when scheduled in the same cycle. */ -static int +static bool ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i, sbitmap must_follow) { @@ -3158,7 +3158,7 @@ advance_one_cycle (void) /* Checks if PS has resource conflicts according to DFA, starting from FROM cycle to TO cycle; returns true if there are conflicts and false if there are no conflicts. Assumes DFA is being used. */ -static int +static bool ps_has_conflicts (partial_schedule_ptr ps, int from, int to) { int cycle; @@ -3214,7 +3214,8 @@ ps_add_node_check_conflicts (partial_schedule_ptr ps, int n, int c, sbitmap must_precede, sbitmap must_follow) { - int i, first, amount, has_conflicts = 0; + int i, first, amount; + bool has_conflicts = false; ps_insn_ptr ps_i; /* First add the node to the PS, if this succeeds check for diff --git a/gcc/sched-deps.cc b/gcc/sched-deps.cc index 998fe93..c232188 100644 --- a/gcc/sched-deps.cc +++ b/gcc/sched-deps.cc @@ -472,7 +472,7 @@ static int cache_size; /* True if we should mark added dependencies as a non-register deps. */ static bool mark_as_hard; -static int deps_may_trap_p (const_rtx); +static bool deps_may_trap_p (const_rtx); static void add_dependence_1 (rtx_insn *, rtx_insn *, enum reg_note); static void add_dependence_list (rtx_insn *, rtx_insn_list *, int, enum reg_note, bool); @@ -488,7 +488,7 @@ static void sched_analyze_2 (class deps_desc *, rtx, rtx_insn *); static void sched_analyze_insn (class deps_desc *, rtx, rtx_insn *); static bool sched_has_condition_p (const rtx_insn *); -static int conditions_mutex_p (const_rtx, const_rtx, bool, bool); +static bool conditions_mutex_p (const_rtx, const_rtx, bool, bool); static enum DEPS_ADJUST_RESULT maybe_add_or_update_dep_1 (dep_t, bool, rtx, rtx); @@ -497,9 +497,9 @@ static enum DEPS_ADJUST_RESULT add_or_update_dep_1 (dep_t, bool, rtx, rtx); static void check_dep (dep_t, bool); -/* Return nonzero if a load of the memory reference MEM can cause a trap. */ +/* Return true if a load of the memory reference MEM can cause a trap. */ -static int +static bool deps_may_trap_p (const_rtx mem) { const_rtx addr = XEXP (mem, 0); @@ -617,8 +617,8 @@ sched_has_condition_p (const rtx_insn *insn) -/* Return nonzero if conditions COND1 and COND2 can never be both true. */ -static int +/* Return true if conditions COND1 and COND2 can never be both true. */ +static bool conditions_mutex_p (const_rtx cond1, const_rtx cond2, bool rev1, bool rev2) { if (COMPARISON_P (cond1) @@ -629,8 +629,8 @@ conditions_mutex_p (const_rtx cond1, const_rtx cond2, bool rev1, bool rev2) : GET_CODE (cond2)) && rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0)) && XEXP (cond1, 1) == XEXP (cond2, 1)) - return 1; - return 0; + return true; + return false; } /* Return true if insn1 and insn2 can never depend on one another because diff --git a/gcc/sched-ebb.cc b/gcc/sched-ebb.cc index 3eb6a24..110fcdb 100644 --- a/gcc/sched-ebb.cc +++ b/gcc/sched-ebb.cc @@ -51,10 +51,10 @@ static basic_block last_bb; /* Implementations of the sched_info functions for region scheduling. */ static void init_ready_list (void); static void begin_schedule_ready (rtx_insn *); -static int schedule_more_p (void); +static bool schedule_more_p (void); static const char *ebb_print_insn (const rtx_insn *, int); static int rank (rtx_insn *, rtx_insn *); -static int ebb_contributes_to_priority (rtx_insn *, rtx_insn *); +static bool ebb_contributes_to_priority (rtx_insn *, rtx_insn *); static basic_block earliest_block_with_similiar_load (basic_block, rtx); static void add_deps_for_risky_insns (rtx_insn *, rtx_insn *); static void debug_ebb_dependencies (rtx_insn *, rtx_insn *); @@ -83,9 +83,9 @@ restore_ebb_state (void *p_) free (p_); } -/* Return nonzero if there are more insns that should be scheduled. */ +/* Return true if there are more insns that should be scheduled. */ -static int +static bool schedule_more_p (void) { return sched_rgn_n_insns < rgn_n_insns; @@ -238,14 +238,14 @@ rank (rtx_insn *insn1, rtx_insn *insn2) } /* NEXT is an instruction that depends on INSN (a backward dependence); - return nonzero if we should include this dependence in priority + return true if we should include this dependence in priority calculations. */ -static int +static bool ebb_contributes_to_priority (rtx_insn *next ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED) { - return 1; + return true; } /* INSN is a JUMP_INSN. Store the set of registers that diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 97b7d2d..64a2f0b 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -585,11 +585,11 @@ struct haifa_sched_info /* Add all insns that are initially ready to the ready list. Called once before scheduling a set of insns. */ void (*init_ready_list) (void); - /* Called after taking an insn from the ready list. Returns nonzero if - this insn can be scheduled, nonzero if we should silently discard it. */ - int (*can_schedule_ready_p) (rtx_insn *); - /* Return nonzero if there are more insns that should be scheduled. */ - int (*schedule_more_p) (void); + /* Called after taking an insn from the ready list. Returns true if + this insn can be scheduled, false if we should silently discard it. */ + bool (*can_schedule_ready_p) (rtx_insn *); + /* Return true if there are more insns that should be scheduled. */ + bool (*schedule_more_p) (void); /* Called after an insn has all its hard dependencies resolved. Adjusts status of instruction (which is passed through second parameter) to indicate if instruction should be moved to the ready list or the @@ -605,9 +605,9 @@ struct haifa_sched_info static buffer for this. The ALIGNED parameter should cause the string to be formatted so that multiple output lines will line up nicely. */ const char *(*print_insn) (const rtx_insn *, int); - /* Return nonzero if an insn should be included in priority + /* Return true if an insn should be included in priority calculations. */ - int (*contributes_to_priority) (rtx_insn *, rtx_insn *); + bool (*contributes_to_priority) (rtx_insn *, rtx_insn *); /* Return true if scheduling insn (passed as the parameter) will trigger finish of scheduling current block. */ @@ -1397,7 +1397,7 @@ extern void free_global_sched_pressure_data (void); extern int haifa_classify_insn (const_rtx); extern void get_ebb_head_tail (basic_block, basic_block, rtx_insn **, rtx_insn **); -extern int no_real_insns_p (const rtx_insn *, const rtx_insn *); +extern bool no_real_insns_p (const rtx_insn *, const rtx_insn *); extern int insn_sched_cost (rtx_insn *); extern int dep_cost_1 (dep_t, dw_t); @@ -1509,7 +1509,7 @@ extern void dump_rgn_dependencies_dot (FILE *); extern void dump_rgn_dependencies_dot (const char *); extern void free_rgn_deps (void); -extern int contributes_to_priority (rtx_insn *, rtx_insn *); +extern bool contributes_to_priority (rtx_insn *, rtx_insn *); extern void extend_rgns (int *, int *, sbitmap, int *); extern void deps_join (class deps_desc *, class deps_desc *); diff --git a/gcc/sched-rgn.cc b/gcc/sched-rgn.cc index f2751f6..e5964f5 100644 --- a/gcc/sched-rgn.cc +++ b/gcc/sched-rgn.cc @@ -82,7 +82,7 @@ along with GCC; see the file COPYING3. If not see /* nr_inter/spec counts interblock/speculative motion for the function. */ static int nr_inter, nr_spec; -static int is_cfg_nonregular (void); +static bool is_cfg_nonregular (void); /* Number of regions in the procedure. */ int nr_regions = 0; @@ -231,13 +231,13 @@ static edgeset *ancestor_edges; #define INSN_PROBABILITY(INSN) (SRC_PROB (BLOCK_TO_BB (BLOCK_NUM (INSN)))) /* Speculative scheduling functions. */ -static int check_live_1 (int, rtx); +static bool check_live_1 (int, rtx); static void update_live_1 (int, rtx); -static int is_pfree (rtx, int, int); -static int find_conditional_protection (rtx_insn *, int); -static int is_conditionally_protected (rtx, int, int); -static int is_prisky (rtx, int, int); -static int is_exception_free (rtx_insn *, int, int); +static bool is_pfree (rtx, int, int); +static bool find_conditional_protection (rtx_insn *, int); +static bool is_conditionally_protected (rtx, int, int); +static bool is_prisky (rtx, int, int); +static bool is_exception_free (rtx_insn *, int, int); static bool sets_likely_spilled (rtx); static void sets_likely_spilled_1 (rtx, const_rtx, void *); @@ -252,13 +252,14 @@ static void free_pending_lists (void); /* Functions for construction of the control flow graph. */ -/* Return 1 if control flow graph should not be constructed, 0 otherwise. +/* Return true if control flow graph should not be constructed, + false otherwise. We decide not to build the control flow graph if there is possibly more than one entry to the function, if computed branches exist, if we have nonlocal gotos, or if we have an unreachable loop. */ -static int +static bool is_cfg_nonregular (void) { basic_block b; @@ -267,17 +268,17 @@ is_cfg_nonregular (void) /* If we have a label that could be the target of a nonlocal goto, then the cfg is not well structured. */ if (nonlocal_goto_handler_labels) - return 1; + return true; /* If we have any forced labels, then the cfg is not well structured. */ if (forced_labels) - return 1; + return true; /* If we have exception handlers, then we consider the cfg not well structured. ?!? We should be able to handle this now that we compute an accurate cfg for EH. */ if (current_function_has_exception_handlers ()) - return 1; + return true; /* If we have insns which refer to labels as non-jumped-to operands, then we consider the cfg not well structured. */ @@ -290,7 +291,7 @@ is_cfg_nonregular (void) /* If this function has a computed jump, then we consider the cfg not well structured. */ if (JUMP_P (insn) && computed_jump_p (insn)) - return 1; + return true; if (!INSN_P (insn)) continue; @@ -310,15 +311,15 @@ is_cfg_nonregular (void) && find_reg_note (next, REG_LABEL_TARGET, XEXP (note, 0)) == NULL_RTX) || BLOCK_FOR_INSN (insn) != BLOCK_FOR_INSN (next)) - return 1; + return true; set = single_set (insn); if (set == NULL_RTX) - return 1; + return true; dest = SET_DEST (set); if (!REG_P (dest) || !dead_or_set_p (next, dest)) - return 1; + return true; } /* Unreachable loops with more than one basic block are detected @@ -332,11 +333,11 @@ is_cfg_nonregular (void) if (EDGE_COUNT (b->preds) == 0 || (single_pred_p (b) && single_pred (b) == b)) - return 1; + return true; } /* All the tests passed. Consider the cfg well structured. */ - return 0; + return false; } /* Extract list of edges from a bitmap containing EDGE_TO_BIT bits. */ @@ -627,8 +628,9 @@ haifa_find_rgns (void) int count = 0, sp, idx = 0; edge_iterator current_edge; edge_iterator *stack; - int num_bbs, num_insns, unreachable; - int too_large_failure; + int num_bbs, num_insns; + bool unreachable; + bool too_large_failure; basic_block bb; /* Perform a DFS traversal of the cfg. Identify loop headers, inner loops @@ -764,11 +766,11 @@ haifa_find_rgns (void) The DFS traversal will mark every block that is reachable from the entry node by placing a nonzero value in dfs_nr. Thus if dfs_nr is zero for any block, then it must be unreachable. */ - unreachable = 0; + unreachable = false; FOR_EACH_BB_FN (bb, cfun) if (dfs_nr[bb->index] == 0) { - unreachable = 1; + unreachable = true; break; } @@ -851,7 +853,7 @@ haifa_find_rgns (void) /* I is a header of an inner loop, or block 0 in a subroutine with no loops at all. */ head = tail = -1; - too_large_failure = 0; + too_large_failure = false; loop_head = max_hdr[bb->index]; if (extend_regions_p) @@ -888,7 +890,7 @@ haifa_find_rgns (void) if (too_large (jbb->index, &num_bbs, &num_insns)) { - too_large_failure = 1; + too_large_failure = true; break; } } @@ -912,7 +914,7 @@ haifa_find_rgns (void) if (too_large (node, &num_bbs, &num_insns)) { - too_large_failure = 1; + too_large_failure = true; break; } } @@ -974,7 +976,7 @@ haifa_find_rgns (void) if (too_large (node, &num_bbs, &num_insns)) { - too_large_failure = 1; + too_large_failure = true; break; } } @@ -1157,8 +1159,9 @@ print_region_statistics (int *s1, int s1_sz, int *s2, int s2_sz) void extend_rgns (int *degree, int *idxp, sbitmap header, int *loop_hdr) { - int *order, i, rescan = 0, idx = *idxp, iter = 0, max_iter, *max_hdr; + int *order, i, idx = *idxp, iter = 0, max_iter, *max_hdr; int nblocks = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; + bool rescan = false; max_iter = param_max_sched_extend_regions_iters; @@ -1173,7 +1176,7 @@ extend_rgns (int *degree, int *idxp, sbitmap header, int *loop_hdr) if (degree[bbn] >= 0) { max_hdr[bbn] = bbn; - rescan = 1; + rescan = true; } else /* This block already was processed in find_rgns. */ @@ -1193,7 +1196,7 @@ extend_rgns (int *degree, int *idxp, sbitmap header, int *loop_hdr) while (rescan && iter < max_iter) { - rescan = 0; + rescan = false; for (i = nblocks - 1; i >= 0; i--) { @@ -1241,7 +1244,7 @@ extend_rgns (int *degree, int *idxp, sbitmap header, int *loop_hdr) /* If BB start its own region, update set of headers with BB. */ bitmap_set_bit (header, bbn); - rescan = 1; + rescan = true; } else gcc_assert (hdr != -1); @@ -1658,10 +1661,10 @@ debug_candidates (int trg) static bitmap_head not_in_df; -/* Return 0 if x is a set of a register alive in the beginning of one - of the split-blocks of src, otherwise return 1. */ +/* Return false if x is a set of a register alive in the beginning of one + of the split-blocks of src, otherwise return true. */ -static int +static bool check_live_1 (int src, rtx x) { int i; @@ -1669,7 +1672,7 @@ check_live_1 (int src, rtx x) rtx reg = SET_DEST (x); if (reg == 0) - return 1; + return true; while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT @@ -1683,20 +1686,20 @@ check_live_1 (int src, rtx x) for (i = XVECLEN (reg, 0) - 1; i >= 0; i--) if (XEXP (XVECEXP (reg, 0, i), 0) != 0) if (check_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0))) - return 1; + return true; - return 0; + return false; } if (!REG_P (reg)) - return 1; + return true; regno = REGNO (reg); if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno]) { /* Global registers are assumed live. */ - return 0; + return false; } else { @@ -1717,7 +1720,7 @@ check_live_1 (int src, rtx x) != CONTAINING_RGN (BB_TO_BLOCK (src)))); if (t || REGNO_REG_SET_P (df_get_live_in (b), regno + j)) - return 0; + return false; } } } @@ -1733,12 +1736,12 @@ check_live_1 (int src, rtx x) != CONTAINING_RGN (BB_TO_BLOCK (src)))); if (t || REGNO_REG_SET_P (df_get_live_in (b), regno)) - return 0; + return false; } } } - return 1; + return true; } /* If x is a set of a register R, mark that R is alive in the beginning @@ -1789,11 +1792,11 @@ update_live_1 (int src, rtx x) } } -/* Return 1 if insn can be speculatively moved from block src to trg, - otherwise return 0. Called before first insertion of insn to +/* Return true if insn can be speculatively moved from block src to trg, + otherwise return false. Called before first insertion of insn to ready-list or before the scheduling. */ -static int +static bool check_live (rtx_insn *insn, int src) { /* Find the registers set by instruction. */ @@ -1807,12 +1810,12 @@ check_live (rtx_insn *insn, int src) if ((GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER) && !check_live_1 (src, XVECEXP (PATTERN (insn), 0, j))) - return 0; + return false; - return 1; + return true; } - return 1; + return true; } /* Update the live registers info after insn was moved speculatively from @@ -1835,13 +1838,15 @@ update_live (rtx_insn *insn, int src) } } -/* Nonzero if block bb_to is equal to, or reachable from block bb_from. */ +/* True if block bb_to is equal to, or reachable from block bb_from. */ #define IS_REACHABLE(bb_from, bb_to) \ (bb_from == bb_to \ || IS_RGN_ENTRY (bb_from) \ - || (bitmap_bit_p (ancestor_edges[bb_to], \ - EDGE_TO_BIT (single_pred_edge (BASIC_BLOCK_FOR_FN (cfun, \ - BB_TO_BLOCK (bb_from))))))) + || (bitmap_bit_p \ + (ancestor_edges[bb_to], \ + EDGE_TO_BIT (single_pred_edge \ + (BASIC_BLOCK_FOR_FN (cfun, \ + BB_TO_BLOCK (bb_from))))))) /* Turns on the fed_by_spec_load flag for insns fed by load_insn. */ @@ -1857,9 +1862,9 @@ set_spec_fed (rtx load_insn) } /* On the path from the insn to load_insn_bb, find a conditional -branch depending on insn, that guards the speculative load. */ + branch depending on insn, that guards the speculative load. */ -static int +static bool find_conditional_protection (rtx_insn *insn, int load_insn_bb) { sd_iterator_def sd_it; @@ -1877,12 +1882,12 @@ find_conditional_protection (rtx_insn *insn, int load_insn_bb) && DEP_TYPE (dep) == REG_DEP_TRUE && (JUMP_P (next) || find_conditional_protection (next, load_insn_bb))) - return 1; + return true; } - return 0; + return false; } /* find_conditional_protection */ -/* Returns 1 if the same insn1 that participates in the computation +/* Returns true if the same insn1 that participates in the computation of load_insn's address is feeding a conditional branch that is guarding on load_insn. This is true if we find two DEF-USE chains: @@ -1896,7 +1901,7 @@ find_conditional_protection (rtx_insn *insn, int load_insn_bb) Locate insn1 by climbing on INSN_BACK_DEPS from load_insn. Locate the branch by following INSN_FORW_DEPS from insn1. */ -static int +static bool is_conditionally_protected (rtx load_insn, int bb_src, int bb_trg) { sd_iterator_def sd_it; @@ -1921,17 +1926,17 @@ is_conditionally_protected (rtx load_insn, int bb_src, int bb_trg) /* Now search for the conditional-branch. */ if (find_conditional_protection (insn1, bb_src)) - return 1; + return true; /* Recursive step: search another insn1, "above" current insn1. */ return is_conditionally_protected (insn1, bb_src, bb_trg); } /* The chain does not exist. */ - return 0; + return false; } /* is_conditionally_protected */ -/* Returns 1 if a clue for "similar load" 'insn2' is found, and hence +/* Returns true if a clue for "similar load" 'insn2' is found, and hence load_insn can move speculatively from bb_src to bb_trg. All the following must hold: @@ -1947,7 +1952,7 @@ is_conditionally_protected (rtx load_insn, int bb_src, int bb_trg) load_insn would cause an exception, it would have been caused by load2 anyhow. */ -static int +static bool is_pfree (rtx load_insn, int bb_src, int bb_trg) { sd_iterator_def back_sd_it; @@ -1956,7 +1961,7 @@ is_pfree (rtx load_insn, int bb_src, int bb_trg) if (candp->split_bbs.nr_members != 1) /* Must have exactly one escape block. */ - return 0; + return false; FOR_EACH_DEP (load_insn, SD_LIST_BACK, back_sd_it, back_dep) { @@ -1981,45 +1986,45 @@ is_pfree (rtx load_insn, int bb_src, int bb_trg) if (INSN_BB (insn2) == bb_trg) /* insn2 is the similar load, in the target block. */ - return 1; + return true; if (*(candp->split_bbs.first_member) == BLOCK_FOR_INSN (insn2)) /* insn2 is a similar load, in a split-block. */ - return 1; + return true; } } } } /* Couldn't find a similar load. */ - return 0; + return false; } /* is_pfree */ -/* Return 1 if load_insn is prisky (i.e. if load_insn is fed by +/* Return true if load_insn is prisky (i.e. if load_insn is fed by a load moved speculatively, or if load_insn is protected by a compare on load_insn's address). */ -static int +static bool is_prisky (rtx load_insn, int bb_src, int bb_trg) { if (FED_BY_SPEC_LOAD (load_insn)) - return 1; + return true; if (sd_lists_empty_p (load_insn, SD_LIST_BACK)) /* Dependence may 'hide' out of the region. */ - return 1; + return true; if (is_conditionally_protected (load_insn, bb_src, bb_trg)) - return 1; + return true; - return 0; + return false; } /* Insn is a candidate to be moved speculatively from bb_src to bb_trg. - Return 1 if insn is exception-free (and the motion is valid) - and 0 otherwise. */ + Return true if insn is exception-free (and the motion is valid) + and false otherwise. */ -static int +static bool is_exception_free (rtx_insn *insn, int bb_src, int bb_trg) { int insn_class = haifa_classify_insn (insn); @@ -2028,31 +2033,31 @@ is_exception_free (rtx_insn *insn, int bb_src, int bb_trg) switch (insn_class) { case TRAP_FREE: - return 1; + return true; case TRAP_RISKY: - return 0; + return false; default:; } /* Handle loads. */ if (!flag_schedule_speculative_load) - return 0; + return false; IS_LOAD_INSN (insn) = 1; switch (insn_class) { case IFREE: - return (1); + return true; case IRISKY: - return 0; + return false; case PFREE_CANDIDATE: if (is_pfree (insn, bb_src, bb_trg)) - return 1; + return true; /* Don't 'break' here: PFREE-candidate is also PRISKY-candidate. */ /* FALLTHRU */ case PRISKY_CANDIDATE: if (!flag_schedule_speculative_load_dangerous || is_prisky (insn, bb_src, bb_trg)) - return 0; + return false; break; default:; } @@ -2069,10 +2074,10 @@ static int sched_n_insns; /* Implementations of the sched_info functions for region scheduling. */ static void init_ready_list (void); -static int can_schedule_ready_p (rtx_insn *); +static bool can_schedule_ready_p (rtx_insn *); static void begin_schedule_ready (rtx_insn *); static ds_t new_ready (rtx_insn *, ds_t); -static int schedule_more_p (void); +static bool schedule_more_p (void); static const char *rgn_print_insn (const rtx_insn *, int); static int rgn_rank (rtx_insn *, rtx_insn *); static void compute_jump_reg_dependencies (rtx, regset); @@ -2083,9 +2088,9 @@ static void rgn_add_block (basic_block, basic_block); static void rgn_fix_recovery_cfg (int, int, int); static basic_block advance_target_bb (basic_block, rtx_insn *); -/* Return nonzero if there are more insns that should be scheduled. */ +/* Return true if there are more insns that should be scheduled. */ -static int +static bool schedule_more_p (void) { return sched_target_n_insns < target_n_insns; @@ -2151,10 +2156,10 @@ init_ready_list (void) } } -/* Called after taking INSN from the ready list. Returns nonzero if this +/* Called after taking INSN from the ready list. Returns true if this insn can be scheduled, nonzero if we should silently discard it. */ -static int +static bool can_schedule_ready_p (rtx_insn *insn) { /* An interblock motion? */ @@ -2162,15 +2167,15 @@ can_schedule_ready_p (rtx_insn *insn) { /* Cannot schedule this insn unless all operands are live. */ if (!check_live (insn, INSN_BB (insn))) - return 0; + return false; /* Should not move expensive instructions speculatively. */ if (GET_CODE (PATTERN (insn)) != CLOBBER && !targetm.sched.can_speculate_insn (insn)) - return 0; + return false; } - return 1; + return true; } /* Updates counter and other information. Split from can_schedule_ready_p () @@ -2311,10 +2316,10 @@ rgn_rank (rtx_insn *insn1, rtx_insn *insn2) } /* NEXT is an instruction that depends on INSN (a backward dependence); - return nonzero if we should include this dependence in priority + return true if we should include this dependence in priority calculations. */ -int +bool contributes_to_priority (rtx_insn *next, rtx_insn *insn) { /* NEXT and INSN reside in one ebb. */ -- cgit v1.1 From 1ee710027d8aa16145dab623815d9f9921cf9633 Mon Sep 17 00:00:00 2001 From: Filip Kastl Date: Wed, 5 Jul 2023 17:36:02 +0200 Subject: value-prof.cc: Correct edge prob calculation. The mod-subtract optimization with ncounts==1 produced incorrect edge probabilities due to incorrect conditional probability calculation. This patch fixes the calculation. Signed-off-by: Filip Kastl gcc/ChangeLog: * value-prof.cc (gimple_mod_subtract_transform): Correct edge prob calculation. --- gcc/value-prof.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/value-prof.cc b/gcc/value-prof.cc index f40e58a..5033a6f 100644 --- a/gcc/value-prof.cc +++ b/gcc/value-prof.cc @@ -1186,7 +1186,11 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si) if (all > 0) { prob1 = profile_probability::probability_in_gcov_type (count1, all); - prob2 = profile_probability::probability_in_gcov_type (count2, all); + if (all == count1) + prob2 = profile_probability::even (); + else + prob2 = profile_probability::probability_in_gcov_type (count2, all + - count1); } else { -- cgit v1.1 From be240fc6acc9714e66afbfbe6dc193844bfcba05 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 3 Jul 2023 17:20:30 +0100 Subject: doc: Update my Contributors entry gcc/ChangeLog: * doc/contrib.texi (Contributors): Update my entry. --- gcc/doc/contrib.texi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi index 758805d..fa551c5 100644 --- a/gcc/doc/contrib.texi +++ b/gcc/doc/contrib.texi @@ -1095,8 +1095,7 @@ Todd Vierling for contributions for NetBSD ports. Andrew Waterman for contributing the RISC-V port, as well as maintaining it. @item -Jonathan Wakely for contributing libstdc++ Doxygen notes and XHTML -guidance and maintaining libstdc++. +Jonathan Wakely for contributing to and maintaining libstdc++. @item Dean Wakerley for converting the install documentation from HTML to texinfo -- cgit v1.1 From 70d1e3f40f09102c6b12c58d97809552b1a08961 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 4 Jul 2023 11:28:52 -0400 Subject: Move relation discovery into compute_operand_range compute_operand1_range and compute_operand2_range were both doing relation discovery between the 2 operands... move it into a common area. * gimple-range-gori.cc (compute_operand_range): Check for a relation between op1 and op2 and use that instead. (compute_operand1_range): Don't look for a relation override. (compute_operand2_range): Ditto. --- gcc/gimple-range-gori.cc | 42 +++++++++++++----------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 4ee0ae3..b0d13a8 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -623,6 +623,18 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, tree op1 = gimple_range_ssa_p (handler.operand1 ()); tree op2 = gimple_range_ssa_p (handler.operand2 ()); + // If there is a relation betwen op1 and op2, use it instead as it is + // likely to be more applicable. + if (op1 && op2) + { + relation_kind k = handler.op1_op2_relation (lhs); + if (k != VREL_VARYING) + { + vrel.set_relation (k, op1, op2); + vrel_ptr = &vrel; + } + } + // Handle end of lookup first. if (op1 == name) return compute_operand1_range (r, handler, lhs, name, src, vrel_ptr); @@ -1079,7 +1091,6 @@ gori_compute::compute_operand1_range (vrange &r, const vrange &lhs, tree name, fur_source &src, value_relation *rel) { - value_relation local_rel; gimple *stmt = handler.stmt (); tree op1 = handler.operand1 (); tree op2 = handler.operand2 (); @@ -1088,7 +1099,6 @@ gori_compute::compute_operand1_range (vrange &r, relation_trio trio; if (rel) trio = rel->create_trio (lhs_name, op1, op2); - relation_kind op_op = trio.op1_op2 (); Value_Range op1_range (TREE_TYPE (op1)); Value_Range tmp (TREE_TYPE (op1)); @@ -1102,19 +1112,7 @@ gori_compute::compute_operand1_range (vrange &r, { src.get_operand (op2_range, op2); - // If there is a relation betwen op1 and op2, use it instead. - // This allows multiple relations to be processed in compound logicals. - if (gimple_range_ssa_p (op1) && gimple_range_ssa_p (op2)) - { - relation_kind k = handler.op1_op2_relation (lhs); - if (k != VREL_VARYING) - { - op_op = k; - local_rel.set_relation (op_op, op1, op2); - rel = &local_rel; - } - } - + relation_kind op_op = trio.op1_op2 (); if (op_op != VREL_VARYING) refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); @@ -1189,7 +1187,6 @@ gori_compute::compute_operand2_range (vrange &r, const vrange &lhs, tree name, fur_source &src, value_relation *rel) { - value_relation local_rel; gimple *stmt = handler.stmt (); tree op1 = handler.operand1 (); tree op2 = handler.operand2 (); @@ -1207,19 +1204,6 @@ gori_compute::compute_operand2_range (vrange &r, trio = rel->create_trio (lhs_name, op1, op2); relation_kind op_op = trio.op1_op2 (); - // If there is a relation betwen op1 and op2, use it instead. - // This allows multiple relations to be processed in compound logicals. - if (gimple_range_ssa_p (op1) && gimple_range_ssa_p (op2)) - { - relation_kind k = handler.op1_op2_relation (lhs); - if (k != VREL_VARYING) - { - op_op = k; - local_rel.set_relation (op_op, op1, op2); - rel = &local_rel; - } - } - if (op_op != VREL_VARYING) refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); -- cgit v1.1 From f0375705613675ab13cd211e93a1d620be8bf03f Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 5 Jul 2023 13:36:27 -0400 Subject: Simplify compute_operand_range for op1 and op2 case. Move the check for co-dependency between 2 operands into compute_operand_range, resulting in a much cleaner compute_operand1_and_operand2_range routine. * gimple-range-gori.cc (compute_operand_range): Check for operand interdependence when both op1 and op2 are computed. (compute_operand1_and_operand2_range): No checks required now. --- gcc/gimple-range-gori.cc | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index b0d13a8..5429c6e 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -650,6 +650,17 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, if (!op1_in_chain && !op2_in_chain) return false; + // If either operand is in the def chain of the other (or they are equal), it + // will be evaluated twice and can result in an exponential time calculation. + // Instead just evaluate the one operand. + if (op1_in_chain && op2_in_chain) + { + if (in_chain_p (op1, op2) || op1 == op2) + op1_in_chain = false; + else if (in_chain_p (op2, op1)) + op2_in_chain = false; + } + bool res = false; // If the lhs doesn't tell us anything only a relation can possibly enhance // the result. @@ -1275,24 +1286,10 @@ gori_compute::compute_operand1_and_operand2_range (vrange &r, { Value_Range op_range (TREE_TYPE (name)); - // If op1 is in the def chain of op2, we'll do the work twice to evalaute - // op1. This can result in an exponential time calculation. - // Instead just evaluate op2, which will eventualy get to op1. - if (in_chain_p (handler.operand1 (), handler.operand2 ())) - return compute_operand2_range (r, handler, lhs, name, src, rel); - - // Likewise if op2 is in the def chain of op1. - if (in_chain_p (handler.operand2 (), handler.operand1 ())) - return compute_operand1_range (r, handler, lhs, name, src, rel); - // Calculate a good a range through op2. if (!compute_operand2_range (r, handler, lhs, name, src, rel)) return false; - // If op1 == op2 there is again no need to go further. - if (handler.operand1 () == handler.operand2 ()) - return true; - // Now get the range thru op1. if (!compute_operand1_range (op_range, handler, lhs, name, src, rel)) return false; -- cgit v1.1 From 018e7f16408022dbea9d2d4570150ce823117e08 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 5 Jul 2023 13:41:50 -0400 Subject: Make compute_operand1_range a leaf call. Rather than creating long call chains, put the onus for finishing the evlaution on the caller. * gimple-range-gori.cc (compute_operand_range): After calling compute_operand1_range, recursively call self if needed. (compute_operand1_range): Turn into a leaf function. (gori_compute::compute_operand1_and_operand2_range): Finish operand1 calculation. * gimple-range-gori.h (compute_operand1_range): Remove name param. --- gcc/gimple-range-gori.cc | 49 ++++++++++++++++++++++++------------------------ gcc/gimple-range-gori.h | 2 +- 2 files changed, 25 insertions(+), 26 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 5429c6e..b66b9b0 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -637,7 +637,7 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, // Handle end of lookup first. if (op1 == name) - return compute_operand1_range (r, handler, lhs, name, src, vrel_ptr); + return compute_operand1_range (r, handler, lhs, src, vrel_ptr); if (op2 == name) return compute_operand2_range (r, handler, lhs, name, src, vrel_ptr); @@ -731,7 +731,15 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, res = compute_operand1_and_operand2_range (r, handler, lhs, name, src, vrel_ptr); else if (op1_in_chain) - res = compute_operand1_range (r, handler, lhs, name, src, vrel_ptr); + { + Value_Range vr (TREE_TYPE (op1)); + if (!compute_operand1_range (vr, handler, lhs, src, vrel_ptr)) + return false; + gimple *src_stmt = SSA_NAME_DEF_STMT (op1); + gcc_checking_assert (src_stmt); + // Then feed this range back as the LHS of the defining statement. + return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr); + } else if (op2_in_chain) res = compute_operand2_range (r, handler, lhs, name, src, vrel_ptr); else @@ -1099,7 +1107,7 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range, bool gori_compute::compute_operand1_range (vrange &r, gimple_range_op_handler &handler, - const vrange &lhs, tree name, + const vrange &lhs, fur_source &src, value_relation *rel) { gimple *stmt = handler.stmt (); @@ -1112,7 +1120,6 @@ gori_compute::compute_operand1_range (vrange &r, trio = rel->create_trio (lhs_name, op1, op2); Value_Range op1_range (TREE_TYPE (op1)); - Value_Range tmp (TREE_TYPE (op1)); Value_Range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1)); // Fetch the known range for op1 in this block. @@ -1130,7 +1137,7 @@ gori_compute::compute_operand1_range (vrange &r, // If op1 == op2, create a new trio for just this call. if (op1 == op2 && gimple_range_ssa_p (op1)) trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ); - if (!handler.calc_op1 (tmp, lhs, op2_range, trio)) + if (!handler.calc_op1 (r, lhs, op2_range, trio)) return false; } else @@ -1138,7 +1145,7 @@ gori_compute::compute_operand1_range (vrange &r, // We pass op1_range to the unary operation. Normally it's a // hidden range_for_type parameter, but sometimes having the // actual range can result in better information. - if (!handler.calc_op1 (tmp, lhs, op1_range, trio)) + if (!handler.calc_op1 (r, lhs, op1_range, trio)) return false; } @@ -1161,30 +1168,16 @@ gori_compute::compute_operand1_range (vrange &r, tracer.print (idx, "Computes "); print_generic_expr (dump_file, op1, TDF_SLIM); fprintf (dump_file, " = "); - tmp.dump (dump_file); + r.dump (dump_file); fprintf (dump_file, " intersect Known range : "); op1_range.dump (dump_file); fputc ('\n', dump_file); } - // Intersect the calculated result with the known result and return if done. - if (op1 == name) - { - tmp.intersect (op1_range); - r = tmp; - if (idx) - tracer.trailer (idx, "produces ", true, name, r); - return true; - } - // If the calculation continues, we're using op1_range as the new LHS. - op1_range.intersect (tmp); + r.intersect (op1_range); if (idx) - tracer.trailer (idx, "produces ", true, op1, op1_range); - gimple *src_stmt = SSA_NAME_DEF_STMT (op1); - gcc_checking_assert (src_stmt); - - // Then feed this range back as the LHS of the defining statement. - return compute_operand_range (r, src_stmt, op1_range, name, src, rel); + tracer.trailer (idx, "produces ", true, op1, r); + return true; } @@ -1291,7 +1284,13 @@ gori_compute::compute_operand1_and_operand2_range (vrange &r, return false; // Now get the range thru op1. - if (!compute_operand1_range (op_range, handler, lhs, name, src, rel)) + Value_Range vr (TREE_TYPE (handler.operand1 ())); + if (!compute_operand1_range (vr, handler, lhs, src, rel)) + return false; + gimple *src_stmt = SSA_NAME_DEF_STMT (handler.operand1 ()); + gcc_checking_assert (src_stmt); + // Then feed this range back as the LHS of the defining statement. + if (!compute_operand_range (op_range, src_stmt, vr, name, src, rel)) return false; // Both operands have to be simultaneously true, so perform an intersection. diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 526edc2..1d451fa 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -183,7 +183,7 @@ private: bool compute_operand_range_switch (vrange &r, gswitch *s, const vrange &lhs, tree name, fur_source &src); bool compute_operand1_range (vrange &r, gimple_range_op_handler &handler, - const vrange &lhs, tree name, fur_source &src, + const vrange &lhs, fur_source &src, value_relation *rel = NULL); bool compute_operand2_range (vrange &r, gimple_range_op_handler &handler, const vrange &lhs, tree name, fur_source &src, -- cgit v1.1 From 988b07a66a96d70c47f697dd0d07c0e14c742451 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 5 Jul 2023 13:52:21 -0400 Subject: Make compute_operand2_range a leaf call. Rather than creating long call chains, put the onus for finishing the evlaution on the caller. * gimple-range-gori.cc (compute_operand_range): After calling compute_operand2_range, recursively call self if needed. (compute_operand2_range): Turn into a leaf function. (gori_compute::compute_operand1_and_operand2_range): Finish operand2 calculation. * gimple-range-gori.h (compute_operand2_range): Remove name param. --- gcc/gimple-range-gori.cc | 52 +++++++++++++++++++++++------------------------- gcc/gimple-range-gori.h | 2 +- 2 files changed, 26 insertions(+), 28 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index b66b9b0..b036ed5 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -639,7 +639,7 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, if (op1 == name) return compute_operand1_range (r, handler, lhs, src, vrel_ptr); if (op2 == name) - return compute_operand2_range (r, handler, lhs, name, src, vrel_ptr); + return compute_operand2_range (r, handler, lhs, src, vrel_ptr); // NAME is not in this stmt, but one of the names in it ought to be // derived from it. @@ -741,7 +741,15 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr); } else if (op2_in_chain) - res = compute_operand2_range (r, handler, lhs, name, src, vrel_ptr); + { + Value_Range vr (TREE_TYPE (op2)); + if (!compute_operand2_range (vr, handler, lhs, src, vrel_ptr)) + return false; + gimple *src_stmt = SSA_NAME_DEF_STMT (op2); + gcc_checking_assert (src_stmt); + // Then feed this range back as the LHS of the defining statement. + return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr); + } else gcc_unreachable (); @@ -1188,7 +1196,7 @@ gori_compute::compute_operand1_range (vrange &r, bool gori_compute::compute_operand2_range (vrange &r, gimple_range_op_handler &handler, - const vrange &lhs, tree name, + const vrange &lhs, fur_source &src, value_relation *rel) { gimple *stmt = handler.stmt (); @@ -1198,7 +1206,6 @@ gori_compute::compute_operand2_range (vrange &r, Value_Range op1_range (TREE_TYPE (op1)); Value_Range op2_range (TREE_TYPE (op2)); - Value_Range tmp (TREE_TYPE (op2)); src.get_operand (op1_range, op1); src.get_operand (op2_range, op2); @@ -1215,7 +1222,7 @@ gori_compute::compute_operand2_range (vrange &r, if (op1 == op2 && gimple_range_ssa_p (op1)) trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ); // Intersect with range for op2 based on lhs and op1. - if (!handler.calc_op2 (tmp, lhs, op1_range, trio)) + if (!handler.calc_op2 (r, lhs, op1_range, trio)) return false; unsigned idx; @@ -1237,31 +1244,16 @@ gori_compute::compute_operand2_range (vrange &r, tracer.print (idx, "Computes "); print_generic_expr (dump_file, op2, TDF_SLIM); fprintf (dump_file, " = "); - tmp.dump (dump_file); + r.dump (dump_file); fprintf (dump_file, " intersect Known range : "); op2_range.dump (dump_file); fputc ('\n', dump_file); } // Intersect the calculated result with the known result and return if done. - if (op2 == name) - { - tmp.intersect (op2_range); - r = tmp; - if (idx) - tracer.trailer (idx, " produces ", true, NULL_TREE, r); - return true; - } - // If the calculation continues, we're using op2_range as the new LHS. - op2_range.intersect (tmp); - + r.intersect (op2_range); if (idx) - tracer.trailer (idx, " produces ", true, op2, op2_range); - gimple *src_stmt = SSA_NAME_DEF_STMT (op2); - gcc_checking_assert (src_stmt); -// gcc_checking_assert (!is_import_p (op2, find.bb)); - - // Then feed this range back as the LHS of the defining statement. - return compute_operand_range (r, src_stmt, op2_range, name, src, rel); + tracer.trailer (idx, " produces ", true, op2, r); + return true; } // Calculate a range for NAME from both operand positions of S @@ -1279,15 +1271,21 @@ gori_compute::compute_operand1_and_operand2_range (vrange &r, { Value_Range op_range (TREE_TYPE (name)); + Value_Range vr (TREE_TYPE (handler.operand2 ())); // Calculate a good a range through op2. - if (!compute_operand2_range (r, handler, lhs, name, src, rel)) + if (!compute_operand2_range (vr, handler, lhs, src, rel)) + return false; + gimple *src_stmt = SSA_NAME_DEF_STMT (handler.operand2 ()); + gcc_checking_assert (src_stmt); + // Then feed this range back as the LHS of the defining statement. + if (!compute_operand_range (r, src_stmt, vr, name, src, rel)) return false; // Now get the range thru op1. - Value_Range vr (TREE_TYPE (handler.operand1 ())); + vr.set_type (TREE_TYPE (handler.operand1 ())); if (!compute_operand1_range (vr, handler, lhs, src, rel)) return false; - gimple *src_stmt = SSA_NAME_DEF_STMT (handler.operand1 ()); + src_stmt = SSA_NAME_DEF_STMT (handler.operand1 ()); gcc_checking_assert (src_stmt); // Then feed this range back as the LHS of the defining statement. if (!compute_operand_range (op_range, src_stmt, vr, name, src, rel)) diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 1d451fa..b8d97d1 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -186,7 +186,7 @@ private: const vrange &lhs, fur_source &src, value_relation *rel = NULL); bool compute_operand2_range (vrange &r, gimple_range_op_handler &handler, - const vrange &lhs, tree name, fur_source &src, + const vrange &lhs, fur_source &src, value_relation *rel = NULL); bool compute_operand1_and_operand2_range (vrange &r, gimple_range_op_handler &handler, -- cgit v1.1 From 778099c426d7162000f1ed8d2937488e54021b75 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 5 Jul 2023 14:26:00 -0400 Subject: Make compute_operand_range a tail call. Tweak the routine so it is making a tail call. * gimple-range-gori.cc (compute_operand_range): Convert to a tail call. --- gcc/gimple-range-gori.cc | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index b036ed5..6dc15a0 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -725,36 +725,34 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, op1_trange, op1_frange, op2_trange, op2_frange); if (idx) tracer.trailer (idx, "compute_operand", res, name, r); + return res; } // Follow the appropriate operands now. - else if (op1_in_chain && op2_in_chain) - res = compute_operand1_and_operand2_range (r, handler, lhs, name, src, - vrel_ptr); - else if (op1_in_chain) + if (op1_in_chain && op2_in_chain) + return compute_operand1_and_operand2_range (r, handler, lhs, name, src, + vrel_ptr); + Value_Range vr; + gimple *src_stmt; + if (op1_in_chain) { - Value_Range vr (TREE_TYPE (op1)); + vr.set_type (TREE_TYPE (op1)); if (!compute_operand1_range (vr, handler, lhs, src, vrel_ptr)) return false; - gimple *src_stmt = SSA_NAME_DEF_STMT (op1); - gcc_checking_assert (src_stmt); - // Then feed this range back as the LHS of the defining statement. - return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr); + src_stmt = SSA_NAME_DEF_STMT (op1); } - else if (op2_in_chain) + else { - Value_Range vr (TREE_TYPE (op2)); + gcc_checking_assert (op2_in_chain); + vr.set_type (TREE_TYPE (op2)); if (!compute_operand2_range (vr, handler, lhs, src, vrel_ptr)) return false; - gimple *src_stmt = SSA_NAME_DEF_STMT (op2); - gcc_checking_assert (src_stmt); - // Then feed this range back as the LHS of the defining statement. - return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr); + src_stmt = SSA_NAME_DEF_STMT (op2); } - else - gcc_unreachable (); + gcc_checking_assert (src_stmt); + // Then feed this range back as the LHS of the defining statement. + return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr); // If neither operand is derived, this statement tells us nothing. - return res; } -- cgit v1.1 From 5158918aa211ee85176c058831707dbb3eaf0fb4 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 6 Jul 2023 00:17:51 +0000 Subject: Daily bump. --- gcc/ChangeLog | 257 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/c-family/ChangeLog | 5 + gcc/fortran/ChangeLog | 5 + gcc/go/ChangeLog | 5 + gcc/lto/ChangeLog | 5 + gcc/rust/ChangeLog | 5 + gcc/testsuite/ChangeLog | 107 ++++++++++++++++++++ 8 files changed, 390 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9e0bdab..6236e9d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,260 @@ +2023-07-05 Andrew MacLeod + + * gimple-range-gori.cc (compute_operand_range): Convert to a tail + call. + +2023-07-05 Andrew MacLeod + + * gimple-range-gori.cc (compute_operand_range): After calling + compute_operand2_range, recursively call self if needed. + (compute_operand2_range): Turn into a leaf function. + (gori_compute::compute_operand1_and_operand2_range): Finish + operand2 calculation. + * gimple-range-gori.h (compute_operand2_range): Remove name param. + +2023-07-05 Andrew MacLeod + + * gimple-range-gori.cc (compute_operand_range): After calling + compute_operand1_range, recursively call self if needed. + (compute_operand1_range): Turn into a leaf function. + (gori_compute::compute_operand1_and_operand2_range): Finish + operand1 calculation. + * gimple-range-gori.h (compute_operand1_range): Remove name param. + +2023-07-05 Andrew MacLeod + + * gimple-range-gori.cc (compute_operand_range): Check for + operand interdependence when both op1 and op2 are computed. + (compute_operand1_and_operand2_range): No checks required now. + +2023-07-05 Andrew MacLeod + + * gimple-range-gori.cc (compute_operand_range): Check for + a relation between op1 and op2 and use that instead. + (compute_operand1_range): Don't look for a relation override. + (compute_operand2_range): Ditto. + +2023-07-05 Jonathan Wakely + + * doc/contrib.texi (Contributors): Update my entry. + +2023-07-05 Filip Kastl + + * value-prof.cc (gimple_mod_subtract_transform): Correct edge + prob calculation. + +2023-07-05 Uros Bizjak + + * sched-int.h (struct haifa_sched_info): Change can_schedule_ready_p, + scehdule_more_p and contributes_to_priority indirect frunction + type from int to bool. + (no_real_insns_p): Change return type from int to bool. + (contributes_to_priority): Ditto. + * haifa-sched.cc (no_real_insns_p): Change return type from + int to bool and adjust function body accordingly. + * modulo-sched.cc (try_scheduling_node_in_cycle): Change "success" + variable type from int to bool. + (ps_insn_advance_column): Change return type from int to bool. + (ps_has_conflicts): Ditto. Change "has_conflicts" + variable type from int to bool. + * sched-deps.cc (deps_may_trap_p): Change return type from int to bool. + (conditions_mutex_p): Ditto. + * sched-ebb.cc (schedule_more_p): Ditto. + (ebb_contributes_to_priority): Change return type from + int to bool and adjust function body accordingly. + * sched-rgn.cc (is_cfg_nonregular): Ditto. + (check_live_1): Ditto. + (is_pfree): Ditto. + (find_conditional_protection): Ditto. + (is_conditionally_protected): Ditto. + (is_prisky): Ditto. + (is_exception_free): Ditto. + (haifa_find_rgns): Change "unreachable" and "too_large_failure" + variables from int to bool. + (extend_rgns): Change "rescan" variable from int to bool. + (check_live): Change return type from + int to bool and adjust function body accordingly. + (can_schedule_ready_p): Ditto. + (schedule_more_p): Ditto. + (contributes_to_priority): Ditto. + +2023-07-05 Robin Dapp + + * doc/md.texi: Document that vec_set and vec_extract must not + fail. + * gimple-isel.cc (gimple_expand_vec_set_expr): Rename this... + (gimple_expand_vec_set_extract_expr): ...to this. + (gimple_expand_vec_exprs): Call renamed function. + * internal-fn.cc (vec_extract_direct): Add. + (expand_vec_extract_optab_fn): New function to expand + vec_extract optab. + (direct_vec_extract_optab_supported_p): Add. + * internal-fn.def (VEC_EXTRACT): Add. + * optabs.cc (can_vec_extract_var_idx_p): New function. + * optabs.h (can_vec_extract_var_idx_p): Declare. + +2023-07-05 Robin Dapp + + * config/riscv/autovec.md: Add gen_lowpart. + +2023-07-05 Robin Dapp + + * config/riscv/autovec.md: Allow register index operand. + +2023-07-05 Pan Li + + * config/riscv/riscv-vector-builtins.cc + (function_expander::use_exact_insn): Use FRM_DYN instead of const0. + +2023-07-05 Robin Dapp + + * config/riscv/autovec.md: Use float_truncate. + +2023-07-05 Ju-Zhe Zhong + + * internal-fn.cc (internal_fn_len_index): Apply + LEN_MASK_GATHER_LOAD/SCATTER_STORE into vectorizer. + (internal_fn_mask_index): Ditto. + * optabs-query.cc (supports_vec_gather_load_p): Ditto. + (supports_vec_scatter_store_p): Ditto. + * tree-vect-data-refs.cc (vect_gather_scatter_fn_p): Ditto. + * tree-vect-patterns.cc (vect_recog_gather_scatter_pattern): Ditto. + * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Ditto. + (vect_get_strided_load_store_ops): Ditto. + (vectorizable_store): Ditto. + (vectorizable_load): Ditto. + +2023-07-05 Robin Dapp + Juzhe-Zhong + + * simplify-rtx.cc (native_encode_rtx): Ditto. + (native_decode_vector_rtx): Ditto. + (simplify_const_vector_byte_offset): Ditto. + (simplify_const_vector_subreg): Ditto. + * tree.cc (build_truth_vector_type_for_mode): Ditto. + * varasm.cc (output_constant_pool_2): Ditto. + +2023-07-05 YunQiang Su + + * config/mips/mips.cc (mips_expand_block_move): don't expand for + r6 with -mno-unaligned-access option if one or both of src and + dest are unaligned. restruct: return directly if length is not const. + (mips_block_move_straight): emit_move if ISA_HAS_UNALIGNED_ACCESS. + +2023-07-05 Jan Beulich + + PR target/100711 + * config/i386/sse.md: New splitters to simplify + not;vec_duplicate as a singular vpternlog. + (one_cmpl2): Allow broadcast for operand 1. + (one_cmpl2): Likewise. + +2023-07-05 Jan Beulich + + PR target/100711 + * config/i386/sse.md: New splitters to simplify + not;vec_duplicate;{ior,xor} as vec_duplicate;{iornot,xnor}. + +2023-07-05 Jan Beulich + + PR target/100711 + * config/i386/sse.md: Permit non-immediate operand 1 in AVX2 + form of splitter for PR target/100711. + +2023-07-05 Richard Biener + + PR middle-end/110541 + * tree.def (VEC_PERM_EXPR): Adjust documentation to reflect + reality. + +2023-07-05 Jan Beulich + + PR target/93768 + * config/i386/sse.md (*andnot3): Add new alternatives + for memory form operand 1. + +2023-07-05 Jan Beulich + + PR target/93768 + * config/i386/i386.cc (ix86_rtx_costs): Further special-case + bitwise vector operations. + * config/i386/sse.md (*iornot3): New insn. + (*xnor3): Likewise. + (*3): Likewise. + (andor): New code iterator. + (nlogic): New code attribute. + (ternlog_nlogic): Likewise. + +2023-07-05 Richard Biener + + * tree-vect-stmts.cc (vect_mark_relevant): Fix typo. + +2023-07-05 yulong + + * config/riscv/vector.md: Add float16 attr at sew、vlmul and ratio. + +2023-07-05 yulong + + * config/riscv/genrvv-type-indexer.cc (valid_type): Enable FP16 tuple. + * config/riscv/riscv-modes.def (RVV_TUPLE_MODES): New macro. + (ADJUST_ALIGNMENT): Ditto. + (RVV_TUPLE_PARTIAL_MODES): Ditto. + (ADJUST_NUNITS): Ditto. + * config/riscv/riscv-vector-builtins-types.def (vfloat16mf4x2_t): + New types. + (vfloat16mf4x3_t): Ditto. + (vfloat16mf4x4_t): Ditto. + (vfloat16mf4x5_t): Ditto. + (vfloat16mf4x6_t): Ditto. + (vfloat16mf4x7_t): Ditto. + (vfloat16mf4x8_t): Ditto. + (vfloat16mf2x2_t): Ditto. + (vfloat16mf2x3_t): Ditto. + (vfloat16mf2x4_t): Ditto. + (vfloat16mf2x5_t): Ditto. + (vfloat16mf2x6_t): Ditto. + (vfloat16mf2x7_t): Ditto. + (vfloat16mf2x8_t): Ditto. + (vfloat16m1x2_t): Ditto. + (vfloat16m1x3_t): Ditto. + (vfloat16m1x4_t): Ditto. + (vfloat16m1x5_t): Ditto. + (vfloat16m1x6_t): Ditto. + (vfloat16m1x7_t): Ditto. + (vfloat16m1x8_t): Ditto. + (vfloat16m2x2_t): Ditto. + (vfloat16m2x3_t): Ditto. + (vfloat16m2x4_t): Ditto. + (vfloat16m4x2_t): Ditto. + * config/riscv/riscv-vector-builtins.def (vfloat16mf4x2_t): New macro. + (vfloat16mf4x3_t): Ditto. + (vfloat16mf4x4_t): Ditto. + (vfloat16mf4x5_t): Ditto. + (vfloat16mf4x6_t): Ditto. + (vfloat16mf4x7_t): Ditto. + (vfloat16mf4x8_t): Ditto. + (vfloat16mf2x2_t): Ditto. + (vfloat16mf2x3_t): Ditto. + (vfloat16mf2x4_t): Ditto. + (vfloat16mf2x5_t): Ditto. + (vfloat16mf2x6_t): Ditto. + (vfloat16mf2x7_t): Ditto. + (vfloat16mf2x8_t): Ditto. + (vfloat16m1x2_t): Ditto. + (vfloat16m1x3_t): Ditto. + (vfloat16m1x4_t): Ditto. + (vfloat16m1x5_t): Ditto. + (vfloat16m1x6_t): Ditto. + (vfloat16m1x7_t): Ditto. + (vfloat16m1x8_t): Ditto. + (vfloat16m2x2_t): Ditto. + (vfloat16m2x3_t): Ditto. + (vfloat16m2x4_t): Ditto. + (vfloat16m4x2_t): Ditto. + * config/riscv/riscv-vector-switch.def (TUPLE_ENTRY): New. + * config/riscv/riscv.md: New. + * config/riscv/vector-iterators.md: New. + 2023-07-04 Andrew Pinski PR tree-optimization/110487 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 31e1a2e..ec0d4f3 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230705 +20230706 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 6419820..2533274 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2023-07-05 Robin Dapp + Juzhe-Zhong + + * c-common.cc (c_common_type_for_mode): Use GET_MODE_PRECISION. + 2023-06-29 Qing Zhao PR c/77650 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 92385a0..ed322a9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2023-07-05 Robin Dapp + Juzhe-Zhong + + * trans-types.cc (gfc_type_for_mode): Ditto. + 2023-06-28 Harald Anlauf PR fortran/110360 diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 432ae83..0af134c 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2023-07-05 Robin Dapp + Juzhe-Zhong + + * go-lang.cc (go_langhook_type_for_mode): Ditto. + 2023-06-26 Ian Lance Taylor * lang.opt (fgo-importcfg): New option. diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index ef375fa..77325bd 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,8 @@ +2023-07-05 Robin Dapp + Juzhe-Zhong + + * lto-lang.cc (lto_type_for_mode): Ditto. + 2023-07-04 Pan Li Thomas Schwinge diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog index 4854d71..de25e73 100644 --- a/gcc/rust/ChangeLog +++ b/gcc/rust/ChangeLog @@ -1,3 +1,8 @@ +2023-07-05 Robin Dapp + Juzhe-Zhong + + * backend/rust-tree.cc (c_common_type_for_mode): Ditto. + 2023-06-22 Paul E. Murphy * rust-object-export.cc [TARGET_AIX]: Rename and update usage to diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b6ce873..9b5fa70 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,110 @@ +2023-07-05 Robin Dapp + + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c: Add + tests for variable index. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-run.c: + Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-zvfh-run.c: + Ditto. + +2023-07-05 Robin Dapp + + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c: Adjust + test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-run.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-zvfh-run.c: + Ditto. + +2023-07-05 Robin Dapp + Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-10.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-11.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-12.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-13.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-14.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c: New test. + +2023-07-05 YunQiang Su + + * gcc.target/mips/expand-block-move-r6-no-unaligned.c: new test. + * gcc.target/mips/expand-block-move-r6.c: new test. + +2023-07-05 Richard Biener + + * gcc.dg/vect/slp-perm-9.c: Always use alternate N. + +2023-07-05 Jan Beulich + + * gcc.target/i386/avx512f-copysign.c: Suppress for 32-bit. + +2023-07-05 Jan Beulich + + PR target/100711 + * gcc.target/i386/pr100711-6.c: New test. + +2023-07-05 Jan Beulich + + PR target/100711 + * gcc.target/i386/pr100711-4.c: New test. + * gcc.target/i386/pr100711-5.c: New test. + +2023-07-05 Jan Beulich + + PR target/93768 + * gcc.target/i386/avx512f-andn-di-zmm-2.c: New test. + * gcc.target/i386/avx512f-andn-si-zmm-2.c: Adjust expecations + towards generated code. + * gcc.target/i386/pr100711-3.c: Adjust expectations for 32-bit + code. + +2023-07-05 Jan Beulich + + PR target/93768 + * gcc.target/i386/avx512-binop-not-1.h: New. + * gcc.target/i386/avx512-binop-not-2.h: New. + * gcc.target/i386/avx512f-orn-si-zmm-1.c: New test. + * gcc.target/i386/avx512f-orn-si-zmm-2.c: New test. + +2023-07-05 yulong + + * gcc.target/riscv/rvv/base/abi-10.c: Add float16 tuple type case. + * gcc.target/riscv/rvv/base/abi-11.c: Ditto. + * gcc.target/riscv/rvv/base/abi-12.c: Ditto. + * gcc.target/riscv/rvv/base/abi-15.c: Ditto. + * gcc.target/riscv/rvv/base/abi-8.c: Ditto. + * gcc.target/riscv/rvv/base/abi-9.c: Ditto. + * gcc.target/riscv/rvv/base/abi-17.c: New test. + * gcc.target/riscv/rvv/base/abi-18.c: New test. + +2023-07-05 yulong + + * gcc.target/riscv/rvv/base/tuple-28.c: New test. + * gcc.target/riscv/rvv/base/tuple-29.c: New test. + * gcc.target/riscv/rvv/base/tuple-30.c: New test. + * gcc.target/riscv/rvv/base/tuple-31.c: New test. + * gcc.target/riscv/rvv/base/tuple-32.c: New test. + +2023-07-05 Jie Mei + + * gcc.target/mips/mips16e2-cmov.c: Adjust branch cost to + encourage if-conversion. + * gcc.target/mips/movcc-3.c: Same as above. + 2023-07-04 Richard Biener PR tree-optimization/110491 -- cgit v1.1 From 7339e725b995912747c01c3ec80ce602512f45df Mon Sep 17 00:00:00 2001 From: Hao Liu Date: Thu, 6 Jul 2023 10:03:47 +0800 Subject: tree-optimization/110474 - Vect: select small VF for epilog of unrolled loop If a loop is unrolled during vectorization (i.e. suggested_unroll_factor > 1), the VFs of both main and epilog loop are enlarged. The epilog vect loop is specific for a loop with small iteration counts, so a large VF may hurt performance. This patch unscales the main loop VF by suggested_unroll_factor while selecting the epilog loop VF, so that it will be the same as vectorized loop without unrolling (i.e. suggested_unroll_factor = 1). gcc/ChangeLog: PR tree-optimization/110474 * tree-vect-loop.cc (vect_analyze_loop_2): unscale the VF by suggested unroll factor while selecting the epilog vect loop VF. gcc/testsuite/ChangeLog: * gcc.target/aarch64/pr110474.c: New testcase. --- gcc/testsuite/gcc.target/aarch64/pr110474.c | 37 +++++++++++++++++++++++++++++ gcc/tree-vect-loop.cc | 16 ++++++++----- 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/pr110474.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/aarch64/pr110474.c b/gcc/testsuite/gcc.target/aarch64/pr110474.c new file mode 100644 index 0000000..e548416 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr110474.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mtune=neoverse-n2 -mcpu=neoverse-n1 -fdump-tree-vect-details --param aarch64-vect-unroll-limit=2" } */ +/* { dg-final { scan-tree-dump "Choosing vector mode V8HI" "vect" } } */ +/* { dg-final { scan-tree-dump "Choosing epilogue vector mode V8QI" "vect" } } */ + +/* Do not increase the the vector factor of the epilog vectorized loop + for a loop with suggested_unroll_factor > 1. + + before (suggested_unroll_factor=1): + if N >= 16: + main vect loop + if N >= 8: + epilog vect loop + scalar code + + before (suggested_unroll_factor=2): + if N >= 32: + main vect loop + if N >= 16: // May fail to execute vectorized code (e.g. N is 8) + epilog vect loop + scalar code + + after (suggested_unroll_factor=2): + if N >= 32: + main vect loop + if N >= 8: // The same VF as suggested_unroll_factor=1 + epilog vect loop + scalar code */ + +int +foo (short *A, char *B, int N) +{ + int sum = 0; + for (int i = 0; i < N; ++i) + sum += A[i] * B[i]; + return sum; +} diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 3b46c58..4d9abd0 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -3021,12 +3021,16 @@ start_over: to be able to handle fewer than VF scalars, or needs to have a lower VF than the main loop. */ if (LOOP_VINFO_EPILOGUE_P (loop_vinfo) - && !LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) - && maybe_ge (LOOP_VINFO_VECT_FACTOR (loop_vinfo), - LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo))) - return opt_result::failure_at (vect_location, - "Vectorization factor too high for" - " epilogue loop.\n"); + && !LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) + { + poly_uint64 unscaled_vf + = exact_div (LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo), + orig_loop_vinfo->suggested_unroll_factor); + if (maybe_ge (LOOP_VINFO_VECT_FACTOR (loop_vinfo), unscaled_vf)) + return opt_result::failure_at (vect_location, + "Vectorization factor too high for" + " epilogue loop.\n"); + } /* Decide whether this loop_vinfo should use partial vectors or peeling, assuming that the loop will be used as a main loop. We will redo -- cgit v1.1 From 1669fad496ed6cc7ddea142e12af15e0b9f7f3b4 Mon Sep 17 00:00:00 2001 From: Jeevitha Palanisamy Date: Wed, 5 Jul 2023 23:46:15 -0500 Subject: rs6000: Remove redundant initialization [PR106907] PR106907 has few warnings spotted from cppcheck. In that addressing redundant initialization issue. Here the initialized value of 'new_addr' was overwritten before it was read. Updated the source by removing the unnecessary initialization of 'new_addr'. 2023-07-06 Jeevitha Palanisamy gcc/ PR target/106907 * config/rs6000/rs6000.cc (rs6000_expand_vector_extract): Remove redundant initialization of new_addr. --- gcc/config/rs6000/rs6000.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 07c3a3d..44b448d 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -7694,12 +7694,11 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt) { unsigned int ele_size = GET_MODE_SIZE (inner_mode); rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1); - rtx new_addr = gen_reg_rtx (Pmode); elt = gen_rtx_AND (Pmode, elt, num_ele_m1); if (ele_size > 1) elt = gen_rtx_MULT (Pmode, elt, GEN_INT (ele_size)); - new_addr = gen_rtx_PLUS (Pmode, XEXP (mem, 0), elt); + rtx new_addr = gen_rtx_PLUS (Pmode, XEXP (mem, 0), elt); new_addr = change_address (mem, inner_mode, new_addr); emit_move_insn (target, new_addr); } -- cgit v1.1 From 37a231cc7594d12ba0822077018aad751a6fb94e Mon Sep 17 00:00:00 2001 From: liuhongt Date: Wed, 5 Jul 2023 13:45:11 +0800 Subject: Disparage slightly for the alternative which move DFmode between SSE_REGS and GENERAL_REGS. For testcase void __cond_swap(double* __x, double* __y) { bool __r = (*__x < *__y); auto __tmp = __r ? *__x : *__y; *__y = __r ? *__y : *__x; *__x = __tmp; } GCC-14 with -O2 and -march=x86-64 options generates the following code: __cond_swap(double*, double*): movsd xmm1, QWORD PTR [rdi] movsd xmm0, QWORD PTR [rsi] comisd xmm0, xmm1 jbe .L2 movq rax, xmm1 movapd xmm1, xmm0 movq xmm0, rax .L2: movsd QWORD PTR [rsi], xmm1 movsd QWORD PTR [rdi], xmm0 ret rax is used to save and restore DFmode value. In RA both GENERAL_REGS and SSE_REGS cost zero since we didn't disparage the alternative in movdf_internal pattern, according to register allocation order, GENERAL_REGS is allocated. The patch add ? for alternative (r,v) and (v,r) just like we did for movsf/hf/bf_internal pattern, after that we get optimal RA. __cond_swap: .LFB0: .cfi_startproc movsd (%rdi), %xmm1 movsd (%rsi), %xmm0 comisd %xmm1, %xmm0 jbe .L2 movapd %xmm1, %xmm2 movapd %xmm0, %xmm1 movapd %xmm2, %xmm0 .L2: movsd %xmm1, (%rsi) movsd %xmm0, (%rdi) ret gcc/ChangeLog: PR target/110170 * config/i386/i386.md (movdf_internal): Disparage slightly for 2 alternatives (r,v) and (v,r) by adding constraint modifier '?'. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110170-3.c: New test. --- gcc/config/i386/i386.md | 4 ++-- gcc/testsuite/gcc.target/i386/pr110170-3.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110170-3.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a82cc35..e47ced1 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3915,9 +3915,9 @@ ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7. (define_insn "*movdf_internal" [(set (match_operand:DF 0 "nonimmediate_operand" - "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m") + "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,?r,?v,r ,o ,r ,m") (match_operand:DF 1 "general_operand" - "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))] + "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x, v, r,roF,rF,rmF,rC"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && (lra_in_progress || reload_completed || !CONST_DOUBLE_P (operands[1]) diff --git a/gcc/testsuite/gcc.target/i386/pr110170-3.c b/gcc/testsuite/gcc.target/i386/pr110170-3.c new file mode 100644 index 0000000..70daa89 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110170-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -fno-if-conversion -fno-if-conversion2" } */ +/* { dg-final { scan-assembler-not {(?n)movq.*r} } } */ + +void __cond_swap(double* __x, double* __y) { + _Bool __r = (*__x < *__y); + double __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} + -- cgit v1.1 From a73b65b74105e76473cc2825bb4e7253deaf18b3 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Tue, 4 Jul 2023 20:38:06 -0700 Subject: Fix PR 110554: vec lowering introduces scalar signed-boolean:32 comparisons So the problem is vector generic decided to do comparisons in signed-boolean:32 types but the rest of the middle-end was not ready for that. Since we are building the comparison which will feed into a cond_expr here, using boolean_type_node is better and also correct. The rest of the compiler thinks the ranges for comparison is always [0,1] too. Note this code does not currently lowers bigger vector sizes into smaller vector sizes so using boolean_type_node here is better. OK? bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: PR middle-end/110554 * tree-vect-generic.cc (expand_vector_condition): For comparisons, just build using boolean_type_node instead of the cond_type. For non-comparisons/non-scalar-bitmask, build a ` != 0` gimple that will feed into the COND_EXPR. --- gcc/tree-vect-generic.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc index df04a0d..a7e6cb8 100644 --- a/gcc/tree-vect-generic.cc +++ b/gcc/tree-vect-generic.cc @@ -1121,7 +1121,7 @@ expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names) comp_width, comp_index); tree aa2 = tree_vec_extract (gsi, comp_inner_type, a2, comp_width, comp_index); - aa = gimplify_build2 (gsi, code, cond_type, aa1, aa2); + aa = gimplify_build2 (gsi, code, boolean_type_node, aa1, aa2); } else if (a_is_scalar_bitmask) { @@ -1132,7 +1132,11 @@ expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names) build_zero_cst (TREE_TYPE (a))); } else - aa = tree_vec_extract (gsi, cond_type, a, comp_width, comp_index); + { + result = tree_vec_extract (gsi, cond_type, a, comp_width, comp_index); + aa = gimplify_build2 (gsi, NE_EXPR, boolean_type_node, result, + build_zero_cst (cond_type)); + } result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc); if (!CONSTANT_CLASS_P (result)) constant_p = false; -- cgit v1.1 From e1c23189abdd7bbbc066b2aa47ae4b7db0d69f2b Mon Sep 17 00:00:00 2001 From: liuhongt Date: Tue, 4 Jul 2023 13:59:17 +0800 Subject: Adjust rtx_cost for DF/SFmode AND/IOR/XOR/ANDN operations. They should have same cost as vector mode since both generate pand/pandn/pxor/por instruction. gcc/ChangeLog: * config/i386/i386.cc (ix86_rtx_costs): Adjust rtx_cost for DF/SFmode AND/IOR/XOR/ANDN operations. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110170-2.c: New test. --- gcc/config/i386/i386.cc | 9 ++++++--- gcc/testsuite/gcc.target/i386/pr110170-2.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110170-2.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index a9da66d..0cc4b32 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -21179,7 +21179,8 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, return false; case IOR: - if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT + || SSE_FLOAT_MODE_P (mode)) { /* (ior (not ...) ...) can be a single insn in AVX512. */ if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F @@ -21206,7 +21207,8 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, return false; case XOR: - if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT + || SSE_FLOAT_MODE_P (mode)) *total = ix86_vec_cost (mode, cost->sse_op); else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) *total = cost->add * 2; @@ -21220,7 +21222,8 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, *total = cost->lea; return true; } - else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT + || SSE_FLOAT_MODE_P (mode)) { /* pandn is a single instruction. */ if (GET_CODE (XEXP (x, 0)) == NOT) diff --git a/gcc/testsuite/gcc.target/i386/pr110170-2.c b/gcc/testsuite/gcc.target/i386/pr110170-2.c new file mode 100644 index 0000000..d43e322 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110170-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-msse2 -O2 -mfpmath=sse" } */ +/* { dg-final { scan-assembler-not "comi" } } */ + +double +foo (double* a, double* b, double c, double d) +{ + return *a < *b ? c : d; +} + +float +foo1 (float* a, float* b, float c, float d) +{ + return *a < *b ? c : d; +} + -- cgit v1.1 From e24b8256fe37df6ad39e2634c66ade70ca7c4e83 Mon Sep 17 00:00:00 2001 From: Hongyu Wang Date: Fri, 30 Jun 2023 09:44:56 +0800 Subject: i386: Inline function with default arch/tune to caller For function with different target attributes, current logic rejects to inline the callee when any arch or tune is mismatched. Relax the condition to allow callee with default arch/tune to be inlined. gcc/ChangeLog: * config/i386/i386.cc (ix86_can_inline_p): If callee has default arch=x86-64 and tune=generic, do not block the inlining to its caller. Also allow callee with different arch= to be inlined if it has always_inline attribute and it's ISA is subset of caller's. gcc/testsuite/ChangeLog: * gcc.target/i386/inline_attr_arch.c: New test. * gcc.target/i386/inline_target_clones.c: Ditto. --- gcc/config/i386/i386.cc | 24 +++++++++++++++------ gcc/testsuite/gcc.target/i386/inline_attr_arch.c | 25 ++++++++++++++++++++++ .../gcc.target/i386/inline_target_clones.c | 24 +++++++++++++++++++++ 3 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/inline_attr_arch.c create mode 100644 gcc/testsuite/gcc.target/i386/inline_target_clones.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 0cc4b32..f0d6167 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -605,13 +605,6 @@ ix86_can_inline_p (tree caller, tree callee) != (callee_opts->x_target_flags & ~always_inline_safe_mask)) ret = false; - /* See if arch, tune, etc. are the same. */ - else if (caller_opts->arch != callee_opts->arch) - ret = false; - - else if (!always_inline && caller_opts->tune != callee_opts->tune) - ret = false; - else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath /* If the calle doesn't use FP expressions differences in ix86_fpmath can be ignored. We are called from FEs @@ -622,6 +615,23 @@ ix86_can_inline_p (tree caller, tree callee) || ipa_fn_summaries->get (callee_node)->fp_expressions)) ret = false; + /* At this point we cannot identify whether arch or tune setting + comes from target attribute or not. So the most conservative way + is to allow the callee that uses default arch and tune string to + be inlined. */ + else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64") + && !strcmp (callee_opts->x_ix86_tune_string, "generic")) + ret = true; + + /* See if arch, tune, etc. are the same. As previous ISA flags already + checks if callee's ISA is subset of caller's, do not block + always_inline attribute for callee even it has different arch. */ + else if (!always_inline && caller_opts->arch != callee_opts->arch) + ret = false; + + else if (!always_inline && caller_opts->tune != callee_opts->tune) + ret = false; + else if (!always_inline && caller_opts->branch_cost != callee_opts->branch_cost) ret = false; diff --git a/gcc/testsuite/gcc.target/i386/inline_attr_arch.c b/gcc/testsuite/gcc.target/i386/inline_attr_arch.c new file mode 100644 index 0000000..1fab485 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/inline_attr_arch.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O3 -march=x86-64" } */ +/* { dg-final { scan-assembler-not "call\[ \t\]+callee" } } */ + +__attribute__((always_inline,target("arch=haswell"))) +inline float callee (float a, float b, float c, float d, + float e, float f, float g, float h) +{ + return a * b + c * d + e * f + g + h + a * c + b * c + + a * d + b * e + a * f + c * h + + b * (a - 0.4f) * (c + h) * (b + e * d) - a / f * h; +} + +__attribute__((target("arch=icelake-server"))) +void caller (int n, float *a, + float c1, float c2, float c3, + float c4, float c5, float c6, + float c7) +{ + for (int i = 0; i < n; i++) + { + a[i] = callee (a[i], c1, c2, c3, c4, c5, c6, c7); + } +} diff --git a/gcc/testsuite/gcc.target/i386/inline_target_clones.c b/gcc/testsuite/gcc.target/i386/inline_target_clones.c new file mode 100644 index 0000000..53db160 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/inline_target_clones.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O3 -march=x86-64" } */ +/* { dg-final { scan-assembler-not "call\[ \t\]+callee" } } */ + +float callee (float a, float b, float c, float d, + float e, float f, float g, float h) +{ + return a * b + c * d + e * f + g + h + a * c + b * c + + a * d + b * e + a * f + c * h + + b * (a - 0.4f) * (c + h) * (b + e * d) - a / f * h; +} + +__attribute__((target_clones("default","arch=icelake-server"))) +void caller (int n, float *a, + float c1, float c2, float c3, + float c4, float c5, float c6, + float c7) +{ + for (int i = 0; i < n; i++) + { + a[i] = callee (a[i], c1, c2, c3, c4, c5, c6, c7); + } +} -- cgit v1.1 From 2ab065c3e6950bc4995fcb16cebc5164d6213708 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 6 Jul 2023 08:52:46 +0200 Subject: Fix expectation on gcc.dg/vect/pr71264.c With the recent change to more reliably not vectorize code already using vector types we run into FAILs of gcc.dg/vect/pr71264.c The testcase was added for fixing an ICE and possible (re-)vectorization of the code isn't really supported and I suspect might even go wrong for non-bitops. The following leaves the testcase as just testing for an ICE. PR tree-optimization/110544 * gcc.dg/vect/pr71264.c: Remove scan for vectorization. --- gcc/testsuite/gcc.dg/vect/pr71264.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/pr71264.c b/gcc/testsuite/gcc.dg/vect/pr71264.c index 1381e0e..b372c00 100644 --- a/gcc/testsuite/gcc.dg/vect/pr71264.c +++ b/gcc/testsuite/gcc.dg/vect/pr71264.c @@ -1,5 +1,4 @@ /* { dg-do compile } */ -/* { dg-require-effective-target vect_int } */ typedef unsigned char uint8_t; typedef uint8_t footype __attribute__((vector_size(4))); @@ -18,5 +17,3 @@ void test(uint8_t *ptr, uint8_t *mask) __builtin_memcpy(&ptr[i], &temp, sizeof(temp)); } } - -/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail { { s390*-*-* sparc*-*-* } || vect32 } } } } */ -- cgit v1.1 From f2b37c8a38e44696287b19856bcbbf52e8b004f8 Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Thu, 6 Jul 2023 14:51:35 +0800 Subject: VECT: Fix ICE of variable stride on strieded load/store with SELECT_VL loop control. Hi, Richi. Sorry for making mistake on LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE with SELECT_VL loop control. Consider this following case: void __attribute__ ((noinline, noclone)) \ f_##DATA_TYPE##_##BITS (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ INDEX##BITS stride, INDEX##BITS n) \ { \ for (INDEX##BITS i = 0; i < n; ++i) \ dest[i] += src[i * stride]; \ } When "stride" is a constant, current flow works fine. However, when "stride" is a variable. It causes an ICE: ... _96 = .SELECT_VL (ivtmp_94, 4); ... ivtmp_78 = ((sizetype) _39 * (sizetype) _96) * 4; vect__11.69_87 = .LEN_MASK_GATHER_LOAD (vectp_src.67_85, _84, 4, { 0, 0, 0, 0 }, { -1, -1, -1, -1 }, _96, 0); ... vectp_src.67_86 = vectp_src.67_85 + ivtmp_78; Becase the IR: ivtmp_78 = ((sizetype) _39 * (sizetype) _96) * 4; Instead, I split the IR into: step_stride = _39 step = step_stride * 4 ivtmp_78 = step * _96 Thanks. gcc/ChangeLog: * tree-vect-stmts.cc (vect_get_strided_load_store_ops): Fix ICE. --- gcc/tree-vect-stmts.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index c10a4be..10e7117 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -3176,10 +3176,8 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info, = fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, unshare_expr (DR_STEP (dr))), loop_len); - tree bump = make_temp_ssa_name (sizetype, NULL, "ivtmp"); - gassign *assign = gimple_build_assign (bump, tmp); - gsi_insert_before (gsi, assign, GSI_SAME_STMT); - *dataref_bump = bump; + *dataref_bump = force_gimple_operand_gsi (gsi, tmp, true, NULL_TREE, true, + GSI_SAME_STMT); } else { -- cgit v1.1 From 9f4f833455bb35c11d03e93f802604ac7cd8b740 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 5 Jul 2023 15:57:49 +0200 Subject: tree-optimization/110515 - wrong code with LIM + PRE In this PR we face the issue that LIM speculates a load when hoisting it out of the loop (since it knows it cannot trap). Unfortunately this exposes undefined behavior when the load accesses memory with the wrong dynamic type. This later makes PRE use that representation instead of the original which accesses the same memory location but using a different dynamic type leading to a wrong disambiguation of that original access against another and thus a wrong-code transform. Fortunately there already is code in PRE dealing with a similar situation for code hoisting but that left a small gap which when fixed also fixes the wrong-code transform in this bug even if it doesn't address the underlying issue of LIM speculating that load. The upside is this fix is trivially safe to backport and chances of code generation regressions are very low. PR tree-optimization/110515 * tree-ssa-pre.cc (compute_avail): Make code dealing with hoisting loads with different alias-sets more robust. * g++.dg/opt/pr110515.C: New testcase. --- gcc/testsuite/g++.dg/opt/pr110515.C | 223 ++++++++++++++++++++++++++++++++++++ gcc/tree-ssa-pre.cc | 1 + 2 files changed, 224 insertions(+) create mode 100644 gcc/testsuite/g++.dg/opt/pr110515.C (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/opt/pr110515.C b/gcc/testsuite/g++.dg/opt/pr110515.C new file mode 100644 index 0000000..7a75cea --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr110515.C @@ -0,0 +1,223 @@ +// { dg-do run } +// { dg-require-effective-target c++11 } +// { dg-options "-O2" } + +typedef __UINT64_TYPE__ u64; + +struct SmallDenseMap { + static constexpr u64 EmptyKey = 0xC0FFEUL; + struct V { u64 v; }; + + bool contains(u64 Val) { + V *TheSlot = nullptr; + return (LookupSlotFor(Val, TheSlot) ? 1 : 0); + } + + void try_emplace(u64 Key) { + V *TheSlot = nullptr; + if (LookupSlotFor(Key, TheSlot)) + return; + + // Otherwise, insert the new element. + InsertIntoSlot(TheSlot, Key); + } + + void moveFromOldSlots(V *OldSlotsBegin, V *OldSlotsEnd) { + Size = 0; + + V *B_ = u.o.Slots; + V *E_ = B_ + u.o.Capacity; + for (; B_ != E_; ++B_) + B_->v = EmptyKey; + + // Insert all the old elements. + V *O = OldSlotsBegin; + V *E = OldSlotsEnd; + for (; O != E; ++O) { + if (O->v != EmptyKey) { + // Insert the key/value into the new table. + V * N = nullptr; + LookupSlotFor(O->v, N); + N->v = O->v; + Size++; + } + } + } + + void InsertIntoSlot(V *TheSlot, u64 Key) { + unsigned NewSize = Size + 1; + unsigned Capacity = getCapacity(); + // Make sure we always keep at least one Empty value + if (NewSize >= Capacity) { + //fprintf(stderr, "GROW: size=%u capacity=%u -> ...\n", Size, Capacity); + grow(); + LookupSlotFor(Key, TheSlot); + Capacity = getCapacity(); + //fprintf(stderr, "GROW: ... -> size=%u capacity=%u\n", NewSize, Capacity); + } + + Size++; + + TheSlot->v = Key; + } + + bool LookupSlotFor(u64 Val, + V *&FoundSlot) { + V *SlotsPtr = getSlots(); + const unsigned Capacity = getCapacity(); + + for (unsigned i = 0; i < Capacity; ++i) { + V *ThisSlot = SlotsPtr + i; + if (Val == ThisSlot->v) { + FoundSlot = ThisSlot; + return true; + } + + if (ThisSlot->v == EmptyKey) { + FoundSlot = ThisSlot; + return false; + } + } + // Guarantee that within an array there is a match + // or Empty value where to insert a new vaue. + __builtin_trap(); + } + + // Needs to bea at least 1 to hld one empty value + static constexpr unsigned InlineSlots = 2; + + bool Small; + unsigned Size; + + struct LargeRep { + V *Slots; + unsigned Capacity; + }; + + union { + V i[InlineSlots]; // Small = true + LargeRep o; // Small = false + } u; + + explicit SmallDenseMap() : Small(true), Size(0) { + Size = 0; + + V *B = u.i; + V *E = B + InlineSlots; + for (; B != E; ++B) + B->v = EmptyKey; + } + + void grow() { + // assert: + if (!Small) __builtin_trap(); + + // First move the inline Slots into a temporary storage. + V TmpStorage[InlineSlots]; + V *TmpBegin = TmpStorage; + V *TmpEnd = TmpBegin; + + // Loop over the Slots, moving non-empty, non-tombstones into the + // temporary storage. Have the loop move the TmpEnd forward as it goes. + V *P = u.i; + V *E = P + InlineSlots; + for (; P != E; ++P) { + if (P->v != EmptyKey) { + TmpEnd->v = P->v; + ++TmpEnd; + } + } + + Small = false; + u.o = LargeRep{new V[128], 128}; + moveFromOldSlots(TmpBegin, TmpEnd); + } + + V *getSlots() { + if (Small) { + V * inl = u.i; + return inl; + } + else { + LargeRep * rep = &u.o; + return rep->Slots; + } + } + + unsigned getCapacity() { + if (Small) { + return InlineSlots; + } + else { + LargeRep * rep = &u.o; + return rep->Capacity; + } + } +}; + +#pragma GCC optimize(0) + +struct P { + u64 f; + bool s; +}; + +static u64 ws = 0; +static P WorkList[128]; + +__attribute__((noipa)) +static void popupateIni() { + for (u64 Var : (u64[]){8,7,6,5,4,3,0}) { + WorkList[ws++] = P{Var, false}; + } +} + +__attribute__((noipa)) +static void checkCycle(u64 Var) { + // Detect cycles. + static bool seen[256]; + if (Var >= 256 || seen[Var]) __builtin_trap(); + seen[Var] = true; +} + + +__attribute__((noipa)) +static void populateDeps(u64 Var) { + + WorkList[ws++] = P{Var, true}; + if (Var == 8) + WorkList[ws++] = P{0, false}; +} + + +__attribute__((noipa)) __attribute__((optimize(3))) +static void bug() { + + // triggers growth on insert + SmallDenseMap Visited; + + popupateIni(); + + while (ws > 0) { + P Item = WorkList[--ws]; + u64 Var = Item.f; + bool visitedAllDependencies = Item.s; + + if (Visited.contains(Var)) { + continue; + } + + if (visitedAllDependencies) { + Visited.try_emplace(Var); + continue; + } + + checkCycle(Var); + populateDeps(Var); + } +} + +__attribute__((noipa)) +int main() { + bug(); +} diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index 7bbfa5a..e33c5ba 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -4245,6 +4245,7 @@ compute_avail (function *fun) else { ref->set = 0; + ref->base_set = 0; if (ref1->opcode == MEM_REF) ref1->op0 = wide_int_to_tree (ptr_type_node, -- cgit v1.1 From 6ded65b8e6c55a9280e381775a64b2c282df6207 Mon Sep 17 00:00:00 2001 From: Hongyu Wang Date: Thu, 6 Jul 2023 14:22:52 +0800 Subject: i386: Update document for inlining rules gcc/ChangeLog: * doc/extend.texi: Move x86 inlining rule to a new subsubsection and add description for inling of function with arch and tune attributes. --- gcc/doc/extend.texi | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d1b018e..d701b4d 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7243,11 +7243,6 @@ Prefer 256-bit vector width for instructions. Prefer 512-bit vector width for instructions. @end table -On the x86, the inliner does not inline a -function that has different target options than the caller, unless the -callee has a subset of the target options of the caller. For example -a function declared with @code{target("sse3")} can inline a function -with @code{target("sse2")}, since @code{-msse3} implies @code{-msse2}. @end table @cindex @code{indirect_branch} function attribute, x86 @@ -7361,6 +7356,20 @@ counterpart to option @option{-mno-direct-extern-access}. @end table +@subsubsection Inlining rules +On the x86, the inliner does not inline a +function that has different target options than the caller, unless the +callee has a subset of the target options of the caller. For example +a function declared with @code{target("sse3")} can inline a function +with @code{target("sse2")}, since @code{-msse3} implies @code{-msse2}. + +Besides the basic rule, when a function specifies +@code{target("arch=@var{ARCH}")} or @code{target("tune=@var{TUNE}")} +attribute, the inlining rule will be different. It allows inlining of +a function with default @option{-march=x86-64} and +@option{-mtune=generic} specified, or a function that has a subset +of ISA features and marked with always_inline. + @node Xstormy16 Function Attributes @subsection Xstormy16 Function Attributes -- cgit v1.1 From 11578db6e2a0da8fa7921713093e91ea0e599bef Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Thu, 6 Jul 2023 09:58:17 +0100 Subject: [Committed] Handle COPYSIGN in dwarf2out.cc's mem_loc_descriptor. Many thanks to Hans-Peter Nilsson for reminding me that new RTX codes need to be added to dwarf2out.cc's mem_loc_descriptor, and for doing this for BITREVERSE. This patch does the same for the recently added COPYSIGN. I'd been testing these on a target that doesn't use DWARF (nvptx-none) and so didn't exhibit the issue, and my additional testing on x86_64-pc-linux-gnu to double check that changes were safe, doesn't (yet) trigger the problematic assert in dwarf2out.cc's mem_loc_descriptor. 2023-07-06 Roger Sayle gcc/ChangeLog * dwarf2out.cc (mem_loc_descriptor): Handle COPYSIGN. --- gcc/dwarf2out.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index e973644..238d0a9 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -16941,6 +16941,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, case SMUL_HIGHPART: case UMUL_HIGHPART: case BITREVERSE: + case COPYSIGN: break; case CONST_STRING: -- cgit v1.1 From bbbe2dc1fc4f561cda3d8cb383132b7d519b0de8 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Sat, 1 Jul 2023 00:25:05 +0200 Subject: GGC: Remove unused 'bool is_string' arguments to 'ggc_pch_{count,alloc,write}_object' They're unused since the removal of 'gcc/ggc-zone.c' in 2013 Subversion r195426 (Git commit cd030c079e5e42fe3f49261fe01f384e6b7f0111) "Remove zone allocator". Should any future 'gcc/ggc-[...].cc' ever need this again, it'll be a conscious decision at that time. gcc/ * ggc-internal.h (ggc_pch_count_object, ggc_pch_alloc_object) (ggc_pch_write_object): Remove 'bool is_string' argument. * ggc-common.cc: Adjust. * ggc-page.cc: Likewise. --- gcc/ggc-common.cc | 9 +++------ gcc/ggc-internal.h | 15 ++++++--------- gcc/ggc-page.cc | 6 +++--- 3 files changed, 12 insertions(+), 18 deletions(-) (limited to 'gcc') diff --git a/gcc/ggc-common.cc b/gcc/ggc-common.cc index db317f4..173ab64 100644 --- a/gcc/ggc-common.cc +++ b/gcc/ggc-common.cc @@ -336,8 +336,7 @@ ggc_call_count (ptr_data **slot, traversal_state *state) { struct ptr_data *d = *slot; - ggc_pch_count_object (state->d, d->obj, d->size, - d->note_ptr_fn == gt_pch_p_S); + ggc_pch_count_object (state->d, d->obj, d->size); state->count++; return 1; } @@ -347,8 +346,7 @@ ggc_call_alloc (ptr_data **slot, traversal_state *state) { struct ptr_data *d = *slot; - d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size, - d->note_ptr_fn == gt_pch_p_S); + d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size); state->ptrs[state->ptrs_i++] = d; return 1; } @@ -642,8 +640,7 @@ gt_pch_save (FILE *f) state.ptrs[i]->note_ptr_cookie, relocate_ptrs, &state); ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj, - state.ptrs[i]->new_addr, state.ptrs[i]->size, - state.ptrs[i]->note_ptr_fn == gt_pch_p_S); + state.ptrs[i]->new_addr, state.ptrs[i]->size); if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S) memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size); #if defined ENABLE_VALGRIND_ANNOTATIONS && defined VALGRIND_GET_VBITS diff --git a/gcc/ggc-internal.h b/gcc/ggc-internal.h index 25e6ce6..33874bc 100644 --- a/gcc/ggc-internal.h +++ b/gcc/ggc-internal.h @@ -52,9 +52,8 @@ extern struct ggc_pch_data *init_ggc_pch (void); /* The second parameter and third parameters give the address and size of an object. Update the ggc_pch_data structure with as much of - that information as is necessary. The bool argument should be true - if the object is a string. */ -extern void ggc_pch_count_object (struct ggc_pch_data *, void *, size_t, bool); + that information as is necessary. */ +extern void ggc_pch_count_object (struct ggc_pch_data *, void *, size_t); /* Return the total size of the data to be written to hold all the objects previously passed to ggc_pch_count_object. */ @@ -65,17 +64,15 @@ extern size_t ggc_pch_total_size (struct ggc_pch_data *); extern void ggc_pch_this_base (struct ggc_pch_data *, void *); /* Assuming that the objects really do end up at the address - passed to ggc_pch_this_base, return the address of this object. - The bool argument should be true if the object is a string. */ -extern char *ggc_pch_alloc_object (struct ggc_pch_data *, void *, size_t, bool); + passed to ggc_pch_this_base, return the address of this object. */ +extern char *ggc_pch_alloc_object (struct ggc_pch_data *, void *, size_t); /* Write out any initial information required. */ extern void ggc_pch_prepare_write (struct ggc_pch_data *, FILE *); -/* Write out this object, including any padding. The last argument should be - true if the object is a string. */ +/* Write out this object, including any padding. */ extern void ggc_pch_write_object (struct ggc_pch_data *, FILE *, void *, - void *, size_t, bool); + void *, size_t); /* All objects have been written, write out any final information required. */ diff --git a/gcc/ggc-page.cc b/gcc/ggc-page.cc index 2f0b72e..b74572c 100644 --- a/gcc/ggc-page.cc +++ b/gcc/ggc-page.cc @@ -2409,7 +2409,7 @@ init_ggc_pch (void) void ggc_pch_count_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED, - size_t size, bool is_string ATTRIBUTE_UNUSED) + size_t size) { unsigned order; @@ -2452,7 +2452,7 @@ ggc_pch_this_base (struct ggc_pch_data *d, void *base) char * ggc_pch_alloc_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED, - size_t size, bool is_string ATTRIBUTE_UNUSED) + size_t size) { unsigned order; char *result; @@ -2481,7 +2481,7 @@ ggc_pch_prepare_write (struct ggc_pch_data *d ATTRIBUTE_UNUSED, void ggc_pch_write_object (struct ggc_pch_data *d, FILE *f, void *x, void *newx ATTRIBUTE_UNUSED, - size_t size, bool is_string ATTRIBUTE_UNUSED) + size_t size) { unsigned order; static const char emptyBytes[256] = { 0 }; -- cgit v1.1 From ee8ed948c1f659d10f5c19e4d51bd8a79369762b Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 4 Jul 2023 11:46:50 +0200 Subject: GTY: Explicitly reject 'string_length' option for (fields in) global variables This is preparational for another thing that I'm working on. No change in behavior -- other than a more explicit error message. The 'string_length' option currently is not supported for (fields in) global variables. For example, if we apply the following (made-up) changes: --- gcc/c-family/c-cppbuiltin.cc +++ gcc/c-family/c-cppbuiltin.cc @@ -1777 +1777 @@ struct GTY(()) lazy_hex_fp_value_struct - const char *hex_str; + const char * GTY((string_length("strlen(%h.hex_str) + 1"))) hex_str; --- gcc/varasm.cc +++ gcc/varasm.cc @@ -66 +66 @@ along with GCC; see the file COPYING3. If not see -extern GTY(()) const char *first_global_object_name; +extern GTY((string_length("strlen(%h.first_global_object_name) + 1"))) const char *first_global_object_name; ..., we get: [...] build/gengtype \ -S [...]/source-gcc/gcc -I gtyp-input.list -w tmp-gtype.state /bin/sh [...]/source-gcc/gcc/../move-if-change tmp-gtype.state gtype.state build/gengtype \ -r gtype.state [...]/source-gcc/gcc/varasm.cc:66: global `first_global_object_name' has unknown option `string_length' [...]/source-gcc/gcc/c-family/c-cppbuiltin.cc:1789: field `hex_str' of global `lazy_hex_fp_values[0]' has unknown option `string_length' make[2]: *** [Makefile:2890: s-gtype] Error 1 [...] These errors occur when writing "GC roots", where -- per my understanding -- 'string_length' isn't relevant for actual GC purposes. However, like elsewhere, it is for PCH purposes, and simply accepting 'string_length' here isn't sufficient: we'll still get '(gt_pointer_walker) >_pch_n_S' used in the 'struct ggc_root_tab' instances, and there's no easy way to change that to instead use 'gt_pch_n_S2' with explicit 'size_t string_len' argument. (At least not sufficiently easy to justify spending any further time on, given that I don't have an actual use for that feature.) So, until an actual need arises, and/or to avoid the next person looking into this having to figure out the same thing again, let's just document this limitation: [...]/source-gcc/gcc/varasm.cc:66: option `string_length' not supported for global `first_global_object_name' [...]/source-gcc/gcc/c-family/c-cppbuiltin.cc:1789: option `string_length' not supported for field `hex_str' of global `lazy_hex_fp_values[0]' This amends commit f3b957ea8b9dadfb1ed30f24f463529684b7a36a "pch: Fix streaming of strings with embedded null bytes". gcc/ * gengtype.cc (write_root, write_roots): Explicitly reject 'string_length' option. * doc/gty.texi (GTY Options) : Document. --- gcc/doc/gty.texi | 4 ++++ gcc/gengtype.cc | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi index 9fc5091..7bd064b 100644 --- a/gcc/doc/gty.texi +++ b/gcc/doc/gty.texi @@ -217,6 +217,10 @@ struct GTY(()) non_terminated_string @{ @}; @end smallexample +The @code{string_length} option currently is not supported for (fields +in) global variables. +@c + @findex skip @item skip diff --git a/gcc/gengtype.cc b/gcc/gengtype.cc index 7763f40..04dbb0d 100644 --- a/gcc/gengtype.cc +++ b/gcc/gengtype.cc @@ -4337,6 +4337,11 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length, else if (strcmp (o->name, "desc") == 0 && o->kind == OPTION_STRING) desc = o->info.string; + else if (strcmp (o->name, "string_length") == 0) + /* See 'doc/gty.texi'. */ + error_at_line (line, + "option `%s' not supported for field `%s' of global `%s'", + o->name, fld->name, name); else error_at_line (line, "field `%s' of global `%s' has unknown option `%s'", @@ -4535,6 +4540,11 @@ write_roots (pair_p variables, bool emit_pch) deletable_p = 1; else if (strcmp (o->name, "cache") == 0) ; + else if (strcmp (o->name, "string_length") == 0) + /* See 'doc/gty.texi'. */ + error_at_line (&v->line, + "option `%s' not supported for global `%s'", + o->name, v->name); else error_at_line (&v->line, "global `%s' has unknown option `%s'", -- cgit v1.1 From 62db795a8fdec8b618a61e40a9e2716768d50d90 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Wed, 5 Jul 2023 08:38:49 +0200 Subject: GTY: Enhance 'string_length' option documentation We're (currently) not aware of any actual use of 'ht_identifier's with NUL characters embedded; its 'len' field appears to exist for optimization purposes, since "forever". Before 'struct ht_identifier' was added in commit 2a967f3d3a45294640e155381ef549e0b8090ad4 (Subversion r42334), we had in 'gcc/cpplib.h:struct cpp_hashnode': 'unsigned short len', or earlier 'length', earlier in 'gcc/cpphash.h:struct hashnode': 'unsigned short length', earlier 'size_t length' with comment: "length of token, for quick comparison", earlier 'int length', ever since the 'gcc/cpp*' files were added in commit 7f2935c734c36f84ab62b20a04de465e19061333 (Subversion r9191). This amends commit f3b957ea8b9dadfb1ed30f24f463529684b7a36a "pch: Fix streaming of strings with embedded null bytes". gcc/ * doc/gty.texi (GTY Options) : Enhance. libcpp/ * include/symtab.h (struct ht_identifier): Document different rationale. --- gcc/doc/gty.texi | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi index 7bd064b..15f9fa0 100644 --- a/gcc/doc/gty.texi +++ b/gcc/doc/gty.texi @@ -217,6 +217,17 @@ struct GTY(()) non_terminated_string @{ @}; @end smallexample +Similarly, this is useful for (regular NUL-terminated) strings with +NUL characters embedded (that the default @code{strlen} use would run +afoul of): + +@smallexample +struct GTY(()) multi_string @{ + const char * GTY((string_length ("%h.len + 1"))) str; + size_t len; +@}; +@end smallexample + The @code{string_length} option currently is not supported for (fields in) global variables. @c -- cgit v1.1 From da5f6d9c88c3b6fd505fed06359e344b2892528d Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Wed, 5 Jul 2023 11:10:55 +0200 Subject: GTY: Repair 'enum gty_token', 'token_names' desynchronization For example, for the following (made-up) changes: --- gcc/ggc-tests.cc +++ gcc/ggc-tests.cc @@ -258 +258 @@ class GTY((tag("1"))) some_subclass : public example_base -class GTY((tag("2"))) some_other_subclass : public example_base +class GTY((tag(user))) some_other_subclass : public example_base @@ -384 +384 @@ test_chain_next () -struct GTY((user)) user_struct +struct GTY((user user)) user_struct ..., we get unexpected "have a param_is option" diagnostics: [...] build/gengtype \ -S [...]/source-gcc/gcc -I gtyp-input.list -w tmp-gtype.state [...]/source-gcc/gcc/ggc-tests.cc:258: parse error: expected a string constant, have a param_is option [...]/source-gcc/gcc/ggc-tests.cc:384: parse error: expected ')', have a param_is option make[2]: *** [Makefile:2888: s-gtype] Error 1 [...] This traces back to 2012 "Support garbage-collected C++ templates", which got incorporated in commit 0823efedd0fb8669b7e840954bc54c3b2cf08d67 (Subversion r190402), which did add 'USER_GTY' to what nowadays is known as 'enum gty_token', but didn't accordingly update 'gcc/gengtype-parse.c:token_names', leaving those out of sync. Updating 'gcc/gengtype-parse.c:token_value_format' wasn't necessary, as: /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have a meaningful value to be printed. */ FIRST_TOKEN_WITH_VALUE = PARAM_IS This, in turn, got further confused -- or "fixed" -- by later changes: 2014 commit 63f5d5b818319129217e41bcb23db53f99ff11b0 (Subversion r218558) "remove gengtype support for param_is use_param, if_marked and splay tree allocators", which reciprocally missed corresponding clean-up. With that addressed via adding the missing '"user"' to 'token_names', and, until that is properly fixed, a temporary 'UNUSED_PARAM_IS' (re-)added for use with 'FIRST_TOKEN_WITH_VALUE', we then get the expected: [...]/source-gcc/gcc/ggc-tests.cc:258: parse error: expected a string constant, have 'user' [...]/source-gcc/gcc/ggc-tests.cc:384: parse error: expected ')', have 'user' gcc/ * gengtype-parse.cc (token_names): Add '"user"'. * gengtype.h (gty_token): Add 'UNUSED_PARAM_IS' for use with 'FIRST_TOKEN_WITH_VALUE'. --- gcc/gengtype-parse.cc | 3 +++ gcc/gengtype.h | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/gengtype-parse.cc b/gcc/gengtype-parse.cc index 19184d7..2efbda0 100644 --- a/gcc/gengtype-parse.cc +++ b/gcc/gengtype-parse.cc @@ -69,6 +69,7 @@ advance (void) /* Diagnostics. */ /* This array is indexed by the token code minus CHAR_TOKEN_OFFSET. */ +/* Keep in sync with 'gengtype.h:enum gty_token'. */ static const char *const token_names[] = { "GTY", "typedef", @@ -80,6 +81,7 @@ static const char *const token_names[] = { "...", "ptr_alias", "nested_ptr", + "user", "a param_is option", "a number", "a scalar type", @@ -91,6 +93,7 @@ static const char *const token_names[] = { }; /* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */ +/* Keep in sync with 'gengtype.h:enum gty_token'. */ static const char *const token_value_format[] = { "%s", "'%s'", diff --git a/gcc/gengtype.h b/gcc/gengtype.h index 4e5df54..2122373 100644 --- a/gcc/gengtype.h +++ b/gcc/gengtype.h @@ -458,6 +458,8 @@ extern void parse_file (const char *name); extern bool hit_error; /* Token codes. */ +/* Keep 'gengtype-parse.cc:token_names', 'gengtype-parse.cc:token_value_format' + in sync. */ enum gty_token { EOF_TOKEN = 0, @@ -476,6 +478,7 @@ enum gty_token PTR_ALIAS, NESTED_PTR, USER_GTY, + UNUSED_PARAM_IS, NUM, SCALAR, ID, @@ -486,7 +489,7 @@ enum gty_token /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have a meaningful value to be printed. */ - FIRST_TOKEN_WITH_VALUE = USER_GTY + FIRST_TOKEN_WITH_VALUE = UNUSED_PARAM_IS }; -- cgit v1.1 From 493bb5a974a5a51ebc8493916f88ef5a0cded93e Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 4 Jul 2023 22:47:48 +0200 Subject: GTY: Clean up obsolete 'bool needs_cast_p' field of 'gcc/gengtype.cc:struct walk_type_data' Last use disappeared in 2014 with commit 63f5d5b818319129217e41bcb23db53f99ff11b0 (Subversion r218558) "remove gengtype support for param_is use_param, if_marked and splay tree allocators". gcc/ * gengtype.cc (struct walk_type_data): Remove 'needs_cast_p'. Adjust all users. --- gcc/gengtype.cc | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'gcc') diff --git a/gcc/gengtype.cc b/gcc/gengtype.cc index 04dbb0d..54d3c8a 100644 --- a/gcc/gengtype.cc +++ b/gcc/gengtype.cc @@ -2447,7 +2447,6 @@ struct walk_type_data int used_length; type_p orig_s; const char *reorder_fn; - bool needs_cast_p; bool fn_wants_lvalue; bool in_record_p; int loopcounter; @@ -2663,7 +2662,6 @@ walk_type (type_p t, struct walk_type_data *d) options_p oo; const struct nested_ptr_data *nested_ptr_d = NULL; - d->needs_cast_p = false; for (oo = d->opt; oo; oo = oo->next) if (strcmp (oo->name, "length") == 0 && oo->kind == OPTION_STRING) length = oo->info.string; @@ -3186,7 +3184,6 @@ static void write_types_process_field (type_p f, const struct walk_type_data *d) { const struct write_types_data *wtd; - const char *cast = d->needs_cast_p ? "(void *)" : ""; wtd = (const struct write_types_data *) d->cookie; switch (f->kind) @@ -3195,8 +3192,8 @@ write_types_process_field (type_p f, const struct walk_type_data *d) case TYPE_UNDEFINED: gcc_unreachable (); case TYPE_POINTER: - oprintf (d->of, "%*s%s (%s%s", d->indent, "", - wtd->subfield_marker_routine, cast, d->val); + oprintf (d->of, "%*s%s (%s", d->indent, "", + wtd->subfield_marker_routine, d->val); if (wtd->param_prefix) { if (f->u.p->kind == TYPE_SCALAR) @@ -3229,8 +3226,8 @@ write_types_process_field (type_p f, const struct walk_type_data *d) } oprintf (d->of, ");\n"); if (d->reorder_fn && wtd->reorder_note_routine) - oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "", - wtd->reorder_note_routine, cast, d->val, + oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "", + wtd->reorder_note_routine, d->val, d->prev_val[3], d->reorder_fn); break; @@ -3262,16 +3259,16 @@ write_types_process_field (type_p f, const struct walk_type_data *d) : nullptr); if (length_override) { - oprintf (d->of, "2 (%s%s, ", cast, d->val); + oprintf (d->of, "2 (%s, ", d->val); output_escaped_param (d, length_override, "string_length"); } else - oprintf (d->of, " (%s%s", cast, d->val); + oprintf (d->of, " (%s", d->val); oprintf (d->of, ");\n"); if (d->reorder_fn && wtd->reorder_note_routine) - oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "", - wtd->reorder_note_routine, cast, d->val, cast, d->val, + oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "", + wtd->reorder_note_routine, d->val, d->val, d->reorder_fn); } break; -- cgit v1.1 From a53bbd8cd2ec6f08d756faf9f9d7e345704bb880 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 4 Jul 2023 22:47:48 +0200 Subject: GTY: Clean up obsolete parametrized structs remnants Support removed in 2014 with commit 63f5d5b818319129217e41bcb23db53f99ff11b0 (Subversion r218558) "remove gengtype support for param_is use_param, if_marked and splay tree allocators". gcc/ * gengtype-parse.cc: Clean up obsolete parametrized structs remnants. * gengtype.cc: Likewise. * gengtype.h: Likewise. --- gcc/gengtype-parse.cc | 2 -- gcc/gengtype.cc | 6 ++---- gcc/gengtype.h | 3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/gengtype-parse.cc b/gcc/gengtype-parse.cc index 2efbda0..fce1fe9 100644 --- a/gcc/gengtype-parse.cc +++ b/gcc/gengtype-parse.cc @@ -82,7 +82,6 @@ static const char *const token_names[] = { "ptr_alias", "nested_ptr", "user", - "a param_is option", "a number", "a scalar type", "an identifier", @@ -95,7 +94,6 @@ static const char *const token_names[] = { /* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */ /* Keep in sync with 'gengtype.h:enum gty_token'. */ static const char *const token_value_format[] = { - "%s", "'%s'", "'%s'", "'%s'", diff --git a/gcc/gengtype.cc b/gcc/gengtype.cc index 54d3c8a..49ddba6 100644 --- a/gcc/gengtype.cc +++ b/gcc/gengtype.cc @@ -1388,8 +1388,6 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) At present: - Converts pointer-to-char, with no length parameter, to TYPE_STRING; - Similarly for arrays of pointer-to-char; - - Converts structures for which a parameter is provided to - TYPE_PARAM_STRUCT; - Handles "special" options. */ @@ -3654,7 +3652,7 @@ write_func_for_structure (type_p orig_s, type_p s, } -/* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */ +/* Write out marker routines for STRUCTURES. */ static void write_types (outf_p output_header, type_p structures, @@ -4002,7 +4000,7 @@ write_local_func_for_structure (const_type_p orig_s, type_p s) } } -/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */ +/* Write out local marker routines for STRUCTURES. */ static void write_local (outf_p output_header, type_p structures) diff --git a/gcc/gengtype.h b/gcc/gengtype.h index 2122373..1394290 100644 --- a/gcc/gengtype.h +++ b/gcc/gengtype.h @@ -478,7 +478,6 @@ enum gty_token PTR_ALIAS, NESTED_PTR, USER_GTY, - UNUSED_PARAM_IS, NUM, SCALAR, ID, @@ -489,7 +488,7 @@ enum gty_token /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have a meaningful value to be printed. */ - FIRST_TOKEN_WITH_VALUE = UNUSED_PARAM_IS + FIRST_TOKEN_WITH_VALUE = NUM }; -- cgit v1.1 From 79a90e69ec9faf53ba84391f3c558e552711f6a6 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Wed, 5 Jul 2023 15:34:56 +0200 Subject: GGC, GTY: Tighten up a few things re 'reorder' option and strings ..., which doesn't make sense in combination. This, again, is primarily preparational for another change. gcc/ * ggc-common.cc (gt_pch_note_reorder, gt_pch_save): Tighten up a few things re 'reorder' option and strings. * stringpool.cc (gt_pch_p_S): This is now 'gcc_unreachable'. --- gcc/ggc-common.cc | 18 ++++++++++++++---- gcc/stringpool.cc | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ggc-common.cc b/gcc/ggc-common.cc index 173ab64..bed7a9d 100644 --- a/gcc/ggc-common.cc +++ b/gcc/ggc-common.cc @@ -314,6 +314,9 @@ gt_pch_note_reorder (void *obj, void *note_ptr_cookie, data = (struct ptr_data *) saving_htab->find_with_hash (obj, POINTER_HASH (obj)); gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie); + /* The GTY 'reorder' option doesn't make sense if we don't walk pointers, + such as for strings. */ + gcc_checking_assert (data->note_ptr_fn != gt_pch_p_S); data->reorder_fn = reorder_fn; } @@ -636,12 +639,19 @@ gt_pch_save (FILE *f) state.ptrs[i]->reorder_fn (state.ptrs[i]->obj, state.ptrs[i]->note_ptr_cookie, relocate_ptrs, &state); - state.ptrs[i]->note_ptr_fn (state.ptrs[i]->obj, - state.ptrs[i]->note_ptr_cookie, - relocate_ptrs, &state); + gt_note_pointers note_ptr_fn = state.ptrs[i]->note_ptr_fn; + gcc_checking_assert (note_ptr_fn != NULL); + /* 'gt_pch_p_S' enables certain special handling, but otherwise + corresponds to no 'note_ptr_fn'. */ + if (note_ptr_fn == gt_pch_p_S) + note_ptr_fn = NULL; + if (note_ptr_fn != NULL) + note_ptr_fn (state.ptrs[i]->obj, state.ptrs[i]->note_ptr_cookie, + relocate_ptrs, &state); ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj, state.ptrs[i]->new_addr, state.ptrs[i]->size); - if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S) + if (state.ptrs[i]->reorder_fn != NULL + || note_ptr_fn != NULL) memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size); #if defined ENABLE_VALGRIND_ANNOTATIONS && defined VALGRIND_GET_VBITS if (UNLIKELY (get_vbits == 1)) diff --git a/gcc/stringpool.cc b/gcc/stringpool.cc index 46aff39..8658e6a 100644 --- a/gcc/stringpool.cc +++ b/gcc/stringpool.cc @@ -185,6 +185,7 @@ gt_pch_p_S (void *obj ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED, gt_pointer_operator op ATTRIBUTE_UNUSED, void *cookie ATTRIBUTE_UNUSED) { + gcc_unreachable (); } /* PCH pointer-walking routine for strings. */ -- cgit v1.1 From deebf06a1207bf7d84f4bebc462137d9436ee6dd Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 6 Jul 2023 09:56:23 +0200 Subject: tree-optimization/110563 - simplify epilogue VF checks The following consolidates an assert that now hits for ppc64le with an earlier check we already do, simplifying vect_determine_partial_vectors_and_peeling and getting rid of its now redundant argument. PR tree-optimization/110563 * tree-vectorizer.h (vect_determine_partial_vectors_and_peeling): Remove second argument. * tree-vect-loop.cc (vect_determine_partial_vectors_and_peeling): Remove for_epilogue_p argument. Merge assert ... (vect_analyze_loop_2): ... with check done before determining partial vectors by moving it after. * tree-vect-loop-manip.cc (vect_do_peeling): Adjust. --- gcc/tree-vect-loop-manip.cc | 3 +-- gcc/tree-vect-loop.cc | 54 ++++++++++++++------------------------------- gcc/tree-vectorizer.h | 3 +-- 3 files changed, 19 insertions(+), 41 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 6c452e0..d66d4a6 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -3461,8 +3461,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, a multiple of the epilogue loop's vectorization factor. We should have rejected the loop during the analysis phase if this fails. */ - bool res = vect_determine_partial_vectors_and_peeling (epilogue_vinfo, - true); + bool res = vect_determine_partial_vectors_and_peeling (epilogue_vinfo); gcc_assert (res); } diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 4d9abd0..36d19a5 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -2494,16 +2494,10 @@ vect_dissolve_slp_only_groups (loop_vec_info loop_vinfo) In this case: LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P == false - - When FOR_EPILOGUE_P is true, make this determination based on the - assumption that LOOP_VINFO is an epilogue loop, otherwise make it - based on the assumption that LOOP_VINFO is the main loop. The caller - has made sure that the number of iterations is set appropriately for - this value of FOR_EPILOGUE_P. */ + */ opt_result -vect_determine_partial_vectors_and_peeling (loop_vec_info loop_vinfo, - bool for_epilogue_p) +vect_determine_partial_vectors_and_peeling (loop_vec_info loop_vinfo) { /* Determine whether there would be any scalar iterations left over. */ bool need_peeling_or_partial_vectors_p @@ -2537,25 +2531,12 @@ vect_determine_partial_vectors_and_peeling (loop_vec_info loop_vinfo, } if (dump_enabled_p ()) - { - if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) - dump_printf_loc (MSG_NOTE, vect_location, - "operating on partial vectors%s.\n", - for_epilogue_p ? " for epilogue loop" : ""); - else - dump_printf_loc (MSG_NOTE, vect_location, - "operating only on full vectors%s.\n", - for_epilogue_p ? " for epilogue loop" : ""); - } - - if (for_epilogue_p) - { - loop_vec_info orig_loop_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo); - gcc_assert (orig_loop_vinfo); - if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) - gcc_assert (known_lt (LOOP_VINFO_VECT_FACTOR (loop_vinfo), - LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo))); - } + dump_printf_loc (MSG_NOTE, vect_location, + "operating on %s vectors%s.\n", + LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) + ? "partial" : "full", + LOOP_VINFO_EPILOGUE_P (loop_vinfo) + ? " for epilogue loop" : ""); LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) = (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) @@ -3017,11 +2998,19 @@ start_over: LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo) = true; } + /* Decide whether this loop_vinfo should use partial vectors or peeling, + assuming that the loop will be used as a main loop. We will redo + this analysis later if we instead decide to use the loop as an + epilogue loop. */ + ok = vect_determine_partial_vectors_and_peeling (loop_vinfo); + if (!ok) + return ok; + /* If we're vectorizing an epilogue loop, the vectorized loop either needs to be able to handle fewer than VF scalars, or needs to have a lower VF than the main loop. */ if (LOOP_VINFO_EPILOGUE_P (loop_vinfo) - && !LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) + && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) { poly_uint64 unscaled_vf = exact_div (LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo), @@ -3032,15 +3021,6 @@ start_over: " epilogue loop.\n"); } - /* Decide whether this loop_vinfo should use partial vectors or peeling, - assuming that the loop will be used as a main loop. We will redo - this analysis later if we instead decide to use the loop as an - epilogue loop. */ - ok = vect_determine_partial_vectors_and_peeling - (loop_vinfo, LOOP_VINFO_EPILOGUE_P (loop_vinfo)); - if (!ok) - return ok; - /* Check the costings of the loop make vectorizing worthwhile. */ res = vect_analyze_loop_costing (loop_vinfo, suggested_unroll_factor); if (res < 0) diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index a36974c..6b1cf6d 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -2316,8 +2316,7 @@ extern tree neutral_op_for_reduction (tree, code_helper, tree); extern widest_int vect_iv_limit_for_partial_vectors (loop_vec_info loop_vinfo); bool vect_rgroup_iv_might_wrap_p (loop_vec_info, rgroup_controls *); /* Used in tree-vect-loop-manip.cc */ -extern opt_result vect_determine_partial_vectors_and_peeling (loop_vec_info, - bool); +extern opt_result vect_determine_partial_vectors_and_peeling (loop_vec_info); /* Used in gimple-loop-interchange.c and tree-parloops.cc. */ extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree, enum tree_code); -- cgit v1.1 From fd4f48b37718748b39344129e70223a5d290c6eb Mon Sep 17 00:00:00 2001 From: Steve Baird Date: Tue, 6 Jun 2023 12:44:00 -0700 Subject: ada: Finalization not performed for component of protected type In some cases involving a discriminated protected type with an array component that is subject to a discriminant-dependent index constraint, where the element type of the array requires finalization and the array type has not yet been frozen at the point of the declaration of the protected type, finalization of an object of the protected type may incorrectly omit finalization of the array component. One case where this scenario can arise is an instantiation of Ada.Containers.Bounded_Synchronized_Queues, passing in an Element type that requires finalization. gcc/ada/ * exp_ch7.adb (Make_Final_Call): Add assertion that if no finalization call is generated, then the type of the object being finalized does not require finalization. * freeze.adb (Freeze_Entity): If freezing an already-frozen subtype, do not assume that nothing needs to be done. In the case of a frozen subtype of a non-frozen type or subtype (which is possible), freeze the non-frozen entity. --- gcc/ada/exp_ch7.adb | 2 ++ gcc/ada/freeze.adb | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index 1b16839..aa16c70 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -8387,6 +8387,8 @@ package body Exp_Ch7 is Param => Ref, Skip_Self => Skip_Self); else + pragma Assert (Serious_Errors_Detected > 0 + or else not Has_Controlled_Component (Utyp)); return Empty; end if; end Make_Final_Call; diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index 83ce030..38aeb24 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -6188,7 +6188,20 @@ package body Freeze is -- Do not freeze if already frozen since we only need one freeze node if Is_Frozen (E) then - Result := No_List; + + if Is_Itype (E) + and then not Is_Base_Type (E) + and then not Is_Frozen (Etype (E)) + then + -- If a frozen subtype of an unfrozen type seems impossible + -- then see Analyze_Protected_Definition.Undelay_Itypes. + + Result := Freeze_Entity + (Etype (E), N, Do_Freeze_Profile => Do_Freeze_Profile); + else + Result := No_List; + end if; + goto Leave; -- Do not freeze if we are preanalyzing without freezing -- cgit v1.1 From d1715f6e7613969d44ab6ab0585eb99200fd62cc Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Tue, 27 Jun 2023 11:49:09 +0200 Subject: ada: Improve error message on violation of SPARK_Mode rules SPARK_Mode On can only be used on library-level entities. Improve the error message here. gcc/ada/ * errout.ads: Add explain code. * sem_prag.adb (Check_Library_Level_Entity): Refine error message and add explain code. --- gcc/ada/errout.ads | 1 + gcc/ada/sem_prag.adb | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads index 80dd7df..2065d73 100644 --- a/gcc/ada/errout.ads +++ b/gcc/ada/errout.ads @@ -622,6 +622,7 @@ package Errout is GEC_Volatile_Non_Interfering_Context : constant := 0004; GEC_Required_Part_Of : constant := 0009; GEC_Ownership_Moved_Object : constant := 0010; + GEC_SPARK_Mode_On_Not_Library_Level : constant := 0011; ------------------------ -- List Pragmas Table -- diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index c581068..6de87fb 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -24144,7 +24144,8 @@ package body Sem_Prag is -- Local variables - Msg_1 : constant String := "incorrect placement of pragma%"; + Msg_1 : constant String := + "incorrect placement of pragma% with value ""On"" '[[]']"; Msg_2 : Name_Id; -- Start of processing for Check_Library_Level_Entity @@ -24161,6 +24162,7 @@ package body Sem_Prag is and then Instantiation_Location (Sloc (N)) = No_Location then Error_Msg_Name_1 := Pname; + Error_Msg_Code := GEC_SPARK_Mode_On_Not_Library_Level; Error_Msg_N (Fix_Error (Msg_1), N); Name_Len := 0; -- cgit v1.1 From 957b48650c8ad893b2b4995b4dcb0b560a0aad3f Mon Sep 17 00:00:00 2001 From: Viljar Indus Date: Wed, 14 Jun 2023 23:19:49 +0300 Subject: ada: Avoid crash in Find_Optional_Prim_Op Find_Optional_Prim_Op can crash when the Underlying_Type is Empty. This can happen when you are dealing with a structure type with a private part that does not have its Full_View set yet. gcc/ada/ * exp_util.adb (Find_Optional_Prim_Op): Stop deriving primitive operation if there is no underlying type to derive it from. --- gcc/ada/exp_util.adb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index c74921e..66e1acb 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -6291,6 +6291,11 @@ package body Exp_Util is Typ := Underlying_Type (Typ); + -- We cannot find the operation if there is no full view available. + if Typ = Empty then + return Empty; + end if; + -- Loop through primitive operations Prim := First_Elmt (Primitive_Operations (Typ)); -- cgit v1.1 From db01ce5381fc38c50454b544d6692d2b7e39ac29 Mon Sep 17 00:00:00 2001 From: Viljar Indus Date: Mon, 19 Jun 2023 14:11:20 +0300 Subject: ada: Reuse code in Is_Fully_Initialized_Type gcc/ada/ * sem_util.adb (Is_Fully_Initialized_Type): Avoid recalculating the underlying type twice. --- gcc/ada/sem_util.adb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 736751f..821aacf 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -17333,7 +17333,7 @@ package body Sem_Util is declare Init : constant Entity_Id := (Find_Optional_Prim_Op - (Underlying_Type (Typ), Name_Initialize)); + (Utyp, Name_Initialize)); begin if Present (Init) -- cgit v1.1 From d4fea89d289d45aa6811b9e1fa6d40ba9f28dd60 Mon Sep 17 00:00:00 2001 From: Viljar Indus Date: Tue, 20 Jun 2023 17:29:41 +0300 Subject: ada: Refer to non-Ada binding limitations in user guide The limitation of resetting the FPU mode for non 80-bit precision was not referenced from "Creating a Stand-alone Library to be used in a non-Ada context". Reference it the same way it is already referenced from "Interfacing to C". gcc/ada/ * doc/gnat_ugn/the_gnat_compilation_model.rst: Reference "Binding with Non-Ada Main Programs" from "Creating a Stand-alone Library to be used in a non-Ada context". * gnat_ugn.texi: Regenerate. --- .../doc/gnat_ugn/the_gnat_compilation_model.rst | 3 + gcc/ada/gnat_ugn.texi | 65 +++++++++++----------- 2 files changed, 37 insertions(+), 31 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst index e4639d9..148d408 100644 --- a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst +++ b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst @@ -2331,6 +2331,9 @@ finalization of all Ada libraries must be performed at the end of the program. No call to these libraries or to the Ada run-time library should be made after the finalization phase. +Information on limitations of binding Ada code in non-Ada contexts can be +found under :ref:`Binding_with_Non-Ada_Main_Programs`. + Note also that special care must be taken with multi-tasks applications. The initialization and finalization routines are not protected against concurrent access. If such requirement is needed it diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index 104adb9..37d914c 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -19,7 +19,7 @@ @copying @quotation -GNAT User's Guide for Native Platforms , Jul 04, 2023 +GNAT User's Guide for Native Platforms , Jul 06, 2023 AdaCore @@ -3857,6 +3857,9 @@ finalization of all Ada libraries must be performed at the end of the program. No call to these libraries or to the Ada run-time library should be made after the finalization phase. +Information on limitations of binding Ada code in non-Ada contexts can be +found under @ref{7e,,Binding with Non-Ada Main Programs}. + Note also that special care must be taken with multi-tasks applications. The initialization and finalization routines are not protected against concurrent access. If such requirement is needed it @@ -3864,7 +3867,7 @@ must be ensured at the application level using a specific operating system services like a mutex or a critical-section. @node Restrictions in Stand-alone Libraries,,Creating a Stand-alone Library to be used in a non-Ada context,Stand-alone Ada Libraries -@anchor{gnat_ugn/the_gnat_compilation_model id45}@anchor{7e}@anchor{gnat_ugn/the_gnat_compilation_model restrictions-in-stand-alone-libraries}@anchor{7f} +@anchor{gnat_ugn/the_gnat_compilation_model id45}@anchor{7f}@anchor{gnat_ugn/the_gnat_compilation_model restrictions-in-stand-alone-libraries}@anchor{80} @subsubsection Restrictions in Stand-alone Libraries @@ -3910,7 +3913,7 @@ In practice these attributes are rarely used, so this is unlikely to be a consideration. @node Rebuilding the GNAT Run-Time Library,,Stand-alone Ada Libraries,GNAT and Libraries -@anchor{gnat_ugn/the_gnat_compilation_model id46}@anchor{80}@anchor{gnat_ugn/the_gnat_compilation_model rebuilding-the-gnat-run-time-library}@anchor{81} +@anchor{gnat_ugn/the_gnat_compilation_model id46}@anchor{81}@anchor{gnat_ugn/the_gnat_compilation_model rebuilding-the-gnat-run-time-library}@anchor{82} @subsection Rebuilding the GNAT Run-Time Library @@ -3946,7 +3949,7 @@ experiments or debugging, and is not supported. @geindex Conditional compilation @node Conditional Compilation,Mixed Language Programming,GNAT and Libraries,The GNAT Compilation Model -@anchor{gnat_ugn/the_gnat_compilation_model conditional-compilation}@anchor{2b}@anchor{gnat_ugn/the_gnat_compilation_model id47}@anchor{82} +@anchor{gnat_ugn/the_gnat_compilation_model conditional-compilation}@anchor{2b}@anchor{gnat_ugn/the_gnat_compilation_model id47}@anchor{83} @section Conditional Compilation @@ -3963,7 +3966,7 @@ gnatprep preprocessor utility. @end menu @node Modeling Conditional Compilation in Ada,Preprocessing with gnatprep,,Conditional Compilation -@anchor{gnat_ugn/the_gnat_compilation_model id48}@anchor{83}@anchor{gnat_ugn/the_gnat_compilation_model modeling-conditional-compilation-in-ada}@anchor{84} +@anchor{gnat_ugn/the_gnat_compilation_model id48}@anchor{84}@anchor{gnat_ugn/the_gnat_compilation_model modeling-conditional-compilation-in-ada}@anchor{85} @subsection Modeling Conditional Compilation in Ada @@ -4014,7 +4017,7 @@ be achieved using Ada in general, and GNAT in particular. @end menu @node Use of Boolean Constants,Debugging - A Special Case,,Modeling Conditional Compilation in Ada -@anchor{gnat_ugn/the_gnat_compilation_model id49}@anchor{85}@anchor{gnat_ugn/the_gnat_compilation_model use-of-boolean-constants}@anchor{86} +@anchor{gnat_ugn/the_gnat_compilation_model id49}@anchor{86}@anchor{gnat_ugn/the_gnat_compilation_model use-of-boolean-constants}@anchor{87} @subsubsection Use of Boolean Constants @@ -4058,7 +4061,7 @@ Then any other unit requiring conditional compilation can do a `with' of @code{Config} to make the constants visible. @node Debugging - A Special Case,Conditionalizing Declarations,Use of Boolean Constants,Modeling Conditional Compilation in Ada -@anchor{gnat_ugn/the_gnat_compilation_model debugging-a-special-case}@anchor{87}@anchor{gnat_ugn/the_gnat_compilation_model id50}@anchor{88} +@anchor{gnat_ugn/the_gnat_compilation_model debugging-a-special-case}@anchor{88}@anchor{gnat_ugn/the_gnat_compilation_model id50}@anchor{89} @subsubsection Debugging - A Special Case @@ -4171,7 +4174,7 @@ end if; @end example @node Conditionalizing Declarations,Use of Alternative Implementations,Debugging - A Special Case,Modeling Conditional Compilation in Ada -@anchor{gnat_ugn/the_gnat_compilation_model conditionalizing-declarations}@anchor{89}@anchor{gnat_ugn/the_gnat_compilation_model id51}@anchor{8a} +@anchor{gnat_ugn/the_gnat_compilation_model conditionalizing-declarations}@anchor{8a}@anchor{gnat_ugn/the_gnat_compilation_model id51}@anchor{8b} @subsubsection Conditionalizing Declarations @@ -4236,7 +4239,7 @@ constant was introduced as @code{System.Default_Bit_Order}, so you do not need to define this one yourself). @node Use of Alternative Implementations,Preprocessing,Conditionalizing Declarations,Modeling Conditional Compilation in Ada -@anchor{gnat_ugn/the_gnat_compilation_model id52}@anchor{8b}@anchor{gnat_ugn/the_gnat_compilation_model use-of-alternative-implementations}@anchor{8c} +@anchor{gnat_ugn/the_gnat_compilation_model id52}@anchor{8c}@anchor{gnat_ugn/the_gnat_compilation_model use-of-alternative-implementations}@anchor{8d} @subsubsection Use of Alternative Implementations @@ -4370,7 +4373,7 @@ The same idea can also be implemented using tagged types and dispatching calls. @node Preprocessing,,Use of Alternative Implementations,Modeling Conditional Compilation in Ada -@anchor{gnat_ugn/the_gnat_compilation_model id53}@anchor{8d}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing}@anchor{8e} +@anchor{gnat_ugn/the_gnat_compilation_model id53}@anchor{8e}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing}@anchor{8f} @subsubsection Preprocessing @@ -4393,7 +4396,7 @@ The preprocessor may be used in two separate modes. It can be used quite separately from the compiler, to generate a separate output source file that is then fed to the compiler as a separate step. This is the @code{gnatprep} utility, whose use is fully described in -@ref{8f,,Preprocessing with gnatprep}. +@ref{90,,Preprocessing with gnatprep}. The preprocessing language allows such constructs as @@ -4413,10 +4416,10 @@ often more convenient. In this approach the preprocessing is integrated into the compilation process. The compiler is given the preprocessor input which includes @code{#if} lines etc, and then the compiler carries out the preprocessing internally and processes the resulting output. -For more details on this approach, see @ref{90,,Integrated Preprocessing}. +For more details on this approach, see @ref{91,,Integrated Preprocessing}. @node Preprocessing with gnatprep,Integrated Preprocessing,Modeling Conditional Compilation in Ada,Conditional Compilation -@anchor{gnat_ugn/the_gnat_compilation_model id54}@anchor{91}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing-with-gnatprep}@anchor{8f} +@anchor{gnat_ugn/the_gnat_compilation_model id54}@anchor{92}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing-with-gnatprep}@anchor{90} @subsection Preprocessing with @code{gnatprep} @@ -4441,7 +4444,7 @@ For further discussion of conditional compilation in general, see @end menu @node Preprocessing Symbols,Using gnatprep,,Preprocessing with gnatprep -@anchor{gnat_ugn/the_gnat_compilation_model id55}@anchor{92}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing-symbols}@anchor{93} +@anchor{gnat_ugn/the_gnat_compilation_model id55}@anchor{93}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing-symbols}@anchor{94} @subsubsection Preprocessing Symbols @@ -4451,7 +4454,7 @@ normal Ada (case-insensitive) rules for its syntax, with the restriction that all characters need to be in the ASCII set (no accented letters). @node Using gnatprep,Switches for gnatprep,Preprocessing Symbols,Preprocessing with gnatprep -@anchor{gnat_ugn/the_gnat_compilation_model id56}@anchor{94}@anchor{gnat_ugn/the_gnat_compilation_model using-gnatprep}@anchor{95} +@anchor{gnat_ugn/the_gnat_compilation_model id56}@anchor{95}@anchor{gnat_ugn/the_gnat_compilation_model using-gnatprep}@anchor{96} @subsubsection Using @code{gnatprep} @@ -4509,7 +4512,7 @@ optional, and can be replaced by the use of the @code{-D} switch. @end itemize @node Switches for gnatprep,Form of Definitions File,Using gnatprep,Preprocessing with gnatprep -@anchor{gnat_ugn/the_gnat_compilation_model id57}@anchor{96}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatprep}@anchor{97} +@anchor{gnat_ugn/the_gnat_compilation_model id57}@anchor{97}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatprep}@anchor{98} @subsubsection Switches for @code{gnatprep} @@ -4660,7 +4663,7 @@ deleted lines are completely removed from the output, unless -r is specified, in which case -b is assumed. @node Form of Definitions File,Form of Input Text for gnatprep,Switches for gnatprep,Preprocessing with gnatprep -@anchor{gnat_ugn/the_gnat_compilation_model form-of-definitions-file}@anchor{98}@anchor{gnat_ugn/the_gnat_compilation_model id58}@anchor{99} +@anchor{gnat_ugn/the_gnat_compilation_model form-of-definitions-file}@anchor{99}@anchor{gnat_ugn/the_gnat_compilation_model id58}@anchor{9a} @subsubsection Form of Definitions File @@ -4690,7 +4693,7 @@ the usual @code{--}, and comments may be added to the definitions lines. @node Form of Input Text for gnatprep,,Form of Definitions File,Preprocessing with gnatprep -@anchor{gnat_ugn/the_gnat_compilation_model form-of-input-text-for-gnatprep}@anchor{9a}@anchor{gnat_ugn/the_gnat_compilation_model id59}@anchor{9b} +@anchor{gnat_ugn/the_gnat_compilation_model form-of-input-text-for-gnatprep}@anchor{9b}@anchor{gnat_ugn/the_gnat_compilation_model id59}@anchor{9c} @subsubsection Form of Input Text for @code{gnatprep} @@ -4822,7 +4825,7 @@ Header : String := $XYZ; and then the substitution will occur as desired. @node Integrated Preprocessing,,Preprocessing with gnatprep,Conditional Compilation -@anchor{gnat_ugn/the_gnat_compilation_model id60}@anchor{9c}@anchor{gnat_ugn/the_gnat_compilation_model integrated-preprocessing}@anchor{90} +@anchor{gnat_ugn/the_gnat_compilation_model id60}@anchor{9d}@anchor{gnat_ugn/the_gnat_compilation_model integrated-preprocessing}@anchor{91} @subsection Integrated Preprocessing @@ -4883,7 +4886,7 @@ because @code{gnatmake} cannot compute the checksum of the source after preprocessing. The actual preprocessing function is described in detail in -@ref{8f,,Preprocessing with gnatprep}. This section explains the switches +@ref{90,,Preprocessing with gnatprep}. This section explains the switches that relate to integrated preprocessing. @geindex -gnatep (gcc) @@ -4982,7 +4985,7 @@ lines starting with the character ‘*’. After the file name or ‘*’, an optional literal string specifies the name of the definition file to be used for preprocessing -(@ref{98,,Form of Definitions File}). The definition files are found by the +(@ref{99,,Form of Definitions File}). The definition files are found by the compiler in one of the source directories. In some cases, when compiling a source in a directory other than the current directory, if the definition file is in the current directory, it may be necessary to add the current @@ -5074,7 +5077,7 @@ the output file will be @code{foo.adb.prep}. @end table @node Mixed Language Programming,GNAT and Other Compilation Models,Conditional Compilation,The GNAT Compilation Model -@anchor{gnat_ugn/the_gnat_compilation_model id61}@anchor{9d}@anchor{gnat_ugn/the_gnat_compilation_model mixed-language-programming}@anchor{2c} +@anchor{gnat_ugn/the_gnat_compilation_model id61}@anchor{9e}@anchor{gnat_ugn/the_gnat_compilation_model mixed-language-programming}@anchor{2c} @section Mixed Language Programming @@ -5094,7 +5097,7 @@ with a focus on combining Ada with C or C++. @end menu @node Interfacing to C,Calling Conventions,,Mixed Language Programming -@anchor{gnat_ugn/the_gnat_compilation_model id62}@anchor{9e}@anchor{gnat_ugn/the_gnat_compilation_model interfacing-to-c}@anchor{9f} +@anchor{gnat_ugn/the_gnat_compilation_model id62}@anchor{9f}@anchor{gnat_ugn/the_gnat_compilation_model interfacing-to-c}@anchor{a0} @subsection Interfacing to C @@ -5205,7 +5208,7 @@ $ gnatmake my_main.adb -largs file1.o file2.o If the main program is in a language other than Ada, then you may have more than one entry point into the Ada subsystem. You must use a special binder option to generate callable routines that initialize and -finalize the Ada units (@ref{a0,,Binding with Non-Ada Main Programs}). +finalize the Ada units (@ref{7e,,Binding with Non-Ada Main Programs}). Calls to the initialization and finalization routines must be inserted in the main program, or some other appropriate point in the code. The call to initialize the Ada units must occur before the first Ada @@ -9073,7 +9076,7 @@ Disable atomic synchronization @item @code{-gnateDsymbol[=`value']} Defines a symbol, associated with @code{value}, for preprocessing. -(@ref{90,,Integrated Preprocessing}). +(@ref{91,,Integrated Preprocessing}). @end table @geindex -gnateE (gcc) @@ -9221,7 +9224,7 @@ Specify a mapping file Specify a preprocessing data file (the equal sign is optional) -(@ref{90,,Integrated Preprocessing}). +(@ref{91,,Integrated Preprocessing}). @end table @geindex -gnateP (gcc) @@ -15947,7 +15950,7 @@ Output chosen elaboration order. @item @code{-L`xxx'} Bind the units for library building. In this case the @code{adainit} and -@code{adafinal} procedures (@ref{a0,,Binding with Non-Ada Main Programs}) +@code{adafinal} procedures (@ref{7e,,Binding with Non-Ada Main Programs}) are renamed to @code{@var{xxx}init} and @code{@var{xxx}final}. Implies -n. @@ -16608,7 +16611,7 @@ unless explicitly overridden by a @code{'Size} clause on the access type. These switches are only effective on VMS platforms. @node Binding with Non-Ada Main Programs,Binding Programs with No Main Subprogram,Dynamic Allocation Control,Switches for gnatbind -@anchor{gnat_ugn/building_executable_programs_with_gnat binding-with-non-ada-main-programs}@anchor{a0}@anchor{gnat_ugn/building_executable_programs_with_gnat id40}@anchor{11e} +@anchor{gnat_ugn/building_executable_programs_with_gnat binding-with-non-ada-main-programs}@anchor{7e}@anchor{gnat_ugn/building_executable_programs_with_gnat id40}@anchor{11e} @subsubsection Binding with Non-Ada Main Programs @@ -17496,7 +17499,7 @@ Other GNAT utilities are described elsewhere in this manual: @ref{1d,,Renaming Files with gnatchop} @item -@ref{8f,,Preprocessing with gnatprep} +@ref{90,,Preprocessing with gnatprep} @end itemize @menu @@ -24266,7 +24269,7 @@ To achieve this you must export an initialization routine (@code{Initialize_API} in the previous example), which must be invoked before using any of the DLL services. This elaboration routine must call the Ada elaboration routine @code{adainit} generated by the GNAT binder -(@ref{a0,,Binding with Non-Ada Main Programs}). See the body of +(@ref{7e,,Binding with Non-Ada Main Programs}). See the body of @code{Initialize_Api} for an example. Note that the GNAT binder is automatically invoked during the DLL build process by the @code{gnatdll} tool (@ref{1e9,,Using gnatdll}). @@ -24293,7 +24296,7 @@ invoke the DLL finalization routine, if available. The DLL finalization routine is in charge of releasing all resources acquired by the DLL. In the case of the Ada code contained in the DLL, this is achieved by calling routine @code{adafinal} generated by the GNAT binder -(@ref{a0,,Binding with Non-Ada Main Programs}). +(@ref{7e,,Binding with Non-Ada Main Programs}). See the body of @code{Finalize_Api} for an example. As already pointed out the GNAT binder is automatically invoked during the DLL build process by the @code{gnatdll} tool -- cgit v1.1 From 15e2d19ff46527d56407eaea64161943efc3e2b7 Mon Sep 17 00:00:00 2001 From: Viljar Indus Date: Wed, 21 Jun 2023 16:22:37 +0300 Subject: ada: Evaluate static expressions in Range attributes Gigi assumes that the value of range expressions is an integer literal. Force evaluation of such expressions since static non-literal expressions are not always evaluated to a literal form by gnat. gcc/ada/ * sem_attr.adb (analyze_attribute.check_array_type): Replace valid indexes with their staticly evaluated values. --- gcc/ada/sem_attr.adb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index 7a47abd..e00addd 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -2013,10 +2013,20 @@ package body Sem_Attr is Flag_Non_Static_Expr ("expression for dimension must be static!", E1); Error_Attr; - - elsif Expr_Value (E1) > D or else Expr_Value (E1) < 1 then - Error_Attr ("invalid dimension number for array type", E1); end if; + + declare + Value : constant Uint := Expr_Value (E1); + begin + + if Value > D or else Value < 1 then + Error_Attr ("invalid dimension number for array type", E1); + end if; + + -- Replace the static value to simplify the tree for gigi + Fold_Uint (E1, Value, True); + end; + end if; if (Style_Check and Style_Check_Array_Attribute_Index) -- cgit v1.1 From 70bcf5c4d39abb26106bb00faceb411c5b8d0c1b Mon Sep 17 00:00:00 2001 From: Claire Dross Date: Thu, 15 Jun 2023 16:22:11 +0200 Subject: ada: Refactor the proof of the Value and Image runtime units The aim of this refactoring is to avoid unnecessary dependencies between Image and Value units even though they share the same specification functions. These functions are grouped inside ghost packages which are then withed by Image and Value units. gcc/ada/ * libgnat/s-vs_int.ads: Instance of Value_I_Spec for Integer. * libgnat/s-vs_lli.ads: Instance of Value_I_Spec for Long_Long_Integer. * libgnat/s-vsllli.ads: Instance of Value_I_Spec for Long_Long_Long_Integer. * libgnat/s-vs_uns.ads: Instance of Value_U_Spec for Unsigned. * libgnat/s-vs_llu.ads: Instance of Value_U_Spec for Long_Long_Unsigned. * libgnat/s-vslllu.ads: Instance of Value_U_Spec for Long_Long_Long_Unsigned. * libgnat/s-imagei.ads: Take instances of Value_*_Spec as parameters. * libgnat/s-imagei.adb: Idem. * libgnat/s-imageu.ads: Idem. * libgnat/s-imageu.adb: Idem. * libgnat/s-valuei.ads: Idem. * libgnat/s-valuei.adb: Idem. * libgnat/s-valueu.ads: Idem. * libgnat/s-valueu.adb: Idem. * libgnat/s-imgint.ads: Adapt instance to new ghost parameters. * libgnat/s-imglli.ads: Adapt instance to new ghost parameters. * libgnat/s-imgllli.ads: Adapt instance to new ghost parameters. * libgnat/s-imglllu.ads: Adapt instance to new ghost parameters. * libgnat/s-imgllu.ads: Adapt instance to new ghost parameters. * libgnat/s-imguns.ads: Adapt instance to new ghost parameters. * libgnat/s-valint.ads: Adapt instance to new ghost parameters. * libgnat/s-vallli.ads: Adapt instance to new ghost parameters. * libgnat/s-valllli.ads: Adapt instance to new ghost parameters. * libgnat/s-vallllu.ads: Adapt instance to new ghost parameters. * libgnat/s-valllu.ads: Adapt instance to new ghost parameters. * libgnat/s-valuns.ads: Adapt instance to new ghost parameters. * libgnat/s-vaispe.ads: Take instance of Value_U_Spec as parameter and remove unused declaration. * libgnat/s-vaispe.adb: Idem. * libgnat/s-vauspe.ads: Remove unused declaration. * libgnat/s-valspe.ads: Factor out the specification part of Val_Util. * libgnat/s-valspe.adb: Idem. * libgnat/s-valuti.ads: Move specification to Val_Spec. * libgnat/s-valuti.adb: Idem. * libgnat/s-valboo.ads: Use Val_Spec. * libgnat/s-valboo.adb: Idem. * libgnat/s-imgboo.adb: Idem. * libgnat/s-imagef.adb: Adapt instances to new ghost parameters. * Makefile.rtl: List new files. --- gcc/ada/Makefile.rtl | 7 + gcc/ada/libgnat/s-imagef.adb | 12 +- gcc/ada/libgnat/s-imagei.adb | 4 +- gcc/ada/libgnat/s-imagei.ads | 17 +- gcc/ada/libgnat/s-imageu.adb | 81 +++----- gcc/ada/libgnat/s-imageu.ads | 20 +- gcc/ada/libgnat/s-imgboo.adb | 6 +- gcc/ada/libgnat/s-imgint.ads | 13 +- gcc/ada/libgnat/s-imglli.ads | 14 +- gcc/ada/libgnat/s-imgllli.ads | 14 +- gcc/ada/libgnat/s-imglllu.ads | 10 +- gcc/ada/libgnat/s-imgllu.ads | 9 +- gcc/ada/libgnat/s-imguns.ads | 9 +- gcc/ada/libgnat/s-vaispe.adb | 10 +- gcc/ada/libgnat/s-vaispe.ads | 42 ++-- gcc/ada/libgnat/s-valboo.adb | 2 +- gcc/ada/libgnat/s-valboo.ads | 12 +- gcc/ada/libgnat/s-valint.ads | 5 +- gcc/ada/libgnat/s-vallli.ads | 5 +- gcc/ada/libgnat/s-valllli.ads | 5 +- gcc/ada/libgnat/s-vallllu.ads | 3 +- gcc/ada/libgnat/s-valllu.ads | 3 +- gcc/ada/libgnat/s-valspe.adb | 82 ++++++++ gcc/ada/libgnat/s-valspe.ads | 211 +++++++++++++++++++ gcc/ada/libgnat/s-valuei.adb | 6 +- gcc/ada/libgnat/s-valuei.ads | 21 +- gcc/ada/libgnat/s-valueu.adb | 1 + gcc/ada/libgnat/s-valueu.ads | 8 +- gcc/ada/libgnat/s-valuns.ads | 3 +- gcc/ada/libgnat/s-valuti.adb | 50 +---- gcc/ada/libgnat/s-valuti.ads | 474 ++---------------------------------------- gcc/ada/libgnat/s-vauspe.ads | 53 ++--- gcc/ada/libgnat/s-vs_int.ads | 59 ++++++ gcc/ada/libgnat/s-vs_lli.ads | 60 ++++++ gcc/ada/libgnat/s-vs_llu.ads | 58 ++++++ gcc/ada/libgnat/s-vs_uns.ads | 57 +++++ gcc/ada/libgnat/s-vsllli.ads | 60 ++++++ gcc/ada/libgnat/s-vslllu.ads | 58 ++++++ 38 files changed, 835 insertions(+), 729 deletions(-) create mode 100644 gcc/ada/libgnat/s-valspe.adb create mode 100644 gcc/ada/libgnat/s-valspe.ads create mode 100644 gcc/ada/libgnat/s-vs_int.ads create mode 100644 gcc/ada/libgnat/s-vs_lli.ads create mode 100644 gcc/ada/libgnat/s-vs_llu.ads create mode 100644 gcc/ada/libgnat/s-vs_uns.ads create mode 100644 gcc/ada/libgnat/s-vsllli.ads create mode 100644 gcc/ada/libgnat/s-vslllu.ads (limited to 'gcc') diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl index ca4c528..b94caa4 100644 --- a/gcc/ada/Makefile.rtl +++ b/gcc/ada/Makefile.rtl @@ -772,6 +772,7 @@ GNATRTL_NONTASKING_OBJS= \ s-vallli$(objext) \ s-valllu$(objext) \ s-valrea$(objext) \ + s-valspe$(objext) \ s-valued$(objext) \ s-valuef$(objext) \ s-valuei$(objext) \ @@ -785,6 +786,10 @@ GNATRTL_NONTASKING_OBJS= \ s-veboop$(objext) \ s-vector$(objext) \ s-vercon$(objext) \ + s-vs_int$(objext) \ + s-vs_lli$(objext) \ + s-vs_llu$(objext) \ + s-vs_uns$(objext) \ s-wchcnv$(objext) \ s-wchcon$(objext) \ s-wchjis$(objext) \ @@ -1030,6 +1035,8 @@ GNATRTL_128BIT_OBJS = \ s-vafi128$(objext) \ s-valllli$(objext) \ s-vallllu$(objext) \ + s-vsllli$(objext) \ + s-vslllu$(objext) \ s-widllli$(objext) \ s-widlllu$(objext) diff --git a/gcc/ada/libgnat/s-imagef.adb b/gcc/ada/libgnat/s-imagef.adb index a10dfdc..3f6bfa2 100644 --- a/gcc/ada/libgnat/s-imagef.adb +++ b/gcc/ada/libgnat/s-imagef.adb @@ -70,16 +70,14 @@ package body System.Image_F is -- if the small is larger than 1, and smaller than 2**(Int'Size - 1) / 10 -- if the small is smaller than 1. - Unsigned_Width_Ghost : constant Natural := Int'Width; - package Uns_Spec is new System.Value_U_Spec (Uns); - package Int_Spec is new System.Value_I_Spec (Int, Uns, Uns_Spec.Uns_Params); + package Int_Spec is new System.Value_I_Spec (Int, Uns, Uns_Spec); package Image_I is new System.Image_I - (Int => Int, - Uns => Uns, - Unsigned_Width_Ghost => Unsigned_Width_Ghost, - Int_Params => Int_Spec.Int_Params); + (Int => Int, + Uns => Uns, + U_Spec => Uns_Spec, + I_Spec => Int_Spec); procedure Set_Image_Integer (V : Int; diff --git a/gcc/ada/libgnat/s-imagei.adb b/gcc/ada/libgnat/s-imagei.adb index a56d635..cbe03e7 100644 --- a/gcc/ada/libgnat/s-imagei.adb +++ b/gcc/ada/libgnat/s-imagei.adb @@ -32,6 +32,8 @@ with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; use Ada.Numerics.Big_Numbers.Big_Integers_Ghost; +with System.Val_Spec; + package body System.Image_I is -- Ghost code, loop invariants and assertions in this unit are meant for @@ -149,7 +151,7 @@ package body System.Image_I is and then UP.Only_Decimal_Ghost (S, From => 2, To => P) and then UP.Scan_Based_Number_Ghost (S, From => 2, To => P) = UP.Wrap_Option (IP.Abs_Uns_Of_Int (V)), - Post => not System.Val_Util.Only_Space_Ghost (S, 1, P) + Post => not System.Val_Spec.Only_Space_Ghost (S, 1, P) and then IP.Is_Integer_Ghost (S (1 .. P)) and then IP.Is_Value_Integer_Ghost (S (1 .. P), V); -- Ghost lemma to prove the value of Value_Integer from the value of diff --git a/gcc/ada/libgnat/s-imagei.ads b/gcc/ada/libgnat/s-imagei.ads index 38c6e6e..7e39f86 100644 --- a/gcc/ada/libgnat/s-imagei.ads +++ b/gcc/ada/libgnat/s-imagei.ads @@ -45,23 +45,26 @@ pragma Assertion_Policy (Pre => Ignore, Ghost => Ignore, Subprogram_Variant => Ignore); -with System.Val_Util; +with System.Value_I_Spec; +with System.Value_U_Spec; generic type Int is range <>; type Uns is mod <>; - Unsigned_Width_Ghost : Natural; + -- Additional parameters for ghost subprograms used inside contracts - with package Int_Params is new System.Val_Util.Int_Params - (Int => Int, Uns => Uns, others => <>) - with Ghost; + with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; + with package I_Spec is new System.Value_I_Spec + (Int => Int, Uns => Uns, U_Spec => U_Spec) with Ghost; package System.Image_I is - package IP renames Int_Params; - package UP renames IP.Uns_Params; + package IP renames I_Spec; + package UP renames U_Spec; use type UP.Uns_Option; + Unsigned_Width_Ghost : constant Natural := U_Spec.Max_Log10 + 2 with Ghost; + procedure Image_Integer (V : Int; S : in out String; diff --git a/gcc/ada/libgnat/s-imageu.adb b/gcc/ada/libgnat/s-imageu.adb index eb1d054..919b401 100644 --- a/gcc/ada/libgnat/s-imageu.adb +++ b/gcc/ada/libgnat/s-imageu.adb @@ -31,6 +31,7 @@ with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; use Ada.Numerics.Big_Numbers.Big_Integers_Ghost; +with System.Val_Spec; package body System.Image_U is @@ -54,17 +55,6 @@ package body System.Image_U is Big_10 : constant Big_Integer := Big (10) with Ghost; - -- Maximum value of exponent for 10 that fits in Uns'Base - function Max_Log10 return Natural is - (case Uns'Base'Size is - when 8 => 2, - when 16 => 4, - when 32 => 9, - when 64 => 19, - when 128 => 38, - when others => raise Program_Error) - with Ghost; - ------------------ -- Local Lemmas -- ------------------ @@ -86,11 +76,6 @@ package body System.Image_U is Ghost, Post => X / Y / Z = X / (Y * Z); - procedure Lemma_Unsigned_Width_Ghost - with - Ghost, - Post => Unsigned_Width_Ghost = Max_Log10 + 2; - --------------------------- -- Lemma_Div_Commutation -- --------------------------- @@ -117,18 +102,6 @@ package body System.Image_U is pragma Assert (X / YZ = XYZ + R / YZ); end Lemma_Div_Twice; - -------------------------------- - -- Lemma_Unsigned_Width_Ghost -- - -------------------------------- - - procedure Lemma_Unsigned_Width_Ghost is - begin - pragma Assert (Unsigned_Width_Ghost <= Max_Log10 + 2); - pragma Assert (Big (Uns'Last) > Big_10 ** Max_Log10); - pragma Assert (Big (Uns'Last) < Big_10 ** (Unsigned_Width_Ghost - 1)); - pragma Assert (Unsigned_Width_Ghost >= Max_Log10 + 2); - end Lemma_Unsigned_Width_Ghost; - -------------------- -- Image_Unsigned -- -------------------- @@ -147,12 +120,12 @@ package body System.Image_U is and then S'Last < Integer'Last and then P in 2 .. S'Last and then S (1) = ' ' - and then Uns_Params.Only_Decimal_Ghost (S, From => 2, To => P) - and then Uns_Params.Scan_Based_Number_Ghost (S, From => 2, To => P) - = Uns_Params.Wrap_Option (V), - Post => not System.Val_Util.Only_Space_Ghost (S, 1, P) - and then Uns_Params.Is_Unsigned_Ghost (S (1 .. P)) - and then Uns_Params.Is_Value_Unsigned_Ghost (S (1 .. P), V); + and then U_Spec.Only_Decimal_Ghost (S, From => 2, To => P) + and then U_Spec.Scan_Based_Number_Ghost (S, From => 2, To => P) + = U_Spec.Wrap_Option (V), + Post => not System.Val_Spec.Only_Space_Ghost (S, 1, P) + and then U_Spec.Is_Unsigned_Ghost (S (1 .. P)) + and then U_Spec.Is_Value_Unsigned_Ghost (S (1 .. P), V); -- Ghost lemma to prove the value of Value_Unsigned from the value of -- Scan_Based_Number_Ghost on a decimal string. @@ -166,13 +139,13 @@ package body System.Image_U is pragma Assert (Str'First = 1); pragma Assert (S (2) /= ' '); pragma Assert - (Uns_Params.Only_Decimal_Ghost (Str, From => 2, To => P)); - Uns_Params.Prove_Scan_Based_Number_Ghost_Eq + (U_Spec.Only_Decimal_Ghost (Str, From => 2, To => P)); + U_Spec.Prove_Scan_Based_Number_Ghost_Eq (S, Str, From => 2, To => P); pragma Assert - (Uns_Params.Scan_Based_Number_Ghost (Str, From => 2, To => P) - = Uns_Params.Wrap_Option (V)); - Uns_Params.Prove_Scan_Only_Decimal_Ghost (Str, V); + (U_Spec.Scan_Based_Number_Ghost (Str, From => 2, To => P) + = U_Spec.Wrap_Option (V)); + U_Spec.Prove_Scan_Only_Decimal_Ghost (Str, V); end Prove_Value_Unsigned; -- Start of processing for Image_Unsigned @@ -227,7 +200,7 @@ package body System.Image_U is with Ghost, Pre => R in 0 .. 9, - Post => Uns_Params.Hexa_To_Unsigned_Ghost (Character'Val (48 + R)) = R; + Post => U_Spec.Hexa_To_Unsigned_Ghost (Character'Val (48 + R)) = R; -- Ghost lemma to prove that Hexa_To_Unsigned_Ghost returns the source -- figure when applied to the corresponding character. @@ -245,26 +218,26 @@ package body System.Image_U is and then (for all I in P + 1 .. Max => Prev_S (I) = S (I)) and then S (P) in '0' .. '9' and then V <= Uns'Last / 10 - and then Uns'Last - Uns_Params.Hexa_To_Unsigned_Ghost (S (P)) + and then Uns'Last - U_Spec.Hexa_To_Unsigned_Ghost (S (P)) >= 10 * V and then Prev_V = - V * 10 + Uns_Params.Hexa_To_Unsigned_Ghost (S (P)) + V * 10 + U_Spec.Hexa_To_Unsigned_Ghost (S (P)) and then (if P = Max then Prev_V = Res - else Uns_Params.Scan_Based_Number_Ghost + else U_Spec.Scan_Based_Number_Ghost (Str => Prev_S, From => P + 1, To => Max, Base => 10, - Acc => Prev_V) = Uns_Params.Wrap_Option (Res)), + Acc => Prev_V) = U_Spec.Wrap_Option (Res)), Post => (for all I in P .. Max => S (I) in '0' .. '9') - and then Uns_Params.Scan_Based_Number_Ghost + and then U_Spec.Scan_Based_Number_Ghost (Str => S, From => P, To => Max, Base => 10, - Acc => V) = Uns_Params.Wrap_Option (Res); + Acc => V) = U_Spec.Wrap_Option (Res); -- Ghost lemma to prove that Scan_Based_Number_Ghost is preserved -- through an iteration of the loop. @@ -287,17 +260,17 @@ package body System.Image_U is is pragma Unreferenced (Res); begin - Uns_Params.Lemma_Scan_Based_Number_Ghost_Step + U_Spec.Lemma_Scan_Based_Number_Ghost_Step (Str => S, From => P, To => Max, Base => 10, Acc => V); if P < Max then - Uns_Params.Prove_Scan_Based_Number_Ghost_Eq + U_Spec.Prove_Scan_Based_Number_Ghost_Eq (Prev_S, S, P + 1, Max, 10, Prev_V); else - Uns_Params.Lemma_Scan_Based_Number_Ghost_Base + U_Spec.Lemma_Scan_Based_Number_Ghost_Base (Str => S, From => P + 1, To => Max, @@ -314,8 +287,6 @@ package body System.Image_U is -- No check is done since, as documented in the specification, the -- caller guarantees that S is long enough to hold the result. - Lemma_Unsigned_Width_Ghost; - -- First we compute the number of characters needed for representing -- the number. loop @@ -359,7 +330,7 @@ package body System.Image_U is Prove_Euclidian (Val => Prev_Value, Quot => Value, - Rest => Uns_Params.Hexa_To_Unsigned_Ghost (S (P + J))); + Rest => U_Spec.Hexa_To_Unsigned_Ghost (S (P + J))); Prove_Scan_Iter (S, Prev_S, Value, Prev_Value, V, P + J, P + Nb_Digits); @@ -368,18 +339,18 @@ package body System.Image_U is pragma Loop_Invariant (for all K in S'First .. P => S (K) = S_Init (K)); pragma Loop_Invariant - (Uns_Params.Only_Decimal_Ghost + (U_Spec.Only_Decimal_Ghost (S, From => P + J, To => P + Nb_Digits)); pragma Loop_Invariant (Pow = Big_10 ** (Nb_Digits - J + 1)); pragma Loop_Invariant (Big (Value) = Big (V) / Pow); pragma Loop_Invariant - (Uns_Params.Scan_Based_Number_Ghost + (U_Spec.Scan_Based_Number_Ghost (Str => S, From => P + J, To => P + Nb_Digits, Base => 10, Acc => Value) - = Uns_Params.Wrap_Option (V)); + = U_Spec.Wrap_Option (V)); end loop; pragma Assert (Big (Value) = Big (V) / (Big_10 ** Nb_Digits)); pragma Assert (Value = 0); diff --git a/gcc/ada/libgnat/s-imageu.ads b/gcc/ada/libgnat/s-imageu.ads index 1c58ea1..cec5263 100644 --- a/gcc/ada/libgnat/s-imageu.ads +++ b/gcc/ada/libgnat/s-imageu.ads @@ -45,7 +45,7 @@ pragma Assertion_Policy (Pre => Ignore, Ghost => Ignore, Subprogram_Variant => Ignore); -with System.Val_Util; +with System.Value_U_Spec; generic @@ -53,14 +53,12 @@ generic -- Additional parameters for ghost subprograms used inside contracts - Unsigned_Width_Ghost : Natural; - - with package Uns_Params is new System.Val_Util.Uns_Params - (Uns => Uns, others => <>) - with Ghost; + with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; package System.Image_U is - use all type Uns_Params.Uns_Option; + use all type U_Spec.Uns_Option; + + Unsigned_Width_Ghost : constant Natural := U_Spec.Max_Log10 + 2 with Ghost; procedure Image_Unsigned (V : Uns; @@ -71,7 +69,7 @@ package System.Image_U is and then S'Last < Integer'Last and then S'Last >= Unsigned_Width_Ghost, Post => P in S'Range - and then Uns_Params.Is_Value_Unsigned_Ghost (S (1 .. P), V); + and then U_Spec.Is_Value_Unsigned_Ghost (S (1 .. P), V); pragma Inline (Image_Unsigned); -- Computes Uns'Image (V) and stores the result in S (1 .. P) setting -- the resulting value of P. The caller guarantees that S is long enough to @@ -89,10 +87,10 @@ package System.Image_U is and then P <= S'Last - Unsigned_Width_Ghost + 1, Post => S (S'First .. P'Old) = S'Old (S'First .. P'Old) and then P in P'Old + 1 .. S'Last - and then Uns_Params.Only_Decimal_Ghost (S, From => P'Old + 1, To => P) - and then Uns_Params.Scan_Based_Number_Ghost + and then U_Spec.Only_Decimal_Ghost (S, From => P'Old + 1, To => P) + and then U_Spec.Scan_Based_Number_Ghost (S, From => P'Old + 1, To => P) - = Uns_Params.Wrap_Option (V); + = U_Spec.Wrap_Option (V); -- Stores the image of V in S starting at S (P + 1), P is updated to point -- to the last character stored. The value stored is identical to the value -- of Uns'Image (V) except that no leading space is stored. The caller diff --git a/gcc/ada/libgnat/s-imgboo.adb b/gcc/ada/libgnat/s-imgboo.adb index fd1d9a6..fb3301a 100644 --- a/gcc/ada/libgnat/s-imgboo.adb +++ b/gcc/ada/libgnat/s-imgboo.adb @@ -37,7 +37,7 @@ pragma Assertion_Policy (Ghost => Ignore, Loop_Invariant => Ignore, Assert => Ignore); -with System.Val_Util; +with System.Val_Spec; package body System.Img_Bool with SPARK_Mode @@ -58,12 +58,12 @@ is S (1 .. 4) := "TRUE"; P := 4; pragma Assert - (System.Val_Util.First_Non_Space_Ghost (S, S'First, S'Last) = 1); + (System.Val_Spec.First_Non_Space_Ghost (S, S'First, S'Last) = 1); else S (1 .. 5) := "FALSE"; P := 5; pragma Assert - (System.Val_Util.First_Non_Space_Ghost (S, S'First, S'Last) = 1); + (System.Val_Spec.First_Non_Space_Ghost (S, S'First, S'Last) = 1); end if; end Image_Boolean; diff --git a/gcc/ada/libgnat/s-imgint.ads b/gcc/ada/libgnat/s-imgint.ads index 320edc9..fe93899 100644 --- a/gcc/ada/libgnat/s-imgint.ads +++ b/gcc/ada/libgnat/s-imgint.ads @@ -47,8 +47,8 @@ pragma Assertion_Policy (Pre => Ignore, with System.Image_I; with System.Unsigned_Types; -with System.Val_Int; -with System.Wid_Uns; +with System.Vs_Int; +with System.Vs_Uns; package System.Img_Int with SPARK_Mode @@ -56,11 +56,10 @@ is subtype Unsigned is Unsigned_Types.Unsigned; package Impl is new Image_I - (Int => Integer, - Uns => Unsigned, - Unsigned_Width_Ghost => - Wid_Uns.Width_Unsigned (0, Unsigned'Last), - Int_Params => System.Val_Int.Impl.Spec.Int_Params); + (Int => Integer, + Uns => Unsigned, + U_Spec => System.Vs_Uns.Spec, + I_Spec => System.Vs_Int.Spec); procedure Image_Integer (V : Integer; diff --git a/gcc/ada/libgnat/s-imglli.ads b/gcc/ada/libgnat/s-imglli.ads index 1d34e77..809ca10 100644 --- a/gcc/ada/libgnat/s-imglli.ads +++ b/gcc/ada/libgnat/s-imglli.ads @@ -47,8 +47,8 @@ pragma Assertion_Policy (Pre => Ignore, with System.Image_I; with System.Unsigned_Types; -with System.Val_LLI; -with System.Wid_LLU; +with System.Vs_LLI; +with System.Vs_LLU; package System.Img_LLI with SPARK_Mode @@ -56,12 +56,10 @@ is subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; package Impl is new Image_I - (Int => Long_Long_Integer, - Uns => Long_Long_Unsigned, - Unsigned_Width_Ghost => - Wid_LLU.Width_Long_Long_Unsigned - (0, Long_Long_Unsigned'Last), - Int_Params => System.Val_LLI.Impl.Spec.Int_Params); + (Int => Long_Long_Integer, + Uns => Long_Long_Unsigned, + U_Spec => System.Vs_LLU.Spec, + I_Spec => System.Vs_LLI.Spec); procedure Image_Long_Long_Integer (V : Long_Long_Integer; diff --git a/gcc/ada/libgnat/s-imgllli.ads b/gcc/ada/libgnat/s-imgllli.ads index 05dec5e..727388f 100644 --- a/gcc/ada/libgnat/s-imgllli.ads +++ b/gcc/ada/libgnat/s-imgllli.ads @@ -47,8 +47,8 @@ pragma Assertion_Policy (Pre => Ignore, with System.Image_I; with System.Unsigned_Types; -with System.Val_LLLI; -with System.Wid_LLLU; +with System.Vs_LLLI; +with System.Vs_LLLU; package System.Img_LLLI with SPARK_Mode @@ -56,12 +56,10 @@ is subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; package Impl is new Image_I - (Int => Long_Long_Long_Integer, - Uns => Long_Long_Long_Unsigned, - Unsigned_Width_Ghost => - Wid_LLLU.Width_Long_Long_Long_Unsigned - (0, Long_Long_Long_Unsigned'Last), - Int_Params => System.Val_LLLI.Impl.Spec.Int_Params); + (Int => Long_Long_Long_Integer, + Uns => Long_Long_Long_Unsigned, + U_Spec => System.Vs_LLLU.Spec, + I_Spec => System.Vs_LLLI.Spec); procedure Image_Long_Long_Long_Integer (V : Long_Long_Long_Integer; diff --git a/gcc/ada/libgnat/s-imglllu.ads b/gcc/ada/libgnat/s-imglllu.ads index 888d782..09c8965 100644 --- a/gcc/ada/libgnat/s-imglllu.ads +++ b/gcc/ada/libgnat/s-imglllu.ads @@ -47,8 +47,7 @@ pragma Assertion_Policy (Pre => Ignore, with System.Image_U; with System.Unsigned_Types; -with System.Val_LLLU; -with System.Wid_LLLU; +with System.Vs_LLLU; package System.Img_LLLU with SPARK_Mode @@ -56,11 +55,8 @@ is subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; package Impl is new Image_U - (Uns => Long_Long_Long_Unsigned, - Unsigned_Width_Ghost => - Wid_LLLU.Width_Long_Long_Long_Unsigned - (0, Long_Long_Long_Unsigned'Last), - Uns_Params => System.Val_LLLU.Impl.Spec.Uns_Params); + (Uns => Long_Long_Long_Unsigned, + U_Spec => System.Vs_LLLU.Spec); procedure Image_Long_Long_Long_Unsigned (V : Long_Long_Long_Unsigned; diff --git a/gcc/ada/libgnat/s-imgllu.ads b/gcc/ada/libgnat/s-imgllu.ads index b00dc66..9709c96 100644 --- a/gcc/ada/libgnat/s-imgllu.ads +++ b/gcc/ada/libgnat/s-imgllu.ads @@ -47,8 +47,7 @@ pragma Assertion_Policy (Pre => Ignore, with System.Image_U; with System.Unsigned_Types; -with System.Val_LLU; -with System.Wid_LLU; +with System.Vs_LLU; package System.Img_LLU with SPARK_Mode @@ -56,10 +55,8 @@ is subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; package Impl is new Image_U - (Uns => Long_Long_Unsigned, - Unsigned_Width_Ghost => - Wid_LLU.Width_Long_Long_Unsigned (0, Long_Long_Unsigned'Last), - Uns_Params => System.Val_LLU.Impl.Spec.Uns_Params); + (Uns => Long_Long_Unsigned, + U_Spec => System.Vs_LLU.Spec); procedure Image_Long_Long_Unsigned (V : Long_Long_Unsigned; diff --git a/gcc/ada/libgnat/s-imguns.ads b/gcc/ada/libgnat/s-imguns.ads index 2bd7216..7c79a66 100644 --- a/gcc/ada/libgnat/s-imguns.ads +++ b/gcc/ada/libgnat/s-imguns.ads @@ -47,8 +47,7 @@ pragma Assertion_Policy (Pre => Ignore, with System.Image_U; with System.Unsigned_Types; -with System.Val_Uns; -with System.Wid_Uns; +with System.Vs_Uns; package System.Img_Uns with SPARK_Mode @@ -56,10 +55,8 @@ is subtype Unsigned is Unsigned_Types.Unsigned; package Impl is new Image_U - (Uns => Unsigned, - Unsigned_Width_Ghost => - Wid_Uns.Width_Unsigned (0, Unsigned'Last), - Uns_Params => System.Val_Uns.Impl.Spec.Uns_Params); + (Uns => Unsigned, + U_Spec => System.Vs_Uns.Spec); procedure Image_Unsigned (V : Unsigned; diff --git a/gcc/ada/libgnat/s-vaispe.adb b/gcc/ada/libgnat/s-vaispe.adb index b1a3884..a13dc6a8 100644 --- a/gcc/ada/libgnat/s-vaispe.adb +++ b/gcc/ada/libgnat/s-vaispe.adb @@ -71,14 +71,14 @@ package body System.Value_I_Spec is begin Prove_Conversion_Is_Identity (Val, Uval); pragma Assert - (Uns_Params.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last))); + (U_Spec.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last))); pragma Assert - (Uns_Params.Scan_Split_No_Overflow_Ghost (Str, Fst_Num, Str'Last)); - Uns_Params.Lemma_Exponent_Unsigned_Ghost_Base (Uval, 0, 10); + (U_Spec.Scan_Split_No_Overflow_Ghost (Str, Fst_Num, Str'Last)); + U_Spec.Lemma_Exponent_Unsigned_Ghost_Base (Uval, 0, 10); pragma Assert - (Uns_Params.Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Str'Last)); + (U_Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Str'Last)); pragma Assert (Only_Space_Ghost - (Str, Uns_Params.Raw_Unsigned_Last_Ghost + (Str, U_Spec.Raw_Unsigned_Last_Ghost (Str, Fst_Num, Str'Last), Str'Last)); pragma Assert (Is_Integer_Ghost (Str)); pragma Assert (Is_Value_Integer_Ghost (Str, Val)); diff --git a/gcc/ada/libgnat/s-vaispe.ads b/gcc/ada/libgnat/s-vaispe.ads index e74202d7..33cc1f6 100644 --- a/gcc/ada/libgnat/s-vaispe.ads +++ b/gcc/ada/libgnat/s-vaispe.ads @@ -44,7 +44,8 @@ pragma Assertion_Policy (Pre => Ignore, Ghost => Ignore, Subprogram_Variant => Ignore); -with System.Val_Util; use System.Val_Util; +with System.Value_U_Spec; +with System.Val_Spec; use System.Val_Spec; generic @@ -52,12 +53,9 @@ generic type Uns is mod <>; - -- Additional parameters for specification subprograms on modular Unsigned - -- integers. + -- Additional parameters for ghost subprograms used inside contracts - with package Uns_Params is new System.Val_Util.Uns_Params - (Uns => Uns, others => <>) - with Ghost; + with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; package System.Value_I_Spec with Ghost, @@ -65,7 +63,7 @@ package System.Value_I_Spec with Always_Terminates is pragma Preelaborate; - use all type Uns_Params.Uns_Option; + use all type U_Spec.Uns_Option; function Uns_Is_Valid_Int (Minus : Boolean; Uval : Uns) return Boolean is (if Minus then Uval <= Uns (Int'Last) + 1 @@ -113,16 +111,16 @@ is Fst_Num : constant Positive := (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 else Non_Blank); begin - Uns_Params.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last)) - and then Uns_Params.Raw_Unsigned_No_Overflow_Ghost + U_Spec.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last)) + and then U_Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Str'Last) and then Uns_Is_Valid_Int (Minus => Str (Non_Blank) = '-', - Uval => Uns_Params.Scan_Raw_Unsigned_Ghost + Uval => U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Str'Last)) and then Only_Space_Ghost - (Str, Uns_Params.Raw_Unsigned_Last_Ghost + (Str, U_Spec.Raw_Unsigned_Last_Ghost (Str, Fst_Num, Str'Last), Str'Last)) with Pre => not Only_Space_Ghost (Str, Str'First, Str'Last) @@ -140,7 +138,7 @@ is Fst_Num : constant Positive := (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 else Non_Blank); Uval : constant Uns := - Uns_Params.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Str'Last); + U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Str'Last); begin Is_Int_Of_Uns (Minus => Str (Non_Blank) = '-', Uval => Uval, @@ -160,30 +158,16 @@ is and then Str'Length >= 2 and then Str (Str'First) in ' ' | '-' and then (Str (Str'First) = '-') = (Val < 0) - and then Uns_Params.Only_Decimal_Ghost (Str, Str'First + 1, Str'Last) - and then Uns_Params.Scan_Based_Number_Ghost + and then U_Spec.Only_Decimal_Ghost (Str, Str'First + 1, Str'Last) + and then U_Spec.Scan_Based_Number_Ghost (Str, Str'First + 1, Str'Last) - = Uns_Params.Wrap_Option (Abs_Uns_Of_Int (Val)), + = U_Spec.Wrap_Option (Abs_Uns_Of_Int (Val)), Post => Is_Integer_Ghost (Slide_If_Necessary (Str)) and then Is_Value_Integer_Ghost (Str, Val); -- Ghost lemma used in the proof of 'Image implementation, to prove that -- the result of Value_Integer on a decimal string is the same as the -- signing the result of Scan_Based_Number_Ghost. - -- Bundle Int type with other types, constants and subprograms used in - -- ghost code, so that this package can be instantiated once and used - -- multiple times as generic formal for a given Int type. - - package Int_Params is new System.Val_Util.Int_Params - (Uns => Uns, - Int => Int, - P_Uns_Params => Uns_Params, - P_Is_Integer_Ghost => Is_Integer_Ghost, - P_Is_Value_Integer_Ghost => Is_Value_Integer_Ghost, - P_Is_Int_Of_Uns => Is_Int_Of_Uns, - P_Abs_Uns_Of_Int => Abs_Uns_Of_Int, - P_Prove_Scan_Only_Decimal_Ghost => Prove_Scan_Only_Decimal_Ghost); - private ---------------- diff --git a/gcc/ada/libgnat/s-valboo.adb b/gcc/ada/libgnat/s-valboo.adb index 41c54bf..f988c97 100644 --- a/gcc/ada/libgnat/s-valboo.adb +++ b/gcc/ada/libgnat/s-valboo.adb @@ -55,7 +55,7 @@ is begin Normalize_String (S, F, L); - pragma Assert (F = System.Val_Util.First_Non_Space_Ghost + pragma Assert (F = System.Val_Spec.First_Non_Space_Ghost (S, Str'First, Str'Last)); if S (F .. L) = "TRUE" then diff --git a/gcc/ada/libgnat/s-valboo.ads b/gcc/ada/libgnat/s-valboo.ads index 4866900..d482199 100644 --- a/gcc/ada/libgnat/s-valboo.ads +++ b/gcc/ada/libgnat/s-valboo.ads @@ -40,7 +40,7 @@ pragma Assertion_Policy (Pre => Ignore, Contract_Cases => Ignore, Ghost => Ignore); -with System.Val_Util; +with System.Val_Spec; package System.Val_Bool with SPARK_Mode @@ -48,10 +48,10 @@ is pragma Preelaborate; function Is_Boolean_Image_Ghost (Str : String) return Boolean is - (not System.Val_Util.Only_Space_Ghost (Str, Str'First, Str'Last) + (not System.Val_Spec.Only_Space_Ghost (Str, Str'First, Str'Last) and then (declare - F : constant Positive := System.Val_Util.First_Non_Space_Ghost + F : constant Positive := System.Val_Spec.First_Non_Space_Ghost (Str, Str'First, Str'Last); begin (F <= Str'Last - 3 @@ -61,7 +61,7 @@ is and then Str (F + 3) in 'e' | 'E' and then (if F + 3 < Str'Last then - System.Val_Util.Only_Space_Ghost (Str, F + 4, Str'Last))) + System.Val_Spec.Only_Space_Ghost (Str, F + 4, Str'Last))) or else (F <= Str'Last - 4 and then Str (F) in 'f' | 'F' @@ -71,7 +71,7 @@ is and then Str (F + 4) in 'e' | 'E' and then (if F + 4 < Str'Last then - System.Val_Util.Only_Space_Ghost (Str, F + 5, Str'Last))))) + System.Val_Spec.Only_Space_Ghost (Str, F + 5, Str'Last))))) with Ghost; -- Ghost function that returns True iff Str is the image of a boolean, that @@ -83,7 +83,7 @@ is Pre => Is_Boolean_Image_Ghost (Str), Post => Value_Boolean'Result = - (Str (System.Val_Util.First_Non_Space_Ghost + (Str (System.Val_Spec.First_Non_Space_Ghost (Str, Str'First, Str'Last)) in 't' | 'T'); -- Computes Boolean'Value (Str) diff --git a/gcc/ada/libgnat/s-valint.ads b/gcc/ada/libgnat/s-valint.ads index d3df7db..d8393ac 100644 --- a/gcc/ada/libgnat/s-valint.ads +++ b/gcc/ada/libgnat/s-valint.ads @@ -47,6 +47,8 @@ pragma Assertion_Policy (Pre => Ignore, with System.Unsigned_Types; with System.Val_Uns; with System.Value_I; +with System.Vs_Int; +with System.Vs_Uns; package System.Val_Int with SPARK_Mode is pragma Preelaborate; @@ -57,7 +59,8 @@ package System.Val_Int with SPARK_Mode is (Int => Integer, Uns => Unsigned, Scan_Raw_Unsigned => Val_Uns.Scan_Raw_Unsigned, - Uns_Params => System.Val_Uns.Impl.Spec.Uns_Params); + U_Spec => System.Vs_Uns.Spec, + Spec => System.Vs_Int.Spec); procedure Scan_Integer (Str : String; diff --git a/gcc/ada/libgnat/s-vallli.ads b/gcc/ada/libgnat/s-vallli.ads index 93d96bc..fb10b66 100644 --- a/gcc/ada/libgnat/s-vallli.ads +++ b/gcc/ada/libgnat/s-vallli.ads @@ -47,6 +47,8 @@ pragma Assertion_Policy (Pre => Ignore, with System.Unsigned_Types; with System.Val_LLU; with System.Value_I; +with System.Vs_LLI; +with System.Vs_LLU; package System.Val_LLI with SPARK_Mode is pragma Preelaborate; @@ -57,7 +59,8 @@ package System.Val_LLI with SPARK_Mode is (Int => Long_Long_Integer, Uns => Long_Long_Unsigned, Scan_Raw_Unsigned => Val_LLU.Scan_Raw_Long_Long_Unsigned, - Uns_Params => System.Val_LLU.Impl.Spec.Uns_Params); + U_Spec => System.Vs_LLU.Spec, + Spec => System.Vs_LLI.Spec); procedure Scan_Long_Long_Integer (Str : String; diff --git a/gcc/ada/libgnat/s-valllli.ads b/gcc/ada/libgnat/s-valllli.ads index e31b692..8122da8 100644 --- a/gcc/ada/libgnat/s-valllli.ads +++ b/gcc/ada/libgnat/s-valllli.ads @@ -47,6 +47,8 @@ pragma Assertion_Policy (Pre => Ignore, with System.Unsigned_Types; with System.Val_LLLU; with System.Value_I; +with System.Vs_LLLI; +with System.Vs_LLLU; package System.Val_LLLI with SPARK_Mode is pragma Preelaborate; @@ -57,7 +59,8 @@ package System.Val_LLLI with SPARK_Mode is (Int => Long_Long_Long_Integer, Uns => Long_Long_Long_Unsigned, Scan_Raw_Unsigned => Val_LLLU.Scan_Raw_Long_Long_Long_Unsigned, - Uns_Params => System.Val_LLLU.Impl.Spec.Uns_Params); + U_Spec => System.Vs_LLLU.Spec, + Spec => System.Vs_LLLI.Spec); procedure Scan_Long_Long_Long_Integer (Str : String; diff --git a/gcc/ada/libgnat/s-vallllu.ads b/gcc/ada/libgnat/s-vallllu.ads index 4dcf4c8..0957f84 100644 --- a/gcc/ada/libgnat/s-vallllu.ads +++ b/gcc/ada/libgnat/s-vallllu.ads @@ -46,13 +46,14 @@ pragma Assertion_Policy (Pre => Ignore, with System.Unsigned_Types; with System.Value_U; +with System.Vs_LLLU; package System.Val_LLLU with SPARK_Mode is pragma Preelaborate; subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; - package Impl is new Value_U (Long_Long_Long_Unsigned); + package Impl is new Value_U (Long_Long_Long_Unsigned, System.Vs_LLLU.Spec); procedure Scan_Raw_Long_Long_Long_Unsigned (Str : String; diff --git a/gcc/ada/libgnat/s-valllu.ads b/gcc/ada/libgnat/s-valllu.ads index c4d73d0..e860505 100644 --- a/gcc/ada/libgnat/s-valllu.ads +++ b/gcc/ada/libgnat/s-valllu.ads @@ -46,13 +46,14 @@ pragma Assertion_Policy (Pre => Ignore, with System.Unsigned_Types; with System.Value_U; +with System.Vs_LLU; package System.Val_LLU with SPARK_Mode is pragma Preelaborate; subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; - package Impl is new Value_U (Long_Long_Unsigned); + package Impl is new Value_U (Long_Long_Unsigned, System.Vs_LLU.Spec); procedure Scan_Raw_Long_Long_Unsigned (Str : String; diff --git a/gcc/ada/libgnat/s-valspe.adb b/gcc/ada/libgnat/s-valspe.adb new file mode 100644 index 0000000..56e6ed7 --- /dev/null +++ b/gcc/ada/libgnat/s-valspe.adb @@ -0,0 +1,82 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V A L _ S P E C -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- Ghost code, loop invariants and assertions in this unit are meant for +-- analysis only, not for run-time checking, as it would be too costly +-- otherwise. This is enforced by setting the assertion policy to Ignore. + +pragma Assertion_Policy (Ghost => Ignore, + Loop_Invariant => Ignore, + Assert => Ignore); + +package body System.Val_Spec + with SPARK_Mode +is + + --------------------------- + -- First_Non_Space_Ghost -- + --------------------------- + + function First_Non_Space_Ghost + (S : String; + From, To : Integer) return Positive + is + begin + for J in From .. To loop + if S (J) /= ' ' then + return J; + end if; + + pragma Loop_Invariant (for all K in From .. J => S (K) = ' '); + end loop; + + raise Program_Error; + end First_Non_Space_Ghost; + + ----------------------- + -- Last_Number_Ghost -- + ----------------------- + + function Last_Number_Ghost (Str : String) return Positive is + begin + for J in Str'Range loop + if Str (J) not in '0' .. '9' | '_' then + return J - 1; + end if; + + pragma Loop_Invariant + (for all K in Str'First .. J => Str (K) in '0' .. '9' | '_'); + end loop; + + return Str'Last; + end Last_Number_Ghost; + +end System.Val_Spec; diff --git a/gcc/ada/libgnat/s-valspe.ads b/gcc/ada/libgnat/s-valspe.ads new file mode 100644 index 0000000..dd861e5 --- /dev/null +++ b/gcc/ada/libgnat/s-valspe.ads @@ -0,0 +1,211 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V A L _ S P E C -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package provides some common specification functions used by the +-- s-valxxx files. + +-- Preconditions in this unit are meant for analysis only, not for run-time +-- checking, so that the expected exceptions are raised. This is enforced by +-- setting the corresponding assertion policy to Ignore. Postconditions and +-- contract cases should not be executed at runtime as well, in order not to +-- slow down the execution of these functions. + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore); + +package System.Val_Spec with + SPARK_Mode, + Pure, + Ghost +is + pragma Unevaluated_Use_Of_Old (Allow); + + function Only_Space_Ghost (S : String; From, To : Integer) return Boolean is + (for all J in From .. To => S (J) = ' ') + with + Pre => From > To or else (From >= S'First and then To <= S'Last), + Post => True; + -- Ghost function that returns True if S has only space characters from + -- index From to index To. + + function First_Non_Space_Ghost + (S : String; + From, To : Integer) return Positive + with + Pre => From in S'Range + and then To in S'Range + and then not Only_Space_Ghost (S, From, To), + Post => First_Non_Space_Ghost'Result in From .. To + and then S (First_Non_Space_Ghost'Result) /= ' ' + and then Only_Space_Ghost + (S, From, First_Non_Space_Ghost'Result - 1); + -- Ghost function that returns the index of the first non-space character + -- in S, which necessarily exists given the precondition on S. + + function Only_Number_Ghost (Str : String; From, To : Integer) return Boolean + is + (for all J in From .. To => Str (J) in '0' .. '9' | '_') + with + Pre => From > To or else (From >= Str'First and then To <= Str'Last); + -- Ghost function that returns True if S has only number characters from + -- index From to index To. + + function Last_Number_Ghost (Str : String) return Positive + with + Pre => Str /= "" and then Str (Str'First) in '0' .. '9', + Post => Last_Number_Ghost'Result in Str'Range + and then (if Last_Number_Ghost'Result < Str'Last then + Str (Last_Number_Ghost'Result + 1) not in '0' .. '9' | '_') + and then Only_Number_Ghost (Str, Str'First, Last_Number_Ghost'Result); + -- Ghost function that returns the index of the last character in S that + -- is either a figure or underscore, which necessarily exists given the + -- precondition on Str. + + function Is_Natural_Format_Ghost (Str : String) return Boolean is + (Str /= "" + and then Str (Str'First) in '0' .. '9' + and then + (declare + L : constant Positive := Last_Number_Ghost (Str); + begin + Str (L) in '0' .. '9' + and then (for all J in Str'First .. L => + (if Str (J) = '_' then Str (J + 1) /= '_')))); + -- Ghost function that determines if Str has the correct format for a + -- natural number, consisting in a sequence of figures possibly separated + -- by single underscores. It may be followed by other characters. + + function Starts_As_Exponent_Format_Ghost + (Str : String; + Real : Boolean := False) return Boolean + is + (Str'Length > 1 + and then Str (Str'First) in 'E' | 'e' + and then + (declare + Plus_Sign : constant Boolean := Str (Str'First + 1) = '+'; + Minus_Sign : constant Boolean := Str (Str'First + 1) = '-'; + Sign : constant Boolean := Plus_Sign or Minus_Sign; + begin + (if Minus_Sign then Real) + and then (if Sign then Str'Length > 2) + and then + (declare + Start : constant Natural := + (if Sign then Str'First + 2 else Str'First + 1); + begin + Str (Start) in '0' .. '9'))); + -- Ghost function that determines if Str is recognized as something which + -- might be an exponent, ie. it starts with an 'e', capitalized or not, + -- followed by an optional sign which can only be '-' if we are working on + -- real numbers (Real is True), and then a digit in decimal notation. + + function Is_Opt_Exponent_Format_Ghost + (Str : String; + Real : Boolean := False) return Boolean + is + (not Starts_As_Exponent_Format_Ghost (Str, Real) + or else + (declare + Start : constant Natural := + (if Str (Str'First + 1) in '+' | '-' then Str'First + 2 + else Str'First + 1); + begin Is_Natural_Format_Ghost (Str (Start .. Str'Last)))); + -- Ghost function that determines if Str has the correct format for an + -- optional exponent, that is, either it does not start as an exponent, or + -- it is in a correct format for a natural number. + + function Scan_Natural_Ghost + (Str : String; + P : Natural; + Acc : Natural) + return Natural + with + Subprogram_Variant => (Increases => P), + Pre => Str /= "" and then Str (Str'First) in '0' .. '9' + and then Str'Last < Natural'Last + and then P in Str'First .. Last_Number_Ghost (Str) + 1; + -- Ghost function that recursively computes the natural number in Str, up + -- to the first number greater or equal to Natural'Last / 10, assuming Acc + -- has been scanned already and scanning continues at index P. + + function Scan_Exponent_Ghost + (Str : String; + Real : Boolean := False) + return Integer + is + (declare + Plus_Sign : constant Boolean := Str (Str'First + 1) = '+'; + Minus_Sign : constant Boolean := Str (Str'First + 1) = '-'; + Sign : constant Boolean := Plus_Sign or Minus_Sign; + Start : constant Natural := + (if Sign then Str'First + 2 else Str'First + 1); + Value : constant Natural := + Scan_Natural_Ghost (Str (Start .. Str'Last), Start, 0); + begin + (if Minus_Sign then -Value else Value)) + with + Pre => Str'Last < Natural'Last + and then Starts_As_Exponent_Format_Ghost (Str, Real), + Post => (if not Real then Scan_Exponent_Ghost'Result >= 0); + -- Ghost function that scans an exponent + +private + + ------------------------ + -- Scan_Natural_Ghost -- + ------------------------ + + function Scan_Natural_Ghost + (Str : String; + P : Natural; + Acc : Natural) + return Natural + is + (if P > Str'Last + or else Str (P) not in '0' .. '9' | '_' + or else Acc >= Integer'Last / 10 + then + Acc + elsif Str (P) = '_' then + Scan_Natural_Ghost (Str, P + 1, Acc) + else + (declare + Shift_Acc : constant Natural := + Acc * 10 + + (Integer'(Character'Pos (Str (P))) - + Integer'(Character'Pos ('0'))); + begin + Scan_Natural_Ghost (Str, P + 1, Shift_Acc))); + +end System.Val_Spec; diff --git a/gcc/ada/libgnat/s-valuei.adb b/gcc/ada/libgnat/s-valuei.adb index 5932a01..71bfc0c 100644 --- a/gcc/ada/libgnat/s-valuei.adb +++ b/gcc/ada/libgnat/s-valuei.adb @@ -29,6 +29,8 @@ -- -- ------------------------------------------------------------------------------ +with System.Val_Util; use System.Val_Util; + package body System.Value_I is -- Ghost code, loop invariants and assertions in this unit are meant for @@ -98,7 +100,7 @@ package body System.Value_I is Scan_Raw_Unsigned (Str, Ptr, Max, Uval); pragma Assert - (Uval = Uns_Params.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max)); + (Uval = U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max)); -- Deal with overflow cases, and also with largest negative number @@ -175,7 +177,7 @@ package body System.Value_I is end; pragma Assert - (P = Uns_Params.Raw_Unsigned_Last_Ghost + (P = U_Spec.Raw_Unsigned_Last_Ghost (Str, Fst_Num, Str'Last)); Scan_Trailing_Blanks (Str, P); diff --git a/gcc/ada/libgnat/s-valuei.ads b/gcc/ada/libgnat/s-valuei.ads index 0ff25f5..baf1f86 100644 --- a/gcc/ada/libgnat/s-valuei.ads +++ b/gcc/ada/libgnat/s-valuei.ads @@ -38,8 +38,9 @@ pragma Assertion_Policy (Pre => Ignore, Ghost => Ignore, Subprogram_Variant => Ignore); -with System.Val_Util; use System.Val_Util; +with System.Val_Spec; use System.Val_Spec; with System.Value_I_Spec; +with System.Value_U_Spec; generic @@ -55,15 +56,13 @@ generic -- Additional parameters for ghost subprograms used inside contracts - with package Uns_Params is new System.Val_Util.Uns_Params - (Uns => Uns, others => <>) + with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; + with package Spec is new System.Value_I_Spec + (Int => Int, Uns => Uns, U_Spec => U_Spec) with Ghost; package System.Value_I is pragma Preelaborate; - use all type Uns_Params.Uns_Option; - - package Spec is new System.Value_I_Spec (Int, Uns, Uns_Params); procedure Scan_Integer (Str : String; @@ -84,12 +83,12 @@ package System.Value_I is (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 else Non_Blank); begin - Uns_Params.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Max)) - and then Uns_Params.Raw_Unsigned_No_Overflow_Ghost + U_Spec.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Max)) + and then U_Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Max) and then Spec.Uns_Is_Valid_Int (Minus => Str (Non_Blank) = '-', - Uval => Uns_Params.Scan_Raw_Unsigned_Ghost + Uval => U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max))), Post => (declare @@ -99,12 +98,12 @@ package System.Value_I is (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 else Non_Blank); Uval : constant Uns := - Uns_Params.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max); + U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max); begin Spec.Is_Int_Of_Uns (Minus => Str (Non_Blank) = '-', Uval => Uval, Val => Res) - and then Ptr.all = Uns_Params.Raw_Unsigned_Last_Ghost + and then Ptr.all = U_Spec.Raw_Unsigned_Last_Ghost (Str, Fst_Num, Max)); -- This procedure scans the string starting at Str (Ptr.all) for a valid -- integer according to the syntax described in (RM 3.5(43)). The substring diff --git a/gcc/ada/libgnat/s-valueu.adb b/gcc/ada/libgnat/s-valueu.adb index 9c77caa..7aeed3b 100644 --- a/gcc/ada/libgnat/s-valueu.adb +++ b/gcc/ada/libgnat/s-valueu.adb @@ -30,6 +30,7 @@ ------------------------------------------------------------------------------ with System.SPARK.Cut_Operations; use System.SPARK.Cut_Operations; +with System.Val_Util; use System.Val_Util; package body System.Value_U is diff --git a/gcc/ada/libgnat/s-valueu.ads b/gcc/ada/libgnat/s-valueu.ads index 6cc0260..fabaa36 100644 --- a/gcc/ada/libgnat/s-valueu.ads +++ b/gcc/ada/libgnat/s-valueu.ads @@ -45,17 +45,19 @@ pragma Assertion_Policy (Pre => Ignore, Subprogram_Variant => Ignore); with System.Value_U_Spec; -with System.Val_Util; use System.Val_Util; +with System.Val_Spec; use System.Val_Spec; generic type Uns is mod <>; + -- Additional parameters for ghost subprograms used inside contracts + + with package Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; + package System.Value_U is pragma Preelaborate; - package Spec is new System.Value_U_Spec (Uns); - procedure Scan_Raw_Unsigned (Str : String; Ptr : not null access Integer; diff --git a/gcc/ada/libgnat/s-valuns.ads b/gcc/ada/libgnat/s-valuns.ads index 357e5d6..1176153 100644 --- a/gcc/ada/libgnat/s-valuns.ads +++ b/gcc/ada/libgnat/s-valuns.ads @@ -46,13 +46,14 @@ pragma Assertion_Policy (Pre => Ignore, with System.Unsigned_Types; with System.Value_U; +with System.Vs_Uns; package System.Val_Uns with SPARK_Mode is pragma Preelaborate; subtype Unsigned is Unsigned_Types.Unsigned; - package Impl is new Value_U (Unsigned); + package Impl is new Value_U (Unsigned, System.Vs_Uns.Spec); procedure Scan_Raw_Unsigned (Str : String; diff --git a/gcc/ada/libgnat/s-valuti.adb b/gcc/ada/libgnat/s-valuti.adb index ee37c1a..5dfc307 100644 --- a/gcc/ada/libgnat/s-valuti.adb +++ b/gcc/ada/libgnat/s-valuti.adb @@ -62,44 +62,6 @@ is end if; end Bad_Value; - --------------------------- - -- First_Non_Space_Ghost -- - --------------------------- - - function First_Non_Space_Ghost - (S : String; - From, To : Integer) return Positive - is - begin - for J in From .. To loop - if S (J) /= ' ' then - return J; - end if; - - pragma Loop_Invariant (for all K in From .. J => S (K) = ' '); - end loop; - - raise Program_Error; - end First_Non_Space_Ghost; - - ----------------------- - -- Last_Number_Ghost -- - ----------------------- - - function Last_Number_Ghost (Str : String) return Positive is - begin - for J in Str'Range loop - if Str (J) not in '0' .. '9' | '_' then - return J - 1; - end if; - - pragma Loop_Invariant - (for all K in Str'First .. J => Str (K) in '0' .. '9' | '_'); - end loop; - - return Str'Last; - end Last_Number_Ghost; - ---------------------- -- Normalize_String -- ---------------------- @@ -224,10 +186,10 @@ is declare Rest : constant String := Str (P .. Max) with Ghost; - Last : constant Natural := Last_Number_Ghost (Rest) with Ghost; + Last : constant Natural := Sp.Last_Number_Ghost (Rest) with Ghost; begin - pragma Assert (Is_Natural_Format_Ghost (Rest)); + pragma Assert (Sp.Is_Natural_Format_Ghost (Rest)); loop pragma Assert (Str (P) in '0' .. '9'); @@ -240,8 +202,8 @@ is pragma Loop_Invariant (P in Rest'First .. Last); pragma Loop_Invariant (Str (P) in '0' .. '9'); pragma Loop_Invariant - (Scan_Natural_Ghost (Rest, Rest'First, 0) - = Scan_Natural_Ghost (Rest, P + 1, X)); + (Sp.Scan_Natural_Ghost (Rest, Rest'First, 0) + = Sp.Scan_Natural_Ghost (Rest, P + 1, X)); P := P + 1; @@ -301,7 +263,7 @@ is Start := P; - pragma Assert (Start = First_Non_Space_Ghost (Str, Ptr.all, Max)); + pragma Assert (Start = Sp.First_Non_Space_Ghost (Str, Ptr.all, Max)); -- Skip past an initial plus sign @@ -357,7 +319,7 @@ is Start := P; - pragma Assert (Start = First_Non_Space_Ghost (Str, Ptr.all, Max)); + pragma Assert (Start = Sp.First_Non_Space_Ghost (Str, Ptr.all, Max)); -- Remember an initial minus sign diff --git a/gcc/ada/libgnat/s-valuti.ads b/gcc/ada/libgnat/s-valuti.ads index 22d0612..cdd56c0 100644 --- a/gcc/ada/libgnat/s-valuti.ads +++ b/gcc/ada/libgnat/s-valuti.ads @@ -43,12 +43,15 @@ pragma Assertion_Policy (Pre => Ignore, Ghost => Ignore); with System.Case_Util; +with System.Val_Spec; package System.Val_Util with SPARK_Mode, Pure is pragma Unevaluated_Use_Of_Old (Allow); + package Sp renames System.Val_Spec; + procedure Bad_Value (S : String) with Depends => (null => S), @@ -56,46 +59,22 @@ is pragma No_Return (Bad_Value); -- Raises constraint error with message: bad input for 'Value: "xxx" - function Only_Space_Ghost (S : String; From, To : Integer) return Boolean is - (for all J in From .. To => S (J) = ' ') - with - Ghost, - Pre => From > To or else (From >= S'First and then To <= S'Last), - Post => True; - -- Ghost function that returns True if S has only space characters from - -- index From to index To. - - function First_Non_Space_Ghost - (S : String; - From, To : Integer) return Positive - with - Ghost, - Pre => From in S'Range - and then To in S'Range - and then not Only_Space_Ghost (S, From, To), - Post => First_Non_Space_Ghost'Result in From .. To - and then S (First_Non_Space_Ghost'Result) /= ' ' - and then Only_Space_Ghost - (S, From, First_Non_Space_Ghost'Result - 1); - -- Ghost function that returns the index of the first non-space character - -- in S, which necessarily exists given the precondition on S. - procedure Normalize_String (S : in out String; F, L : out Integer) with - Post => (if Only_Space_Ghost (S'Old, S'First, S'Last) then + Post => (if Sp.Only_Space_Ghost (S'Old, S'First, S'Last) then F > L else F >= S'First and then L <= S'Last and then F <= L - and then Only_Space_Ghost (S'Old, S'First, F - 1) + and then Sp.Only_Space_Ghost (S'Old, S'First, F - 1) and then S'Old (F) /= ' ' and then S'Old (L) /= ' ' and then (if L < S'Last then - Only_Space_Ghost (S'Old, L + 1, S'Last)) + Sp.Only_Space_Ghost (S'Old, L + 1, S'Last)) and then (if S'Old (F) /= ''' then (for all J in S'Range => @@ -119,18 +98,18 @@ is Pre => -- Ptr.all .. Max is either an empty range, or a valid range in Str (Ptr.all > Max or else (Ptr.all >= Str'First and then Max <= Str'Last)) - and then not Only_Space_Ghost (Str, Ptr.all, Max) + and then not Sp.Only_Space_Ghost (Str, Ptr.all, Max) and then (declare F : constant Positive := - First_Non_Space_Ghost (Str, Ptr.all, Max); + Sp.First_Non_Space_Ghost (Str, Ptr.all, Max); begin (if Str (F) in '+' | '-' then F <= Max - 1 and then Str (F + 1) /= ' ')), Post => (declare F : constant Positive := - First_Non_Space_Ghost (Str, Ptr.all'Old, Max); + Sp.First_Non_Space_Ghost (Str, Ptr.all'Old, Max); begin Minus = (Str (F) = '-') and then Ptr.all = (if Str (F) in '+' | '-' then F + 1 else F) @@ -164,142 +143,24 @@ is Pre => -- Ptr.all .. Max is either an empty range, or a valid range in Str (Ptr.all > Max or else (Ptr.all >= Str'First and then Max <= Str'Last)) - and then not Only_Space_Ghost (Str, Ptr.all, Max) + and then not Sp.Only_Space_Ghost (Str, Ptr.all, Max) and then (declare F : constant Positive := - First_Non_Space_Ghost (Str, Ptr.all, Max); + Sp.First_Non_Space_Ghost (Str, Ptr.all, Max); begin (if Str (F) = '+' then F <= Max - 1 and then Str (F + 1) /= ' ')), Post => (declare F : constant Positive := - First_Non_Space_Ghost (Str, Ptr.all'Old, Max); + Sp.First_Non_Space_Ghost (Str, Ptr.all'Old, Max); begin Ptr.all = (if Str (F) = '+' then F + 1 else F) and then Start = F); -- Same as Scan_Sign, but allows only plus, not minus. This is used for -- modular types. - function Only_Number_Ghost (Str : String; From, To : Integer) return Boolean - is - (for all J in From .. To => Str (J) in '0' .. '9' | '_') - with - Ghost, - Pre => From > To or else (From >= Str'First and then To <= Str'Last); - -- Ghost function that returns True if S has only number characters from - -- index From to index To. - - function Last_Number_Ghost (Str : String) return Positive - with - Ghost, - Pre => Str /= "" and then Str (Str'First) in '0' .. '9', - Post => Last_Number_Ghost'Result in Str'Range - and then (if Last_Number_Ghost'Result < Str'Last then - Str (Last_Number_Ghost'Result + 1) not in '0' .. '9' | '_') - and then Only_Number_Ghost (Str, Str'First, Last_Number_Ghost'Result); - -- Ghost function that returns the index of the last character in S that - -- is either a figure or underscore, which necessarily exists given the - -- precondition on Str. - - function Is_Natural_Format_Ghost (Str : String) return Boolean is - (Str /= "" - and then Str (Str'First) in '0' .. '9' - and then - (declare - L : constant Positive := Last_Number_Ghost (Str); - begin - Str (L) in '0' .. '9' - and then (for all J in Str'First .. L => - (if Str (J) = '_' then Str (J + 1) /= '_')))) - with - Ghost; - -- Ghost function that determines if Str has the correct format for a - -- natural number, consisting in a sequence of figures possibly separated - -- by single underscores. It may be followed by other characters. - - function Starts_As_Exponent_Format_Ghost - (Str : String; - Real : Boolean := False) return Boolean - is - (Str'Length > 1 - and then Str (Str'First) in 'E' | 'e' - and then - (declare - Plus_Sign : constant Boolean := Str (Str'First + 1) = '+'; - Minus_Sign : constant Boolean := Str (Str'First + 1) = '-'; - Sign : constant Boolean := Plus_Sign or Minus_Sign; - begin - (if Minus_Sign then Real) - and then (if Sign then Str'Length > 2) - and then - (declare - Start : constant Natural := - (if Sign then Str'First + 2 else Str'First + 1); - begin - Str (Start) in '0' .. '9'))) - with - Ghost; - -- Ghost function that determines if Str is recognized as something which - -- might be an exponent, ie. it starts with an 'e', capitalized or not, - -- followed by an optional sign which can only be '-' if we are working on - -- real numbers (Real is True), and then a digit in decimal notation. - - function Is_Opt_Exponent_Format_Ghost - (Str : String; - Real : Boolean := False) return Boolean - is - (not Starts_As_Exponent_Format_Ghost (Str, Real) - or else - (declare - Start : constant Natural := - (if Str (Str'First + 1) in '+' | '-' then Str'First + 2 - else Str'First + 1); - begin Is_Natural_Format_Ghost (Str (Start .. Str'Last)))) - with - Ghost; - -- Ghost function that determines if Str has the correct format for an - -- optional exponent, that is, either it does not start as an exponent, or - -- it is in a correct format for a natural number. - - function Scan_Natural_Ghost - (Str : String; - P : Natural; - Acc : Natural) - return Natural - with - Ghost, - Subprogram_Variant => (Increases => P), - Pre => Str /= "" and then Str (Str'First) in '0' .. '9' - and then Str'Last < Natural'Last - and then P in Str'First .. Last_Number_Ghost (Str) + 1; - -- Ghost function that recursively computes the natural number in Str, up - -- to the first number greater or equal to Natural'Last / 10, assuming Acc - -- has been scanned already and scanning continues at index P. - - function Scan_Exponent_Ghost - (Str : String; - Real : Boolean := False) - return Integer - is - (declare - Plus_Sign : constant Boolean := Str (Str'First + 1) = '+'; - Minus_Sign : constant Boolean := Str (Str'First + 1) = '-'; - Sign : constant Boolean := Plus_Sign or Minus_Sign; - Start : constant Natural := - (if Sign then Str'First + 2 else Str'First + 1); - Value : constant Natural := - Scan_Natural_Ghost (Str (Start .. Str'Last), Start, 0); - begin - (if Minus_Sign then -Value else Value)) - with - Ghost, - Pre => Str'Last < Natural'Last - and then Starts_As_Exponent_Format_Ghost (Str, Real), - Post => (if not Real then Scan_Exponent_Ghost'Result >= 0); - -- Ghost function that scans an exponent - procedure Scan_Exponent (Str : String; Ptr : not null access Integer; @@ -311,14 +172,15 @@ is -- Ptr.all .. Max is either an empty range, or a valid range in Str (Ptr.all > Max or else (Ptr.all >= Str'First and then Max <= Str'Last)) and then Max < Natural'Last - and then Is_Opt_Exponent_Format_Ghost (Str (Ptr.all .. Max), Real), + and then Sp.Is_Opt_Exponent_Format_Ghost (Str (Ptr.all .. Max), Real), Post => - (if Starts_As_Exponent_Format_Ghost (Str (Ptr.all'Old .. Max), Real) - then Exp = Scan_Exponent_Ghost (Str (Ptr.all'Old .. Max), Real) + (if Sp.Starts_As_Exponent_Format_Ghost (Str (Ptr.all'Old .. Max), Real) + then Exp = Sp.Scan_Exponent_Ghost (Str (Ptr.all'Old .. Max), Real) and then (if Str (Ptr.all'Old + 1) in '-' | '+' then - Ptr.all = Last_Number_Ghost (Str (Ptr.all'Old + 2 .. Max)) + 1 - else Ptr.all = Last_Number_Ghost (Str (Ptr.all'Old + 1 .. Max)) + 1) + Ptr.all = Sp.Last_Number_Ghost (Str (Ptr.all'Old + 2 .. Max)) + 1 + else + Ptr.all = Sp.Last_Number_Ghost (Str (Ptr.all'Old + 1 .. Max)) + 1) else Exp = 0 and Ptr.all = Ptr.all'Old); -- Called to scan a possible exponent. Str, Ptr, Max are as described above -- for Scan_Sign. If Ptr.all < Max and Str (Ptr.all) = 'E' or 'e', then an @@ -337,7 +199,7 @@ is procedure Scan_Trailing_Blanks (Str : String; P : Positive) with Pre => P >= Str'First - and then Only_Space_Ghost (Str, P, Str'Last); + and then Sp.Only_Space_Ghost (Str, P, Str'Last); -- Checks that the remainder of the field Str (P .. Str'Last) is all -- blanks. Raises Constraint_Error if a non-blank character is found. @@ -375,302 +237,4 @@ is -- no check for this case, the caller must ensure this condition is met. pragma Warnings (GNATprove, On, """Ptr"" is not modified"); - -- Bundle Uns type with other types, constants and subprograms used in - -- ghost code, so that this package can be instantiated once and used - -- multiple times as generic formal for a given Uns type. - generic - type Uns is mod <>; - type P_Uns_Option is private with Ghost; - with function P_Wrap_Option (Value : Uns) return P_Uns_Option - with Ghost; - with function P_Hexa_To_Unsigned_Ghost (X : Character) return Uns - with Ghost; - with function P_Scan_Overflows_Ghost - (Digit : Uns; - Base : Uns; - Acc : Uns) return Boolean - with Ghost; - with function P_Is_Raw_Unsigned_Format_Ghost - (Str : String) return Boolean - with Ghost; - with function P_Scan_Split_No_Overflow_Ghost - (Str : String; - From, To : Integer) - return Boolean - with Ghost; - with function P_Raw_Unsigned_No_Overflow_Ghost - (Str : String; - From, To : Integer) - return Boolean - with Ghost; - - with function P_Exponent_Unsigned_Ghost - (Value : Uns; - Exp : Natural; - Base : Uns := 10) return P_Uns_Option - with Ghost; - with procedure P_Lemma_Exponent_Unsigned_Ghost_Base - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - with Ghost; - with procedure P_Lemma_Exponent_Unsigned_Ghost_Overflow - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - with Ghost; - with procedure P_Lemma_Exponent_Unsigned_Ghost_Step - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - with Ghost; - - with function P_Scan_Raw_Unsigned_Ghost - (Str : String; - From, To : Integer) - return Uns - with Ghost; - with procedure P_Lemma_Scan_Based_Number_Ghost_Base - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with Ghost; - with procedure P_Lemma_Scan_Based_Number_Ghost_Underscore - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with Ghost; - with procedure P_Lemma_Scan_Based_Number_Ghost_Overflow - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with Ghost; - with procedure P_Lemma_Scan_Based_Number_Ghost_Step - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with Ghost; - - with function P_Raw_Unsigned_Last_Ghost - (Str : String; - From, To : Integer) - return Positive - with Ghost; - with function P_Only_Decimal_Ghost - (Str : String; - From, To : Integer) - return Boolean - with Ghost; - with function P_Scan_Based_Number_Ghost - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - return P_Uns_Option - with Ghost; - with function P_Is_Unsigned_Ghost (Str : String) return Boolean - with Ghost; - with function P_Is_Value_Unsigned_Ghost - (Str : String; - Val : Uns) return Boolean - with Ghost; - - with procedure P_Prove_Scan_Only_Decimal_Ghost - (Str : String; - Val : Uns) - with Ghost; - with procedure P_Prove_Scan_Based_Number_Ghost_Eq - (Str1, Str2 : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with Ghost; - - package Uns_Params is - subtype Uns_Option is P_Uns_Option with Ghost; - function Wrap_Option (Value : Uns) return Uns_Option renames - P_Wrap_Option; - function Hexa_To_Unsigned_Ghost - (X : Character) return Uns - renames P_Hexa_To_Unsigned_Ghost; - function Scan_Overflows_Ghost - (Digit : Uns; - Base : Uns; - Acc : Uns) return Boolean - renames P_Scan_Overflows_Ghost; - function Is_Raw_Unsigned_Format_Ghost - (Str : String) return Boolean - renames P_Is_Raw_Unsigned_Format_Ghost; - function Scan_Split_No_Overflow_Ghost - (Str : String; - From, To : Integer) return Boolean - renames P_Scan_Split_No_Overflow_Ghost; - function Raw_Unsigned_No_Overflow_Ghost - (Str : String; - From, To : Integer) return Boolean - renames P_Raw_Unsigned_No_Overflow_Ghost; - - function Exponent_Unsigned_Ghost - (Value : Uns; - Exp : Natural; - Base : Uns := 10) return Uns_Option - renames P_Exponent_Unsigned_Ghost; - procedure Lemma_Exponent_Unsigned_Ghost_Base - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - renames P_Lemma_Exponent_Unsigned_Ghost_Base; - procedure Lemma_Exponent_Unsigned_Ghost_Overflow - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - renames P_Lemma_Exponent_Unsigned_Ghost_Overflow; - procedure Lemma_Exponent_Unsigned_Ghost_Step - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - renames P_Lemma_Exponent_Unsigned_Ghost_Step; - - function Scan_Raw_Unsigned_Ghost - (Str : String; - From, To : Integer) return Uns - renames P_Scan_Raw_Unsigned_Ghost; - procedure Lemma_Scan_Based_Number_Ghost_Base - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - renames P_Lemma_Scan_Based_Number_Ghost_Base; - procedure Lemma_Scan_Based_Number_Ghost_Underscore - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - renames P_Lemma_Scan_Based_Number_Ghost_Underscore; - procedure Lemma_Scan_Based_Number_Ghost_Overflow - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - renames P_Lemma_Scan_Based_Number_Ghost_Overflow; - procedure Lemma_Scan_Based_Number_Ghost_Step - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - renames P_Lemma_Scan_Based_Number_Ghost_Step; - - function Raw_Unsigned_Last_Ghost - (Str : String; - From, To : Integer) return Positive - renames P_Raw_Unsigned_Last_Ghost; - function Only_Decimal_Ghost - (Str : String; - From, To : Integer) return Boolean - renames P_Only_Decimal_Ghost; - function Scan_Based_Number_Ghost - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) return Uns_Option - renames P_Scan_Based_Number_Ghost; - function Is_Unsigned_Ghost (Str : String) return Boolean - renames P_Is_Unsigned_Ghost; - function Is_Value_Unsigned_Ghost - (Str : String; - Val : Uns) return Boolean - renames P_Is_Value_Unsigned_Ghost; - - procedure Prove_Scan_Only_Decimal_Ghost - (Str : String; - Val : Uns) - renames P_Prove_Scan_Only_Decimal_Ghost; - procedure Prove_Scan_Based_Number_Ghost_Eq - (Str1, Str2 : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - renames P_Prove_Scan_Based_Number_Ghost_Eq; - end Uns_Params; - - -- Bundle Int type with other types, constants and subprograms used in - -- ghost code, so that this package can be instantiated once and used - -- multiple times as generic formal for a given Int type. - generic - type Int is range <>; - type Uns is mod <>; - - with package P_Uns_Params is new System.Val_Util.Uns_Params - (Uns => Uns, others => <>) - with Ghost; - - with function P_Abs_Uns_Of_Int (Val : Int) return Uns - with Ghost; - with function P_Is_Int_Of_Uns - (Minus : Boolean; - Uval : Uns; - Val : Int) - return Boolean - with Ghost; - with function P_Is_Integer_Ghost (Str : String) return Boolean - with Ghost; - with function P_Is_Value_Integer_Ghost - (Str : String; - Val : Int) return Boolean - with Ghost; - with procedure P_Prove_Scan_Only_Decimal_Ghost (Str : String; Val : Int) - with Ghost; - - package Int_Params is - package Uns_Params renames P_Uns_Params; - function Abs_Uns_Of_Int (Val : Int) return Uns renames - P_Abs_Uns_Of_Int; - function Is_Int_Of_Uns - (Minus : Boolean; - Uval : Uns; - Val : Int) - return Boolean - renames P_Is_Int_Of_Uns; - function Is_Integer_Ghost (Str : String) return Boolean renames - P_Is_Integer_Ghost; - function Is_Value_Integer_Ghost - (Str : String; - Val : Int) return Boolean - renames P_Is_Value_Integer_Ghost; - procedure Prove_Scan_Only_Decimal_Ghost (Str : String; Val : Int) renames - P_Prove_Scan_Only_Decimal_Ghost; - end Int_Params; - -private - - ------------------------ - -- Scan_Natural_Ghost -- - ------------------------ - - function Scan_Natural_Ghost - (Str : String; - P : Natural; - Acc : Natural) - return Natural - is - (if P > Str'Last - or else Str (P) not in '0' .. '9' | '_' - or else Acc >= Integer'Last / 10 - then - Acc - elsif Str (P) = '_' then - Scan_Natural_Ghost (Str, P + 1, Acc) - else - (declare - Shift_Acc : constant Natural := - Acc * 10 + - (Integer'(Character'Pos (Str (P))) - - Integer'(Character'Pos ('0'))); - begin - Scan_Natural_Ghost (Str, P + 1, Shift_Acc))); - end System.Val_Util; diff --git a/gcc/ada/libgnat/s-vauspe.ads b/gcc/ada/libgnat/s-vauspe.ads index bdd97b5..a6f81d7 100644 --- a/gcc/ada/libgnat/s-vauspe.ads +++ b/gcc/ada/libgnat/s-vauspe.ads @@ -44,7 +44,7 @@ pragma Assertion_Policy (Pre => Ignore, Ghost => Ignore, Subprogram_Variant => Ignore); -with System.Val_Util; use System.Val_Util; +with System.Val_Spec; use System.Val_Spec; generic @@ -57,6 +57,17 @@ package System.Value_U_Spec with is pragma Preelaborate; + -- Maximum value of exponent for 10 that fits in Uns'Base + function Max_Log10 return Natural is + (case Uns'Base'Size is + when 8 => 2, + when 16 => 4, + when 32 => 9, + when 64 => 19, + when 128 => 38, + when others => raise Program_Error) + with Ghost; + type Uns_Option (Overflow : Boolean := False) is record case Overflow is when True => @@ -598,46 +609,6 @@ is -- ghost code, so that this package can be instantiated once and used -- multiple times as generic formal for a given Int type. - package Uns_Params is new System.Val_Util.Uns_Params - (Uns => Uns, - P_Uns_Option => Uns_Option, - P_Wrap_Option => Wrap_Option, - P_Hexa_To_Unsigned_Ghost => Hexa_To_Unsigned_Ghost, - P_Scan_Overflows_Ghost => Scan_Overflows_Ghost, - P_Is_Raw_Unsigned_Format_Ghost => - Is_Raw_Unsigned_Format_Ghost, - P_Scan_Split_No_Overflow_Ghost => - Scan_Split_No_Overflow_Ghost, - P_Raw_Unsigned_No_Overflow_Ghost => - Raw_Unsigned_No_Overflow_Ghost, - P_Exponent_Unsigned_Ghost => Exponent_Unsigned_Ghost, - P_Lemma_Exponent_Unsigned_Ghost_Base => - Lemma_Exponent_Unsigned_Ghost_Base, - P_Lemma_Exponent_Unsigned_Ghost_Overflow => - Lemma_Exponent_Unsigned_Ghost_Overflow, - P_Lemma_Exponent_Unsigned_Ghost_Step => - Lemma_Exponent_Unsigned_Ghost_Step, - P_Scan_Raw_Unsigned_Ghost => Scan_Raw_Unsigned_Ghost, - P_Lemma_Scan_Based_Number_Ghost_Base => - Lemma_Scan_Based_Number_Ghost_Base, - P_Lemma_Scan_Based_Number_Ghost_Underscore => - Lemma_Scan_Based_Number_Ghost_Underscore, - P_Lemma_Scan_Based_Number_Ghost_Overflow => - Lemma_Scan_Based_Number_Ghost_Overflow, - P_Lemma_Scan_Based_Number_Ghost_Step => - Lemma_Scan_Based_Number_Ghost_Step, - P_Raw_Unsigned_Last_Ghost => Raw_Unsigned_Last_Ghost, - P_Only_Decimal_Ghost => Only_Decimal_Ghost, - P_Scan_Based_Number_Ghost => Scan_Based_Number_Ghost, - P_Is_Unsigned_Ghost => - Is_Unsigned_Ghost, - P_Is_Value_Unsigned_Ghost => - Is_Value_Unsigned_Ghost, - P_Prove_Scan_Only_Decimal_Ghost => - Prove_Scan_Only_Decimal_Ghost, - P_Prove_Scan_Based_Number_Ghost_Eq => - Prove_Scan_Based_Number_Ghost_Eq); - private ---------------- diff --git a/gcc/ada/libgnat/s-vs_int.ads b/gcc/ada/libgnat/s-vs_int.ads new file mode 100644 index 0000000..739a30c --- /dev/null +++ b/gcc/ada/libgnat/s-vs_int.ads @@ -0,0 +1,59 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V S _ I N T -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package contains specification functions for scanning signed Integer +-- values for use in Text_IO.Integer_IO, and the Value attribute. + +-- Preconditions in this unit are meant for analysis only, not for run-time +-- checking, so that the expected exceptions are raised. This is enforced by +-- setting the corresponding assertion policy to Ignore. Postconditions and +-- contract cases should not be executed at runtime as well, in order not to +-- slow down the execution of these functions. + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore, + Subprogram_Variant => Ignore); + +with System.Unsigned_Types; +with System.Value_I_Spec; +with System.Vs_Uns; + +package System.Vs_Int with SPARK_Mode, Ghost is + pragma Preelaborate; + + subtype Unsigned is Unsigned_Types.Unsigned; + + package Spec is new System.Value_I_Spec + (Integer, Unsigned, System.Vs_Uns.Spec); + +end System.Vs_Int; diff --git a/gcc/ada/libgnat/s-vs_lli.ads b/gcc/ada/libgnat/s-vs_lli.ads new file mode 100644 index 0000000..e3a1179 --- /dev/null +++ b/gcc/ada/libgnat/s-vs_lli.ads @@ -0,0 +1,60 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V S _ L L I -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package contains specification functions for scanning +-- Long_Long_Integer values for use in Text_IO.Integer_IO, and the Value +-- attribute. + +-- Preconditions in this unit are meant for analysis only, not for run-time +-- checking, so that the expected exceptions are raised. This is enforced by +-- setting the corresponding assertion policy to Ignore. Postconditions and +-- contract cases should not be executed at runtime as well, in order not to +-- slow down the execution of these functions. + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore, + Subprogram_Variant => Ignore); + +with System.Unsigned_Types; +with System.Value_I_Spec; +with System.Vs_LLU; + +package System.Vs_LLI with SPARK_Mode, Ghost is + pragma Preelaborate; + + subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; + + package Spec is new System.Value_I_Spec + (Long_Long_Integer, Long_Long_Unsigned, System.Vs_LLU.Spec); + +end System.Vs_LLI; diff --git a/gcc/ada/libgnat/s-vs_llu.ads b/gcc/ada/libgnat/s-vs_llu.ads new file mode 100644 index 0000000..f6d9334 --- /dev/null +++ b/gcc/ada/libgnat/s-vs_llu.ads @@ -0,0 +1,58 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V S _ L L U -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package contains specification functions for scanning +-- Long_Long_Unsigned values for use in Text_IO.Modular_IO, and the Value +-- attribute. + +-- Preconditions in this unit are meant for analysis only, not for run-time +-- checking, so that the expected exceptions are raised. This is enforced by +-- setting the corresponding assertion policy to Ignore. Postconditions and +-- contract cases should not be executed at runtime as well, in order not to +-- slow down the execution of these functions. + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore, + Subprogram_Variant => Ignore); + +with System.Unsigned_Types; +with System.Value_U_Spec; + +package System.Vs_LLU with SPARK_Mode, Ghost is + pragma Preelaborate; + + subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; + + package Spec is new System.Value_U_Spec (Long_Long_Unsigned); + +end System.Vs_LLU; diff --git a/gcc/ada/libgnat/s-vs_uns.ads b/gcc/ada/libgnat/s-vs_uns.ads new file mode 100644 index 0000000..5f21684 --- /dev/null +++ b/gcc/ada/libgnat/s-vs_uns.ads @@ -0,0 +1,57 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V S _ U N S -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package contains specification functions for scanning modular Unsigned +-- values for use in Text_IO.Modular_IO, and the Value attribute. + +-- Preconditions in this unit are meant for analysis only, not for run-time +-- checking, so that the expected exceptions are raised. This is enforced by +-- setting the corresponding assertion policy to Ignore. Postconditions and +-- contract cases should not be executed at runtime as well, in order not to +-- slow down the execution of these functions. + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore, + Subprogram_Variant => Ignore); + +with System.Unsigned_Types; +with System.Value_U_Spec; + +package System.Vs_Uns with SPARK_Mode, Ghost is + pragma Preelaborate; + + subtype Unsigned is Unsigned_Types.Unsigned; + + package Spec is new System.Value_U_Spec (Unsigned); + +end System.Vs_Uns; diff --git a/gcc/ada/libgnat/s-vsllli.ads b/gcc/ada/libgnat/s-vsllli.ads new file mode 100644 index 0000000..f70290b --- /dev/null +++ b/gcc/ada/libgnat/s-vsllli.ads @@ -0,0 +1,60 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V S _ L L L I -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package contains specification functions for scanning +-- Long_Long_Long_Integer values for use in Text_IO.Integer_IO, and the Value +-- attribute. + +-- Preconditions in this unit are meant for analysis only, not for run-time +-- checking, so that the expected exceptions are raised. This is enforced by +-- setting the corresponding assertion policy to Ignore. Postconditions and +-- contract cases should not be executed at runtime as well, in order not to +-- slow down the execution of these functions. + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore, + Subprogram_Variant => Ignore); + +with System.Unsigned_Types; +with System.Value_I_Spec; +with System.Vs_LLLU; + +package System.Vs_LLLI with SPARK_Mode, Ghost is + pragma Preelaborate; + + subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; + + package Spec is new System.Value_I_Spec + (Long_Long_Long_Integer, Long_Long_Long_Unsigned, System.Vs_LLLU.Spec); + +end System.Vs_LLLI; diff --git a/gcc/ada/libgnat/s-vslllu.ads b/gcc/ada/libgnat/s-vslllu.ads new file mode 100644 index 0000000..0a53cfe --- /dev/null +++ b/gcc/ada/libgnat/s-vslllu.ads @@ -0,0 +1,58 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . V S _ L L L U -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023-2023, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package contains specification functions for scanning +-- Long_Long_Long_Unsigned values for use in Text_IO.Modular_IO, and the Value +-- attribute. + +-- Preconditions in this unit are meant for analysis only, not for run-time +-- checking, so that the expected exceptions are raised. This is enforced by +-- setting the corresponding assertion policy to Ignore. Postconditions and +-- contract cases should not be executed at runtime as well, in order not to +-- slow down the execution of these functions. + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore, + Subprogram_Variant => Ignore); + +with System.Unsigned_Types; +with System.Value_U_Spec; + +package System.Vs_LLLU with SPARK_Mode, Ghost is + pragma Preelaborate; + + subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; + + package Spec is new System.Value_U_Spec (Long_Long_Long_Unsigned); + +end System.Vs_LLLU; -- cgit v1.1 From acaa441a98bebc5216334557cf8d09d63087ce37 Mon Sep 17 00:00:00 2001 From: Claire Dross Date: Mon, 19 Jun 2023 16:09:21 +0200 Subject: ada: Add specification source files of runtime units gcc/ada/ * gcc-interface/Make-lang.in: Add object files of specification files. --- gcc/ada/gcc-interface/Make-lang.in | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 364dea6..8c9eec3 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -550,8 +550,11 @@ GNAT_ADA_OBJS+= \ ada/libgnat/s-trasym.o \ ada/libgnat/s-unstyp.o \ ada/libgnat/s-valint.o \ + ada/libgnat/s-valspe.o \ ada/libgnat/s-valuns.o \ ada/libgnat/s-valuti.o \ + ada/libgnat/s-vs_int.o \ + ada/libgnat/s-vs_uns.o \ ada/libgnat/s-wchcnv.o \ ada/libgnat/s-wchcon.o \ ada/libgnat/s-wchjis.o \ -- cgit v1.1 From 7b16686ef882ab141276f0e36a9d4ce1d755f64a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 6 Jul 2023 13:51:55 +0200 Subject: tree-optimization/110556 - tail merging still pre-tuples The stmt comparison function for GIMPLE_ASSIGNs for tail merging still looks like it deals with pre-tuples IL. The following attempts to fix this, not only comparing the first operand (sic!) of stmts but all of them plus also compare the operation code. PR tree-optimization/110556 * tree-ssa-tail-merge.cc (gimple_equal_p): Check assign code and all operands of non-stores. * gcc.dg/torture/pr110556.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr110556.c | 42 +++++++++++++++++++++++++++++++++ gcc/tree-ssa-tail-merge.cc | 22 +++++++++++++---- 2 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr110556.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/torture/pr110556.c b/gcc/testsuite/gcc.dg/torture/pr110556.c new file mode 100644 index 0000000..bc60db8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110556.c @@ -0,0 +1,42 @@ +/* { dg-do run } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-additional-options "-fno-tree-fre -fno-delete-dead-exceptions -fnon-call-exceptions" } */ + +typedef __INT32_TYPE__ int32_t; +typedef __INT64_TYPE__ int64_t; + +static int64_t __attribute__((noinline,noclone)) +safe_mul_func_int64_t_s_s(int64_t si1, int64_t si2) +{ + return ((((si1 > 0) && (si2 > 0) && (si1 > ( (9223372036854775807L) / si2))) + || ((si1 > 0) && (si2 <= 0) && (si2 < ( (-9223372036854775807L -1) / si1))) + || ((si1 <= 0) && (si2 > 0) && (si1 < ( (-9223372036854775807L -1) / si2))) + || ((si1 <= 0) && (si2 <= 0) && (si1 != 0) && (si2 < ( (9223372036854775807L) / si1)))) + ? ((si1)) : si1 * si2); +} + +static int32_t g_93 = 0x947A4BBFL; +static int32_t tt = 6; +int64_t ty, ty1; + +static void func_34(void) +{ + ty=safe_mul_func_int64_t_s_s (g_93, -1L) ; +} +static void func_30(void) +{ + ty1=safe_mul_func_int64_t_s_s(0, tt); +} +static void func_6(void) +{ + for (int g_9 = 5; (g_9 >= 0); g_9 -= 1) + { + func_34(); + func_30 (); + } +} + +int main () +{ + func_6(); +} diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc index 13bc853..33acb64 100644 --- a/gcc/tree-ssa-tail-merge.cc +++ b/gcc/tree-ssa-tail-merge.cc @@ -1165,6 +1165,9 @@ gimple_equal_p (same_succ *same_succ, gimple *s1, gimple *s2) return operand_equal_p (lhs1, lhs2, 0); case GIMPLE_ASSIGN: + if (gimple_assign_rhs_code (s1) != gimple_assign_rhs_code (s2)) + return false; + lhs1 = gimple_get_lhs (s1); lhs2 = gimple_get_lhs (s2); if (TREE_CODE (lhs1) != SSA_NAME @@ -1172,11 +1175,20 @@ gimple_equal_p (same_succ *same_succ, gimple *s1, gimple *s2) return (operand_equal_p (lhs1, lhs2, 0) && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1), gimple_assign_rhs1 (s2))); - else if (TREE_CODE (lhs1) == SSA_NAME - && TREE_CODE (lhs2) == SSA_NAME) - return operand_equal_p (gimple_assign_rhs1 (s1), - gimple_assign_rhs1 (s2), 0); - return false; + + if (TREE_CODE (lhs1) != SSA_NAME + || TREE_CODE (lhs2) != SSA_NAME) + return false; + + gcc_checking_assert (gimple_num_args (s1) == gimple_num_args (s2)); + for (i = 0; i < gimple_num_args (s1); ++i) + { + t1 = gimple_arg (s1, i); + t2 = gimple_arg (s2, i); + if (!gimple_operand_equal_value_p (t1, t2)) + return false; + } + return true; case GIMPLE_COND: t1 = gimple_cond_lhs (s1); -- cgit v1.1 From b74e4cabd5984b742dbe32ba246b0d618bc30dd8 Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Thu, 6 Jul 2023 16:50:14 +0300 Subject: arc: Update builtin documentation gcc/ChangeLog: * doc/extend.texi (ARC Built-in Functions): Update documentation with missing builtins. --- gcc/doc/extend.texi | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d701b4d..bfbc1d6 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -15260,6 +15260,23 @@ __builtin_arc_sr() __builtin_arc_swi() @end example +The following built-in functions are available for the ARCv2 family of +processors. + +@example +int __builtin_arc_clri (); +void __builtin_arc_kflag (unsigned); +void __builtin_arc_seti (int); +@end example + +The following built-in functions are available for the ARCv2 family +and uses @option{-mnorm}. + +@example +int __builtin_arc_ffs (int); +int __builtin_arc_fls (int); +@end example + @node ARC SIMD Built-in Functions @subsection ARC SIMD Built-in Functions @@ -15486,6 +15503,44 @@ void __builtin_arc_vst16_n (__v8hi, const int, const int, const int); void __builtin_arc_vst32_n (__v8hi, const int, const int, const int); @end example +The following built-in functions are available on systems that uses +@option{-mmpy-option=6} or higher. + +@example +__v2hi __builtin_arc_dmach (__v2hi, __v2hi); +__v2hi __builtin_arc_dmachu (__v2hi, __v2hi); +__v2hi __builtin_arc_dmpyh (__v2hi, __v2hi); +__v2hi __builtin_arc_dmpyhu (__v2hi, __v2hi); +__v2hi __builtin_arc_vaddsub2h (__v2hi, __v2hi); +__v2hi __builtin_arc_vsubadd2h (__v2hi, __v2hi); +@end example + +The following built-in functions are available on systems that uses +@option{-mmpy-option=7} or higher. + +@example +__v2si __builtin_arc_vmac2h (__v2hi, __v2hi); +__v2si __builtin_arc_vmac2hu (__v2hi, __v2hi); +__v2si __builtin_arc_vmpy2h (__v2hi, __v2hi); +__v2si __builtin_arc_vmpy2hu (__v2hi, __v2hi); +@end example + +The following built-in functions are available on systems that uses +@option{-mmpy-option=8} or higher. + +@example +long long __builtin_arc_qmach (__v4hi, __v4hi); +long long __builtin_arc_qmachu (__v4hi, __v4hi); +long long __builtin_arc_qmpyh (__v4hi, __v4hi); +long long __builtin_arc_qmpyhu (__v4hi, __v4hi); +long long __builtin_arc_dmacwh (__v2si, __v2hi); +long long __builtin_arc_dmacwhu (__v2si, __v2hi); +_v2si __builtin_arc_vaddsub (__v2si, __v2si); +_v2si __builtin_arc_vsubadd (__v2si, __v2si); +_v4hi __builtin_arc_vaddsub4h (__v4hi, __v4hi); +_v4hi __builtin_arc_vsubadd4h (__v4hi, __v4hi); +@end example + @node ARM iWMMXt Built-in Functions @subsection ARM iWMMXt Built-in Functions -- cgit v1.1 From 2e406f0753e8d78d320437189211e3094c33b7e4 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 6 Jul 2023 16:19:15 +0200 Subject: updat_bb_profile_for_threading TLC Apply some TLC to update_bb_profile_for_threading. The function resales probabilities by: FOR_EACH_EDGE (c, ei, bb->succs) c->probability /= prob; which is correct but in case prob is 0 (took all execution counts to the newly constructed path), this leads to undefined results which do not sum to 100%. In several other plpaces we need to change probability of one edge and rescale remaining to sum to 100% so I decided to break this off to helper function set_edge_probability_and_rescale_others For jump threading the probability of edge is always reduced, so division is right update, however in general case we also may want to increase probability of the edge which needs different scalling. This is bit hard to do staying with probabilities in range 0...1 for all temporaries. For this reason I decided to add profile_probability::apply_scale which is symmetric to what we already have in profile_count::apply_scale and does right thing in both directions. Finally I added few early exits so we do not produce confused dumps when profile is missing and special case the common situation where edges out of BB are precisely two. In this case we can set the other edge to inverter probability which. Saling drop probability quality from PRECISE to ADJUSTED. Bootstrapped/regtested x86_64-linux. The patch has no effect on in count mismatches in tramp3d build and improves out-count. Will commit it shortly. gcc/ChangeLog: * cfg.cc (set_edge_probability_and_rescale_others): New function. (update_bb_profile_for_threading): Use it; simplify the rest. * cfg.h (set_edge_probability_and_rescale_others): Declare. * profile-count.h (profile_probability::apply_scale): New. --- gcc/cfg.cc | 142 ++++++++++++++++++++++++++++++++++++---------------- gcc/cfg.h | 1 + gcc/profile-count.h | 28 +++++++++++ 3 files changed, 128 insertions(+), 43 deletions(-) (limited to 'gcc') diff --git a/gcc/cfg.cc b/gcc/cfg.cc index 57b4011..740d4f3 100644 --- a/gcc/cfg.cc +++ b/gcc/cfg.cc @@ -901,6 +901,67 @@ brief_dump_cfg (FILE *file, dump_flags_t flags) } } +/* Set probability of E to NEW_PROB and rescale other edges + from E->src so their sum remains the same. */ + +void +set_edge_probability_and_rescale_others (edge e, profile_probability new_prob) +{ + edge e2; + edge_iterator ei; + if (e->probability == new_prob) + return; + /* If we made E unconditional, drop other frequencies to 0. */ + if (new_prob == profile_probability::always ()) + { + FOR_EACH_EDGE (e2, ei, e->src->succs) + if (e2 != e) + e2->probability = profile_probability::never (); + } + else + { + int n = 0; + edge other_e = NULL; + + /* See how many other edges are leaving exit_edge->src. */ + FOR_EACH_EDGE (e2, ei, e->src->succs) + if (e2 != e && !(e2->flags & EDGE_FAKE)) + { + other_e = e2; + n++; + } + /* If there is only one other edge with non-zero probability we do not + need to scale which drops quality of profile from precise + to adjusted. */ + if (n == 1) + other_e->probability = new_prob.invert (); + /* Nothing to do if there are no other edges. */ + else if (!n) + ; + /* Do scaling if possible. */ + else if (e->probability.invert ().nonzero_p ()) + { + profile_probability num = new_prob.invert (), + den = e->probability.invert (); + FOR_EACH_EDGE (e2, ei, e->src->succs) + if (e2 != e && !(e2->flags & EDGE_FAKE)) + e2->probability = e2->probability.apply_scale (num, den); + } + else + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + ";; probability of edge %i->%i set reduced from 1." + " The remaining edges are left inconsistent.\n", + e->src->index, e->dest->index); + FOR_EACH_EDGE (e2, ei, e->src->succs) + if (e2 != e && !(e2->flags & EDGE_FAKE)) + e2->probability = new_prob.invert ().guessed () / n; + } + } + e->probability = new_prob; +} + /* An edge originally destinating BB of COUNT has been proved to leave the block by TAKEN_EDGE. Update profile of BB such that edge E can be redirected to destination of TAKEN_EDGE. @@ -912,62 +973,57 @@ void update_bb_profile_for_threading (basic_block bb, profile_count count, edge taken_edge) { - edge c; - profile_probability prob; - edge_iterator ei; + gcc_assert (bb == taken_edge->src); + + /* If there is no profile or the threaded path is never executed + we don't need to upate. */ + if (!bb->count.initialized_p () + || count == profile_count::zero ()) + return; if (bb->count < count) { if (dump_file) fprintf (dump_file, "bb %i count became negative after threading", bb->index); + /* If probabilities looks very off, scale down and reduce to guesses + to avoid dropping the other path close to zero. */ + if (bb->count < count.apply_scale (7, 8)) + count = bb->count.apply_scale (1, 2).guessed (); } - /* Compute the probability of TAKEN_EDGE being reached via threaded edge. - Watch for overflows. */ - if (bb->count.nonzero_p ()) - prob = count.probability_in (bb->count); - else - prob = profile_probability::never (); - if (prob > taken_edge->probability) + /* If bb->count will become zero, the probabilities on the original path + are not really known, but it is probably better to keep original ones + then try to invent something new. */ + if (!(bb->count <= count)) { - if (dump_file) + profile_probability prob; + /* Compute the probability of TAKEN_EDGE being reached via threaded edge. + Watch for overflows. */ + if (bb->count.nonzero_p ()) + prob = count.probability_in (bb->count); + else + prob = taken_edge->probability.apply_scale (1, 2).guessed (); + if (prob > taken_edge->probability) { - fprintf (dump_file, "Jump threading proved that the probability of edge " - "%i->%i was originally estimated too small (it is ", - taken_edge->src->index, taken_edge->dest->index); - taken_edge->probability.dump (dump_file); - fprintf (dump_file, " should be "); - prob.dump (dump_file); - fprintf (dump_file, ")\n"); + if (dump_file) + { + fprintf (dump_file, "Jump threading proved that the probability " + "of edge %i->%i was originally estimated too small. " + "(it is ", + taken_edge->src->index, taken_edge->dest->index); + taken_edge->probability.dump (dump_file); + fprintf (dump_file, " should be "); + prob.dump (dump_file); + fprintf (dump_file, ")\n"); + } + prob = taken_edge->probability.apply_scale (6, 8).guessed (); } - prob = taken_edge->probability.apply_scale (6, 8); + set_edge_probability_and_rescale_others (taken_edge, + (taken_edge->probability - prob) + / prob.invert ()); } - bb->count -= count; - - /* Now rescale the probabilities. */ - taken_edge->probability -= prob; - prob = prob.invert (); - if (prob == profile_probability::never ()) - { - if (dump_file) - fprintf (dump_file, "Edge probabilities of bb %i has been reset, " - "count of block should end up being 0, it is non-zero\n", - bb->index); - EDGE_SUCC (bb, 0)->probability = profile_probability::guessed_always (); - ei = ei_start (bb->succs); - ei_next (&ei); - for (; (c = ei_safe_edge (ei)); ei_next (&ei)) - c->probability = profile_probability::guessed_never (); - } - else if (!(prob == profile_probability::always ())) - { - FOR_EACH_EDGE (c, ei, bb->succs) - c->probability /= prob; - } - - gcc_assert (bb == taken_edge->src); } /* Multiply all frequencies of basic blocks in array BBS of length NBBS diff --git a/gcc/cfg.h b/gcc/cfg.h index 4cd2958..4bf4263 100644 --- a/gcc/cfg.h +++ b/gcc/cfg.h @@ -112,6 +112,7 @@ extern void debug_bb (basic_block, dump_flags_t); extern basic_block debug_bb_n (int, dump_flags_t); extern void dump_bb_info (FILE *, basic_block, int, dump_flags_t, bool, bool); extern void brief_dump_cfg (FILE *, dump_flags_t); +extern void set_edge_probability_and_rescale_others (edge, profile_probability); extern void update_bb_profile_for_threading (basic_block, profile_count, edge); extern void scale_bbs_frequencies_profile_count (basic_block *, int, profile_count, profile_count); diff --git a/gcc/profile-count.h b/gcc/profile-count.h index 0739e26..4270793 100644 --- a/gcc/profile-count.h +++ b/gcc/profile-count.h @@ -212,6 +212,11 @@ public: { return always () - unlikely (); } + /* Return true when value is not zero and can be used for scaling. */ + bool nonzero_p () const + { + return initialized_p () && m_val != 0; + } static profile_probability guessed_always () { @@ -541,6 +546,29 @@ public: return ret; } + /* Return *THIS * NUM / DEN. */ + profile_probability apply_scale (profile_probability num, + profile_probability den) const + { + if (*this == never ()) + return *this; + if (num == never ()) + return num; + if (!initialized_p () || !num.initialized_p () || !den.initialized_p ()) + return uninitialized (); + if (num == den) + return *this; + gcc_checking_assert (den.m_val); + + profile_probability ret; + uint64_t val; + safe_scale_64bit (m_val, num.m_val, den.m_val, &val); + ret.m_val = MIN (val, max_probability); + ret.m_quality = MIN (MIN (MIN (m_quality, ADJUSTED), + num.m_quality), den.m_quality); + return ret; + } + /* Return true when the probability of edge is reliable. The profile guessing code is good at predicting branch outcome (i.e. -- cgit v1.1 From 224fd59b2dc8a5fa78a309a09863afe9b3cf2111 Mon Sep 17 00:00:00 2001 From: Hao Liu OS Date: Thu, 6 Jul 2023 10:04:46 -0600 Subject: Vect: use a small step to calculate induction for the unrolled loop (PR tree-optimization/110449) If a loop is unrolled by n times during vectoriation, two steps are used to calculate the induction variable: - The small step for the unrolled ith-copy: vec_1 = vec_iv + (VF/n * Step) - The large step for the whole loop: vec_loop = vec_iv + (VF * Step) This patch calculates an extra vec_n to replace vec_loop: vec_n = vec_prev + (VF/n * S) = vec_iv + (VF/n * S) * n = vec_loop. So that we can save the large step register and related operations. gcc/ChangeLog: PR tree-optimization/110449 * tree-vect-loop.cc (vectorizable_induction): use vec_n to replace vec_loop for the unrolled loop. gcc/testsuite/ChangeLog: * gcc.target/aarch64/pr110449.c: New testcase. --- gcc/testsuite/gcc.target/aarch64/pr110449.c | 40 +++++++++++++++++++++++++++++ gcc/tree-vect-loop.cc | 21 ++++++++++++--- 2 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/pr110449.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/aarch64/pr110449.c b/gcc/testsuite/gcc.target/aarch64/pr110449.c new file mode 100644 index 0000000..bb3b6dc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr110449.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -mcpu=neoverse-n2 --param aarch64-vect-unroll-limit=2" } */ +/* { dg-final { scan-assembler-not "8.0e\\+0" } } */ + +/* Calcualte the vectorized induction with smaller step for an unrolled loop. + + before (suggested_unroll_factor=2): + fmov s30, 8.0e+0 + fmov s31, 4.0e+0 + dup v27.4s, v30.s[0] + dup v28.4s, v31.s[0] + .L6: + mov v30.16b, v31.16b + fadd v31.4s, v31.4s, v27.4s + fadd v29.4s, v30.4s, v28.4s + stp q30, q29, [x0] + add x0, x0, 32 + cmp x1, x0 + bne .L6 + + after: + fmov s31, 4.0e+0 + dup v29.4s, v31.s[0] + .L6: + fadd v30.4s, v31.4s, v29.4s + stp q31, q30, [x0] + add x0, x0, 32 + fadd v31.4s, v29.4s, v30.4s + cmp x0, x1 + bne .L6 */ + +void +foo2 (float *arr, float freq, float step) +{ + for (int i = 0; i < 1024; i++) + { + arr[i] = freq; + freq += step; + } +} diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 36d19a5..7d917bf 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -10098,7 +10098,7 @@ vectorizable_induction (loop_vec_info loop_vinfo, new_vec, step_vectype, NULL); vec_def = induc_def; - for (i = 1; i < ncopies; i++) + for (i = 1; i < ncopies + 1; i++) { /* vec_i = vec_prev + vec_step */ gimple_seq stmts = NULL; @@ -10108,8 +10108,23 @@ vectorizable_induction (loop_vec_info loop_vinfo, vec_def = gimple_convert (&stmts, vectype, vec_def); gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); - new_stmt = SSA_NAME_DEF_STMT (vec_def); - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + if (i < ncopies) + { + new_stmt = SSA_NAME_DEF_STMT (vec_def); + STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + } + else + { + /* vec_1 = vec_iv + (VF/n * S) + vec_2 = vec_1 + (VF/n * S) + ... + vec_n = vec_prev + (VF/n * S) = vec_iv + VF * S = vec_loop + + vec_n is used as vec_loop to save the large step register and + related operations. */ + add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop), + UNKNOWN_LOCATION); + } } } -- cgit v1.1 From d4c2e34deef8cbd81ba2ef3389fdbaf95c70e225 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 6 Jul 2023 18:51:02 +0200 Subject: Improve scale_loop_profile Original scale_loop_profile was implemented to only handle very simple loops produced by vectorizer at that time (basically loops with only one exit and no subloops). It also has not been updated to new profile-count API very carefully. The function does two thigs 1) scales down the loop profile by a given probability. This is useful, for example, to scale down profile after peeling when loop body is executed less often than before 2) update profile to cap iteration count by ITERATION_BOUND parameter. I changed ITERATION_BOUND to be actual bound on number of iterations as used elsewhere (i.e. number of executions of latch edge) rather then number of iterations + 1 as it was before. To do 2) one needs to do the following a) scale own loop profile so frquency o header is at most the sum of in-edge counts * (iteration_bound + 1) b) update loop exit probabilities so their count is the same as before scaling. c) reduce frequencies of basic blocks after loop exit old code did b) by setting probability to 1 / iteration_bound which is correctly only of the basic block containing exit executes precisely one per iteration (it is not insie other conditional or inner loop). This is fixed now by using set_edge_probability_and_rescale_others aldo c) was implemented only for special case when the exit was just before latch bacis block. I now use dominance info to get right some of addional case. I still did not try to do anything for multiple exit loops, though the implementatoin could be generalized. Bootstrapped/regtested x86_64-linux. Plan to cmmit it tonight if there are no complains. gcc/ChangeLog: * cfgloopmanip.cc (scale_loop_profile): Rewrite exit edge probability update to be safe on loops with subloops. Make bound parameter to be iteration bound. * tree-ssa-loop-ivcanon.cc (try_peel_loop): Update call of scale_loop_profile. * tree-vect-loop-manip.cc (vect_do_peeling): Likewise. --- gcc/cfgloopmanip.cc | 179 +++++++++++++++++++++++-------------------- gcc/tree-ssa-loop-ivcanon.cc | 2 +- gcc/tree-vect-loop-manip.cc | 6 +- 3 files changed, 102 insertions(+), 85 deletions(-) (limited to 'gcc') diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 6e09dcb..524b979 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -499,7 +499,7 @@ scale_loop_frequencies (class loop *loop, profile_probability p) } /* Scale profile in LOOP by P. - If ITERATION_BOUND is non-zero, scale even further if loop is predicted + If ITERATION_BOUND is not -1, scale even further if loop is predicted to iterate too many times. Before caling this function, preheader block profile should be already scaled to final count. This is necessary because loop iterations are @@ -510,106 +510,123 @@ void scale_loop_profile (class loop *loop, profile_probability p, gcov_type iteration_bound) { - edge e, preheader_e; - edge_iterator ei; - - if (dump_file && (dump_flags & TDF_DETAILS)) + if (!(p == profile_probability::always ())) { - fprintf (dump_file, ";; Scaling loop %i with scale ", - loop->num); - p.dump (dump_file); - fprintf (dump_file, " bounding iterations to %i\n", - (int)iteration_bound); - } + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, ";; Scaling loop %i with scale ", + loop->num); + p.dump (dump_file); + fprintf (dump_file, "\n"); + } - /* Scale the probabilities. */ - scale_loop_frequencies (loop, p); + /* Scale the probabilities. */ + scale_loop_frequencies (loop, p); + } - if (iteration_bound == 0) + if (iteration_bound == -1) return; gcov_type iterations = expected_loop_iterations_unbounded (loop, NULL, true); + if (iterations == -1) + return; if (dump_file && (dump_flags & TDF_DETAILS)) { - fprintf (dump_file, ";; guessed iterations after scaling %i\n", - (int)iterations); + fprintf (dump_file, + ";; guessed iterations of loop %i:%i new upper bound %i:\n", + loop->num, + (int)iterations, + (int)iteration_bound); } /* See if loop is predicted to iterate too many times. */ if (iterations <= iteration_bound) return; - preheader_e = loop_preheader_edge (loop); - - /* We could handle also loops without preheaders, but bounding is - currently used only by optimizers that have preheaders constructed. */ - gcc_checking_assert (preheader_e); - profile_count count_in = preheader_e->count (); + /* Compute number of invocations of the loop. */ + profile_count count_in = profile_count::zero (); + edge e; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, loop->header->preds) + count_in += e->count (); - if (count_in > profile_count::zero () - && loop->header->count.initialized_p ()) + /* Now scale the loop body so header count is + count_in * (iteration_bound + 1) */ + profile_probability scale_prob + = (count_in *= iteration_bound).probability_in (loop->header->count); + if (dump_file && (dump_flags & TDF_DETAILS)) { - profile_count count_delta = profile_count::zero (); - - e = single_exit (loop); - if (e) - { - edge other_e; - FOR_EACH_EDGE (other_e, ei, e->src->succs) - if (!(other_e->flags & (EDGE_ABNORMAL | EDGE_FAKE)) - && e != other_e) - break; - - /* Probability of exit must be 1/iterations. */ - count_delta = e->count (); - e->probability = profile_probability::always () / iteration_bound; - other_e->probability = e->probability.invert (); - - /* In code below we only handle the following two updates. */ - if (other_e->dest != loop->header - && other_e->dest != loop->latch - && (dump_file && (dump_flags & TDF_DETAILS))) - { - fprintf (dump_file, ";; giving up on update of paths from " - "exit condition to latch\n"); - } - } + fprintf (dump_file, ";; Scaling loop %i with scale ", + loop->num); + p.dump (dump_file); + fprintf (dump_file, " to reach upper bound %i\n", + (int)iteration_bound); + } + /* Finally attempt to fix exit edge probability. */ + auto_vec exits = get_loop_exit_edges (loop); + edge exit_edge = single_likely_exit (loop, exits); + + /* In a consistent profile unadjusted_exit_count should be same as count_in, + however to preserve as much of the original info, avoid recomputing + it. */ + profile_count unadjusted_exit_count; + if (exit_edge) + unadjusted_exit_count = exit_edge->count (); + scale_loop_frequencies (loop, scale_prob); + + if (exit_edge) + { + profile_count old_exit_count = exit_edge->count (); + profile_probability new_probability; + if (iteration_bound > 0) + new_probability + = unadjusted_exit_count.probability_in (exit_edge->src->count); else - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Loop has multiple exit edges; " - "giving up on exit condition update\n"); - - /* Roughly speaking we want to reduce the loop body profile by the - difference of loop iterations. We however can do better if - we look at the actual profile, if it is available. */ - p = profile_probability::always (); - - count_in *= iteration_bound; - p = count_in.probability_in (loop->header->count); - if (!(p > profile_probability::never ())) - p = profile_probability::very_unlikely (); - - if (p == profile_probability::always () - || !p.initialized_p ()) - return; - - /* If latch exists, change its count, since we changed - probability of exit. Theoretically we should update everything from - source of exit edge to latch, but for vectorizer this is enough. */ - if (loop->latch && loop->latch != e->src) - loop->latch->count += count_delta; - - /* Scale the probabilities. */ - scale_loop_frequencies (loop, p); + new_probability = profile_probability::always (); + set_edge_probability_and_rescale_others (exit_edge, new_probability); + profile_count new_exit_count = exit_edge->count (); + + /* Rescale the remaining edge probabilities and see if there is only + one. */ + edge other_edge = NULL; + bool found = false; + FOR_EACH_EDGE (e, ei, exit_edge->src->succs) + if (!(e->flags & EDGE_FAKE) + && !(e->probability == profile_probability::never ()) + && !loop_exit_edge_p (loop, e)) + { + if (found) + { + other_edge = NULL; + break; + } + other_edge = e; + found = true; + } + /* If there is only loop latch after other edge, + update its profile. */ + if (other_edge && other_edge->dest == loop->latch) + loop->latch->count -= new_exit_count - old_exit_count; + else + { + basic_block *body = get_loop_body (loop); + profile_count new_count = exit_edge->src->count - new_exit_count; + profile_count old_count = exit_edge->src->count - old_exit_count; - /* Change latch's count back. */ - if (loop->latch && loop->latch != e->src) - loop->latch->count -= count_delta; + for (unsigned int i = 0; i < loop->num_nodes; i++) + if (body[i] != exit_edge->src + && dominated_by_p (CDI_DOMINATORS, body[i], exit_edge->src)) + body[i]->count.apply_scale (new_count, old_count); - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; guessed iterations are now %i\n", - (int)expected_loop_iterations_unbounded (loop, NULL, true)); + free (body); + } + } + else if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, + ";; Loop has mulitple exits;" + " will leave exit probabilities inconsistent\n"); } } diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc index 491b57e..9e119eb 100644 --- a/gcc/tree-ssa-loop-ivcanon.cc +++ b/gcc/tree-ssa-loop-ivcanon.cc @@ -1173,7 +1173,7 @@ try_peel_loop (class loop *loop, } profile_probability p; p = entry_count.probability_in (loop->header->count); - scale_loop_profile (loop, p, 0); + scale_loop_profile (loop, p, -1); bitmap_set_bit (peeled_loops, loop->num); return true; } diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index d66d4a6..2361cb3 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -3191,7 +3191,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, if (prob_vector.initialized_p ()) { scale_bbs_frequencies (&bb_before_loop, 1, prob_vector); - scale_loop_profile (loop, prob_vector, 0); + scale_loop_profile (loop, prob_vector, -1); } } @@ -3236,7 +3236,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, slpeel_update_phi_nodes_for_guard1 (prolog, loop, guard_e, e); scale_bbs_frequencies (&bb_after_prolog, 1, prob_prolog); - scale_loop_profile (prolog, prob_prolog, bound_prolog); + scale_loop_profile (prolog, prob_prolog, bound_prolog - 1); } /* Update init address of DRs. */ @@ -3378,7 +3378,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, scale_bbs_frequencies (&bb_before_epilog, 1, prob_epilog); } - scale_loop_profile (epilog, prob_epilog, 0); + scale_loop_profile (epilog, prob_epilog, -1); } else slpeel_update_phi_nodes_for_lcssa (epilog); -- cgit v1.1 From 3a61ca1b9256535e1bfb19b2d46cde21f3908a5d Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 6 Jul 2023 18:56:22 +0200 Subject: Improve profile updates after loop-ch and cunroll Extend loop-ch and loop unrolling to fix profile in case the loop is known to not iterate at all (or iterate few times) while profile claims it iterates more. While this is kind of symptomatic fix, it is best we can do incase profile was originally esitmated incorrectly. In the testcase the problematic loop is produced by vectorizer and I think vectorizer should know and account into its costs that vectorizer loop and/or epilogue is not going to loop after the transformation. So it would be nice to fix it on that side, too. The patch avoids about half of profile mismatches caused by cunroll. Pass dump id and name |static mismatcdynamic mismatch |in count |in count 107t cunrolli | 3 +3| 17251 +17251 115t threadfull | 3 | 14376 -2875 116t vrp | 5 +2| 30908 +16532 117t dse | 5 | 30908 118t dce | 3 -2| 17251 -13657 127t ch | 13 +10| 17251 131t dom | 39 +26| 17251 133t isolate-paths | 47 +8| 17251 134t reassoc | 49 +2| 17251 136t forwprop | 53 +4| 202501 +185250 159t cddce | 61 +8| 216211 +13710 161t ldist | 62 +1| 216211 172t ifcvt | 66 +4| 373711 +157500 173t vect | 143 +77| 9802097 +9428386 176t cunroll | 221 +78| 15639591 +5837494 183t loopdone | 218 -3| 15577640 -61951 195t fre | 214 -4| 15577640 197t dom | 213 -1| 16671606 +1093966 199t threadfull | 215 +2| 16879581 +207975 200t vrp | 217 +2| 17077750 +198169 204t dce | 215 -2| 17004486 -73264 206t sink | 213 -2| 17004486 211t cddce | 219 +6| 17005926 +1440 255t optimized | 217 -2| 17005926 256r expand | 210 -7| 19571573 +2565647 258r into_cfglayout | 208 -2| 19571573 275r loop2_unroll | 212 +4| 22992432 +3420859 291r ce2 | 210 -2| 23011838 312r pro_and_epilogue | 230 +20| 23073776 +61938 315r jump2 | 236 +6| 27110534 +4036758 323r bbro | 229 -7| 21826835 -5283699 W/o the patch cunroll does: 176t cunroll | 294 +151|126548439 +116746342 and we end up with 291 mismatches at bbro. Bootstrapped/regtested x86_64-linux. Plan to commit it after the scale_loop_frequency patch. gcc/ChangeLog: PR middle-end/25623 * tree-ssa-loop-ch.cc (ch_base::copy_headers): Scale loop frequency to maximal number of iterations determined. * tree-ssa-loop-ivcanon.cc (try_unroll_loop_completely): Likewise. gcc/testsuite/ChangeLog: PR middle-end/25623 * gfortran.dg/pr25623-2.f90: New test. --- gcc/testsuite/gfortran.dg/pr25623-2.f90 | 19 +++++++++++++++++++ gcc/tree-ssa-loop-ch.cc | 2 ++ gcc/tree-ssa-loop-ivcanon.cc | 6 ++++++ 3 files changed, 27 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr25623-2.f90 (limited to 'gcc') diff --git a/gcc/testsuite/gfortran.dg/pr25623-2.f90 b/gcc/testsuite/gfortran.dg/pr25623-2.f90 new file mode 100644 index 0000000..57679e0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr25623-2.f90 @@ -0,0 +1,19 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-optimized-blocks -O3" } + +SUBROUTINE S42(a,b,c,N) + IMPLICIT NONE + integer :: N + real*8 :: a(N),b(N),c(N),tmp,tmp2,tmp4 + real*8, parameter :: p=1.0D0/3.0D0 + integer :: i + c=0.0D0 + DO i=1,N + tmp=a(i)**p ! could even be done with a cube root + tmp2=tmp*tmp + tmp4=tmp2*tmp2 + b(i)=b(i)+tmp4 + c(i)=c(i)+tmp2 + ENDDO +END SUBROUTINE +! { dg-final { scan-tree-dump-not "Invalid sum" "optimized" } } diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 291f2db..72792ce 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -422,6 +422,7 @@ ch_base::copy_headers (function *fun) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Loop %d never loops.\n", loop->num); + scale_loop_profile (loop, profile_probability::always (), 0); loops_to_unloop.safe_push (loop); loops_to_unloop_nunroll.safe_push (0); continue; @@ -666,6 +667,7 @@ ch_base::copy_headers (function *fun) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Loop %d no longer loops.\n", loop->num); + scale_loop_profile (loop, profile_probability::always (), 0); loops_to_unloop.safe_push (loop); loops_to_unloop_nunroll.safe_push (0); } diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc index 9e119eb..0117dbf 100644 --- a/gcc/tree-ssa-loop-ivcanon.cc +++ b/gcc/tree-ssa-loop-ivcanon.cc @@ -906,6 +906,10 @@ try_unroll_loop_completely (class loop *loop, if (may_be_zero) bitmap_clear_bit (wont_exit, 1); + /* If loop was originally estimated to iterate too many times, + reduce the profile to avoid new profile inconsistencies. */ + scale_loop_profile (loop, profile_probability::always (), n_unroll); + if (!gimple_duplicate_loop_body_to_header_edge ( loop, loop_preheader_edge (loop), n_unroll, wont_exit, exit, &edges_to_remove, @@ -919,6 +923,8 @@ try_unroll_loop_completely (class loop *loop, free_original_copy_tables (); } + else + scale_loop_profile (loop, profile_probability::always (), 0); /* Remove the conditional from the last copy of the loop. */ if (edge_to_cancel) -- cgit v1.1 From 738808bd9acf1c8a2030449b038502c4286c004d Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 7 Jul 2023 00:17:17 +0000 Subject: Daily bump. --- gcc/ChangeLog | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 91 ++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 41 +++++++++++++ 4 files changed, 286 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6236e9d..222dfe3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,156 @@ +2023-07-06 Jan Hubicka + + PR middle-end/25623 + * tree-ssa-loop-ch.cc (ch_base::copy_headers): Scale loop frequency to maximal number + of iterations determined. + * tree-ssa-loop-ivcanon.cc (try_unroll_loop_completely): Likewise. + +2023-07-06 Jan Hubicka + + * cfgloopmanip.cc (scale_loop_profile): Rewrite exit edge + probability update to be safe on loops with subloops. + Make bound parameter to be iteration bound. + * tree-ssa-loop-ivcanon.cc (try_peel_loop): Update call + of scale_loop_profile. + * tree-vect-loop-manip.cc (vect_do_peeling): Likewise. + +2023-07-06 Hao Liu OS + + PR tree-optimization/110449 + * tree-vect-loop.cc (vectorizable_induction): use vec_n to replace + vec_loop for the unrolled loop. + +2023-07-06 Jan Hubicka + + * cfg.cc (set_edge_probability_and_rescale_others): New function. + (update_bb_profile_for_threading): Use it; simplify the rest. + * cfg.h (set_edge_probability_and_rescale_others): Declare. + * profile-count.h (profile_probability::apply_scale): New. + +2023-07-06 Claudiu Zissulescu + + * doc/extend.texi (ARC Built-in Functions): Update documentation + with missing builtins. + +2023-07-06 Richard Biener + + PR tree-optimization/110556 + * tree-ssa-tail-merge.cc (gimple_equal_p): Check + assign code and all operands of non-stores. + +2023-07-06 Richard Biener + + PR tree-optimization/110563 + * tree-vectorizer.h (vect_determine_partial_vectors_and_peeling): + Remove second argument. + * tree-vect-loop.cc (vect_determine_partial_vectors_and_peeling): + Remove for_epilogue_p argument. Merge assert ... + (vect_analyze_loop_2): ... with check done before determining + partial vectors by moving it after. + * tree-vect-loop-manip.cc (vect_do_peeling): Adjust. + +2023-07-06 Thomas Schwinge + + * ggc-common.cc (gt_pch_note_reorder, gt_pch_save): Tighten up a + few things re 'reorder' option and strings. + * stringpool.cc (gt_pch_p_S): This is now 'gcc_unreachable'. + +2023-07-06 Thomas Schwinge + + * gengtype-parse.cc: Clean up obsolete parametrized structs + remnants. + * gengtype.cc: Likewise. + * gengtype.h: Likewise. + +2023-07-06 Thomas Schwinge + + * gengtype.cc (struct walk_type_data): Remove 'needs_cast_p'. + Adjust all users. + +2023-07-06 Thomas Schwinge + + * gengtype-parse.cc (token_names): Add '"user"'. + * gengtype.h (gty_token): Add 'UNUSED_PARAM_IS' for use with + 'FIRST_TOKEN_WITH_VALUE'. + +2023-07-06 Thomas Schwinge + + * doc/gty.texi (GTY Options) : Enhance. + +2023-07-06 Thomas Schwinge + + * gengtype.cc (write_root, write_roots): Explicitly reject + 'string_length' option. + * doc/gty.texi (GTY Options) : Document. + +2023-07-06 Thomas Schwinge + + * ggc-internal.h (ggc_pch_count_object, ggc_pch_alloc_object) + (ggc_pch_write_object): Remove 'bool is_string' argument. + * ggc-common.cc: Adjust. + * ggc-page.cc: Likewise. + +2023-07-06 Roger Sayle + + * dwarf2out.cc (mem_loc_descriptor): Handle COPYSIGN. + +2023-07-06 Hongyu Wang + + * doc/extend.texi: Move x86 inlining rule to a new subsubsection + and add description for inling of function with arch and tune + attributes. + +2023-07-06 Richard Biener + + PR tree-optimization/110515 + * tree-ssa-pre.cc (compute_avail): Make code dealing + with hoisting loads with different alias-sets more + robust. + +2023-07-06 Ju-Zhe Zhong + + * tree-vect-stmts.cc (vect_get_strided_load_store_ops): Fix ICE. + +2023-07-06 Hongyu Wang + + * config/i386/i386.cc (ix86_can_inline_p): If callee has + default arch=x86-64 and tune=generic, do not block the + inlining to its caller. Also allow callee with different + arch= to be inlined if it has always_inline attribute and + it's ISA is subset of caller's. + +2023-07-06 liuhongt + + * config/i386/i386.cc (ix86_rtx_costs): Adjust rtx_cost for + DF/SFmode AND/IOR/XOR/ANDN operations. + +2023-07-06 Andrew Pinski + + PR middle-end/110554 + * tree-vect-generic.cc (expand_vector_condition): For comparisons, + just build using boolean_type_node instead of the cond_type. + For non-comparisons/non-scalar-bitmask, build a ` != 0` gimple + that will feed into the COND_EXPR. + +2023-07-06 liuhongt + + PR target/110170 + * config/i386/i386.md (movdf_internal): Disparage slightly for + 2 alternatives (r,v) and (v,r) by adding constraint modifier + '?'. + +2023-07-06 Jeevitha Palanisamy + + PR target/106907 + * config/rs6000/rs6000.cc (rs6000_expand_vector_extract): Remove redundant + initialization of new_addr. + +2023-07-06 Hao Liu + + PR tree-optimization/110474 + * tree-vect-loop.cc (vect_analyze_loop_2): unscale the VF by suggested + unroll factor while selecting the epilog vect loop VF. + 2023-07-05 Andrew MacLeod * gimple-range-gori.cc (compute_operand_range): Convert to a tail diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ec0d4f3..2e3c50b 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230706 +20230707 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c3f5906..4f94ccf 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,94 @@ +2023-07-06 Claire Dross + + * gcc-interface/Make-lang.in: Add object files of specification + files. + +2023-07-06 Claire Dross + + * libgnat/s-vs_int.ads: Instance of Value_I_Spec for Integer. + * libgnat/s-vs_lli.ads: Instance of Value_I_Spec for + Long_Long_Integer. + * libgnat/s-vsllli.ads: Instance of Value_I_Spec for + Long_Long_Long_Integer. + * libgnat/s-vs_uns.ads: Instance of Value_U_Spec for Unsigned. + * libgnat/s-vs_llu.ads: Instance of Value_U_Spec for + Long_Long_Unsigned. + * libgnat/s-vslllu.ads: Instance of Value_U_Spec for + Long_Long_Long_Unsigned. + * libgnat/s-imagei.ads: Take instances of Value_*_Spec as + parameters. + * libgnat/s-imagei.adb: Idem. + * libgnat/s-imageu.ads: Idem. + * libgnat/s-imageu.adb: Idem. + * libgnat/s-valuei.ads: Idem. + * libgnat/s-valuei.adb: Idem. + * libgnat/s-valueu.ads: Idem. + * libgnat/s-valueu.adb: Idem. + * libgnat/s-imgint.ads: Adapt instance to new ghost parameters. + * libgnat/s-imglli.ads: Adapt instance to new ghost parameters. + * libgnat/s-imgllli.ads: Adapt instance to new ghost parameters. + * libgnat/s-imglllu.ads: Adapt instance to new ghost parameters. + * libgnat/s-imgllu.ads: Adapt instance to new ghost parameters. + * libgnat/s-imguns.ads: Adapt instance to new ghost parameters. + * libgnat/s-valint.ads: Adapt instance to new ghost parameters. + * libgnat/s-vallli.ads: Adapt instance to new ghost parameters. + * libgnat/s-valllli.ads: Adapt instance to new ghost parameters. + * libgnat/s-vallllu.ads: Adapt instance to new ghost parameters. + * libgnat/s-valllu.ads: Adapt instance to new ghost parameters. + * libgnat/s-valuns.ads: Adapt instance to new ghost parameters. + * libgnat/s-vaispe.ads: Take instance of Value_U_Spec as parameter + and remove unused declaration. + * libgnat/s-vaispe.adb: Idem. + * libgnat/s-vauspe.ads: Remove unused declaration. + * libgnat/s-valspe.ads: Factor out the specification part of + Val_Util. + * libgnat/s-valspe.adb: Idem. + * libgnat/s-valuti.ads: Move specification to Val_Spec. + * libgnat/s-valuti.adb: Idem. + * libgnat/s-valboo.ads: Use Val_Spec. + * libgnat/s-valboo.adb: Idem. + * libgnat/s-imgboo.adb: Idem. + * libgnat/s-imagef.adb: Adapt instances to new ghost parameters. + * Makefile.rtl: List new files. + +2023-07-06 Viljar Indus + + * sem_attr.adb (analyze_attribute.check_array_type): Replace valid + indexes with their staticly evaluated values. + +2023-07-06 Viljar Indus + + * doc/gnat_ugn/the_gnat_compilation_model.rst: Reference "Binding + with Non-Ada Main Programs" from "Creating a Stand-alone Library + to be used in a non-Ada context". + * gnat_ugn.texi: Regenerate. + +2023-07-06 Viljar Indus + + * sem_util.adb (Is_Fully_Initialized_Type): Avoid recalculating + the underlying type twice. + +2023-07-06 Viljar Indus + + * exp_util.adb (Find_Optional_Prim_Op): Stop deriving primitive + operation if there is no underlying type to derive it from. + +2023-07-06 Yannick Moy + + * errout.ads: Add explain code. + * sem_prag.adb (Check_Library_Level_Entity): Refine error message + and add explain code. + +2023-07-06 Steve Baird + + * exp_ch7.adb (Make_Final_Call): Add assertion that if no + finalization call is generated, then the type of the object being + finalized does not require finalization. + * freeze.adb (Freeze_Entity): If freezing an already-frozen + subtype, do not assume that nothing needs to be done. In the case + of a frozen subtype of a non-frozen type or subtype (which is + possible), freeze the non-frozen entity. + 2023-07-04 Eric Botcazou * exp_ch5.adb (Expand_Assign_Array): Adjust comment above the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b5fa70..24119be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,44 @@ +2023-07-06 Jan Hubicka + + PR middle-end/25623 + * gfortran.dg/pr25623-2.f90: New test. + +2023-07-06 Hao Liu OS + + * gcc.target/aarch64/pr110449.c: New testcase. + +2023-07-06 Richard Biener + + PR tree-optimization/110556 + * gcc.dg/torture/pr110556.c: New testcase. + +2023-07-06 Richard Biener + + PR tree-optimization/110515 + * g++.dg/opt/pr110515.C: New testcase. + +2023-07-06 Richard Biener + + PR tree-optimization/110544 + * gcc.dg/vect/pr71264.c: Remove scan for vectorization. + +2023-07-06 Hongyu Wang + + * gcc.target/i386/inline_attr_arch.c: New test. + * gcc.target/i386/inline_target_clones.c: Ditto. + +2023-07-06 liuhongt + + * gcc.target/i386/pr110170-2.c: New test. + +2023-07-06 liuhongt + + * gcc.target/i386/pr110170-3.c: New test. + +2023-07-06 Hao Liu + + * gcc.target/aarch64/pr110474.c: New testcase. + 2023-07-05 Robin Dapp * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c: Add -- cgit v1.1 From f58819c9aabfe23fa0e6ba422b39a00a980f991e Mon Sep 17 00:00:00 2001 From: Pan Li Date: Mon, 3 Jul 2023 15:59:03 +0800 Subject: RISC-V: Fix one typo of FRM dynamic definition This patch would like to fix one typo that take rdn instead of dyn by mistake. Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/vector.md: Fix typo. --- gcc/config/riscv/vector.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 9df40e4..5b7a17b 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -496,8 +496,8 @@ (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RMM") (const_string "rmm") - (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RDN") - (const_string "rdn") + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_DYN") + (const_string "dyn") ] (const_string "none") ) -- cgit v1.1 From 55900189ab517906efe08f8d17f3e4a310ee7fff Mon Sep 17 00:00:00 2001 From: Pan Li Date: Tue, 4 Jul 2023 22:05:36 +0800 Subject: RISC-V: Fix one bug for floating-point static frm This patch would like to fix one bug to align below items of spec. RVV floating-point instructions always (implicitly) use the dynamic rounding mode. This implies that rounding is performed according to the rounding mode set in the FRM register. The FRM register itself only holds proper rounding modes and never the dynamic rounding mode. Signed-off-by: Pan Li Co-Authored-By: Robin Dapp gcc/ChangeLog: * config/riscv/riscv.cc (riscv_emit_mode_set): Avoid emit insn when FRM_MODE_DYN. (riscv_mode_entry): Take FRM_MODE_DYN as entry mode. (riscv_mode_exit): Likewise for exit mode. (riscv_mode_needed): Likewise for needed mode. (riscv_mode_after): Likewise for after mode. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: New test. --- gcc/config/riscv/riscv.cc | 27 +++++++++++++++---- .../riscv/rvv/base/float-point-frm-insert-6.c | 31 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index e4dc811..38d8eb2 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7670,8 +7670,19 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode, emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode))); break; case RISCV_FRM: - if (mode != FRM_MODE_NONE && mode != prev_mode) + /* Switching to the dynamic rounding mode is not necessary. When an + instruction requests it, it effectively uses the rounding mode already + set in the FRM register. All other rounding modes require us to + switch the rounding mode via the FRM register. */ + if (mode != FRM_MODE_DYN && mode != prev_mode) { + /* TODO: By design, FRM_MODE_xxx used by mode switch which is + different from the FRM value like FRM_RTZ defined in + riscv-protos.h. When mode switching we actually need a conversion + function to convert the mode of mode switching to the actual + FRM value like FRM_RTZ. For now, the value between the mode of + mode swith and the FRM value in riscv-protos.h take the same value, + and then we leverage this assumption when emit. */ rtx scaler = gen_reg_rtx (SImode); rtx imm = gen_int_mode (mode, SImode); @@ -7697,7 +7708,10 @@ riscv_mode_needed (int entity, rtx_insn *insn) case RISCV_VXRM: return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE; case RISCV_FRM: - return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_NONE; + /* TODO: Here we may return FRM_MODE_NONE from get_attr_frm_mode, as well + as FRM_MODE_DYN as default. It is kind of inconsistent and we will + take care of it after dynamic rounding mode. */ + return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_DYN; default: gcc_unreachable (); } @@ -7757,7 +7771,7 @@ riscv_mode_after (int entity, int mode, rtx_insn *insn) case RISCV_FRM: return riscv_entity_mode_after (FRM_REGNUM, insn, mode, (int (*)(rtx_insn *)) get_attr_frm_mode, - FRM_MODE_NONE); + FRM_MODE_DYN); default: gcc_unreachable (); } @@ -7774,7 +7788,10 @@ riscv_mode_entry (int entity) case RISCV_VXRM: return VXRM_MODE_NONE; case RISCV_FRM: - return FRM_MODE_NONE; + /* According to RVV 1.0 spec, all vector floating-point operations use + the dynamic rounding mode in the frm register. Likewise in other + similar places. */ + return FRM_MODE_DYN; default: gcc_unreachable (); } @@ -7791,7 +7808,7 @@ riscv_mode_exit (int entity) case RISCV_VXRM: return VXRM_MODE_NONE; case RISCV_FRM: - return FRM_MODE_NONE; + return FRM_MODE_DYN; default: gcc_unreachable (); } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c new file mode 100644 index 0000000..6d896e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +typedef float float32_t; + +vfloat32m1_t +test_riscv_vfadd_vv_f32m1_rm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + return __riscv_vfadd_vv_f32m1_rm (op1, op2, 7, vl); +} + +vfloat32m1_t +test_vfadd_vv_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, vfloat32m1_t op2, + size_t vl) { + return __riscv_vfadd_vv_f32m1_m_rm(mask, op1, op2, 7, vl); +} + +vfloat32m1_t +test_vfadd_vf_f32m1_rm(vfloat32m1_t op1, float32_t op2, size_t vl) { + return __riscv_vfadd_vf_f32m1_rm(op1, op2, 7, vl); +} + +vfloat32m1_t +test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2, + size_t vl) { + return __riscv_vfadd_vf_f32m1_m_rm(mask, op1, op2, 7, vl); +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-not {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} } } */ -- cgit v1.1 From cab6a6b6d3a28032c812f78b5d96aedb597c91f8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 7 Jul 2023 09:44:36 +0200 Subject: x86: correct / simplify @vec_extract_hi_ and vec_extract_hi_v32qi The middle alternative each was unusable without enabling AVX512DQ (in addition to AVX512VL), which is entirely unrelated here. The last alternative is usable with AVX512VL only (due to type restrictions on what may be put in the upper 16 YMM registers), and hence is pointlessly forcing 512-bit mode (without actually reflecting that in the "mode" attribute). gcc/ * config/i386/sse.md (@vec_extract_hi_): Drop last alternative. Switch new last alternative's "isa" attribute to "avx512vl". (vec_extract_hi_v32qi): Likewise. --- gcc/config/i386/sse.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 418c337..4fb1ce4 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -12029,9 +12029,9 @@ "operands[1] = gen_lowpart (mode, operands[1]);") (define_insn "@vec_extract_hi_" - [(set (match_operand: 0 "nonimmediate_operand" "=xm,vm,vm") + [(set (match_operand: 0 "nonimmediate_operand" "=xm,vm") (vec_select: - (match_operand:V16_256 1 "register_operand" "x,v,v") + (match_operand:V16_256 1 "register_operand" "x,v") (parallel [(const_int 8) (const_int 9) (const_int 10) (const_int 11) (const_int 12) (const_int 13) @@ -12039,13 +12039,12 @@ "TARGET_AVX" "@ vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1} - vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1} - vextracti32x4\t{$0x1, %g1, %0|%0, %g1, 0x1}" + vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1}" [(set_attr "type" "sselog1") (set_attr "prefix_extra" "1") (set_attr "length_immediate" "1") - (set_attr "isa" "*,avx512dq,avx512f") - (set_attr "prefix" "vex,evex,evex") + (set_attr "isa" "*,avx512vl") + (set_attr "prefix" "vex,evex") (set_attr "mode" "OI")]) (define_insn_and_split "vec_extract_lo_v64qi" @@ -12144,9 +12143,9 @@ "operands[1] = gen_lowpart (V16QImode, operands[1]);") (define_insn "vec_extract_hi_v32qi" - [(set (match_operand:V16QI 0 "nonimmediate_operand" "=xm,vm,vm") + [(set (match_operand:V16QI 0 "nonimmediate_operand" "=xm,vm") (vec_select:V16QI - (match_operand:V32QI 1 "register_operand" "x,v,v") + (match_operand:V32QI 1 "register_operand" "x,v") (parallel [(const_int 16) (const_int 17) (const_int 18) (const_int 19) (const_int 20) (const_int 21) @@ -12158,13 +12157,12 @@ "TARGET_AVX" "@ vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1} - vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1} - vextracti32x4\t{$0x1, %g1, %0|%0, %g1, 0x1}" + vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1}" [(set_attr "type" "sselog1") (set_attr "prefix_extra" "1") (set_attr "length_immediate" "1") - (set_attr "isa" "*,avx512dq,avx512f") - (set_attr "prefix" "vex,evex,evex") + (set_attr "isa" "*,avx512vl") + (set_attr "prefix" "vex,evex") (set_attr "mode" "OI")]) ;; NB: *vec_extract_0 must be placed before *vec_extracthf. -- cgit v1.1 From a069b8662689865178596e2aab46d4dc4eaa051e Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 7 Jul 2023 09:45:06 +0200 Subject: x86: slightly correct / simplify *vec_extractv2ti V2TImode values cannot appear in the upper 16 YMM registers without AVX512VL being enabled. Therefore forcing 512-bit mode (also not reflected in the "mode" attribute) is pointless. gcc/ * config/i386/sse.md (*vec_extractv2ti): Drop g modifiers. --- gcc/config/i386/sse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 4fb1ce4..a209937 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -20115,7 +20115,7 @@ "TARGET_AVX" "@ vextract%~128\t{%2, %1, %0|%0, %1, %2} - vextracti32x4\t{%2, %g1, %0|%0, %g1, %2}" + vextracti32x4\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") (set_attr "length_immediate" "1") -- cgit v1.1 From 0c888665dfbd5175256c674ee82d85bd0f7450f7 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 29 Jun 2023 11:27:22 +0200 Subject: Implement value/mask tracking for irange. Integer ranges (irange) currently track known 0 bits. We've wanted to track known 1 bits for some time, and instead of tracking known 0 and known 1's separately, it has been suggested we track a value/mask pair similarly to what we do for CCP and RTL. This patch implements such a thing. With this we now track a VALUE integer which are the known values, and a MASK which tells us which bits contain meaningful information. This allows us to fix a handful of enhancement requests, such as PR107043 and PR107053. There is a 4.48% performance penalty for VRP and 0.42% in overall compilation for this entire patchset. It is expected and in line with the loss incurred when we started tracking known 0 bits. This patch just provides the value/mask tracking support. All the nonzero users (range-op, IPA, CCP, etc), are still using the nonzero nomenclature. For that matter, this patch reimplements the nonzero accessors with the value/mask functionality. In follow-up patches I will enhance these passes to use the value/mask information, and fix the aforementioned PRs. gcc/ChangeLog: * data-streamer-in.cc (streamer_read_value_range): Adjust for value/mask. * data-streamer-out.cc (streamer_write_vrange): Same. * range-op.cc (operator_cast::fold_range): Same. * value-range-pretty-print.cc (vrange_printer::print_irange_bitmasks): Same. * value-range-storage.cc (irange_storage::write_lengths_address): Same. (irange_storage::set_irange): Same. (irange_storage::get_irange): Same. (irange_storage::size): Same. (irange_storage::dump): Same. * value-range-storage.h: Same. * value-range.cc (debug): New. (irange_bitmask::dump): New. (add_vrange): Adjust for value/mask. (irange::operator=): Same. (irange::set): Same. (irange::verify_range): Same. (irange::operator==): Same. (irange::contains_p): Same. (irange::irange_single_pair_union): Same. (irange::union_): Same. (irange::intersect): Same. (irange::invert): Same. (irange::get_nonzero_bits_from_range): Rename to... (irange::get_bitmask_from_range): ...this. (irange::set_range_from_nonzero_bits): Rename to... (irange::set_range_from_bitmask): ...this. (irange::set_nonzero_bits): Rename to... (irange::update_bitmask): ...this. (irange::get_nonzero_bits): Rename to... (irange::get_bitmask): ...this. (irange::intersect_nonzero_bits): Rename to... (irange::intersect_bitmask): ...this. (irange::union_nonzero_bits): Rename to... (irange::union_bitmask): ...this. (irange_bitmask::verify_mask): New. * value-range.h (class irange_bitmask): New. (irange_bitmask::set_unknown): New. (irange_bitmask::unknown_p): New. (irange_bitmask::irange_bitmask): New. (irange_bitmask::get_precision): New. (irange_bitmask::get_nonzero_bits): New. (irange_bitmask::set_nonzero_bits): New. (irange_bitmask::operator==): New. (irange_bitmask::union_): New. (irange_bitmask::intersect): New. (class irange): Friend vrange_printer. (irange::varying_compatible_p): Adjust for bitmask. (irange::set_varying): Same. (irange::set_nonzero): Same. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107009.c: Adjust irange dumping for value/mask changes. * gcc.dg/tree-ssa/vrp-unreachable.c: Same. * gcc.dg/tree-ssa/vrp122.c: Same. --- gcc/data-streamer-in.cc | 6 +- gcc/data-streamer-out.cc | 5 +- gcc/range-op.cc | 16 +- gcc/testsuite/gcc.dg/tree-ssa/pr107009.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp122.c | 2 +- gcc/value-range-pretty-print.cc | 11 +- gcc/value-range-storage.cc | 26 ++- gcc/value-range-storage.h | 2 +- gcc/value-range.cc | 248 +++++++++++++++--------- gcc/value-range.h | 153 ++++++++++++++- 11 files changed, 351 insertions(+), 122 deletions(-) (limited to 'gcc') diff --git a/gcc/data-streamer-in.cc b/gcc/data-streamer-in.cc index 578c328..6e36adc 100644 --- a/gcc/data-streamer-in.cc +++ b/gcc/data-streamer-in.cc @@ -241,8 +241,10 @@ streamer_read_value_range (class lto_input_block *ib, data_in *data_in, int_range<2> tmp (type, lb, ub); r.union_ (tmp); } - wide_int nz = streamer_read_wide_int (ib); - r.set_nonzero_bits (nz); + wide_int value = streamer_read_wide_int (ib); + wide_int mask = streamer_read_wide_int (ib); + irange_bitmask bm (value, mask); + r.update_bitmask (bm); return; } if (is_a (vr)) diff --git a/gcc/data-streamer-out.cc b/gcc/data-streamer-out.cc index 93dedfc..8af8ae0 100644 --- a/gcc/data-streamer-out.cc +++ b/gcc/data-streamer-out.cc @@ -423,7 +423,10 @@ streamer_write_vrange (struct output_block *ob, const vrange &v) streamer_write_wide_int (ob, r.lower_bound (i)); streamer_write_wide_int (ob, r.upper_bound (i)); } - streamer_write_wide_int (ob, r.get_nonzero_bits ()); + // TODO: We could avoid streaming out the value if the mask is -1. + irange_bitmask bm = r.get_bitmask (); + streamer_write_wide_int (ob, bm.value ()); + streamer_write_wide_int (ob, bm.mask ()); return; } if (is_a (v)) diff --git a/gcc/range-op.cc b/gcc/range-op.cc index f0dff53..cb58431 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -2876,16 +2876,20 @@ operator_cast::fold_range (irange &r, tree type ATTRIBUTE_UNUSED, return true; } - // Update the nonzero mask. Truncating casts are problematic unless + // Update the bitmask. Truncating casts are problematic unless // the conversion fits in the resulting outer type. - wide_int nz = inner.get_nonzero_bits (); + irange_bitmask bm = inner.get_bitmask (); if (truncating_cast_p (inner, outer) - && wi::rshift (nz, wi::uhwi (TYPE_PRECISION (outer.type ()), - TYPE_PRECISION (inner.type ())), + && wi::rshift (bm.mask (), + wi::uhwi (TYPE_PRECISION (outer.type ()), + TYPE_PRECISION (inner.type ())), TYPE_SIGN (inner.type ())) != 0) return true; - nz = wide_int::from (nz, TYPE_PRECISION (type), TYPE_SIGN (inner.type ())); - r.set_nonzero_bits (nz); + unsigned prec = TYPE_PRECISION (type); + signop sign = TYPE_SIGN (inner.type ()); + bm = irange_bitmask (wide_int::from (bm.value (), prec, sign), + wide_int::from (bm.mask (), prec, sign)); + r.update_bitmask (bm); return true; } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c index 5010aed..0450950 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c @@ -12,4 +12,4 @@ void saxpy(size_t n) foobar (n); } -// { dg-final { scan-tree-dump "NONZERO.*fff8" "dom2" } } +// { dg-final { scan-tree-dump "fff8 VALUE 0x0" "dom2" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable.c index cdc5740..5835dfc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-unreachable.c @@ -39,4 +39,4 @@ void func (unsigned n, unsigned m) /* { dg-final { scan-tree-dump-not "dead" "vrp1" } } */ /* { dg-final { scan-tree-dump-times "builtin_unreachable" 1 "vrp1" } } */ /* { dg-final { scan-tree-dump-not "builtin_unreachable" "vrp2" } } */ -/* { dg-final { scan-tree-dump-times "fff8" 4 "vrp2" } } */ +/* { dg-final { scan-tree-dump-times "fff8 VALUE 0x0" 4 "vrp2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c index b2ddcda..5a4ca85 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c @@ -16,4 +16,4 @@ int f(unsigned t) return 0; } -// { dg-final { scan-tree-dump "Global Exported: g_.* NONZERO 0x.*fff0" "evrp" } } +// { dg-final { scan-tree-dump "Global Exported: g_.* MASK 0x1 VALUE 0x0" "evrp" } } diff --git a/gcc/value-range-pretty-print.cc b/gcc/value-range-pretty-print.cc index 8d47d80..c95b09d 100644 --- a/gcc/value-range-pretty-print.cc +++ b/gcc/value-range-pretty-print.cc @@ -94,13 +94,16 @@ vrange_printer::print_irange_bound (const wide_int &bound, tree type) const void vrange_printer::print_irange_bitmasks (const irange &r) const { - wide_int nz = r.get_nonzero_bits (); - if (nz == -1) + irange_bitmask bm = r.m_bitmask; + if (bm.unknown_p ()) return; - pp_string (pp, " NONZERO "); + pp_string (pp, " MASK "); char buf[WIDE_INT_PRINT_BUFFER_SIZE]; - print_hex (nz, buf); + print_hex (bm.mask (), buf); + pp_string (pp, buf); + pp_string (pp, " VALUE "); + print_hex (bm.value (), buf); pp_string (pp, buf); } diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc index 2f82739..e94d7f9 100644 --- a/gcc/value-range-storage.cc +++ b/gcc/value-range-storage.cc @@ -232,7 +232,7 @@ vrange_storage::equal_p (const vrange &r) const unsigned char * irange_storage::write_lengths_address () { - return (unsigned char *)&m_val[(m_num_ranges * 2 + 1) + return (unsigned char *)&m_val[(m_num_ranges * 2 + 2) * WIDE_INT_MAX_HWIS (m_precision)]; } @@ -301,7 +301,11 @@ irange_storage::set_irange (const irange &r) write_wide_int (val, len, r.lower_bound (i)); write_wide_int (val, len, r.upper_bound (i)); } - write_wide_int (val, len, r.m_nonzero_mask); + + // TODO: We could avoid streaming out the value if the mask is -1. + irange_bitmask bm = r.m_bitmask; + write_wide_int (val, len, bm.value ()); + write_wide_int (val, len, bm.mask ()); if (flag_checking) { @@ -367,7 +371,12 @@ irange_storage::get_irange (irange &r, tree type) const r.union_ (tmp); } } - read_wide_int (r.m_nonzero_mask, val, *len, m_precision); + + wide_int bits_value, bits_mask; + read_wide_int (bits_value, val, *len, m_precision); + val += *len++; + read_wide_int (bits_mask, val, *len, m_precision); + r.m_bitmask = irange_bitmask (bits_value, bits_mask); if (r.m_kind == VR_VARYING) r.m_kind = VR_RANGE; @@ -399,7 +408,7 @@ irange_storage::size (const irange &r) return sizeof (irange_storage); unsigned prec = TYPE_PRECISION (r.type ()); - unsigned n = r.num_pairs () * 2 + 1; + unsigned n = r.num_pairs () * 2 + 2; unsigned hwi_size = ((n * WIDE_INT_MAX_HWIS (prec) - 1) * sizeof (HOST_WIDE_INT)); unsigned len_size = n; @@ -428,7 +437,7 @@ irange_storage::dump () const int i, j; fprintf (stderr, " lengths = [ "); - for (i = 0; i < m_num_ranges * 2 + 1; ++i) + for (i = 0; i < m_num_ranges * 2 + 2; ++i) fprintf (stderr, "%d ", len[i]); fprintf (stderr, "]\n"); @@ -443,8 +452,13 @@ irange_storage::dump () const *val++); ++len; } + + // Dump value/mask pair. + for (j = 0; j < *len; ++j) + fprintf (stderr, " [VALUE] " HOST_WIDE_INT_PRINT_DEC "\n", *val++); + ++len; for (j = 0; j < *len; ++j) - fprintf (stderr, " [NZ] " HOST_WIDE_INT_PRINT_DEC "\n", *val++); + fprintf (stderr, " [MASK] " HOST_WIDE_INT_PRINT_DEC "\n", *val++); } DEBUG_FUNCTION void diff --git a/gcc/value-range-storage.h b/gcc/value-range-storage.h index 99fb815..a91833c 100644 --- a/gcc/value-range-storage.h +++ b/gcc/value-range-storage.h @@ -91,7 +91,7 @@ private: enum value_range_kind m_kind : 3; - // The length of this is m_num_ranges * 2 + 1 to accomodate the nonzero bits. + // The length of this is m_num_ranges * 2 + 2 to accomodate the bitmask. HOST_WIDE_INT m_val[1]; // Another variable-length part of the structure following the HWIs. diff --git a/gcc/value-range.cc b/gcc/value-range.cc index f5d4bf3..8e5607a 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -79,6 +79,13 @@ debug (const Value_Range &r) fprintf (stderr, "\n"); } +DEBUG_FUNCTION void +debug (const irange_bitmask &bm) +{ + bm.dump (stderr); + fprintf (stderr, "\n"); +} + // Default vrange definitions. bool @@ -235,6 +242,23 @@ vrange::dump (FILE *file) const pp_flush (&buffer); } +void +irange_bitmask::dump (FILE *file) const +{ + char buf[WIDE_INT_PRINT_BUFFER_SIZE]; + pretty_printer buffer; + + pp_needs_newline (&buffer) = true; + buffer.buffer->stream = file; + pp_string (&buffer, "MASK "); + print_hex (m_mask, buf); + pp_string (&buffer, buf); + pp_string (&buffer, " VALUE "); + print_hex (m_value, buf); + pp_string (&buffer, buf); + pp_flush (&buffer); +} + namespace inchash { @@ -263,7 +287,9 @@ add_vrange (const vrange &v, inchash::hash &hstate, hstate.add_wide_int (r.lower_bound (i)); hstate.add_wide_int (r.upper_bound (i)); } - hstate.add_wide_int (r.get_nonzero_bits ()); + irange_bitmask bm = r.get_bitmask (); + hstate.add_wide_int (bm.value ()); + hstate.add_wide_int (bm.mask ()); return; } if (is_a (v)) @@ -908,7 +934,7 @@ irange::operator= (const irange &src) m_num_ranges = lim; m_type = src.m_type; m_kind = src.m_kind; - m_nonzero_mask = src.m_nonzero_mask; + m_bitmask = src.m_bitmask; if (m_max_ranges == 1) normalize_kind (); if (flag_checking) @@ -972,7 +998,7 @@ irange::set (tree type, const wide_int &min, const wide_int &max, wide_int max_value = wi::max_value (prec, sign); m_type = type; - m_nonzero_mask = wi::minus_one (prec); + m_bitmask.set_unknown (prec); if (kind == VR_RANGE) { @@ -1059,7 +1085,7 @@ irange::verify_range () unsigned prec = TYPE_PRECISION (m_type); if (m_kind == VR_VARYING) { - gcc_checking_assert (m_nonzero_mask == -1); + gcc_checking_assert (m_bitmask.unknown_p ()); gcc_checking_assert (m_num_ranges == 1); gcc_checking_assert (varying_compatible_p ()); gcc_checking_assert (lower_bound ().get_precision () == prec); @@ -1077,7 +1103,7 @@ irange::verify_range () int c = wi::cmp (lb, ub, TYPE_SIGN (m_type)); gcc_checking_assert (c == 0 || c == -1); } - gcc_checking_assert (m_nonzero_mask.get_precision () == prec); + m_bitmask.verify_mask (); } bool @@ -1101,9 +1127,18 @@ irange::operator== (const irange &other) const if (lb != lb_other || ub != ub_other) return false; } - widest_int nz1 = widest_int::from (get_nonzero_bits (), sign1); - widest_int nz2 = widest_int::from (other.get_nonzero_bits (), sign2); - return nz1 == nz2; + + irange_bitmask bm1 = get_bitmask (); + irange_bitmask bm2 = other.get_bitmask (); + widest_int tmp1 = widest_int::from (bm1.mask (), sign1); + widest_int tmp2 = widest_int::from (bm2.mask (), sign2); + if (tmp1 != tmp2) + return false; + if (bm1.unknown_p ()) + return true; + tmp1 = widest_int::from (bm1.value (), sign1); + tmp2 = widest_int::from (bm2.value (), sign2); + return tmp1 == tmp2; } /* If range is a singleton, place it in RESULT and return TRUE. */ @@ -1143,10 +1178,10 @@ irange::contains_p (const wide_int &cst) const if (undefined_p ()) return false; - // See if we can exclude CST based on the nonzero bits. - if (m_nonzero_mask != -1 + // See if we can exclude CST based on the known 0 bits. + if (!m_bitmask.unknown_p () && cst != 0 - && wi::bit_and (m_nonzero_mask, cst) == 0) + && wi::bit_and (m_bitmask.get_nonzero_bits (), cst) == 0) return false; signop sign = TYPE_SIGN (type ()); @@ -1176,7 +1211,7 @@ irange::irange_single_pair_union (const irange &r) { // If current upper bound is new upper bound, we're done. if (wi::le_p (r.m_base[1], m_base[1], sign)) - return union_nonzero_bits (r); + return union_bitmask (r); // Otherwise R has the new upper bound. // Check for overlap/touching ranges, or single target range. if (m_max_ranges == 1 @@ -1192,7 +1227,7 @@ irange::irange_single_pair_union (const irange &r) } // The range has been altered, so normalize it even if nothing // changed in the mask. - if (!union_nonzero_bits (r)) + if (!union_bitmask (r)) normalize_kind (); if (flag_checking) verify_range (); @@ -1221,7 +1256,7 @@ irange::irange_single_pair_union (const irange &r) } // The range has been altered, so normalize it even if nothing // changed in the mask. - if (!union_nonzero_bits (r)) + if (!union_bitmask (r)) normalize_kind (); if (flag_checking) verify_range (); @@ -1261,7 +1296,7 @@ irange::union_ (const vrange &v) // If this ranges fully contains R, then we need do nothing. if (irange_contains_p (r)) - return union_nonzero_bits (r); + return union_bitmask (r); // Do not worry about merging and such by reserving twice as many // pairs as needed, and then simply sort the 2 ranges into this @@ -1356,7 +1391,7 @@ irange::union_ (const vrange &v) m_kind = VR_RANGE; // The range has been altered, so normalize it even if nothing // changed in the mask. - if (!union_nonzero_bits (r)) + if (!union_bitmask (r)) normalize_kind (); if (flag_checking) verify_range (); @@ -1439,13 +1474,13 @@ irange::intersect (const vrange &v) if (undefined_p ()) return true; - res |= intersect_nonzero_bits (r); + res |= intersect_bitmask (r); return res; } // If R fully contains this, then intersection will change nothing. if (r.irange_contains_p (*this)) - return intersect_nonzero_bits (r); + return intersect_bitmask (r); // ?? We could probably come up with something smarter than the // worst case scenario here. @@ -1528,7 +1563,7 @@ irange::intersect (const vrange &v) m_kind = VR_RANGE; // The range has been altered, so normalize it even if nothing // changed in the mask. - if (!intersect_nonzero_bits (r)) + if (!intersect_bitmask (r)) normalize_kind (); if (flag_checking) verify_range (); @@ -1652,7 +1687,7 @@ irange::invert () signop sign = TYPE_SIGN (ttype); wide_int type_min = wi::min_value (prec, sign); wide_int type_max = wi::max_value (prec, sign); - m_nonzero_mask = wi::minus_one (prec); + m_bitmask.set_unknown (prec); // At this point, we need one extra sub-range to represent the // inverse. @@ -1723,45 +1758,45 @@ irange::invert () verify_range (); } -// Return the nonzero bits inherent in the range. +// Return the bitmask inherent in the range. -wide_int -irange::get_nonzero_bits_from_range () const +irange_bitmask +irange::get_bitmask_from_range () const { wide_int min = lower_bound (); wide_int max = upper_bound (); wide_int xorv = min ^ max; + unsigned prec = TYPE_PRECISION (type ()); + if (xorv != 0) - { - unsigned prec = TYPE_PRECISION (type ()); - xorv = wi::mask (prec - wi::clz (xorv), false, prec); - } - return min | xorv; + xorv = wi::mask (prec - wi::clz (xorv), false, prec); + + return irange_bitmask (wi::zero (prec), min | xorv); } -// If the the nonzero mask can be trivially converted to a range, do -// so and return TRUE. +// If the the mask can be trivially converted to a range, do so and +// return TRUE. bool -irange::set_range_from_nonzero_bits () +irange::set_range_from_bitmask () { gcc_checking_assert (!undefined_p ()); - if (m_nonzero_mask == -1) + if (m_bitmask.unknown_p ()) return false; - unsigned popcount = wi::popcount (m_nonzero_mask); + unsigned popcount = wi::popcount (m_bitmask.get_nonzero_bits ()); // If we have only one bit set in the mask, we can figure out the // range immediately. if (popcount == 1) { // Make sure we don't pessimize the range. - if (!contains_p (m_nonzero_mask)) + if (!contains_p (m_bitmask.get_nonzero_bits ())) return false; bool has_zero = contains_zero_p (*this); - wide_int nz = m_nonzero_mask; + wide_int nz = m_bitmask.get_nonzero_bits (); set (m_type, nz, nz); - m_nonzero_mask = nz; + m_bitmask.set_nonzero_bits (nz); if (has_zero) { int_range<2> zero; @@ -1781,95 +1816,126 @@ irange::set_range_from_nonzero_bits () } void -irange::set_nonzero_bits (const wide_int &bits) +irange::update_bitmask (const irange_bitmask &bm) { gcc_checking_assert (!undefined_p ()); - // Drop VARYINGs with a nonzero mask to a plain range. - if (m_kind == VR_VARYING && bits != -1) + // Drop VARYINGs with known bits to a plain range. + if (m_kind == VR_VARYING && !bm.unknown_p ()) m_kind = VR_RANGE; - m_nonzero_mask = bits; - if (!set_range_from_nonzero_bits ()) + m_bitmask = bm; + if (!set_range_from_bitmask ()) normalize_kind (); if (flag_checking) verify_range (); } -// Return the nonzero bitmask. This will return the nonzero bits plus -// the nonzero bits inherent in the range. +// Return the bitmask of known bits that includes the bitmask inherent +// in the range. + +irange_bitmask +irange::get_bitmask () const +{ + gcc_checking_assert (!undefined_p ()); + + // The mask inherent in the range is calculated on-demand. For + // example, [0,255] does not have known bits set by default. This + // saves us considerable time, because setting it at creation incurs + // a large penalty for irange::set. At the time of writing there + // was a 5% slowdown in VRP if we kept the mask precisely up to date + // at all times. Instead, we default to -1 and set it when + // explicitly requested. However, this function will always return + // the correct mask. + // + // This also means that the mask may have a finer granularity than + // the range and thus contradict it. Think of the mask as an + // enhancement to the range. For example: + // + // [3, 1000] MASK 0xfffffffe VALUE 0x0 + // + // 3 is in the range endpoints, but is excluded per the known 0 bits + // in the mask. + irange_bitmask bm = get_bitmask_from_range (); + if (!m_bitmask.unknown_p ()) + bm.intersect (m_bitmask); + return bm; +} + +// Set the nonzero bits in R into THIS. Return TRUE and +// normalize the range if anything changed. + +void +irange::set_nonzero_bits (const wide_int &bits) +{ + gcc_checking_assert (!undefined_p ()); + irange_bitmask bm (wi::zero (TYPE_PRECISION (type ())), bits); + update_bitmask (bm); +} + +// Return the nonzero bits in R. wide_int irange::get_nonzero_bits () const { gcc_checking_assert (!undefined_p ()); - // The nonzero mask inherent in the range is calculated on-demand. - // For example, [0,255] does not have a 0xff nonzero mask by default - // (unless manually set). This saves us considerable time, because - // setting it at creation incurs a large penalty for irange::set. - // At the time of writing there was a 5% slowdown in VRP if we kept - // the mask precisely up to date at all times. Instead, we default - // to -1 and set it when explicitly requested. However, this - // function will always return the correct mask. - if (m_nonzero_mask == -1) - return get_nonzero_bits_from_range (); - else - return m_nonzero_mask & get_nonzero_bits_from_range (); + irange_bitmask bm = get_bitmask (); + return bm.value () | bm.mask (); } -// Intersect the nonzero bits in R into THIS. Return TRUE and -// normalize the range if anything changed. +// Intersect the bitmask in R into THIS and normalize the range. +// Return TRUE if the intersection changed anything. bool -irange::intersect_nonzero_bits (const irange &r) +irange::intersect_bitmask (const irange &r) { gcc_checking_assert (!undefined_p () && !r.undefined_p ()); - if (m_nonzero_mask == -1 && r.m_nonzero_mask == -1) + if (m_bitmask == r.m_bitmask) return false; - if (m_nonzero_mask != r.m_nonzero_mask) - { - wide_int nz = get_nonzero_bits () & r.get_nonzero_bits (); - // If the nonzero bits did not change, return false. - if (nz == get_nonzero_bits ()) - return false; + irange_bitmask bm = get_bitmask (); + if (!bm.intersect (r.get_bitmask ())) + return false; - m_nonzero_mask = nz; - if (!set_range_from_nonzero_bits ()) - normalize_kind (); - if (flag_checking) - verify_range (); - return true; - } - return false; + m_bitmask = bm; + if (!set_range_from_bitmask ()) + normalize_kind (); + if (flag_checking) + verify_range (); + return true; } -// Union the nonzero bits in R into THIS. Return TRUE and normalize -// the range if anything changed. +// Union the bitmask in R into THIS. Return TRUE and normalize the +// range if anything changed. bool -irange::union_nonzero_bits (const irange &r) +irange::union_bitmask (const irange &r) { gcc_checking_assert (!undefined_p () && !r.undefined_p ()); - if (m_nonzero_mask == -1 && r.m_nonzero_mask == -1) + if (m_bitmask == r.m_bitmask) return false; - if (m_nonzero_mask != r.m_nonzero_mask) - { - wide_int save = get_nonzero_bits (); - m_nonzero_mask = save | r.get_nonzero_bits (); - if (m_nonzero_mask == save) - return false; - // No need to call set_range_from_nonzero_bits, because we'll - // never narrow the range. Besides, it would cause endless - // recursion because of the union_ in - // set_range_from_nonzero_bits. - normalize_kind (); - return true; - } - return false; + irange_bitmask bm = get_bitmask (); + if (!bm.union_ (r.get_bitmask ())) + return false; + + m_bitmask = bm; + // No need to call set_range_from_mask, because we'll never + // narrow the range. Besides, it would cause endless recursion + // because of the union_ in set_range_from_mask. + normalize_kind (); + return true; +} + +void +irange_bitmask::verify_mask () const +{ + gcc_assert (m_value.get_precision () == m_mask.get_precision ()); + // Unknown bits must have their corresponding value bits cleared as + // it simplifies union and intersect. + gcc_assert (wi::bit_and (m_mask, m_value) == 0); } void diff --git a/gcc/value-range.h b/gcc/value-range.h index 5d4eaf8..0170188 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -113,12 +113,146 @@ namespace inchash extern void add_vrange (const vrange &, hash &, unsigned flags = 0); } +// A pair of values representing the known bits in a range. Zero bits +// in MASK cover constant values. Set bits in MASK cover unknown +// values. VALUE are the known bits. +// +// Set bits in MASK (no meaningful information) must have their +// corresponding bits in VALUE cleared, as this speeds up union and +// intersect. + +class irange_bitmask +{ +public: + irange_bitmask () { /* uninitialized */ } + irange_bitmask (unsigned prec) { set_unknown (prec); } + irange_bitmask (const wide_int &value, const wide_int &mask); + wide_int value () const { return m_value; } + wide_int mask () const { return m_mask; } + void set_unknown (unsigned prec); + bool unknown_p () const; + unsigned get_precision () const; + bool union_ (const irange_bitmask &src); + bool intersect (const irange_bitmask &src); + bool operator== (const irange_bitmask &src) const; + bool operator!= (const irange_bitmask &src) const { return !(*this == src); } + void verify_mask () const; + void dump (FILE *) const; + + // Convenience functions for nonzero bitmask compatibility. + wide_int get_nonzero_bits () const; + void set_nonzero_bits (const wide_int &bits); +private: + wide_int m_value; + wide_int m_mask; +}; + +inline void +irange_bitmask::set_unknown (unsigned prec) +{ + m_value = wi::zero (prec); + m_mask = wi::minus_one (prec); + if (flag_checking) + verify_mask (); +} + +// Return TRUE if THIS does not have any meaningful information. + +inline bool +irange_bitmask::unknown_p () const +{ + return m_mask == -1; +} + +inline +irange_bitmask::irange_bitmask (const wide_int &value, const wide_int &mask) +{ + m_value = value; + m_mask = mask; + if (flag_checking) + verify_mask (); +} + +inline unsigned +irange_bitmask::get_precision () const +{ + return m_mask.get_precision (); +} + +// The following two functions are meant for backwards compatability +// with the nonzero bitmask. A cleared bit means the value must be 0. +// A set bit means we have no information for the bit. + +// Return the nonzero bits. +inline wide_int +irange_bitmask::get_nonzero_bits () const +{ + return m_value | m_mask; +} + +// Set the bitmask to the nonzero bits in BITS. +inline void +irange_bitmask::set_nonzero_bits (const wide_int &bits) +{ + m_value = wi::zero (bits.get_precision ()); + m_mask = bits; + if (flag_checking) + verify_mask (); +} + +inline bool +irange_bitmask::operator== (const irange_bitmask &src) const +{ + bool unknown1 = unknown_p (); + bool unknown2 = src.unknown_p (); + if (unknown1 || unknown2) + return unknown1 == unknown2; + return m_value == src.m_value && m_mask == src.m_mask; +} + +inline bool +irange_bitmask::union_ (const irange_bitmask &src) +{ + irange_bitmask save (*this); + m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value); + m_value = m_value & src.m_value; + if (flag_checking) + verify_mask (); + return *this != save; +} + +inline bool +irange_bitmask::intersect (const irange_bitmask &src) +{ + irange_bitmask save (*this); + // If we have two known bits that are incompatible, the resulting + // bit is undefined. It is unclear whether we should set the entire + // range to UNDEFINED, or just a subset of it. For now, set the + // entire bitmask to unknown (VARYING). + if (wi::bit_and (~(m_mask | src.m_mask), + m_value ^ src.m_value) != 0) + { + unsigned prec = m_mask.get_precision (); + m_mask = wi::minus_one (prec); + m_value = wi::zero (prec); + } + else + { + m_mask = m_mask & src.m_mask; + m_value = m_value | src.m_value; + } + if (flag_checking) + verify_mask (); + return *this != save; +} + // An integer range without any storage. class GTY((user)) irange : public vrange { friend value_range_kind get_legacy_range (const irange &, tree &, tree &); friend class irange_storage; + friend class vrange_printer; public: // In-place setters. void set (tree type, const wide_int &, const wide_int &, @@ -161,6 +295,8 @@ public: virtual bool fits_p (const vrange &r) const override; virtual void accept (const vrange_visitor &v) const override; + void update_bitmask (const irange_bitmask &); + irange_bitmask get_bitmask () const; // Nonzero masks. wide_int get_nonzero_bits () const; void set_nonzero_bits (const wide_int &bits); @@ -187,17 +323,17 @@ private: friend void gt_pch_nx (irange *, gt_pointer_operator, void *); bool varying_compatible_p () const; - bool intersect_nonzero_bits (const irange &r); - bool union_nonzero_bits (const irange &r); - wide_int get_nonzero_bits_from_range () const; - bool set_range_from_nonzero_bits (); + bool intersect_bitmask (const irange &r); + bool union_bitmask (const irange &r); + irange_bitmask get_bitmask_from_range () const; + bool set_range_from_bitmask (); bool intersect (const wide_int& lb, const wide_int& ub); unsigned char m_num_ranges; bool m_resizable; unsigned char m_max_ranges; tree m_type; - wide_int m_nonzero_mask; + irange_bitmask m_bitmask; protected: wide_int *m_base; }; @@ -741,7 +877,7 @@ irange::varying_compatible_p () const if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t)) return (l == wi::min_value (prec, sign) && u == wi::max_value (prec, sign) - && m_nonzero_mask == -1); + && m_bitmask.unknown_p ()); return true; } @@ -908,7 +1044,7 @@ irange::set_varying (tree type) { m_kind = VR_VARYING; m_num_ranges = 1; - m_nonzero_mask = wi::minus_one (TYPE_PRECISION (type)); + m_bitmask.set_unknown (TYPE_PRECISION (type)); if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) { @@ -966,7 +1102,8 @@ irange::set_nonzero (tree type) m_type = type; m_kind = VR_RANGE; m_base[0] = wi::one (prec); - m_base[1] = m_nonzero_mask = wi::minus_one (prec); + m_base[1] = wi::minus_one (prec); + m_bitmask.set_unknown (prec); m_num_ranges = 1; if (flag_checking) -- cgit v1.1 From bf3469b6474f6cff168c1e9171879d29a8296fae Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Fri, 30 Jun 2023 20:24:38 +0200 Subject: The caller to irange::intersect (wide_int, wide_int) must normalize the range. Per the function comment, the caller to intersect(wide_int, wide_int) must handle the mask. This means it must also normalize the range if anything changed. gcc/ChangeLog: * value-range.cc (irange::intersect): Leave normalization to caller. --- gcc/value-range.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 8e5607a..fbc0c7a 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1475,6 +1475,8 @@ irange::intersect (const vrange &v) return true; res |= intersect_bitmask (r); + if (res) + normalize_kind (); return res; } @@ -1574,7 +1576,7 @@ irange::intersect (const vrange &v) // Multirange intersect for a specified wide_int [lb, ub] range. // Return TRUE if intersect changed anything. // -// NOTE: It is the caller's responsibility to intersect the nonzero masks. +// NOTE: It is the caller's responsibility to intersect the mask. bool irange::intersect (const wide_int& lb, const wide_int& ub) @@ -1633,7 +1635,8 @@ irange::intersect (const wide_int& lb, const wide_int& ub) } m_kind = VR_RANGE; - normalize_kind (); + // The caller must normalize and verify the range, as the bitmask + // still needs to be handled. return true; } -- cgit v1.1 From c496d15954cdeab7f9039328f94a6f62cf893d5f Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 6 Jul 2023 11:23:04 +0200 Subject: A singleton irange has all known bits. gcc/ChangeLog: * value-range.cc (irange::get_bitmask_from_range): Return all the known bits for a singleton. (irange::set_range_from_bitmask): Set a range of a singleton when all bits are known. --- gcc/value-range.cc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/value-range.cc b/gcc/value-range.cc index fbc0c7a..011bdbd 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1766,10 +1766,19 @@ irange::invert () irange_bitmask irange::get_bitmask_from_range () const { + unsigned prec = TYPE_PRECISION (type ()); wide_int min = lower_bound (); wide_int max = upper_bound (); + + // All the bits of a singleton are known. + if (min == max) + { + wide_int mask = wi::zero (prec); + wide_int value = lower_bound (); + return irange_bitmask (value, mask); + } + wide_int xorv = min ^ max; - unsigned prec = TYPE_PRECISION (type ()); if (xorv != 0) xorv = wi::mask (prec - wi::clz (xorv), false, prec); @@ -1786,6 +1795,14 @@ irange::set_range_from_bitmask () gcc_checking_assert (!undefined_p ()); if (m_bitmask.unknown_p ()) return false; + + // If all the bits are known, this is a singleton. + if (m_bitmask.mask () == 0) + { + set (m_type, m_bitmask.value (), m_bitmask.value ()); + return true; + } + unsigned popcount = wi::popcount (m_bitmask.get_nonzero_bits ()); // If we have only one bit set in the mask, we can figure out the -- cgit v1.1 From 1f7e5a7b91862b999aab88ee0319052aaf00f0f1 Mon Sep 17 00:00:00 2001 From: "Vladimir N. Makarov" Date: Fri, 7 Jul 2023 09:53:38 -0400 Subject: LRA: Refine reload pseudo class For given testcase a reload pseudo happened to occur only in reload insns created on one constraint sub-pass. Therefore its initial class (ALL_REGS) was not refined and the reload insns were not processed on the next constraint sub-passes. This resulted into the wrong insn. PR rtl-optimization/110372 gcc/ChangeLog: * lra-assigns.cc (assign_by_spills): Add reload insns involving reload pseudos with non-refined class to be processed on the next sub-pass. * lra-constraints.cc (enough_allocatable_hard_regs_p): New func. (in_class_p): Use it. (print_curr_insn_alt): New func. (process_alt_operands): Use it. Improve debug info. (curr_insn_transform): Use print_curr_insn_alt. Refine reload pseudo class if it is not refined yet. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110372.c: New. --- gcc/lra-assigns.cc | 9 +- gcc/lra-constraints.cc | 136 +++++++++++++++++++------------ gcc/testsuite/gcc.target/i386/pr110372.c | 14 ++++ 3 files changed, 104 insertions(+), 55 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110372.c (limited to 'gcc') diff --git a/gcc/lra-assigns.cc b/gcc/lra-assigns.cc index 73fbef2..2f95121 100644 --- a/gcc/lra-assigns.cc +++ b/gcc/lra-assigns.cc @@ -1443,10 +1443,11 @@ assign_by_spills (void) pass. Indicate that it is no longer spilled. */ bitmap_clear_bit (&all_spilled_pseudos, regno); assign_hard_regno (hard_regno, regno); - if (! reload_p) - /* As non-reload pseudo assignment is changed we - should reconsider insns referring for the - pseudo. */ + if (! reload_p || regno_allocno_class_array[regno] == ALL_REGS) + /* As non-reload pseudo assignment is changed we should + reconsider insns referring for the pseudo. Do the same if a + reload pseudo did not refine its class which can happens + when the pseudo occurs only in reload insns. */ bitmap_set_bit (&changed_pseudo_bitmap, regno); } } diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 4dc2d70..123ff66 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -233,6 +233,34 @@ get_reg_class (int regno) return NO_REGS; } +/* Return true if REG_CLASS has enough allocatable hard regs to keep value of + REG_MODE. */ +static bool +enough_allocatable_hard_regs_p (enum reg_class reg_class, + enum machine_mode reg_mode) +{ + int i, j, hard_regno, class_size, nregs; + + if (hard_reg_set_subset_p (reg_class_contents[reg_class], lra_no_alloc_regs)) + return false; + class_size = ira_class_hard_regs_num[reg_class]; + for (i = 0; i < class_size; i++) + { + hard_regno = ira_class_hard_regs[reg_class][i]; + nregs = hard_regno_nregs (hard_regno, reg_mode); + if (nregs == 1) + return true; + for (j = 0; j < nregs; j++) + if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j) + || ! TEST_HARD_REG_BIT (reg_class_contents[reg_class], + hard_regno + j)) + break; + if (j >= nregs) + return true; + } + return false; +} + /* Return true if REG satisfies (or will satisfy) reg class constraint CL. Use elimination first if REG is a hard register. If REG is a reload pseudo created by this constraints pass, assume that it will @@ -252,7 +280,6 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class, enum reg_class rclass, common_class; machine_mode reg_mode; rtx src; - int class_size, hard_regno, nregs, i, j; int regno = REGNO (reg); if (new_class != NULL) @@ -291,26 +318,7 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class, common_class = ira_reg_class_subset[rclass][cl]; if (new_class != NULL) *new_class = common_class; - if (hard_reg_set_subset_p (reg_class_contents[common_class], - lra_no_alloc_regs)) - return false; - /* Check that there are enough allocatable regs. */ - class_size = ira_class_hard_regs_num[common_class]; - for (i = 0; i < class_size; i++) - { - hard_regno = ira_class_hard_regs[common_class][i]; - nregs = hard_regno_nregs (hard_regno, reg_mode); - if (nregs == 1) - return true; - for (j = 0; j < nregs; j++) - if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j) - || ! TEST_HARD_REG_BIT (reg_class_contents[common_class], - hard_regno + j)) - break; - if (j >= nregs) - return true; - } - return false; + return enough_allocatable_hard_regs_p (common_class, reg_mode); } } @@ -2046,6 +2054,23 @@ update_and_check_small_class_inputs (int nop, int nalt, return false; } +/* Print operand constraints for alternative ALT_NUMBER of the current + insn. */ +static void +print_curr_insn_alt (int alt_number) +{ + for (int i = 0; i < curr_static_id->n_operands; i++) + { + const char *p = (curr_static_id->operand_alternative + [alt_number * curr_static_id->n_operands + i].constraint); + if (*p == '\0') + continue; + fprintf (lra_dump_file, " (%d) ", i); + for (; *p != '\0' && *p != ',' && *p != '#'; p++) + fputc (*p, lra_dump_file); + } +} + /* Major function to choose the current insn alternative and what operands should be reloaded and how. If ONLY_ALTERNATIVE is not negative we should consider only this alternative. Return false if @@ -2145,6 +2170,14 @@ process_alt_operands (int only_alternative) if (!TEST_BIT (preferred, nalt)) continue; + if (lra_dump_file != NULL) + { + fprintf (lra_dump_file, " Considering alt=%d of insn %d: ", + nalt, INSN_UID (curr_insn)); + print_curr_insn_alt (nalt); + fprintf (lra_dump_file, "\n"); + } + bool matching_early_clobber[MAX_RECOG_OPERANDS]; curr_small_class_check++; overall = losers = addr_losers = 0; @@ -2671,8 +2704,7 @@ process_alt_operands (int only_alternative) { if (lra_dump_file != NULL) fprintf (lra_dump_file, - " alt=%d: Bad operand -- refuse\n", - nalt); + " Bad operand -- refuse\n"); goto fail; } @@ -2701,8 +2733,7 @@ process_alt_operands (int only_alternative) { if (lra_dump_file != NULL) fprintf (lra_dump_file, - " alt=%d: Wrong mode -- refuse\n", - nalt); + " Wrong mode -- refuse\n"); goto fail; } } @@ -2769,8 +2800,7 @@ process_alt_operands (int only_alternative) if (lra_dump_file != NULL) fprintf (lra_dump_file, - " alt=%d: Strict low subreg reload -- refuse\n", - nalt); + " Strict low subreg reload -- refuse\n"); goto fail; } losers++; @@ -2832,8 +2862,7 @@ process_alt_operands (int only_alternative) if (lra_dump_file != NULL) fprintf (lra_dump_file, - " alt=%d: No input/output reload -- refuse\n", - nalt); + " No input/output reload -- refuse\n"); goto fail; } @@ -2860,9 +2889,9 @@ process_alt_operands (int only_alternative) { if (lra_dump_file != NULL) fprintf (lra_dump_file, - " alt=%d: reload pseudo for op %d " + " reload pseudo for op %d " "cannot hold the mode value -- refuse\n", - nalt, nop); + nop); goto fail; } @@ -2989,7 +3018,7 @@ process_alt_operands (int only_alternative) /* If reload requires moving value through secondary memory, it will need one more insn at least. */ - if (this_alternative != NO_REGS + if (this_alternative != NO_REGS && REG_P (op) && (cl = get_reg_class (REGNO (op))) != NO_REGS && ((curr_static_id->operand[nop].type != OP_OUT && targetm.secondary_memory_needed (GET_MODE (op), cl, @@ -3046,8 +3075,8 @@ process_alt_operands (int only_alternative) { if (lra_dump_file != NULL) fprintf (lra_dump_file, - " alt=%d,overall=%d,losers=%d -- refuse\n", - nalt, overall, losers); + " overall=%d,losers=%d -- refuse\n", + overall, losers); goto fail; } @@ -3056,8 +3085,7 @@ process_alt_operands (int only_alternative) { if (lra_dump_file != NULL) fprintf (lra_dump_file, - " alt=%d, not enough small class regs -- refuse\n", - nalt); + " not enough small class regs -- refuse\n"); goto fail; } curr_alt[nop] = this_alternative; @@ -3238,8 +3266,8 @@ process_alt_operands (int only_alternative) overall += LRA_LOSER_COST_FACTOR - 1; } if (lra_dump_file != NULL) - fprintf (lra_dump_file, " alt=%d,overall=%d,losers=%d,rld_nregs=%d\n", - nalt, overall, losers, reload_nregs); + fprintf (lra_dump_file, " overall=%d,losers=%d,rld_nregs=%d\n", + overall, losers, reload_nregs); /* If this alternative can be made to work by reloading, and it needs less reloading than the others checked so far, record @@ -4355,18 +4383,9 @@ curr_insn_transform (bool check_only_p) { const char *p; - fprintf (lra_dump_file, " Choosing alt %d in insn %u:", + fprintf (lra_dump_file, " Choosing alt %d in insn %u:", goal_alt_number, INSN_UID (curr_insn)); - for (i = 0; i < n_operands; i++) - { - p = (curr_static_id->operand_alternative - [goal_alt_number * n_operands + i].constraint); - if (*p == '\0') - continue; - fprintf (lra_dump_file, " (%d) ", i); - for (; *p != '\0' && *p != ',' && *p != '#'; p++) - fputc (*p, lra_dump_file); - } + print_curr_insn_alt (goal_alt_number); if (INSN_CODE (curr_insn) >= 0 && (p = get_insn_name (INSN_CODE (curr_insn))) != NULL) fprintf (lra_dump_file, " {%s}", p); @@ -4564,7 +4583,22 @@ curr_insn_transform (bool check_only_p) continue; } else - continue; + { + enum reg_class rclass, common_class; + + if (REG_P (op) && goal_alt[i] != NO_REGS + && (regno = REGNO (op)) >= new_regno_start + && (rclass = get_reg_class (regno)) == ALL_REGS + && ((common_class = ira_reg_class_subset[rclass][goal_alt[i]]) + != NO_REGS) + && common_class != ALL_REGS + && enough_allocatable_hard_regs_p (common_class, + GET_MODE (op))) + /* Refine reload pseudo class from chosen alternative + constraint. */ + lra_change_class (regno, common_class, " Change to", true); + continue; + } } /* Operands that match previous ones have already been handled. */ @@ -5249,7 +5283,7 @@ lra_constraints (bool first_p) the equiv. We could update the equiv insns after transformations including an equiv insn deletion but it is not worthy as such cases are extremely - rare. */ + rare. */ || contains_deleted_insn_p (ira_reg_equiv[i].init_insns) /* If it is not a reverse equivalence, we check that a pseudo in rhs of the init insn is not dying in the diff --git a/gcc/testsuite/gcc.target/i386/pr110372.c b/gcc/testsuite/gcc.target/i386/pr110372.c new file mode 100644 index 0000000..dd7d76a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110372.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O -mno-sse2" } */ + +typedef char __attribute__((__vector_size__ (16))) U; +typedef int __attribute__((__vector_size__ (16))) V; + +V v; + +U +foo0 (U u) +{ + v *= (V) u & 4; + return u; +} -- cgit v1.1 From 6f428f1a88557f8b5df653ece92ac3e7b5baf6c6 Mon Sep 17 00:00:00 2001 From: Juergen Christ Date: Fri, 7 Jul 2023 16:52:22 +0200 Subject: IBM Z: Fix vec_init default expander Do not reinitialize vector lanes to zero since they are already initialized to zero. gcc/ChangeLog: * config/s390/s390.cc (vec_init): Fix default case gcc/testsuite/ChangeLog: * gcc.target/s390/vector/vec-init-3.c: New test. --- gcc/config/s390/s390.cc | 11 ++++++----- gcc/testsuite/gcc.target/s390/vector/vec-init-3.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/vector/vec-init-3.c (limited to 'gcc') diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index d9f10542..13970ed 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -7381,11 +7381,12 @@ s390_expand_vec_init (rtx target, rtx vals) if (!general_operand (elem, GET_MODE (elem))) elem = force_reg (inner_mode, elem); - emit_insn (gen_rtx_SET (target, - gen_rtx_UNSPEC (mode, - gen_rtvec (3, elem, - GEN_INT (i), target), - UNSPEC_VEC_SET))); + if (elem != const0_rtx) + emit_insn (gen_rtx_SET (target, + gen_rtx_UNSPEC (mode, + gen_rtvec (3, elem, + GEN_INT (i), target), + UNSPEC_VEC_SET))); } } diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-init-3.c b/gcc/testsuite/gcc.target/s390/vector/vec-init-3.c new file mode 100644 index 0000000..12008a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vec-init-3.c @@ -0,0 +1,17 @@ +/* Check that the default case of the vec_init expander does its job. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z13" } */ + +typedef __attribute__((vector_size(16))) signed int v4si; + +extern v4si G; + +v4si +n (signed int a) +{ + return G == (v4si){ a }; +} +/* { dg-final { scan-assembler-times "vzero" 1 } } */ +/* { dg-final { scan-assembler-times "vlvgf\t" 1 } } */ +/* { dg-final { scan-assembler-not "vleif\t" } } */ -- cgit v1.1 From 5966349aa7e1fcbee2558f996b2484b433a0fcf4 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 7 Jul 2023 18:22:11 +0200 Subject: Fix epilogue loop profile Fix two bugs in scale_loop_profile which crept in during my cleanups and curiously enoug did not show on the testcases we have so far. The patch also adds the missing call to cap iteration count of the vectorized loop epilogues. Vectorizer profile needs more work, but I am trying to chase out obvious bugs first so the profile quality statistics become meaningful and we can try to improve on them. Now we get: Pass dump id and name |static mismatcdynamic mismatch |in count |in count 107t cunrolli | 3 +3| 17251 +17251 116t vrp | 5 +2| 30908 +16532 118t dce | 3 -2| 17251 -13657 127t ch | 13 +10| 17251 131t dom | 39 +26| 17251 133t isolate-paths | 47 +8| 17251 134t reassoc | 49 +2| 17251 136t forwprop | 53 +4| 202501 +185250 159t cddce | 61 +8| 216211 +13710 161t ldist | 62 +1| 216211 172t ifcvt | 66 +4| 373711 +157500 173t vect | 143 +77| 9801947 +9428236 176t cunroll | 149 +6| 12006408 +2204461 183t loopdone | 146 -3| 11944469 -61939 195t fre | 142 -4| 11944469 197t dom | 141 -1| 13038435 +1093966 199t threadfull | 143 +2| 13246410 +207975 200t vrp | 145 +2| 13444579 +198169 204t dce | 143 -2| 13371315 -73264 206t sink | 141 -2| 13371315 211t cddce | 147 +6| 13372755 +1440 255t optimized | 145 -2| 13372755 256r expand | 141 -4| 13371197 -1558 258r into_cfglayout | 139 -2| 13371197 275r loop2_unroll | 143 +4| 16792056 +3420859 291r ce2 | 141 -2| 16811462 312r pro_and_epilogue | 161 +20| 16873400 +61938 315r jump2 | 167 +6| 20910158 +4036758 323r bbro | 160 -7| 16559844 -4350314 Vect still introduces 77 profile mismatches (same as without this patch) however subsequent cunroll works much better with 6 new mismatches compared to 78. Overall it reduces 229 mismatches to 160. Also overall runtime estimate is now reduced by 6.9%. Previously the overall runtime estimate grew by 11% which was result of the fat that the epilogue profile was pretty much the same as profile of the original loop. Bootstrapped/regtested x86_64-linux, comitted. gcc/ChangeLog: * cfgloopmanip.cc (scale_loop_profile): Fix computation of count_in and scaling blocks after exit. * tree-vect-loop-manip.cc (vect_do_peeling): Scale loop profile of the epilogue if bound is known. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/vect-profile-upate.c: New test. --- gcc/cfgloopmanip.cc | 15 ++++++++++----- gcc/testsuite/gcc.dg/tree-ssa/vect-profile-upate.c | 9 +++++++++ gcc/tree-vect-loop-manip.cc | 2 ++ 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vect-profile-upate.c (limited to 'gcc') diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 524b979..f56a9b8 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -548,18 +548,23 @@ scale_loop_profile (class loop *loop, profile_probability p, profile_count count_in = profile_count::zero (); edge e; edge_iterator ei; + bool found_latch = false; FOR_EACH_EDGE (e, ei, loop->header->preds) - count_in += e->count (); + if (e->src != loop->latch) + count_in += e->count (); + else + found_latch = true; + gcc_checking_assert (found_latch); /* Now scale the loop body so header count is count_in * (iteration_bound + 1) */ profile_probability scale_prob - = (count_in *= iteration_bound).probability_in (loop->header->count); + = (count_in * (iteration_bound + 1)).probability_in (loop->header->count); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, ";; Scaling loop %i with scale ", loop->num); - p.dump (dump_file); + scale_prob.dump (dump_file); fprintf (dump_file, " to reach upper bound %i\n", (int)iteration_bound); } @@ -593,7 +598,6 @@ scale_loop_profile (class loop *loop, profile_probability p, bool found = false; FOR_EACH_EDGE (e, ei, exit_edge->src->succs) if (!(e->flags & EDGE_FAKE) - && !(e->probability == profile_probability::never ()) && !loop_exit_edge_p (loop, e)) { if (found) @@ -617,7 +621,8 @@ scale_loop_profile (class loop *loop, profile_probability p, for (unsigned int i = 0; i < loop->num_nodes; i++) if (body[i] != exit_edge->src && dominated_by_p (CDI_DOMINATORS, body[i], exit_edge->src)) - body[i]->count.apply_scale (new_count, old_count); + body[i]->count = body[i]->count.apply_scale (new_count, + old_count); free (body); } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vect-profile-upate.c b/gcc/testsuite/gcc.dg/tree-ssa/vect-profile-upate.c new file mode 100644 index 0000000..72cc428 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vect-profile-upate.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks" } */ +int a[99]; +void test() +{ + for (int i = 0; i < 99; i++) + a[i]++; +} +/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 2361cb3..30baac6 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -3389,6 +3389,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, gcc_assert (bound != 0); /* -1 to convert loop iterations to latch iterations. */ record_niter_bound (epilog, bound - 1, false, true); + scale_loop_profile (epilog, profile_probability::always (), + bound - 1); } delete_update_ssa (); -- cgit v1.1 From 768f00e3e84123e8d0f1bf28a3b2e0b7995402f1 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 7 Jul 2023 19:16:59 +0200 Subject: Fix some profile consistency testcases Information about profile mismatches is printed only with -details-blocks for some time. I think it should be printed even with default to make it easier to spot when someone introduces new transform that breaks the profile, but I will send separate RFC for that. This patch enables details in all testcases that greps for Invalid sum. There are 4 testcases which fails: gcc.dg/tree-ssa/loop-ch-profile-1.c here the problem is that loop header dulication introduces loop invariant conditoinal that is later updated by tree-ssa-dom but dom does not take care of updating profile. Since loop-ch knows when it duplicates loop invariant, we may be able to get this right. The test is still useful since it tests that right after ch profile is consistent. gcc.dg/tree-prof/update-cunroll-2.c This is about profile updating code in duplicate_loop_body_to_header_edge being wrong when optimized out exit is not last in the loop. In that case the probability of later exits needs to be accounted in. I will think about making this better - in general this does not seem to have easy solution, but for special case of chained tests we can definitely account for the later exits. gcc.dg/tree-ssa/update-unroll-1.c This fails after aprefetch invoked unrolling. I did not look into details yet. gcc.dg/tree-prof/update-unroll-2.c This one seems similar as previous I decided to xfail these tests and deal with them incrementally and filled in PR110590. gcc/testsuite/ChangeLog: * g++.dg/tree-prof/indir-call-prof.C: Add block-details to dump flags. * gcc.dg/pr43864-2.c: Likewise. * gcc.dg/pr43864-3.c: Likewise. * gcc.dg/pr43864-4.c: Likewise. * gcc.dg/pr43864.c: Likewise. * gcc.dg/tree-prof/cold_partition_label.c: Likewise. * gcc.dg/tree-prof/indir-call-prof.c: Likewise. * gcc.dg/tree-prof/update-cunroll-2.c: Likewise. * gcc.dg/tree-prof/update-tailcall.c: Likewise. * gcc.dg/tree-prof/val-prof-1.c: Likewise. * gcc.dg/tree-prof/val-prof-2.c: Likewise. * gcc.dg/tree-prof/val-prof-3.c: Likewise. * gcc.dg/tree-prof/val-prof-4.c: Likewise. * gcc.dg/tree-prof/val-prof-5.c: Likewise. * gcc.dg/tree-ssa/fnsplit-1.c: Likewise. * gcc.dg/tree-ssa/loop-ch-profile-2.c: Likewise. * gcc.dg/tree-ssa/update-threading.c: Likewise. * gcc.dg/tree-ssa/update-unswitch-1.c: Likewise. * gcc.dg/unroll-7.c: Likewise. * gcc.dg/unroll-8.c: Likewise. * gfortran.dg/pr25623-2.f90: Likewise. * gfortran.dg/pr25623.f90: Likewise. * gcc.dg/tree-ssa/loop-ch-profile-1.c: Likewise; xfail. * gcc.dg/tree-ssa/update-cunroll.c: Likewise; xfail. * gcc.dg/tree-ssa/update-unroll-1.c: Likewise; xfail. --- gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C | 2 +- gcc/testsuite/gcc.dg/pr43864-2.c | 2 +- gcc/testsuite/gcc.dg/pr43864-3.c | 2 +- gcc/testsuite/gcc.dg/pr43864-4.c | 2 +- gcc/testsuite/gcc.dg/pr43864.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c | 4 ++-- gcc/testsuite/gcc.dg/tree-prof/update-tailcall.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c | 6 ++++-- gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c | 6 ++++-- gcc/testsuite/gcc.dg/tree-ssa/update-threading.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/update-unroll-1.c | 4 ++-- gcc/testsuite/gcc.dg/tree-ssa/update-unswitch-1.c | 2 +- gcc/testsuite/gcc.dg/unroll-7.c | 2 +- gcc/testsuite/gcc.dg/unroll-8.c | 2 +- gcc/testsuite/gfortran.dg/pr25623-2.f90 | 2 +- gcc/testsuite/gfortran.dg/pr25623.f90 | 2 +- 25 files changed, 33 insertions(+), 29 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C b/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C index b454171..1f74046 100644 --- a/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C +++ b/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized -fdump-ipa-afdo-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-blocks-details -fdump-ipa-profile-optimized -fdump-ipa-afdo-optimized" } */ struct A { A () {} diff --git a/gcc/testsuite/gcc.dg/pr43864-2.c b/gcc/testsuite/gcc.dg/pr43864-2.c index 6393144..102295a 100644 --- a/gcc/testsuite/gcc.dg/pr43864-2.c +++ b/gcc/testsuite/gcc.dg/pr43864-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */ +/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre-details-blocks" } */ int f (int c, int b, int d) diff --git a/gcc/testsuite/gcc.dg/pr43864-3.c b/gcc/testsuite/gcc.dg/pr43864-3.c index 24b59a1..f70b876 100644 --- a/gcc/testsuite/gcc.dg/pr43864-3.c +++ b/gcc/testsuite/gcc.dg/pr43864-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */ +/* { dg-options "-O2 -fdump-tree-pre-blocks-details" } */ /* Commutative case. */ diff --git a/gcc/testsuite/gcc.dg/pr43864-4.c b/gcc/testsuite/gcc.dg/pr43864-4.c index 8a25b0f..3de71fc 100644 --- a/gcc/testsuite/gcc.dg/pr43864-4.c +++ b/gcc/testsuite/gcc.dg/pr43864-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */ +/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre-details-blocks" } */ /* Different stmt order. */ diff --git a/gcc/testsuite/gcc.dg/pr43864.c b/gcc/testsuite/gcc.dg/pr43864.c index ed69a73..7bd1ba6 100644 --- a/gcc/testsuite/gcc.dg/pr43864.c +++ b/gcc/testsuite/gcc.dg/pr43864.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */ +/* { dg-options "-O2 -fdump-tree-pre-details-blocks" } */ extern void foo (char*, int); extern void mysprintf (char *, char *); diff --git a/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c b/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c index b85e6c1..15e1a97 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c +++ b/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c @@ -1,7 +1,7 @@ /* Test case to check if function foo gets split and the cold function gets a label. */ /* { dg-require-effective-target freorder } */ -/* { dg-options "-O2 -freorder-blocks-and-partition -save-temps -fdump-tree-optimized" } */ +/* { dg-options "-O2 -freorder-blocks-and-partition -save-temps -fdump-tree-optimized-details-blocks" } */ #ifdef FOR_AUTOFDO_TESTING #define MAXITER 1000000 diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c index 7020452..0a45872 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c +++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized -fdump-ipa-afdo-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-ipa-profile-optimized -fdump-ipa-afdo-optimized" } */ static int a1 (void) { diff --git a/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c b/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c index c286816..8ef3ab2 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c +++ b/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c @@ -1,5 +1,5 @@ -/* { dg-options "-O2 -fdump-tree-optimized-blocks" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks" } */ int a[8]; __attribute__ ((noinline)) int t() @@ -18,4 +18,4 @@ main () t (); return 0; } -/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized" {xfail *-*-*} } } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/update-tailcall.c b/gcc/testsuite/gcc.dg/tree-prof/update-tailcall.c index 57e781c..bfee314 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/update-tailcall.c +++ b/gcc/testsuite/gcc.dg/tree-prof/update-tailcall.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-tailc -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-tailc-details-blocks -fdump-tree-optimized-details-blocks" } */ __attribute__ ((noinline)) int factorial(int x) { diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c index 8495c4c..d2fe21c 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-ipa-profile-optimized" } */ int a[1000]; int b = 256; int c = 257; diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c index 4f758af..3c4bc8d 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-ipa-profile-optimized" } */ unsigned int a[1000]; unsigned int b = 256; unsigned int c = 1024; diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c index 5897d75..74e1a3f 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-ipa-profile-optimized" } */ unsigned int a[1000]; unsigned int b = 257; unsigned int c = 1023; diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c index b13601e..602e8e6 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-ipa-profile-optimized" } */ unsigned int a[1000]; unsigned int b = 999; unsigned int c = 1002; diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c index 982bcb1..087310f 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-ipa-profile-optimized" } */ int a[1000]; int b=997; int diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c index 1b9696d..470f5ee 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-fnsplit" } */ +/* { dg-options "-O2 -fdump-tree-fnsplit-blocks-details" } */ #include int a[1000]; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c index e8bab62..1634086 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-ch2-blocks-details -fdump-tree-optimized" } */ +/* { dg-options "-O1 -fdump-tree-ch2-blocks-details -fdump-tree-optimized-blocks-details" } */ void foo (); void test(int v, int q) { @@ -7,4 +7,6 @@ void test(int v, int q) foo (); } /* { dg-final { scan-tree-dump-not "Invalid sum" "ch2"} } */ -/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* dom2 optimizes out the redundant test for loop invariant v/q + which leads to inconsistent profile. */ +/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized" { xfail *-*-* }} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c index 99d22ba..09270be 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-ch2-blocks-details -fdump-tree-optimized" } */ +/* { dg-options "-O1 -fdump-tree-ch2-blocks-details -fdump-tree-optimized-blocks-details" } */ void foo (); void test() { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c b/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c index 3b47ede..5820423 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-details-blocks" } */ int a[8]; int t() { @@ -9,4 +9,6 @@ int t() break; return i; } -/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized"} } */ +/* Currently duplicate_loop_body_to_header_edge gets wrong computation of prob_pass_wont_exit + which assumes that the exit condition is last in the loop. */ +/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized" { xfail *-*-*}} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c b/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c index 9c87ba0..1435e9b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized-blocks-details" } */ typedef struct { unsigned short a; } A; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/update-unroll-1.c b/gcc/testsuite/gcc.dg/tree-ssa/update-unroll-1.c index 1028c8b..138448b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/update-unroll-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/update-unroll-1.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ -/* { dg-options "-O1 -fprefetch-loop-arrays -march=amdfam10 -fdump-tree-aprefetch-blocks" } */ +/* { dg-options "-O1 -fprefetch-loop-arrays -march=amdfam10 -fdump-tree-aprefetch-blocks-details" } */ int a[10000]; @@ -16,5 +16,5 @@ int foo(unsigned n) /* We used to make the probability that the body of the loop (unrolled to enable prefetching) is entered 0, which is not correct. */ -/* { dg-final { scan-tree-dump-not "Invalid sum" "aprefetch"} } */ +/* { dg-final { scan-tree-dump-not "Invalid sum" "aprefetch" { xfail *-*-* }} } */ /* { dg-final { scan-tree-dump-not "SUCC: 7 .100.0%" "aprefetch"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/update-unswitch-1.c b/gcc/testsuite/gcc.dg/tree-ssa/update-unswitch-1.c index a48710d..65154d8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/update-unswitch-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/update-unswitch-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -funswitch-loops -fdump-tree-unswitch-blocks" } */ +/* { dg-options "-O1 -funswitch-loops -fdump-tree-unswitch-blocks-details" } */ int bla(int p) { diff --git a/gcc/testsuite/gcc.dg/unroll-7.c b/gcc/testsuite/gcc.dg/unroll-7.c index 695af57..17c5e53 100644 --- a/gcc/testsuite/gcc.dg/unroll-7.c +++ b/gcc/testsuite/gcc.dg/unroll-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-vectorize -fdump-rtl-loop2_unroll-details -funroll-loops" } */ +/* { dg-options "-O2 -fno-tree-vectorize -fdump-rtl-loop2_unroll-blocks-details -funroll-loops" } */ /* { dg-require-effective-target int32plus } */ extern int *a; diff --git a/gcc/testsuite/gcc.dg/unroll-8.c b/gcc/testsuite/gcc.dg/unroll-8.c index c4f6ac9..4388f47 100644 --- a/gcc/testsuite/gcc.dg/unroll-8.c +++ b/gcc/testsuite/gcc.dg/unroll-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-rtl-loop2_unroll -funroll-loops" } */ +/* { dg-options "-O2 -fdump-rtl-loop2_unroll-details-blocks -funroll-loops" } */ /* { dg-additional-options "-fno-tree-vectorize" { target amdgcn-*-* } } */ struct a {int a[7];}; diff --git a/gcc/testsuite/gfortran.dg/pr25623-2.f90 b/gcc/testsuite/gfortran.dg/pr25623-2.f90 index 57679e0..c7a4fe0 100644 --- a/gcc/testsuite/gfortran.dg/pr25623-2.f90 +++ b/gcc/testsuite/gfortran.dg/pr25623-2.f90 @@ -1,5 +1,5 @@ ! { dg-do compile } -! { dg-options "-fdump-tree-optimized-blocks -O3" } +! { dg-options "-fdump-tree-optimized-blocks-details -O3" } SUBROUTINE S42(a,b,c,N) IMPLICIT NONE diff --git a/gcc/testsuite/gfortran.dg/pr25623.f90 b/gcc/testsuite/gfortran.dg/pr25623.f90 index 30905e4..7302f37 100644 --- a/gcc/testsuite/gfortran.dg/pr25623.f90 +++ b/gcc/testsuite/gfortran.dg/pr25623.f90 @@ -1,5 +1,5 @@ ! { dg-do compile } -! { dg-options "-fdump-tree-optimized-blocks -O2" } +! { dg-options "-fdump-tree-optimized-blocks-details -O2" } SUBROUTINE S42(a,b,c,N) IMPLICIT NONE -- cgit v1.1 From bb3b9c1c3ba8228387ea8a94f3638190d1696324 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 7 Jul 2023 19:21:02 +0200 Subject: Simplify force_edge_cold. gcc/ChangeLog: * predict.cc (force_edge_cold): Use set_edge_probability_and_rescale_others; improve dumps. --- gcc/predict.cc | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/predict.cc b/gcc/predict.cc index d65c26f..1aa4c25 100644 --- a/gcc/predict.cc +++ b/gcc/predict.cc @@ -4421,21 +4421,16 @@ force_edge_cold (edge e, bool impossible) there. */ else if (prob_sum > profile_probability::never ()) { - if (!(e->probability < goal)) - e->probability = goal; - - profile_probability prob_comp = prob_sum / e->probability.invert (); - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Making edge %i->%i %s by redistributing " - "probability to other edges.\n", - e->src->index, e->dest->index, - impossible ? "impossible" : "cold"); - FOR_EACH_EDGE (e2, ei, e->src->succs) - if (e2 != e) - { - e2->probability /= prob_comp; - } + { + fprintf (dump_file, "Making edge %i->%i %s by redistributing " + "probability to other edges. Original probability: ", + e->src->index, e->dest->index, + impossible ? "impossible" : "cold"); + e->probability.dump (dump_file); + fprintf (dump_file, "\n"); + } + set_edge_probability_and_rescale_others (e, goal); if (current_ir_type () != IR_GIMPLE && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)) update_br_prob_note (e->src); -- cgit v1.1 From f934c5753849f7c48c6a3abfcd73b8f6008e8371 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Fri, 7 Jul 2023 21:06:07 +0200 Subject: d: Fix PR 108842: Cannot use enum array with -fno-druntime Restrict the generating of CONST_DECLs for D manifest constants to just scalars without pointers. It shouldn't happen that a reference to a manifest constant has not been expanded within a function body during codegen, but it has been found to occur in older versions of the D front-end (PR98277), so if the decl of a non-scalar constant is requested, just return its initializer as an expression. PR d/108842 gcc/d/ChangeLog: * decl.cc (DeclVisitor::visit (VarDeclaration *)): Only emit scalar manifest constants. (get_symbol_decl): Don't generate CONST_DECL for non-scalar manifest constants. * imports.cc (ImportVisitor::visit (VarDeclaration *)): New method. gcc/testsuite/ChangeLog: * gdc.dg/pr98277.d: Add more tests. * gdc.dg/pr108842.d: New test. --- gcc/d/decl.cc | 36 +++++++++++++++++++++--------------- gcc/d/imports.cc | 9 +++++++++ gcc/testsuite/gdc.dg/pr108842.d | 4 ++++ gcc/testsuite/gdc.dg/pr98277.d | 11 +++++++++++ 4 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gdc.dg/pr108842.d (limited to 'gcc') diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 3f98085..0375ede 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -782,7 +782,7 @@ public: { /* Do not store variables we cannot take the address of, but keep the values for purposes of debugging. */ - if (!d->type->isscalar ()) + if (d->type->isscalar () && !d->type->hasPointers ()) { tree decl = get_symbol_decl (d); d_pushdecl (decl); @@ -1212,6 +1212,20 @@ get_symbol_decl (Declaration *decl) return decl->csym; } + if (VarDeclaration *vd = decl->isVarDeclaration ()) + { + /* CONST_DECL was initially intended for enumerals and may be used for + scalars in general, but not for aggregates. Here a non-constant + value is generated anyway so as its value can be used. */ + if (!vd->canTakeAddressOf () && !vd->type->isscalar ()) + { + gcc_assert (vd->_init && !vd->_init->isVoidInitializer ()); + Expression *ie = initializerToExpression (vd->_init); + decl->csym = build_expr (ie, false); + return decl->csym; + } + } + /* Build the tree for the symbol. */ FuncDeclaration *fd = decl->isFuncDeclaration (); if (fd) @@ -1259,23 +1273,15 @@ get_symbol_decl (Declaration *decl) if (vd->storage_class & STCextern) DECL_EXTERNAL (decl->csym) = 1; - /* CONST_DECL was initially intended for enumerals and may be used for - scalars in general, but not for aggregates. Here a non-constant - value is generated anyway so as the CONST_DECL only serves as a - placeholder for the value, however the DECL itself should never be - referenced in any generated code, or passed to the back-end. */ - if (vd->storage_class & STCmanifest) + if (!vd->canTakeAddressOf ()) { /* Cannot make an expression out of a void initializer. */ - if (vd->_init && !vd->_init->isVoidInitializer ()) - { - Expression *ie = initializerToExpression (vd->_init); + gcc_assert (vd->_init && !vd->_init->isVoidInitializer ()); + /* Non-scalar manifest constants have already been dealt with. */ + gcc_assert (vd->type->isscalar ()); - if (!vd->type->isscalar ()) - DECL_INITIAL (decl->csym) = build_expr (ie, false); - else - DECL_INITIAL (decl->csym) = build_expr (ie, true); - } + Expression *ie = initializerToExpression (vd->_init); + DECL_INITIAL (decl->csym) = build_expr (ie, true); } /* [type-qualifiers/const-and-immutable] diff --git a/gcc/d/imports.cc b/gcc/d/imports.cc index 2efef4e..3172b79 100644 --- a/gcc/d/imports.cc +++ b/gcc/d/imports.cc @@ -127,6 +127,15 @@ public: this->result_ = this->make_import (TYPE_STUB_DECL (type)); } + void visit (VarDeclaration *d) final override + { + /* Not all kinds of manifest constants create a CONST_DECL. */ + if (!d->canTakeAddressOf () && !d->type->isscalar ()) + return; + + visit ((Declaration *) d); + } + /* For now, ignore importing other kinds of dsymbols. */ void visit (ScopeDsymbol *) final override { diff --git a/gcc/testsuite/gdc.dg/pr108842.d b/gcc/testsuite/gdc.dg/pr108842.d new file mode 100644 index 0000000..5aae9e5 --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr108842.d @@ -0,0 +1,4 @@ +// { dg-do compile } +// { dg-options "-fno-rtti" } +module object; +enum int[] x = [0, 1, 2]; diff --git a/gcc/testsuite/gdc.dg/pr98277.d b/gcc/testsuite/gdc.dg/pr98277.d index 0dff142..c88c735 100644 --- a/gcc/testsuite/gdc.dg/pr98277.d +++ b/gcc/testsuite/gdc.dg/pr98277.d @@ -11,3 +11,14 @@ ref int getSide(Side side, return ref int left, return ref int right) { return side == Side.left ? left : right; } + +enum SideA : int[] +{ + left = [0], + right = [1], +} + +int getSideA(SideA side, ref int left, ref int right) +{ + return side == SideA.left ? left : right; +} -- cgit v1.1 From bdf2737cda53a83332db1a1a021653447b05a7e7 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Fri, 7 Jul 2023 20:39:58 +0100 Subject: i386: Improve __int128 argument passing (in ix86_expand_move). Passing 128-bit integer (TImode) parameters on x86_64 can sometimes result in surprising code. Consider the example below (from PR 43644): unsigned __int128 foo(unsigned __int128 x, unsigned long long y) { return x+y; } which currently results in 6 consecutive movq instructions: foo: movq %rsi, %rax movq %rdi, %rsi movq %rdx, %rcx movq %rax, %rdi movq %rsi, %rax movq %rdi, %rdx addq %rcx, %rax adcq $0, %rdx ret The underlying issue is that during RTL expansion, we generate the following initial RTL for the x argument: (insn 4 3 5 2 (set (reg:TI 85) (subreg:TI (reg:DI 86) 0)) "pr43644-2.c":5:1 -1 (nil)) (insn 5 4 6 2 (set (subreg:DI (reg:TI 85) 8) (reg:DI 87)) "pr43644-2.c":5:1 -1 (nil)) (insn 6 5 7 2 (set (reg/v:TI 84 [ x ]) (reg:TI 85)) "pr43644-2.c":5:1 -1 (nil)) which by combine/reload becomes (insn 25 3 22 2 (set (reg/v:TI 84 [ x ]) (const_int 0 [0])) "pr43644-2.c":5:1 -1 (nil)) (insn 22 25 23 2 (set (subreg:DI (reg/v:TI 84 [ x ]) 0) (reg:DI 93)) "pr43644-2.c":5:1 90 {*movdi_internal} (expr_list:REG_DEAD (reg:DI 93) (nil))) (insn 23 22 28 2 (set (subreg:DI (reg/v:TI 84 [ x ]) 8) (reg:DI 94)) "pr43644-2.c":5:1 90 {*movdi_internal} (expr_list:REG_DEAD (reg:DI 94) (nil))) where the heavy use of SUBREG SET_DESTs creates challenges for both combine and register allocation. The improvement proposed here is to avoid these problematic SUBREGs by adding (two) special cases to ix86_expand_move. For insn 4, which sets a TImode destination from a paradoxical SUBREG, to assign the lowpart, we can use an explicit zero extension (zero_extendditi2 was added in July 2022), and for insn 5, which sets the highpart of a TImode register we can use the *insvti_highpart_1 instruction (that was added in May 2023, after being approved for stage1 in January). This allows combine to work its magic, merging these insns into a *concatditi3 and from there into other optimized forms. So for the test case above, we now generate only a single movq: foo: movq %rdx, %rax xorl %edx, %edx addq %rdi, %rax adcq %rsi, %rdx ret But there is a little bad news. This patch causes two (minor) missed optimization regressions on x86_64; gcc.target/i386/pr82580.c and gcc.target/i386/pr91681-1.c. As shown in the test case above, we're no longer generating adcq $0, but instead using xorl. For the other FAIL, register allocation now has more freedom and is (arbitrarily) choosing a register assignment that doesn't match what the test is expecting. These issues are easier to explain and fix once this patch is in the tree. The good news is that this approach fixes a number of long standing issues, that need to checked in bugzilla, including PR target/110533 which was just opened/reported earlier this week. 2023-07-07 Roger Sayle gcc/ChangeLog PR target/43644 PR target/110533 * config/i386/i386-expand.cc (ix86_expand_move): Convert SETs of TImode destinations from paradoxical SUBREGs (setting the lowpart) into explicit zero extensions. Use *insvti_highpart_1 instruction to set the highpart of a TImode destination. gcc/testsuite/ChangeLog PR target/43644 PR target/110533 * gcc.target/i386/pr110533.c: New test case. * gcc.target/i386/pr43644-2.c: Likewise. --- gcc/config/i386/i386-expand.cc | 28 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr110533.c | 9 +++++++++ gcc/testsuite/gcc.target/i386/pr43644-2.c | 9 +++++++++ 3 files changed, 46 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr110533.c create mode 100644 gcc/testsuite/gcc.target/i386/pr43644-2.c (limited to 'gcc') diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 567248d..92ffa4b 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -429,6 +429,16 @@ ix86_expand_move (machine_mode mode, rtx operands[]) default: break; + + case SUBREG: + /* Transform TImode paradoxical SUBREG into zero_extendditi2. */ + if (TARGET_64BIT + && mode == TImode + && SUBREG_P (op1) + && GET_MODE (SUBREG_REG (op1)) == DImode + && SUBREG_BYTE (op1) == 0) + op1 = gen_rtx_ZERO_EXTEND (TImode, SUBREG_REG (op1)); + break; } if ((flag_pic || MACHOPIC_INDIRECT) @@ -532,6 +542,24 @@ ix86_expand_move (machine_mode mode, rtx operands[]) } } + /* Use *insvti_highpart_1 to set highpart of TImode register. */ + if (TARGET_64BIT + && mode == DImode + && SUBREG_P (op0) + && SUBREG_BYTE (op0) == 8 + && GET_MODE (SUBREG_REG (op0)) == TImode + && REG_P (SUBREG_REG (op0)) + && REG_P (op1)) + { + wide_int mask = wi::mask (64, false, 128); + rtx tmp = immed_wide_int_const (mask, TImode); + op0 = SUBREG_REG (op0); + tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp); + op1 = gen_rtx_ZERO_EXTEND (TImode, op1); + op1 = gen_rtx_ASHIFT (TImode, op1, GEN_INT (64)); + op1 = gen_rtx_IOR (TImode, tmp, op1); + } + emit_insn (gen_rtx_SET (op0, op1)); } diff --git a/gcc/testsuite/gcc.target/i386/pr110533.c b/gcc/testsuite/gcc.target/i386/pr110533.c new file mode 100644 index 0000000..513bcd4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110533.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O0" } */ + +__attribute__((naked)) +void fn(__int128 a) { + asm("ret"); +} + +/* { dg-final { scan-assembler-not "mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr43644-2.c b/gcc/testsuite/gcc.target/i386/pr43644-2.c new file mode 100644 index 0000000..d470b0a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr43644-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2" } */ + +unsigned __int128 foo(unsigned __int128 x, unsigned long long y) +{ + return x+y; +} + +/* { dg-final { scan-assembler-times "movq" 1 } } */ -- cgit v1.1 From 275f7bc35fb864ef7867ff7e12bf5b27277ecc36 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Thu, 29 Jun 2023 19:38:41 -0700 Subject: Collect both user and kernel events for autofdo tests and autoprofiledbootstrap When we collect just user events for autofdo with lbr we get some events where branch sources are kernel addresses and branch targets are user addresses. Without kernel MMAP events create_gcov can't make sense of kernel addresses. Currently create_gcov fails if it can't map at least 95% of events. We sometimes get below this threshold with just user events. The change is to collect both user events and kernel events. Tested on x86_64-pc-linux-gnu. ChangeLog: * Makefile.in: Collect both kernel and user events for autofdo * Makefile.tpl: Collect both kernel and user events for autofdo gcc/testsuite/ChangeLog: * lib/target-supports.exp: Collect both kernel and user events for autofdo --- gcc/testsuite/lib/target-supports.exp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 4d04df2..b16853d 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -704,7 +704,7 @@ proc check_effective_target_keeps_null_pointer_checks { } { # this allows parallelism of 16 and higher of parallel gcc-auto-profile proc profopt-perf-wrapper { } { global srcdir - return "$srcdir/../config/i386/gcc-auto-profile -m8 " + return "$srcdir/../config/i386/gcc-auto-profile --all -m8 " } # Return true if profiling is supported on the target. -- cgit v1.1 From ba8d3e566787b40e3a91fd259da19c7b59aa4c0f Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 7 Jul 2023 23:04:15 +0200 Subject: Fix fallout from re-enabling profile consistency checks. gcc/testsuite/ChangeLog: * gcc.dg/pr43864-2.c: Avoid matching pre dump with details-blocks. * gcc.dg/pr43864-3.c: Likewise. * gcc.dg/pr43864-4.c: Likewise. * gcc.dg/pr43864.c: Likewise. * gcc.dg/unroll-7.c: xfail. --- gcc/testsuite/gcc.dg/pr43864-2.c | 4 ++-- gcc/testsuite/gcc.dg/pr43864-3.c | 4 ++-- gcc/testsuite/gcc.dg/pr43864-4.c | 4 ++-- gcc/testsuite/gcc.dg/pr43864.c | 4 ++-- gcc/testsuite/gcc.dg/unroll-7.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/pr43864-2.c b/gcc/testsuite/gcc.dg/pr43864-2.c index 102295a..ea247ac 100644 --- a/gcc/testsuite/gcc.dg/pr43864-2.c +++ b/gcc/testsuite/gcc.dg/pr43864-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre-details-blocks" } */ +/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre -fdump-tree-optimized-blocks-details" } */ int f (int c, int b, int d) @@ -19,4 +19,4 @@ f (int c, int b, int d) /* { dg-final { scan-tree-dump-times "if " 0 "pre"} } */ /* { dg-final { scan-tree-dump-times "(?n)_.*\\+.*_" 1 "pre"} } */ -/* { dg-final { scan-tree-dump-not "Invalid sum" "pre"} } */ +/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/pr43864-3.c b/gcc/testsuite/gcc.dg/pr43864-3.c index f70b876..a771d4b 100644 --- a/gcc/testsuite/gcc.dg/pr43864-3.c +++ b/gcc/testsuite/gcc.dg/pr43864-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-blocks-details" } */ +/* { dg-options "-O2 -fdump-tree-pre -fdump-tree-optimized-blocks-details" } */ /* Commutative case. */ @@ -20,4 +20,4 @@ int f(int c, int b, int d) /* { dg-final { scan-tree-dump-times "if " 0 "pre"} } */ /* { dg-final { scan-tree-dump-times "(?n)_.*\\+.*_" 1 "pre"} } */ -/* { dg-final { scan-tree-dump-not "Invalid sum" "pre"} } */ +/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/pr43864-4.c b/gcc/testsuite/gcc.dg/pr43864-4.c index 3de71fc..535d1cd 100644 --- a/gcc/testsuite/gcc.dg/pr43864-4.c +++ b/gcc/testsuite/gcc.dg/pr43864-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre-details-blocks" } */ +/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre -fdump-tree-optimized-details-blocks" } */ /* Different stmt order. */ @@ -25,4 +25,4 @@ int f(int c, int b, int d) /* During PRE elimination we should simplify this to return b * 2. */ /* { dg-final { scan-tree-dump-times "if " 0 "pre" } } */ /* { dg-final { scan-tree-dump "_\[0-9\]+ = b_\[0-9\]+\\(D\\) \\* 2;\[\\r\\n\]\[^\\r\\n\]*return _\[0-9\]+;" "pre" } } */ -/* { dg-final { scan-tree-dump-not "Invalid sum" "pre"} } */ +/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/pr43864.c b/gcc/testsuite/gcc.dg/pr43864.c index 7bd1ba6..12849f5 100644 --- a/gcc/testsuite/gcc.dg/pr43864.c +++ b/gcc/testsuite/gcc.dg/pr43864.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-details-blocks" } */ +/* { dg-options "-O2 -fdump-tree-pre -fdump-tree-optimized-blocks-details" } */ extern void foo (char*, int); extern void mysprintf (char *, char *); @@ -32,4 +32,4 @@ hprofStartupp (char *outputFileName, char *ctx) } /* { dg-final { scan-tree-dump-times "myfree \\(" 1 "pre"} } */ -/* { dg-final { scan-tree-dump-not "Invalid sum" "pre"} } */ +/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/unroll-7.c b/gcc/testsuite/gcc.dg/unroll-7.c index 17c5e53..650448d 100644 --- a/gcc/testsuite/gcc.dg/unroll-7.c +++ b/gcc/testsuite/gcc.dg/unroll-7.c @@ -15,4 +15,4 @@ int t(void) /* { dg-final { scan-rtl-dump "upper bound: 999999" "loop2_unroll" } } */ /* { dg-final { scan-rtl-dump "realistic bound: 999999" "loop2_unroll" } } */ /* { dg-final { scan-rtl-dump "considering unrolling loop with constant number of iterations" "loop2_unroll" } } */ -/* { dg-final { scan-rtl-dump-not "Invalid sum" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-not "Invalid sum" "loop2_unroll" {xfail *-*-* } } } */ -- cgit v1.1 From 3cce8d98f270f48f480046d439c9d4635641c24e Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 7 Jul 2023 23:06:33 +0200 Subject: Dump profile_count along with relative frequency gcc/ChangeLog: * profile-count.cc (profile_count::dump): Add FUN parameter; print relative frequency. (profile_count::debug): Update. * profile-count.h (profile_count::dump): Update prototype. --- gcc/profile-count.cc | 14 ++++++++++---- gcc/profile-count.h | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/profile-count.cc b/gcc/profile-count.cc index 1658504..6bf9700 100644 --- a/gcc/profile-count.cc +++ b/gcc/profile-count.cc @@ -87,10 +87,16 @@ const char *profile_quality_display_names[] = /* Dump THIS to BUFFER. */ void -profile_count::dump (char *buffer) const +profile_count::dump (char *buffer, struct function *fun) const { if (!initialized_p ()) sprintf (buffer, "uninitialized"); + else if (fun && initialized_p () + && fun->cfg + && ENTRY_BLOCK_PTR_FOR_FN (fun)->count.initialized_p ()) + sprintf (buffer, "%" PRId64 " (%s freq %.4f)", m_val, + profile_quality_display_names[m_quality], + to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (fun)->count).to_double ()); else sprintf (buffer, "%" PRId64 " (%s)", m_val, profile_quality_display_names[m_quality]); @@ -99,10 +105,10 @@ profile_count::dump (char *buffer) const /* Dump THIS to F. */ void -profile_count::dump (FILE *f) const +profile_count::dump (FILE *f, struct function *fun) const { char buffer[64]; - dump (buffer); + dump (buffer, fun); fputs (buffer, f); } @@ -111,7 +117,7 @@ profile_count::dump (FILE *f) const void profile_count::debug () const { - dump (stderr); + dump (stderr, cfun); fprintf (stderr, "\n"); } diff --git a/gcc/profile-count.h b/gcc/profile-count.h index 4270793..99416d9 100644 --- a/gcc/profile-count.h +++ b/gcc/profile-count.h @@ -1281,10 +1281,10 @@ public: sreal to_sreal_scale (profile_count in, bool *known = NULL) const; /* Output THIS to F. */ - void dump (FILE *f) const; + void dump (FILE *f, struct function *fun = NULL) const; /* Output THIS to BUFFER. */ - void dump (char *buffer) const; + void dump (char *buffer, struct function *fun = NULL) const; /* Print THIS to stderr. */ void debug () const; -- cgit v1.1 From 01405f01087b05d71a1f3bd1d4272bec332aeb58 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 8 Jul 2023 00:16:53 +0000 Subject: Daily bump. --- gcc/ChangeLog | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/d/ChangeLog | 9 ++++ gcc/testsuite/ChangeLog | 77 +++++++++++++++++++++++++++ 4 files changed, 224 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 222dfe3..a9a2f9e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,140 @@ +2023-07-07 Jan Hubicka + + * profile-count.cc (profile_count::dump): Add FUN + parameter; print relative frequency. + (profile_count::debug): Update. + * profile-count.h (profile_count::dump): Update + prototype. + +2023-07-07 Roger Sayle + + PR target/43644 + PR target/110533 + * config/i386/i386-expand.cc (ix86_expand_move): Convert SETs of + TImode destinations from paradoxical SUBREGs (setting the lowpart) + into explicit zero extensions. Use *insvti_highpart_1 instruction + to set the highpart of a TImode destination. + +2023-07-07 Jan Hubicka + + * predict.cc (force_edge_cold): Use + set_edge_probability_and_rescale_others; improve dumps. + +2023-07-07 Jan Hubicka + + * cfgloopmanip.cc (scale_loop_profile): Fix computation of count_in and scaling blocks + after exit. + * tree-vect-loop-manip.cc (vect_do_peeling): Scale loop profile of the epilogue if bound + is known. + +2023-07-07 Juergen Christ + + * config/s390/s390.cc (vec_init): Fix default case + +2023-07-07 Vladimir N. Makarov + + * lra-assigns.cc (assign_by_spills): Add reload insns involving + reload pseudos with non-refined class to be processed on the next + sub-pass. + * lra-constraints.cc (enough_allocatable_hard_regs_p): New func. + (in_class_p): Use it. + (print_curr_insn_alt): New func. + (process_alt_operands): Use it. Improve debug info. + (curr_insn_transform): Use print_curr_insn_alt. Refine reload + pseudo class if it is not refined yet. + +2023-07-07 Aldy Hernandez + + * value-range.cc (irange::get_bitmask_from_range): Return all the + known bits for a singleton. + (irange::set_range_from_bitmask): Set a range of a singleton when + all bits are known. + +2023-07-07 Aldy Hernandez + + * value-range.cc (irange::intersect): Leave normalization to + caller. + +2023-07-07 Aldy Hernandez + + * data-streamer-in.cc (streamer_read_value_range): Adjust for + value/mask. + * data-streamer-out.cc (streamer_write_vrange): Same. + * range-op.cc (operator_cast::fold_range): Same. + * value-range-pretty-print.cc + (vrange_printer::print_irange_bitmasks): Same. + * value-range-storage.cc (irange_storage::write_lengths_address): + Same. + (irange_storage::set_irange): Same. + (irange_storage::get_irange): Same. + (irange_storage::size): Same. + (irange_storage::dump): Same. + * value-range-storage.h: Same. + * value-range.cc (debug): New. + (irange_bitmask::dump): New. + (add_vrange): Adjust for value/mask. + (irange::operator=): Same. + (irange::set): Same. + (irange::verify_range): Same. + (irange::operator==): Same. + (irange::contains_p): Same. + (irange::irange_single_pair_union): Same. + (irange::union_): Same. + (irange::intersect): Same. + (irange::invert): Same. + (irange::get_nonzero_bits_from_range): Rename to... + (irange::get_bitmask_from_range): ...this. + (irange::set_range_from_nonzero_bits): Rename to... + (irange::set_range_from_bitmask): ...this. + (irange::set_nonzero_bits): Rename to... + (irange::update_bitmask): ...this. + (irange::get_nonzero_bits): Rename to... + (irange::get_bitmask): ...this. + (irange::intersect_nonzero_bits): Rename to... + (irange::intersect_bitmask): ...this. + (irange::union_nonzero_bits): Rename to... + (irange::union_bitmask): ...this. + (irange_bitmask::verify_mask): New. + * value-range.h (class irange_bitmask): New. + (irange_bitmask::set_unknown): New. + (irange_bitmask::unknown_p): New. + (irange_bitmask::irange_bitmask): New. + (irange_bitmask::get_precision): New. + (irange_bitmask::get_nonzero_bits): New. + (irange_bitmask::set_nonzero_bits): New. + (irange_bitmask::operator==): New. + (irange_bitmask::union_): New. + (irange_bitmask::intersect): New. + (class irange): Friend vrange_printer. + (irange::varying_compatible_p): Adjust for bitmask. + (irange::set_varying): Same. + (irange::set_nonzero): Same. + +2023-07-07 Jan Beulich + + * config/i386/sse.md (*vec_extractv2ti): Drop g modifiers. + +2023-07-07 Jan Beulich + + * config/i386/sse.md (@vec_extract_hi_): Drop last + alternative. Switch new last alternative's "isa" attribute to + "avx512vl". + (vec_extract_hi_v32qi): Likewise. + +2023-07-07 Pan Li + Robin Dapp + + * config/riscv/riscv.cc (riscv_emit_mode_set): Avoid emit insn + when FRM_MODE_DYN. + (riscv_mode_entry): Take FRM_MODE_DYN as entry mode. + (riscv_mode_exit): Likewise for exit mode. + (riscv_mode_needed): Likewise for needed mode. + (riscv_mode_after): Likewise for after mode. + +2023-07-07 Pan Li + + * config/riscv/vector.md: Fix typo. + 2023-07-06 Jan Hubicka PR middle-end/25623 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 2e3c50b..f3144f1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230707 +20230708 diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index 750b848..a967772 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,12 @@ +2023-07-07 Iain Buclaw + + PR d/108842 + * decl.cc (DeclVisitor::visit (VarDeclaration *)): Only emit scalar + manifest constants. + (get_symbol_decl): Don't generate CONST_DECL for non-scalar manifest + constants. + * imports.cc (ImportVisitor::visit (VarDeclaration *)): New method. + 2023-07-02 Iain Buclaw PR d/110516 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24119be..b398ab2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,80 @@ +2023-07-07 Jan Hubicka + + * gcc.dg/pr43864-2.c: Avoid matching pre dump with details-blocks. + * gcc.dg/pr43864-3.c: Likewise. + * gcc.dg/pr43864-4.c: Likewise. + * gcc.dg/pr43864.c: Likewise. + * gcc.dg/unroll-7.c: xfail. + +2023-07-07 Eugene Rozenfeld + + * lib/target-supports.exp: Collect both kernel and user events for autofdo + +2023-07-07 Roger Sayle + + PR target/43644 + PR target/110533 + * gcc.target/i386/pr110533.c: New test case. + * gcc.target/i386/pr43644-2.c: Likewise. + +2023-07-07 Iain Buclaw + + PR d/108842 + * gdc.dg/pr98277.d: Add more tests. + * gdc.dg/pr108842.d: New test. + +2023-07-07 Jan Hubicka + + * g++.dg/tree-prof/indir-call-prof.C: Add block-details to dump flags. + * gcc.dg/pr43864-2.c: Likewise. + * gcc.dg/pr43864-3.c: Likewise. + * gcc.dg/pr43864-4.c: Likewise. + * gcc.dg/pr43864.c: Likewise. + * gcc.dg/tree-prof/cold_partition_label.c: Likewise. + * gcc.dg/tree-prof/indir-call-prof.c: Likewise. + * gcc.dg/tree-prof/update-cunroll-2.c: Likewise. + * gcc.dg/tree-prof/update-tailcall.c: Likewise. + * gcc.dg/tree-prof/val-prof-1.c: Likewise. + * gcc.dg/tree-prof/val-prof-2.c: Likewise. + * gcc.dg/tree-prof/val-prof-3.c: Likewise. + * gcc.dg/tree-prof/val-prof-4.c: Likewise. + * gcc.dg/tree-prof/val-prof-5.c: Likewise. + * gcc.dg/tree-ssa/fnsplit-1.c: Likewise. + * gcc.dg/tree-ssa/loop-ch-profile-2.c: Likewise. + * gcc.dg/tree-ssa/update-threading.c: Likewise. + * gcc.dg/tree-ssa/update-unswitch-1.c: Likewise. + * gcc.dg/unroll-7.c: Likewise. + * gcc.dg/unroll-8.c: Likewise. + * gfortran.dg/pr25623-2.f90: Likewise. + * gfortran.dg/pr25623.f90: Likewise. + * gcc.dg/tree-ssa/loop-ch-profile-1.c: Likewise; xfail. + * gcc.dg/tree-ssa/update-cunroll.c: Likewise; xfail. + * gcc.dg/tree-ssa/update-unroll-1.c: Likewise; xfail. + +2023-07-07 Jan Hubicka + + * gcc.dg/tree-ssa/vect-profile-upate.c: New test. + +2023-07-07 Juergen Christ + + * gcc.target/s390/vector/vec-init-3.c: New test. + +2023-07-07 Vladimir N. Makarov + + * gcc.target/i386/pr110372.c: New. + +2023-07-07 Aldy Hernandez + + * gcc.dg/tree-ssa/pr107009.c: Adjust irange dumping for + value/mask changes. + * gcc.dg/tree-ssa/vrp-unreachable.c: Same. + * gcc.dg/tree-ssa/vrp122.c: Same. + +2023-07-07 Pan Li + Robin Dapp + + * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: New test. + 2023-07-06 Jan Hubicka PR middle-end/25623 -- cgit v1.1 From 72cfa0f799f3a695cc7b6d0c10a27a27fa087c26 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Sat, 8 Jul 2023 10:22:29 +0100 Subject: doc: Fix typos in Warning Options [PR110596] gcc/ChangeLog: PR c++/110595 PR c++/110596 * doc/invoke.texi (Warning Options): Fix typos. --- gcc/doc/invoke.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 594b24d..3063e71 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6730,7 +6730,7 @@ Warn if the compiler does not elide the copy from a local variable to the return value of a function in a context where it is allowed by [class.copy.elision]. This elision is commonly known as the Named Return Value Optimization. For instance, in the example below the -compiler cannot elide copies from both v1 and b2, so it elides neither. +compiler cannot elide copies from both v1 and v2, so it elides neither. @smallexample std::vector f() @@ -7086,7 +7086,7 @@ This warning is enabled by @option{-Wall}. @opindex Wmissing-include-dirs @opindex Wno-missing-include-dirs @item -Wmissing-include-dirs @r{(C, C++, Objective-C, Objective-C++ and Fortran only)} -Warn if a user-supplied include directory does not exist. This opions is disabled +Warn if a user-supplied include directory does not exist. This option is disabled by default for C, C++, Objective-C and Objective-C++. For Fortran, it is partially enabled by default by warning for -I and -J, only. -- cgit v1.1 From 0926f205075583c0655c0884fca22a3d02b3660f Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Sat, 8 Jul 2023 14:49:49 +0200 Subject: gcse: Change return type of predicate functions from int to bool Also change some internal variables and function arguments from int to bool. gcc/ChangeLog: * gcse.cc (expr_equiv_p): Change return type from int to bool. (oprs_unchanged_p): Change return type from int to void and adjust function body accordingly. (oprs_anticipatable_p): Ditto. (oprs_available_p): Ditto. (insert_expr_in_table): Ditto. Change "antic_p" and "avail_p" arguments to bool. Change "found" variable to bool. (load_killed_in_block_p): Change return type from int to void and adjust function body accordingly. Change "avail_p" argument to bool. (pre_expr_reaches_here_p): Change return type from int to void and adjust function body accordingly. (pre_delete): Ditto. Change "changed" variable to bool. (pre_gcse): Change return type from int to void and adjust function body accordingly. Change "did_insert" and "changed" variables to bool. (one_pre_gcse_pass): Change return type from int to void and adjust function body accordingly. Change "changed" variable to bool. (should_hoist_expr_to_dom): Change return type from int to void and adjust function body accordingly. Change "visited_allocated_locally" variable to bool. (hoist_code): Change return type from int to void and adjust function body accordingly. Change "changed" variable to bool. (one_code_hoisting_pass): Ditto. (pre_edge_insert): Change return type from int to void and adjust function body accordingly. Change "did_insert" variable to bool. (pre_expr_reaches_here_p_work): Change return type from int to void and adjust function body accordingly. (simple_mem): Ditto. (want_to_gcse_p): Change return type from int to void and adjust function body accordingly. (can_assign_to_reg_without_clobbers_p): Update function body for bool return type. (hash_scan_set): Change "antic_p" and "avail_p" variables to bool. (pre_insert_copies): Change "added_copy" variable to bool. --- gcc/gcse.cc | 234 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 119 insertions(+), 115 deletions(-) (limited to 'gcc') diff --git a/gcc/gcse.cc b/gcc/gcse.cc index 7283273..8413c9a 100644 --- a/gcc/gcse.cc +++ b/gcc/gcse.cc @@ -371,7 +371,7 @@ pre_ldst_expr_hasher::hash (const ls_expr *x) hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false); } -static int expr_equiv_p (const_rtx, const_rtx); +static bool expr_equiv_p (const_rtx, const_rtx); inline bool pre_ldst_expr_hasher::equal (const ls_expr *ptr1, @@ -454,10 +454,10 @@ static void hash_scan_insn (rtx_insn *, struct gcse_hash_table_d *); static void hash_scan_set (rtx, rtx_insn *, struct gcse_hash_table_d *); static void hash_scan_clobber (rtx, rtx_insn *, struct gcse_hash_table_d *); static void hash_scan_call (rtx, rtx_insn *, struct gcse_hash_table_d *); -static int oprs_unchanged_p (const_rtx, const rtx_insn *, int); -static int oprs_anticipatable_p (const_rtx, const rtx_insn *); -static int oprs_available_p (const_rtx, const rtx_insn *); -static void insert_expr_in_table (rtx, machine_mode, rtx_insn *, int, int, +static bool oprs_unchanged_p (const_rtx, const rtx_insn *, bool); +static bool oprs_anticipatable_p (const_rtx, const rtx_insn *); +static bool oprs_available_p (const_rtx, const rtx_insn *); +static void insert_expr_in_table (rtx, machine_mode, rtx_insn *, bool, bool, HOST_WIDE_INT, struct gcse_hash_table_d *); static unsigned int hash_expr (const_rtx, machine_mode, int *, int); static void record_last_reg_set_info (rtx_insn *, int); @@ -471,42 +471,42 @@ static void dump_hash_table (FILE *, const char *, struct gcse_hash_table_d *); static void compute_local_properties (sbitmap *, sbitmap *, sbitmap *, struct gcse_hash_table_d *); static void mems_conflict_for_gcse_p (rtx, const_rtx, void *); -static int load_killed_in_block_p (const_basic_block, int, const_rtx, int); +static bool load_killed_in_block_p (const_basic_block, int, const_rtx, bool); static void alloc_pre_mem (int, int); static void free_pre_mem (void); static struct edge_list *compute_pre_data (void); -static int pre_expr_reaches_here_p (basic_block, struct gcse_expr *, - basic_block); +static bool pre_expr_reaches_here_p (basic_block, struct gcse_expr *, + basic_block); static void insert_insn_end_basic_block (struct gcse_expr *, basic_block); static void pre_insert_copy_insn (struct gcse_expr *, rtx_insn *); static void pre_insert_copies (void); -static int pre_delete (void); -static int pre_gcse (struct edge_list *); -static int one_pre_gcse_pass (void); +static bool pre_delete (void); +static bool pre_gcse (struct edge_list *); +static bool one_pre_gcse_pass (void); static void add_label_notes (rtx, rtx_insn *); static void alloc_code_hoist_mem (int, int); static void free_code_hoist_mem (void); static void compute_code_hoist_vbeinout (void); static void compute_code_hoist_data (void); -static int should_hoist_expr_to_dom (basic_block, struct gcse_expr *, - basic_block, - sbitmap, HOST_WIDE_INT, int *, - enum reg_class, - int *, bitmap, rtx_insn *); -static int hoist_code (void); +static bool should_hoist_expr_to_dom (basic_block, struct gcse_expr *, + basic_block, + sbitmap, HOST_WIDE_INT, int *, + enum reg_class, + int *, bitmap, rtx_insn *); +static bool hoist_code (void); static enum reg_class get_regno_pressure_class (int regno, int *nregs); static enum reg_class get_pressure_class_and_nregs (rtx_insn *insn, int *nregs); -static int one_code_hoisting_pass (void); +static bool one_code_hoisting_pass (void); static rtx_insn *process_insert_insn (struct gcse_expr *); -static int pre_edge_insert (struct edge_list *, struct gcse_expr **); -static int pre_expr_reaches_here_p_work (basic_block, struct gcse_expr *, - basic_block, char *); +static bool pre_edge_insert (struct edge_list *, struct gcse_expr **); +static bool pre_expr_reaches_here_p_work (basic_block, struct gcse_expr *, + basic_block, char *); static struct ls_expr * ldst_entry (rtx); static void free_ldst_entry (struct ls_expr *); static void free_ld_motion_mems (void); static void print_ldst_list (FILE *); static struct ls_expr * find_rtx_in_ldst (rtx); -static int simple_mem (const_rtx); +static bool simple_mem (const_rtx); static void invalidate_any_buried_refs (rtx); static void compute_ld_motion_mems (void); static void trim_ld_motion_mems (void); @@ -744,7 +744,7 @@ static basic_block current_bb; /* See whether X, the source of a set, is something we want to consider for GCSE. */ -static int +static bool want_to_gcse_p (rtx x, machine_mode mode, HOST_WIDE_INT *max_distance_ptr) { #ifdef STACK_REGS @@ -778,12 +778,12 @@ want_to_gcse_p (rtx x, machine_mode mode, HOST_WIDE_INT *max_distance_ptr) case REG: case SUBREG: case CALL: - return 0; + return false; CASE_CONST_ANY: if (!doing_code_hoisting_p) /* Do not PRE constants. */ - return 0; + return false; /* FALLTHRU */ @@ -803,7 +803,7 @@ want_to_gcse_p (rtx x, machine_mode mode, HOST_WIDE_INT *max_distance_ptr) max_distance = ((HOST_WIDE_INT)param_gcse_cost_distance_ratio * cost) / 10; if (max_distance == 0) - return 0; + return false; gcc_assert (max_distance > 0); } @@ -843,9 +843,9 @@ can_assign_to_reg_without_clobbers_p (rtx x, machine_mode mode) /* If this is a valid operand, we are OK. If it's VOIDmode, we aren't. */ if (general_operand (x, mode)) - return 1; + return true; else if (GET_MODE (x) == VOIDmode) - return 0; + return false; /* Otherwise, check if we can make a valid insn from it. First initialize our test insn if we haven't already. */ @@ -880,19 +880,20 @@ can_assign_to_reg_without_clobbers_p (rtx x, machine_mode mode) return can_assign; } -/* Return nonzero if the operands of expression X are unchanged from the - start of INSN's basic block up to but not including INSN (if AVAIL_P == 0), - or from INSN to the end of INSN's basic block (if AVAIL_P != 0). */ +/* Return true if the operands of expression X are unchanged from the + start of INSN's basic block up to but not including INSN + (if AVAIL_P == false), or from INSN to the end of INSN's basic block + (if AVAIL_P == true). */ -static int -oprs_unchanged_p (const_rtx x, const rtx_insn *insn, int avail_p) +static bool +oprs_unchanged_p (const_rtx x, const rtx_insn *insn, bool avail_p) { int i, j; enum rtx_code code; const char *fmt; if (x == 0) - return 1; + return true; code = GET_CODE (x); switch (code) @@ -902,7 +903,7 @@ oprs_unchanged_p (const_rtx x, const rtx_insn *insn, int avail_p) struct reg_avail_info *info = ®_avail_info[REGNO (x)]; if (info->last_bb != current_bb) - return 1; + return true; if (avail_p) return info->last_set < DF_INSN_LUID (insn); else @@ -913,7 +914,7 @@ oprs_unchanged_p (const_rtx x, const rtx_insn *insn, int avail_p) if (! flag_gcse_lm || load_killed_in_block_p (current_bb, DF_INSN_LUID (insn), x, avail_p)) - return 0; + return false; else return oprs_unchanged_p (XEXP (x, 0), insn, avail_p); @@ -923,7 +924,7 @@ oprs_unchanged_p (const_rtx x, const rtx_insn *insn, int avail_p) case POST_INC: case PRE_MODIFY: case POST_MODIFY: - return 0; + return false; case PC: case CONST: @@ -932,7 +933,7 @@ oprs_unchanged_p (const_rtx x, const rtx_insn *insn, int avail_p) case LABEL_REF: case ADDR_VEC: case ADDR_DIFF_VEC: - return 1; + return true; default: break; @@ -949,15 +950,15 @@ oprs_unchanged_p (const_rtx x, const rtx_insn *insn, int avail_p) return oprs_unchanged_p (XEXP (x, i), insn, avail_p); else if (! oprs_unchanged_p (XEXP (x, i), insn, avail_p)) - return 0; + return false; } else if (fmt[i] == 'E') for (j = 0; j < XVECLEN (x, i); j++) if (! oprs_unchanged_p (XVECEXP (x, i, j), insn, avail_p)) - return 0; + return false; } - return 1; + return true; } /* Info passed from load_killed_in_block_p to mems_conflict_for_gcse_p. */ @@ -1007,17 +1008,17 @@ mems_conflict_for_gcse_p (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, mci->conflict = true; } -/* Return nonzero if the expression in X (a memory reference) is killed +/* Return true if the expression in X (a memory reference) is killed in block BB before or after the insn with the LUID in UID_LIMIT. - AVAIL_P is nonzero for kills after UID_LIMIT, and zero for kills + AVAIL_P is true for kills after UID_LIMIT, and zero for kills before UID_LIMIT. To check the entire block, set UID_LIMIT to max_uid + 1 and - AVAIL_P to 0. */ + AVAIL_P to false. */ -static int +static bool load_killed_in_block_p (const_basic_block bb, int uid_limit, const_rtx x, - int avail_p) + bool avail_p) { vec list = modify_mem_list[bb->index]; rtx_insn *setter; @@ -1025,7 +1026,7 @@ load_killed_in_block_p (const_basic_block bb, int uid_limit, const_rtx x, /* If this is a readonly then we aren't going to be changing it. */ if (MEM_READONLY_P (x)) - return 0; + return false; FOR_EACH_VEC_ELT_REVERSE (list, ix, setter) { @@ -1042,7 +1043,7 @@ load_killed_in_block_p (const_basic_block bb, int uid_limit, const_rtx x, to pure functions are never put on the list, so we need not worry about them. */ if (CALL_P (setter)) - return 1; + return true; /* SETTER must be an INSN of some kind that sets memory. Call note_stores to examine each hunk of memory that is modified. */ @@ -1050,27 +1051,27 @@ load_killed_in_block_p (const_basic_block bb, int uid_limit, const_rtx x, mci.conflict = false; note_stores (setter, mems_conflict_for_gcse_p, &mci); if (mci.conflict) - return 1; + return true; } - return 0; + return false; } -/* Return nonzero if the operands of expression X are unchanged from +/* Return true if the operands of expression X are unchanged from the start of INSN's basic block up to but not including INSN. */ -static int +static bool oprs_anticipatable_p (const_rtx x, const rtx_insn *insn) { - return oprs_unchanged_p (x, insn, 0); + return oprs_unchanged_p (x, insn, false); } -/* Return nonzero if the operands of expression X are unchanged from +/* Return true if the operands of expression X are unchanged from INSN to the end of INSN's basic block. */ -static int +static bool oprs_available_p (const_rtx x, const rtx_insn *insn) { - return oprs_unchanged_p (x, insn, 1); + return oprs_unchanged_p (x, insn, true); } /* Hash expression X. @@ -1092,9 +1093,9 @@ hash_expr (const_rtx x, machine_mode mode, int *do_not_record_p, return hash % hash_table_size; } -/* Return nonzero if exp1 is equivalent to exp2. */ +/* Return true if exp1 is equivalent to exp2. */ -static int +static bool expr_equiv_p (const_rtx x, const_rtx y) { return exp_equiv_p (x, y, 0, true); @@ -1107,19 +1108,19 @@ expr_equiv_p (const_rtx x, const_rtx y) MODE is the mode of the value X is being stored into. It is only used if X is a CONST_INT. - ANTIC_P is nonzero if X is an anticipatable expression. - AVAIL_P is nonzero if X is an available expression. + ANTIC_P is true if X is an anticipatable expression. + AVAIL_P is true if X is an available expression. MAX_DISTANCE is the maximum distance in instructions this expression can be moved. */ static void insert_expr_in_table (rtx x, machine_mode mode, rtx_insn *insn, - int antic_p, - int avail_p, HOST_WIDE_INT max_distance, + bool antic_p, bool avail_p, HOST_WIDE_INT max_distance, struct gcse_hash_table_d *table) { - int found, do_not_record_p; + bool found; + int do_not_record_p; unsigned int hash; struct gcse_expr *cur_expr, *last_expr = NULL; struct gcse_occr *antic_occr, *avail_occr; @@ -1133,7 +1134,7 @@ insert_expr_in_table (rtx x, machine_mode mode, rtx_insn *insn, return; cur_expr = table->table[hash]; - found = 0; + found = false; while (cur_expr && (found = expr_equiv_p (cur_expr->expr, x)) == 0) { @@ -1283,14 +1284,14 @@ hash_scan_set (rtx set, rtx_insn *insn, struct gcse_hash_table_d *table) this insn. The latter condition does not have to mean that SRC itself is not anticipatable, but we just will not be able to handle code motion of insns with multiple sets. */ - int antic_p = oprs_anticipatable_p (src, insn) - && !multiple_sets (insn); + bool antic_p = (oprs_anticipatable_p (src, insn) + && !multiple_sets (insn)); /* An expression is not available if its operands are subsequently modified, including this insn. It's also not available if this is a branch, because we can't insert a set after the branch. */ - int avail_p = (oprs_available_p (src, insn) - && ! JUMP_P (insn)); + bool avail_p = (oprs_available_p (src, insn) + && ! JUMP_P (insn)); insert_expr_in_table (src, GET_MODE (dest), insn, antic_p, avail_p, max_distance, table); @@ -1324,12 +1325,12 @@ hash_scan_set (rtx set, rtx_insn *insn, struct gcse_hash_table_d *table) || ! MEM_P (XEXP (note, 0)))) { /* Stores are never anticipatable. */ - int antic_p = 0; + bool antic_p = 0; /* An expression is not available if its operands are subsequently modified, including this insn. It's also not available if this is a branch, because we can't insert a set after the branch. */ - int avail_p = oprs_available_p (dest, insn) && ! JUMP_P (insn); + bool avail_p = oprs_available_p (dest, insn) && ! JUMP_P (insn); /* Record the memory expression (DEST) in the hash table. */ insert_expr_in_table (dest, GET_MODE (dest), insn, @@ -1897,7 +1898,7 @@ compute_pre_data (void) /* PRE utilities */ -/* Return nonzero if an occurrence of expression EXPR in OCCR_BB would reach +/* Return true if an occurrence of expression EXPR in OCCR_BB would reach block BB. VISITED is a pointer to a working buffer for tracking which BB's have @@ -1910,7 +1911,7 @@ compute_pre_data (void) only one reaching expression and to reduce register lifetimes by picking the closest such expression. */ -static int +static bool pre_expr_reaches_here_p_work (basic_block occr_bb, struct gcse_expr *expr, basic_block bb, char *visited) { @@ -1933,7 +1934,7 @@ pre_expr_reaches_here_p_work (basic_block occr_bb, struct gcse_expr *expr, Note that there's only one generating occurrence per block so we just need to check the block number. */ if (occr_bb == pred_bb) - return 1; + return true; visited[pred_bb->index] = 1; } @@ -1946,21 +1947,22 @@ pre_expr_reaches_here_p_work (basic_block occr_bb, struct gcse_expr *expr, { visited[pred_bb->index] = 1; if (pre_expr_reaches_here_p_work (occr_bb, expr, pred_bb, visited)) - return 1; + return true; } } /* All paths have been checked. */ - return 0; + return false; } /* The wrapper for pre_expr_reaches_here_work that ensures that any memory allocated for that function is returned. */ -static int -pre_expr_reaches_here_p (basic_block occr_bb, struct gcse_expr *expr, basic_block bb) +static bool +pre_expr_reaches_here_p (basic_block occr_bb, struct gcse_expr *expr, + basic_block bb) { - int rval; + bool rval; char *visited = XCNEWVEC (char, last_basic_block_for_fn (cfun)); rval = pre_expr_reaches_here_p_work (occr_bb, expr, bb, visited); @@ -2099,10 +2101,11 @@ insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb) /* Insert partially redundant expressions on edges in the CFG to make the expressions fully redundant. */ -static int +static bool pre_edge_insert (struct edge_list *edge_list, struct gcse_expr **index_map) { - int e, i, j, num_edges, set_size, did_insert = 0; + int e, i, j, num_edges, set_size; + bool did_insert = false; sbitmap *inserted; /* Where PRE_INSERT_MAP is nonzero, we add the expression on that edge @@ -2169,7 +2172,7 @@ pre_edge_insert (struct edge_list *edge_list, struct gcse_expr **index_map) update_ld_motion_stores (expr); bitmap_set_bit (inserted[e], j); - did_insert = 1; + did_insert = true; gcse_create_count++; } } @@ -2289,7 +2292,8 @@ pre_insert_copy_insn (struct gcse_expr *expr, rtx_insn *insn) static void pre_insert_copies (void) { - unsigned int i, added_copy; + unsigned int i; + bool added_copy; struct gcse_expr *expr; struct gcse_occr *occr; struct gcse_occr *avail; @@ -2312,7 +2316,7 @@ pre_insert_copies (void) continue; /* Set when we add a copy for that expression. */ - added_copy = 0; + added_copy = false; for (occr = expr->antic_occr; occr != NULL; occr = occr->next) { @@ -2337,7 +2341,7 @@ pre_insert_copies (void) BLOCK_FOR_INSN (occr->insn))) continue; - added_copy = 1; + added_copy = true; /* Copy the result of avail to reaching_reg. */ pre_insert_copy_insn (expr, insn); @@ -2449,17 +2453,16 @@ gcse_emit_move_after (rtx dest, rtx src, rtx_insn *insn) the expression into the result of the SET. It is left to later passes to propagate the copy or eliminate it. - Return nonzero if a change is made. */ + Return true if a change is made. */ -static int +static bool pre_delete (void) { unsigned int i; - int changed; + bool changed = false; struct gcse_expr *expr; struct gcse_occr *occr; - changed = 0; for (i = 0; i < expr_hash_table.size; i++) for (expr = expr_hash_table.table[i]; expr; expr = expr->next_same_hash) { @@ -2486,7 +2489,7 @@ pre_delete (void) gcse_emit_move_after (SET_DEST (set), expr->reaching_reg, insn); delete_insn (insn); occr->deleted_p = 1; - changed = 1; + changed = true; gcse_subst_count++; if (dump_file) @@ -2524,11 +2527,11 @@ pre_delete (void) can't handle PARALLELs in the cases where there are no partial redundancies. */ -static int +static bool pre_gcse (struct edge_list *edge_list) { unsigned int i; - int did_insert, changed; + bool did_insert, changed; struct gcse_expr **index_map; struct gcse_expr *expr; @@ -2554,7 +2557,7 @@ pre_gcse (struct edge_list *edge_list) if (did_insert) { commit_edge_insertions (); - changed = 1; + changed = true; } free (index_map); @@ -2563,12 +2566,12 @@ pre_gcse (struct edge_list *edge_list) /* Top level routine to perform one PRE GCSE pass. - Return nonzero if a change was made. */ + Return true if a change was made. */ -static int +static bool one_pre_gcse_pass (void) { - int changed = 0; + bool changed = false; gcse_subst_count = 0; gcse_create_count = 0; @@ -2576,7 +2579,7 @@ one_pre_gcse_pass (void) /* Return if there's nothing to do, or it is too expensive. */ if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1 || gcse_or_cprop_is_too_expensive (_("PRE disabled"))) - return 0; + return false; /* We need alias. */ init_alias_analysis (); @@ -2601,7 +2604,8 @@ one_pre_gcse_pass (void) struct edge_list *edge_list; alloc_pre_mem (last_basic_block_for_fn (cfun), expr_hash_table.n_elems); edge_list = compute_pre_data (); - changed |= pre_gcse (edge_list); + if (pre_gcse (edge_list)) + changed = true; free_edge_list (edge_list); free_pre_mem (); } @@ -2883,7 +2887,7 @@ update_bb_reg_pressure (basic_block bb, rtx_insn *from) considered reachable if *any* path reaches instead of *all* paths. */ -static int +static bool should_hoist_expr_to_dom (basic_block expr_bb, struct gcse_expr *expr, basic_block bb, sbitmap visited, HOST_WIDE_INT distance, @@ -2894,7 +2898,7 @@ should_hoist_expr_to_dom (basic_block expr_bb, struct gcse_expr *expr, edge pred; edge_iterator ei; sbitmap_iterator sbi; - int visited_allocated_locally = 0; + bool visited_allocated_locally = false; int decreased_pressure = 0; if (flag_ira_hoist_pressure) @@ -2946,7 +2950,7 @@ should_hoist_expr_to_dom (basic_block expr_bb, struct gcse_expr *expr, if (visited == NULL) { - visited_allocated_locally = 1; + visited_allocated_locally = true; visited = sbitmap_alloc (last_basic_block_for_fn (cfun)); bitmap_clear (visited); } @@ -3047,7 +3051,7 @@ find_occr_in_bb (struct gcse_occr *occr, basic_block bb) 5. Update register pressure information for basic blocks through which expression is hoisted. */ -static int +static bool hoist_code (void) { basic_block bb, dominated; @@ -3057,7 +3061,7 @@ hoist_code (void) struct gcse_expr *expr; int *to_bb_head; int *bb_size; - int changed = 0; + bool changed = false; struct bb_data *data; /* Basic blocks that have occurrences reachable from BB. */ bitmap from_bbs; @@ -3301,7 +3305,7 @@ hoist_code (void) insn); delete_insn (insn); occr->deleted_p = 1; - changed = 1; + changed = true; gcse_subst_count++; if (!insn_inserted_p) @@ -3490,12 +3494,12 @@ calculate_bb_reg_pressure (void) /* Top level routine to perform one code hoisting (aka unification) pass - Return nonzero if a change was made. */ + Return true if a change was made. */ -static int +static bool one_code_hoisting_pass (void) { - int changed = 0; + bool changed = false; gcse_subst_count = 0; gcse_create_count = 0; @@ -3503,7 +3507,7 @@ one_code_hoisting_pass (void) /* Return if there's nothing to do, or it is too expensive. */ if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1 || gcse_or_cprop_is_too_expensive (_("GCSE disabled"))) - return 0; + return false; doing_code_hoisting_p = true; @@ -3702,32 +3706,32 @@ find_rtx_in_ldst (rtx x) These are the types of loads we consider for the ld_motion list, otherwise we let the usual aliasing take care of it. */ -static int +static bool simple_mem (const_rtx x) { if (MEM_VOLATILE_P (x)) - return 0; + return false; if (GET_MODE (x) == BLKmode) - return 0; + return false; /* If we are handling exceptions, we must be careful with memory references that may trap. If we are not, the behavior is undefined, so we may just continue. */ if (cfun->can_throw_non_call_exceptions && may_trap_p (x)) - return 0; + return false; if (side_effects_p (x)) - return 0; + return false; /* Do not consider function arguments passed on stack. */ if (reg_mentioned_p (stack_pointer_rtx, x)) - return 0; + return false; if (flag_float_store && FLOAT_MODE_P (GET_MODE (x))) - return 0; + return false; - return 1; + return true; } /* Make sure there isn't a buried reference in this pattern anywhere. -- cgit v1.1 From 38b7125be9ce76402cf6ea16cdbc6055358a6e54 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Sat, 8 Jul 2023 15:00:19 +0200 Subject: cprop: Change return type of predicate functions from int to bool Also change some internal variables from int to bool. gcc/ChangeLog: * cprop.cc (reg_available_p): Change return type from int to bool. (reg_not_set_p): Ditto. (try_replace_reg): Ditto. Change "success" variable to bool. (cprop_jump): Change return type from int to void and adjust function body accordingly. (constprop_register): Ditto. (cprop_insn): Ditto. Change "changed" variable to bool. (local_cprop_pass): Change return type from int to void and adjust function body accordingly. (bypass_block): Ditto. Change "change", "may_be_loop_header" and "removed_p" variables to bool. (bypass_conditional_jumps): Change return type from int to void and adjust function body accordingly. Change "changed" variable to bool. (one_cprop_pass): Ditto. --- gcc/cprop.cc | 113 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 52 deletions(-) (limited to 'gcc') diff --git a/gcc/cprop.cc b/gcc/cprop.cc index 6ec0bda..b7400c9 100644 --- a/gcc/cprop.cc +++ b/gcc/cprop.cc @@ -142,10 +142,10 @@ cprop_alloc (unsigned long size) return obstack_alloc (&cprop_obstack, size); } -/* Return nonzero if register X is unchanged from INSN to the end +/* Return true if register X is unchanged from INSN to the end of INSN's basic block. */ -static int +static bool reg_available_p (const_rtx x, const rtx_insn *insn ATTRIBUTE_UNUSED) { return ! REGNO_REG_SET_P (reg_set_bitmap, REGNO (x)); @@ -517,10 +517,10 @@ reset_opr_set_tables (void) CLEAR_REG_SET (reg_set_bitmap); } -/* Return nonzero if the register X has not been set yet [since the +/* Return true if the register X has not been set yet [since the start of the basic block containing INSN]. */ -static int +static bool reg_not_set_p (const_rtx x, const rtx_insn *insn ATTRIBUTE_UNUSED) { return ! REGNO_REG_SET_P (reg_set_bitmap, REGNO (x)); @@ -722,14 +722,14 @@ find_used_regs (rtx *xptr, void *data ATTRIBUTE_UNUSED) } /* Try to replace all uses of FROM in INSN with TO. - Return nonzero if successful. */ + Return true if successful. */ -static int +static bool try_replace_reg (rtx from, rtx to, rtx_insn *insn) { rtx note = find_reg_equal_equiv_note (insn); rtx src = 0; - int success = 0; + bool success = false; rtx set = single_set (insn); bool check_rtx_costs = true; @@ -765,7 +765,7 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn) if (num_changes_pending () && apply_change_group ()) - success = 1; + success = true; /* Try to simplify SET_SRC if we have substituted a constant. */ if (success && set && CONSTANT_P (to)) @@ -790,7 +790,7 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn) if (!rtx_equal_p (src, SET_SRC (set)) && validate_change (insn, &SET_SRC (set), src, 0)) - success = 1; + success = true; /* If we've failed perform the replacement, have a single SET to a REG destination and don't yet have a note, add a REG_EQUAL note @@ -808,7 +808,7 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn) if (!rtx_equal_p (dest, SET_DEST (set)) && validate_change (insn, &SET_DEST (set), dest, 0)) - success = 1; + success = true; } /* REG_EQUAL may get simplified into register. @@ -889,10 +889,10 @@ find_avail_set (int regno, rtx_insn *insn, struct cprop_expr *set_ret[2]) JUMP_INSNS. JUMP must be a conditional jump. If SETCC is non-NULL it is the instruction that immediately precedes JUMP, and must be a single SET of a register. FROM is what we will try to replace, - SRC is the constant we will try to substitute for it. Return nonzero + SRC is the constant we will try to substitute for it. Return true if a change was made. */ -static int +static bool cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) { rtx new_rtx, set_src, note_src; @@ -931,7 +931,7 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) /* If no simplification can be made, then try the next register. */ if (rtx_equal_p (new_rtx, SET_SRC (set))) - return 0; + return false; /* If this is now a no-op delete it, otherwise this must be a valid insn. */ if (new_rtx == pc_rtx) @@ -941,7 +941,7 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) /* Ensure the value computed inside the jump insn to be equivalent to one computed by setcc. */ if (setcc && modified_in_p (new_rtx, setcc)) - return 0; + return false; if (! validate_unshare_change (jump, &SET_SRC (set), new_rtx, 0)) { /* When (some) constants are not valid in a comparison, and there @@ -955,7 +955,7 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) if (!rtx_equal_p (new_rtx, note_src)) set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new_rtx)); - return 0; + return false; } /* Remove REG_EQUAL note after simplification. */ @@ -992,14 +992,14 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) delete_insn (jump); } - return 1; + return true; } /* Subroutine of cprop_insn that tries to propagate constants. FROM is what we will try to replace, SRC is the constant we will try to substitute for it and INSN is the instruction where this will be happening. */ -static int +static bool constprop_register (rtx from, rtx src, rtx_insn *insn) { rtx sset; @@ -1016,12 +1016,12 @@ constprop_register (rtx from, rtx src, rtx_insn *insn) if (REG_P (dest) && cprop_jump (BLOCK_FOR_INSN (insn), insn, next_insn, from, src)) - return 1; + return true; } /* Handle normal insns next. */ if (NONJUMP_INSN_P (insn) && try_replace_reg (from, src, insn)) - return 1; + return true; /* Try to propagate a CONST_INT into a conditional jump. We're pretty specific about what we will handle in this @@ -1031,17 +1031,18 @@ constprop_register (rtx from, rtx src, rtx_insn *insn) (set (pc) (if_then_else ...)) */ else if (any_condjump_p (insn) && onlyjump_p (insn)) return cprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, src); - return 0; + return false; } /* Perform constant and copy propagation on INSN. - Return nonzero if a change was made. */ + Return true if a change was made. */ -static int +static bool cprop_insn (rtx_insn *insn) { unsigned i; - int changed = 0, changed_this_round; + int changed_this_round; + bool changed = false; rtx note; do @@ -1079,7 +1080,8 @@ cprop_insn (rtx_insn *insn) if (src_cst && cprop_constant_p (src_cst) && constprop_register (reg_used, src_cst, insn)) { - changed_this_round = changed = 1; + changed = true; + changed_this_round = 1; global_const_prop_count++; if (dump_file != NULL) { @@ -1091,14 +1093,15 @@ cprop_insn (rtx_insn *insn) fprintf (dump_file, "\n"); } if (insn->deleted ()) - return 1; + return true; } /* Copy propagation. */ else if (src_reg && cprop_reg_p (src_reg) && REGNO (src_reg) != regno && try_replace_reg (reg_used, src_reg, insn)) { - changed_this_round = changed = 1; + changed = true; + changed_this_round = 1; global_copy_prop_count++; if (dump_file != NULL) { @@ -1121,7 +1124,7 @@ cprop_insn (rtx_insn *insn) while (changed_this_round); if (changed && DEBUG_INSN_P (insn)) - return 0; + return false; return changed; } @@ -1237,7 +1240,7 @@ do_local_cprop (rtx x, rtx_insn *insn) /* Do local const/copy propagation (i.e. within each basic block). */ -static int +static bool local_cprop_pass (void) { basic_block bb; @@ -1352,12 +1355,12 @@ implicit_set_cond_p (const_rtx cond) handle float, complex, and vector. If any subpart is a zero, then the optimization can't be performed. */ /* ??? The complex and vector checks are not implemented yet. We just - always return zero for them. */ + always return false for them. */ if (CONST_DOUBLE_AS_FLOAT_P (cst) && real_equal (CONST_DOUBLE_REAL_VALUE (cst), &dconst0)) - return 0; + return false; else - return 0; + return false; } return cprop_constant_p (cst); @@ -1510,21 +1513,21 @@ reg_killed_on_edge (const_rtx reg, const_edge e) basic block BB which has more than one predecessor. If not NULL, SETCC is the first instruction of BB, which is immediately followed by JUMP_INSN JUMP. Otherwise, SETCC is NULL, and JUMP is the first insn of BB. - Returns nonzero if a change was made. + Returns true if a change was made. During the jump bypassing pass, we may place copies of SETCC instructions on CFG edges. The following routine must be careful to pay attention to these inserted insns when performing its transformations. */ -static int +static bool bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn *jump) { rtx_insn *insn; rtx note; edge e, edest; - int change; - int may_be_loop_header = false; - unsigned removed_p; + bool change; + bool may_be_loop_header = false; + bool removed_p; unsigned i; edge_iterator ei; @@ -1555,10 +1558,10 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn *jump) } } - change = 0; + change = false; for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) { - removed_p = 0; + removed_p = false; if (e->flags & EDGE_COMPLEX) { @@ -1663,8 +1666,8 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn *jump) old_dest->index, e->src->index, e->src->index, old_dest->index, dest->index); } - change = 1; - removed_p = 1; + change = true; + removed_p = true; break; } } @@ -1681,22 +1684,22 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn *jump) This function is now mis-named, because we also handle indirect jumps. */ -static int +static bool bypass_conditional_jumps (void) { basic_block bb; - int changed; + bool changed; rtx_insn *setcc; rtx_insn *insn; rtx dest; /* Note we start at block 1. */ if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)) - return 0; + return false; mark_dfs_back_edges (); - changed = 0; + changed = false; FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->next_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) { @@ -1724,7 +1727,8 @@ bypass_conditional_jumps (void) { if ((any_condjump_p (insn) || computed_jump_p (insn)) && onlyjump_p (insn)) - changed |= bypass_block (bb, setcc, insn); + if (bypass_block (bb, setcc, insn)) + changed = true; break; } else if (INSN_P (insn)) @@ -1742,16 +1746,16 @@ bypass_conditional_jumps (void) /* Main function for the CPROP pass. */ -static int +static bool one_cprop_pass (void) { + bool changed = false; int i; - int changed = 0; /* Return if there's nothing to do, or it is too expensive. */ if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1 || gcse_or_cprop_is_too_expensive (_ ("const/copy propagation disabled"))) - return 0; + return false; global_const_prop_count = local_const_prop_count = 0; global_copy_prop_count = local_copy_prop_count = 0; @@ -1772,7 +1776,9 @@ one_cprop_pass (void) FIXME: The global analysis would not get into infinite loops if it would use the DF solver (via df_simple_dataflow) instead of the solver implemented in this file. */ - changed |= local_cprop_pass (); + if (local_cprop_pass ()) + changed = true; + if (changed) delete_unreachable_blocks (); @@ -1783,7 +1789,8 @@ one_cprop_pass (void) changed something. ??? This could run earlier so that any uncovered implicit sets sets could be exploited in local_cprop_pass() also. Later. */ - changed |= find_implicit_sets (); + if (find_implicit_sets ()) + changed = true; /* If local_cprop_pass() or find_implicit_sets() changed something, run df_analyze() to bring all insn caches up-to-date, and to take @@ -1840,7 +1847,8 @@ one_cprop_pass (void) = (GET_CODE (PATTERN (insn)) == TRAP_IF && XEXP (PATTERN (insn), 0) == const1_rtx); - changed |= cprop_insn (insn); + if (cprop_insn (insn)) + changed = true; /* Keep track of everything modified by this insn. */ /* ??? Need to be careful w.r.t. mods done to INSN. @@ -1882,7 +1890,8 @@ one_cprop_pass (void) emit_barrier_after_bb (to_split); } - changed |= bypass_conditional_jumps (); + if (bypass_conditional_jumps ()) + changed = true; FREE_REG_SET (reg_set_bitmap); free_cprop_mem (); -- cgit v1.1 From 7ac1581d066a6f3a0d4acf1042a74634258b4966 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Fri, 7 Jul 2023 20:25:06 +0200 Subject: Fortran: simplification of FINDLOC for constant complex arguments [PR110585] gcc/fortran/ChangeLog: PR fortran/110585 * arith.cc (gfc_compare_expr): Handle equality comparison of constant complex gfc_expr arguments. gcc/testsuite/ChangeLog: PR fortran/110585 * gfortran.dg/findloc_9.f90: New test. --- gcc/fortran/arith.cc | 5 +++++ gcc/testsuite/gfortran.dg/findloc_9.f90 | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/findloc_9.f90 (limited to 'gcc') diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc index 86d56406..f9c6658 100644 --- a/gcc/fortran/arith.cc +++ b/gcc/fortran/arith.cc @@ -1120,6 +1120,11 @@ gfc_compare_expr (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) || (op1->value.logical && !op2->value.logical)); break; + case BT_COMPLEX: + gcc_assert (op == INTRINSIC_EQ); + rc = mpc_cmp (op1->value.complex, op2->value.complex); + break; + default: gfc_internal_error ("gfc_compare_expr(): Bad basic type"); } diff --git a/gcc/testsuite/gfortran.dg/findloc_9.f90 b/gcc/testsuite/gfortran.dg/findloc_9.f90 new file mode 100644 index 0000000..0597447 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/findloc_9.f90 @@ -0,0 +1,19 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! PR fortran/110585 - simplification of FINDLOC for constant complex arguments + +program mvce + implicit none + integer, parameter :: a(*) = findloc([(1.,0.),(2.,1.)], (2.,0.)) + integer, parameter :: b(*) = findloc([(1.,0.),(2.,1.)], (2.,0.), back=.true.) + integer, parameter :: c(*) = findloc([(1.,0.),(2.,1.)], (2.,1.)) + integer, parameter :: d(*) = findloc([(1.,0.),(2.,1.)], (2.,1.), back=.true.) + integer, parameter :: e = findloc([(1.,0.),(2.,1.)], (2.,1.), dim=1) + if (a(1) /= 0) stop 1 + if (b(1) /= 0) stop 2 + if (c(1) /= 2) stop 3 + if (d(1) /= 2) stop 4 + if (e /= 2) stop 5 +end + +! { dg-final { scan-tree-dump-not "_gfortran_stop_numeric" "original" } } -- cgit v1.1 From b1079fc88f082d3c5b583c8822c08c5647810259 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Wed, 5 Jul 2023 22:21:09 +0200 Subject: Fortran: fixes for procedures with ALLOCATABLE,INTENT(OUT) arguments [PR92178] gcc/fortran/ChangeLog: PR fortran/92178 * trans-expr.cc (gfc_conv_procedure_call): Check procedures for allocatable dummy arguments with INTENT(OUT) and move deallocation of actual arguments after evaluation of argument expressions before the procedure is executed. gcc/testsuite/ChangeLog: PR fortran/92178 * gfortran.dg/intent_out_16.f90: New test. * gfortran.dg/intent_out_17.f90: New test. * gfortran.dg/intent_out_18.f90: New test. Co-authored-by: Steven G. Kargl --- gcc/fortran/trans-expr.cc | 54 +++++++++++++++-- gcc/testsuite/gfortran.dg/intent_out_16.f90 | 89 +++++++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/intent_out_17.f90 | 46 +++++++++++++++ gcc/testsuite/gfortran.dg/intent_out_18.f90 | 31 ++++++++++ 4 files changed, 215 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/intent_out_16.f90 create mode 100644 gcc/testsuite/gfortran.dg/intent_out_17.f90 create mode 100644 gcc/testsuite/gfortran.dg/intent_out_18.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 30946ba..7017b65 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6085,9 +6085,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else info = NULL; - stmtblock_t post, clobbers; + stmtblock_t post, clobbers, dealloc_blk; gfc_init_block (&post); gfc_init_block (&clobbers); + gfc_init_block (&dealloc_blk); gfc_init_interface_mapping (&mapping); if (!comp) { @@ -6117,6 +6118,32 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && UNLIMITED_POLY (sym) && comp && (strcmp ("_copy", comp->name) == 0); + /* Scan for allocatable actual arguments passed to allocatable dummy + arguments with INTENT(OUT). As the corresponding actual arguments are + deallocated before execution of the procedure, we evaluate actual + argument expressions to avoid problems with possible dependencies. */ + bool force_eval_args = false; + gfc_formal_arglist *tmp_formal; + for (arg = args, tmp_formal = formal; arg != NULL; + arg = arg->next, tmp_formal = tmp_formal ? tmp_formal->next : NULL) + { + e = arg->expr; + fsym = tmp_formal ? tmp_formal->sym : NULL; + if (e && fsym + && e->expr_type == EXPR_VARIABLE + && fsym->attr.intent == INTENT_OUT + && (fsym->ts.type == BT_CLASS && fsym->attr.class_ok + ? CLASS_DATA (fsym)->attr.allocatable + : fsym->attr.allocatable) + && e->symtree + && e->symtree->n.sym + && gfc_variable_attr (e, NULL).allocatable) + { + force_eval_args = true; + break; + } + } + /* Evaluate the arguments. */ for (arg = args, argc = 0; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL, ++argc) @@ -6680,7 +6707,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else tmp = gfc_finish_block (&block); - gfc_add_expr_to_block (&se->pre, tmp); + gfc_add_expr_to_block (&dealloc_blk, tmp); } /* A class array element needs converting back to be a @@ -6776,6 +6803,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, /* Pass a class array. */ parmse.use_offset = 1; gfc_conv_expr_descriptor (&parmse, e); + bool defer_to_dealloc_blk = false; /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is allocated on entry, it must be deallocated. */ @@ -6816,7 +6844,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else tmp = gfc_finish_block (&block); - gfc_add_expr_to_block (&se->pre, tmp); + gfc_add_expr_to_block (&dealloc_blk, tmp); + defer_to_dealloc_blk = true; } /* The conversion does not repackage the reference to a class @@ -6830,6 +6859,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && e->symtree->n.sym->attr.optional, CLASS_DATA (fsym)->attr.class_pointer || CLASS_DATA (fsym)->attr.allocatable); + + /* Defer repackaging after deallocation. */ + if (defer_to_dealloc_blk) + gfc_add_block_to_block (&dealloc_blk, &parmse.pre); } else { @@ -6980,7 +7013,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, build_empty_stmt (input_location)); } if (tmp != NULL_TREE) - gfc_add_expr_to_block (&se->pre, tmp); + gfc_add_expr_to_block (&dealloc_blk, tmp); } tmp = parmse.expr; @@ -7004,7 +7037,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, void_type_node, gfc_conv_expr_present (e->symtree->n.sym), tmp, build_empty_stmt (input_location)); - gfc_add_expr_to_block (&se->pre, tmp); + gfc_add_expr_to_block (&dealloc_blk, tmp); } } } @@ -7101,6 +7134,16 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, } } + /* If any actual argument of the procedure is allocatable and passed + to an allocatable dummy with INTENT(OUT), we conservatively + evaluate actual argument expressions before deallocations are + performed and the procedure is executed. May create temporaries. + This ensures we conform to F2023:15.5.3, 15.5.4. */ + if (e && fsym && force_eval_args + && fsym->attr.intent != INTENT_OUT + && !gfc_is_constant_expr (e)) + parmse.expr = gfc_evaluate_now (parmse.expr, &parmse.pre); + if (fsym && need_interface_mapping && e) gfc_add_interface_mapping (&mapping, fsym, &parmse, e); @@ -7499,6 +7542,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, vec_safe_push (arglist, parmse.expr); } + gfc_add_block_to_block (&se->pre, &dealloc_blk); gfc_add_block_to_block (&se->pre, &clobbers); gfc_finish_interface_mapping (&mapping, &se->pre, &se->post); diff --git a/gcc/testsuite/gfortran.dg/intent_out_16.f90 b/gcc/testsuite/gfortran.dg/intent_out_16.f90 new file mode 100644 index 0000000..e8d635f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intent_out_16.f90 @@ -0,0 +1,89 @@ +! { dg-do run } +! +! PR fortran/92178 +! Re-order argument deallocation + +program p + implicit none + integer, allocatable :: a(:) + class(*), allocatable :: c(:) + type t + integer, allocatable :: a(:) + end type t + type(t) :: b + integer :: k = -999 + + ! Test based on original PR + a = [1] + call assign (a, (max(a(1),0))) + if (allocated (a)) stop 9 + if (k /= 1) stop 10 + + ! Additional variations based on suggestions by Tobias Burnus + ! to check that argument expressions are evaluated early enough + a = [1, 2] + call foo (allocated (a), size (a), test (a), a, allocated (a)) + if (allocated (a)) stop 11 + + a = [1, 2] + k = 1 + call foo (allocated (a), size (a), test (k*a), a, allocated (a)) + if (allocated (a)) stop 12 + + b% a = [1, 2] + call foo (allocated (b% a), size (b% a), test (b% a), b% a, allocated (b% a)) + if (allocated (b% a)) stop 13 + + c = [3, 4] + call bar (allocated (c), size (c), test2 (c), c, & + allocated (c), size (c), test2 (c) ) + if (allocated (c)) stop 14 + +contains + + subroutine assign (a, i) + integer, allocatable, intent(out) :: a(:) + integer, value :: i + k = i + end subroutine + + subroutine foo (alloc, sz, tst, x, alloc2) + logical, value :: alloc, tst + integer, value :: sz + logical :: alloc2 + integer, allocatable, intent(out) :: x(:) + if (allocated (x)) stop 1 + if (.not. alloc) stop 2 + if (sz /= 2) stop 3 + if (.not. tst) stop 4 + if (.not. alloc2) stop 15 + end subroutine foo + ! + logical function test (zz) + integer :: zz(2) + test = zz(2) == 2 + end function test + ! + subroutine bar (alloc, sz, tst, x, alloc2, sz2, tst2) + logical, value :: alloc, tst, alloc2, tst2 + integer, value :: sz, sz2 + class(*), allocatable, intent(out) :: x(:) + if (allocated (x)) stop 5 + if (.not. alloc) stop 6 + if (sz /= 2) stop 7 + if (.not. tst) stop 8 + if (.not. alloc2) stop 16 + if (sz2 /= 2) stop 17 + if (.not. tst2) stop 18 + end subroutine bar + ! + logical function test2 (zz) + class(*), intent(in) :: zz(:) + select type (zz) + type is (integer) + test2 = zz(2) == 4 + class default + stop 99 + end select + end function test2 +end diff --git a/gcc/testsuite/gfortran.dg/intent_out_17.f90 b/gcc/testsuite/gfortran.dg/intent_out_17.f90 new file mode 100644 index 0000000..bc9208d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intent_out_17.f90 @@ -0,0 +1,46 @@ +! { dg-do run } +! +! PR fortran/92178 +! Contributed by Tobias Burnus + +program foo + implicit none (type, external) + + type t + end type t + + type, extends(t) :: t2 + end type t2 + + type(t2) :: x2 + class(t), allocatable :: aa + + call check_intentout_false(allocated(aa), aa, & + allocated(aa)) + if (allocated(aa)) stop 1 + + allocate(t2 :: aa) + if (.not.allocated(aa)) stop 2 + if (.not.same_type_as(aa, x2)) stop 3 + call check_intentout_true(allocated(aa), (same_type_as(aa, x2)), aa, & + allocated(aa), (same_type_as(aa, x2))) + if (allocated(aa)) stop 4 + +contains + subroutine check_intentout_false(alloc1, yy, alloc2) + logical, value :: alloc1, alloc2 + class(t), allocatable, intent(out) :: yy + if (allocated(yy)) stop 11 + if (alloc1) stop 12 + if (alloc2) stop 13 + end subroutine check_intentout_false + subroutine check_intentout_true(alloc1, same1, zz, alloc2, same2) + logical, value :: alloc1, alloc2, same1, same2 + class(t), allocatable, intent(out) :: zz + if (allocated(zz)) stop 21 + if (.not.alloc1) stop 22 + if (.not.alloc2) stop 23 + if (.not.same1) stop 24 + if (.not.same2) stop 25 + end subroutine check_intentout_true +end program diff --git a/gcc/testsuite/gfortran.dg/intent_out_18.f90 b/gcc/testsuite/gfortran.dg/intent_out_18.f90 new file mode 100644 index 0000000..50f9948 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intent_out_18.f90 @@ -0,0 +1,31 @@ +! { dg-do run } +! +! PR fortran/92178 +! Contributed by Mikael Morin + +program p + implicit none + type t + integer :: i + integer, pointer :: pi + end type t + integer, target :: j + type(t), allocatable :: ta + j = 1 + ta = t(2, j) + call assign(ta, id(ta%pi)) + if (ta%i /= 1) stop 1 + if (associated(ta%pi)) stop 2 +contains + subroutine assign(a, b) + type(t), intent(out), allocatable :: a + integer, intent(in) , value :: b + allocate(a) + a%i = b + a%pi => null() + end subroutine assign + function id(a) + integer, pointer :: id, a + id => a + end function id +end program p -- cgit v1.1 From 15bbf1826a01f5beb2d7c0f74d6270bbc94ece91 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 8 Jul 2023 17:38:09 +0200 Subject: Fix tree-ssa/update-cunroll.c In this testcase the profile is misupdated before loop has two exits. The first exit is one eliminated by complete unrolling while second exit remains. We remove first exit but forget about fact that the source BB of other exit will then have higher frequency making other exit more likely. This patch fixes that in duplicate_loop_body_to_header_edge. While looking into resulting profiles I also noticed that in some cases scale_loop_profile may drop probabilities to 0 incorrectly either when trying to update exit from nested loop (which has similar problem) or when the profile was inconsistent as described in coment bellow. gcc/ChangeLog: PR middle-end/110590 * cfgloopmanip.cc (scale_loop_profile): Avoid scaling exits within inner loops and be more careful about inconsistent profiles. (duplicate_loop_body_to_header_edge): Fix profile update when eliminated exit is followed by other exit. gcc/testsuite/ChangeLog: PR middle-end/110590 * gcc.dg/tree-prof/update-cunroll-2.c: Remove xfail. * gcc.dg/tree-ssa/update-cunroll.c: Likewise. --- gcc/cfgloopmanip.cc | 57 +++++++++++++++++++++-- gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c | 2 +- 3 files changed, 54 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index f56a9b8..5273242 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -580,13 +580,47 @@ scale_loop_profile (class loop *loop, profile_probability p, unadjusted_exit_count = exit_edge->count (); scale_loop_frequencies (loop, scale_prob); - if (exit_edge) + if (exit_edge && exit_edge->src->loop_father != loop) + { + fprintf (dump_file, + ";; Loop exit is in inner loop;" + " will leave exit probabilities inconsistent\n"); + } + else if (exit_edge) { profile_count old_exit_count = exit_edge->count (); profile_probability new_probability; if (iteration_bound > 0) - new_probability - = unadjusted_exit_count.probability_in (exit_edge->src->count); + { + /* It may happen that the source basic block of the exit edge is + inside in-loop condition: + + +-> header + | | + | B1 + | / \ + | | B2--exit_edge--> + | \ / + | B3 + +__/ + + If B2 count is smaller than desired exit edge count + the profile was inconsistent with the newly discovered upper bound. + Probablity of edge B1->B2 is too low. We do not attempt to fix + that (as it is hard in general) but we want to avoid dropping + count of edge B2->B3 to zero may confuse later optimizations. */ + if (unadjusted_exit_count.apply_scale (7, 8) > exit_edge->src->count) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + ";; Source basic block of loop exit count is too small;" + " will leave exit probabilities inconsistent\n"); + exit_edge->probability = exit_edge->probability.guessed (); + return; + } + new_probability + = unadjusted_exit_count.probability_in (exit_edge->src->count); + } else new_probability = profile_probability::always (); set_edge_probability_and_rescale_others (exit_edge, new_probability); @@ -1146,8 +1180,7 @@ duplicate_loop_body_to_header_edge (class loop *loop, edge e, profile_count count_le = latch_edge->count (); profile_count count_out_orig = orig ? orig->count () : count_in - count_le; profile_probability prob_pass_thru = count_le.probability_in (count_in); - profile_probability prob_pass_wont_exit = - (count_le + count_out_orig).probability_in (count_in); + profile_count new_count_le = count_le + count_out_orig; if (orig && orig->probability.initialized_p () && !(orig->probability == profile_probability::always ())) @@ -1167,7 +1200,21 @@ duplicate_loop_body_to_header_edge (class loop *loop, edge e, && dominated_by_p (CDI_DOMINATORS, bbs[i], orig->src)) bitmap_set_bit (bbs_to_scale, i); } + /* Since we will scale up all basic blocks dominated by orig, exits + will become more likely; compensate for that. */ + if (after_exit_den.nonzero_p ()) + { + auto_vec exits = get_loop_exit_edges (loop); + for (edge ex : exits) + if (ex != orig + && dominated_by_p (CDI_DOMINATORS, ex->src, orig->src)) + new_count_le -= ex->count ().apply_scale (after_exit_num + - after_exit_den, + after_exit_den); + } } + profile_probability prob_pass_wont_exit = + new_count_le.probability_in (count_in); scale_step = XNEWVEC (profile_probability, ndupl); diff --git a/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c b/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c index 8ef3ab2..58c0fb5 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c +++ b/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c @@ -18,4 +18,4 @@ main () t (); return 0; } -/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized" {xfail *-*-*} } } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c b/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c index 5820423..687fe15 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c @@ -11,4 +11,4 @@ int t() } /* Currently duplicate_loop_body_to_header_edge gets wrong computation of prob_pass_wont_exit which assumes that the exit condition is last in the loop. */ -/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized" { xfail *-*-*}} } */ +/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized" } } */ -- cgit v1.1 From 9a2eab6172a8067e2f63e0fa2bcd5b2190656303 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Sat, 8 Jul 2023 18:13:23 +0100 Subject: Fortran: Fix default type bugs in gfortran [PR99139, PR99368] 2023-07-08 Steve Kargl gcc/fortran PR fortran/99139 PR fortran/99368 * match.cc (gfc_match_namelist): Check for host associated or defined types before applying default type. (gfc_match_select_rank): Apply default type to selector of unknown type if possible. * resolve.cc (resolve_fl_variable): Do not apply local default initialization to assumed rank entities. gcc/testsuite/ PR fortran/99139 * gfortran.dg/pr99139.f90 : New test PR fortran/99368 * gfortran.dg/pr99368.f90 : New test --- gcc/fortran/match.cc | 41 +++++++++++++++++++++++++++++++---- gcc/fortran/resolve.cc | 3 ++- gcc/testsuite/gfortran.dg/pr99139.f90 | 24 ++++++++++++++++++++ gcc/testsuite/gfortran.dg/pr99368.f90 | 17 +++++++++++++++ 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr99139.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr99368.f90 (limited to 'gcc') diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc index ca64e59..7335d98 100644 --- a/gcc/fortran/match.cc +++ b/gcc/fortran/match.cc @@ -5622,10 +5622,31 @@ gfc_match_namelist (void) gfc_error_check (); } else - /* If the type is not set already, we set it here to the - implicit default type. It is not allowed to set it - later to any other type. */ - gfc_set_default_type (sym, 0, gfc_current_ns); + { + /* Before the symbol is given an implicit type, check to + see if the symbol is already available in the namespace, + possibly through host association. Importantly, the + symbol may be a user defined type. */ + + gfc_symbol *tmp; + + gfc_find_symbol (sym->name, NULL, 1, &tmp); + if (tmp && tmp->attr.generic + && (tmp = gfc_find_dt_in_generic (tmp))) + { + if (tmp->attr.flavor == FL_DERIVED) + { + gfc_error ("Derived type %qs at %L conflicts with " + "namelist object %qs at %C", + tmp->name, &tmp->declared_at, sym->name); + goto error; + } + } + + /* Set type of the symbol to its implicit default type. It is + not allowed to set it later to any other type. */ + gfc_set_default_type (sym, 0, gfc_current_ns); + } } if (sym->attr.in_namelist == 0 && !gfc_add_in_namelist (&sym->attr, sym->name, NULL)) @@ -6805,8 +6826,20 @@ gfc_match_select_rank (void) gfc_current_ns = gfc_build_block_ns (ns); m = gfc_match (" %n => %e", name, &expr2); + if (m == MATCH_YES) { + /* If expr2 corresponds to an implicitly typed variable, then the + actual type of the variable may not have been set. Set it here. */ + if (!gfc_current_ns->seen_implicit_none + && expr2->expr_type == EXPR_VARIABLE + && expr2->ts.type == BT_UNKNOWN + && expr2->symtree && expr2->symtree->n.sym) + { + gfc_set_default_type (expr2->symtree->n.sym, 0, gfc_current_ns); + expr2->ts.type = expr2->symtree->n.sym->ts.type; + } + expr1 = gfc_get_expr (); expr1->expr_type = EXPR_VARIABLE; expr1->where = expr2->where; diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 8e018b6..f7cfdfc 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -13510,7 +13510,8 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag) } } - if (sym->value == NULL && sym->attr.referenced) + if (sym->value == NULL && sym->attr.referenced + && !(sym->as && sym->as->type == AS_ASSUMED_RANK)) apply_default_init_local (sym); /* Try to apply a default initialization. */ /* Determine if the symbol may not have an initializer. */ diff --git a/gcc/testsuite/gfortran.dg/pr99139.f90 b/gcc/testsuite/gfortran.dg/pr99139.f90 new file mode 100644 index 0000000..a064103 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr99139.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-options "-finit-local-zero" } +! +! Contributed by Gerhard Steinmetz +! +! Original implicitly typed 'x' gave a bad symbol ICE +subroutine s1(x) + target :: x(..) + select rank (y => x) + rank (1) + rank (2) + end select +end + +! Comment #2: Failed with above option +subroutine s2(x, z) + real, target :: x(..) + real :: z(10) + select rank (y => x) ! Error was:Assumed-rank variable y at (1) may only be + ! used as actual argument + rank (1) + rank (2) + end select +end diff --git a/gcc/testsuite/gfortran.dg/pr99368.f90 b/gcc/testsuite/gfortran.dg/pr99368.f90 new file mode 100644 index 0000000..9ba0425 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr99368.f90 @@ -0,0 +1,17 @@ +! { dg-do compile } +! +! Contributed by Gerhard Steinmetz +! +program p + type y ! { dg-error "Derived type" } + end type +contains + subroutine s1 + namelist /x/ y ! { dg-error "conflicts with namelist object" } + character(3) y + end + subroutine s2 + namelist /z/ y ! { dg-error "conflicts with namelist object" } + character(3) y + end +end \ No newline at end of file -- cgit v1.1 From 3a42c79c258f54f5837d2fd54874f8b291a518fc Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 8 Jul 2023 23:47:38 +0200 Subject: Add missing profile_dump check gcc/ChangeLog: PR tree-optimization/110600 * cfgloopmanip.cc (scale_loop_profile): Add mising profile_dump check. gcc/testsuite/ChangeLog: PR tree-optimization/110600 * gcc.c-torture/compile/pr110600.c: New test. --- gcc/cfgloopmanip.cc | 7 ++++--- gcc/testsuite/gcc.c-torture/compile/pr110600.c | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr110600.c (limited to 'gcc') diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 5273242..5c0065b 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -582,9 +582,10 @@ scale_loop_profile (class loop *loop, profile_probability p, if (exit_edge && exit_edge->src->loop_father != loop) { - fprintf (dump_file, - ";; Loop exit is in inner loop;" - " will leave exit probabilities inconsistent\n"); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + ";; Loop exit is in inner loop;" + " will leave exit probabilities inconsistent\n"); } else if (exit_edge) { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr110600.c b/gcc/testsuite/gcc.c-torture/compile/pr110600.c new file mode 100644 index 0000000..4b126f7 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr110600.c @@ -0,0 +1,6 @@ +int a(int b, int c) { return (b ^ c) < 0 ? b : b - c; } +int main() { + for (int e = 0; e != -1; e = a(e, 1)) + ; + return 0; +} -- cgit v1.1 From 95b712928b479f7a65910cf1c550ed67b8976617 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 9 Jul 2023 00:17:17 +0000 Subject: Daily bump. --- gcc/ChangeLog | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/fortran/ChangeLog | 26 +++++++++++++++++ gcc/testsuite/ChangeLog | 31 ++++++++++++++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a9a2f9e..73ec6c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,78 @@ +2023-07-08 Jan Hubicka + + PR tree-optimization/110600 + * cfgloopmanip.cc (scale_loop_profile): Add mising profile_dump check. + +2023-07-08 Jan Hubicka + + PR middle-end/110590 + * cfgloopmanip.cc (scale_loop_profile): Avoid scaling exits within + inner loops and be more careful about inconsistent profiles. + (duplicate_loop_body_to_header_edge): Fix profile update when eliminated + exit is followed by other exit. + +2023-07-08 Uros Bizjak + + * cprop.cc (reg_available_p): Change return type from int to bool. + (reg_not_set_p): Ditto. + (try_replace_reg): Ditto. Change "success" variable to bool. + (cprop_jump): Change return type from int to void + and adjust function body accordingly. + (constprop_register): Ditto. + (cprop_insn): Ditto. Change "changed" variable to bool. + (local_cprop_pass): Change return type from int to void + and adjust function body accordingly. + (bypass_block): Ditto. Change "change", "may_be_loop_header" + and "removed_p" variables to bool. + (bypass_conditional_jumps): Change return type from int to void + and adjust function body accordingly. Change "changed" + variable to bool. + (one_cprop_pass): Ditto. + +2023-07-08 Uros Bizjak + + * gcse.cc (expr_equiv_p): Change return type from int to bool. + (oprs_unchanged_p): Change return type from int to void + and adjust function body accordingly. + (oprs_anticipatable_p): Ditto. + (oprs_available_p): Ditto. + (insert_expr_in_table): Ditto. Change "antic_p" and "avail_p" + arguments to bool. Change "found" variable to bool. + (load_killed_in_block_p): Change return type from int to void and + adjust function body accordingly. Change "avail_p" argument to bool. + (pre_expr_reaches_here_p): Change return type from int to void + and adjust function body accordingly. + (pre_delete): Ditto. Change "changed" variable to bool. + (pre_gcse): Change return type from int to void + and adjust function body accordingly. Change "did_insert" and + "changed" variables to bool. + (one_pre_gcse_pass): Change return type from int to void + and adjust function body accordingly. Change "changed" variable + to bool. + (should_hoist_expr_to_dom): Change return type from int to void + and adjust function body accordingly. Change + "visited_allocated_locally" variable to bool. + (hoist_code): Change return type from int to void and adjust + function body accordingly. Change "changed" variable to bool. + (one_code_hoisting_pass): Ditto. + (pre_edge_insert): Change return type from int to void and adjust + function body accordingly. Change "did_insert" variable to bool. + (pre_expr_reaches_here_p_work): Change return type from int to void + and adjust function body accordingly. + (simple_mem): Ditto. + (want_to_gcse_p): Change return type from int to void + and adjust function body accordingly. + (can_assign_to_reg_without_clobbers_p): Update function body + for bool return type. + (hash_scan_set): Change "antic_p" and "avail_p" variables to bool. + (pre_insert_copies): Change "added_copy" variable to bool. + +2023-07-08 Jonathan Wakely + + PR c++/110595 + PR c++/110596 + * doc/invoke.texi (Warning Options): Fix typos. + 2023-07-07 Jan Hubicka * profile-count.cc (profile_count::dump): Add FUN diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index f3144f1..6ca206c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230708 +20230709 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ed322a9..b6a902a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,29 @@ +2023-07-08 Steve Kargl + + PR fortran/99139 + PR fortran/99368 + * match.cc (gfc_match_namelist): Check for host associated or + defined types before applying default type. + (gfc_match_select_rank): Apply default type to selector of + unknown type if possible. + * resolve.cc (resolve_fl_variable): Do not apply local default + initialization to assumed rank entities. + +2023-07-08 Harald Anlauf + Steven G. Kargl + + PR fortran/92178 + * trans-expr.cc (gfc_conv_procedure_call): Check procedures for + allocatable dummy arguments with INTENT(OUT) and move deallocation + of actual arguments after evaluation of argument expressions before + the procedure is executed. + +2023-07-08 Harald Anlauf + + PR fortran/110585 + * arith.cc (gfc_compare_expr): Handle equality comparison of constant + complex gfc_expr arguments. + 2023-07-05 Robin Dapp Juzhe-Zhong diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b398ab2..3fe5639 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,34 @@ +2023-07-08 Jan Hubicka + + PR tree-optimization/110600 + * gcc.c-torture/compile/pr110600.c: New test. + +2023-07-08 Steve Kargl + + PR fortran/99139 + PR fortran/99368 + * gfortran.dg/pr99139.f90 : New test + * gfortran.dg/pr99368.f90 : New test + +2023-07-08 Jan Hubicka + + PR middle-end/110590 + * gcc.dg/tree-prof/update-cunroll-2.c: Remove xfail. + * gcc.dg/tree-ssa/update-cunroll.c: Likewise. + +2023-07-08 Harald Anlauf + Steven G. Kargl + + PR fortran/92178 + * gfortran.dg/intent_out_16.f90: New test. + * gfortran.dg/intent_out_17.f90: New test. + * gfortran.dg/intent_out_18.f90: New test. + +2023-07-08 Harald Anlauf + + PR fortran/110585 + * gfortran.dg/findloc_9.f90: New test. + 2023-07-07 Jan Hubicka * gcc.dg/pr43864-2.c: Avoid matching pre dump with details-blocks. -- cgit v1.1 From d6c1d7c4009bfe759719675ce3bc03ca503b9bf4 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 9 Jul 2023 15:14:54 +0200 Subject: Improve dumping of profile_count Dumps of profile_counts are quite hard to interpret since they are 64bit fixed point values. In many cases one looks at a single function and it is better to think of basic block frequency, that is how many times it is executed each invocatoin. This patch makes CFG dumps to also print this info. For example: main() { for (int i = 0; i < 10; i++) t(); } the -fdump-tree-optimized-blocks-details now prints: int main () { unsigned int ivtmp_1; unsigned int ivtmp_2; ;; basic block 2, loop depth 0, count 97603128 (estimated locally, freq 1.0000), maybe hot ;; prev block 0, next block 3, flags: (NEW, VISITED) ;; pred: ENTRY [always] count:97603128 (estimated locally, freq 1.0000) (FALLTHRU,EXECUTABLE) ;; succ: 3 [always] count:97603128 (estimated locally, freq 1.0000) (FALLTHRU,EXECUTABLE) ;; basic block 3, loop depth 1, count 976138697 (estimated locally, freq 10.0011), maybe hot ;; prev block 2, next block 4, flags: (NEW, VISITED) ;; pred: 3 [90.0% (guessed)] count:878535568 (estimated locally, freq 9.0011) (TRUE_VALUE,EXECUTABLE) ;; 2 [always] count:97603128 (estimated locally, freq 1.0000) (FALLTHRU,EXECUTABLE) # ivtmp_2 = PHI t (); ivtmp_1 = ivtmp_2 + 4294967295; if (ivtmp_1 != 0) goto ; [90.00%] else goto ; [10.00%] ;; succ: 3 [90.0% (guessed)] count:878535568 (estimated locally, freq 9.0011) (TRUE_VALUE,EXECUTABLE) ;; 4 [10.0% (guessed)] count:97603129 (estimated locally, freq 1.0000) (FALSE_VALUE,EXECUTABLE) ;; basic block 4, loop depth 0, count 97603128 (estimated locally, freq 1.0000), maybe hot ;; prev block 3, next block 1, flags: (NEW, VISITED) ;; pred: 3 [10.0% (guessed)] count:97603129 (estimated locally, freq 1.0000) (FALSE_VALUE,EXECUTABLE) return 0; ;; succ: EXIT [always] count:97603128 (estimated locally, freq 1.0000) (EXECUTABLE) } Which makes it easier to see that the inner bb is executed 10 times per invocation gcc/ChangeLog: * cfg.cc (check_bb_profile): Dump counts with relative frequency. (dump_edge_info): Likewise. (dump_bb_info): Likewise. * profile-count.cc (profile_count::dump): Add comma between quality and freq. gcc/testsuite/ChangeLog: * gcc.dg/predict-22.c: Update template. --- gcc/cfg.cc | 8 ++++---- gcc/profile-count.cc | 2 +- gcc/testsuite/gcc.dg/predict-22.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/cfg.cc b/gcc/cfg.cc index 740d4f3..0de6d6b 100644 --- a/gcc/cfg.cc +++ b/gcc/cfg.cc @@ -475,9 +475,9 @@ check_bb_profile (basic_block bb, FILE * file, int indent) { fprintf (file, ";; %sInvalid sum of incoming counts ", s_indent); - sum.dump (file); + sum.dump (file, fun); fprintf (file, ", should be "); - bb->count.dump (file); + bb->count.dump (file, fun); fprintf (file, "\n"); } } @@ -525,7 +525,7 @@ dump_edge_info (FILE *file, edge e, dump_flags_t flags, int do_succ) if (e->count ().initialized_p () && do_details) { fputs (" count:", file); - e->count ().dump (file); + e->count ().dump (file, cfun); } if (e->flags && do_details) @@ -808,7 +808,7 @@ dump_bb_info (FILE *outf, basic_block bb, int indent, dump_flags_t flags, if (bb->count.initialized_p ()) { fputs (", count ", outf); - bb->count.dump (outf); + bb->count.dump (outf, cfun); } if (maybe_hot_bb_p (fun, bb)) fputs (", maybe hot", outf); diff --git a/gcc/profile-count.cc b/gcc/profile-count.cc index 6bf9700..2c07ebc 100644 --- a/gcc/profile-count.cc +++ b/gcc/profile-count.cc @@ -94,7 +94,7 @@ profile_count::dump (char *buffer, struct function *fun) const else if (fun && initialized_p () && fun->cfg && ENTRY_BLOCK_PTR_FOR_FN (fun)->count.initialized_p ()) - sprintf (buffer, "%" PRId64 " (%s freq %.4f)", m_val, + sprintf (buffer, "%" PRId64 " (%s, freq %.4f)", m_val, profile_quality_display_names[m_quality], to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (fun)->count).to_double ()); else diff --git a/gcc/testsuite/gcc.dg/predict-22.c b/gcc/testsuite/gcc.dg/predict-22.c index f14c2b6..1aed03f 100644 --- a/gcc/testsuite/gcc.dg/predict-22.c +++ b/gcc/testsuite/gcc.dg/predict-22.c @@ -55,5 +55,5 @@ foo (int x, int y, int z) baz (&f); } /* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "count 0 .precise.," 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "count 0 .precise" 1 "optimized"} } */ /* { dg-final { scan-rtl-dump-times "COLD_PARTITION" 1 "bbpart"} } */ -- cgit v1.1 From 3b007164b3ef114c3c86c42ca2455f8f2696fb0d Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sun, 9 Jul 2023 22:08:36 +0200 Subject: d: Merge upstream dmd, druntime 28a3b24c2e, phobos 8ab95ded5. D front-end changes: - Import dmd v2.104.0-beta.1. - Better error message when attribute inference fails down the call stack. - Using `;' as an empty statement has been turned into an error. - Using `in' parameters with non- `extern(D)' or `extern(C++)' functions is deprecated. - `in ref' on parameters has been deprecated in favor of `-preview=in'. - Throwing `immutable', `const', `inout', and `shared' qualified objects is now deprecated. - User Defined Attributes now parse Template Arguments. D runtime changes: - Import druntime v2.104.0-beta.1. Phobos changes: - Import phobos v2.104.0-beta.1. - Better static assert messages when instantiating `std.algorithm.comparison.clamp' with wrong inputs. - `std.typecons.Rebindable' now supports all types. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 28a3b24c2e. * dmd/VERSION: Bump version to v2.104.0-beta.1. * d-codegen.cc (build_bounds_slice_condition): Update for new front-end interface. * d-lang.cc (d_init_options): Likewise. (d_handle_option): Likewise. (d_post_options): Initialize global.compileEnv. * expr.cc (ExprVisitor::visit (CatExp *)): Replace code generation with new front-end lowering. (ExprVisitor::visit (LoweredAssignExp *)): New method. (ExprVisitor::visit (StructLiteralExp *)): Don't generate static initializer symbols for structs defined in C sources. * runtime.def (ARRAYCATT): Remove. (ARRAYCATNTX): Remove. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 28a3b24c2e. * src/MERGE: Merge upstream phobos 8ab95ded5. gcc/testsuite/ChangeLog: * gdc.dg/rtti1.d: Move array concat testcase to ... * gdc.dg/nogc1.d: ... here. New test. --- gcc/d/d-codegen.cc | 4 +- gcc/d/d-lang.cc | 12 +- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/README.md | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/aliasthis.d | 24 +- gcc/d/dmd/apply.d | 2 +- gcc/d/dmd/astenums.d | 25 +- gcc/d/dmd/attrib.d | 27 +- gcc/d/dmd/attrib.h | 4 +- gcc/d/dmd/blockexit.d | 110 ++- gcc/d/dmd/canthrow.d | 13 +- gcc/d/dmd/clone.d | 7 +- gcc/d/dmd/common/string.d | 34 +- gcc/d/dmd/constfold.d | 2 +- gcc/d/dmd/cparse.d | 462 +++++++++-- gcc/d/dmd/cppmangle.d | 151 ++-- gcc/d/dmd/ctfeexpr.d | 12 +- gcc/d/dmd/dcast.d | 4 +- gcc/d/dmd/declaration.d | 18 +- gcc/d/dmd/declaration.h | 7 + gcc/d/dmd/dinterpret.d | 648 ++++++++------- gcc/d/dmd/dmodule.d | 39 +- gcc/d/dmd/doc.d | 2 +- gcc/d/dmd/dscope.d | 10 + gcc/d/dmd/dstruct.d | 16 +- gcc/d/dmd/dsymbol.d | 2 +- gcc/d/dmd/dsymbol.h | 2 +- gcc/d/dmd/dsymbolsem.d | 157 +++- gcc/d/dmd/dtemplate.d | 120 +-- gcc/d/dmd/dtoh.d | 4 +- gcc/d/dmd/errors.d | 8 + gcc/d/dmd/errorsink.d | 20 + gcc/d/dmd/escape.d | 2 +- gcc/d/dmd/expression.d | 512 ++++++++---- gcc/d/dmd/expression.h | 58 +- gcc/d/dmd/expressionsem.d | 345 +++++--- gcc/d/dmd/foreachvar.d | 2 +- gcc/d/dmd/func.d | 140 +++- gcc/d/dmd/globals.d | 74 +- gcc/d/dmd/globals.h | 17 +- gcc/d/dmd/hdrgen.d | 268 +++---- gcc/d/dmd/iasm.d | 19 + gcc/d/dmd/iasmgcc.d | 9 +- gcc/d/dmd/id.d | 15 + gcc/d/dmd/init.d | 84 +- gcc/d/dmd/initsem.d | 35 +- gcc/d/dmd/json.d | 10 +- gcc/d/dmd/lexer.d | 145 ++-- gcc/d/dmd/mtype.d | 146 +++- gcc/d/dmd/nogc.d | 6 +- gcc/d/dmd/ob.d | 2 +- gcc/d/dmd/opover.d | 65 +- gcc/d/dmd/optimize.d | 2 +- gcc/d/dmd/parse.d | 226 +++--- gcc/d/dmd/parsetimevisitor.d | 4 +- gcc/d/dmd/printast.d | 19 + gcc/d/dmd/semantic3.d | 2 +- gcc/d/dmd/sideeffect.d | 1 + gcc/d/dmd/statement.d | 125 ++- gcc/d/dmd/statement.h | 8 +- gcc/d/dmd/statementsem.d | 884 +++++++++++---------- gcc/d/dmd/tokens.d | 16 +- gcc/d/dmd/tokens.h | 10 +- gcc/d/dmd/traits.d | 235 +++--- gcc/d/dmd/transitivevisitor.d | 6 +- gcc/d/dmd/typesem.d | 154 +++- gcc/d/dmd/typinf.d | 1 + gcc/d/dmd/visitor.d | 9 +- gcc/d/dmd/visitor.h | 10 +- gcc/d/expr.cc | 91 +-- gcc/d/runtime.def | 7 - gcc/testsuite/gdc.dg/nogc1.d | 8 + gcc/testsuite/gdc.dg/rtti1.d | 5 - .../compilable/dtoh_CPPNamespaceDeclaration.d | 4 +- gcc/testsuite/gdc.test/compilable/dtoh_functions.d | 2 +- .../gdc.test/compilable/dtoh_invalid_identifiers.d | 2 +- .../gdc.test/compilable/dtoh_special_enum.d | 20 +- gcc/testsuite/gdc.test/compilable/imports/c23789.i | 31 + gcc/testsuite/gdc.test/compilable/interpret3.d | 4 +- gcc/testsuite/gdc.test/compilable/test18493.d | 19 + gcc/testsuite/gdc.test/compilable/test19688.d | 13 + gcc/testsuite/gdc.test/compilable/test21667.d | 19 + gcc/testsuite/gdc.test/compilable/test23789.d | 12 + gcc/testsuite/gdc.test/compilable/test23862.d | 15 + gcc/testsuite/gdc.test/compilable/test23863.d | 15 + .../compilable/traits_getFunctionAttributes.d | 14 +- .../gdc.test/compilable/user_defined_attributes.d | 22 + gcc/testsuite/gdc.test/compilable/warn3882.d | 4 +- .../fail_compilation/attributediagnostic.d | 6 +- .../fail_compilation/attributediagnostic_nogc.d | 56 ++ .../fail_compilation/attributediagnostic_nothrow.d | 45 ++ .../fail_compilation/attributediagnostic_pure.d | 21 + gcc/testsuite/gdc.test/fail_compilation/bug9631.d | 8 +- .../gdc.test/fail_compilation/ctfeblock.d | 13 +- .../gdc.test/fail_compilation/deprecatedinref.d | 10 + .../fail_compilation/deprecations_preview_in.d | 11 + .../gdc.test/fail_compilation/diag10319.d | 26 +- .../gdc.test/fail_compilation/diag10415.d | 2 +- .../gdc.test/fail_compilation/diag11769.d | 4 +- .../gdc.test/fail_compilation/diag14818.d | 4 +- .../gdc.test/fail_compilation/diag20268.d | 12 + .../gdc.test/fail_compilation/diag8101b.d | 12 +- gcc/testsuite/gdc.test/fail_compilation/diag9312.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/diag9620.d | 6 +- gcc/testsuite/gdc.test/fail_compilation/diag9831.d | 2 +- .../fail_compilation/dip1000_deprecation.d | 4 +- .../gdc.test/fail_compilation/dtor_attributes.d | 2 - .../fail_compilation/dtorfields_attributes.d | 1 - .../gdc.test/fail_compilation/fail10968.d | 9 + .../gdc.test/fail_compilation/fail11375.d | 5 +- .../gdc.test/fail_compilation/fail12236.d | 2 +- .../gdc.test/fail_compilation/fail13120.d | 2 +- .../gdc.test/fail_compilation/fail13577.d | 28 + .../gdc.test/fail_compilation/fail16600.d | 4 +- .../gdc.test/fail_compilation/fail17518.d | 4 +- .../gdc.test/fail_compilation/fail17955.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail196.d | 18 +- .../gdc.test/fail_compilation/fail19948.d | 2 +- .../gdc.test/fail_compilation/fail20609.d | 2 +- .../gdc.test/fail_compilation/fail22202.d | 2 +- .../gdc.test/fail_compilation/fail23773.d | 15 + .../gdc.test/fail_compilation/fail23822.d | 22 + .../gdc.test/fail_compilation/fail23826.d | 24 + .../gdc.test/fail_compilation/fail23861.d | 25 + gcc/testsuite/gdc.test/fail_compilation/fail332.d | 16 +- .../gdc.test/fail_compilation/fail4375q.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail4559.d | 8 +- .../gdc.test/fail_compilation/fail_typeof.d | 21 +- gcc/testsuite/gdc.test/fail_compilation/ice10651.d | 21 +- gcc/testsuite/gdc.test/fail_compilation/ice11626.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice11982.d | 17 +- gcc/testsuite/gdc.test/fail_compilation/ice13225.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice23097.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice9540.d | 2 +- .../fail_compilation/misc_parser_err_cov1.d | 2 +- .../fail_compilation/named_arguments_parse.d | 4 +- gcc/testsuite/gdc.test/fail_compilation/parseStc.d | 2 +- .../gdc.test/fail_compilation/previewin.d | 8 +- .../gdc.test/fail_compilation/retscope2.d | 4 +- .../gdc.test/fail_compilation/retscope6.d | 2 +- .../fail_compilation/systemvariables_deprecation.d | 2 +- .../gdc.test/fail_compilation/testInference.d | 15 + .../gdc.test/fail_compilation/testrvaluecpctor.d | 2 +- .../gdc.test/fail_compilation/var_func_attr.d | 35 + gcc/testsuite/gdc.test/runnable/eh2.d | 2 +- .../gdc.test/runnable/imports/link11069z.d | 2 +- .../gdc.test/runnable/imports/link13415a.d | 2 +- .../gdc.test/runnable/imports/mainx23837.c | 10 + gcc/testsuite/gdc.test/runnable/mangle.d | 6 - gcc/testsuite/gdc.test/runnable/test19688.d | 13 - gcc/testsuite/gdc.test/runnable/test23837.d | 15 + gcc/testsuite/gdc.test/runnable/test42.d | 2 +- gcc/testsuite/gdc.test/runnable/xtest46.d | 23 +- 154 files changed, 4310 insertions(+), 2272 deletions(-) create mode 100644 gcc/testsuite/gdc.dg/nogc1.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/c23789.i create mode 100644 gcc/testsuite/gdc.test/compilable/test18493.d create mode 100644 gcc/testsuite/gdc.test/compilable/test19688.d create mode 100644 gcc/testsuite/gdc.test/compilable/test21667.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23789.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23862.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23863.d create mode 100644 gcc/testsuite/gdc.test/compilable/user_defined_attributes.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nogc.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nothrow.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_pure.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/deprecatedinref.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/deprecations_preview_in.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/diag20268.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail13577.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23773.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23822.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23826.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23861.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/var_func_attr.d create mode 100644 gcc/testsuite/gdc.test/runnable/imports/mainx23837.c delete mode 100644 gcc/testsuite/gdc.test/runnable/test19688.d create mode 100644 gcc/testsuite/gdc.test/runnable/test23837.d (limited to 'gcc') diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 9bae060..689d1c5 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -1986,14 +1986,14 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length) tree condition = NULL_TREE; /* Enforces that `upper <= length`. */ - if (!se->upperIsInBounds && length != NULL_TREE) + if (!se->upperIsInBounds () && length != NULL_TREE) condition = fold_build2 (GT_EXPR, d_bool_type, upper, length); else length = integer_zero_node; /* Enforces that `lower <= upper`. No need to check `lower <= length` as we've already ensured that `upper <= length`. */ - if (!se->lowerIsLessThanUpper) + if (!se->lowerIsLessThanUpper ()) { tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper); diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 235e22a..7cb86bf 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -293,7 +293,7 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options) /* Set default values. */ global._init (); - global.vendor = lang_hooks.name; + global.compileEnv.vendor = lang_hooks.name; global.params.argv0 = xstrdup (decoded_options[0].arg); global.params.errorLimit = flag_max_errors; @@ -562,7 +562,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.useDIP1021 = value; global.params.bitfields = value; global.params.dtorFields = FeatureState::enabled; - global.params.fieldwise = value; + global.params.fieldwise = FeatureState::enabled; global.params.fixAliasThis = value; global.params.previewIn = value; global.params.fix16997 = value; @@ -594,7 +594,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, break; case OPT_fpreview_fieldwise: - global.params.fieldwise = value; + global.params.fieldwise = FeatureState::enabled; break; case OPT_fpreview_fixaliasthis: @@ -934,6 +934,12 @@ d_post_options (const char ** fn) global.params.obj = !flag_syntax_only; + /* The front-end parser only has access to `compileEnv', synchronize its + fields with params. */ + global.compileEnv.previewIn = global.params.previewIn; + global.compileEnv.ddocOutput = global.params.ddoc.doOutput; + global.compileEnv.shortenedMethods = global.params.shortenedMethods; + /* Add in versions given on the command line. */ if (global.params.versionids) { diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 1205cd9..95ea67d 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -a45f4e9f43e9fdbf0b666175e5e66b1ce4f561f6 +28a3b24c2e45de39cd3df528142fd06b6456e8fd The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/README.md b/gcc/d/dmd/README.md index cecd008..57f56f3 100644 --- a/gcc/d/dmd/README.md +++ b/gcc/d/dmd/README.md @@ -19,7 +19,7 @@ this license for that file. | Folder | Purpose | |--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [dmd/](https://github.com/dlang/dmd/tree/master/compiler/src/dmd) | The dmd driver and front-end | -| [dmd/backend/](https://github.com/dlang/dmd/tree/master/compiler/src/dmd/backend) | Code generation for x86 or x86-64. Shared by the [Digital Mars C compiler](https://github.com/DigitalMars/Compiler/), but not [LDC](https://github.com/ldc-developers/ldc) or [GDC](https://gdcproject.org/). | +| [dmd/backend/](https://github.com/dlang/dmd/tree/master/compiler/src/dmd/backend) | Code generation for x86 or x86-64. Based on [DMC](https://github.com/DigitalMars/Compiler/)'s backend, but not kept in sync anymore. Not used by [LDC](https://github.com/ldc-developers/ldc) or [GDC](https://gdcproject.org/). | | [dmd/common/](https://github.com/dlang/dmd/tree/master/compiler/src/dmd/common) | Code shared by the front-end and back-end | | [dmd/root/](https://github.com/dlang/dmd/tree/master/compiler/src/dmd/root) | Meant as a portable utility library, but ["it wasn't very good and the only project left using it is dmd"](https://github.com/dlang/dmd/pull/9844#issuecomment-498479516). | diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 8316aaf..7cf9127 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.103.1 +v2.104.0-beta.1 diff --git a/gcc/d/dmd/aliasthis.d b/gcc/d/dmd/aliasthis.d index ef839fa..ce38459 100644 --- a/gcc/d/dmd/aliasthis.d +++ b/gcc/d/dmd/aliasthis.d @@ -78,7 +78,7 @@ extern (C++) final class AliasThis : Dsymbol * Params: * sc = context * e = expression forming the `this` - * gag = if true do not print errors, return null instead + * gag = do not print errors, return `null` instead * findOnly = don't do further processing like resolving properties, * i.e. just return plain dotExp() result. * Returns: @@ -93,7 +93,7 @@ Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false, bool find { Loc loc = e.loc; Type tthis = (e.op == EXP.type ? e.type : null); - const flags = DotExpFlag.noAliasThis | (gag ? DotExpFlag.gag : 0); + const flags = cast(DotExpFlag) (DotExpFlag.noAliasThis | (gag * DotExpFlag.gag)); uint olderrors = gag ? global.startGagging() : 0; e = dotExp(ad.type, sc, e, ad.aliasthis.ident, flags); if (!e || findOnly) @@ -200,15 +200,29 @@ bool checkDeprecatedAliasThis(AliasThis at, const ref Loc loc, Scope* sc) /************************************** * Check and set 'att' if 't' is a recursive 'alias this' type + * + * The goal is to prevent endless loops when there is a cycle in the alias this chain. + * Since there is no multiple `alias this`, the chain either ends in a leaf, + * or it loops back on itself as some point. + * + * Example: S0 -> (S1 -> S2 -> S3 -> S1) + * + * `S0` is not a recursive alias this, so this returns `false`, and a rewrite to `S1` can be tried. + * `S1` is a recursive alias this type, but since `att` is initialized to `null`, + * this still returns `false`, but `att1` is set to `S1`. + * A rewrite to `S2` and `S3` can be tried, but when we want to try a rewrite to `S1` again, + * we notice `att == t`, so we're back at the start of the loop, and this returns `true`. + * * Params: - * att = type reference used to detect recursion - * t = 'alias this' type + * att = type reference used to detect recursion. Should be initialized to `null`. + * t = type of 'alias this' rewrite to attempt * * Returns: - * Whether the 'alias this' is recursive or not + * `false` if the rewrite is safe, `true` if it would loop back around */ bool isRecursiveAliasThis(ref Type att, Type t) { + //printf("+isRecursiveAliasThis(att = %s, t = %s)\n", att ? att.toChars() : "null", t.toChars()); auto tb = t.toBasetype(); if (att && tb.equivalent(att)) return true; diff --git a/gcc/d/dmd/apply.d b/gcc/d/dmd/apply.d index 59ba9f5..d18b81f 100644 --- a/gcc/d/dmd/apply.d +++ b/gcc/d/dmd/apply.d @@ -170,7 +170,7 @@ public: { if (e.stageflags & stageApply) return; - int old = e.stageflags; + const old = e.stageflags; e.stageflags |= stageApply; doCond(e.elements.peekSlice()) || applyTo(e); e.stageflags = old; diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d index 6e88208..77f36f3 100644 --- a/gcc/d/dmd/astenums.d +++ b/gcc/d/dmd/astenums.d @@ -214,8 +214,8 @@ enum TY : ubyte Tmixin, Tnoreturn, Ttag, - TMAX } +enum TMAX = TY.max + 1; alias Tarray = TY.Tarray; alias Tsarray = TY.Tsarray; @@ -265,7 +265,6 @@ alias Ttraits = TY.Ttraits; alias Tmixin = TY.Tmixin; alias Tnoreturn = TY.Tnoreturn; alias Ttag = TY.Ttag; -alias TMAX = TY.TMAX; enum TFlags { @@ -328,6 +327,7 @@ enum VarArg : ubyte variadic = 1, /// (T t, ...) can be C-style (core.stdc.stdarg) or D-style (core.vararg) typesafe = 2, /// (T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions /// or https://dlang.org/spec/function.html#typesafe_variadic_functions + KRvariadic = 3, /// K+R C style variadics (no function prototype) } /************************* @@ -339,7 +339,7 @@ enum STMT : ubyte Error, Peel, Exp, DtorExp, - Compile, + Mixin, Compound, CompoundDeclaration, CompoundAsm, UnrolledLoop, Scope, @@ -439,3 +439,22 @@ enum FileType : ubyte ddoc, /// Ddoc documentation file (.dd) c, /// C source file } + +extern (C++) struct structalign_t +{ + private: + ushort value = 0; // unknown + enum STRUCTALIGN_DEFAULT = 1234; // default = match whatever the corresponding C compiler does + bool pack; // use #pragma pack semantics + + public: + pure @safe @nogc nothrow: + bool isDefault() const { return value == STRUCTALIGN_DEFAULT; } + void setDefault() { value = STRUCTALIGN_DEFAULT; } + bool isUnknown() const { return value == 0; } // value is not set + void setUnknown() { value = 0; } + void set(uint value) { this.value = cast(ushort)value; } + uint get() const { return value; } + bool isPack() const { return pack; } + void setPack(bool pack) { this.pack = pack; } +} diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d index dbe78ef..c08382c 100644 --- a/gcc/d/dmd/attrib.d +++ b/gcc/d/dmd/attrib.d @@ -62,6 +62,12 @@ extern (C++) abstract class AttribDeclaration : Dsymbol this.decl = decl; } + extern (D) this(const ref Loc loc, Dsymbols* decl) + { + super(loc, null); + this.decl = decl; + } + extern (D) this(const ref Loc loc, Identifier ident, Dsymbols* decl) { super(loc, ident); @@ -228,6 +234,12 @@ extern (C++) class StorageClassDeclaration : AttribDeclaration this.stc = stc; } + extern (D) this(const ref Loc loc, StorageClass stc, Dsymbols* decl) + { + super(loc, decl); + this.stc = stc; + } + override StorageClassDeclaration syntaxCopy(Dsymbol s) { assert(!s); @@ -1279,7 +1291,8 @@ extern(C++) final class ForwardingAttribDeclaration : AttribDeclaration * mixin("int x"); * https://dlang.org/spec/module.html#mixin-declaration */ -extern (C++) final class CompileDeclaration : AttribDeclaration +// Note: was CompileDeclaration +extern (C++) final class MixinDeclaration : AttribDeclaration { Expressions* exps; ScopeDsymbol scopesym; @@ -1288,19 +1301,19 @@ extern (C++) final class CompileDeclaration : AttribDeclaration extern (D) this(const ref Loc loc, Expressions* exps) { super(loc, null, null); - //printf("CompileDeclaration(loc = %d)\n", loc.linnum); + //printf("MixinDeclaration(loc = %d)\n", loc.linnum); this.exps = exps; } - override CompileDeclaration syntaxCopy(Dsymbol s) + override MixinDeclaration syntaxCopy(Dsymbol s) { - //printf("CompileDeclaration::syntaxCopy('%s')\n", toChars()); - return new CompileDeclaration(loc, Expression.arraySyntaxCopy(exps)); + //printf("MixinDeclaration::syntaxCopy('%s')\n", toChars()); + return new MixinDeclaration(loc, Expression.arraySyntaxCopy(exps)); } override void addMember(Scope* sc, ScopeDsymbol sds) { - //printf("CompileDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\n", sc, sds, memnum); + //printf("MixinDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\n", sc, sds, memnum); this.scopesym = sds; } @@ -1314,7 +1327,7 @@ extern (C++) final class CompileDeclaration : AttribDeclaration return "mixin"; } - override inout(CompileDeclaration) isCompileDeclaration() inout + override inout(MixinDeclaration) isMixinDeclaration() inout { return this; } diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h index 113653e..1e75598 100644 --- a/gcc/d/dmd/attrib.h +++ b/gcc/d/dmd/attrib.h @@ -221,7 +221,7 @@ public: // Mixin declarations -class CompileDeclaration final : public AttribDeclaration +class MixinDeclaration final : public AttribDeclaration { public: Expressions *exps; @@ -229,7 +229,7 @@ public: ScopeDsymbol *scopesym; d_bool compiled; - CompileDeclaration *syntaxCopy(Dsymbol *s) override; + MixinDeclaration *syntaxCopy(Dsymbol *s) override; void addMember(Scope *sc, ScopeDsymbol *sds) override; void setScope(Scope *sc) override; const char *kind() const override; diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d index bd5b78e..db738b4 100644 --- a/gcc/d/dmd/blockexit.d +++ b/gcc/d/dmd/blockexit.d @@ -63,34 +63,21 @@ enum BE : int */ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) { - extern (C++) final class BlockExit : Visitor - { - alias visit = Visitor.visit; - public: - FuncDeclaration func; - bool mustNotThrow; - int result; - - extern (D) this(FuncDeclaration func, bool mustNotThrow) scope - { - this.func = func; - this.mustNotThrow = mustNotThrow; - result = BE.none; - } + int result = BE.none; - override void visit(Statement s) + void visitDefaultCase(Statement s) { printf("Statement::blockExit(%p)\n", s); printf("%s\n", s.toChars()); assert(0); } - override void visit(ErrorStatement s) + void visitError(ErrorStatement s) { result = BE.none; } - override void visit(ExpStatement s) + void visitExp(ExpStatement s) { result = BE.fallthru; if (s.exp) @@ -115,13 +102,18 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) } } - override void visit(CompileStatement s) + void visitDtorExp(DtorExpStatement s) + { + visitExp(s); + } + + void visitMixin(MixinStatement s) { assert(global.errors); result = BE.fallthru; } - override void visit(CompoundStatement cs) + void visitCompound(CompoundStatement cs) { //printf("CompoundStatement.blockExit(%p) %d result = x%X\n", cs, cs.statements.length, result); result = BE.fallthru; @@ -175,7 +167,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) } } - override void visit(UnrolledLoopStatement uls) + void visitUnrolledLoop(UnrolledLoopStatement uls) { result = BE.fallthru; foreach (s; *uls.statements) @@ -190,19 +182,19 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) } } - override void visit(ScopeStatement s) + void visitScope(ScopeStatement s) { //printf("ScopeStatement::blockExit(%p)\n", s.statement); result = blockExit(s.statement, func, mustNotThrow); } - override void visit(WhileStatement s) + void visitWhile(WhileStatement s) { assert(global.errors); result = BE.fallthru; } - override void visit(DoStatement s) + void visitDo(DoStatement s) { if (s._body) { @@ -227,7 +219,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result &= ~(BE.break_ | BE.continue_); } - override void visit(ForStatement s) + void visitFor(ForStatement s) { result = BE.fallthru; if (s._init) @@ -259,7 +251,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result |= canThrow(s.increment, func, mustNotThrow); } - override void visit(ForeachStatement s) + void visitForeach(ForeachStatement s) { result = BE.fallthru; result |= canThrow(s.aggr, func, mustNotThrow); @@ -268,13 +260,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result |= blockExit(s._body, func, mustNotThrow) & ~(BE.break_ | BE.continue_); } - override void visit(ForeachRangeStatement s) + void visitForeachRange(ForeachRangeStatement s) { assert(global.errors); result = BE.fallthru; } - override void visit(IfStatement s) + void visitIf(IfStatement s) { //printf("IfStatement::blockExit(%p)\n", s); result = BE.none; @@ -297,24 +289,24 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) //printf("IfStatement::blockExit(%p) = x%x\n", s, result); } - override void visit(ConditionalStatement s) + void visitConditional(ConditionalStatement s) { result = blockExit(s.ifbody, func, mustNotThrow); if (s.elsebody) result |= blockExit(s.elsebody, func, mustNotThrow); } - override void visit(PragmaStatement s) + void visitPragma(PragmaStatement s) { result = BE.fallthru; } - override void visit(StaticAssertStatement s) + void visitStaticAssert(StaticAssertStatement s) { result = BE.fallthru; } - override void visit(SwitchStatement s) + void visitSwitch(SwitchStatement s) { result = BE.none; result |= canThrow(s.condition, func, mustNotThrow); @@ -332,63 +324,63 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result |= BE.fallthru; } - override void visit(CaseStatement s) + void visitCase(CaseStatement s) { result = blockExit(s.statement, func, mustNotThrow); } - override void visit(DefaultStatement s) + void visitDefault(DefaultStatement s) { result = blockExit(s.statement, func, mustNotThrow); } - override void visit(GotoDefaultStatement s) + void visitGotoDefault(GotoDefaultStatement s) { result = BE.goto_; } - override void visit(GotoCaseStatement s) + void visitGotoCase(GotoCaseStatement s) { result = BE.goto_; } - override void visit(SwitchErrorStatement s) + void visitSwitchError(SwitchErrorStatement s) { // Switch errors are non-recoverable result = BE.halt; } - override void visit(ReturnStatement s) + void visitReturn(ReturnStatement s) { result = BE.return_; if (s.exp) result |= canThrow(s.exp, func, mustNotThrow); } - override void visit(BreakStatement s) + void visitBreak(BreakStatement s) { //printf("BreakStatement::blockExit(%p) = x%x\n", s, s.ident ? BE.goto_ : BE.break_); result = s.ident ? BE.goto_ : BE.break_; } - override void visit(ContinueStatement s) + void visitContinue(ContinueStatement s) { result = s.ident ? BE.continue_ | BE.goto_ : BE.continue_; } - override void visit(SynchronizedStatement s) + void visitSynchronized(SynchronizedStatement s) { result = blockExit(s._body, func, mustNotThrow); } - override void visit(WithStatement s) + void visitWith(WithStatement s) { result = BE.none; result |= canThrow(s.exp, func, mustNotThrow); result |= blockExit(s._body, func, mustNotThrow); } - override void visit(TryCatchStatement s) + void visitTryCatch(TryCatchStatement s) { assert(s._body); result = blockExit(s._body, func, false); @@ -428,7 +420,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result |= catchresult; } - override void visit(TryFinallyStatement s) + void visitTryFinally(TryFinallyStatement s) { result = BE.fallthru; if (s._body) @@ -470,13 +462,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result |= finalresult & ~BE.fallthru; } - override void visit(ScopeGuardStatement s) + void visitScopeGuard(ScopeGuardStatement s) { // At this point, this statement is just an empty placeholder result = BE.fallthru; } - override void visit(ThrowStatement s) + void visitThrow(ThrowStatement s) { if (s.internalThrow) { @@ -486,16 +478,16 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) return; } - result = checkThrow(s.loc, s.exp, mustNotThrow); + result = checkThrow(s.loc, s.exp, mustNotThrow, func); } - override void visit(GotoStatement s) + void visitGoto(GotoStatement s) { //printf("GotoStatement::blockExit(%p)\n", s); result = BE.goto_; } - override void visit(LabelStatement s) + void visitLabel(LabelStatement s) { //printf("LabelStatement::blockExit(%p)\n", s); result = blockExit(s.statement, func, mustNotThrow); @@ -503,30 +495,31 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result |= BE.fallthru; } - override void visit(CompoundAsmStatement s) + void visitCompoundAsm(CompoundAsmStatement s) { // Assume the worst result = BE.fallthru | BE.return_ | BE.goto_ | BE.halt; if (!(s.stc & STC.nothrow_)) { - if (mustNotThrow && !(s.stc & STC.nothrow_)) - s.error("`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); + if(func) + func.setThrow(s.loc, "`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); + if (mustNotThrow) + s.error("`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); // TODO else result |= BE.throw_; } } - override void visit(ImportStatement s) + void visitImport(ImportStatement s) { result = BE.fallthru; } - } if (!s) return BE.fallthru; - scope BlockExit be = new BlockExit(func, mustNotThrow); - s.accept(be); - return be.result; + mixin VisitStatement!void visit; + visit.VisitStatement(s); + return result; } /++ @@ -537,10 +530,11 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) + loc = location of the `throw` + exp = expression yielding the throwable + mustNotThrow = inside of a `nothrow` scope? + + func = function containing the `throw` + + Returns: `BE.[err]throw` depending on the type of `exp` +/ -BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow) +BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow, FuncDeclaration func) { import dmd.errors : error; @@ -554,6 +548,8 @@ BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow) } if (mustNotThrow) loc.error("`%s` is thrown but not caught", exp.type.toChars()); + else if (func) + func.setThrow(loc, "`%s` is thrown but not caught", exp.type); return BE.throw_; } diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d index 0c237e6..7dfec8a 100644 --- a/gcc/d/dmd/canthrow.d +++ b/gcc/d/dmd/canthrow.d @@ -53,7 +53,7 @@ enum CT : BE */ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustNotThrow) { - //printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars()); + //printf("Expression::canThrow(%d) %s\n", mustNotThrow, e.toChars()); // stop walking if we determine this expression can throw extern (C++) final class CanThrow : StoppableVisitor { @@ -76,11 +76,16 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN { if (mustNotThrow) { - e.error("%s `%s` is not `nothrow`", - f.kind(), f.toPrettyChars()); + e.error("%s `%s` is not `nothrow`", f.kind(), f.toPrettyChars()); + if (!f.isDtorDeclaration()) + errorSupplementalInferredAttr(f, 10, false, STC.nothrow_); e.checkOverridenDtor(null, f, dd => dd.type.toTypeFunction().isnothrow, "not nothrow"); } + else if (func) + { + func.setThrowCall(e.loc, f); + } result |= CT.exception; } } @@ -205,7 +210,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN override void visit(ThrowExp te) { - const res = checkThrow(te.loc, te.e1, mustNotThrow); + const res = checkThrow(te.loc, te.e1, mustNotThrow, func); assert((res & ~(CT.exception | CT.error)) == 0); result |= res; } diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 19bf83e..60e373c 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -840,7 +840,7 @@ FuncDeclaration buildXtoHash(StructDeclaration sd, Scope* sc) " else " ~ " h = h * 33 + typeid(T).getHash(cast(const void*)&p.tupleof[i]);" ~ "return h;"; - fop.fbody = new CompileStatement(loc, new StringExp(loc, code)); + fop.fbody = new MixinStatement(loc, new StringExp(loc, code)); Scope* sc2 = sc.push(); sc2.stc = 0; sc2.linkage = LINK.d; @@ -1261,8 +1261,9 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) // if this field's postblit is not `nothrow`, add a `scope(failure)` // block to destroy any prior successfully postblitted fields should - // this field's postblit fail - if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow) + // this field's postblit fail. + // Don't generate it for betterC code since it cannot throw exceptions. + if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow && !global.params.betterC) { // create a list of destructors that need to be called Expression[] dtorCalls; diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/string.d index 1111cec..a1614fd 100644 --- a/gcc/d/dmd/common/string.d +++ b/gcc/d/dmd/common/string.d @@ -13,7 +13,7 @@ module dmd.common.string; nothrow: /** -Defines a temporary array using a fixed-length buffer as back store. If the length +Defines a temporary array of `Element`s using a fixed-length buffer as back store. If the length of the buffer suffices, it is readily used. Otherwise, `malloc` is used to allocate memory for the array and `free` is used for deallocation in the destructor. @@ -21,19 +21,26 @@ destructor. This type is meant to use exclusively as an automatic variable. It is not default constructible or copyable. */ -struct SmallBuffer(T) +struct SmallBuffer(Element) { import core.stdc.stdlib : malloc, free; - private T[] _extent; + private Element[] _extent; private bool needsFree; nothrow: + @nogc: @disable this(); // no default ctor - @disable this(ref const SmallBuffer!T); // noncopyable, nonassignable - - this(size_t len, T[] buffer) + @disable this(ref const SmallBuffer!Element); // noncopyable, nonassignable + + /*********** + * Construct a SmallBuffer + * Params: + * len = number of elements in array + * buffer = slice to use as backing-store, if len will fit in it + */ + scope this(size_t len, return scope Element[] buffer) { if (len <= buffer.length) { @@ -41,7 +48,8 @@ struct SmallBuffer(T) } else { - _extent = (cast(typeof(_extent.ptr)) malloc(len * _extent[0].sizeof))[0 .. len]; + assert(len < sizeof.max / Element.sizeof); + _extent = (cast(typeof(_extent.ptr)) malloc(len * Element.sizeof))[0 .. len]; _extent.ptr || assert(0, "Out of memory."); needsFree = true; } @@ -54,16 +62,22 @@ struct SmallBuffer(T) free(_extent.ptr); } - void create(size_t len) + /****** + * Resize existing SmallBuffer. + * Params: + * len = number of elements after resize + */ + scope void create(size_t len) { if (len <= _extent.length) { - _extent = _extent[0 .. len]; + _extent = _extent[0 .. len]; // reuse existing storage } else { __dtor(); - _extent = (cast(typeof(_extent.ptr)) malloc(len * _extent[0].sizeof))[0 .. len]; + assert(len < sizeof.max / Element.sizeof); + _extent = (cast(typeof(_extent.ptr)) malloc(len * Element.sizeof))[0 .. len]; _extent.ptr || assert(0, "Out of memory."); needsFree = true; } diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d index e4be63c..415606b 100644 --- a/gcc/d/dmd/constfold.d +++ b/gcc/d/dmd/constfold.d @@ -1437,7 +1437,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); StringExp es = ue.exp().isStringExp(); es.type = type; - es.committed = 1; + es.committed = true; } else { diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index a18f810..9b7db1f 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -14,22 +14,18 @@ module dmd.cparse; import core.stdc.stdio; -import core.stdc.string; +import core.stdc.string : memcpy; + import dmd.astenums; import dmd.errorsink; -import dmd.globals; import dmd.id; import dmd.identifier; import dmd.lexer; import dmd.location; import dmd.parse; -import dmd.errors; import dmd.root.array; -import dmd.root.filename; import dmd.common.outbuffer; import dmd.root.rmem; -import dmd.root.rootobject; -import dmd.root.string; import dmd.tokens; /*********************************************************** @@ -71,9 +67,10 @@ final class CParser(AST) : Parser!AST extern (D) this(TARGET)(AST.Module _module, const(char)[] input, bool doDocComment, ErrorSink errorSink, - const ref TARGET target, OutBuffer* defines) scope + const ref TARGET target, OutBuffer* defines, const CompileEnv* compileEnv) scope { - super(_module, input, doDocComment, errorSink); + const bool doUnittests = false; + super(_module, input, doDocComment, errorSink, compileEnv, doUnittests); //printf("CParser.this()\n"); mod = _module; @@ -202,7 +199,7 @@ final class CParser(AST) : Parser!AST else if (token.value == TOK.leftCurly) s = cparseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_); else - s = cparseStatement(ParseStatementFlags.semiOk); + s = cparseStatement(0); s = new AST.LabelStatement(loc, ident, s); break; } @@ -307,6 +304,7 @@ final class CParser(AST) : Parser!AST case TOK.extern_: case TOK.static_: case TOK._Thread_local: + case TOK.__thread: case TOK.auto_: case TOK.register: @@ -376,7 +374,7 @@ final class CParser(AST) : Parser!AST auto statements = new AST.Statements(); while (token.value != TOK.rightCurly && token.value != TOK.endOfFile) { - statements.push(cparseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope)); + statements.push(cparseStatement(ParseStatementFlags.curlyScope)); } if (endPtr) *endPtr = token.ptr; @@ -510,6 +508,14 @@ final class CParser(AST) : Parser!AST nextToken(); auto exp = cparseAssignExp(); + AST.Expression expHigh; + if (token.value == TOK.dotDotDot) + { + /* Case Ranges https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html + */ + nextToken(); + expHigh = cparseAssignExp(); + } check(TOK.colon); if (flags & ParseStatementFlags.curlyScope) @@ -517,7 +523,7 @@ final class CParser(AST) : Parser!AST auto statements = new AST.Statements(); while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly) { - auto cur = cparseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope); + auto cur = cparseStatement(ParseStatementFlags.curlyScope); statements.push(cur); // https://issues.dlang.org/show_bug.cgi?id=21739 @@ -532,10 +538,13 @@ final class CParser(AST) : Parser!AST } else { - s = cparseStatement(ParseStatementFlags.semi); + s = cparseStatement(0); } s = new AST.ScopeStatement(loc, s, token.loc); - s = new AST.CaseStatement(loc, exp, s); + if (expHigh) + s = new AST.CaseRangeStatement(loc, exp, expHigh, s); + else + s = new AST.CaseStatement(loc, exp, s); break; } @@ -549,12 +558,12 @@ final class CParser(AST) : Parser!AST auto statements = new AST.Statements(); while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly) { - statements.push(cparseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope)); + statements.push(cparseStatement(ParseStatementFlags.curlyScope)); } s = new AST.CompoundStatement(loc, statements); } else - s = cparseStatement(ParseStatementFlags.semi); + s = cparseStatement(0); s = new AST.ScopeStatement(loc, s, token.loc); s = new AST.DefaultStatement(loc, s); break; @@ -604,7 +613,20 @@ final class CParser(AST) : Parser!AST } case TOK.asm_: - s = parseAsm(); + switch (peekNext()) + { + case TOK.goto_: + case TOK.inline: + case TOK.volatile: + case TOK.leftParenthesis: + s = cparseGnuAsm(); + break; + + default: + // ImportC extensions: parse as a D asm block. + s = parseAsm(); + break; + } break; default: @@ -777,7 +799,10 @@ final class CParser(AST) : Parser!AST case TOK.leftParenthesis: nextToken(); - e = cparseExpression(); + if (token.value == TOK.leftCurly) + e = cparseStatementExpression(); // gcc extension + else + e = cparseExpression(); check(TOK.rightParenthesis); break; @@ -1600,6 +1625,41 @@ final class CParser(AST) : Parser!AST return e; } + /***************************** + * gcc extension: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html + * Represent as a function literal, then call the function literal. + * Parser is on opening curly brace. + */ + private AST.Expression cparseStatementExpression() + { + AST.ParameterList parameterList; + StorageClass stc = 0; + const loc = token.loc; + typedefTab.push(null); + auto fbody = cparseStatement(ParseStatementFlags.scope_); + typedefTab.pop(); // end of function scope + + // Rewrite last ExpStatement (if there is one) as a ReturnStatement + auto ss = fbody.isScopeStatement(); + auto cs = ss.statement.isCompoundStatement(); + assert(cs); + if (const len = (*cs.statements).length) + { + auto s = (*cs.statements)[len - 1]; + if (auto es = s.isExpStatement()) + (*cs.statements)[len - 1] = new AST.ReturnStatement(es.loc, es.exp); + } + + auto tf = new AST.TypeFunction(parameterList, null, LINK.d, stc); + auto fd = new AST.FuncLiteralDeclaration(loc, token.loc, tf, TOK.delegate_, null, null, 0); + fd.fbody = fbody; + + auto fe = new AST.FuncExp(loc, fd); + auto args = new AST.Expressions(); + auto e = new AST.CallExp(loc, fe, args); // call the function literal + return e; + } + //} /********************************************************************************/ /********************************* Declaration Parser ***************************/ @@ -1660,6 +1720,12 @@ final class CParser(AST) : Parser!AST auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) : (tt.tok == TOK.union_) ? new AST.UnionDeclaration(tt.loc, tt.id) : new AST.EnumDeclaration(tt.loc, tt.id, tt.base); + if (!tt.packalign.isUnknown()) + { + // saw `struct __declspec(align(N)) Tag ...` + auto st = stag.isStructDeclaration(); + st.alignment = tt.packalign; + } stag.members = tt.members; tt.members = null; if (!symbols) @@ -1759,7 +1825,7 @@ final class CParser(AST) : Parser!AST case TOK.asm_: case TOK.__attribute__: if (token.value == TOK.asm_) - asmName = cparseSimpleAsmExpr(); + asmName = cparseGnuAsmLabel(); if (token.value == TOK.__attribute__) { cparseGnuAttributes(specifier); @@ -1892,6 +1958,7 @@ final class CParser(AST) : Parser!AST if (specifier.scw & SCW.x_Thread_local) error("functions cannot be `_Thread_local`"); // C11 6.7.1-4 auto fd = new AST.FuncDeclaration(token.loc, Loc.initial, id, specifiersToSTC(level, specifier), dt, specifier.noreturn); + specifiersToFuncDeclaration(fd, specifier); s = fd; } else @@ -1901,7 +1968,9 @@ final class CParser(AST) : Parser!AST if (!hasInitializer && !(specifier.scw & (SCW.xextern | SCW.xstatic | SCW.x_Thread_local) || level == LVL.global)) initializer = new AST.VoidInitializer(token.loc); - s = new AST.VarDeclaration(token.loc, dt, id, initializer, specifiersToSTC(level, specifier)); + auto vd = new AST.VarDeclaration(token.loc, dt, id, initializer, specifiersToSTC(level, specifier)); + specifiersToVarDeclaration(vd, specifier); + s = vd; } if (level != LVL.global) insertIdToTypedefTab(id); // non-typedef declarations can hide typedefs in outer scopes @@ -2012,8 +2081,7 @@ final class CParser(AST) : Parser!AST auto pl = ft.parameterList; if (pl.varargs != AST.VarArg.none && pl.length) error("function identifier-list cannot end with `...`"); - ft.parameterList.varargs = AST.VarArg.variadic; // but C11 allows extra arguments - importBuiltins = true; // will need __va_list_tag + ft.parameterList.varargs = AST.VarArg.KRvariadic; // but C11 allows extra arguments auto plLength = pl.length; if (symbols.length != plLength) error(token.loc, "%d identifiers does not match %d declarations", cast(int)plLength, cast(int)symbols.length); @@ -2038,6 +2106,10 @@ final class CParser(AST) : Parser!AST error("storage class and type are not allowed in identifier-list"); foreach (s; (*symbols)[]) // yes, quadratic { + auto ad = s.isAttribDeclaration(); + if (ad) + s = (*ad.decl)[0]; // AlignDeclaration wrapping the declaration + auto d = s.isDeclaration(); if (d && p.ident == d.ident && d.type) { @@ -2062,6 +2134,7 @@ final class CParser(AST) : Parser!AST typedefTab.pop(); // end of function scope auto fd = new AST.FuncDeclaration(locFunc, prevloc, id, specifiersToSTC(LVL.global, specifier), ft, specifier.noreturn); + specifiersToFuncDeclaration(fd, specifier); if (addFuncName) { @@ -2234,6 +2307,7 @@ final class CParser(AST) : Parser!AST case TOK.typedef_: scwx = SCW.xtypedef; break; case TOK.inline: scwx = SCW.xinline; break; case TOK._Noreturn: scwx = SCW.x_Noreturn; break; + case TOK.__thread: case TOK._Thread_local: scwx = SCW.x_Thread_local; break; // Type qualifiers @@ -2269,15 +2343,23 @@ final class CParser(AST) : Parser!AST const sloc = token.loc; nextToken(); + Specifier tagSpecifier; + /* GNU Extensions * struct-or-union-specifier: * struct-or-union gnu-attributes (opt) identifier (opt) { struct-declaration-list } gnu-attributes (opt) * struct-or-union gnu-attribute (opt) identifier */ - if (token.value == TOK.__attribute__) - cparseGnuAttributes(specifier); - - t = cparseStruct(sloc, structOrUnion, symbols); + while (1) + { + if (token.value == TOK.__attribute__) + cparseGnuAttributes(tagSpecifier); + else if (token.value == TOK.__declspec) + cparseDeclspec(tagSpecifier); + else + break; + } + t = cparseStruct(sloc, structOrUnion, tagSpecifier.packalign, symbols); tkwx = TKW.xtag; break; } @@ -2298,8 +2380,8 @@ final class CParser(AST) : Parser!AST if (isTypeName(tk) && tk.value == TOK.rightParenthesis) { nextToken(); + nextToken(); t = cparseTypeName(); - // TODO - implement the "atomic" part of t tkwx = TKW.x_Atomic; break; } @@ -2468,6 +2550,12 @@ final class CParser(AST) : Parser!AST error("`inline` and `_Noreturn` function specifiers not allowed for `_Thread_local`"); scw &= ~scwx; } + if (level == LVL.local && + scw & (SCW.x_Thread_local) && !(scw & (SCW.xstatic | SCW.xextern))) + { + error("`_Thread_local` in block scope must be accompanied with `static` or `extern`"); // C11 6.7.1-3 + scw &= ~scwx; + } if (level & (LVL.parameter | LVL.prototype) && scw & ~SCW.xregister) { @@ -2568,6 +2656,7 @@ final class CParser(AST) : Parser!AST } case TKW.xtag: + case TKW.x_Atomic: // no atomics for you break; // t is already set default: @@ -2806,7 +2895,10 @@ final class CParser(AST) : Parser!AST auto parameterList = cparseParameterList(); const lkg = specifier.mod & MOD.x__stdcall ? LINK.windows : linkage; - AST.Type tf = new AST.TypeFunction(parameterList, t, lkg, 0); + StorageClass stc = specifier._nothrow ? STC.nothrow_ : 0; + if (specifier._pure) + stc |= STC.pure_; + AST.Type tf = new AST.TypeFunction(parameterList, t, lkg, stc); // tf = tf.addSTC(storageClass); // TODO insertTx(ts, tf, t); // ts -> ... -> tf -> t @@ -2959,8 +3051,7 @@ final class CParser(AST) : Parser!AST if (token.value == TOK.rightParenthesis) // func() { nextToken(); - importBuiltins = true; // will need __va_list_tag - return AST.ParameterList(parameters, AST.VarArg.variadic, varargsStc); + return AST.ParameterList(parameters, AST.VarArg.KRvariadic, varargsStc); } /* Create function prototype scope @@ -3084,9 +3175,15 @@ final class CParser(AST) : Parser!AST * extended-decl-modifier extended-decl-modifier-seq * * extended-decl-modifier: + * align(number) + * deprecated(depMsg) * dllimport * dllexport + * naked + * noinline * noreturn + * nothrow + * thread * Params: * specifier = filled in with the attribute(s) */ @@ -3096,8 +3193,6 @@ final class CParser(AST) : Parser!AST /* Check for dllexport, dllimport * Ignore the rest */ - bool dllimport; // TODO implement - bool dllexport; // TODO implement nextToken(); // move past __declspec check(TOK.leftParenthesis); while (1) @@ -3113,12 +3208,22 @@ final class CParser(AST) : Parser!AST { if (token.ident == Id.dllimport) { - dllimport = true; + specifier.dllimport = true; nextToken(); } else if (token.ident == Id.dllexport) { - dllexport = true; + specifier.dllexport = true; + nextToken(); + } + else if (token.ident == Id.naked) + { + specifier.naked = true; + nextToken(); + } + else if (token.ident == Id.noinline) + { + specifier.scw |= SCW.xnoinline; nextToken(); } else if (token.ident == Id.noreturn) @@ -3126,6 +3231,49 @@ final class CParser(AST) : Parser!AST specifier.noreturn = true; nextToken(); } + else if (token.ident == Id._nothrow) + { + specifier._nothrow = true; + nextToken(); + } + else if (token.ident == Id.thread) + { + specifier.scw |= SCW.x_Thread_local; + nextToken(); + } + else if (token.ident == Id._align) + { + // Microsoft spec is very imprecise as to how this actually works + nextToken(); + check(TOK.leftParenthesis); + if (token.value == TOK.int32Literal) + { + const n = token.unsvalue; + if (n < 1 || n & (n - 1) || 8192 < n) + error("__decspec(align(%lld)) must be an integer positive power of 2 and be <= 8,192", cast(ulong)n); + specifier.packalign.set(cast(uint)n); + specifier.packalign.setPack(true); + nextToken(); + } + else + { + error("alignment value expected, not `%s`", token.toChars()); + nextToken(); + } + + check(TOK.rightParenthesis); + } + else if (token.ident == Id._deprecated) + { + specifier._deprecated = true; + nextToken(); + if (token.value == TOK.leftParenthesis) // optional deprecation message + { + nextToken(); + specifier.depMsg = cparseExpression(); + check(TOK.rightParenthesis); + } + } else { nextToken(); @@ -3133,6 +3281,8 @@ final class CParser(AST) : Parser!AST cparseParens(); } } + else if (token.value == TOK.restrict) // ImportC assigns no semantics to `restrict`, so just ignore the keyword. + nextToken(); else { error("extended-decl-modifier expected"); @@ -3142,7 +3292,8 @@ final class CParser(AST) : Parser!AST } /************************* - * Simple asm parser + * Parser for asm label. It appears after the declarator, and has apparently + * nothing to do with inline assembler. * https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html * simple-asm-expr: * asm ( asm-string-literal ) @@ -3150,17 +3301,107 @@ final class CParser(AST) : Parser!AST * asm-string-literal: * string-literal */ - private AST.StringExp cparseSimpleAsmExpr() + private AST.StringExp cparseGnuAsmLabel() { nextToken(); // move past asm check(TOK.leftParenthesis); if (token.value != TOK.string_) - error("string literal expected"); + error("string literal expected for Asm Label, not `%s`", token.toChars()); auto label = cparsePrimaryExp(); check(TOK.rightParenthesis); return cast(AST.StringExp) label; } + /******************** + * Parse C inline assembler statement in Gnu format. + * https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html + * asm asm-qualifiers ( AssemblerTemplate : OutputOperands : InputOperands : Clobbers : GotoLabels ) + * Current token is on the `asm`. + * Returns: + * inline assembler expression as a Statement + */ + private AST.Statement cparseGnuAsm() + { + // Defer parsing of AsmStatements until semantic processing. + const loc = token.loc; + + nextToken(); + + // Consume all asm-qualifiers. As a future optimization, we could record + // the `inline` and `volatile` storage classes against the statement. + while (token.value == TOK.goto_ || + token.value == TOK.inline || + token.value == TOK.volatile) + nextToken(); + + check(TOK.leftParenthesis); + if (token.value != TOK.string_) + error("string literal expected for Assembler Template, not `%s`", token.toChars()); + Token* toklist = null; + Token** ptoklist = &toklist; + //Identifier label = null; + auto statements = new AST.Statements(); + + int parens; + while (1) + { + switch (token.value) + { + case TOK.leftParenthesis: + ++parens; + goto default; + + case TOK.rightParenthesis: + --parens; + if (parens >= 0) + goto default; + break; + + case TOK.semicolon: + error("matching `)` expected, not `;`"); + break; + + case TOK.endOfFile: + /* ( */ + error("matching `)` expected, not end of file"); + break; + + case TOK.colonColon: // treat as two separate : tokens for iasmgcc + *ptoklist = allocateToken(); + memcpy(*ptoklist, &token, Token.sizeof); + (*ptoklist).value = TOK.colon; + ptoklist = &(*ptoklist).next; + + *ptoklist = allocateToken(); + memcpy(*ptoklist, &token, Token.sizeof); + (*ptoklist).value = TOK.colon; + ptoklist = &(*ptoklist).next; + + *ptoklist = null; + nextToken(); + continue; + + default: + *ptoklist = allocateToken(); + memcpy(*ptoklist, &token, Token.sizeof); + ptoklist = &(*ptoklist).next; + *ptoklist = null; + nextToken(); + continue; + } + if (toklist) + { + // Create AsmStatement from list of tokens we've saved + AST.Statement s = new AST.AsmStatement(token.loc, toklist); + statements.push(s); + } + break; + } + nextToken(); + auto s = new AST.CompoundAsmStatement(loc, statements, 0); + return s; + } + /************************* * __attribute__ parser * https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html @@ -3222,25 +3463,75 @@ final class CParser(AST) : Parser!AST */ private void cparseGnuAttribute(ref Specifier specifier) { - /* Check for dllimport, dllexport, vector_size(bytes) + /* Check for dllimport, dllexport, naked, noreturn, vector_size(bytes) * Ignore the rest */ - bool dllimport; // TODO implement - bool dllexport; // TODO implement - if (!isGnuAttributeName()) return; if (token.value == TOK.identifier) { - if (token.ident == Id.dllimport) + if (token.ident == Id.aligned) { - dllimport = true; + nextToken(); + if (token.value == TOK.leftParenthesis) + { + nextToken(); + if (token.value == TOK.int32Literal) + { + const n = token.unsvalue; + if (n < 1 || n & (n - 1) || ushort.max < n) + error("__attribute__((aligned(%lld))) must be an integer positive power of 2 and be <= 32,768", cast(ulong)n); + specifier.packalign.set(cast(uint)n); + specifier.packalign.setPack(true); + nextToken(); + } + else + { + error("alignment value expected, not `%s`", token.toChars()); + nextToken(); + } + + check(TOK.rightParenthesis); + } + /* ignore __attribute__((aligned)), which sets the alignment to the largest value for any data + * type on the target machine. It's the opposite of __attribute__((packed)) + */ + } + else if (token.ident == Id.always_inline) // https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + { + specifier.scw |= SCW.xinline; + nextToken(); + } + else if (token.ident == Id._deprecated) + { + specifier._deprecated = true; + nextToken(); + if (token.value == TOK.leftParenthesis) // optional deprecation message + { + nextToken(); + specifier.depMsg = cparseExpression(); + check(TOK.rightParenthesis); + } + } + else if (token.ident == Id.dllimport) + { + specifier.dllimport = true; nextToken(); } else if (token.ident == Id.dllexport) { - dllexport = true; + specifier.dllexport = true; + nextToken(); + } + else if (token.ident == Id.naked) + { + specifier.naked = true; + nextToken(); + } + else if (token.ident == Id.noinline) + { + specifier.scw |= SCW.xnoinline; nextToken(); } else if (token.ident == Id.noreturn) @@ -3248,6 +3539,16 @@ final class CParser(AST) : Parser!AST specifier.noreturn = true; nextToken(); } + else if (token.ident == Id._nothrow) + { + specifier._nothrow = true; + nextToken(); + } + else if (token.ident == Id._pure) + { + specifier._pure = true; + nextToken(); + } else if (token.ident == Id.vector_size) { nextToken(); @@ -3408,7 +3709,8 @@ final class CParser(AST) : Parser!AST * https://en.cppreference.com/w/cpp/language/enum * enum Identifier : Type */ - AST.Type base = AST.Type.tint32; // C11 6.7.2.2-4 implementation defined default base type + //AST.Type base = AST.Type.tint32; // C11 6.7.2.2-4 implementation defined default base type + AST.Type base = null; // C23 says base type is determined by enum member values if (token.value == TOK.colon) { nextToken(); @@ -3488,7 +3790,7 @@ final class CParser(AST) : Parser!AST * redeclaration, or reference to existing declaration. * Defer to the semantic() pass with a TypeTag. */ - return new AST.TypeTag(loc, TOK.enum_, tag, base, members); + return new AST.TypeTag(loc, TOK.enum_, tag, structalign_t.init, base, members); } /************************************* @@ -3510,11 +3812,12 @@ final class CParser(AST) : Parser!AST * Params: * loc = location of `struct` or `union` * structOrUnion = TOK.struct_ or TOK.union_ + * packalign = alignment to use for struct members * symbols = symbols to add struct-or-union declaration to * Returns: * type of the struct */ - private AST.Type cparseStruct(Loc loc, TOK structOrUnion, ref AST.Dsymbols* symbols) + private AST.Type cparseStruct(Loc loc, TOK structOrUnion, structalign_t packalign, ref AST.Dsymbols* symbols) { Identifier tag; @@ -3553,7 +3856,7 @@ final class CParser(AST) : Parser!AST * redeclaration, or reference to existing declaration. * Defer to the semantic() pass with a TypeTag. */ - return new AST.TypeTag(loc, structOrUnion, tag, null, members); + return new AST.TypeTag(loc, structOrUnion, tag, packalign, null, members); } /************************************* @@ -3996,6 +4299,13 @@ final class CParser(AST) : Parser!AST case TOK.union_: case TOK.enum_: t = peek(t); + if (t.value == TOK.__attribute__ || + t.value == TOK.__declspec) + { + t = peek(t); + if (!skipParens(t, &t)) + return false; + } if (t.value == TOK.identifier) { t = peek(t); @@ -4019,6 +4329,7 @@ final class CParser(AST) : Parser!AST case TOK.typedef_: case TOK.extern_: case TOK.static_: + case TOK.__thread: case TOK._Thread_local: case TOK.auto_: case TOK.register: @@ -4620,6 +4931,8 @@ final class CParser(AST) : Parser!AST // C11 6.7.4 Function specifiers xinline = 0x40, x_Noreturn = 0x80, + + xnoinline = 0x100, } /// C11 6.7.3 Type qualifiers @@ -4639,6 +4952,14 @@ final class CParser(AST) : Parser!AST struct Specifier { bool noreturn; /// noreturn attribute + bool naked; /// naked attribute + bool _nothrow; /// nothrow attribute + bool _pure; /// pure attribute + bool dllimport; /// dllimport attribute + bool dllexport; /// dllexport attribute + bool _deprecated; /// deprecated attribute + AST.Expression depMsg; /// deprecated message + SCW scw; /// storage-class specifiers MOD mod; /// type qualifiers AST.Expressions* alignExps; /// alignment @@ -4662,6 +4983,8 @@ final class CParser(AST) : Parser!AST { if (specifier.scw & SCW.xextern) stc = AST.STC.extern_; + else if (specifier.scw & SCW.xstatic) + stc = AST.STC.static_; } else if (level == LVL.local) { @@ -4713,10 +5036,42 @@ final class CParser(AST) : Parser!AST stc = AST.STC.gshared; } } + if (specifier._deprecated && !specifier.depMsg) + stc |= AST.STC.deprecated_; return stc; } /*********************** + * Add attributes from Specifier to function + * Params: + * fd = function to apply them to + * specifier = specifiers + */ + void specifiersToFuncDeclaration(AST.FuncDeclaration fd, const ref Specifier specifier) + { + fd.isNaked = specifier.naked; + fd.dllImport = specifier.dllimport; + fd.dllExport = specifier.dllexport; + + if (specifier.scw & SCW.xnoinline) + fd.inlining = PINLINE.never; + else if (specifier.scw & SCW.xinline) + fd.inlining = PINLINE.always; + } + + /*********************** + * Add attributes from Specifier to variable + * Params: + * vd = function to apply them to + * specifier = specifiers + */ + void specifiersToVarDeclaration(AST.VarDeclaration vd, const ref Specifier specifier) + { + vd.dllImport = specifier.dllimport; + vd.dllExport = specifier.dllexport; + } + + /*********************** * Return suitable signed integer type for the given size * Params: * size = size of type @@ -4826,7 +5181,7 @@ final class CParser(AST) : Parser!AST auto lenfn = new AST.IntegerExp(loc, fn.length + 1, AST.Type.tuns32); // +1 for terminating 0 auto tfn = new AST.TypeSArray(AST.Type.tchar, lenfn); efn.type = tfn.immutableOf(); - efn.committed = 1; + efn.committed = true; auto sfn = new AST.VarDeclaration(loc, tfn, Id.__func__, ifn, STC.gshared | STC.immutable_); auto e = new AST.DeclarationExp(loc, sfn); return new AST.ExpStatement(loc, e); @@ -4879,6 +5234,17 @@ final class CParser(AST) : Parser!AST private AST.Dsymbol applySpecifier(AST.Dsymbol s, ref Specifier specifier) { //printf("applySpecifier() %s\n", s.toChars()); + if (specifier._deprecated) + { + if (specifier.depMsg) + { + // Wrap declaration in a DeprecatedDeclaration + auto decls = new AST.Dsymbols(1); + (*decls)[0] = s; + s = new AST.DeprecatedDeclaration(specifier.depMsg, decls); + } + } + if (specifier.alignExps) { //printf(" applying _Alignas %s, packalign %d\n", (*specifier.alignExps)[0].toChars(), cast(int)specifier.packalign); diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index 32b3851..40092c3 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -211,7 +211,7 @@ private final class CppMangleVisitor : Visitor */ void mangleReturnType(TypeFunction preSemantic) { - auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type; + auto tf = this.context.res.asFuncDecl().type.isTypeFunction(); Type rt = preSemantic.nextOf(); // https://issues.dlang.org/show_bug.cgi?id=22739 // auto return type means that rt is null. @@ -347,14 +347,14 @@ private final class CppMangleVisitor : Visitor * * Params: * off = Offset to insert at - * fd = Type of the function to mangle the return type of + * tf = Type of the function to mangle the return type of */ void writeRemainingTags(size_t off, TypeFunction tf) { - scope remainingVisitor = new LeftoverVisitor(&this.abiTags.written); - tf.next.accept(remainingVisitor); + Array!StringExp toWrite; + leftOver(tf, &this.abiTags.written, &toWrite); OutBuffer b2; - foreach (se; remainingVisitor.toWrite) + foreach (se; toWrite) { auto tag = se.peekString(); // We can only insert a slice, and each insert is a memmove, @@ -496,9 +496,9 @@ private final class CppMangleVisitor : Visitor mangle_function(d.isFuncDeclaration()); buf.writestring("EE"); } - else if (e && e.op == EXP.variable && (cast(VarExp)e).var.isVarDeclaration()) + else if (e && e.isVarExp() && e.isVarExp().var.isVarDeclaration()) { - VarDeclaration vd = (cast(VarExp)e).var.isVarDeclaration(); + VarDeclaration vd = e.isVarExp().var.isVarDeclaration(); buf.writeByte('L'); mangle_variable(vd, true); buf.writeByte('E'); @@ -757,9 +757,9 @@ private final class CppMangleVisitor : Visitor bool isIdent_char(Identifier ident, RootObject o) { Type t = isType(o); - if (!t || t.ty != Tstruct) + if (!t || !t.isTypeStruct()) return false; - Dsymbol s = (cast(TypeStruct)t).toDsymbol(null); + Dsymbol s = t.toDsymbol(null); if (s.ident != ident) return false; Dsymbol p = s.toParent(); @@ -1059,7 +1059,7 @@ private final class CppMangleVisitor : Visitor * ::= * ::= */ - TypeFunction tf = cast(TypeFunction)d.type; + TypeFunction tf = d.type.isTypeFunction(); if (TemplateDeclaration ftd = getFuncTemplateDecl(d)) { @@ -1173,7 +1173,7 @@ private final class CppMangleVisitor : Visitor this.context.ti = ti; this.context.fd = d; this.context.res = d; - TypeFunction preSemantic = cast(TypeFunction)d.originalType; + TypeFunction preSemantic = d.originalType.isTypeFunction(); auto nspace = ti.toParent(); if (nspace && nspace.isNspace()) this.writeChained(ti.toParent(), () => source_name(ti, true)); @@ -1347,7 +1347,7 @@ private final class CppMangleVisitor : Visitor auto prev = this.context.push({ TypeFunction tf; if (isDsymbol(this.context.res)) - tf = cast(TypeFunction)this.context.res.asFuncDecl().type; + tf = this.context.res.asFuncDecl().type.isTypeFunction(); else tf = this.context.res.asType().isTypeFunction(); assert(tf); @@ -1391,9 +1391,9 @@ private final class CppMangleVisitor : Visitor */ void headOfType(Type t) { - if (t.ty == Tclass) + if (auto tc = t.isTypeClass()) { - mangleTypeClass(cast(TypeClass)t, true); + mangleTypeClass(tc, true); } else { @@ -1960,7 +1960,7 @@ extern(C++): */ override void visit(TypeIdentifier t) { - auto decl = cast(TemplateDeclaration)this.context.ti.tempdecl; + auto decl = this.context.ti.tempdecl.isTemplateDeclaration(); assert(decl.parameters !is null); auto idx = templateParamIndex(t.ident, decl.parameters); // If not found, default to the post-semantic type @@ -2019,7 +2019,7 @@ extern(C++): { // If the resolved AST has more args than the parse one, // we have default arguments - auto oparams = (cast(TemplateDeclaration)analyzed_ti.tempdecl).origParameters; + auto oparams = analyzed_ti.tempdecl.isTemplateDeclaration().origParameters; foreach (idx, arg; (*oparams)[t.tiargs.length .. $]) { this.context.res = (*analyzed_ti.tiargs)[idx + t.tiargs.length]; @@ -2044,7 +2044,7 @@ extern(C++): assert(t.tiargs !is null); bool needsTa; - auto decl = cast(TemplateDeclaration)this.context.ti.tempdecl; + auto decl = this.context.ti.tempdecl.isTemplateDeclaration(); // Attempt to substitute the template itself auto idx = templateParamIndex(t.name, decl.parameters); if (idx < decl.parameters.length) @@ -2125,12 +2125,13 @@ private void visitObject(V : Visitor)(RootObject o, V this_) /// Helper function to safely get a type out of a `RootObject` private Type asType(RootObject o) { - Type ta = isType(o); + if (Type ta = isType(o)) + return ta; + // When called with context.res as argument, it can be `FuncDeclaration` - if (!ta && o.asFuncDecl()) - ta = (cast(FuncDeclaration)o).type; - assert(ta !is null, o.toString()); - return ta; + if (auto fd = o.asFuncDecl()) + return fd.type; + assert(0); } /// Helper function to safely get a `FuncDeclaration` out of a `RootObject` @@ -2183,12 +2184,12 @@ private extern(C++) final class ComponentVisitor : Visitor case DYNCAST.type: auto t = cast(Type)base; - if (t.ty == Tpointer) - this.tpointer = cast(TypePointer)t; - else if (t.ty == Treference) - this.tref = cast(TypeReference)t; - else if (t.ty == Tident) - this.tident = cast(TypeIdentifier)t; + if (auto tp = t.isTypePointer()) + this.tpointer = tp; + else if (auto tr = t.isTypeReference()) + this.tref = tr; + else if (auto ti = t.isTypeIdentifier()) + this.tident = ti; else goto default; break; @@ -2531,58 +2532,70 @@ unittest assert(closestIndex([s1, s2, s4], s5, match) == 3 && !match); } -/** +/*** * Visits the return type of a function and writes leftover ABI tags + * Params: + * tf = Type of the function to mangle the return type of + * previous = already written ones + * toWrite = where to put StringExp's to be written */ -extern(C++) private final class LeftoverVisitor : Visitor +private +void leftOver(TypeFunction tf, const(Array!StringExp)* previous, Array!StringExp* toWrite) { - /// List of tags to write - private Array!StringExp toWrite; - /// List of tags to ignore - private const(Array!StringExp)* ignore; - - /// - public this(const(Array!StringExp)* previous) + extern(C++) final class LeftoverVisitor : Visitor { - this.ignore = previous; - } + /// List of tags to write + private Array!StringExp* toWrite; + /// List of tags to ignore + private const(Array!StringExp)* ignore; - /// Reintroduce base class overloads - public alias visit = Visitor.visit; + /// + public this(const(Array!StringExp)* previous, Array!StringExp* toWrite) + { + this.ignore = previous; + this.toWrite = toWrite; + } - /// Least specialized overload of each direct child of `RootObject` - public override void visit(Dsymbol o) - { - auto ale = ABITagContainer.forSymbol(o); - if (!ale) return; + /// Reintroduce base class overloads + public alias visit = Visitor.visit; - bool match; - foreach (elem; *ale.elements) + /// Least specialized overload of each direct child of `RootObject` + public override void visit(Dsymbol o) { - auto se = elem.toStringExp(); - closestIndex((*this.ignore)[], se, match); - if (match) continue; - auto idx = closestIndex(this.toWrite[], se, match); - if (!match) - this.toWrite.insert(idx, se); + auto ale = ABITagContainer.forSymbol(o); + if (!ale) return; + + bool match; + foreach (elem; *ale.elements) + { + auto se = elem.toStringExp(); + closestIndex((*this.ignore)[], se, match); + if (match) continue; + auto idx = closestIndex((*this.toWrite)[], se, match); + if (!match) + (*this.toWrite).insert(idx, se); + } } - } - /// Ditto - public override void visit(Type o) - { - if (auto sym = o.toDsymbol(null)) - sym.accept(this); - } + /// Ditto + public override void visit(Type o) + { + if (auto sym = o.toDsymbol(null)) + sym.accept(this); + } - /// Composite type - public override void visit(TypePointer o) - { - o.next.accept(this); - } + /// Composite type + public override void visit(TypePointer o) + { + o.next.accept(this); + } - public override void visit(TypeReference o) - { - o.next.accept(this); + public override void visit(TypeReference o) + { + o.next.accept(this); + } } + + scope remainingVisitor = new LeftoverVisitor(previous, toWrite); + tf.next.accept(remainingVisitor); } diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d index 8109e12..289ebeb 100644 --- a/gcc/d/dmd/ctfeexpr.d +++ b/gcc/d/dmd/ctfeexpr.d @@ -47,7 +47,7 @@ extern (C++) final class ClassReferenceExp : Expression extern (D) this(const ref Loc loc, StructLiteralExp lit, Type type) { - super(loc, EXP.classReference, __traits(classInstanceSize, ClassReferenceExp)); + super(loc, EXP.classReference); assert(lit && lit.sd && lit.sd.isClassDeclaration()); this.value = lit; this.type = type; @@ -132,7 +132,7 @@ extern (C++) final class ThrownExceptionExp : Expression extern (D) this(const ref Loc loc, ClassReferenceExp victim) { - super(loc, EXP.thrownException, __traits(classInstanceSize, ThrownExceptionExp)); + super(loc, EXP.thrownException); this.thrown = victim; this.type = victim.type; } @@ -170,7 +170,7 @@ extern (C++) final class CTFEExp : Expression { extern (D) this(EXP tok) { - super(Loc.initial, tok, __traits(classInstanceSize, CTFEExp)); + super(Loc.initial, tok); type = Type.tvoid; } @@ -369,7 +369,6 @@ UnionExp copyLiteral(Expression e) case EXP.dotVariable: case EXP.int64: case EXP.float64: - case EXP.char_: case EXP.complex80: case EXP.void_: case EXP.vector: @@ -1468,7 +1467,7 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2) memset(cast(char*)s + len * sz, 0, sz); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); StringExp es = ue.exp().isStringExp(); - es.committed = 0; + es.committed = false; es.type = type; return ue; } @@ -1499,7 +1498,7 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2) emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); StringExp es = ue.exp().isStringExp(); es.sz = sz; - es.committed = 0; //es1.committed; + es.committed = false; //es1.committed; es.type = type; return ue; } @@ -1837,7 +1836,6 @@ bool isCtfeValueValid(Expression newval) { case EXP.int64: case EXP.float64: - case EXP.char_: case EXP.complex80: return tb.isscalar(); diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 2830b25..8ffbef3 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -1845,7 +1845,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) if (!e.committed) { se = e.copy().isStringExp(); - se.committed = 1; + se.committed = true; copied = 1; } @@ -1887,7 +1887,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) assert(szx <= 255); se.sz = cast(ubyte)szx; se.len = cast(size_t)tb.isTypeSArray().dim.toInteger(); - se.committed = 1; + se.committed = true; se.type = t; /* If larger than source, pad with zeros. diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index 7cd8df1..0e5df5e 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -738,7 +738,7 @@ extern (C++) final class AliasDeclaration : Declaration extern (D) this(const ref Loc loc, Identifier ident, Type type) { super(loc, ident); - //printf("AliasDeclaration(id = '%s', type = %p)\n", id.toChars(), type); + //printf("AliasDeclaration(id = '%s', type = %p)\n", ident.toChars(), type); //printf("type = '%s'\n", type.toChars()); this.type = type; assert(type); @@ -747,7 +747,7 @@ extern (C++) final class AliasDeclaration : Declaration extern (D) this(const ref Loc loc, Identifier ident, Dsymbol s) { super(loc, ident); - //printf("AliasDeclaration(id = '%s', s = %p)\n", id.toChars(), s); + //printf("AliasDeclaration(id = '%s', s = %p)\n", ident.toChars(), s); assert(s != this); this.aliassym = s; assert(s); @@ -1149,6 +1149,8 @@ extern (C++) class VarDeclaration : Declaration bool isArgDtorVar; /// temporary created to handle scope destruction of a function argument bool isCmacro; /// it is a C macro turned into a C declaration + bool dllImport; /// __declspec(dllimport) + bool dllExport; /// __declspec(dllexport) version (MARS) { bool inClosure; /// is inserted into a GC allocated closure @@ -1314,7 +1316,7 @@ extern (C++) class VarDeclaration : Declaration override final bool isExport() const { - return visibility.kind == Visibility.Kind.export_; + return visibility.kind == Visibility.Kind.export_ || dllExport; } override final bool isImportedSymbol() const @@ -1325,6 +1327,7 @@ extern (C++) class VarDeclaration : Declaration * export extern int sym3 = 0; // error, extern cannot have initializer */ bool result = + dllImport || visibility.kind == Visibility.Kind.export_ && storage_class & STC.extern_ && (storage_class & STC.static_ || parent.isModule()); @@ -1931,8 +1934,12 @@ extern (C++) class BitFieldDeclaration : VarDeclaration { // If the bit-field spans more units of alignment than its type, // start a new field at the next alignment boundary. - if (fieldState.bitOffset == fieldState.fieldSize * 8) + if (fieldState.bitOffset == fieldState.fieldSize * 8 && + fieldState.bitOffset + fieldWidth > memalignsize * 8) + { + if (log) printf("more units of alignment than its type\n"); startNewField(); // the bit field is full + } else { // if alignment boundary is crossed @@ -1941,7 +1948,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration //printf("%s start: %d end: %d memalignsize: %d\n", ad.toChars(), start, end, memalignsize); if (start / (memalignsize * 8) != (end - 1) / (memalignsize * 8)) { - //printf("alignment is crossed\n"); + if (log) printf("alignment is crossed\n"); startNewField(); } } @@ -1981,6 +1988,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration fieldState.bitOffset = pastField; } + //printf("\t%s: offset = %d bitOffset = %d fieldWidth = %d memsize = %d\n", toChars(), offset, bitOffset, fieldWidth, memsize); //printf("\t%s: memalignsize = %d\n", toChars(), memalignsize); //printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad.toChars(), offset, memsize); } diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index d75f64f..7a69382 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -623,6 +623,9 @@ public: FuncDeclarations *inlinedNestedCallees; AttributeViolation* safetyViolation; + AttributeViolation* nogcViolation; + AttributeViolation* pureViolation; + AttributeViolation* nothrowViolation; // Formerly FUNCFLAGS uint32_t flags; @@ -672,6 +675,10 @@ public: bool isCrtCtor(bool v); bool isCrtDtor() const; bool isCrtDtor(bool v); + bool dllImport() const; + bool dllImport(bool v); + bool dllExport() const; + bool dllExport(bool v); // Data for a function declaration that is needed for the Objective-C // integration. diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index e6ef704..4ef6a39 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -642,7 +642,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta e = CTFEExp.cantexp; break; } - e = interpret(pue, fd.fbody, &istatex); + e = interpretStatement(pue, fd.fbody, &istatex); if (CTFEExp.isCantExp(e)) { debug (LOG) @@ -738,21 +738,30 @@ void incUsageCtfe(InterState* istate, const ref Loc loc) } } -private extern (C++) final class Interpreter : Visitor +/*********************************** + * Interpret the statement. + * Params: + * s = Statement to interpret + * istate = context + * Returns: + * NULL continue to next statement + * EXP.cantExpression cannot interpret statement at compile time + * !NULL expression from return statement, or thrown exception + */ + +Expression interpretStatement(Statement s, InterState* istate) { - alias visit = Visitor.visit; -public: - InterState* istate; - CTFEGoal goal; - Expression result; - UnionExp* pue; // storage for `result` + UnionExp ue = void; + auto result = interpretStatement(&ue, s, istate); + if (result == ue.exp()) + result = ue.copy(); + return result; +} - extern (D) this(UnionExp* pue, InterState* istate, CTFEGoal goal) scope - { - this.pue = pue; - this.istate = istate; - this.goal = goal; - } +/// +Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate) +{ + Expression result; // If e is EXP.throw_exception or EXP.cantExpression, // set it to 'result' and returns true. @@ -767,26 +776,13 @@ public: return false; } - static Expressions* copyArrayOnWrite(Expressions* exps, Expressions* original) - { - if (exps is original) - { - if (!original) - exps = new Expressions(); - else - exps = original.copy(); - ++ctfeGlobals.numArrayAllocs; - } - return exps; - } - /******************************** Statement ***************************/ - override void visit(Statement s) + void visitDefaultCase(Statement s) { debug (LOG) { - printf("%s Statement::interpret()\n", s.loc.toChars()); + printf("%s Statement::interpret() %s\n", s.loc.toChars(), s.toChars()); } if (istate.start) { @@ -799,7 +795,7 @@ public: result = CTFEExp.cantexp; } - override void visit(ExpStatement s) + void visitExp(ExpStatement s) { debug (LOG) { @@ -819,7 +815,12 @@ public: return; } - override void visit(CompoundStatement s) + void visitDtorExp(DtorExpStatement s) + { + visitExp(s); + } + + void visitCompound(CompoundStatement s) { debug (LOG) { @@ -832,7 +833,7 @@ public: foreach (i; 0 .. dim) { Statement sx = (*s.statements)[i]; - result = interpret(pue, sx, istate); + result = interpretStatement(pue, sx, istate); if (result) break; } @@ -842,7 +843,12 @@ public: } } - override void visit(UnrolledLoopStatement s) + void visitCompoundAsm(CompoundAsmStatement s) + { + visitCompound(s); + } + + void visitUnrolledLoop(UnrolledLoopStatement s) { debug (LOG) { @@ -855,7 +861,7 @@ public: foreach (i; 0 .. dim) { Statement sx = (*s.statements)[i]; - Expression e = interpret(pue, sx, istate); + Expression e = interpretStatement(pue, sx, istate); if (!e) // succeeds to interpret, or goto target was not found continue; if (exceptionOrCant(e)) @@ -888,7 +894,7 @@ public: } } - override void visit(IfStatement s) + void visitIf(IfStatement s) { debug (LOG) { @@ -900,9 +906,9 @@ public: if (istate.start) { Expression e = null; - e = interpret(s.ifbody, istate); + e = interpretStatement(s.ifbody, istate); if (!e && istate.start) - e = interpret(s.elsebody, istate); + e = interpretStatement(s.elsebody, istate); result = e; return; } @@ -914,9 +920,9 @@ public: return; if (isTrueBool(e)) - result = interpret(pue, s.ifbody, istate); + result = interpretStatement(pue, s.ifbody, istate); else if (e.toBool().hasValue(false)) - result = interpret(pue, s.elsebody, istate); + result = interpretStatement(pue, s.elsebody, istate); else { // no error, or assert(0)? @@ -924,7 +930,7 @@ public: } } - override void visit(ScopeStatement s) + void visitScope(ScopeStatement s) { debug (LOG) { @@ -933,78 +939,10 @@ public: if (istate.start == s) istate.start = null; - result = interpret(pue, s.statement, istate); + result = interpretStatement(pue, s.statement, istate); } - /** - Given an expression e which is about to be returned from the current - function, generate an error if it contains pointers to local variables. - - Only checks expressions passed by value (pointers to local variables - may already be stored in members of classes, arrays, or AAs which - were passed as mutable function parameters). - Returns: - true if it is safe to return, false if an error was generated. - */ - static bool stopPointersEscaping(const ref Loc loc, Expression e) - { - if (!e.type.hasPointers()) - return true; - if (isPointer(e.type)) - { - Expression x = e; - if (auto eaddr = e.isAddrExp()) - x = eaddr.e1; - VarDeclaration v; - while (x.op == EXP.variable && (v = x.isVarExp().var.isVarDeclaration()) !is null) - { - if (v.storage_class & STC.ref_) - { - x = getValue(v); - if (auto eaddr = e.isAddrExp()) - eaddr.e1 = x; - continue; - } - if (ctfeGlobals.stack.isInCurrentFrame(v)) - { - error(loc, "returning a pointer to a local stack variable"); - return false; - } - else - break; - } - // TODO: If it is a EXP.dotVariable or EXP.index, we should check that it is not - // pointing to a local struct or static array. - } - if (auto se = e.isStructLiteralExp()) - { - return stopPointersEscapingFromArray(loc, se.elements); - } - if (auto ale = e.isArrayLiteralExp()) - { - return stopPointersEscapingFromArray(loc, ale.elements); - } - if (auto aae = e.isAssocArrayLiteralExp()) - { - if (!stopPointersEscapingFromArray(loc, aae.keys)) - return false; - return stopPointersEscapingFromArray(loc, aae.values); - } - return true; - } - - // Check all elements of an array for escaping local variables. Return false if error - static bool stopPointersEscapingFromArray(const ref Loc loc, Expressions* elems) - { - foreach (e; *elems) - { - if (e && !stopPointersEscaping(loc, e)) - return false; - } - return true; - } - - override void visit(ReturnStatement s) + void visitReturn(ReturnStatement s) { debug (LOG) { @@ -1061,7 +999,7 @@ public: if (isRuntimeHook(s.exp, Id._d_arrayappendT) || isRuntimeHook(s.exp, Id._d_arrayappendTTrace)) { auto rs = new ReturnStatement(s.loc, e); - rs.accept(this); + visitReturn(rs); return; } @@ -1082,20 +1020,7 @@ public: result = e; } - static Statement findGotoTarget(InterState* istate, Identifier ident) - { - Statement target = null; - if (ident) - { - LabelDsymbol label = istate.fd.searchLabel(ident); - assert(label && label.statement); - LabelStatement ls = label.statement; - target = ls.gotoTarget ? ls.gotoTarget : ls.statement; - } - return target; - } - - override void visit(BreakStatement s) + void visitBreak(BreakStatement s) { debug (LOG) { @@ -1113,7 +1038,7 @@ public: result = CTFEExp.breakexp; } - override void visit(ContinueStatement s) + void visitContinue(ContinueStatement s) { debug (LOG) { @@ -1131,7 +1056,7 @@ public: result = CTFEExp.continueexp; } - override void visit(WhileStatement s) + void visitWhile(WhileStatement s) { debug (LOG) { @@ -1140,7 +1065,7 @@ public: assert(0); // rewritten to ForStatement } - override void visit(DoStatement s) + void visitDo(DoStatement s) { debug (LOG) { @@ -1151,7 +1076,7 @@ public: while (1) { - Expression e = interpret(s._body, istate); + Expression e = interpretStatement(s._body, istate); if (!e && istate.start) // goto target was not found return; assert(!istate.start); @@ -1201,7 +1126,7 @@ public: assert(result is null); } - override void visit(ForStatement s) + void visitFor(ForStatement s) { debug (LOG) { @@ -1211,7 +1136,7 @@ public: istate.start = null; UnionExp ueinit = void; - Expression ei = interpret(&ueinit, s._init, istate); + Expression ei = interpretStatement(&ueinit, s._init, istate); if (exceptionOrCant(ei)) return; assert(!ei); // s.init never returns from function, or jumps out from it @@ -1230,7 +1155,7 @@ public: assert(isTrueBool(e)); } - Expression e = interpret(pue, s._body, istate); + Expression e = interpretStatement(pue, s._body, istate); if (!e && istate.start) // goto target was not found return; assert(!istate.start); @@ -1273,17 +1198,17 @@ public: assert(result is null); } - override void visit(ForeachStatement s) + void visitForeach(ForeachStatement s) { assert(0); // rewritten to ForStatement } - override void visit(ForeachRangeStatement s) + void visitForeachRange(ForeachRangeStatement s) { assert(0); // rewritten to ForStatement } - override void visit(SwitchStatement s) + void visitSwitch(SwitchStatement s) { debug (LOG) { @@ -1294,7 +1219,7 @@ public: istate.start = null; if (istate.start) { - Expression e = interpret(s._body, istate); + Expression e = interpretStatement(s._body, istate); if (istate.start) // goto target was not found return; if (exceptionOrCant(e)) @@ -1344,7 +1269,7 @@ public: /* Jump to scase */ istate.start = scase; - Expression e = interpret(pue, s._body, istate); + Expression e = interpretStatement(pue, s._body, istate); assert(!istate.start); // jump must not fail if (e && e.op == EXP.break_) { @@ -1359,7 +1284,7 @@ public: result = e; } - override void visit(CaseStatement s) + void visitCase(CaseStatement s) { debug (LOG) { @@ -1369,10 +1294,10 @@ public: if (istate.start == s) istate.start = null; - result = interpret(pue, s.statement, istate); + result = interpretStatement(pue, s.statement, istate); } - override void visit(DefaultStatement s) + void visitDefault(DefaultStatement s) { debug (LOG) { @@ -1382,10 +1307,10 @@ public: if (istate.start == s) istate.start = null; - result = interpret(pue, s.statement, istate); + result = interpretStatement(pue, s.statement, istate); } - override void visit(GotoStatement s) + void visitGoto(GotoStatement s) { debug (LOG) { @@ -1404,7 +1329,7 @@ public: result = CTFEExp.gotoexp; } - override void visit(GotoCaseStatement s) + void visitGotoCase(GotoCaseStatement s) { debug (LOG) { @@ -1423,7 +1348,7 @@ public: result = CTFEExp.gotoexp; } - override void visit(GotoDefaultStatement s) + void visitGotoDefault(GotoDefaultStatement s) { debug (LOG) { @@ -1442,7 +1367,7 @@ public: result = CTFEExp.gotoexp; } - override void visit(LabelStatement s) + void visitLabel(LabelStatement s) { debug (LOG) { @@ -1451,10 +1376,10 @@ public: if (istate.start == s) istate.start = null; - result = interpret(pue, s.statement, istate); + result = interpretStatement(pue, s.statement, istate); } - override void visit(TryCatchStatement s) + void visitTryCatch(TryCatchStatement s) { debug (LOG) { @@ -1465,18 +1390,18 @@ public: if (istate.start) { Expression e = null; - e = interpret(pue, s._body, istate); + e = interpretStatement(pue, s._body, istate); foreach (ca; *s.catches) { if (e || !istate.start) // goto target was found break; - e = interpret(pue, ca.handler, istate); + e = interpretStatement(pue, ca.handler, istate); } result = e; return; } - Expression e = interpret(s._body, istate); + Expression e = interpretStatement(s._body, istate); // An exception was thrown if (e && e.isThrownExceptionExp()) @@ -1497,7 +1422,7 @@ public: ctfeGlobals.stack.push(ca.var); setValue(ca.var, ex.thrown); } - e = interpret(ca.handler, istate); + e = interpretStatement(ca.handler, istate); if (CTFEExp.isGotoExp(e)) { /* This is an optimization that relies on the locality of the jump target. @@ -1509,7 +1434,7 @@ public: InterState istatex = *istate; istatex.start = istate.gotoTarget; // set starting statement istatex.gotoTarget = null; - Expression eh = interpret(ca.handler, &istatex); + Expression eh = interpretStatement(ca.handler, &istatex); if (!istatex.start) { istate.gotoTarget = null; @@ -1522,39 +1447,7 @@ public: result = e; } - static ThrownExceptionExp chainExceptions(ThrownExceptionExp oldest, ThrownExceptionExp newest) - { - debug (LOG) - { - printf("Collided exceptions %s %s\n", oldest.thrown.toChars(), newest.thrown.toChars()); - } - // Little sanity check to make sure it's really a Throwable - ClassReferenceExp boss = oldest.thrown; - const next = 5; // index of Throwable.next - assert((*boss.value.elements)[next].type.ty == Tclass); // Throwable.next - ClassReferenceExp collateral = newest.thrown; - if (collateral.originalClass().isErrorException() && !boss.originalClass().isErrorException()) - { - /* Find the index of the Error.bypassException field - */ - auto bypass = next + 1; - if ((*collateral.value.elements)[bypass].type.ty == Tuns32) - bypass += 1; // skip over _refcount field - assert((*collateral.value.elements)[bypass].type.ty == Tclass); - - // The new exception bypass the existing chain - (*collateral.value.elements)[bypass] = boss; - return newest; - } - while ((*boss.value.elements)[next].op == EXP.classReference) - { - boss = (*boss.value.elements)[next].isClassReferenceExp(); - } - (*boss.value.elements)[next] = collateral; - return oldest; - } - - override void visit(TryFinallyStatement s) + void visitTryFinally(TryFinallyStatement s) { debug (LOG) { @@ -1565,14 +1458,14 @@ public: if (istate.start) { Expression e = null; - e = interpret(pue, s._body, istate); + e = interpretStatement(pue, s._body, istate); // Jump into/out from finalbody is disabled in semantic analysis. // and jump inside will be handled by the ScopeStatement == finalbody. result = e; return; } - Expression ex = interpret(s._body, istate); + Expression ex = interpretStatement(s._body, istate); if (CTFEExp.isCantExp(ex)) { result = ex; @@ -1585,7 +1478,7 @@ public: InterState istatex = *istate; istatex.start = istate.gotoTarget; // set starting statement istatex.gotoTarget = null; - Expression bex = interpret(s._body, &istatex); + Expression bex = interpretStatement(s._body, &istatex); if (istatex.start) { // The goto target is outside the current scope. @@ -1601,7 +1494,7 @@ public: ex = bex; } - Expression ey = interpret(s.finalbody, istate); + Expression ey = interpretStatement(s.finalbody, istate); if (CTFEExp.isCantExp(ey)) { result = ey; @@ -1618,7 +1511,7 @@ public: result = ex; } - override void visit(ThrowStatement s) + void visitThrow(ThrowStatement s) { debug (LOG) { @@ -1631,35 +1524,15 @@ public: istate.start = null; } - interpretThrow(s.exp, s.loc); - } - - /// Interpret `throw ` found at the specified location `loc` - private void interpretThrow(Expression exp, const ref Loc loc) - { - incUsageCtfe(istate, loc); - - Expression e = interpretRegion(exp, istate); - if (exceptionOrCant(e)) - return; - - if (e.op == EXP.classReference) - { - result = ctfeEmplaceExp!ThrownExceptionExp(loc, e.isClassReferenceExp()); - } - else - { - exp.error("to be thrown `%s` must be non-null", exp.toChars()); - result = ErrorExp.get(); - } + interpretThrow(result, s.exp, s.loc, istate); } - override void visit(ScopeGuardStatement s) + void visitScopeGuard(ScopeGuardStatement s) { assert(0); } - override void visit(WithStatement s) + void visitWith(WithStatement s) { debug (LOG) { @@ -1669,14 +1542,14 @@ public: istate.start = null; if (istate.start) { - result = s._body ? interpret(s._body, istate) : null; + result = s._body ? interpretStatement(s._body, istate) : null; return; } // If it is with(Enum) {...}, just execute the body. if (s.exp.op == EXP.scope_ || s.exp.op == EXP.type) { - result = interpret(pue, s._body, istate); + result = interpretStatement(pue, s._body, istate); return; } @@ -1692,7 +1565,7 @@ public: } ctfeGlobals.stack.push(s.wthis); setValue(s.wthis, e); - e = interpret(s._body, istate); + e = interpretStatement(s._body, istate); if (CTFEExp.isGotoExp(e)) { /* This is an optimization that relies on the locality of the jump target. @@ -1704,7 +1577,7 @@ public: InterState istatex = *istate; istatex.start = istate.gotoTarget; // set starting statement istatex.gotoTarget = null; - Expression ex = interpret(s._body, &istatex); + Expression ex = interpretStatement(s._body, &istatex); if (!istatex.start) { istate.gotoTarget = null; @@ -1715,7 +1588,7 @@ public: result = e; } - override void visit(AsmStatement s) + void visitAsm(AsmStatement s) { debug (LOG) { @@ -1731,7 +1604,17 @@ public: result = CTFEExp.cantexp; } - override void visit(ImportStatement s) + void visitInlineAsm(InlineAsmStatement s) + { + visitAsm(s); + } + + void visitGccAsm(GccAsmStatement s) + { + visitAsm(s); + } + + void visitImport(ImportStatement s) { debug (LOG) { @@ -1745,6 +1628,45 @@ public: } } + if (!s) + return null; + + mixin VisitStatement!void visit; + visit.VisitStatement(s); + return result; +} + +/// + +private extern (C++) final class Interpreter : Visitor +{ + alias visit = Visitor.visit; +public: + InterState* istate; + CTFEGoal goal; + Expression result; + UnionExp* pue; // storage for `result` + + extern (D) this(UnionExp* pue, InterState* istate, CTFEGoal goal) scope + { + this.pue = pue; + this.istate = istate; + this.goal = goal; + } + + // If e is EXP.throw_exception or EXP.cantExpression, + // set it to 'result' and returns true. + bool exceptionOrCant(Expression e) + { + if (exceptionOrCantInterpret(e)) + { + // Make sure e is not pointing to a stack temporary + result = (e.op == EXP.cantExpression) ? CTFEExp.cantexp : e; + return true; + } + return false; + } + /******************************** Expression ***************************/ override void visit(Expression e) @@ -2519,7 +2441,7 @@ public: { debug (LOG) { - printf("%s ArrayLiteralExp::interpret() %s\n", e.loc.toChars(), e.toChars()); + printf("%s ArrayLiteralExp::interpret() %s, %s\n", e.loc.toChars(), e.type.toChars(), e.toChars()); } if (e.ownedByCtfe >= OwnedBy.ctfe) // We've already interpreted all the elements { @@ -2527,7 +2449,8 @@ public: return; } - Type tn = e.type.toBasetype().nextOf().toBasetype(); + Type tb = e.type.toBasetype(); + Type tn = tb.nextOf().toBasetype(); bool wantCopy = (tn.ty == Tsarray || tn.ty == Tstruct); auto basis = interpretRegion(e.basis, istate); @@ -2536,6 +2459,7 @@ public: auto expsx = e.elements; size_t dim = expsx ? expsx.length : 0; + for (size_t i = 0; i < dim; i++) { Expression exp = (*expsx)[i]; @@ -4049,6 +3973,8 @@ public: */ private Expression interpretAssignToSlice(UnionExp* pue, BinExp e, Expression e1, Expression newval, bool isBlockAssignment) { + //printf("interpretAssignToSlice(e: %s e1: %s newval: %s\n", e.toChars(), e1.toChars(), newval.toChars()); + dinteger_t lowerbound; dinteger_t upperbound; dinteger_t firstIndex; @@ -4108,7 +4034,7 @@ public: return newval; // For slice assignment, we check that the lengths match. - if (!isBlockAssignment) + if (!isBlockAssignment && e1.type.ty != Tpointer) { const srclen = resolveArrayLength(newval); if (srclen != (upperbound - lowerbound)) @@ -4323,8 +4249,8 @@ public: Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr) { Expressions* w = ae.elements; - assert(ae.type.ty == Tsarray || ae.type.ty == Tarray); - bool directblk = (cast(TypeArray)ae.type).next.equivalent(newval.type); + assert(ae.type.ty == Tsarray || ae.type.ty == Tarray || ae.type.ty == Tpointer); + bool directblk = (cast(TypeNext)ae.type).next.equivalent(newval.type); for (size_t k = lwr; k < upr; k++) { if (!directblk && (*w)[k].op == EXP.arrayLiteral) @@ -4848,25 +4774,6 @@ public: result = CTFEExp.voidexp; return; } - else if (fd.ident == Id._d_arraysetlengthT) - { - // In expressionsem.d `ea.length = eb;` got lowered to `_d_arraysetlengthT(ea, eb);`. - // The following code will rewrite it back to `ea.length = eb` and then interpret that expression. - assert(e.arguments.length == 2); - - Expression ea = (*e.arguments)[0]; - Expression eb = (*e.arguments)[1]; - - auto ale = ctfeEmplaceExp!ArrayLengthExp(e.loc, ea); - ale.type = Type.tsize_t; - AssignExp ae = ctfeEmplaceExp!AssignExp(e.loc, ale, eb); - ae.type = ea.type; - - // if (global.params.verbose) - // message("interpret %s =>\n %s", e.toChars(), ae.toChars()); - result = interpretRegion(ae, istate); - return; - } else if (isArrayConstructionOrAssign(fd.ident)) { // In expressionsem.d, the following lowerings were performed: @@ -5847,7 +5754,25 @@ public: e2 = ue2.copy(); } - *pue = ctfeCat(e.loc, e.type, e1, e2); + Expression prepareCatOperand(Expression exp) + { + /* Convert `elem ~ array` to `[elem] ~ array` if `elem` is itself an + * array. This is needed because interpreting the `CatExp` calls + * `Cat()`, which cannot handle concatenations between different + * types, except for strings and chars. + */ + auto tb = e.type.toBasetype(); + auto tbNext = tb.nextOf(); + auto expTb = exp.type.toBasetype(); + + if (exp.type.implicitConvTo(tbNext) >= MATCH.convert && + (tb.ty == Tarray || tb.ty == Tsarray) && + (expTb.ty == Tarray || expTb.ty == Tsarray)) + return new ArrayLiteralExp(exp.loc, e.type, exp); + return exp; + } + + *pue = ctfeCat(e.loc, e.type, prepareCatOperand(e1), prepareCatOperand(e2)); result = pue.exp(); if (CTFEExp.isCantExp(result)) @@ -6208,15 +6133,18 @@ public: { printf("%s ThrowExpression::interpret()\n", te.loc.toChars()); } - interpretThrow(te.e1, te.loc); + interpretThrow(result, te.e1, te.loc, istate); } override void visit(PtrExp e) { + // Called for both lvalues and rvalues + const lvalue = goal == CTFEGoal.LValue; debug (LOG) { - printf("%s PtrExp::interpret() %s\n", e.loc.toChars(), e.toChars()); + printf("%s PtrExp::interpret(%d) %s, %s\n", e.loc.toChars(), lvalue, e.type.toChars(), e.toChars()); } + // Check for int<->float and long<->double casts. if (auto soe1 = e.e1.isSymOffExp()) if (soe1.offset == 0 && soe1.var.isVarDeclaration() && isFloatIntPaint(e.type, soe1.var.type)) @@ -6274,6 +6202,20 @@ public: return; } + if (!lvalue && result.isArrayLiteralExp() && + result.type.isTypePointer()) + { + /* A pointer variable can point to an array literal like `[3]`. + * Dereferencing it means accessing the first element value. + * Dereference it only if result should be an rvalue + */ + auto ae = result.isArrayLiteralExp(); + if (ae.elements.length == 1) + { + result = (*ae.elements)[0]; + return; + } + } if (result.isStringExp() || result.isArrayLiteralExp()) return; @@ -6514,33 +6456,57 @@ public: { assert(0); // This should never be interpreted } +} - /********************************************* - * Checks if the given expresion is a call to the runtime hook `id`. - * Params: - * e = the expression to check - * id = the identifier of the runtime hook - * Returns: - * `e` cast to `CallExp` if it's the hook, `null` otherwise - */ - private CallExp isRuntimeHook(Expression e, Identifier id) +/// Interpret `throw ` found at the specified location `loc` +private +void interpretThrow(ref Expression result, Expression exp, const ref Loc loc, InterState* istate) +{ + incUsageCtfe(istate, loc); + + Expression e = interpretRegion(exp, istate); + if (exceptionOrCantInterpret(e)) { - if (auto ce = e.isCallExp()) + // Make sure e is not pointing to a stack temporary + result = (e.op == EXP.cantExpression) ? CTFEExp.cantexp : e; + } + else if (e.op == EXP.classReference) + { + result = ctfeEmplaceExp!ThrownExceptionExp(loc, e.isClassReferenceExp()); + } + else + { + exp.error("to be thrown `%s` must be non-null", exp.toChars()); + result = ErrorExp.get(); + } +} + +/********************************************* + * Checks if the given expresion is a call to the runtime hook `id`. + * + * Params: + * e = the expression to check + * id = the identifier of the runtime hook + * Returns: + * `e` cast to `CallExp` if it's the hook, `null` otherwise + */ +public CallExp isRuntimeHook(Expression e, Identifier id) +{ + if (auto ce = e.isCallExp()) + { + if (auto ve = ce.e1.isVarExp()) { - if (auto ve = ce.e1.isVarExp()) + if (auto fd = ve.var.isFuncDeclaration()) { - if (auto fd = ve.var.isFuncDeclaration()) - { - // If `_d_HookTraceImpl` is found, resolve the underlying - // hook and replace `e` and `fd` with it. - removeHookTraceImpl(ce, fd); - return fd.ident == id ? ce : null; - } + // If `_d_HookTraceImpl` is found, resolve the underlying hook + // and replace `e` and `fd` with it. + removeHookTraceImpl(ce, fd); + return fd.ident == id ? ce : null; } } - - return null; } + + return null; } /******************************************** @@ -6558,10 +6524,12 @@ Expression interpret(UnionExp* pue, Expression e, InterState* istate, CTFEGoal g { if (!e) return null; + //printf("+interpret() e : %s, %s\n", e.type.toChars(), e.toChars()); scope Interpreter v = new Interpreter(pue, istate, goal); e.accept(v); Expression ex = v.result; assert(goal == CTFEGoal.Nothing || ex !is null); + //if (ex) printf("-interpret() ex: %s, %s\n", ex.type.toChars(), ex.toChars()); else printf("-interpret()\n"); return ex; } @@ -6608,34 +6576,135 @@ Expression interpretRegion(Expression e, InterState* istate, CTFEGoal goal = CTF return cast(Expression)memcpy(p, cast(void*)uexp, uexp.size); } -/*********************************** - * Interpret the statement. - * Params: - * pue = non-null pointer to temporary storage that can be used to store the return value - * s = Statement to interpret - * istate = context - * Returns: - * NULL continue to next statement - * EXP.cantExpression cannot interpret statement at compile time - * !NULL expression from return statement, or thrown exception +private +Expressions* copyArrayOnWrite(Expressions* exps, Expressions* original) +{ + if (exps is original) + { + if (!original) + exps = new Expressions(); + else + exps = original.copy(); + ++ctfeGlobals.numArrayAllocs; + } + return exps; +} + +/** + Given an expression e which is about to be returned from the current + function, generate an error if it contains pointers to local variables. + + Only checks expressions passed by value (pointers to local variables + may already be stored in members of classes, arrays, or AAs which + were passed as mutable function parameters). + Returns: + true if it is safe to return, false if an error was generated. */ -Expression interpret(UnionExp* pue, Statement s, InterState* istate) +private +bool stopPointersEscaping(const ref Loc loc, Expression e) { - if (!s) - return null; - scope Interpreter v = new Interpreter(pue, istate, CTFEGoal.Nothing); - s.accept(v); - return v.result; + if (!e.type.hasPointers()) + return true; + if (isPointer(e.type)) + { + Expression x = e; + if (auto eaddr = e.isAddrExp()) + x = eaddr.e1; + VarDeclaration v; + while (x.op == EXP.variable && (v = x.isVarExp().var.isVarDeclaration()) !is null) + { + if (v.storage_class & STC.ref_) + { + x = getValue(v); + if (auto eaddr = e.isAddrExp()) + eaddr.e1 = x; + continue; + } + if (ctfeGlobals.stack.isInCurrentFrame(v)) + { + error(loc, "returning a pointer to a local stack variable"); + return false; + } + else + break; + } + // TODO: If it is a EXP.dotVariable or EXP.index, we should check that it is not + // pointing to a local struct or static array. + } + if (auto se = e.isStructLiteralExp()) + { + return stopPointersEscapingFromArray(loc, se.elements); + } + if (auto ale = e.isArrayLiteralExp()) + { + return stopPointersEscapingFromArray(loc, ale.elements); + } + if (auto aae = e.isAssocArrayLiteralExp()) + { + if (!stopPointersEscapingFromArray(loc, aae.keys)) + return false; + return stopPointersEscapingFromArray(loc, aae.values); + } + return true; } -/// -Expression interpret(Statement s, InterState* istate) +// Check all elements of an array for escaping local variables. Return false if error +private +bool stopPointersEscapingFromArray(const ref Loc loc, Expressions* elems) { - UnionExp ue = void; - auto result = interpret(&ue, s, istate); - if (result == ue.exp()) - result = ue.copy(); - return result; + foreach (e; *elems) + { + if (e && !stopPointersEscaping(loc, e)) + return false; + } + return true; +} + +private +Statement findGotoTarget(InterState* istate, Identifier ident) +{ + Statement target = null; + if (ident) + { + LabelDsymbol label = istate.fd.searchLabel(ident); + assert(label && label.statement); + LabelStatement ls = label.statement; + target = ls.gotoTarget ? ls.gotoTarget : ls.statement; + } + return target; +} + +private +ThrownExceptionExp chainExceptions(ThrownExceptionExp oldest, ThrownExceptionExp newest) +{ + debug (LOG) + { + printf("Collided exceptions %s %s\n", oldest.thrown.toChars(), newest.thrown.toChars()); + } + // Little sanity check to make sure it's really a Throwable + ClassReferenceExp boss = oldest.thrown; + const next = 5; // index of Throwable.next + assert((*boss.value.elements)[next].type.ty == Tclass); // Throwable.next + ClassReferenceExp collateral = newest.thrown; + if (collateral.originalClass().isErrorException() && !boss.originalClass().isErrorException()) + { + /* Find the index of the Error.bypassException field + */ + auto bypass = next + 1; + if ((*collateral.value.elements)[bypass].type.ty == Tuns32) + bypass += 1; // skip over _refcount field + assert((*collateral.value.elements)[bypass].type.ty == Tclass); + + // The new exception bypass the existing chain + (*collateral.value.elements)[bypass] = boss; + return newest; + } + while ((*boss.value.elements)[next].op == EXP.classReference) + { + boss = (*boss.value.elements)[next].isClassReferenceExp(); + } + (*boss.value.elements)[next] = collateral; + return oldest; } /** @@ -6978,7 +7047,6 @@ private Expression copyRegionExp(Expression e) case EXP.null_: case EXP.void_: case EXP.symbolOffset: - case EXP.char_: break; case EXP.cantExpression: diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index a5f7cd3..149a5b1 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -767,7 +767,7 @@ extern (C++) final class Module : Package { filetype = FileType.c; - scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines); + scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines, &global.compileEnv); p.nextToken(); checkCompiledImport(); members = p.parseModule(); @@ -776,7 +776,9 @@ extern (C++) final class Module : Package } else { - scope p = new Parser!AST(this, buf, cast(bool) docfile, global.errorSink); + const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; + scope p = new Parser!AST(this, buf, cast(bool) docfile, global.errorSink, &global.compileEnv, doUnittests); + p.transitionIn = global.params.vin; p.nextToken(); p.parseModuleDeclaration(); md = p.md; @@ -1229,8 +1231,7 @@ extern (C++) final class Module : Package return this.importedFrom == this; } - // true if the module source file is directly - // listed in command line. + /// Returns: Whether this module is in the `core` package and has name `ident` bool isCoreModule(Identifier ident) nothrow { return this.ident == ident && parent && parent.ident == Id.core && !parent.parent; @@ -1287,6 +1288,20 @@ extern (C++) final class Module : Package } /**************************** + * A Singleton that loads core.stdc.config + * Returns: + * Module of core.stdc.config, null if couldn't find it + */ + extern (D) static Module loadCoreStdcConfig() + { + __gshared Module core_stdc_config; + auto pkgids = new Identifier[2]; + pkgids[0] = Id.core; + pkgids[1] = Id.stdc; + return loadModuleFromLibrary(core_stdc_config, pkgids, Id.config); + } + + /**************************** * A Singleton that loads core.atomic * Returns: * Module of core.atomic, null if couldn't find it @@ -1294,7 +1309,9 @@ extern (C++) final class Module : Package extern (D) static Module loadCoreAtomic() { __gshared Module core_atomic; - return loadModuleFromLibrary(core_atomic, Id.core, Id.atomic); + auto pkgids = new Identifier[1]; + pkgids[0] = Id.core; + return loadModuleFromLibrary(core_atomic, pkgids, Id.atomic); } /**************************** @@ -1305,26 +1322,26 @@ extern (C++) final class Module : Package extern (D) static Module loadStdMath() { __gshared Module std_math; - return loadModuleFromLibrary(std_math, Id.std, Id.math); + auto pkgids = new Identifier[1]; + pkgids[0] = Id.std; + return loadModuleFromLibrary(std_math, pkgids, Id.math); } /********************************** * Load a Module from the library. * Params: * mod = cached return value of this call - * pkgid = package id + * pkgids = package identifiers * modid = module id * Returns: * Module loaded, null if cannot load it */ - private static Module loadModuleFromLibrary(ref Module mod, Identifier pkgid, Identifier modid) + extern (D) private static Module loadModuleFromLibrary(ref Module mod, Identifier[] pkgids, Identifier modid) { if (mod) return mod; - auto ids = new Identifier[1]; - ids[0] = pkgid; - auto imp = new Import(Loc.initial, ids[], modid, null, true); + auto imp = new Import(Loc.initial, pkgids[], modid, null, true); // Module.load will call fatal() if there's no module available. // Gag the error here, pushing the error handling to the caller. const errors = global.startGagging(); diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d index 88e8996..7674f77 100644 --- a/gcc/d/dmd/doc.d +++ b/gcc/d/dmd/doc.d @@ -5184,7 +5184,7 @@ private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t of scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1, global.errorSink, - global.vendor, global.versionNumber()); + &global.compileEnv); OutBuffer res; const(char)* lastp = cast(char*)buf[].ptr; //printf("highlightCode2('%.*s')\n", cast(int)(buf.length - 1), buf[].ptr); diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index ab422fd..95cfec9 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -813,4 +813,14 @@ extern (C++) struct Scope { return this.intypeof || this.flags & SCOPE.compile; } + + + /** + * Returns: true if the code needs to go all the way through to code generation. + * This implies things like needing lowering to simpler forms. + */ + extern (D) bool needsCodegen() + { + return (flags & (SCOPE.ctfe | SCOPE.ctfeBlock | SCOPE.compile)) == 0; + } } diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index 3268d56..49b9841 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -13,6 +13,8 @@ module dmd.dstruct; +import core.stdc.stdio; + import dmd.aggregate; import dmd.arraytypes; import dmd.astenums; @@ -75,7 +77,7 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t) { if (sc.intypeof) return; - if (sc.flags & (SCOPE.ctfe | SCOPE.compile | SCOPE.ctfeBlock)) + if (!sc.needsCodegen()) return; } @@ -567,7 +569,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration * Returns: * true if it's all binary 0 */ -private bool _isZeroInit(Expression exp) +bool _isZeroInit(Expression exp) { switch (exp.op) { @@ -575,20 +577,22 @@ private bool _isZeroInit(Expression exp) return exp.toInteger() == 0; case EXP.null_: - case EXP.false_: return true; case EXP.structLiteral: { - auto sle = cast(StructLiteralExp) exp; + auto sle = exp.isStructLiteralExp(); + if (sle.sd.isNested()) + return false; + const isCstruct = sle.sd.isCsymbol(); // C structs are default initialized to all zeros foreach (i; 0 .. sle.sd.fields.length) { auto field = sle.sd.fields[i]; if (field.type.size(field.loc)) { - auto e = (*sle.elements)[i]; + auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null; if (e ? !_isZeroInit(e) - : !field.type.isZeroInit(field.loc)) + : !isCstruct && !field.type.isZeroInit(field.loc)) return false; } } diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index e7ce93e..2373313 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -1407,7 +1407,7 @@ extern (C++) class Dsymbol : ASTNode inout(CPPNamespaceDeclaration) isCPPNamespaceDeclaration() inout { return null; } inout(VisibilityDeclaration) isVisibilityDeclaration() inout { return null; } inout(OverloadSet) isOverloadSet() inout { return null; } - inout(CompileDeclaration) isCompileDeclaration() inout { return null; } + inout(MixinDeclaration) isMixinDeclaration() inout { return null; } inout(StaticAssert) isStaticAssert() inout { return null; } inout(StaticIfDeclaration) isStaticIfDeclaration() inout { return null; } } diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h index 039a288..96fa8fd 100644 --- a/gcc/d/dmd/dsymbol.h +++ b/gcc/d/dmd/dsymbol.h @@ -321,7 +321,7 @@ public: virtual CPPNamespaceDeclaration *isCPPNamespaceDeclaration() { return NULL; } virtual VisibilityDeclaration *isVisibilityDeclaration() { return NULL; } virtual OverloadSet *isOverloadSet() { return NULL; } - virtual CompileDeclaration *isCompileDeclaration() { return NULL; } + virtual MixinDeclaration *isMixinDeclaration() { return NULL; } virtual StaticAssert *isStaticAssert() { return NULL; } virtual StaticIfDeclaration *isStaticIfDeclaration() { return NULL; } void accept(Visitor *v) override { v->visit(this); } diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 0f0ed2a..506946f 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -1321,6 +1321,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (dsym.errors) return; + if (!(global.params.bitfields || sc.flags & SCOPE.Cfile)) + dsym.error("use -preview=bitfields for bitfield support"); + if (!dsym.parent.isStructDeclaration() && !dsym.parent.isClassDeclaration()) { dsym.error("- bit-field must be member of struct, union, or class"); @@ -1923,9 +1926,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor attribSemantic(sfd); } - private Dsymbols* compileIt(CompileDeclaration cd) + private Dsymbols* compileIt(MixinDeclaration cd) { - //printf("CompileDeclaration::compileIt(loc = %d) %s\n", cd.loc.linnum, cd.exp.toChars()); + //printf("MixinDeclaration::compileIt(loc = %d) %s\n", cd.loc.linnum, cd.exp.toChars()); OutBuffer buf; if (expressionsToString(buf, sc, cd.exps)) return null; @@ -1934,7 +1937,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor const len = buf.length; buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; - scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false, global.errorSink); + const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; + auto loc = adjustLocForMixin(str, cd.loc, global.params.mixinOut); + scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + p.transitionIn = global.params.vin; p.nextToken(); auto d = p.parseDeclDefs(0); @@ -1952,9 +1958,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor /*********************************************************** * https://dlang.org/spec/module.html#mixin-declaration */ - override void visit(CompileDeclaration cd) + override void visit(MixinDeclaration cd) { - //printf("CompileDeclaration::semantic()\n"); + //printf("MixinDeclaration::semantic()\n"); if (!cd.compiled) { cd.decl = compileIt(cd); @@ -2252,32 +2258,39 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { /* C11 6.7.2.2 */ - assert(ed.memtype); - int nextValue = 0; // C11 6.7.2.2-3 first member value defaults to 0 + Type commonType = ed.memtype; + if (!commonType) + commonType = Type.tint32; + ulong nextValue = 0; // C11 6.7.2.2-3 first member value defaults to 0 // C11 6.7.2.2-2 value must be representable as an int. // The sizemask represents all values that int will fit into, // from 0..uint.max. We want to cover int.min..uint.max. - const mask = Type.tint32.sizemask(); - IntRange ir = IntRange(SignExtendedNumber(~(mask >> 1), true), - SignExtendedNumber(mask)); + IntRange ir = IntRange.fromType(commonType); - void emSemantic(EnumMember em, ref int nextValue) + void emSemantic(EnumMember em, ref ulong nextValue) { static void errorReturn(EnumMember em) { + em.value = ErrorExp.get(); em.errors = true; em.semanticRun = PASS.semanticdone; } em.semanticRun = PASS.semantic; - em.type = Type.tint32; + em.type = commonType; em._linkage = LINK.c; em.storage_class |= STC.manifest; if (em.value) { Expression e = em.value; assert(e.dyncast() == DYNCAST.expression); + + /* To merge the type of e with commonType, add 0 of type commonType + */ + if (!ed.memtype) + e = new AddExp(em.loc, e, new IntegerExp(em.loc, 0, commonType)); + e = e.expressionSemantic(sc); e = resolveProperties(sc, e); e = e.integralPromotions(sc); @@ -2291,14 +2304,16 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor em.error("enum member must be an integral constant expression, not `%s` of type `%s`", e.toChars(), e.type.toChars()); return errorReturn(em); } - if (!ir.contains(getIntRange(ie))) + if (ed.memtype && !ir.contains(getIntRange(ie))) { // C11 6.7.2.2-2 - em.error("enum member value `%s` does not fit in an `int`", e.toChars()); + em.error("enum member value `%s` does not fit in `%s`", e.toChars(), commonType.toChars()); return errorReturn(em); } - nextValue = cast(int)ie.toInteger(); - em.value = new IntegerExp(em.loc, nextValue, Type.tint32); + nextValue = ie.toInteger(); + if (!ed.memtype) + commonType = e.type; + em.value = new IntegerExp(em.loc, nextValue, commonType); } else { @@ -2306,17 +2321,17 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor bool first = (em == (*em.ed.members)[0]); if (!first) { - import core.checkedint : adds; - bool overflow; - nextValue = adds(nextValue, 1, overflow); - if (overflow) + Expression max = getProperty(commonType, null, em.loc, Id.max, 0); + if (nextValue == max.toInteger()) { - em.error("initialization with `%d+1` causes overflow for type `int`", nextValue - 1); + em.error("initialization with `%s+1` causes overflow for type `%s`", max.toChars(), commonType.toChars()); return errorReturn(em); } + nextValue += 1; } - em.value = new IntegerExp(em.loc, nextValue, Type.tint32); + em.value = new IntegerExp(em.loc, nextValue, commonType); } + em.type = commonType; em.semanticRun = PASS.semanticdone; } @@ -2325,6 +2340,21 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (EnumMember em = s.isEnumMember()) emSemantic(em, nextValue); }); + + if (!ed.memtype) + { + // cast all members to commonType + ed.members.foreachDsymbol( (s) + { + if (EnumMember em = s.isEnumMember()) + { + em.type = commonType; + em.value = em.value.castTo(sc, commonType); + } + }); + } + + ed.memtype = commonType; ed.semanticRun = PASS.semanticdone; return; } @@ -4662,7 +4692,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { sd.visibility = sc.visibility; - sd.alignment = sc.alignment(); + if (sd.alignment.isUnknown()) // can be set already by `struct __declspec(align(N)) Tag { ... }` + sd.alignment = sc.alignment(); sd.storage_class |= sc.stc; if (sd.storage_class & STC.abstract_) @@ -7228,3 +7259,83 @@ PINLINE evalPragmaInline(Loc loc, Scope* sc, Expressions* args) else return PINLINE.never; } + +/*************************************************** + * Set up loc for a parse of a mixin. Append the input text to the mixin. + * Params: + * input = mixin text + * loc = location to adjust + * mixinOut = sink for mixin text data + * Returns: + * adjusted loc suitable for Parser + */ + +Loc adjustLocForMixin(const(char)[] input, ref const Loc loc, ref Output mixinOut) +{ + Loc result; + if (mixinOut.doOutput) + { + const lines = mixinOut.bufferLines; + writeMixin(input, loc, mixinOut.bufferLines, *mixinOut.buffer); + result = Loc(mixinOut.name.ptr, lines + 2, loc.charnum); + } + else if (loc.filename) + { + /* Create a pseudo-filename for the mixin string, as it may not even exist + * in the source file. + */ + auto len = strlen(loc.filename) + 7 + (loc.linnum).sizeof * 3 + 1; + char* filename = cast(char*)mem.xmalloc(len); + snprintf(filename, len, "%s-mixin-%d", loc.filename, cast(int)loc.linnum); + result = Loc(filename, loc.linnum, loc.charnum); + } + else + result = loc; + return result; +} + +/************************************** + * Append source code text to output for better debugging. + * Canonicalize line endings. + * Params: + * s = source code text + * loc = location of source code text + * lines = line count to update + * output = sink for output + */ +private void writeMixin(const(char)[] s, ref const Loc loc, ref int lines, ref OutBuffer buf) +{ + buf.writestring("// expansion at "); + buf.writestring(loc.toChars()); + buf.writenl(); + + ++lines; + + // write by line to create consistent line endings + size_t lastpos = 0; + for (size_t i = 0; i < s.length; ++i) + { + // detect LF and CRLF + const c = s[i]; + if (c == '\n' || (c == '\r' && i+1 < s.length && s[i+1] == '\n')) + { + buf.writestring(s[lastpos .. i]); + buf.writenl(); + ++lines; + if (c == '\r') + ++i; + lastpos = i + 1; + } + } + + if(lastpos < s.length) + buf.writestring(s[lastpos .. $]); + + if (s.length == 0 || s[$-1] != '\n') + { + buf.writenl(); // ensure empty line after expansion + ++lines; + } + buf.writenl(); + ++lines; +} diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index ad3a6d4..ef743d6 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -741,9 +741,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol const(char)* toCharsMaybeConstraints(bool includeConstraints) const { - if (literal) - return Dsymbol.toChars(); - OutBuffer buf; HdrGenState hgs; @@ -1858,19 +1855,16 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol Type taai; if (argtype.ty == Tarray && (prmtype.ty == Tsarray || prmtype.ty == Taarray && (taai = (cast(TypeAArray)prmtype).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0)) { - if (farg.op == EXP.string_) + if (StringExp se = farg.isStringExp()) { - StringExp se = cast(StringExp)farg; argtype = se.type.nextOf().sarrayOf(se.len); } - else if (farg.op == EXP.arrayLiteral) + else if (ArrayLiteralExp ae = farg.isArrayLiteralExp()) { - ArrayLiteralExp ae = cast(ArrayLiteralExp)farg; argtype = ae.type.nextOf().sarrayOf(ae.elements.length); } - else if (farg.op == EXP.slice) + else if (SliceExp se = farg.isSliceExp()) { - SliceExp se = cast(SliceExp)farg; if (Type tsa = toStaticArrayType(se)) argtype = tsa; } @@ -2283,18 +2277,23 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol Declaration d; VarDeclaration v = null; - if (ea && ea.op == EXP.type) - ta = ea.type; - else if (ea && ea.op == EXP.scope_) - sa = (cast(ScopeExp)ea).sds; - else if (ea && (ea.op == EXP.this_ || ea.op == EXP.super_)) - sa = (cast(ThisExp)ea).var; - else if (ea && ea.op == EXP.function_) + if (ea) { - if ((cast(FuncExp)ea).td) - sa = (cast(FuncExp)ea).td; - else - sa = (cast(FuncExp)ea).fd; + if (ea.op == EXP.type) + ta = ea.type; + else if (auto se = ea.isScopeExp()) + sa = se.sds; + else if (auto te = ea.isThisExp()) + sa = te.var; + else if (auto se = ea.isSuperExp()) + sa = se.var; + else if (auto fe = ea.isFuncExp()) + { + if (fe.td) + sa = fe.td; + else + sa = fe.fd; + } } if (ta) @@ -3856,9 +3855,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param if (tparam.ty == Tsarray) { TypeSArray tsa = cast(TypeSArray)tparam; - if (tsa.dim.op == EXP.variable && (cast(VarExp)tsa.dim).var.storage_class & STC.templateparameter) + if (tsa.dim.isVarExp() && tsa.dim.isVarExp().var.storage_class & STC.templateparameter) { - Identifier id = (cast(VarExp)tsa.dim).var.ident; + Identifier id = tsa.dim.isVarExp().var.ident; i = templateIdentifierLookup(id, parameters); assert(i != IDX_NOTFOUND); tp = (*parameters)[i]; @@ -4250,12 +4249,12 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param /* If it is one of the template parameters for this template, * we should not attempt to interpret it. It already has a value. */ - if (e2.op == EXP.variable && ((cast(VarExp)e2).var.storage_class & STC.templateparameter)) + if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter)) { /* * (T:Number!(e2), int e2) */ - j = templateIdentifierLookup((cast(VarExp)e2).var.ident, parameters); + j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters); if (j != IDX_NOTFOUND) goto L1; // The template parameter was not from this template @@ -5236,7 +5235,7 @@ private bool reliesOnTemplateParameters(Expression e, TemplateParameter[] tparam override void visit(DotTemplateInstanceExp e) { //printf("DotTemplateInstanceExp.reliesOnTemplateParameters('%s')\n", e.toChars()); - visit(cast(UnaExp)e); + visit(e.isUnaExp()); if (!result && e.ti.tiargs) { foreach (oa; *e.ti.tiargs) @@ -5254,7 +5253,7 @@ private bool reliesOnTemplateParameters(Expression e, TemplateParameter[] tparam override void visit(CallExp e) { //printf("CallExp.reliesOnTemplateParameters('%s')\n", e.toChars()); - visit(cast(UnaExp)e); + visit(e.isUnaExp()); if (!result && e.arguments) { foreach (ea; *e.arguments) @@ -5269,7 +5268,7 @@ private bool reliesOnTemplateParameters(Expression e, TemplateParameter[] tparam override void visit(CastExp e) { //printf("CallExp.reliesOnTemplateParameters('%s')\n", e.toChars()); - visit(cast(UnaExp)e); + visit(e.isUnaExp()); // e.to can be null for cast() with no type if (!result && e.to) result = e.to.reliesOnTemplateParameters(tparams); @@ -5278,7 +5277,7 @@ private bool reliesOnTemplateParameters(Expression e, TemplateParameter[] tparam override void visit(SliceExp e) { //printf("SliceExp.reliesOnTemplateParameters('%s')\n", e.toChars()); - visit(cast(UnaExp)e); + visit(e.isUnaExp()); if (!result && e.lwr) e.lwr.accept(this); if (!result && e.upr) @@ -5296,7 +5295,7 @@ private bool reliesOnTemplateParameters(Expression e, TemplateParameter[] tparam override void visit(ArrayExp e) { //printf("ArrayExp.reliesOnTemplateParameters('%s')\n", e.toChars()); - visit(cast(UnaExp)e); + visit(e.isUnaExp()); if (!result && e.arguments) { foreach (ea; *e.arguments) @@ -5317,7 +5316,7 @@ private bool reliesOnTemplateParameters(Expression e, TemplateParameter[] tparam //printf("BinExp.reliesOnTemplateParameters('%s')\n", e.toChars()); e.econd.accept(this); if (!result) - visit(cast(BinExp)e); + visit(e.isBinExp()); } } @@ -6727,7 +6726,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol ea = ea.expressionSemantic(sc); // must not interpret the args, excepting template parameters - if (ea.op != EXP.variable || ((cast(VarExp)ea).var.storage_class & STC.templateparameter)) + if (!ea.isVarExp() || (ea.isVarExp().var.storage_class & STC.templateparameter)) { ea = ea.optimize(WANTvalue); } @@ -6738,13 +6737,13 @@ extern (C++) class TemplateInstance : ScopeDsymbol ea = ea.expressionSemantic(sc); sc = sc.endCTFE(); - if (ea.op == EXP.variable) + if (auto varExp = ea.isVarExp()) { /* If the parameter is a function that is not called * explicitly, i.e. `foo!func` as opposed to `foo!func()`, * then it is a dsymbol, not the return value of `func()` */ - Declaration vd = (cast(VarExp)ea).var; + Declaration vd = varExp.var; if (auto fd = vd.isFuncDeclaration()) { sa = fd; @@ -6767,10 +6766,9 @@ extern (C++) class TemplateInstance : ScopeDsymbol } } //printf("-[%d] ea = %s %s\n", j, EXPtoString(ea.op).ptr, ea.toChars()); - if (ea.op == EXP.tuple) + if (TupleExp te = ea.isTupleExp()) { // Expand tuple - TupleExp te = cast(TupleExp)ea; size_t dim = te.exps.length; tiargs.remove(j); if (dim) @@ -6796,12 +6794,11 @@ extern (C++) class TemplateInstance : ScopeDsymbol } if (ea.op == EXP.scope_) { - sa = (cast(ScopeExp)ea).sds; + sa = ea.isScopeExp().sds; goto Ldsym; } - if (ea.op == EXP.function_) + if (FuncExp fe = ea.isFuncExp()) { - FuncExp fe = cast(FuncExp)ea; /* A function literal, that is passed to template and * already semanticed as function pointer, never requires * outer frame. So convert it to global function is valid. @@ -6823,23 +6820,23 @@ extern (C++) class TemplateInstance : ScopeDsymbol if (ea.op == EXP.dotVariable && !(flags & 1)) { // translate expression to dsymbol. - sa = (cast(DotVarExp)ea).var; + sa = ea.isDotVarExp().var; goto Ldsym; } - if (ea.op == EXP.template_) + if (auto te = ea.isTemplateExp()) { - sa = (cast(TemplateExp)ea).td; + sa = te.td; goto Ldsym; } if (ea.op == EXP.dotTemplateDeclaration && !(flags & 1)) { // translate expression to dsymbol. - sa = (cast(DotTemplateExp)ea).td; + sa = ea.isDotTemplateExp().td; goto Ldsym; } - if (ea.op == EXP.dot) + if (auto de = ea.isDotExp()) { - if (auto se = (cast(DotExp)ea).e2.isScopeExp()) + if (auto se = de.e2.isScopeExp()) { sa = se.sds; goto Ldsym; @@ -7340,22 +7337,22 @@ extern (C++) class TemplateInstance : ScopeDsymbol Tuple va = isTuple(o); if (ea) { - if (ea.op == EXP.variable) + if (auto ve = ea.isVarExp()) { - sa = (cast(VarExp)ea).var; + sa = ve.var; goto Lsa; } - if (ea.op == EXP.this_) + if (auto te = ea.isThisExp()) { - sa = (cast(ThisExp)ea).var; + sa = te.var; goto Lsa; } - if (ea.op == EXP.function_) + if (auto fe = ea.isFuncExp()) { - if ((cast(FuncExp)ea).td) - sa = (cast(FuncExp)ea).td; + if (fe.td) + sa = fe.td; else - sa = (cast(FuncExp)ea).fd; + sa = fe.fd; goto Lsa; } // Emulate Expression.toMangleBuffer call that had exist in TemplateInstance.genIdent. @@ -7727,13 +7724,13 @@ bool definitelyValueParameter(Expression e) */ // x.y.f cannot be a value - FuncDeclaration f = (cast(DotVarExp)e).var.isFuncDeclaration(); + FuncDeclaration f = e.isDotVarExp().var.isFuncDeclaration(); if (f) return false; while (e.op == EXP.dotVariable) { - e = (cast(DotVarExp)e).e1; + e = e.isDotVarExp().e1; } // this.x.y and super.x.y couldn't possibly be valid values. if (e.op == EXP.this_ || e.op == EXP.super_) @@ -7747,7 +7744,7 @@ bool definitelyValueParameter(Expression e) if (e.op != EXP.variable) return true; - VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration(); + VarDeclaration v = e.isVarExp().var.isVarDeclaration(); // func.x.y is not an alias if (!v) return true; @@ -8242,10 +8239,15 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ Type ta = isType(oarg); RootObject sa = ta && !ta.deco ? null : getDsymbol(oarg); Expression ea = isExpression(oarg); - if (ea && (ea.op == EXP.this_ || ea.op == EXP.super_)) - sa = (cast(ThisExp)ea).var; - else if (ea && ea.op == EXP.scope_) - sa = (cast(ScopeExp)ea).sds; + if (ea) + { + if (auto te = ea.isThisExp()) + sa = te.var; + else if (auto se = ea.isSuperExp()) + sa = se.var; + else if (auto se = ea.isScopeExp()) + sa = se.sds; + } if (sa) { if ((cast(Dsymbol)sa).isAggregateDeclaration()) diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index 7c3ff4b..f00b8db 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -84,9 +84,9 @@ extern(C++) void genCppHdrFiles(ref Modules ms) m.accept(v); if (global.params.cxxhdr.fullOutput) - buf.printf("// Automatically generated by %s Compiler v%d", global.vendor.ptr, global.versionNumber()); + buf.printf("// Automatically generated by %s Compiler v%d", global.compileEnv.vendor.ptr, global.versionNumber()); else - buf.printf("// Automatically generated by %s Compiler", global.vendor.ptr); + buf.printf("// Automatically generated by %s Compiler", global.compileEnv.vendor.ptr); buf.writenl(); buf.writenl(); diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d index f107f7b..287dc49 100644 --- a/gcc/d/dmd/errors.d +++ b/gcc/d/dmd/errors.d @@ -66,6 +66,14 @@ class ErrorSinkCompiler : ErrorSink vdeprecationSupplemental(loc, format, ap); va_end(ap); } + + void message(const ref Loc loc, const(char)* format, ...) + { + va_list ap; + va_start(ap, format); + vmessage(loc, format, ap); + va_end(ap); + } } diff --git a/gcc/d/dmd/errorsink.d b/gcc/d/dmd/errorsink.d index b519db7..e57c2b6 100644 --- a/gcc/d/dmd/errorsink.d +++ b/gcc/d/dmd/errorsink.d @@ -27,6 +27,8 @@ abstract class ErrorSink void warning(const ref Loc loc, const(char)* format, ...); + void message(const ref Loc loc, const(char)* format, ...); + void deprecation(const ref Loc loc, const(char)* format, ...); void deprecationSupplemental(const ref Loc loc, const(char)* format, ...); @@ -47,6 +49,8 @@ class ErrorSinkNull : ErrorSink void warning(const ref Loc loc, const(char)* format, ...) { } + void message(const ref Loc loc, const(char)* format, ...) { } + void deprecation(const ref Loc loc, const(char)* format, ...) { } void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { } @@ -117,5 +121,21 @@ class ErrorSinkStderr : ErrorSink va_end(ap); } + void message(const ref Loc loc, const(char)* format, ...) + { + const p = loc.toChars(); + if (*p) + { + fprintf(stderr, "%s: ", p); + //mem.xfree(cast(void*)p); // loc should provide the free() + } + + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + fputc('\n', stderr); + va_end(ap); + } + void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { } } diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index 420fa7f..4f1edaa 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -2377,7 +2377,7 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f) foreach (u, p; f.parameterList) { auto v = (*funcdecl.parameters)[u]; - if (!v.isScope() && inferScope(v)) + if (!v.isScope() && v.type.hasPointers() && inferScope(v)) { //printf("Inferring scope for %s\n", v.toChars()); p.storageClass |= STC.scope_ | STC.scopeinferred; diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index df5e9dd..067d22f 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -720,20 +720,21 @@ enum WANTexpand = 1; // expand const/immutable variables if possible */ extern (C++) abstract class Expression : ASTNode { - const EXP op; // to minimize use of dynamic_cast - ubyte size; // # of bytes in Expression so we can copy() it - bool parens; // if this is a parenthesized expression Type type; // !=null means that semantic() has been run Loc loc; // file location + const EXP op; // to minimize use of dynamic_cast + bool parens; // if this is a parenthesized expression - extern (D) this(const ref Loc loc, EXP op, int size) scope + extern (D) this(const ref Loc loc, EXP op) scope { //printf("Expression::Expression(op = %d) this = %p\n", op, this); this.loc = loc; this.op = op; - this.size = cast(ubyte)size; } + /// Returns: class instance size of this expression (implemented manually because `extern(C++)`) + final size_t size() nothrow @nogc pure @safe const { return expSize[op]; } + static void _init() { CTFEExp.cantexp = new CTFEExp(EXP.cantExpression); @@ -1219,12 +1220,15 @@ extern (C++) abstract class Expression : ASTNode return false; // If the call has a pure parent, then the called func must be pure. - if (!f.isPure() && checkImpure(sc)) + if (!f.isPure() && checkImpure(sc, loc, null, f)) { error("`pure` %s `%s` cannot call impure %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), f.kind(), f.toPrettyChars()); + if (!f.isDtorDeclaration()) + errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.pure_); + checkOverridenDtor(sc, f, dd => dd.type.toTypeFunction().purity != PURE.impure, "impure"); return true; } @@ -1355,7 +1359,7 @@ extern (C++) abstract class Expression : ASTNode if (v.ident == Id.gate) return false; - if (checkImpure(sc)) + if (checkImpure(sc, loc, "`pure` %s `%s` cannot access mutable static data `%s`", v)) { error("`pure` %s `%s` cannot access mutable static data `%s`", sc.func.kind(), sc.func.toPrettyChars(), v.toChars()); @@ -1431,11 +1435,11 @@ extern (C++) abstract class Expression : ASTNode Check if sc.func is impure or can be made impure. Returns true on error, i.e. if sc.func is pure and cannot be made impure. */ - private static bool checkImpure(Scope* sc) + private static bool checkImpure(Scope* sc, Loc loc, const(char)* fmt, RootObject arg0) { return sc.func && (isRootTraitsCompilesScope(sc) ? sc.func.isPureBypassingInference() >= PURE.weak - : sc.func.setImpure()); + : sc.func.setImpure(loc, fmt, arg0)); } /********************************************* @@ -1484,7 +1488,8 @@ extern (C++) abstract class Expression : ASTNode error("`@safe` %s `%s` cannot call `@system` %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), f.kind(), prettyChars); - f.errorSupplementalInferredSafety(/*max depth*/ 10, /*deprecation*/ false); + if (!f.isDtorDeclaration) + errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.safe); .errorSupplemental(f.loc, "`%s` is declared here", prettyChars); checkOverridenDtor(sc, f, dd => dd.type.toTypeFunction().trust > TRUST.system, "@system"); @@ -1498,7 +1503,7 @@ extern (C++) abstract class Expression : ASTNode if (sc.func.isSafeBypassingInference()) { .deprecation(this.loc, "`@safe` function `%s` calling `%s`", sc.func.toChars(), f.toChars()); - errorSupplementalInferredSafety(f, 10, true); + errorSupplementalInferredAttr(f, 10, true, STC.safe); } else if (!sc.func.safetyViolation) { @@ -1528,7 +1533,7 @@ extern (C++) abstract class Expression : ASTNode if (!f.isNogc()) { - if (isRootTraitsCompilesScope(sc) ? sc.func.isNogcBypassingInference() : sc.func.setGC()) + if (isRootTraitsCompilesScope(sc) ? sc.func.isNogcBypassingInference() : sc.func.setGCCall(f)) { if (loc.linnum == 0) // e.g. implicitly generated dtor loc = sc.func.loc; @@ -1537,10 +1542,15 @@ extern (C++) abstract class Expression : ASTNode // so don't print anything to avoid double error messages. if (!(f.ident == Id._d_HookTraceImpl || f.ident == Id._d_arraysetlengthT || f.ident == Id._d_arrayappendT || f.ident == Id._d_arrayappendcTX - || f.ident == Id._d_newclassT)) + || f.ident == Id._d_arraycatnTX || f.ident == Id._d_newclassT)) + { error("`@nogc` %s `%s` cannot call non-@nogc %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), f.kind(), f.toPrettyChars()); + if (!f.isDtorDeclaration) + f.errorSupplementalInferredAttr(/*max depth*/ 10, /*deprecation*/ false, STC.nogc); + } + checkOverridenDtor(sc, f, dd => dd.type.toTypeFunction().isnogc, "non-@nogc"); return true; @@ -1775,6 +1785,7 @@ extern (C++) abstract class Expression : ASTNode inout(PostExp) isPostExp() { return (op == EXP.plusPlus || op == EXP.minusMinus) ? cast(typeof(return))this : null; } inout(PreExp) isPreExp() { return (op == EXP.prePlusPlus || op == EXP.preMinusMinus) ? cast(typeof(return))this : null; } inout(AssignExp) isAssignExp() { return op == EXP.assign ? cast(typeof(return))this : null; } + inout(LoweredAssignExp) isLoweredAssignExp() { return op == EXP.loweredAssignExp ? cast(typeof(return))this : null; } inout(ConstructExp) isConstructExp() { return op == EXP.construct ? cast(typeof(return))this : null; } inout(BlitExp) isBlitExp() { return op == EXP.blit ? cast(typeof(return))this : null; } inout(AddAssignExp) isAddAssignExp() { return op == EXP.addAssign ? cast(typeof(return))this : null; } @@ -1866,7 +1877,7 @@ extern (C++) final class IntegerExp : Expression extern (D) this(const ref Loc loc, dinteger_t value, Type type) { - super(loc, EXP.int64, __traits(classInstanceSize, IntegerExp)); + super(loc, EXP.int64); //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type.toChars() : ""); assert(type); if (!type.isscalar()) @@ -1882,7 +1893,7 @@ extern (C++) final class IntegerExp : Expression extern (D) this(dinteger_t value) { - super(Loc.initial, EXP.int64, __traits(classInstanceSize, IntegerExp)); + super(Loc.initial, EXP.int64); this.type = Type.tint32; this.value = cast(int)value; } @@ -2082,7 +2093,7 @@ extern (C++) final class ErrorExp : Expression { private extern (D) this() { - super(Loc.initial, EXP.error, __traits(classInstanceSize, ErrorExp)); + super(Loc.initial, EXP.error); type = Type.terror; } @@ -2130,7 +2141,7 @@ extern (C++) final class VoidInitExp : Expression extern (D) this(VarDeclaration var) { - super(var.loc, EXP.void_, __traits(classInstanceSize, VoidInitExp)); + super(var.loc, EXP.void_); this.var = var; this.type = var.type; } @@ -2156,7 +2167,7 @@ extern (C++) final class RealExp : Expression extern (D) this(const ref Loc loc, real_t value, Type type) { - super(loc, EXP.float64, __traits(classInstanceSize, RealExp)); + super(loc, EXP.float64); //printf("RealExp::RealExp(%Lg)\n", value); this.value = value; this.type = type; @@ -2239,7 +2250,7 @@ extern (C++) final class ComplexExp : Expression extern (D) this(const ref Loc loc, complex_t value, Type type) { - super(loc, EXP.complex80, __traits(classInstanceSize, ComplexExp)); + super(loc, EXP.complex80); this.value = value; this.type = type; //printf("ComplexExp::ComplexExp(%s)\n", toChars()); @@ -2330,7 +2341,7 @@ extern (C++) class IdentifierExp : Expression extern (D) this(const ref Loc loc, Identifier ident) scope { - super(loc, EXP.identifier, __traits(classInstanceSize, IdentifierExp)); + super(loc, EXP.identifier); this.ident = ident; } @@ -2383,7 +2394,7 @@ extern (C++) final class DsymbolExp : Expression extern (D) this(const ref Loc loc, Dsymbol s, bool hasOverloads = true) { - super(loc, EXP.dSymbol, __traits(classInstanceSize, DsymbolExp)); + super(loc, EXP.dSymbol); this.s = s; this.hasOverloads = hasOverloads; } @@ -2413,13 +2424,13 @@ extern (C++) class ThisExp : Expression extern (D) this(const ref Loc loc) { - super(loc, EXP.this_, __traits(classInstanceSize, ThisExp)); + super(loc, EXP.this_); //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum); } this(const ref Loc loc, const EXP tok) { - super(loc, tok, __traits(classInstanceSize, ThisExp)); + super(loc, tok); //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum); } @@ -2485,7 +2496,7 @@ extern (C++) final class NullExp : Expression { extern (D) this(const ref Loc loc, Type type = null) scope { - super(loc, EXP.null_, __traits(classInstanceSize, NullExp)); + super(loc, EXP.null_); this.type = type; } @@ -2529,6 +2540,8 @@ extern (C++) final class NullExp : Expression */ extern (C++) final class StringExp : Expression { + char postfix = NoPostfix; // 'c', 'w', 'd' + OwnedBy ownedByCtfe = OwnedBy.code; private union { char* string; // if sz == 1 @@ -2537,14 +2550,22 @@ extern (C++) final class StringExp : Expression } // (const if ownedByCtfe == OwnedBy.code) size_t len; // number of code units ubyte sz = 1; // 1: char, 2: wchar, 4: dchar - ubyte committed; // !=0 if type is committed + + /** + * Whether the string literal's type is fixed + * Example: + * --- + * wstring x = "abc"; // OK, string literal is flexible + * wstring y = cast(string) "abc"; // Error: type was committed after cast + * --- + */ + bool committed; + enum char NoPostfix = 0; - char postfix = NoPostfix; // 'c', 'w', 'd' - OwnedBy ownedByCtfe = OwnedBy.code; extern (D) this(const ref Loc loc, const(void)[] string) scope { - super(loc, EXP.string_, __traits(classInstanceSize, StringExp)); + super(loc, EXP.string_); this.string = cast(char*)string.ptr; // note that this.string should be const this.len = string.length; this.sz = 1; // work around LDC bug #1286 @@ -2552,7 +2573,7 @@ extern (C++) final class StringExp : Expression extern (D) this(const ref Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = NoPostfix) scope { - super(loc, EXP.string_, __traits(classInstanceSize, StringExp)); + super(loc, EXP.string_); this.string = cast(char*)string.ptr; // note that this.string should be const this.len = len; this.sz = sz; @@ -2750,7 +2771,7 @@ extern (C++) final class StringExp : Expression if (sz != 1) { // Convert to UTF-8 string - committed = 0; + committed = false; Expression e = castTo(sc, Type.tchar.arrayOf()); e = e.optimize(WANTvalue); auto se = e.isStringExp(); @@ -2939,7 +2960,7 @@ extern (C++) final class TupleExp : Expression extern (D) this(const ref Loc loc, Expression e0, Expressions* exps) { - super(loc, EXP.tuple, __traits(classInstanceSize, TupleExp)); + super(loc, EXP.tuple); //printf("TupleExp(this = %p)\n", this); this.e0 = e0; this.exps = exps; @@ -2947,14 +2968,14 @@ extern (C++) final class TupleExp : Expression extern (D) this(const ref Loc loc, Expressions* exps) { - super(loc, EXP.tuple, __traits(classInstanceSize, TupleExp)); + super(loc, EXP.tuple); //printf("TupleExp(this = %p)\n", this); this.exps = exps; } extern (D) this(const ref Loc loc, TupleDeclaration tup) { - super(loc, EXP.tuple, __traits(classInstanceSize, TupleExp)); + super(loc, EXP.tuple); this.exps = new Expressions(); this.exps.reserve(tup.objects.length); @@ -3031,6 +3052,9 @@ extern (C++) final class TupleExp : Expression */ extern (C++) final class ArrayLiteralExp : Expression { + OwnedBy ownedByCtfe = OwnedBy.code; + bool onstack = false; + /** If !is null, elements[] can be sparse and basis is used for the * "default" element value. In other words, non-null elements[i] overrides * this 'basis' value. @@ -3038,19 +3062,17 @@ extern (C++) final class ArrayLiteralExp : Expression Expression basis; Expressions* elements; - OwnedBy ownedByCtfe = OwnedBy.code; - bool onstack = false; extern (D) this(const ref Loc loc, Type type, Expressions* elements) { - super(loc, EXP.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp)); + super(loc, EXP.arrayLiteral); this.type = type; this.elements = elements; } extern (D) this(const ref Loc loc, Type type, Expression e) { - super(loc, EXP.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp)); + super(loc, EXP.arrayLiteral); this.type = type; elements = new Expressions(); elements.push(e); @@ -3058,7 +3080,7 @@ extern (C++) final class ArrayLiteralExp : Expression extern (D) this(const ref Loc loc, Type type, Expression basis, Expressions* elements) { - super(loc, EXP.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp)); + super(loc, EXP.arrayLiteral); this.type = type; this.basis = basis; this.elements = elements; @@ -3196,14 +3218,14 @@ extern (C++) final class ArrayLiteralExp : Expression */ extern (C++) final class AssocArrayLiteralExp : Expression { + OwnedBy ownedByCtfe = OwnedBy.code; + Expressions* keys; Expressions* values; - OwnedBy ownedByCtfe = OwnedBy.code; - extern (D) this(const ref Loc loc, Expressions* keys, Expressions* values) { - super(loc, EXP.assocArrayLiteral, __traits(classInstanceSize, AssocArrayLiteralExp)); + super(loc, EXP.assocArrayLiteral); assert(keys.length == values.length); this.keys = keys; this.values = values; @@ -3271,7 +3293,15 @@ extern (C++) final class StructLiteralExp : Expression Expressions* elements; /// parallels sd.fields[] with null entries for fields to skip Type stype; /// final type of result (can be different from sd's type) - Symbol* sym; /// back end symbol to initialize with literal + // `inlineCopy` is only used temporarily in the `inline.d` pass, + // while `sym` is only used in `e2ir/s2ir/tocsym` which comes after + union + { + Symbol* sym; /// back end symbol to initialize with literal + + /// those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer. + StructLiteralExp inlinecopy; + } /** pointer to the origin instance of the expression. * once a new expression is created, origin is set to 'this'. @@ -3280,15 +3310,13 @@ extern (C++) final class StructLiteralExp : Expression */ StructLiteralExp origin; - /// those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer. - StructLiteralExp inlinecopy; /** anytime when recursive function is calling, 'stageflags' marks with bit flag of * current stage and unmarks before return from this function. * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline' * (with infinite recursion) of this expression. */ - int stageflags; + ubyte stageflags; bool useStaticInit; /// if this is true, use the StructDeclaration's init symbol bool isOriginal = false; /// used when moving instances to indicate `this is this.origin` @@ -3296,7 +3324,7 @@ extern (C++) final class StructLiteralExp : Expression extern (D) this(const ref Loc loc, StructDeclaration sd, Expressions* elements, Type stype = null) { - super(loc, EXP.structLiteral, __traits(classInstanceSize, StructLiteralExp)); + super(loc, EXP.structLiteral); this.sd = sd; if (!elements) elements = new Expressions(); @@ -3475,7 +3503,7 @@ extern (C++) final class CompoundLiteralExp : Expression extern (D) this(const ref Loc loc, Type type_name, Initializer initializer) { - super(loc, EXP.compoundLiteral, __traits(classInstanceSize, CompoundLiteralExp)); + super(loc, EXP.compoundLiteral); super.type = type_name; this.initializer = initializer; //printf("CompoundLiteralExp::CompoundLiteralExp(%s)\n", toChars()); @@ -3494,7 +3522,7 @@ extern (C++) final class TypeExp : Expression { extern (D) this(const ref Loc loc, Type type) { - super(loc, EXP.type, __traits(classInstanceSize, TypeExp)); + super(loc, EXP.type); //printf("TypeExp::TypeExp(%s)\n", type.toChars()); this.type = type; } @@ -3536,7 +3564,7 @@ extern (C++) final class ScopeExp : Expression extern (D) this(const ref Loc loc, ScopeDsymbol sds) { - super(loc, EXP.scope_, __traits(classInstanceSize, ScopeExp)); + super(loc, EXP.scope_); //printf("ScopeExp::ScopeExp(sds = '%s')\n", sds.toChars()); //static int count; if (++count == 38) *(char*)0=0; this.sds = sds; @@ -3591,7 +3619,7 @@ extern (C++) final class TemplateExp : Expression extern (D) this(const ref Loc loc, TemplateDeclaration td, FuncDeclaration fd = null) { - super(loc, EXP.template_, __traits(classInstanceSize, TemplateExp)); + super(loc, EXP.template_); //printf("TemplateExp(): %s\n", td.toChars()); this.td = td; this.fd = fd; @@ -3652,7 +3680,7 @@ extern (C++) final class NewExp : Expression extern (D) this(const ref Loc loc, Expression thisexp, Type newtype, Expressions* arguments, Identifiers* names = null) { - super(loc, EXP.new_, __traits(classInstanceSize, NewExp)); + super(loc, EXP.new_); this.thisexp = thisexp; this.newtype = newtype; this.arguments = arguments; @@ -3690,7 +3718,7 @@ extern (C++) final class NewAnonClassExp : Expression extern (D) this(const ref Loc loc, Expression thisexp, ClassDeclaration cd, Expressions* arguments) { - super(loc, EXP.newAnonymousClass, __traits(classInstanceSize, NewAnonClassExp)); + super(loc, EXP.newAnonymousClass); this.thisexp = thisexp; this.cd = cd; this.arguments = arguments; @@ -3715,9 +3743,9 @@ extern (C++) class SymbolExp : Expression Dsymbol originalScope; // original scope before inlining bool hasOverloads; - extern (D) this(const ref Loc loc, EXP op, int size, Declaration var, bool hasOverloads) + extern (D) this(const ref Loc loc, EXP op, Declaration var, bool hasOverloads) { - super(loc, op, size); + super(loc, op); assert(var); this.var = var; this.hasOverloads = hasOverloads; @@ -3746,7 +3774,7 @@ extern (C++) final class SymOffExp : SymbolExp .error(loc, "need `this` for address of `%s`", v.toChars()); hasOverloads = false; } - super(loc, EXP.symbolOffset, __traits(classInstanceSize, SymOffExp), var, hasOverloads); + super(loc, EXP.symbolOffset, var, hasOverloads); this.offset = offset; } @@ -3772,7 +3800,7 @@ extern (C++) final class VarExp : SymbolExp if (var.isVarDeclaration()) hasOverloads = false; - super(loc, EXP.variable, __traits(classInstanceSize, VarExp), var, hasOverloads); + super(loc, EXP.variable, var, hasOverloads); //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var.toChars(), loc.toChars()); //if (strcmp(var.ident.toChars(), "func") == 0) assert(0); this.type = var.type; @@ -3856,7 +3884,7 @@ extern (C++) final class OverExp : Expression extern (D) this(const ref Loc loc, OverloadSet s) { - super(loc, EXP.overloadSet, __traits(classInstanceSize, OverExp)); + super(loc, EXP.overloadSet); //printf("OverExp(this = %p, '%s')\n", this, var.toChars()); vars = s; type = Type.tvoid; @@ -3890,7 +3918,7 @@ extern (C++) final class FuncExp : Expression extern (D) this(const ref Loc loc, Dsymbol s) { - super(loc, EXP.function_, __traits(classInstanceSize, FuncExp)); + super(loc, EXP.function_); this.td = s.isTemplateDeclaration(); this.fd = s.isFuncLiteralDeclaration(); if (td) @@ -4189,7 +4217,7 @@ extern (C++) final class DeclarationExp : Expression extern (D) this(const ref Loc loc, Dsymbol declaration) { - super(loc, EXP.declaration, __traits(classInstanceSize, DeclarationExp)); + super(loc, EXP.declaration); this.declaration = declaration; } @@ -4222,7 +4250,7 @@ extern (C++) final class TypeidExp : Expression extern (D) this(const ref Loc loc, RootObject o) { - super(loc, EXP.typeid_, __traits(classInstanceSize, TypeidExp)); + super(loc, EXP.typeid_); this.obj = o; } @@ -4247,7 +4275,7 @@ extern (C++) final class TraitsExp : Expression extern (D) this(const ref Loc loc, Identifier ident, Objects* args) { - super(loc, EXP.traits, __traits(classInstanceSize, TraitsExp)); + super(loc, EXP.traits); this.ident = ident; this.args = args; } @@ -4272,7 +4300,7 @@ extern (C++) final class HaltExp : Expression { extern (D) this(const ref Loc loc) { - super(loc, EXP.halt, __traits(classInstanceSize, HaltExp)); + super(loc, EXP.halt); } override void accept(Visitor v) @@ -4296,7 +4324,7 @@ extern (C++) final class IsExp : Expression extern (D) this(const ref Loc loc, Type targ, Identifier id, TOK tok, Type tspec, TOK tok2, TemplateParameters* parameters) scope { - super(loc, EXP.is_, __traits(classInstanceSize, IsExp)); + super(loc, EXP.is_); this.targ = targ; this.id = id; this.tok = tok; @@ -4332,11 +4360,10 @@ extern (C++) final class IsExp : Expression extern (C++) abstract class UnaExp : Expression { Expression e1; - Type att1; // Save alias this type to detect recursion - extern (D) this(const ref Loc loc, EXP op, int size, Expression e1) scope + extern (D) this(const ref Loc loc, EXP op, Expression e1) scope { - super(loc, op, size); + super(loc, op); this.e1 = e1; } @@ -4407,9 +4434,9 @@ extern (C++) abstract class BinExp : Expression Type att1; // Save alias this type to detect recursion Type att2; // Save alias this type to detect recursion - extern (D) this(const ref Loc loc, EXP op, int size, Expression e1, Expression e2) scope + extern (D) this(const ref Loc loc, EXP op, Expression e1, Expression e2) scope { - super(loc, op, size); + super(loc, op); this.e1 = e1; this.e2 = e2; } @@ -4698,9 +4725,9 @@ extern (C++) abstract class BinExp : Expression */ extern (C++) class BinAssignExp : BinExp { - extern (D) this(const ref Loc loc, EXP op, int size, Expression e1, Expression e2) scope + extern (D) this(const ref Loc loc, EXP op, Expression e1, Expression e2) scope { - super(loc, op, size, e1, e2); + super(loc, op, e1, e2); } override final bool isLvalue() @@ -4737,7 +4764,7 @@ extern (C++) final class MixinExp : Expression extern (D) this(const ref Loc loc, Expressions* exps) { - super(loc, EXP.mixin_, __traits(classInstanceSize, MixinExp)); + super(loc, EXP.mixin_); this.exps = exps; } @@ -4785,7 +4812,7 @@ extern (C++) final class ImportExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.import_, __traits(classInstanceSize, ImportExp), e); + super(loc, EXP.import_, e); } override void accept(Visitor v) @@ -4805,7 +4832,7 @@ extern (C++) final class AssertExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Expression msg = null) { - super(loc, EXP.assert_, __traits(classInstanceSize, AssertExp), e); + super(loc, EXP.assert_, e); this.msg = msg; } @@ -4830,7 +4857,7 @@ extern (C++) final class ThrowExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.throw_, __traits(classInstanceSize, ThrowExp), e); + super(loc, EXP.throw_, e); this.type = Type.tnoreturn; } @@ -4856,7 +4883,7 @@ extern (C++) final class DotIdExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Identifier ident) { - super(loc, EXP.dotIdentifier, __traits(classInstanceSize, DotIdExp), e); + super(loc, EXP.dotIdentifier, e); this.ident = ident; } @@ -4880,7 +4907,7 @@ extern (C++) final class DotTemplateExp : UnaExp extern (D) this(const ref Loc loc, Expression e, TemplateDeclaration td) { - super(loc, EXP.dotTemplateDeclaration, __traits(classInstanceSize, DotTemplateExp), e); + super(loc, EXP.dotTemplateDeclaration, e); this.td = td; } @@ -4914,7 +4941,7 @@ extern (C++) final class DotVarExp : UnaExp if (var.isVarDeclaration()) hasOverloads = false; - super(loc, EXP.dotVariable, __traits(classInstanceSize, DotVarExp), e); + super(loc, EXP.dotVariable, e); //printf("DotVarExp()\n"); this.var = var; this.hasOverloads = hasOverloads; @@ -4995,14 +5022,14 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Identifier name, Objects* tiargs) { - super(loc, EXP.dotTemplateInstance, __traits(classInstanceSize, DotTemplateInstanceExp), e); + super(loc, EXP.dotTemplateInstance, e); //printf("DotTemplateInstanceExp()\n"); this.ti = new TemplateInstance(loc, name, tiargs); } extern (D) this(const ref Loc loc, Expression e, TemplateInstance ti) { - super(loc, EXP.dotTemplateInstance, __traits(classInstanceSize, DotTemplateInstanceExp), e); + super(loc, EXP.dotTemplateInstance, e); this.ti = ti; } @@ -5095,7 +5122,7 @@ extern (C++) final class DelegateExp : UnaExp extern (D) this(const ref Loc loc, Expression e, FuncDeclaration f, bool hasOverloads = true, VarDeclaration vthis2 = null) { - super(loc, EXP.delegate_, __traits(classInstanceSize, DelegateExp), e); + super(loc, EXP.delegate_, e); this.func = f; this.hasOverloads = hasOverloads; this.vthis2 = vthis2; @@ -5115,7 +5142,7 @@ extern (C++) final class DotTypeExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Dsymbol s) { - super(loc, EXP.dotType, __traits(classInstanceSize, DotTypeExp), e); + super(loc, EXP.dotType, e); this.sym = s; } @@ -5169,19 +5196,19 @@ extern (C++) final class CallExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Expressions* exps, Identifiers* names = null) { - super(loc, EXP.call, __traits(classInstanceSize, CallExp), e); + super(loc, EXP.call, e); this.arguments = exps; this.names = names; } extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.call, __traits(classInstanceSize, CallExp), e); + super(loc, EXP.call, e); } extern (D) this(const ref Loc loc, Expression e, Expression earg1) { - super(loc, EXP.call, __traits(classInstanceSize, CallExp), e); + super(loc, EXP.call, e); this.arguments = new Expressions(); if (earg1) this.arguments.push(earg1); @@ -5189,7 +5216,7 @@ extern (C++) final class CallExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Expression earg1, Expression earg2) { - super(loc, EXP.call, __traits(classInstanceSize, CallExp), e); + super(loc, EXP.call, e); auto arguments = new Expressions(2); (*arguments)[0] = earg1; (*arguments)[1] = earg2; @@ -5345,7 +5372,7 @@ extern (C++) final class AddrExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.address, __traits(classInstanceSize, AddrExp), e); + super(loc, EXP.address, e); } extern (D) this(const ref Loc loc, Expression e, Type t) @@ -5367,14 +5394,14 @@ extern (C++) final class PtrExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.star, __traits(classInstanceSize, PtrExp), e); + super(loc, EXP.star, e); //if (e.type) // type = ((TypePointer *)e.type).next; } extern (D) this(const ref Loc loc, Expression e, Type t) { - super(loc, EXP.star, __traits(classInstanceSize, PtrExp), e); + super(loc, EXP.star, e); type = t; } @@ -5420,7 +5447,7 @@ extern (C++) final class NegExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.negate, __traits(classInstanceSize, NegExp), e); + super(loc, EXP.negate, e); } override void accept(Visitor v) @@ -5436,7 +5463,7 @@ extern (C++) final class UAddExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) scope { - super(loc, EXP.uadd, __traits(classInstanceSize, UAddExp), e); + super(loc, EXP.uadd, e); } override void accept(Visitor v) @@ -5452,7 +5479,7 @@ extern (C++) final class ComExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.tilde, __traits(classInstanceSize, ComExp), e); + super(loc, EXP.tilde, e); } override void accept(Visitor v) @@ -5468,7 +5495,7 @@ extern (C++) final class NotExp : UnaExp { extern (D) this(const ref Loc loc, Expression e) { - super(loc, EXP.not, __traits(classInstanceSize, NotExp), e); + super(loc, EXP.not, e); } override void accept(Visitor v) @@ -5488,7 +5515,7 @@ extern (C++) final class DeleteExp : UnaExp extern (D) this(const ref Loc loc, Expression e, bool isRAII) { - super(loc, EXP.delete_, __traits(classInstanceSize, DeleteExp), e); + super(loc, EXP.delete_, e); this.isRAII = isRAII; } @@ -5512,7 +5539,7 @@ extern (C++) final class CastExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Type t) { - super(loc, EXP.cast_, __traits(classInstanceSize, CastExp), e); + super(loc, EXP.cast_, e); this.to = t; } @@ -5520,7 +5547,7 @@ extern (C++) final class CastExp : UnaExp */ extern (D) this(const ref Loc loc, Expression e, ubyte mod) { - super(loc, EXP.cast_, __traits(classInstanceSize, CastExp), e); + super(loc, EXP.cast_, e); this.mod = mod; } @@ -5574,7 +5601,7 @@ extern (C++) final class VectorExp : UnaExp extern (D) this(const ref Loc loc, Expression e, Type t) { - super(loc, EXP.vector, __traits(classInstanceSize, VectorExp), e); + super(loc, EXP.vector, e); assert(t.ty == Tvector); to = cast(TypeVector)t; } @@ -5610,7 +5637,7 @@ extern (C++) final class VectorArrayExp : UnaExp { extern (D) this(const ref Loc loc, Expression e1) { - super(loc, EXP.vectorArray, __traits(classInstanceSize, VectorArrayExp), e1); + super(loc, EXP.vectorArray, e1); } override bool isLvalue() @@ -5641,21 +5668,27 @@ extern (C++) final class SliceExp : UnaExp Expression lwr; // null if implicit [length - 1] VarDeclaration lengthVar; - bool upperIsInBounds; // true if upr <= e1.length - bool lowerIsLessThanUpper; // true if lwr <= upr - bool arrayop; // an array operation, rather than a slice + + private extern(D) static struct BitFields + { + bool upperIsInBounds; // true if upr <= e1.length + bool lowerIsLessThanUpper; // true if lwr <= upr + bool arrayop; // an array operation, rather than a slice + } + import dmd.common.bitfields : generateBitFields; + mixin(generateBitFields!(BitFields, ubyte)); /************************************************************/ extern (D) this(const ref Loc loc, Expression e1, IntervalExp ie) { - super(loc, EXP.slice, __traits(classInstanceSize, SliceExp), e1); + super(loc, EXP.slice, e1); this.upr = ie ? ie.upr : null; this.lwr = ie ? ie.lwr : null; } extern (D) this(const ref Loc loc, Expression e1, Expression lwr, Expression upr) { - super(loc, EXP.slice, __traits(classInstanceSize, SliceExp), e1); + super(loc, EXP.slice, e1); this.upr = upr; this.lwr = lwr; } @@ -5705,7 +5738,7 @@ extern (C++) final class ArrayLengthExp : UnaExp { extern (D) this(const ref Loc loc, Expression e1) { - super(loc, EXP.arrayLength, __traits(classInstanceSize, ArrayLengthExp), e1); + super(loc, EXP.arrayLength, e1); } override void accept(Visitor v) @@ -5728,7 +5761,7 @@ extern (C++) final class ArrayExp : UnaExp extern (D) this(const ref Loc loc, Expression e1, Expression index = null) { - super(loc, EXP.array, __traits(classInstanceSize, ArrayExp), e1); + super(loc, EXP.array, e1); arguments = new Expressions(); if (index) arguments.push(index); @@ -5736,7 +5769,7 @@ extern (C++) final class ArrayExp : UnaExp extern (D) this(const ref Loc loc, Expression e1, Expressions* args) { - super(loc, EXP.array, __traits(classInstanceSize, ArrayExp), e1); + super(loc, EXP.array, e1); arguments = args; } @@ -5773,7 +5806,7 @@ extern (C++) final class DotExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.dot, __traits(classInstanceSize, DotExp), e1, e2); + super(loc, EXP.dot, e1, e2); } override void accept(Visitor v) @@ -5799,7 +5832,7 @@ extern (C++) final class CommaExp : BinExp extern (D) this(const ref Loc loc, Expression e1, Expression e2, bool generated = true) { - super(loc, EXP.comma, __traits(classInstanceSize, CommaExp), e1, e2); + super(loc, EXP.comma, e1, e2); allowCommaExp = isGenerated = generated; } @@ -5868,7 +5901,7 @@ extern (C++) final class IntervalExp : Expression extern (D) this(const ref Loc loc, Expression lwr, Expression upr) { - super(loc, EXP.interval, __traits(classInstanceSize, IntervalExp)); + super(loc, EXP.interval); this.lwr = lwr; this.upr = upr; } @@ -5893,7 +5926,7 @@ extern (C++) final class DelegatePtrExp : UnaExp { extern (D) this(const ref Loc loc, Expression e1) { - super(loc, EXP.delegatePointer, __traits(classInstanceSize, DelegatePtrExp), e1); + super(loc, EXP.delegatePointer, e1); } override bool isLvalue() @@ -5931,7 +5964,7 @@ extern (C++) final class DelegateFuncptrExp : UnaExp { extern (D) this(const ref Loc loc, Expression e1) { - super(loc, EXP.delegateFunctionPointer, __traits(classInstanceSize, DelegateFuncptrExp), e1); + super(loc, EXP.delegateFunctionPointer, e1); } override bool isLvalue() @@ -5971,13 +6004,13 @@ extern (C++) final class IndexExp : BinExp extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.index, __traits(classInstanceSize, IndexExp), e1, e2); + super(loc, EXP.index, e1, e2); //printf("IndexExp::IndexExp('%s')\n", toChars()); } extern (D) this(const ref Loc loc, Expression e1, Expression e2, bool indexIsInBounds) { - super(loc, EXP.index, __traits(classInstanceSize, IndexExp), e1, e2); + super(loc, EXP.index, e1, e2); this.indexIsInBounds = indexIsInBounds; //printf("IndexExp::IndexExp('%s')\n", toChars()); } @@ -6054,7 +6087,7 @@ extern (C++) final class PostExp : BinExp { extern (D) this(EXP op, const ref Loc loc, Expression e) { - super(loc, op, __traits(classInstanceSize, PostExp), e, IntegerExp.literal!1); + super(loc, op, e, IntegerExp.literal!1); assert(op == EXP.minusMinus || op == EXP.plusPlus); } @@ -6071,7 +6104,7 @@ extern (C++) final class PreExp : UnaExp { extern (D) this(EXP op, const ref Loc loc, Expression e) { - super(loc, op, __traits(classInstanceSize, PreExp), e); + super(loc, op, e); assert(op == EXP.preMinusMinus || op == EXP.prePlusPlus); } @@ -6101,12 +6134,12 @@ extern (C++) class AssignExp : BinExp /* op can be EXP.assign, EXP.construct, or EXP.blit */ extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.assign, __traits(classInstanceSize, AssignExp), e1, e2); + super(loc, EXP.assign, e1, e2); } this(const ref Loc loc, EXP tok, Expression e1, Expression e2) { - super(loc, tok, __traits(classInstanceSize, AssignExp), e1, e2); + super(loc, tok, e1, e2); } override final bool isLvalue() @@ -6141,6 +6174,32 @@ extern (C++) class AssignExp : BinExp } /*********************************************************** + * When an assignment expression is lowered to a druntime call + * this class is used to store the lowering. + * It essentially behaves the same as an AssignExp, but it is + * used to not waste space for other AssignExp that are not + * lowered to anything. + */ +extern (C++) final class LoweredAssignExp : AssignExp +{ + Expression lowering; + extern (D) this(AssignExp exp, Expression lowering) + { + super(exp.loc, EXP.loweredAssignExp, exp.e1, exp.e2); + this.lowering = lowering; + } + + override const(char)* toChars() const + { + return lowering.toChars(); + } + override void accept(Visitor v) + { + v.visit(this); + } +} + +/*********************************************************** */ extern (C++) final class ConstructExp : AssignExp { @@ -6204,7 +6263,7 @@ extern (C++) final class AddAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.addAssign, __traits(classInstanceSize, AddAssignExp), e1, e2); + super(loc, EXP.addAssign, e1, e2); } override void accept(Visitor v) @@ -6220,7 +6279,7 @@ extern (C++) final class MinAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.minAssign, __traits(classInstanceSize, MinAssignExp), e1, e2); + super(loc, EXP.minAssign, e1, e2); } override void accept(Visitor v) @@ -6236,7 +6295,7 @@ extern (C++) final class MulAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.mulAssign, __traits(classInstanceSize, MulAssignExp), e1, e2); + super(loc, EXP.mulAssign, e1, e2); } override void accept(Visitor v) @@ -6252,7 +6311,7 @@ extern (C++) final class DivAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.divAssign, __traits(classInstanceSize, DivAssignExp), e1, e2); + super(loc, EXP.divAssign, e1, e2); } override void accept(Visitor v) @@ -6268,7 +6327,7 @@ extern (C++) final class ModAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.modAssign, __traits(classInstanceSize, ModAssignExp), e1, e2); + super(loc, EXP.modAssign, e1, e2); } override void accept(Visitor v) @@ -6284,7 +6343,7 @@ extern (C++) final class AndAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.andAssign, __traits(classInstanceSize, AndAssignExp), e1, e2); + super(loc, EXP.andAssign, e1, e2); } override void accept(Visitor v) @@ -6300,7 +6359,7 @@ extern (C++) final class OrAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.orAssign, __traits(classInstanceSize, OrAssignExp), e1, e2); + super(loc, EXP.orAssign, e1, e2); } override void accept(Visitor v) @@ -6316,7 +6375,7 @@ extern (C++) final class XorAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.xorAssign, __traits(classInstanceSize, XorAssignExp), e1, e2); + super(loc, EXP.xorAssign, e1, e2); } override void accept(Visitor v) @@ -6332,7 +6391,7 @@ extern (C++) final class PowAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.powAssign, __traits(classInstanceSize, PowAssignExp), e1, e2); + super(loc, EXP.powAssign, e1, e2); } override void accept(Visitor v) @@ -6348,7 +6407,7 @@ extern (C++) final class ShlAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.leftShiftAssign, __traits(classInstanceSize, ShlAssignExp), e1, e2); + super(loc, EXP.leftShiftAssign, e1, e2); } override void accept(Visitor v) @@ -6364,7 +6423,7 @@ extern (C++) final class ShrAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.rightShiftAssign, __traits(classInstanceSize, ShrAssignExp), e1, e2); + super(loc, EXP.rightShiftAssign, e1, e2); } override void accept(Visitor v) @@ -6380,7 +6439,7 @@ extern (C++) final class UshrAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.unsignedRightShiftAssign, __traits(classInstanceSize, UshrAssignExp), e1, e2); + super(loc, EXP.unsignedRightShiftAssign, e1, e2); } override void accept(Visitor v) @@ -6405,12 +6464,12 @@ extern (C++) class CatAssignExp : BinAssignExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.concatenateAssign, __traits(classInstanceSize, CatAssignExp), e1, e2); + super(loc, EXP.concatenateAssign, e1, e2); } extern (D) this(const ref Loc loc, EXP tok, Expression e1, Expression e2) { - super(loc, tok, __traits(classInstanceSize, CatAssignExp), e1, e2); + super(loc, tok, e1, e2); } override void accept(Visitor v) @@ -6462,7 +6521,7 @@ extern (C++) final class AddExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.add, __traits(classInstanceSize, AddExp), e1, e2); + super(loc, EXP.add, e1, e2); } override void accept(Visitor v) @@ -6480,7 +6539,7 @@ extern (C++) final class MinExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.min, __traits(classInstanceSize, MinExp), e1, e2); + super(loc, EXP.min, e1, e2); } override void accept(Visitor v) @@ -6496,9 +6555,11 @@ extern (C++) final class MinExp : BinExp */ extern (C++) final class CatExp : BinExp { + Expression lowering; // call to druntime hook `_d_arraycatnTX` + extern (D) this(const ref Loc loc, Expression e1, Expression e2) scope { - super(loc, EXP.concatenate, __traits(classInstanceSize, CatExp), e1, e2); + super(loc, EXP.concatenate, e1, e2); } override Expression resolveLoc(const ref Loc loc, Scope* sc) @@ -6523,7 +6584,7 @@ extern (C++) final class MulExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.mul, __traits(classInstanceSize, MulExp), e1, e2); + super(loc, EXP.mul, e1, e2); } override void accept(Visitor v) @@ -6541,7 +6602,7 @@ extern (C++) final class DivExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.div, __traits(classInstanceSize, DivExp), e1, e2); + super(loc, EXP.div, e1, e2); } override void accept(Visitor v) @@ -6559,7 +6620,7 @@ extern (C++) final class ModExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.mod, __traits(classInstanceSize, ModExp), e1, e2); + super(loc, EXP.mod, e1, e2); } override void accept(Visitor v) @@ -6577,7 +6638,7 @@ extern (C++) final class PowExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.pow, __traits(classInstanceSize, PowExp), e1, e2); + super(loc, EXP.pow, e1, e2); } override void accept(Visitor v) @@ -6595,7 +6656,7 @@ extern (C++) final class ShlExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.leftShift, __traits(classInstanceSize, ShlExp), e1, e2); + super(loc, EXP.leftShift, e1, e2); } override void accept(Visitor v) @@ -6613,7 +6674,7 @@ extern (C++) final class ShrExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.rightShift, __traits(classInstanceSize, ShrExp), e1, e2); + super(loc, EXP.rightShift, e1, e2); } override void accept(Visitor v) @@ -6631,7 +6692,7 @@ extern (C++) final class UshrExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.unsignedRightShift, __traits(classInstanceSize, UshrExp), e1, e2); + super(loc, EXP.unsignedRightShift, e1, e2); } override void accept(Visitor v) @@ -6649,7 +6710,7 @@ extern (C++) final class AndExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.and, __traits(classInstanceSize, AndExp), e1, e2); + super(loc, EXP.and, e1, e2); } override void accept(Visitor v) @@ -6667,7 +6728,7 @@ extern (C++) final class OrExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.or, __traits(classInstanceSize, OrExp), e1, e2); + super(loc, EXP.or, e1, e2); } override void accept(Visitor v) @@ -6685,7 +6746,7 @@ extern (C++) final class XorExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.xor, __traits(classInstanceSize, XorExp), e1, e2); + super(loc, EXP.xor, e1, e2); } override void accept(Visitor v) @@ -6704,7 +6765,7 @@ extern (C++) final class LogicalExp : BinExp { extern (D) this(const ref Loc loc, EXP op, Expression e1, Expression e2) { - super(loc, op, __traits(classInstanceSize, LogicalExp), e1, e2); + super(loc, op, e1, e2); assert(op == EXP.andAnd || op == EXP.orOr); } @@ -6726,7 +6787,7 @@ extern (C++) final class CmpExp : BinExp { extern (D) this(EXP op, const ref Loc loc, Expression e1, Expression e2) { - super(loc, op, __traits(classInstanceSize, CmpExp), e1, e2); + super(loc, op, e1, e2); assert(op == EXP.lessThan || op == EXP.lessOrEqual || op == EXP.greaterThan || op == EXP.greaterOrEqual); } @@ -6747,7 +6808,7 @@ extern (C++) final class InExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.in_, __traits(classInstanceSize, InExp), e1, e2); + super(loc, EXP.in_, e1, e2); } override void accept(Visitor v) @@ -6765,7 +6826,7 @@ extern (C++) final class RemoveExp : BinExp { extern (D) this(const ref Loc loc, Expression e1, Expression e2) { - super(loc, EXP.remove, __traits(classInstanceSize, RemoveExp), e1, e2); + super(loc, EXP.remove, e1, e2); type = Type.tbool; } @@ -6786,7 +6847,7 @@ extern (C++) final class EqualExp : BinExp { extern (D) this(EXP op, const ref Loc loc, Expression e1, Expression e2) { - super(loc, op, __traits(classInstanceSize, EqualExp), e1, e2); + super(loc, op, e1, e2); assert(op == EXP.equal || op == EXP.notEqual); } @@ -6807,7 +6868,7 @@ extern (C++) final class IdentityExp : BinExp { extern (D) this(EXP op, const ref Loc loc, Expression e1, Expression e2) { - super(loc, op, __traits(classInstanceSize, IdentityExp), e1, e2); + super(loc, op, e1, e2); assert(op == EXP.identity || op == EXP.notIdentity); } @@ -6828,7 +6889,7 @@ extern (C++) final class CondExp : BinExp extern (D) this(const ref Loc loc, Expression econd, Expression e1, Expression e2) scope { - super(loc, EXP.question, __traits(classInstanceSize, CondExp), e1, e2); + super(loc, EXP.question, e1, e2); this.econd = econd; } @@ -6966,9 +7027,9 @@ bool isDefaultInitOp(EXP op) pure nothrow @safe @nogc */ extern (C++) class DefaultInitExp : Expression { - extern (D) this(const ref Loc loc, EXP op, int size) + extern (D) this(const ref Loc loc, EXP op) { - super(loc, op, size); + super(loc, op); } override void accept(Visitor v) @@ -6984,7 +7045,7 @@ extern (C++) final class FileInitExp : DefaultInitExp { extern (D) this(const ref Loc loc, EXP tok) { - super(loc, tok, __traits(classInstanceSize, FileInitExp)); + super(loc, tok); } override Expression resolveLoc(const ref Loc loc, Scope* sc) @@ -7015,7 +7076,7 @@ extern (C++) final class LineInitExp : DefaultInitExp { extern (D) this(const ref Loc loc) { - super(loc, EXP.line, __traits(classInstanceSize, LineInitExp)); + super(loc, EXP.line); } override Expression resolveLoc(const ref Loc loc, Scope* sc) @@ -7038,7 +7099,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp { extern (D) this(const ref Loc loc) { - super(loc, EXP.moduleString, __traits(classInstanceSize, ModuleInitExp)); + super(loc, EXP.moduleString); } override Expression resolveLoc(const ref Loc loc, Scope* sc) @@ -7063,7 +7124,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp { extern (D) this(const ref Loc loc) { - super(loc, EXP.functionString, __traits(classInstanceSize, FuncInitExp)); + super(loc, EXP.functionString); } override Expression resolveLoc(const ref Loc loc, Scope* sc) @@ -7094,7 +7155,7 @@ extern (C++) final class PrettyFuncInitExp : DefaultInitExp { extern (D) this(const ref Loc loc) { - super(loc, EXP.prettyFunction, __traits(classInstanceSize, PrettyFuncInitExp)); + super(loc, EXP.prettyFunction); } override Expression resolveLoc(const ref Loc loc, Scope* sc) @@ -7139,8 +7200,7 @@ extern (C++) final class ObjcClassReferenceExp : Expression extern (D) this(const ref Loc loc, ClassDeclaration classDeclaration) { - super(loc, EXP.objcClassReference, - __traits(classInstanceSize, ObjcClassReferenceExp)); + super(loc, EXP.objcClassReference); this.classDeclaration = classDeclaration; type = objc.getRuntimeMetaclass(classDeclaration).getType(); } @@ -7163,7 +7223,7 @@ extern (C++) final class GenericExp : Expression extern (D) this(const ref Loc loc, Expression cntlExp, Types* types, Expressions* exps) { - super(loc, EXP._Generic, __traits(classInstanceSize, GenericExp)); + super(loc, EXP._Generic); this.cntlExp = cntlExp; this.types = types; this.exps = exps; @@ -7398,3 +7458,135 @@ private enum EbinaryAssign = EXP.leftShiftAssign, EXP.rightShiftAssign, EXP.unsignedRightShiftAssign, EXP.concatenateAssign, EXP.concatenateElemAssign, EXP.concatenateDcharAssign, ]; + +/// Given a member of the EXP enum, get the class instance size of the corresponding Expression class. +/// Needed because the classes are `extern(C++)` +private immutable ubyte[EXP.max+1] expSize = [ + EXP.reserved: 0, + EXP.negate: __traits(classInstanceSize, NegExp), + EXP.cast_: __traits(classInstanceSize, CastExp), + EXP.null_: __traits(classInstanceSize, NullExp), + EXP.assert_: __traits(classInstanceSize, AssertExp), + EXP.array: __traits(classInstanceSize, ArrayExp), + EXP.call: __traits(classInstanceSize, CallExp), + EXP.address: __traits(classInstanceSize, AddrExp), + EXP.type: __traits(classInstanceSize, TypeExp), + EXP.throw_: __traits(classInstanceSize, ThrowExp), + EXP.new_: __traits(classInstanceSize, NewExp), + EXP.delete_: __traits(classInstanceSize, DeleteExp), + EXP.star: __traits(classInstanceSize, PtrExp), + EXP.symbolOffset: __traits(classInstanceSize, SymOffExp), + EXP.variable: __traits(classInstanceSize, VarExp), + EXP.dotVariable: __traits(classInstanceSize, DotVarExp), + EXP.dotIdentifier: __traits(classInstanceSize, DotIdExp), + EXP.dotTemplateInstance: __traits(classInstanceSize, DotTemplateInstanceExp), + EXP.dotType: __traits(classInstanceSize, DotTypeExp), + EXP.slice: __traits(classInstanceSize, SliceExp), + EXP.arrayLength: __traits(classInstanceSize, ArrayLengthExp), + EXP.dollar: __traits(classInstanceSize, DollarExp), + EXP.template_: __traits(classInstanceSize, TemplateExp), + EXP.dotTemplateDeclaration: __traits(classInstanceSize, DotTemplateExp), + EXP.declaration: __traits(classInstanceSize, DeclarationExp), + EXP.dSymbol: __traits(classInstanceSize, DsymbolExp), + EXP.typeid_: __traits(classInstanceSize, TypeidExp), + EXP.uadd: __traits(classInstanceSize, UAddExp), + EXP.remove: __traits(classInstanceSize, RemoveExp), + EXP.newAnonymousClass: __traits(classInstanceSize, NewAnonClassExp), + EXP.arrayLiteral: __traits(classInstanceSize, ArrayLiteralExp), + EXP.assocArrayLiteral: __traits(classInstanceSize, AssocArrayLiteralExp), + EXP.structLiteral: __traits(classInstanceSize, StructLiteralExp), + EXP.classReference: __traits(classInstanceSize, ClassReferenceExp), + EXP.thrownException: __traits(classInstanceSize, ThrownExceptionExp), + EXP.delegatePointer: __traits(classInstanceSize, DelegatePtrExp), + EXP.delegateFunctionPointer: __traits(classInstanceSize, DelegateFuncptrExp), + EXP.lessThan: __traits(classInstanceSize, CmpExp), + EXP.greaterThan: __traits(classInstanceSize, CmpExp), + EXP.lessOrEqual: __traits(classInstanceSize, CmpExp), + EXP.greaterOrEqual: __traits(classInstanceSize, CmpExp), + EXP.equal: __traits(classInstanceSize, EqualExp), + EXP.notEqual: __traits(classInstanceSize, EqualExp), + EXP.identity: __traits(classInstanceSize, IdentityExp), + EXP.notIdentity: __traits(classInstanceSize, IdentityExp), + EXP.index: __traits(classInstanceSize, IndexExp), + EXP.is_: __traits(classInstanceSize, IsExp), + EXP.leftShift: __traits(classInstanceSize, ShlExp), + EXP.rightShift: __traits(classInstanceSize, ShrExp), + EXP.leftShiftAssign: __traits(classInstanceSize, ShlAssignExp), + EXP.rightShiftAssign: __traits(classInstanceSize, ShrAssignExp), + EXP.unsignedRightShift: __traits(classInstanceSize, UshrExp), + EXP.unsignedRightShiftAssign: __traits(classInstanceSize, UshrAssignExp), + EXP.concatenate: __traits(classInstanceSize, CatExp), + EXP.concatenateAssign: __traits(classInstanceSize, CatAssignExp), + EXP.concatenateElemAssign: __traits(classInstanceSize, CatElemAssignExp), + EXP.concatenateDcharAssign: __traits(classInstanceSize, CatDcharAssignExp), + EXP.add: __traits(classInstanceSize, AddExp), + EXP.min: __traits(classInstanceSize, MinExp), + EXP.addAssign: __traits(classInstanceSize, AddAssignExp), + EXP.minAssign: __traits(classInstanceSize, MinAssignExp), + EXP.mul: __traits(classInstanceSize, MulExp), + EXP.div: __traits(classInstanceSize, DivExp), + EXP.mod: __traits(classInstanceSize, ModExp), + EXP.mulAssign: __traits(classInstanceSize, MulAssignExp), + EXP.divAssign: __traits(classInstanceSize, DivAssignExp), + EXP.modAssign: __traits(classInstanceSize, ModAssignExp), + EXP.and: __traits(classInstanceSize, AndExp), + EXP.or: __traits(classInstanceSize, OrExp), + EXP.xor: __traits(classInstanceSize, XorExp), + EXP.andAssign: __traits(classInstanceSize, AndAssignExp), + EXP.orAssign: __traits(classInstanceSize, OrAssignExp), + EXP.xorAssign: __traits(classInstanceSize, XorAssignExp), + EXP.assign: __traits(classInstanceSize, AssignExp), + EXP.not: __traits(classInstanceSize, NotExp), + EXP.tilde: __traits(classInstanceSize, ComExp), + EXP.plusPlus: __traits(classInstanceSize, PostExp), + EXP.minusMinus: __traits(classInstanceSize, PostExp), + EXP.construct: __traits(classInstanceSize, ConstructExp), + EXP.blit: __traits(classInstanceSize, BlitExp), + EXP.dot: __traits(classInstanceSize, DotExp), + EXP.comma: __traits(classInstanceSize, CommaExp), + EXP.question: __traits(classInstanceSize, CondExp), + EXP.andAnd: __traits(classInstanceSize, LogicalExp), + EXP.orOr: __traits(classInstanceSize, LogicalExp), + EXP.prePlusPlus: __traits(classInstanceSize, PreExp), + EXP.preMinusMinus: __traits(classInstanceSize, PreExp), + EXP.identifier: __traits(classInstanceSize, IdentifierExp), + EXP.string_: __traits(classInstanceSize, StringExp), + EXP.this_: __traits(classInstanceSize, ThisExp), + EXP.super_: __traits(classInstanceSize, SuperExp), + EXP.halt: __traits(classInstanceSize, HaltExp), + EXP.tuple: __traits(classInstanceSize, TupleExp), + EXP.error: __traits(classInstanceSize, ErrorExp), + EXP.void_: __traits(classInstanceSize, VoidInitExp), + EXP.int64: __traits(classInstanceSize, IntegerExp), + EXP.float64: __traits(classInstanceSize, RealExp), + EXP.complex80: __traits(classInstanceSize, ComplexExp), + EXP.import_: __traits(classInstanceSize, ImportExp), + EXP.delegate_: __traits(classInstanceSize, DelegateExp), + EXP.function_: __traits(classInstanceSize, FuncExp), + EXP.mixin_: __traits(classInstanceSize, MixinExp), + EXP.in_: __traits(classInstanceSize, InExp), + EXP.break_: __traits(classInstanceSize, CTFEExp), + EXP.continue_: __traits(classInstanceSize, CTFEExp), + EXP.goto_: __traits(classInstanceSize, CTFEExp), + EXP.scope_: __traits(classInstanceSize, ScopeExp), + EXP.traits: __traits(classInstanceSize, TraitsExp), + EXP.overloadSet: __traits(classInstanceSize, OverExp), + EXP.line: __traits(classInstanceSize, LineInitExp), + EXP.file: __traits(classInstanceSize, FileInitExp), + EXP.fileFullPath: __traits(classInstanceSize, FileInitExp), + EXP.moduleString: __traits(classInstanceSize, ModuleInitExp), + EXP.functionString: __traits(classInstanceSize, FuncInitExp), + EXP.prettyFunction: __traits(classInstanceSize, PrettyFuncInitExp), + EXP.pow: __traits(classInstanceSize, PowExp), + EXP.powAssign: __traits(classInstanceSize, PowAssignExp), + EXP.vector: __traits(classInstanceSize, VectorExp), + EXP.voidExpression: __traits(classInstanceSize, CTFEExp), + EXP.cantExpression: __traits(classInstanceSize, CTFEExp), + EXP.showCtfeContext: __traits(classInstanceSize, CTFEExp), + EXP.objcClassReference: __traits(classInstanceSize, ObjcClassReferenceExp), + EXP.vectorArray: __traits(classInstanceSize, VectorArrayExp), + EXP.compoundLiteral: __traits(classInstanceSize, CompoundLiteralExp), + EXP._Generic: __traits(classInstanceSize, GenericExp), + EXP.interval: __traits(classInstanceSize, IntervalExp), + EXP.loweredAssignExp : __traits(classInstanceSize, LoweredAssignExp), +]; diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 1bc78e7..a4b18b9 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -38,6 +38,7 @@ class TemplateDeclaration; class ClassDeclaration; class OverloadSet; class StringExp; +class LoweredAssignExp; struct UnionExp; #ifdef IN_GCC typedef union tree_node Symbol; @@ -79,12 +80,12 @@ enum class ModifyFlags class Expression : public ASTNode { public: - EXP op; // to minimize use of dynamic_cast - unsigned char size; // # of bytes in Expression so we can copy() it - d_bool parens; // if this is a parenthesized expression Type *type; // !=NULL means that semantic() has been run Loc loc; // file location + EXP op; // to minimize use of dynamic_cast + d_bool parens; // if this is a parenthesized expression + size_t size() const; static void _init(); Expression *copy(); virtual Expression *syntaxCopy(); @@ -240,6 +241,7 @@ public: UnaExp* isUnaExp(); BinExp* isBinExp(); BinAssignExp* isBinAssignExp(); + LoweredAssignExp* isLoweredAssignExp(); void accept(Visitor *v) override { v->visit(this); } }; @@ -370,12 +372,12 @@ public: class StringExp final : public Expression { public: + utf8_t postfix; // 'c', 'w', 'd' + OwnedBy ownedByCtfe; void *string; // char, wchar, or dchar data size_t len; // number of chars, wchars, or dchars unsigned char sz; // 1: char, 2: wchar, 4: dchar - unsigned char committed; // !=0 if type is committed - utf8_t postfix; // 'c', 'w', 'd' - OwnedBy ownedByCtfe; + bool committed; // if type is committed static StringExp *create(const Loc &loc, const char *s); static StringExp *create(const Loc &loc, const void *s, d_size_t len); @@ -419,10 +421,10 @@ public: class ArrayLiteralExp final : public Expression { public: - Expression *basis; - Expressions *elements; OwnedBy ownedByCtfe; d_bool onstack; + Expression *basis; + Expressions *elements; static ArrayLiteralExp *create(const Loc &loc, Expressions *elements); static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements); @@ -439,9 +441,9 @@ public: class AssocArrayLiteralExp final : public Expression { public: + OwnedBy ownedByCtfe; Expressions *keys; Expressions *values; - OwnedBy ownedByCtfe; bool equals(const RootObject * const o) const override; AssocArrayLiteralExp *syntaxCopy() override; @@ -457,7 +459,13 @@ public: Expressions *elements; // parallels sd->fields[] with NULL entries for fields to skip Type *stype; // final type of result (can be different from sd's type) - Symbol *sym; // back end symbol to initialize with literal + union + { + Symbol *sym; // back end symbol to initialize with literal + + // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer. + StructLiteralExp *inlinecopy; + }; /** pointer to the origin instance of the expression. * once a new expression is created, origin is set to 'this'. @@ -466,15 +474,13 @@ public: */ StructLiteralExp *origin; - // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer. - StructLiteralExp *inlinecopy; /** anytime when recursive function is calling, 'stageflags' marks with bit flag of * current stage and unmarks before return from this function. * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline' * (with infinite recursion) of this expression. */ - int stageflags; + uint8_t stageflags; d_bool useStaticInit; // if this is true, use the StructDeclaration's init symbol d_bool isOriginal; // used when moving instances to indicate `this is this.origin` @@ -693,7 +699,6 @@ class UnaExp : public Expression { public: Expression *e1; - Type *att1; // Save alias this type to detect recursion UnaExp *syntaxCopy() override; Expression *incompatibleTypes(); @@ -937,9 +942,15 @@ public: Expression *upr; // NULL if implicit 0 Expression *lwr; // NULL if implicit [length - 1] VarDeclaration *lengthVar; - d_bool upperIsInBounds; // true if upr <= e1.length - d_bool lowerIsLessThanUpper; // true if lwr <= upr - d_bool arrayop; // an array operation, rather than a slice + + bool upperIsInBounds() const; // true if upr <= e1.length + bool upperIsInBounds(bool v); + bool lowerIsLessThanUpper() const; // true if lwr <= upr + bool lowerIsLessThanUpper(bool v); + bool arrayop() const; // an array operation, rather than a slice + bool arrayop(bool v); +private: + uint8_t bitFields; SliceExp *syntaxCopy() override; bool isLvalue() override; @@ -1076,6 +1087,15 @@ public: void accept(Visitor *v) override { v->visit(this); } }; +class LoweredAssignExp final : public AssignExp +{ +public: + Expression *lowering; + + const char *toChars() const override; + void accept(Visitor *v) override { v->visit(this); } +}; + class BlitExp final : public AssignExp { public: @@ -1187,6 +1207,8 @@ public: class CatExp final : public BinExp { public: + Expression *lowering; // call to druntime hook `_d_arraycatnTX` + void accept(Visitor *v) override { v->visit(this); } }; @@ -1372,7 +1394,7 @@ struct UnionExp UnionExp(Expression *e) { - memcpy(this, (void *)e, e->size); + memcpy(this, (void *)e, e->size()); } /* Extract pointer to Expression diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 45dcb97..cf4aac4 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -65,7 +65,6 @@ import dmd.parse; import dmd.printast; import dmd.root.array; import dmd.root.ctfloat; -import dmd.root.file; import dmd.root.filename; import dmd.common.outbuffer; import dmd.root.rootobject; @@ -635,7 +634,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) } else if (auto dti = ce.e1.isDotTemplateInstanceExp()) { - if (Expression ey = dti.dotTemplateSemanticProp(sc, 1)) + if (Expression ey = dti.dotTemplateSemanticProp(sc, DotExpFlag.gag)) { ce.e1 = ey; return null; @@ -1221,7 +1220,7 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc) /*************************************** * Pull out any properties. */ -private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = null) +private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = null, BinExp saveAtts = null) { //printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", EXPtoString(e1.op).ptr, e1.toChars(), e2 ? e2.toChars() : null); Loc loc = e1.loc; @@ -1295,7 +1294,14 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = { Expression e = new CallExp(loc, e1); if (e2) + { e = new AssignExp(loc, e, e2); + if (saveAtts) + { + (cast(BinExp)e).att1 = saveAtts.att1; + (cast(BinExp)e).att2 = saveAtts.att2; + } + } return e.expressionSemantic(sc); } } @@ -1413,7 +1419,14 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = } Expression e = new CallExp(loc, e1); if (e2) + { e = new AssignExp(loc, e, e2); + if (saveAtts) + { + (cast(BinExp)e).att1 = saveAtts.att1; + (cast(BinExp)e).att2 = saveAtts.att2; + } + } return e.expressionSemantic(sc); } } @@ -2177,7 +2190,11 @@ private bool functionParameters(const ref Loc loc, Scope* sc, } // Allow 'lazy' to imply 'scope' - lazy parameters can be passed along // as lazy parameters to the next function, but that isn't escaping. - else if (!(pStc & STC.lazy_)) + // The arguments of `_d_arraycatnTX` are already handled in + // expressionsem.d, via `checkNewEscape`. Without `-dip1000`, the + // check does not return an error, so the lowering of `a ~ b` to + // `_d_arraycatnTX(a, b)` still occurs. + else if (!(pStc & STC.lazy_) && (!fd || fd.ident != Id._d_arraycatnTX)) { /* Argument value can escape from the called function. * Check arg to see if it matters. @@ -2208,6 +2225,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, // allocate the array literal as temporary static array on the stack ale.type = ale.type.nextOf().sarrayOf(ale.elements.length); auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale); + tmp.storage_class |= STC.exptemp; auto declareTmp = new DeclarationExp(ale.loc, tmp); auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp), p.type.substWildTo(MODFlags.mutable)); @@ -2266,7 +2284,8 @@ private bool functionParameters(const ref Loc loc, Scope* sc, default: break; } - if (tf.parameterList.varargs == VarArg.variadic) + if (tf.parameterList.varargs == VarArg.variadic || + tf.parameterList.varargs == VarArg.KRvariadic) { const(char)* p = tf.linkage == LINK.c ? "extern(C)" : "extern(C++)"; if (arg.type.ty == Tarray) @@ -2348,30 +2367,18 @@ private bool functionParameters(const ref Loc loc, Scope* sc, } /* Remaining problems: - * 1. order of evaluation - some function push L-to-R, others R-to-L. Until we resolve what array assignment does (which is - * implemented by calling a function) we'll defer this for now. - * 2. value structs (or static arrays of them) that need to be copy constructed - * 3. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the + * 1. value structs (or static arrays of them) that need to be copy constructed + * 2. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the * function gets called. - * 4. value structs need to be destructed after the function call for platforms where the caller destroys the arguments. - * 2, 3 and 4 are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned + * 3. value structs need to be destructed after the function call for platforms where the caller destroys the arguments. + * Those are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned * up properly. Pushing arguments on the stack then cannot fail. */ { - /* TODO: tackle problem 1) - */ - const bool leftToRight = true; // TODO: Any cases that need rightToLeft? - if (!leftToRight) - assert(nargs == nparams); // no variadics for RTL order, as they would probably be evaluated LTR and so add complexity - - /* Does Problem (4) apply? + /* Does Problem (3) apply? */ const bool callerDestroysArgs = !target.isCalleeDestroyingArgs(tf); - const ptrdiff_t start = (leftToRight ? 0 : cast(ptrdiff_t)nargs - 1); - const ptrdiff_t end = (leftToRight ? cast(ptrdiff_t)nargs : -1); - const ptrdiff_t step = (leftToRight ? 1 : -1); - /* Compute indices of last throwing argument and first arg needing destruction. * Used to not set up destructors unless an arg needs destruction on a throw * in a later argument. @@ -2379,7 +2386,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, ptrdiff_t lastthrow = -1; // last argument that may throw ptrdiff_t firstdtor = -1; // first argument that needs destruction ptrdiff_t lastdtor = -1; // last argument that needs destruction - for (ptrdiff_t i = start; i != end; i += step) + for (ptrdiff_t i = 0; i != nargs; i++) { Expression arg = (*arguments)[i]; if (canThrow(arg, sc.func, false)) @@ -2396,12 +2403,12 @@ private bool functionParameters(const ref Loc loc, Scope* sc, } } - /* Do we need 'eprefix' for problems 3 or 4? + /* Do we need 'eprefix' for problems 2 or 3? */ const bool needsPrefix = callerDestroysArgs ? firstdtor >= 0 // true if any argument needs destruction : firstdtor >= 0 && lastthrow >= 0 && - (lastthrow - firstdtor) * step > 0; // last throw after first destruction + (lastthrow - firstdtor) > 0; // last throw after first destruction const ptrdiff_t lastPrefix = callerDestroysArgs ? lastdtor // up to last argument requiring destruction : lastthrow; // up to last potentially throwing argument @@ -2421,7 +2428,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, eprefix = ae.expressionSemantic(sc); } - for (ptrdiff_t i = start; i != end; i += step) + for (ptrdiff_t i = 0; i != nargs; i++) { Expression arg = (*arguments)[i]; //printf("arg[%d]: %s\n", cast(int)i, arg.toChars()); @@ -2437,12 +2444,12 @@ private bool functionParameters(const ref Loc loc, Scope* sc, /* Do we have 'eprefix' and aren't past 'lastPrefix' yet? * Then declare a temporary variable for this arg and append that declaration - * to 'eprefix', which will implicitly take care of potential problem 2) for + * to 'eprefix', which will implicitly take care of potential problem 1) for * this arg. * 'eprefix' will therefore finally contain all args up to and including 'lastPrefix', * excluding all lazy parameters. */ - if (needsPrefix && (lastPrefix - i) * step >= 0) + if (needsPrefix && (lastPrefix - i) >= 0) { const bool needsDtor = !isRef && arg.type.needsDestruction() && // Problem 3: last throwing arg doesn't require dtor patching @@ -2465,7 +2472,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, } else { - /* Problem 3: Modify the destructor so it only runs if gate==false, + /* Problem 2: Modify the destructor so it only runs if gate==false, * i.e., only if there was a throw while constructing the args */ if (!needsDtor) @@ -2500,7 +2507,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, arg = arg.expressionSemantic(sc); } - /* Problem 3: Last throwing arg? + /* Problem 2: Last throwing arg? * Then finalize eprefix => (eprefix, gate = true), i.e., disable the * dtors right after constructing the last throwing arg. * From now on, the callee will take care of destructing the args because @@ -2514,7 +2521,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, } else // not part of 'eprefix' { - /* Handle problem 2) by calling the copy constructor for value structs + /* Handle problem 1) by calling the copy constructor for value structs * (or static arrays of them) if appropriate. */ Type tv = arg.type.baseElemOf(); @@ -2671,6 +2678,34 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (!e.type) e.type = Type.tfloat64; + else if (e.type.isimaginary && sc.flags & SCOPE.Cfile) + { + /* Convert to core.stdc.config.complex + */ + Type t = getComplexLibraryType(e.loc, sc, e.type.ty); + if (t.ty == Terror) + return setError(); + + Type tf; + switch (e.type.ty) + { + case Timaginary32: tf = Type.tfloat32; break; + case Timaginary64: tf = Type.tfloat64; break; + case Timaginary80: tf = Type.tfloat80; break; + default: + assert(0); + } + + /* Construct ts{re : 0.0, im : e} + */ + TypeStruct ts = t.isTypeStruct; + Expressions* elements = new Expressions(2); + (*elements)[0] = new RealExp(e.loc, CTFloat.zero, tf); + (*elements)[1] = new RealExp(e.loc, e.toImaginary(), tf); + Expression sle = new StructLiteralExp(e.loc, ts.sym, elements); + result = sle.expressionSemantic(sc); + return; + } else e.type = e.type.typeSemantic(e.loc, sc); result = e; @@ -2933,7 +2968,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!s) { e.error("`%s` is not in a class or struct scope", e.toChars()); - goto Lerr; + return setError(); } ClassDeclaration cd = s.isClassDeclaration(); if (cd) @@ -2952,7 +2987,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } } if (!fd) - goto Lerr; + { + e.error("`this` is only defined in non-static member functions, not `%s`", sc.parent.toChars()); + return setError(); + } assert(fd.vthis); e.var = fd.vthis; @@ -2967,11 +3005,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); result = e; - return; - - Lerr: - e.error("`this` is only defined in non-static member functions, not `%s`", sc.parent.toChars()); - result = ErrorExp.get(); } override void visit(SuperExp e) @@ -3001,7 +3034,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!s) { e.error("`%s` is not in a class scope", e.toChars()); - goto Lerr; + return setError(); } cd = s.isClassDeclaration(); if (cd) @@ -3010,7 +3043,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!cd) { e.error("class `%s` has no `super`", s.toChars()); - goto Lerr; + return setError(); } e.type = cd.type; result = e; @@ -3109,7 +3142,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e.type = Type.tuns32.sarrayOf(e.len + 1); else e.type = Type.tdchar.immutableOf().arrayOf(); - e.committed = 1; + e.committed = true; break; case 'w': @@ -3134,11 +3167,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e.type = Type.tuns16.sarrayOf(e.len + 1); else e.type = Type.twchar.immutableOf().arrayOf(); - e.committed = 1; + e.committed = true; break; case 'c': - e.committed = 1; + e.committed = true; goto default; default: @@ -3860,8 +3893,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor result = id.expressionSemantic(sc); return; } - else if (!exp.onstack && !exp.type.isscope()) + else if (sc.needsCodegen() && // interpreter doesn't need this lowered + !exp.onstack && !exp.type.isscope()) // these won't use the GC { + /* replace `new T(arguments)` with `core.lifetime._d_newclassT!T(arguments)` + * or `_d_newclassTTrace` + */ auto hook = global.params.tracegc ? Id._d_newclassTTrace : Id._d_newclassT; if (!verifyHookExist(exp.loc, *sc, hook, "new class")) return setError(); @@ -4533,6 +4570,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } } + Type att = null; Lagain: //printf("Lagain: %s\n", toChars()); exp.f = null; @@ -4743,7 +4781,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // overload of opCall, therefore it's a call if (exp.e1.op != EXP.type) { - if (sd.aliasthis && !isRecursiveAliasThis(exp.att1, exp.e1.type)) + if (sd.aliasthis && !isRecursiveAliasThis(att, exp.e1.type)) { exp.e1 = resolveAliasThis(sc, exp.e1); goto Lagain; @@ -4832,10 +4870,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return null; if (f) { - /* Error if match in more than one overload set, + /* Match in more than one overload set, * even if one is a 'better' match than the other. */ - ScopeDsymbol.multiplyDefined(loc, f, f2); + if (f.isCsymbol() && f2.isCsymbol()) + { + /* C has global name space, so just pick one, such as f. + * If f and f2 are not compatible, that's how C rolls. + */ + } + else + ScopeDsymbol.multiplyDefined(loc, f, f2); // issue error } else f = f2; @@ -5203,13 +5248,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor else if (sc.func && sc.intypeof != 1 && !(sc.flags & (SCOPE.ctfe | SCOPE.debug_))) { bool err = false; - if (!tf.purity && sc.func.setImpure()) + if (!tf.purity && sc.func.setImpure(exp.loc, "`pure` %s `%s` cannot call impure `%s`", exp.e1)) { exp.error("`pure` %s `%s` cannot call impure %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars()); err = true; } - if (!tf.isnogc && sc.func.setGC()) + if (!tf.isnogc && sc.func.setGC(exp.loc, "`@nogc` %s `%s` cannot call non-@nogc `%s`", exp.e1)) { exp.error("`@nogc` %s `%s` cannot call non-@nogc %s `%s`", sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars()); @@ -6166,7 +6211,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor uint errors = global.errors; const len = buf.length; const str = buf.extractChars()[0 .. len]; - scope p = new Parser!ASTCodegen(exp.loc, sc._module, str, false, global.errorSink); + const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; + auto loc = adjustLocForMixin(str, exp.loc, global.params.mixinOut); + scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + p.transitionIn = global.params.vin; p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); @@ -6295,19 +6343,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - auto readResult = File.read(resolvedNamez); - if (!readResult.success) - { - e.error("cannot read file `%s`", resolvedNamez.ptr); - return setError(); - } - else - { - // take ownership of buffer (probably leaking) - auto data = readResult.extractSlice(); - se = new StringExp(e.loc, data); - global.fileManager.add(fileName, data); - } + e.error("cannot read file `%s`", resolvedNamez.ptr); + return setError(); } } result = se.expressionSemantic(sc); @@ -6321,7 +6358,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf("AssertExp::semantic('%s')\n", exp.toChars()); } - const generateMsg = !exp.msg && global.params.checkAction == CHECKACTION.context && global.params.useAssert == CHECKENABLE.on; + const generateMsg = !exp.msg && + sc.needsCodegen() && // let ctfe interpreter handle the error message + global.params.checkAction == CHECKACTION.context && + global.params.useAssert == CHECKENABLE.on; Expression temporariesPrefix; if (generateMsg) @@ -6634,7 +6674,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { import dmd.statementsem; - if (StatementSemanticVisitor.throwSemantic(te.loc, te.e1, sc)) + if (throwSemantic(te.loc, te.e1, sc)) result = te; else setError(); @@ -6927,7 +6967,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } // Indicate we need to resolve by UFCS. - Expression e = exp.dotTemplateSemanticProp(sc, 1); + Expression e = exp.dotTemplateSemanticProp(sc, DotExpFlag.gag); if (!e) e = resolveUFCSProperties(sc, exp); if (e is exp) @@ -7824,7 +7864,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } } - if(t1b.ty == Tarray && exp.e1.op != EXP.arrayLiteral && (sc.flags & SCOPE.ctfe) == 0) + if(t1b.ty == Tarray && exp.e1.op != EXP.arrayLiteral && sc.needsCodegen()) { auto tFrom = t1b.nextOf(); auto tTo = tob.nextOf(); @@ -8914,6 +8954,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor assert((*ae.arguments)[0].op == EXP.interval); ie = cast(IntervalExp)(*ae.arguments)[0]; } + Type att = null; // first cyclic `alias this` type while (true) { if (ae.e1.op == EXP.error) @@ -8988,7 +9029,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // No operator overloading member function found yet, but // there might be an alias this to try. - if (ad.aliasthis && !isRecursiveAliasThis(ae.att1, ae.e1.type)) + if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type)) { /* Rewrite (a[arguments] op e2) as: * a.aliasthis[arguments] op e2 @@ -9016,7 +9057,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ if (auto dti = e1x.isDotTemplateInstanceExp()) { - Expression e = dti.dotTemplateSemanticProp(sc, 1); + Expression e = dti.dotTemplateSemanticProp(sc, DotExpFlag.gag); if (!e) { return setResult(resolveUFCSProperties(sc, e1x, exp.e2)); @@ -9070,7 +9111,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor * or: * f() = value */ - if (Expression e = resolvePropertiesX(sc, e1x, exp.e2)) + if (Expression e = resolvePropertiesX(sc, e1x, exp.e2, exp)) return setResult(e); if (e1x.checkRightThis(sc)) @@ -9764,6 +9805,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setResult(res); } + if (!sc.needsCodegen()) // if compile time creature only + { + exp.type = Type.tsize_t; + return setResult(exp); + } + // Lower to object._d_arraysetlengthTImpl!(typeof(e1))._d_arraysetlengthT{,Trace}(e1, e2) Expression id = new IdentifierExp(ale.loc, Id.empty); id = new DotIdExp(ale.loc, id, Id.object); @@ -9785,10 +9832,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor arguments.push(ale.e1); arguments.push(exp.e2); - Expression ce = new CallExp(ale.loc, id, arguments); - auto res = ce.expressionSemantic(sc); + Expression ce = new CallExp(ale.loc, id, arguments).expressionSemantic(sc); + auto res = new LoweredAssignExp(exp, ce); // if (global.params.verbose) // message("lowered %s =>\n %s", exp.toChars(), res.toChars()); + res.type = Type.tsize_t; return setResult(res); } else if (auto se = exp.e1.isSliceExp()) @@ -10117,6 +10165,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } } } + + if (!sc.needsCodegen()) // interpreter can handle these + return setResult(res); + const lowerToArrayCtor = ( (rhsType.ty == Tarray && !rhs.isArrayLiteralExp) || (rhsType.ty == Tsarray && rhs.isLvalue) ) && @@ -10505,7 +10557,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor result = res; if ((exp.op == EXP.concatenateAssign || exp.op == EXP.concatenateElemAssign) && - !(sc.flags & (SCOPE.ctfe | SCOPE.compile))) + sc.needsCodegen()) { // if aa ordering is triggered, `res` will be a CommaExp // and `.e2` will be the rewritten original expression. @@ -10898,6 +10950,86 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } + /** + * If the given expression is a `CatExp`, the function tries to lower it to + * `_d_arraycatnTX`. + * + * Params: + * ee = the `CatExp` to lower + * Returns: + * `_d_arraycatnTX(e1, e2, ..., en)` if `ee` is `e1 ~ e2 ~ ... en` + * `ee` otherwise + */ + private Expression lowerToArrayCat(CatExp exp) + { + // String literals are concatenated by the compiler. No lowering is needed. + if ((exp.e1.isStringExp() && (exp.e2.isIntegerExp() || exp.e2.isStringExp())) || + (exp.e2.isStringExp() && (exp.e1.isIntegerExp() || exp.e1.isStringExp()))) + return exp; + + Identifier hook = global.params.tracegc ? Id._d_arraycatnTXTrace : Id._d_arraycatnTX; + if (!verifyHookExist(exp.loc, *sc, hook, "concatenating arrays")) + { + setError(); + return result; + } + + void handleCatArgument(Expressions *arguments, Expression e) + { + if (auto ce = e.isCatExp()) + { + Expression lowering = ce.lowering; + + /* Skip `file`, `line`, and `funcname` if the hook of the parent + * `CatExp` is `_d_arraycatnTXTrace`. + */ + if (auto callExp = isRuntimeHook(lowering, hook)) + { + if (hook == Id._d_arraycatnTX) + arguments.pushSlice((*callExp.arguments)[]); + else + arguments.pushSlice((*callExp.arguments)[3 .. $]); + } + } + else + arguments.push(e); + } + + auto arguments = new Expressions(); + if (global.params.tracegc) + { + auto funcname = (sc.callsc && sc.callsc.func) ? + sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars(); + arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString())); + arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32)); + arguments.push(new StringExp(exp.loc, funcname.toDString())); + } + + handleCatArgument(arguments, exp.e1); + handleCatArgument(arguments, exp.e2); + + Expression id = new IdentifierExp(exp.loc, Id.empty); + id = new DotIdExp(exp.loc, id, Id.object); + + auto tiargs = new Objects(); + tiargs.push(exp.type); + id = new DotTemplateInstanceExp(exp.loc, id, hook, tiargs); + id = new CallExp(exp.loc, id, arguments); + return id.expressionSemantic(sc); + } + + void trySetCatExpLowering(Expression exp) + { + /* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be + * used with `-betterC`, but only during CTFE. + */ + if (global.params.betterC) + return; + + if (auto ce = exp.isCatExp()) + ce.lowering = lowerToArrayCat(ce); + } + override void visit(CatExp exp) { // https://dlang.org/spec/expression.html#cat_expressions @@ -10985,14 +11117,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.e2 = exp.e2.implicitCastTo(sc, tb1next); exp.type = tb1next.arrayOf(); L2elem: - if (tb2.ty == Tarray || tb2.ty == Tsarray) - { - // Make e2 into [e2] - exp.e2 = new ArrayLiteralExp(exp.e2.loc, exp.type, exp.e2); - } - else if (checkNewEscape(sc, exp.e2, false)) + if (checkNewEscape(sc, exp.e2, false)) return setError(); result = exp.optimize(WANTvalue); + trySetCatExpLowering(result); return; } } @@ -11023,14 +11151,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.e1 = exp.e1.implicitCastTo(sc, tb2next); exp.type = tb2next.arrayOf(); L1elem: - if (tb1.ty == Tarray || tb1.ty == Tsarray) - { - // Make e1 into [e1] - exp.e1 = new ArrayLiteralExp(exp.e1.loc, exp.type, exp.e1); - } - else if (checkNewEscape(sc, exp.e1, false)) + if (checkNewEscape(sc, exp.e1, false)) return setError(); result = exp.optimize(WANTvalue); + trySetCatExpLowering(result); return; } } @@ -11053,6 +11177,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (Expression ex = typeCombine(exp, sc)) { result = ex; + trySetCatExpLowering(result); return; } exp.type = exp.type.toHeadMutable(); @@ -11085,6 +11210,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } result = e; + trySetCatExpLowering(result); } override void visit(MulExp exp) @@ -11895,7 +12021,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.error("array comparison type mismatch, `%s` vs `%s`", t1next.toChars(), t2next.toChars()); return setError(); } - if ((t1.ty == Tarray || t1.ty == Tsarray) && (t2.ty == Tarray || t2.ty == Tsarray)) + + if (sc.needsCodegen() && + (t1.ty == Tarray || t1.ty == Tsarray) && + (t2.ty == Tarray || t2.ty == Tsarray)) { if (!verifyHookExist(exp.loc, *sc, Id.__cmp, "comparing arrays")) return setError(); @@ -12762,7 +12891,7 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) if (exp.e1.isVarExp() && exp.e1.type.toBasetype().isTypeSArray() && exp.ident == Id.length) { // bypass checkPurity - return exp.e1.type.dotExp(sc, exp.e1, exp.ident, exp.noderef ? DotExpFlag.noDeref : 0); + return exp.e1.type.dotExp(sc, exp.e1, exp.ident, cast(DotExpFlag) (exp.noderef * DotExpFlag.noDeref)); } if (!exp.e1.isDotExp()) @@ -12814,11 +12943,11 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) * Params: * exp = expression to resolve * sc = context - * flag = if 1 then do not emit error messages, just return null + * gag = do not emit error messages, just return `null` * Returns: * resolved expression, null if error */ -Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag) +Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag) { //printf("DotIdExp::semanticY(this = %p, '%s')\n", exp, exp.toChars()); @@ -13061,9 +13190,9 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag) } if (ie.sds.isPackage() || ie.sds.isImport() || ie.sds.isModule()) { - flag = 0; + gag = false; } - if (flag) + if (gag) return null; s = ie.sds.search_correct(exp.ident); if (s && symbolIsVisible(sc, s)) @@ -13089,7 +13218,7 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag) )) { Type t1bn = t1b.nextOf(); - if (flag) + if (gag) { if (AggregateDeclaration ad = isAggregate(t1bn)) { @@ -13103,11 +13232,12 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag) * as: * (*p).ident */ - if (flag && t1bn.ty == Tvoid) + if (gag && t1bn.ty == Tvoid) return null; Expression e = new PtrExp(exp.loc, exp.e1); e = e.expressionSemantic(sc); - return e.type.dotExp(sc, e, exp.ident, flag | (exp.noderef ? DotExpFlag.noDeref : 0)); + const newFlag = cast(DotExpFlag) (gag * DotExpFlag.gag | exp.noderef * DotExpFlag.noDeref); + return e.type.dotExp(sc, e, exp.ident, newFlag); } else if (exp.ident == Id.__xalignof && exp.e1.isVarExp() && @@ -13140,8 +13270,11 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag) else { if (exp.e1.isTypeExp() || exp.e1.isTemplateExp()) - flag = 0; - Expression e = exp.e1.type.dotExp(sc, exp.e1, exp.ident, flag | (exp.noderef ? DotExpFlag.noDeref : 0)); + gag = false; + + const flag = cast(DotExpFlag) (exp.noderef * DotExpFlag.noDeref | gag * DotExpFlag.gag); + + Expression e = exp.e1.type.dotExp(sc, exp.e1, exp.ident, flag); if (e) { e = e.expressionSemantic(sc); @@ -13150,9 +13283,16 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag) } } -// Resolve e1.ident!tiargs without seeing UFCS. -// If flag == 1, stop "not a property" error and return NULL. -Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, int flag) +/** + * Resolve `e1.ident!tiargs` without seeing UFCS. + * Params: + * exp = the `DotTemplateInstanceExp` to resolve + * sc = the semantic scope + * gag = stop "not a property" error and return `null`. + * Returns: + * `null` if error or not found, or the resolved expression. + */ +Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, bool gag) { static if (LOGSEMANTIC) { @@ -13186,11 +13326,11 @@ Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, int fl /* No built-in type has templatized properties, so do shortcut. * It is necessary in: 1024.max!"a < b" */ - if (flag) + if (gag) return null; } - e = die.dotIdSemanticProp(sc, flag); - if (flag) + e = die.dotIdSemanticProp(sc, gag); + if (gag) { if (!e || isDotOpDispatch(e)) @@ -13905,6 +14045,7 @@ Expression toBoolean(Expression exp, Scope* sc) case EXP.assign: case EXP.construct: case EXP.blit: + case EXP.loweredAssignExp: if (sc.flags & SCOPE.Cfile) return exp; // Things like: diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d index ba2825a..7a96469 100644 --- a/gcc/d/dmd/foreachvar.d +++ b/gcc/d/dmd/foreachvar.d @@ -299,7 +299,7 @@ void foreachExpAndVar(Statement s, case STMT.Conditional: case STMT.While: case STMT.Forwarding: - case STMT.Compile: + case STMT.Mixin: case STMT.Peel: case STMT.Synchronized: assert(0); // should have been rewritten diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 4b6b5b5..8e11ab1 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -204,6 +204,7 @@ private struct FUNCFLAG bool hasCatches; /// function has try-catch statements bool skipCodegen; /// do not generate code for this function. bool printf; /// is a printf-like function + bool scanf; /// is a scanf-like function bool noreturn; /// the function does not return bool isNRVO = true; /// Support for named return value optimization @@ -214,11 +215,14 @@ private struct FUNCFLAG bool hasNoEH; /// No exception unwinding is needed bool inferRetType; /// Return type is to be inferred bool hasDualContext; /// has a dual-context 'this' parameter + bool hasAlwaysInlines; /// Contains references to functions that must be inlined bool isCrtCtor; /// Has attribute pragma(crt_constructor) bool isCrtDtor; /// Has attribute pragma(crt_destructor) bool hasEscapingSiblings;/// Has sibling functions that escape bool computedEscapingSiblings; /// `hasEscapingSiblings` has been computed + bool dllImport; /// __declspec(dllimport) + bool dllExport; /// __declspec(dllexport) } /*********************************************************** @@ -356,6 +360,9 @@ extern (C++) class FuncDeclaration : Declaration /// In case of failed `@safe` inference, store the error that made the function `@system` for /// better diagnostics AttributeViolation* safetyViolation; + AttributeViolation* nogcViolation; + AttributeViolation* pureViolation; + AttributeViolation* nothrowViolation; /// See the `FUNCFLAG` struct import dmd.common.bitfields; @@ -370,8 +377,8 @@ extern (C++) class FuncDeclaration : Declaration extern (D) this(const ref Loc loc, const ref Loc endloc, Identifier ident, StorageClass storage_class, Type type, bool noreturn = false) { super(loc, ident); - //printf("FuncDeclaration(id = '%s', type = %p)\n", id.toChars(), type); - //printf("storage_class = x%x\n", storage_class); + //.printf("FuncDeclaration(id = '%s', type = %s)\n", ident.toChars(), type.toChars()); + //.printf("storage_class = x%llx\n", storage_class); this.storage_class = storage_class; this.type = type; if (type) @@ -1294,14 +1301,14 @@ extern (C++) class FuncDeclaration : Declaration override final bool isExport() const { - return visibility.kind == Visibility.Kind.export_; + return visibility.kind == Visibility.Kind.export_ || dllExport; } override final bool isImportedSymbol() const { //printf("isImportedSymbol()\n"); //printf("protection = %d\n", visibility); - return (visibility.kind == Visibility.Kind.export_) && !fbody; + return (visibility.kind == Visibility.Kind.export_ || dllImport) && !fbody; } override final bool isCodeseg() const pure nothrow @nogc @safe @@ -1441,17 +1448,27 @@ extern (C++) class FuncDeclaration : Declaration } /************************************** - * The function is doing something impure, - * so mark it as impure. - * If there's a purity error, return true. + * The function is doing something impure, so mark it as impure. + * + * Params: + * loc = location of impure action + * fmt = format string for error message. Must include "%s `%s`" for the function kind and name. + * arg0 = (optional) argument to format string + * + * Returns: `true` if there's a purity error */ - extern (D) final bool setImpure() + extern (D) final bool setImpure(Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null) { if (purityInprocess) { purityInprocess = false; + if (fmt) + pureViolation = new AttributeViolation(loc, fmt, this, arg0); // impure action + else if (arg0) + pureViolation = new AttributeViolation(loc, fmt, arg0); // call to impure function + if (fes) - fes.func.setImpure(); + fes.func.setImpure(loc, fmt, arg0); } else if (isPure()) return true; @@ -1540,7 +1557,7 @@ extern (C++) class FuncDeclaration : Declaration { //printf("isNogc() %s, inprocess: %d\n", toChars(), !!(flags & FUNCFLAG.nogcInprocess)); if (nogcInprocess) - setGC(); + setGC(loc, null); return type.toTypeFunction().isnogc; } @@ -1552,10 +1569,16 @@ extern (C++) class FuncDeclaration : Declaration /************************************** * The function is doing something that may allocate with the GC, * so mark it as not nogc (not no-how). + * + * Params: + * loc = location of impure action + * fmt = format string for error message. Must include "%s `%s`" for the function kind and name. + * arg0 = (optional) argument to format string + * * Returns: * true if function is marked as @nogc, meaning a user error occurred */ - extern (D) final bool setGC() + extern (D) final bool setGC(Loc loc, const(char)* fmt, RootObject arg0 = null) { //printf("setGC() %s\n", toChars()); if (nogcInprocess && semanticRun < PASS.semantic3 && _scope) @@ -1567,15 +1590,59 @@ extern (C++) class FuncDeclaration : Declaration if (nogcInprocess) { nogcInprocess = false; + if (fmt) + nogcViolation = new AttributeViolation(loc, fmt, this, arg0); // action that requires GC + else if (arg0) + nogcViolation = new AttributeViolation(loc, fmt, arg0); // call to non-@nogc function + type.toTypeFunction().isnogc = false; if (fes) - fes.func.setGC(); + fes.func.setGC(Loc.init, null, null); } else if (isNogc()) return true; return false; } + /************************************** + * The function calls non-`@nogc` function f, mark it as not nogc. + * Params: + * f = function being called + * Returns: + * true if function is marked as @nogc, meaning a user error occurred + */ + extern (D) final bool setGCCall(FuncDeclaration f) + { + return setGC(loc, null, f); + } + + /************************************** + * The function is doing something that may throw an exception, register that in case nothrow is being inferred + * + * Params: + * loc = location of action + * fmt = format string for error message + * arg0 = (optional) argument to format string + */ + extern (D) final void setThrow(Loc loc, const(char)* fmt, RootObject arg0 = null) + { + if (nothrowInprocess && !nothrowViolation) + { + nothrowViolation = new AttributeViolation(loc, fmt, arg0); // action that requires GC + } + } + + /************************************** + * The function calls non-`nothrow` function f, register that in case nothrow is being inferred + * Params: + * loc = location of call + * f = function being called + */ + extern (D) final void setThrowCall(Loc loc, FuncDeclaration f) + { + return setThrow(loc, null, f); + } + extern (D) final void printGCUsage(const ref Loc loc, const(char)* warn) { if (!global.params.vgc) @@ -2119,7 +2186,7 @@ extern (C++) class FuncDeclaration : Declaration if (!needsClosure()) return false; - if (setGC()) + if (setGC(loc, "%s `%s` is `@nogc` yet allocates closure for `%s()` with the GC", this)) { error("is `@nogc` yet allocates closure for `%s()` with the GC", toChars()); if (global.gag) // need not report supplemental errors @@ -4531,18 +4598,51 @@ struct AttributeViolation /// fd = function to check /// maxDepth = up to how many functions deep to report errors /// deprecation = print deprecations instead of errors -void errorSupplementalInferredSafety(FuncDeclaration fd, int maxDepth, bool deprecation) +/// stc = storage class of attribute to check +void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool deprecation, STC stc) { auto errorFunc = deprecation ? &deprecationSupplemental : &errorSupplemental; - if (auto s = fd.safetyViolation) + + AttributeViolation* s; + const(char)* attr; + if (stc & STC.safe) + { + s = fd.safetyViolation; + attr = "@safe"; + } + else if (stc & STC.pure_) + { + s = fd.pureViolation; + attr = "pure"; + } + else if (stc & STC.nothrow_) + { + s = fd.nothrowViolation; + attr = "nothrow"; + } + else if (stc & STC.nogc) + { + s = fd.nogcViolation; + attr = "@nogc"; + } + + if (s) { if (s.fmtStr) { errorFunc(s.loc, deprecation ? - "which would be `@system` because of:" : - "which was inferred `@system` because of:"); - errorFunc(s.loc, s.fmtStr, - s.arg0 ? s.arg0.toChars() : "", s.arg1 ? s.arg1.toChars() : "", s.arg2 ? s.arg2.toChars() : ""); + "which wouldn't be `%s` because of:" : + "which wasn't inferred `%s` because of:", attr); + if (stc == STC.nogc || stc == STC.pure_) + { + auto f = (cast(Dsymbol) s.arg0).isFuncDeclaration(); + errorFunc(s.loc, s.fmtStr, f.kind(), f.toPrettyChars(), s.arg1 ? s.arg1.toChars() : ""); + } + else + { + errorFunc(s.loc, s.fmtStr, + s.arg0 ? s.arg0.toChars() : "", s.arg1 ? s.arg1.toChars() : "", s.arg2 ? s.arg2.toChars() : ""); + } } else if (s.arg0.dyncast() == DYNCAST.dsymbol) { @@ -4551,7 +4651,7 @@ void errorSupplementalInferredSafety(FuncDeclaration fd, int maxDepth, bool depr if (maxDepth > 0) { errorFunc(s.loc, "which calls `%s`", fd2.toPrettyChars()); - errorSupplementalInferredSafety(fd2, maxDepth - 1, deprecation); + errorSupplementalInferredAttr(fd2, maxDepth - 1, deprecation, stc); } } } diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 1919d9a..45b4528 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -11,7 +11,10 @@ module dmd.globals; +import core.stdc.stdio; import core.stdc.stdint; +import core.stdc.string; + import dmd.root.array; import dmd.root.filename; import dmd.common.outbuffer; @@ -20,6 +23,8 @@ import dmd.errors; import dmd.file_manager; import dmd.identifier; import dmd.location; +import dmd.lexer : CompileEnv; +import dmd.utils; /// Defines a setting for how compiler warnings and deprecations are handled enum DiagnosticReporting : ubyte @@ -149,7 +154,7 @@ extern (C++) struct Param FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params bool ehnogc; // use @nogc exception handling bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md - bool fieldwise; // do struct equality testing field-wise rather than by memcmp() + FeatureState fieldwise; // do struct equality testing field-wise rather than by memcmp() bool fixAliasThis; // if the current scope has an alias this, check it before searching upper scopes FeatureState rvalueRefParam; // allow rvalues to be arguments to ref parameters // https://dconf.org/2019/talks/alexandrescu.html @@ -209,6 +214,7 @@ extern (C++) struct Param bool run; // run resulting executable Strings runargs; // arguments for executable Array!(const(char)*) cppswitches; // C preprocessor switches + const(char)* cpp; // if not null, then this specifies the C preprocessor // Linker stuff Array!(const(char)*) objfiles; @@ -222,30 +228,6 @@ extern (C++) struct Param const(char)[] mapfile; } -extern (C++) struct structalign_t -{ - private: - ushort value = 0; // unknown - enum STRUCTALIGN_DEFAULT = 1234; // default = match whatever the corresponding C compiler does - bool pack; // use #pragma pack semantics - - public: - pure @safe @nogc nothrow: - bool isDefault() const { return value == STRUCTALIGN_DEFAULT; } - void setDefault() { value = STRUCTALIGN_DEFAULT; } - bool isUnknown() const { return value == 0; } // value is not set - void setUnknown() { value = 0; } - void set(uint value) { this.value = cast(ushort)value; } - uint get() const { return value; } - bool isPack() const { return pack; } - void setPack(bool pack) { this.pack = pack; } -} -//alias structalign_t = uint; - -// magic value means "match whatever the underlying C compiler does" -// other values are all powers of 2 -//enum STRUCTALIGN_DEFAULT = (cast(structalign_t)~0); - enum mars_ext = "d"; // for D source files enum doc_ext = "html"; // for Ddoc generated files enum ddoc_ext = "ddoc"; // for Ddoc macro include files @@ -270,9 +252,7 @@ extern (C++) struct Global Array!(const(char)*)* filePath; /// Array of char*'s which form the file import lookup path private enum string _version = import("VERSION"); - private enum uint _versionNumber = parseVersionNumber(_version); - - const(char)[] vendor; /// Compiler backend name + CompileEnv compileEnv; Param params; /// command line parameters uint errors; /// number of errors reported so far @@ -350,12 +330,12 @@ extern (C++) struct Global extern (C++) void _init() { - global.errorSink = new ErrorSinkCompiler; + errorSink = new ErrorSinkCompiler; this.fileManager = new FileManager(); version (MARS) { - vendor = "Digital Mars D"; + compileEnv.vendor = "Digital Mars D"; // -color=auto is the default value import dmd.console : detectTerminal; @@ -363,8 +343,38 @@ extern (C++) struct Global } else version (IN_GCC) { - vendor = "GNU D"; + compileEnv.vendor = "GNU D"; + } + compileEnv.versionNumber = parseVersionNumber(_version); + + /* Initialize date, time, and timestamp + */ + import core.stdc.time; + import core.stdc.stdlib : getenv; + + time_t ct; + // https://issues.dlang.org/show_bug.cgi?id=20444 + if (auto p = getenv("SOURCE_DATE_EPOCH")) + { + if (!ct.parseDigits(p[0 .. strlen(p)])) + errorSink.error(Loc.initial, "value of environment variable `SOURCE_DATE_EPOCH` should be a valid UNIX timestamp, not: `%s`", p); } + else + core.stdc.time.time(&ct); + const p = ctime(&ct); + assert(p); + + __gshared char[11 + 1] date = 0; // put in BSS segment + __gshared char[8 + 1] time = 0; + __gshared char[24 + 1] timestamp = 0; + + const dsz = snprintf(&date[0], date.length, "%.6s %.4s", p + 4, p + 20); + const tsz = snprintf(&time[0], time.length, "%.8s", p + 11); + const tssz = snprintf(×tamp[0], timestamp.length, "%.24s", p); + assert(dsz > 0 && tsz > 0 && tssz > 0); + compileEnv.time = time[0 .. tsz]; + compileEnv.date = date[0 .. dsz]; + compileEnv.timestamp = timestamp[0 .. tssz]; } /** @@ -415,7 +425,7 @@ extern (C++) struct Global */ extern(C++) uint versionNumber() { - return _versionNumber; + return compileEnv.versionNumber; } /** diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 84fbec6..902cf83 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -151,7 +151,7 @@ struct Param FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params d_bool ehnogc; // use @nogc exception handling d_bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md - d_bool fieldwise; // do struct equality testing field-wise rather than by memcmp() + FeatureState fieldwise; // do struct equality testing field-wise rather than by memcmp() d_bool fixAliasThis; // if the current scope has an alias this, check it before searching upper scopes FeatureState rvalueRefParam; // allow rvalues to be arguments to ref parameters // https://dconf.org/2019/talks/alexandrescu.html @@ -212,6 +212,7 @@ struct Param Strings runargs; // arguments for executable Array cppswitches; // preprocessor switches + const char *cpp; // if not null, then this specifies the C preprocessor // Linker stuff Array objfiles; @@ -252,6 +253,18 @@ const DString hdr_ext = "di"; // for D 'header' import files const DString json_ext = "json"; // for JSON files const DString map_ext = "map"; // for .map files +struct CompileEnv +{ + uint32_t versionNumber; + DString date; + DString time; + DString vendor; + DString timestamp; + bool previewIn; + bool ddocOutput; + bool shortenedMethods; +}; + struct Global { DString inifilename; @@ -261,7 +274,7 @@ struct Global Array *path; // Array of char*'s which form the import lookup path Array *filePath; // Array of char*'s which form the file import lookup path - DString vendor; // Compiler backend name + CompileEnv compileEnv; Param params; unsigned errors; // number of errors reported so far diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index e0684e6..a159c2f 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -134,37 +134,19 @@ void moduleToBuffer2(Module m, OutBuffer* buf, HdrGenState* hgs) private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs) { - scope v = new StatementPrettyPrintVisitor(buf, hgs); - s.accept(v); -} - -private extern (C++) final class StatementPrettyPrintVisitor : Visitor -{ - alias visit = Visitor.visit; -public: - OutBuffer* buf; - HdrGenState* hgs; - - extern (D) this(OutBuffer* buf, HdrGenState* hgs) scope + void visitDefaultCase(Statement s) { - this.buf = buf; - this.hgs = hgs; + printf("Statement::toCBuffer() %d\n", s.stmt); + assert(0, "unrecognized statement in statementToBuffer()"); } - override void visit(Statement s) - { - buf.writestring("Statement::toCBuffer()"); - buf.writenl(); - assert(0); - } - - override void visit(ErrorStatement s) + void visitError(ErrorStatement s) { buf.writestring("__error__"); buf.writenl(); } - override void visit(ExpStatement s) + void visitExp(ExpStatement s) { if (s.exp && s.exp.op == EXP.declaration && (cast(DeclarationExp)s.exp).declaration) @@ -180,7 +162,12 @@ public: buf.writenl(); } - override void visit(CompileStatement s) + void visitDtorExp(DtorExpStatement s) + { + visitExp(s); + } + + void visitMixin(MixinStatement s) { buf.writestring("mixin("); argsToBuffer(s.exps, buf, hgs, null); @@ -189,25 +176,29 @@ public: buf.writenl(); } - override void visit(CompoundStatement s) + void visitCompound(CompoundStatement s) { foreach (sx; *s.statements) { if (sx) - sx.accept(this); + sx.statementToBuffer(buf, hgs); } } - override void visit(CompoundDeclarationStatement s) + void visitCompoundAsm(CompoundAsmStatement s) + { + visitCompound(s); + } + + void visitCompoundDeclaration(CompoundDeclarationStatement s) { bool anywritten = false; foreach (sx; *s.statements) { auto ds = sx ? sx.isExpStatement() : null; - if (ds && ds.exp.op == EXP.declaration) + if (ds && ds.exp.isDeclarationExp()) { - auto d = (cast(DeclarationExp)ds.exp).declaration; - assert(d.isDeclaration()); + auto d = ds.exp.isDeclarationExp().declaration; if (auto v = d.isVarDeclaration()) { scope ppv = new DsymbolPrettyPrintVisitor(buf, hgs); @@ -223,7 +214,7 @@ public: buf.writenl(); } - override void visit(UnrolledLoopStatement s) + void visitUnrolledLoop(UnrolledLoopStatement s) { buf.writestring("/*unrolled*/ {"); buf.writenl(); @@ -231,26 +222,26 @@ public: foreach (sx; *s.statements) { if (sx) - sx.accept(this); + sx.statementToBuffer(buf, hgs); } buf.level--; buf.writeByte('}'); buf.writenl(); } - override void visit(ScopeStatement s) + void visitScope(ScopeStatement s) { buf.writeByte('{'); buf.writenl(); buf.level++; if (s.statement) - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); } - override void visit(WhileStatement s) + void visitWhile(WhileStatement s) { buf.writestring("while ("); if (auto p = s.param) @@ -271,28 +262,28 @@ public: buf.writeByte(')'); buf.writenl(); if (s._body) - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); } - override void visit(DoStatement s) + void visitDo(DoStatement s) { buf.writestring("do"); buf.writenl(); if (s._body) - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.writestring("while ("); s.condition.expressionToBuffer(buf, hgs); buf.writestring(");"); buf.writenl(); } - override void visit(ForStatement s) + void visitFor(ForStatement s) { buf.writestring("for ("); if (s._init) { hgs.forStmtInit++; - s._init.accept(this); + s._init.statementToBuffer(buf, hgs); hgs.forStmtInit--; } else @@ -314,13 +305,13 @@ public: buf.writenl(); buf.level++; if (s._body) - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); } - private void foreachWithoutBody(ForeachStatement s) + void foreachWithoutBody(ForeachStatement s) { buf.writestring(Token.toString(s.op)); buf.writestring(" ("); @@ -341,20 +332,20 @@ public: buf.writenl(); } - override void visit(ForeachStatement s) + void visitForeach(ForeachStatement s) { foreachWithoutBody(s); buf.writeByte('{'); buf.writenl(); buf.level++; if (s._body) - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); } - private void foreachRangeWithoutBody(ForeachRangeStatement s) + void foreachRangeWithoutBody(ForeachRangeStatement s) { buf.writestring(Token.toString(s.op)); buf.writestring(" ("); @@ -370,39 +361,39 @@ public: buf.writenl(); } - override void visit(ForeachRangeStatement s) + void visitForeachRange(ForeachRangeStatement s) { foreachRangeWithoutBody(s); buf.writeByte('{'); buf.writenl(); buf.level++; if (s._body) - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); } - override void visit(StaticForeachStatement s) + void visitStaticForeach(StaticForeachStatement s) { buf.writestring("static "); if (s.sfe.aggrfe) { - visit(s.sfe.aggrfe); + visitForeach(s.sfe.aggrfe); } else { assert(s.sfe.rangefe); - visit(s.sfe.rangefe); + visitForeachRange(s.sfe.rangefe); } } - override void visit(ForwardingStatement s) + void visitForwarding(ForwardingStatement s) { - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); } - override void visit(IfStatement s) + void visitIf(IfStatement s) { buf.writestring("if ("); if (Parameter p = s.prm) @@ -423,12 +414,12 @@ public: buf.writenl(); if (s.ifbody.isScopeStatement()) { - s.ifbody.accept(this); + s.ifbody.statementToBuffer(buf, hgs); } else { buf.level++; - s.ifbody.accept(this); + s.ifbody.statementToBuffer(buf, hgs); buf.level--; } if (s.elsebody) @@ -444,18 +435,18 @@ public: } if (s.elsebody.isScopeStatement() || s.elsebody.isIfStatement()) { - s.elsebody.accept(this); + s.elsebody.statementToBuffer(buf, hgs); } else { buf.level++; - s.elsebody.accept(this); + s.elsebody.statementToBuffer(buf, hgs); buf.level--; } } } - override void visit(ConditionalStatement s) + void visitConditional(ConditionalStatement s) { s.condition.conditionToBuffer(buf, hgs); buf.writenl(); @@ -463,7 +454,7 @@ public: buf.writenl(); buf.level++; if (s.ifbody) - s.ifbody.accept(this); + s.ifbody.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); @@ -474,14 +465,14 @@ public: buf.writeByte('{'); buf.level++; buf.writenl(); - s.elsebody.accept(this); + s.elsebody.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); } buf.writenl(); } - override void visit(PragmaStatement s) + void visitPragma(PragmaStatement s) { buf.writestring("pragma ("); buf.writestring(s.ident.toString()); @@ -497,7 +488,7 @@ public: buf.writeByte('{'); buf.writenl(); buf.level++; - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); @@ -509,12 +500,12 @@ public: } } - override void visit(StaticAssertStatement s) + void visitStaticAssert(StaticAssertStatement s) { s.sa.dsymbolToBuffer(buf, hgs); } - override void visit(SwitchStatement s) + void visitSwitch(SwitchStatement s) { buf.writestring(s.isFinal ? "final switch (" : "switch ("); s.condition.expressionToBuffer(buf, hgs); @@ -527,28 +518,28 @@ public: buf.writeByte('{'); buf.writenl(); buf.level++; - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); } else { - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); } } } - override void visit(CaseStatement s) + void visitCase(CaseStatement s) { buf.writestring("case "); s.exp.expressionToBuffer(buf, hgs); buf.writeByte(':'); buf.writenl(); - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); } - override void visit(CaseRangeStatement s) + void visitCaseRange(CaseRangeStatement s) { buf.writestring("case "); s.first.expressionToBuffer(buf, hgs); @@ -556,23 +547,23 @@ public: s.last.expressionToBuffer(buf, hgs); buf.writeByte(':'); buf.writenl(); - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); } - override void visit(DefaultStatement s) + void visitDefault(DefaultStatement s) { buf.writestring("default:"); buf.writenl(); - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); } - override void visit(GotoDefaultStatement s) + void visitGotoDefault(GotoDefaultStatement s) { buf.writestring("goto default;"); buf.writenl(); } - override void visit(GotoCaseStatement s) + void visitGotoCase(GotoCaseStatement s) { buf.writestring("goto case"); if (s.exp) @@ -584,13 +575,13 @@ public: buf.writenl(); } - override void visit(SwitchErrorStatement s) + void visitSwitchError(SwitchErrorStatement s) { buf.writestring("SwitchErrorStatement::toCBuffer()"); buf.writenl(); } - override void visit(ReturnStatement s) + void visitReturn(ReturnStatement s) { buf.writestring("return "); if (s.exp) @@ -599,7 +590,7 @@ public: buf.writenl(); } - override void visit(BreakStatement s) + void visitBreak(BreakStatement s) { buf.writestring("break"); if (s.ident) @@ -611,7 +602,7 @@ public: buf.writenl(); } - override void visit(ContinueStatement s) + void visitContinue(ContinueStatement s) { buf.writestring("continue"); if (s.ident) @@ -623,7 +614,7 @@ public: buf.writenl(); } - override void visit(SynchronizedStatement s) + void visitSynchronized(SynchronizedStatement s) { buf.writestring("synchronized"); if (s.exp) @@ -635,21 +626,21 @@ public: if (s._body) { buf.writeByte(' '); - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); } } - override void visit(WithStatement s) + void visitWith(WithStatement s) { buf.writestring("with ("); s.exp.expressionToBuffer(buf, hgs); buf.writestring(")"); buf.writenl(); if (s._body) - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); } - override void visit(TryCatchStatement s) + void visitTryCatch(TryCatchStatement s) { buf.writestring("try"); buf.writenl(); @@ -657,29 +648,44 @@ public: { if (s._body.isScopeStatement()) { - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); } else { buf.level++; - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.level--; } } foreach (c; *s.catches) { - visit(c); + buf.writestring("catch"); + if (c.type) + { + buf.writeByte('('); + typeToBuffer(c.type, c.ident, buf, hgs); + buf.writeByte(')'); + } + buf.writenl(); + buf.writeByte('{'); + buf.writenl(); + buf.level++; + if (c.handler) + c.handler.statementToBuffer(buf, hgs); + buf.level--; + buf.writeByte('}'); + buf.writenl(); } } - override void visit(TryFinallyStatement s) + void visitTryFinally(TryFinallyStatement s) { buf.writestring("try"); buf.writenl(); buf.writeByte('{'); buf.writenl(); buf.level++; - s._body.accept(this); + s._body.statementToBuffer(buf, hgs); buf.level--; buf.writeByte('}'); buf.writenl(); @@ -687,25 +693,25 @@ public: buf.writenl(); if (s.finalbody.isScopeStatement()) { - s.finalbody.accept(this); + s.finalbody.statementToBuffer(buf, hgs); } else { buf.level++; - s.finalbody.accept(this); + s.finalbody.statementToBuffer(buf, hgs); buf.level--; } } - override void visit(ScopeGuardStatement s) + void visitScopeGuard(ScopeGuardStatement s) { buf.writestring(Token.toString(s.tok)); buf.writeByte(' '); if (s.statement) - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); } - override void visit(ThrowStatement s) + void visitThrow(ThrowStatement s) { buf.writestring("throw "); s.exp.expressionToBuffer(buf, hgs); @@ -713,15 +719,15 @@ public: buf.writenl(); } - override void visit(DebugStatement s) + void visitDebug(DebugStatement s) { if (s.statement) { - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); } } - override void visit(GotoStatement s) + void visitGoto(GotoStatement s) { buf.writestring("goto "); buf.writestring(s.ident.toString()); @@ -729,16 +735,16 @@ public: buf.writenl(); } - override void visit(LabelStatement s) + void visitLabel(LabelStatement s) { buf.writestring(s.ident.toString()); buf.writeByte(':'); buf.writenl(); if (s.statement) - s.statement.accept(this); + s.statement.statementToBuffer(buf, hgs); } - override void visit(AsmStatement s) + void visitAsm(AsmStatement s) { buf.writestring("asm { "); Token* t = s.tokens; @@ -764,33 +770,26 @@ public: buf.writenl(); } - override void visit(ImportStatement s) + void visitInlineAsm(InlineAsmStatement s) { - foreach (imp; *s.imports) - { - imp.dsymbolToBuffer(buf, hgs); - } + visitAsm(s); } - void visit(Catch c) + void visitGccAsm(GccAsmStatement s) { - buf.writestring("catch"); - if (c.type) + visitAsm(s); + } + + void visitImport(ImportStatement s) + { + foreach (imp; *s.imports) { - buf.writeByte('('); - typeToBuffer(c.type, c.ident, buf, hgs); - buf.writeByte(')'); + imp.dsymbolToBuffer(buf, hgs); } - buf.writenl(); - buf.writeByte('{'); - buf.writenl(); - buf.level++; - if (c.handler) - c.handler.accept(this); - buf.level--; - buf.writeByte('}'); - buf.writenl(); } + + mixin VisitStatement!void visit; + visit.VisitStatement(s); } private void dsymbolToBuffer(Dsymbol s, OutBuffer* buf, HdrGenState* hgs) @@ -1160,7 +1159,7 @@ public: } - override void visit(CompileDeclaration d) + override void visit(MixinDeclaration d) { buf.writestring("mixin("); argsToBuffer(d.exps, buf, hgs, null); @@ -2321,6 +2320,16 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg expToBuffer(e.e1, precedence[e.op], buf, hgs); } + void visitLoweredAssignExp(LoweredAssignExp e) + { + if (global.params.vcg_ast) + { + expressionToBuffer(e.lowering, buf, hgs); + return; + } + + visit(cast(BinExp)e); + } void visitBin(BinExp e) { expToBuffer(e.e1, precedence[e.op], buf, hgs); @@ -2694,6 +2703,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg case EXP.remove: return visitRemove(e.isRemoveExp()); case EXP.question: return visitCond(e.isCondExp()); case EXP.classReference: return visitClassReference(e.isClassReferenceExp()); + case EXP.loweredAssignExp: return visitLoweredAssignExp(e.isLoweredAssignExp()); } } @@ -2882,8 +2892,7 @@ public: void toCBuffer(const Statement s, OutBuffer* buf, HdrGenState* hgs) { - scope v = new StatementPrettyPrintVisitor(buf, hgs); - (cast() s).accept(v); + (cast()s).statementToBuffer(buf, hgs); } void toCBuffer(const Type t, OutBuffer* buf, const Identifier ident, HdrGenState* hgs) @@ -3223,6 +3232,7 @@ private void parametersToBuffer(ParameterList pl, OutBuffer* buf, HdrGenState* h final switch (pl.varargs) { case VarArg.none: + case VarArg.KRvariadic: break; case VarArg.variadic: @@ -3817,15 +3827,8 @@ private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* h buf.writeByte('}'); } - final switch (inx.kind) - { - case InitKind.error: return visitError (inx.isErrorInitializer ()); - case InitKind.void_: return visitVoid (inx.isVoidInitializer ()); - case InitKind.struct_: return visitStruct(inx.isStructInitializer()); - case InitKind.array: return visitArray (inx.isArrayInitializer ()); - case InitKind.exp: return visitExp (inx.isExpInitializer ()); - case InitKind.C_: return visitC (inx.isCInitializer ()); - } + mixin VisitInitializer!void visit; + visit.VisitInitializer(inx); } @@ -4101,7 +4104,6 @@ string EXPtoString(EXP op) EXP.error : "error", EXP.objcClassReference : "class", - EXP.typeof_ : "typeof", EXP.mixin_ : "mixin", EXP.import_ : "import", @@ -4141,7 +4143,6 @@ string EXPtoString(EXP op) EXP.remove : "remove", EXP.tuple : "tuple", EXP.traits : "__traits", - EXP.default_ : "default", EXP.overloadSet : "__overloadset", EXP.void_ : "void", EXP.vectorArray : "vectorarray", @@ -4232,6 +4233,7 @@ string EXPtoString(EXP op) EXP.declaration : "declaration", EXP.interval : "interval", + EXP.loweredAssignExp : "=" ]; const p = strings[op]; if (!p) diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d index 4d780b3..66829da 100644 --- a/gcc/d/dmd/iasm.d +++ b/gcc/d/dmd/iasm.d @@ -13,9 +13,15 @@ module dmd.iasm; +import core.stdc.stdio; + import dmd.dscope; +import dmd.expression; import dmd.func; +import dmd.mtype; +import dmd.tokens; import dmd.statement; +import dmd.statementsem; version (MARS) { @@ -43,6 +49,19 @@ extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc) version (MARS) { + /* If it starts with a string literal, it's gcc inline asm + */ + if (s.tokens.value == TOK.string_) + { + /* Replace the asm statement with an assert(0, msg) that trips at runtime. + */ + const loc = s.loc; + auto e = new IntegerExp(loc, 0, Type.tint32); + auto msg = new StringExp(loc, "Gnu Asm not supported - compile this function with gcc or clang"); + auto ae = new AssertExp(loc, e, msg); + auto se = new ExpStatement(loc, ae); + return statementSemantic(se, sc); + } auto ias = new InlineAsmStatement(s.loc, s.tokens); return inlineAsmSemantic(ias, sc); } diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d index f8c88ab..1d4dea4 100644 --- a/gcc/d/dmd/iasmgcc.d +++ b/gcc/d/dmd/iasmgcc.d @@ -302,7 +302,8 @@ Ldone: extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc) { //printf("GccAsmStatement.semantic()\n"); - scope p = new Parser!ASTCodegen(sc._module, ";", false, global.errorSink); + const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; + scope p = new Parser!ASTCodegen(sc._module, ";", false, global.errorSink, &global.compileEnv, doUnittests); // Make a safe copy of the token list before parsing. Token *toklist = null; @@ -410,7 +411,8 @@ unittest { const errors = global.errors; scope gas = new GccAsmStatement(Loc.initial, tokens); - scope p = new Parser!ASTCodegen(null, ";", false, global.errorSink); + const bool doUnittests = false; + scope p = new Parser!ASTCodegen(null, ";", false, global.errorSink, &global.compileEnv, doUnittests); p.token = *tokens; p.parseGccAsm(gas); return global.errors - errors; @@ -420,7 +422,8 @@ unittest static void parseAsm(string input, bool expectError) { // Generate tokens from input test. - scope p = new Parser!ASTCodegen(null, input, false, global.errorSink); + const bool doUnittests = false; + scope p = new Parser!ASTCodegen(null, input, false, global.errorSink, &global.compileEnv, doUnittests); p.nextToken(); Token* toklist = null; diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d index ec5cb25..a2271d5 100644 --- a/gcc/d/dmd/id.d +++ b/gcc/d/dmd/id.d @@ -361,6 +361,8 @@ immutable Msgtable[] msgtable = { "_d_arrayappendcTXImpl" }, { "_d_arrayappendcTX" }, { "_d_arrayappendcTXTrace" }, + { "_d_arraycatnTX" }, + { "_d_arraycatnTXTrace" }, // varargs implementation { "stdc" }, @@ -370,6 +372,10 @@ immutable Msgtable[] msgtable = // Builtin functions { "std" }, { "core" }, + { "config" }, + { "c_complex_float" }, + { "c_complex_double" }, + { "c_complex_real" }, { "etc" }, { "attribute" }, { "atomic" }, @@ -519,9 +525,17 @@ immutable Msgtable[] msgtable = { "__tag" }, { "dllimport" }, { "dllexport" }, + { "naked" }, + { "thread" }, { "vector_size" }, { "__func__" }, + { "always_inline" }, + { "noinline" }, { "noreturn" }, + { "_nothrow", "nothrow" }, + { "_deprecated", "deprecated" }, + { "_align", "align" }, + { "aligned" }, { "__pragma", "pragma" }, { "builtins", "__builtins" }, { "builtin_va_list", "__builtin_va_list" }, @@ -532,6 +546,7 @@ immutable Msgtable[] msgtable = { "show" }, { "push" }, { "pop" }, + { "_pure", "pure" }, { "define" }, { "undef" }, ]; diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d index f646d03..6f20a3c 100644 --- a/gcc/d/dmd/init.d +++ b/gcc/d/dmd/init.d @@ -269,7 +269,22 @@ extern (C++) final class CInitializer : Initializer */ Initializer syntaxCopy(Initializer inx) { - static Initializer copyStruct(StructInitializer vi) + static Initializer visitVoid(VoidInitializer vi) + { + return new VoidInitializer(vi.loc); + } + + static Initializer visitError(ErrorInitializer vi) + { + return vi; + } + + static Initializer visitExp(ExpInitializer vi) + { + return new ExpInitializer(vi.loc, vi.exp.syntaxCopy()); + } + + static Initializer visitStruct(StructInitializer vi) { auto si = new StructInitializer(vi.loc); assert(vi.field.length == vi.value.length); @@ -283,7 +298,7 @@ Initializer syntaxCopy(Initializer inx) return si; } - static Initializer copyArray(ArrayInitializer vi) + static Initializer visitArray(ArrayInitializer vi) { auto ai = new ArrayInitializer(vi.loc); assert(vi.index.length == vi.value.length); @@ -297,7 +312,7 @@ Initializer syntaxCopy(Initializer inx) return ai; } - static Initializer copyC(CInitializer vi) + static Initializer visitC(CInitializer vi) { auto ci = new CInitializer(vi.loc); ci.initializerList.setDim(vi.initializerList.length); @@ -322,13 +337,62 @@ Initializer syntaxCopy(Initializer inx) return ci; } - final switch (inx.kind) + mixin VisitInitializer!Initializer visit; + return visit.VisitInitializer(inx); +} + +/*********************************************************** + * Visit each Initializer in init. Call a function visit%s(init) for + * each node, where %s is the op of the node. Otherwise call visitDefault(init) + * for that node. If the visit function returns R.init, continue + * visiting each node, otherwise return the value of R. + * Params: + * Result = return type + * init = Initializer tree to traverse + * Returns: + * Result.init for continue, value of type Result for early exit + */ + +mixin template VisitInitializer(Result) +{ + Result VisitInitializer(Initializer init) + { + final switch (init.kind) + { + case InitKind.void_: mixin(visitCase("Void")); break; + case InitKind.error: mixin(visitCase("Error")); break; + case InitKind.struct_: mixin(visitCase("Struct")); break; + case InitKind.array: mixin(visitCase("Array")); break; + case InitKind.exp: mixin(visitCase("Exp")); break; + case InitKind.C_: mixin(visitCase("C")); break; + } + static if (is(Result == void)) { } else + return Result.init; + } +} + +/**************************************** + * CTFE-only helper function for VisitInitializer. + * Params: + * handler = string for the name of the visit handler + * Returns: boilerplate code for a case + */ +pure string visitCase(string handler) +{ + if (__ctfe) { - case InitKind.void_: return new VoidInitializer(inx.loc); - case InitKind.error: return inx; - case InitKind.struct_: return copyStruct(cast(StructInitializer)inx); - case InitKind.array: return copyArray(cast(ArrayInitializer)inx); - case InitKind.exp: return new ExpInitializer(inx.loc, (cast(ExpInitializer)inx).exp.syntaxCopy()); - case InitKind.C_: return copyC(cast(CInitializer)inx); + return + " + auto ix = init.is"~handler~"Initializer(); + static if (is(Result == void)) + visit"~handler~"(ix); + else + { + Result r = visit"~handler~"(ix); + if (r !is Result.init) + return r; + } + "; } + assert(0); } diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index 18b10b4..893d2a6 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -958,15 +958,9 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ } } - final switch (init.kind) - { - case InitKind.void_: return visitVoid (init.isVoidInitializer()); - case InitKind.error: return visitError (init.isErrorInitializer()); - case InitKind.struct_: return visitStruct(init.isStructInitializer()); - case InitKind.array: return visitArray (init.isArrayInitializer()); - case InitKind.exp: return visitExp (init.isExpInitializer()); - case InitKind.C_: return visitC (init.isCInitializer()); - } + mixin VisitInitializer!Initializer visit; + auto result = visit.VisitInitializer(init); + return (result !is null) ? result : new ErrorInitializer(); } /*********************** @@ -1120,15 +1114,9 @@ Initializer inferType(Initializer init, Scope* sc) return new ErrorInitializer(); } - final switch (init.kind) - { - case InitKind.void_: return visitVoid (init.isVoidInitializer()); - case InitKind.error: return visitError (init.isErrorInitializer()); - case InitKind.struct_: return visitStruct(init.isStructInitializer()); - case InitKind.array: return visitArray (init.isArrayInitializer()); - case InitKind.exp: return visitExp (init.isExpInitializer()); - case InitKind.C_: return visitC (init.isCInitializer()); - } + mixin VisitInitializer!Initializer visit; + auto result = visit.VisitInitializer(init); + return (result !is null) ? result : new ErrorInitializer(); } /*********************** @@ -1333,15 +1321,8 @@ extern (C++) Expression initializerToExpression(Initializer init, Type itype = n return null; } - final switch (init.kind) - { - case InitKind.void_: return visitVoid (init.isVoidInitializer()); - case InitKind.error: return visitError (init.isErrorInitializer()); - case InitKind.struct_: return visitStruct(init.isStructInitializer()); - case InitKind.array: return visitArray (init.isArrayInitializer()); - case InitKind.exp: return visitExp (init.isExpInitializer()); - case InitKind.C_: return visitC (init.isCInitializer()); - } + mixin VisitInitializer!Expression visit; + return visit.VisitInitializer(init); } diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d index 2af7fae..dcf53b8 100644 --- a/gcc/d/dmd/json.d +++ b/gcc/d/dmd/json.d @@ -833,7 +833,7 @@ public: { import dmd.target : target; objectStart(); - requiredProperty("vendor", global.vendor); + requiredProperty("vendor", global.compileEnv.vendor); requiredProperty("version", global.versionString()); property("__VERSION__", global.versionNumber()); requiredProperty("interface", determineCompilerInterface()); @@ -1070,13 +1070,13 @@ Determines and returns the compiler interface which is one of `dmd`, `ldc`, */ private extern(D) string determineCompilerInterface() { - if (global.vendor == "Digital Mars D") + if (global.compileEnv.vendor == "Digital Mars D") return "dmd"; - if (global.vendor == "LDC") + if (global.compileEnv.vendor == "LDC") return "ldc"; - if (global.vendor == "GNU D") + if (global.compileEnv.vendor == "GNU D") return "gdc"; - if (global.vendor == "SDC") + if (global.compileEnv.vendor == "SDC") return "sdc"; return null; } diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index f0f7872..0ec468b 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -14,12 +14,8 @@ module dmd.lexer; import core.stdc.ctype; -import core.stdc.errno; -import core.stdc.stdarg; import core.stdc.stdio; -import core.stdc.stdlib : getenv; import core.stdc.string; -import core.stdc.time; import dmd.entity; import dmd.errorsink; @@ -31,10 +27,8 @@ import dmd.root.ctfloat; import dmd.common.outbuffer; import dmd.root.port; import dmd.root.rmem; -import dmd.root.string; import dmd.root.utf; import dmd.tokens; -import dmd.utils; nothrow: @@ -44,6 +38,22 @@ version (DMDLIB) } /*********************************************************** + * Values to use for various magic identifiers + */ +struct CompileEnv +{ + uint versionNumber; /// __VERSION__ + const(char)[] date; /// __DATE__ + const(char)[] time; /// __TIME__ + const(char)[] vendor; /// __VENDOR__ + const(char)[] timestamp; /// __TIMESTAMP__ + + bool previewIn; /// `in` means `[ref] scope const`, accepts rvalues + bool ddocOutput; /// collect embedded documentation comments + bool shortenedMethods = true; /// allow => in normal function declarations +} + +/*********************************************************** */ class Lexer { @@ -69,6 +79,7 @@ class Lexer ubyte wchar_tsize; /// size of C wchar_t, 2 or 4 ErrorSink eSink; /// send error messages through this interface + CompileEnv compileEnv; /// environment private { @@ -87,8 +98,6 @@ class Lexer int lastDocLine; // last line of previous doc comment Token* tokenFreelist; - uint versionNumber; - const(char)[] vendor; } nothrow: @@ -105,13 +114,12 @@ class Lexer * doDocComment = handle documentation comments * commentToken = comments become TOK.comment's * errorSink = where error messages go, must not be null - * vendor = name of the vendor - * versionNumber = version of the caller + * compileEnv = version, vendor, date, time, etc. */ this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, bool doDocComment, bool commentToken, ErrorSink errorSink, - const(char)[] vendor = "DLF", uint versionNumber = 1) pure scope + const CompileEnv* compileEnv) pure scope { scanloc = Loc(filename, 1, 1); // debug printf("Lexer::Lexer(%p)\n", base); @@ -128,8 +136,13 @@ class Lexer this.lastDocLine = 0; this.eSink = errorSink; assert(errorSink); - this.versionNumber = versionNumber; - this.vendor = vendor; + if (compileEnv) + this.compileEnv = *compileEnv; + else + { + this.compileEnv.versionNumber = 1; + this.compileEnv.vendor = "DLF"; + } //initKeywords(); /* If first line starts with '#!', ignore the line */ @@ -169,10 +182,10 @@ class Lexer */ this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, bool doDocComment, bool commentToken, bool whitespaceToken, - ErrorSink errorSink + ErrorSink errorSink, const CompileEnv* compileEnv = null ) { - this(filename, base, begoffset, endoffset, doDocComment, commentToken, errorSink); + this(filename, base, begoffset, endoffset, doDocComment, commentToken, errorSink, compileEnv); this.whitespaceToken = whitespaceToken; } @@ -380,6 +393,15 @@ class Lexer } } continue; // skip white space + + case '\\': + if (Ccompile && (p[1] == '\r' || p[1] == '\n')) + { + ++p; // ignore \ followed by new line, like VC does + continue; + } + goto default; + case '0': if (!isZeroSecond(p[1])) // if numeric literal does not continue { @@ -571,36 +593,26 @@ class Lexer else if (*t.ptr == '_') // if special identifier token { - // Lazy initialization - TimeStampInfo.initialize(t.loc, eSink); - - if (id == Id.DATE) + void toToken(const(char)[] s) { - t.ustring = TimeStampInfo.date.ptr; - goto Lstr; + t.value = TOK.string_; + t.ustring = s.ptr; + t.len = cast(uint)s.length; + t.postfix = 0; } + + if (id == Id.DATE) + toToken(compileEnv.date); else if (id == Id.TIME) - { - t.ustring = TimeStampInfo.time.ptr; - goto Lstr; - } + toToken(compileEnv.time); else if (id == Id.VENDOR) - { - t.ustring = vendor.xarraydup.ptr; - goto Lstr; - } + toToken(compileEnv.vendor); else if (id == Id.TIMESTAMP) - { - t.ustring = TimeStampInfo.timestamp.ptr; - Lstr: - t.value = TOK.string_; - t.postfix = 0; - t.len = cast(uint)strlen(t.ustring); - } + toToken(compileEnv.timestamp); else if (id == Id.VERSIONX) { t.value = TOK.int64Literal; - t.unsvalue = versionNumber; + t.unsvalue = compileEnv.versionNumber; } else if (id == Id.EOFX) { @@ -2570,6 +2582,14 @@ class Lexer TOK result; bool isOutOfRange = false; t.floatvalue = (isWellformedString ? CTFloat.parse(sbufptr, isOutOfRange) : CTFloat.zero); + + bool imaginary = false; + if (*p == 'i' && Ccompile) + { + ++p; + imaginary = true; + } + switch (*p) { case 'F': @@ -2595,11 +2615,17 @@ class Lexer result = TOK.float80Literal; break; } + if ((*p == 'i' || *p == 'I') && !Ccompile) { if (*p == 'I') error("use 'i' suffix instead of 'I'"); p++; + imaginary = true; + } + + if (imaginary) + { switch (result) { case TOK.float32Literal: @@ -3033,7 +3059,10 @@ class Lexer auto dc = (lineComment && anyToken) ? &t.lineComment : &t.blockComment; // Combine with previous doc comment, if any if (*dc) - *dc = combineComments(*dc, buf[], newParagraph).toDString(); + { + auto p = combineComments(*dc, buf[], newParagraph); + *dc = p ? p[0 .. strlen(p)] : null; + } else *dc = buf.extractSlice(true); } @@ -3081,42 +3110,6 @@ class Lexer private: -/// Support for `__DATE__`, `__TIME__`, and `__TIMESTAMP__` -private struct TimeStampInfo -{ - private __gshared bool initdone = false; - - // Note: Those properties need to be guarded by a call to `init` - // The API isn't safe, and quite brittle, but it was left this way - // over performance concerns. - // This is currently only called once, from the lexer. - __gshared char[11 + 1] date; - __gshared char[8 + 1] time; - __gshared char[24 + 1] timestamp; - - public static void initialize(const ref Loc loc, ErrorSink eSink) nothrow - { - if (initdone) - return; - - initdone = true; - time_t ct; - // https://issues.dlang.org/show_bug.cgi?id=20444 - if (auto p = getenv("SOURCE_DATE_EPOCH")) - { - if (!ct.parseDigits(p.toDString())) - eSink.error(loc, "value of environment variable `SOURCE_DATE_EPOCH` should be a valid UNIX timestamp, not: `%s`", p); - } - else - .time(&ct); - const p = ctime(&ct); - assert(p); - snprintf(&date[0], date.length, "%.6s %.4s", p + 4, p + 20); - snprintf(&time[0], time.length, "%.8s", p + 11); - snprintf(×tamp[0], timestamp.length, "%.24s", p); - } -} - private enum LS = 0x2028; // UTF line separator private enum PS = 0x2029; // UTF paragraph separator @@ -3366,7 +3359,7 @@ unittest */ string text = "int"; // We rely on the implicit null-terminator ErrorSink errorSink = new ErrorSinkStderr; - scope Lexer lex1 = new Lexer(null, text.ptr, 0, text.length, false, false, errorSink); + scope Lexer lex1 = new Lexer(null, text.ptr, 0, text.length, false, false, errorSink, null); TOK tok; tok = lex1.nextToken(); //printf("tok == %s, %d, %d\n", Token::toChars(tok), tok, TOK.int32); @@ -3402,7 +3395,7 @@ unittest foreach (testcase; testcases) { - scope Lexer lex2 = new Lexer(null, testcase.ptr, 0, testcase.length-1, false, false, errorSink); + scope Lexer lex2 = new Lexer(null, testcase.ptr, 0, testcase.length-1, false, false, errorSink, null); TOK tok = lex2.nextToken(); size_t iterations = 1; while ((tok != TOK.endOfFile) && (iterations++ < testcase.length)) diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 5939db5..badc579 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -313,6 +313,7 @@ int mutabilityOfType(bool isref, Type t) */ enum DotExpFlag { + none = 0, gag = 1, // don't report "not a property" error and just return null noDeref = 2, // the use of the expression will not attempt a dereference noAliasThis = 4, // don't do 'alias this' resolution @@ -2044,9 +2045,11 @@ extern (C++) abstract class Type : ASTNode t = t.addMod(this.mod); return t; } - if (auto fd = s.isFuncDeclaration()) + Dsymbol callable = s.isFuncDeclaration(); + callable = callable ? callable : s.isTemplateDeclaration(); + if (callable) { - fd = resolveFuncCall(Loc.initial, null, fd, null, this, ArgumentList(), FuncResolveFlag.quiet); + auto fd = resolveFuncCall(Loc.initial, null, callable, null, this, ArgumentList(), FuncResolveFlag.quiet); if (!fd || fd.errors || !fd.functionSemantic()) return Type.terror; @@ -2065,24 +2068,17 @@ extern (C++) abstract class Type : ASTNode { return ed.type; } - if (auto td = s.isTemplateDeclaration()) - { - assert(td._scope); - auto fd = resolveFuncCall(Loc.initial, null, td, null, this, ArgumentList(), FuncResolveFlag.quiet); - if (!fd || fd.errors || !fd.functionSemantic()) - return Type.terror; - - auto t = fd.type.nextOf(); - if (!t) - return Type.terror; - t = t.substWildTo(mod == 0 ? MODFlags.mutable : mod); - return t; - } //printf("%s\n", s.kind()); return null; } + /** + * Check whether this type has endless `alias this` recursion. + * Returns: + * `true` if this type has an `alias this` that can be implicitly + * converted back to this type itself. + */ extern (D) final bool checkAliasThisRec() { Type tb = toBasetype(); @@ -2645,6 +2641,8 @@ extern (C++) abstract class Type : ASTNode if (t.isimaginary() || t.iscomplex()) { + if (sc.flags & SCOPE.Cfile) + return true; // complex/imaginary not deprecated in C code Type rt; switch (t.ty) { @@ -4270,7 +4268,7 @@ extern (C++) final class TypeFunction : TypeNext super(Tfunction, treturn); //if (!treturn) *(char*)0=0; // assert(treturn); - assert(VarArg.none <= pl.varargs && pl.varargs <= VarArg.typesafe); + assert(VarArg.none <= pl.varargs && pl.varargs <= VarArg.max); this.parameterList = pl; this.linkage = linkage; @@ -6513,6 +6511,7 @@ extern (C++) final class TypeTag : Type { Loc loc; /// location of declaration TOK tok; /// TOK.struct_, TOK.union_, TOK.enum_ + structalign_t packalign; /// alignment of struct/union fields Identifier id; /// tag name identifier Type base; /// base type for enums otherwise null Dsymbols* members; /// members of struct, null if none @@ -6522,13 +6521,14 @@ extern (C++) final class TypeTag : Type /// struct S { int a; } s1, *s2; MOD mod; /// modifiers to apply after type is resolved (only MODFlags.const_ at the moment) - extern (D) this(const ref Loc loc, TOK tok, Identifier id, Type base, Dsymbols* members) + extern (D) this(const ref Loc loc, TOK tok, Identifier id, structalign_t packalign, Type base, Dsymbols* members) { //printf("TypeTag ctor %s %p\n", id ? id.toChars() : "null".ptr, this); super(Ttag); this.loc = loc; this.tok = tok; this.id = id; + this.packalign = packalign; this.base = base; this.members = members; this.mod = 0; @@ -7252,7 +7252,7 @@ private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct, s ~= "pure "; if (!f.isSafe() && !f.isTrusted() && sc.setUnsafe()) s ~= "@safe "; - if (!f.isNogc && sc.func.setGC()) + if (!f.isNogc && sc.func.setGC(arg.loc, null)) s ~= "nogc "; if (s) { @@ -7579,3 +7579,113 @@ TypeVector toBooleanVector(TypeVector tv) return new TypeVector(new TypeSArray(telem, tsa.dim)); } + +/************************************************* + * Dispatch to function based on static type of Type. + */ +mixin template VisitType(Result) +{ + Result VisitType(Type t) + { + final switch (t.ty) + { + case TY.Tvoid: + case TY.Tint8: + case TY.Tuns8: + case TY.Tint16: + case TY.Tuns16: + case TY.Tint32: + case TY.Tuns32: + case TY.Tint64: + case TY.Tuns64: + case TY.Tfloat32: + case TY.Tfloat64: + case TY.Tfloat80: + case TY.Timaginary32: + case TY.Timaginary64: + case TY.Timaginary80: + case TY.Tcomplex32: + case TY.Tcomplex64: + case TY.Tcomplex80: + case TY.Tbool: + case TY.Tchar: + case TY.Twchar: + case TY.Tdchar: + case TY.Tint128: + case TY.Tuns128: mixin(visitTYCase("Basic")); + case TY.Tarray: mixin(visitTYCase("DArray")); + case TY.Tsarray: mixin(visitTYCase("SArray")); + case TY.Taarray: mixin(visitTYCase("AArray")); + case TY.Tpointer: mixin(visitTYCase("Pointer")); + case TY.Treference: mixin(visitTYCase("Reference")); + case TY.Tfunction: mixin(visitTYCase("Function")); + case TY.Tident: mixin(visitTYCase("Identifier")); + case TY.Tclass: mixin(visitTYCase("Class")); + case TY.Tstruct: mixin(visitTYCase("Struct")); + case TY.Tenum: mixin(visitTYCase("Enum")); + case TY.Tdelegate: mixin(visitTYCase("Delegate")); + case TY.Terror: mixin(visitTYCase("Error")); + case TY.Tinstance: mixin(visitTYCase("Instance")); + case TY.Ttypeof: mixin(visitTYCase("Typeof")); + case TY.Ttuple: mixin(visitTYCase("Tuple")); + case TY.Tslice: mixin(visitTYCase("Slice")); + case TY.Treturn: mixin(visitTYCase("Return")); + case TY.Tnull: mixin(visitTYCase("Null")); + case TY.Tvector: mixin(visitTYCase("Vector")); + case TY.Ttraits: mixin(visitTYCase("Traits")); + case TY.Tmixin: mixin(visitTYCase("Mixin")); + case TY.Tnoreturn: mixin(visitTYCase("Noreturn")); + case TY.Ttag: mixin(visitTYCase("Tag")); + case TY.Tnone: assert(0); + } + } +} + +/**************************************** + * CTFE-only helper function for VisitInitializer. + * Params: + * handler = string for the name of the visit handler + * Returns: boilerplate code for a case + */ +pure string visitTYCase(string handler) +{ + if (__ctfe) + { + return + " + enum isVoid = is(Result == void); + auto tx = t.isType"~handler~"(); + static if (__traits(compiles, visit"~handler~"(tx))) + { + static if (isVoid) + { + visit"~handler~"(tx); + return; + } + else + { + if (Result r = visit"~handler~"(tx)) + return r; + return Result.init; + } + } + else static if (__traits(compiles, visitDefaultCase(t))) + { + static if (isVoid) + { + visitDefaultCase(tx); + return; + } + else + { + if (Result r = visitDefaultCase(t)) + return r; + return Result.init; + } + } + else + static assert(0, "~handler~"); + "; + } + assert(0); +} diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index 201f168..a0f3e60 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -83,7 +83,7 @@ public: err = true; return true; } - if (f.setGC()) + if (f.setGC(e.loc, format)) { e.error(format, f.kind(), f.toPrettyChars()); err = true; @@ -135,7 +135,7 @@ public: override void visit(NewExp e) { - if (e.member && !e.member.isNogc() && f.setGC()) + if (e.member && !e.member.isNogc() && f.setGC(e.loc, null)) { // @nogc-ness is already checked in NewExp::semantic return; @@ -195,7 +195,7 @@ public: err = true; return; } - if (f.setGC()) + if (f.setGC(e.loc, null)) { err = true; return; diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d index 9cff76b..89728b6 100644 --- a/gcc/d/dmd/ob.d +++ b/gcc/d/dmd/ob.d @@ -844,7 +844,7 @@ void toObNodes(ref ObNodes obnodes, Statement s) case STMT.Conditional: case STMT.While: case STMT.Forwarding: - case STMT.Compile: + case STMT.Mixin: case STMT.Peel: case STMT.Synchronized: debug printf("s: %s\n", s.toChars()); diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d index 3c80e5e..d7b90d7 100644 --- a/gcc/d/dmd/opover.d +++ b/gcc/d/dmd/opover.d @@ -293,6 +293,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) { ie = (*ae.arguments)[0].isIntervalExp(); } + Type att = null; // first cyclic `alias this` type while (true) { if (ae.e1.op == EXP.error) @@ -354,7 +355,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) return result; } // Didn't find it. Forward to aliasthis - if (ad.aliasthis && !isRecursiveAliasThis(ae.att1, ae.e1.type)) + if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type)) { /* Rewrite op(a[arguments]) as: * op(a.aliasthis[arguments]) @@ -370,13 +371,18 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) } e.e1 = e.e1.expressionSemantic(sc); e.e1 = resolveProperties(sc, e.e1); - if (e.e1.op == EXP.error) - { - return e.e1; - } - AggregateDeclaration ad = isAggregate(e.e1.type); - if (ad) + Type att = null; // first cyclic `alias this` type + while (1) { + if (e.e1.op == EXP.error) + { + return e.e1; + } + + AggregateDeclaration ad = isAggregate(e.e1.type); + if (!ad) + break; + Dsymbol fd = null; /* Rewrite as: * e1.opUnary!(op)() @@ -404,18 +410,18 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) } } // Didn't find it. Forward to aliasthis - if (ad.aliasthis && !isRecursiveAliasThis(e.att1, e.e1.type)) + if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type)) { /* Rewrite op(e1) as: * op(e1.aliasthis) */ //printf("att una %s e1 = %s\n", EXPtoString(op).ptr, this.e1.type.toChars()); - Expression e1 = new DotIdExp(e.loc, e.e1, ad.aliasthis.ident); - UnaExp ue = cast(UnaExp)e.copy(); - ue.e1 = e1; - result = ue.trySemantic(sc); - return result; + e.e1 = resolveAliasThis(sc, e.e1, true); + if (e.e1) + continue; + break; } + break; } return result; } @@ -433,6 +439,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) ie = (*ae.arguments)[0].isIntervalExp(); } Expression result; + Type att = null; // first cyclic `alias this` type while (true) { if (ae.e1.op == EXP.error) @@ -526,7 +533,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) return result; } // Didn't find it. Forward to aliasthis - if (ad.aliasthis && !isRecursiveAliasThis(ae.att1, ae.e1.type)) + if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type)) { //printf("att arr e1 = %s\n", this.e1.type.toChars()); /* Rewrite op(a[arguments]) as: @@ -547,7 +554,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) * This is mostly the same as UnaryExp::op_overload(), but has * a different rewrite. */ - Expression visitCast(CastExp e) + Expression visitCast(CastExp e, Type att = null) { //printf("CastExp::op_overload() (%s)\n", e.toChars()); Expression result; @@ -578,7 +585,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) return result; } // Didn't find it. Forward to aliasthis - if (ad.aliasthis && !isRecursiveAliasThis(e.att1, e.e1.type)) + if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type)) { /* Rewrite op(e1) as: * op(e1.aliasthis) @@ -587,7 +594,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) { result = e.copy(); (cast(UnaExp)result).e1 = e1; - result = result.op_overload(sc); + result = visitCast(result.isCastExp(), att); return result; } } @@ -997,7 +1004,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) return null; import dmd.clone : needOpEquals; - if (!global.params.fieldwise && !needOpEquals(sd)) + if (global.params.fieldwise != FeatureState.enabled && !needOpEquals(sd)) { // Use bitwise equality. auto op2 = e.op == EXP.equal ? EXP.identity : EXP.notIdentity; @@ -1016,12 +1023,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) * also compare the parent class's equality. Otherwise, compares * the identity of parent context through void*. */ - if (e.att1 && t1.equivalent(e.att1)) return null; - if (e.att2 && t2.equivalent(e.att2)) return null; - e = e.copy().isEqualExp(); - if (!e.att1) e.att1 = t1; - if (!e.att2) e.att2 = t2; e.e1 = new DotIdExp(e.loc, e.e1, Id._tupleof); e.e2 = new DotIdExp(e.loc, e.e2, Id._tupleof); @@ -1029,18 +1031,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) sc2.flags |= SCOPE.noaccesscheck; Expression r = e.expressionSemantic(sc2); sc2.pop(); - - /* https://issues.dlang.org/show_bug.cgi?id=15292 - * if the rewrite result is same with the original, - * the equality is unresolvable because it has recursive definition. - */ - if (r.op == e.op && - r.isEqualExp().e1.type.toBasetype() == t1) - { - e.error("cannot compare `%s` because its auto generated member-wise equality has recursive definition", - t1.toChars()); - return ErrorExp.get(); - } return r; } @@ -1071,8 +1061,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) auto ex1 = (*tup1.exps)[i]; auto ex2 = (*tup2.exps)[i]; auto eeq = new EqualExp(e.op, e.loc, ex1, ex2); - eeq.att1 = e.att1; - eeq.att2 = e.att2; if (!result) result = eeq; @@ -1114,6 +1102,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) { ie = (*ae.arguments)[0].isIntervalExp(); } + Type att = null; // first cyclic `alias this` type while (true) { if (ae.e1.op == EXP.error) @@ -1185,7 +1174,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) return result; } // Didn't find it. Forward to aliasthis - if (ad.aliasthis && !isRecursiveAliasThis(ae.att1, ae.e1.type)) + if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type)) { /* Rewrite (a[arguments] op= e2) as: * a.aliasthis[arguments] op= e2 diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index b5d32b2..61c385f 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -371,7 +371,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) { if (e.stageflags & stageOptimize) return; - int old = e.stageflags; + const old = e.stageflags; e.stageflags |= stageOptimize; if (e.elements) { diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index 36a76f5..68a2506 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -15,14 +15,13 @@ module dmd.parse; import core.stdc.stdio; import core.stdc.string; + import dmd.astenums; import dmd.errorsink; -import dmd.globals; import dmd.id; import dmd.identifier; import dmd.lexer; import dmd.location; -import dmd.errors; import dmd.root.filename; import dmd.common.outbuffer; import dmd.root.rmem; @@ -30,6 +29,8 @@ import dmd.root.rootobject; import dmd.root.string; import dmd.tokens; +alias CompileEnv = dmd.lexer.CompileEnv; + /*********************************************************** */ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer @@ -45,49 +46,38 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer Loc endloc; // set to location of last right curly int inBrackets; // inside [] of array index or slice Loc lookingForElse; // location of lonely if looking for an else + bool doUnittests; // parse unittest blocks } + bool transitionIn = false; /// `-transition=in` is active, `in` parameters are listed + /********************* * Use this constructor for string mixins. * Input: - * loc location in source file of mixin + * loc = location in source file of mixin */ extern (D) this(const ref Loc loc, AST.Module _module, const(char)[] input, bool doDocComment, - ErrorSink errorSink) scope + ErrorSink errorSink, const CompileEnv* compileEnv, const bool doUnittests) scope { - super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false, - errorSink, - global.vendor, global.versionNumber()); - - //printf("Parser::Parser()\n"); + //printf("Parser::Parser()1 %d\n", doUnittests); + this(_module, input, doDocComment, errorSink, compileEnv, doUnittests); scanloc = loc; - - if (!writeMixin(input, scanloc) && loc.filename) - { - /* Create a pseudo-filename for the mixin string, as it may not even exist - * in the source file. - */ - auto len = strlen(loc.filename) + 7 + (loc.linnum).sizeof * 3 + 1; - char* filename = cast(char*)mem.xmalloc(len); - snprintf(filename, len, "%s-mixin-%d", loc.filename, cast(int)loc.linnum); - scanloc.filename = filename; - } - - mod = _module; - linkage = LINK.d; - //nextToken(); // start up the scanner } - extern (D) this(AST.Module _module, const(char)[] input, bool doDocComment, ErrorSink errorSink) scope + /************************************************** + * Main Parser constructor. + */ + extern (D) this(AST.Module _module, const(char)[] input, bool doDocComment, ErrorSink errorSink, + const CompileEnv* compileEnv, const bool doUnittests) scope { super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false, errorSink, - global.vendor, global.versionNumber()); + compileEnv); - //printf("Parser::Parser()\n"); - mod = _module; - linkage = LINK.d; - //nextToken(); // start up the scanner + //printf("Parser::Parser()2 %d\n", doUnittests); + this.mod = _module; + this.linkage = LINK.d; + this.doUnittests = doUnittests; } /++ @@ -335,6 +325,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer linkage = linksave; Loc startloc; + Loc scdLoc; switch (token.value) { @@ -381,7 +372,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer nextToken(); auto exps = parseArguments(); check(TOK.semicolon); - s = new AST.CompileDeclaration(loc, exps); + s = new AST.MixinDeclaration(loc, exps); break; } case TOK.template_: @@ -497,7 +488,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * template instantiations in these unittests as candidates for * further codegen culling. */ - if (mod.isRoot() && (global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput)) + // The isRoot check is here because it can change after parsing begins (see dmodule.d) + if (doUnittests && mod.isRoot()) { linkage = LINK.d; // unittests have D linkage s = parseUnitTest(pAttrs); @@ -696,6 +688,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } Lstc: pAttrs.storageClass = appendStorageClass(pAttrs.storageClass, stc); + scdLoc = token.loc; nextToken(); Lautodecl: @@ -748,7 +741,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer auto stc2 = getStorageClass!AST(pAttrs); if (stc2 != STC.undefined_) { - s = new AST.StorageClassDeclaration(stc2, a); + s = new AST.StorageClassDeclaration(scdLoc, stc2, a); } if (pAttrs.udas) { @@ -1219,19 +1212,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer return orig | added; } - const Redundant = (STC.const_ | STC.scope_ | - (global.params.previewIn ? STC.ref_ : 0)); + const Redundant = (STC.const_ | STC.scope_ | STC.ref_); orig |= added; if ((orig & STC.in_) && (added & Redundant)) { if (added & STC.const_) error("attribute `const` is redundant with previously-applied `in`"); - else if (global.params.previewIn) + else if (compileEnv.previewIn) { error("attribute `%s` is redundant with previously-applied `in`", (orig & STC.scope_) ? "scope".ptr : "ref".ptr); } + else if (added & STC.ref_) + deprecation("using `in ref` is deprecated, use `-preview=in` and `in` instead"); else error("attribute `scope` cannot be applied with `in`, use `-preview=in` instead"); return orig; @@ -1241,13 +1235,15 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { if (orig & STC.const_) error("attribute `in` cannot be added after `const`: remove `const`"); - else if (global.params.previewIn) + else if (compileEnv.previewIn) { // Windows `printf` does not support `%1$s` const(char*) stc_str = (orig & STC.scope_) ? "scope".ptr : "ref".ptr; error(token.loc, "attribute `in` cannot be added after `%s`: remove `%s`", stc_str, stc_str); } + else if (orig & STC.ref_) + deprecation("using `ref in` is deprecated, use `-preview=in` and `in` instead"); else error("attribute `in` cannot be added after `scope`: remove `scope` and use `-preview=in`"); return orig; @@ -1302,12 +1298,38 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer return 0; } + AST.Expression templateArgToExp(RootObject o, const ref Loc loc) + { + switch (o.dyncast) + { + case DYNCAST.expression: + return cast(AST.Expression) o; + case DYNCAST.type: + return new AST.TypeExp(loc, cast(AST.Type)o); + default: + assert(0); + } + } + if (token.value == TOK.leftParenthesis) { // Multi-UDAs ( `@( ArgumentList )`) form, concatenate with existing if (peekNext() == TOK.rightParenthesis) error("empty attribute list is not allowed"); - udas = AST.UserAttributeDeclaration.concat(udas, parseArguments()); + + if (udas is null) + udas = new AST.Expressions(); + auto args = parseTemplateArgumentList(); + foreach (arg; *args) + udas.push(templateArgToExp(arg, token.loc)); + return 0; + } + + if (auto o = parseTemplateSingleArgument()) + { + if (udas is null) + udas = new AST.Expressions(); + udas.push(templateArgToExp(o, token.loc)); return 0; } @@ -1764,7 +1786,16 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer else { // ident!template_argument - tiargs = parseTemplateSingleArgument(); + RootObject o = parseTemplateSingleArgument(); + if (!o) + { + error("template argument expected following `!`"); + } + else + { + tiargs = new AST.Objects(); + tiargs.push(o); + } } if (token.value == TOK.not) { @@ -1830,11 +1861,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * foo!arg * Input: * current token is the arg + * Returns: An AST.Type, AST.Expression, or `null` on error */ - private AST.Objects* parseTemplateSingleArgument() + private RootObject parseTemplateSingleArgument() { //printf("parseTemplateSingleArgument()\n"); - auto tiargs = new AST.Objects(); AST.Type ta; switch (token.value) { @@ -1942,9 +1973,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer ta = AST.Type.tdchar; goto LabelX; LabelX: - tiargs.push(ta); nextToken(); - break; + return ta; case TOK.int32Literal: case TOK.uns32Literal: @@ -1974,15 +2004,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.this_: { // Template argument is an expression - AST.Expression ea = parsePrimaryExp(); - tiargs.push(ea); - break; + return parsePrimaryExp(); } default: - error("template argument expected following `!`"); - break; + return null; } - return tiargs; } /********************************** @@ -2694,7 +2720,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer /** Extract unittest body as a string. Must be done eagerly since memory will be released by the lexer before doc gen. */ char* docline = null; - if (global.params.ddoc.doOutput && endPtr > begPtr) + if (compileEnv.ddocOutput && endPtr > begPtr) { /* Remove trailing whitespaces */ for (const(char)* p = endPtr - 1; begPtr <= p && (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t'); --p) @@ -2849,8 +2875,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer // Don't call nextToken again. } case TOK.in_: - if (global.params.vin) - message(scanloc, "Usage of 'in' on parameter"); + if (transitionIn) + eSink.message(scanloc, "Usage of 'in' on parameter"); stc = STC.in_; goto L2; @@ -4610,8 +4636,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer AST.Dsymbol s; if (width) { - if (!global.params.bitfields) - error("use -preview=bitfields for bitfield support"); if (_init) error("initializer not allowed for bit-field declaration"); if (storage_class) @@ -5144,7 +5168,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.goesTo: if (requireDo) error("missing `do { ... }` after `in` or `out`"); - if (!global.params.shortenedMethods) + if (!compileEnv.shortenedMethods) error("=> shortened method not enabled, compile with compiler switch `-preview=shortenedMethods`"); const returnloc = token.loc; nextToken(); @@ -5156,7 +5180,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.leftCurly: if (requireDo) error("missing `do { ... }` after `in` or `out`"); - f.fbody = parseStatement(ParseStatementFlags.semi); + f.fbody = parseStatement(0); f.endloc = endloc; break; @@ -5801,7 +5825,11 @@ LagainStc: if (token.value != TOK.semicolon && peek(&token).value == TOK.semicolon) error("found `%s` when expecting `;` following statement", token.toChars()); else - check(TOK.semicolon, "statement"); + { + if (token.value != TOK.semicolon) + error("found `%s` when expecting `;` following statement `%s` on line %s", token.toChars(), exp.toChars(), exp.loc.toChars()); + nextToken(); + } } s = new AST.ExpStatement(loc, exp); break; @@ -5959,7 +5987,7 @@ LagainStc: if (e.op == EXP.mixin_) { AST.MixinExp cpe = cast(AST.MixinExp)e; - s = new AST.CompileStatement(loc, cpe.exps); + s = new AST.MixinStatement(loc, cpe.exps); } else { @@ -5992,7 +6020,7 @@ LagainStc: auto statements = new AST.Statements(); while (token.value != TOK.rightCurly && token.value != TOK.endOfFile) { - statements.push(parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope)); + statements.push(parseStatement(ParseStatementFlags.curlyScope)); } if (endPtr) *endPtr = token.ptr; @@ -6025,10 +6053,7 @@ LagainStc: case TOK.semicolon: if (!(flags & ParseStatementFlags.semiOk)) { - if (flags & ParseStatementFlags.semi) - deprecation("use `{ }` for an empty statement, not `;`"); - else - error("use `{ }` for an empty statement, not `;`"); + error("use `{ }` for an empty statement, not `;`"); } nextToken(); s = new AST.ExpStatement(loc, cast(AST.Expression)null); @@ -6245,7 +6270,7 @@ LagainStc: _body = null; } else - _body = parseStatement(ParseStatementFlags.semi); + _body = parseStatement(0); s = new AST.PragmaStatement(loc, ident, args, _body); break; } @@ -6298,7 +6323,7 @@ LagainStc: auto statements = new AST.Statements(); while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly) { - auto cur = parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope); + auto cur = parseStatement(ParseStatementFlags.curlyScope); statements.push(cur); // https://issues.dlang.org/show_bug.cgi?id=21739 @@ -6313,7 +6338,7 @@ LagainStc: } else { - s = parseStatement(ParseStatementFlags.semi); + s = parseStatement(0); } s = new AST.ScopeStatement(loc, s, token.loc); @@ -6342,12 +6367,12 @@ LagainStc: auto statements = new AST.Statements(); while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly) { - statements.push(parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope)); + statements.push(parseStatement(ParseStatementFlags.curlyScope)); } s = new AST.CompoundStatement(loc, statements); } else - s = parseStatement(ParseStatementFlags.semi); + s = parseStatement(0); s = new AST.ScopeStatement(loc, s, token.loc); s = new AST.DefaultStatement(loc, s); break; @@ -6891,6 +6916,15 @@ LagainStc: /******************** * Parse inline assembler block. + * Enters with token on the `asm`. + * https://dlang.org/spec/iasm.html + * + * AsmStatement: + * asm FunctionAttributes(opt) { AsmInstructionListopt } + * AsmInstructionList: + * AsmInstruction ; + * AsmInstruction ; AsmInstruction + * * Returns: * inline assembler block as a Statement */ @@ -6905,7 +6939,7 @@ LagainStc: Loc labelloc; nextToken(); - StorageClass stc = parsePostfix(STC.undefined_, null); + StorageClass stc = parsePostfix(STC.undefined_, null); // optional FunctionAttributes if (stc & (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild)) error("`const`/`immutable`/`shared`/`inout` attributes are not allowed on `asm` blocks"); @@ -9181,7 +9215,7 @@ LagainStc: void checkRequiredParens() { if (e.op == EXP.question && !e.parens) - dmd.errors.error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", + eSink.error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(token.value)); } @@ -9498,7 +9532,6 @@ immutable PREC[EXP.max + 1] precedence = EXP.error : PREC.expr, EXP.objcClassReference : PREC.expr, // Objective-C class reference, same as EXP.type - EXP.typeof_ : PREC.primary, EXP.mixin_ : PREC.primary, EXP.import_ : PREC.primary, @@ -9538,7 +9571,6 @@ immutable PREC[EXP.max + 1] precedence = EXP.remove : PREC.primary, EXP.tuple : PREC.primary, EXP.traits : PREC.primary, - EXP.default_ : PREC.primary, EXP.overloadSet : PREC.primary, EXP.void_ : PREC.primary, EXP.vectorArray : PREC.primary, @@ -9637,7 +9669,6 @@ immutable PREC[EXP.max + 1] precedence = enum ParseStatementFlags : int { - semi = 1, // empty ';' statements are allowed, but deprecated scope_ = 2, // start a new scope curly = 4, // { } statement is required curlyScope = 8, // { } starts a new scope @@ -9708,52 +9739,3 @@ private StorageClass getStorageClass(AST)(PrefixAttributes!(AST)* pAttrs) } return stc; } - -/************************************** - * dump mixin expansion to file for better debugging - */ -private bool writeMixin(const(char)[] s, ref Loc loc) -{ - if (!global.params.mixinOut.doOutput) - return false; - - OutBuffer* ob = global.params.mixinOut.buffer; - - ob.writestring("// expansion at "); - ob.writestring(loc.toChars()); - ob.writenl(); - - global.params.mixinOut.bufferLines++; - - loc = Loc(global.params.mixinOut.name.ptr, global.params.mixinOut.bufferLines + 1, loc.charnum); - - // write by line to create consistent line endings - size_t lastpos = 0; - for (size_t i = 0; i < s.length; ++i) - { - // detect LF and CRLF - const c = s[i]; - if (c == '\n' || (c == '\r' && i+1 < s.length && s[i+1] == '\n')) - { - ob.writestring(s[lastpos .. i]); - ob.writenl(); - global.params.mixinOut.bufferLines++; - if (c == '\r') - ++i; - lastpos = i + 1; - } - } - - if(lastpos < s.length) - ob.writestring(s[lastpos .. $]); - - if (s.length == 0 || s[$-1] != '\n') - { - ob.writenl(); // ensure empty line after expansion - global.params.mixinOut.bufferLines++; - } - ob.writenl(); - global.params.mixinOut.bufferLines++; - - return true; -} diff --git a/gcc/d/dmd/parsetimevisitor.d b/gcc/d/dmd/parsetimevisitor.d index 387b28c..a4a9434 100644 --- a/gcc/d/dmd/parsetimevisitor.d +++ b/gcc/d/dmd/parsetimevisitor.d @@ -66,7 +66,7 @@ public: void visit(AST.SharedStaticDtorDeclaration s) { visit(cast(AST.StaticDtorDeclaration)s); } // AttribDeclarations - void visit(AST.CompileDeclaration s) { visit(cast(AST.AttribDeclaration)s); } + void visit(AST.MixinDeclaration s) { visit(cast(AST.AttribDeclaration)s); } void visit(AST.UserAttributeDeclaration s) { visit(cast(AST.AttribDeclaration)s); } void visit(AST.LinkDeclaration s) { visit(cast(AST.AttribDeclaration)s); } void visit(AST.AnonDeclaration s) { visit(cast(AST.AttribDeclaration)s); } @@ -99,7 +99,7 @@ public: void visit(AST.ReturnStatement s) { visit(cast(AST.Statement)s); } void visit(AST.LabelStatement s) { visit(cast(AST.Statement)s); } void visit(AST.StaticAssertStatement s) { visit(cast(AST.Statement)s); } - void visit(AST.CompileStatement s) { visit(cast(AST.Statement)s); } + void visit(AST.MixinStatement s) { visit(cast(AST.Statement)s); } void visit(AST.WhileStatement s) { visit(cast(AST.Statement)s); } void visit(AST.ForStatement s) { visit(cast(AST.Statement)s); } void visit(AST.DoStatement s) { visit(cast(AST.Statement)s); } diff --git a/gcc/d/dmd/printast.d b/gcc/d/dmd/printast.d index d85105d..8c01095 100644 --- a/gcc/d/dmd/printast.d +++ b/gcc/d/dmd/printast.d @@ -219,6 +219,25 @@ extern (C++) final class PrintASTVisitor : Visitor printAST(e.value, indent + 2); } + override void visit(ArrayLiteralExp e) + { + visit(cast(Expression)e); + printIndent(indent + 2); + printf(".basis : %s\n", e.basis ? e.basis.toChars() : ""); + if (e.elements) + { + printIndent(indent + 2); + printf("["); + foreach (i, element; (*e.elements)[]) + { + if (i) + printf(", "); + printf("%s", element.toChars()); + } + printf("]\n"); + } + } + static void printIndent(int indent) { foreach (i; 0 .. indent) diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index a912e76..33c2f02 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -467,7 +467,7 @@ private extern(C++) final class Semantic3Visitor : Visitor /* Generate identifier for un-named parameter, * because we need it later on. */ - fparam.ident = id = Identifier.generateId("_param_", i); + fparam.ident = id = Identifier.generateId("__param_", i); stc |= STC.temp; } Type vtype = fparam.type; diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d index 60a74cc..3f3e7e6 100644 --- a/gcc/d/dmd/sideeffect.d +++ b/gcc/d/dmd/sideeffect.d @@ -185,6 +185,7 @@ private bool lambdaHasSideEffect(Expression e, bool assumeImpureCalls = false) case EXP.delete_: case EXP.new_: case EXP.newAnonymousClass: + case EXP.loweredAssignExp: return true; case EXP.call: { diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d index 90728fb..3ccf228 100644 --- a/gcc/d/dmd/statement.d +++ b/gcc/d/dmd/statement.d @@ -373,6 +373,7 @@ extern (C++) abstract class Statement : ASTNode * the downcast statement if it can be downcasted, otherwise `null` */ inout(ErrorStatement) isErrorStatement() { return stmt == STMT.Error ? cast(typeof(return))this : null; } + inout(PeelStatement) isPeelStatement() { return stmt == STMT.Peel ? cast(typeof(return))this : null; } inout(ScopeStatement) isScopeStatement() { return stmt == STMT.Scope ? cast(typeof(return))this : null; } inout(ExpStatement) isExpStatement() { return stmt == STMT.Exp ? cast(typeof(return))this : null; } inout(CompoundStatement) isCompoundStatement() { return stmt == STMT.Compound ? cast(typeof(return))this : null; } @@ -388,7 +389,7 @@ extern (C++) abstract class Statement : ASTNode inout(GotoCaseStatement) isGotoCaseStatement() { return stmt == STMT.GotoCase ? cast(typeof(return))this : null; } inout(BreakStatement) isBreakStatement() { return stmt == STMT.Break ? cast(typeof(return))this : null; } inout(DtorExpStatement) isDtorExpStatement() { return stmt == STMT.DtorExp ? cast(typeof(return))this : null; } - inout(CompileStatement) isCompileStatement() { return stmt == STMT.Compile ? cast(typeof(return))this : null; } + inout(MixinStatement) isMixinStatement() { return stmt == STMT.Mixin ? cast(typeof(return))this : null; } inout(ForwardingStatement) isForwardingStatement() { return stmt == STMT.Forwarding ? cast(typeof(return))this : null; } inout(DoStatement) isDoStatement() { return stmt == STMT.Do ? cast(typeof(return))this : null; } inout(WhileStatement) isWhileStatement() { return stmt == STMT.While ? cast(typeof(return))this : null; } @@ -406,6 +407,15 @@ extern (C++) abstract class Statement : ASTNode inout(UnrolledLoopStatement) isUnrolledLoopStatement() { return stmt == STMT.UnrolledLoop ? cast(typeof(return))this : null; } inout(ForeachRangeStatement) isForeachRangeStatement() { return stmt == STMT.ForeachRange ? cast(typeof(return))this : null; } inout(CompoundDeclarationStatement) isCompoundDeclarationStatement() { return stmt == STMT.CompoundDeclaration ? cast(typeof(return))this : null; } + inout(CompoundAsmStatement) isCompoundAsmStatement() { return stmt == STMT.CompoundAsm ? cast(typeof(return))this : null; } + inout(PragmaStatement) isPragmaStatement() { return stmt == STMT.Pragma ? cast(typeof(return))this : null; } + inout(StaticAssertStatement) isStaticAssertStatement() { return stmt == STMT.StaticAssert ? cast(typeof(return))this : null; } + inout(CaseRangeStatement) isCaseRangeStatement() { return stmt == STMT.CaseRange ? cast(typeof(return))this : null; } + inout(SynchronizedStatement) isSynchronizedStatement() { return stmt == STMT.Synchronized ? cast(typeof(return))this : null; } + inout(AsmStatement) isAsmStatement() { return stmt == STMT.Asm ? cast(typeof(return))this : null; } + inout(InlineAsmStatement) isInlineAsmStatement() { return stmt == STMT.InlineAsm ? cast(typeof(return))this : null; } + inout(GccAsmStatement) isGccAsmStatement() { return stmt == STMT.GccAsm ? cast(typeof(return))this : null; } + inout(ImportStatement) isImportStatement() { return stmt == STMT.Import ? cast(typeof(return))this : null; } } /*********************************************************** @@ -518,7 +528,8 @@ extern (C++) final class DtorExpStatement : ExpStatement /*********************************************************** * https://dlang.org/spec/statement.html#mixin-statement */ -extern (C++) final class CompileStatement : Statement +// Note: was called CompileStatement +extern (C++) final class MixinStatement : Statement { Expressions* exps; @@ -531,13 +542,13 @@ extern (C++) final class CompileStatement : Statement extern (D) this(const ref Loc loc, Expressions* exps) { - super(loc, STMT.Compile); + super(loc, STMT.Mixin); this.exps = exps; } - override CompileStatement syntaxCopy() + override MixinStatement syntaxCopy() { - return new CompileStatement(loc, Expression.arraySyntaxCopy(exps)); + return new MixinStatement(loc, Expression.arraySyntaxCopy(exps)); } override void accept(Visitor v) @@ -2084,3 +2095,107 @@ extern (C++) final class ImportStatement : Statement v.visit(this); } } + + +mixin template VisitStatement(Result) +{ + Result VisitStatement(Statement s) + { + final switch (s.stmt) + { + case STMT.Error: mixin(visitStmtCase("Error")); + case STMT.Scope: mixin(visitStmtCase("Scope")); + case STMT.Exp: mixin(visitStmtCase("Exp")); + case STMT.Compound: mixin(visitStmtCase("Compound")); + case STMT.Return: mixin(visitStmtCase("Return")); + case STMT.If: mixin(visitStmtCase("If")); + case STMT.Conditional: mixin(visitStmtCase("Conditional")); + case STMT.StaticForeach: mixin(visitStmtCase("StaticForeach")); + case STMT.Case: mixin(visitStmtCase("Case")); + case STMT.Default: mixin(visitStmtCase("Default")); + case STMT.Label: mixin(visitStmtCase("Label")); + case STMT.Goto: mixin(visitStmtCase("Goto")); + case STMT.GotoDefault: mixin(visitStmtCase("GotoDefault")); + case STMT.GotoCase: mixin(visitStmtCase("GotoCase")); + case STMT.Break: mixin(visitStmtCase("Break")); + case STMT.DtorExp: mixin(visitStmtCase("DtorExp")); + case STMT.Mixin: mixin(visitStmtCase("Mixin")); + case STMT.Forwarding: mixin(visitStmtCase("Forwarding")); + case STMT.Do: mixin(visitStmtCase("Do")); + case STMT.While: mixin(visitStmtCase("While")); + case STMT.For: mixin(visitStmtCase("For")); + case STMT.Foreach: mixin(visitStmtCase("Foreach")); + case STMT.Switch: mixin(visitStmtCase("Switch")); + case STMT.Continue: mixin(visitStmtCase("Continue")); + case STMT.With: mixin(visitStmtCase("With")); + case STMT.TryCatch: mixin(visitStmtCase("TryCatch")); + case STMT.Throw: mixin(visitStmtCase("Throw")); + case STMT.Debug: mixin(visitStmtCase("Debug")); + case STMT.TryFinally: mixin(visitStmtCase("TryFinally")); + case STMT.ScopeGuard: mixin(visitStmtCase("ScopeGuard")); + case STMT.SwitchError: mixin(visitStmtCase("SwitchError")); + case STMT.UnrolledLoop: mixin(visitStmtCase("UnrolledLoop")); + case STMT.ForeachRange: mixin(visitStmtCase("ForeachRange")); + case STMT.CompoundDeclaration: mixin(visitStmtCase("CompoundDeclaration")); + case STMT.Peel: mixin(visitStmtCase("Peel")); + case STMT.CompoundAsm: mixin(visitStmtCase("CompoundAsm")); + case STMT.Pragma: mixin(visitStmtCase("Pragma")); + case STMT.StaticAssert: mixin(visitStmtCase("StaticAssert")); + case STMT.CaseRange: mixin(visitStmtCase("CaseRange")); + case STMT.Synchronized: mixin(visitStmtCase("Synchronized")); + case STMT.Asm: mixin(visitStmtCase("Asm")); + case STMT.InlineAsm: mixin(visitStmtCase("InlineAsm")); + case STMT.GccAsm: mixin(visitStmtCase("GccAsm")); + case STMT.Import: mixin(visitStmtCase("Import")); + } + } +} + +/**************************************** + * CTFE-only helper function for VisitInitializer. + * Params: + * handler = string for the name of the visit handler + * Returns: boilerplate code for a case + */ +pure string visitStmtCase(string handler) +{ + if (__ctfe) + { + return + " + enum isVoid = is(Result == void); + auto sx = s.is"~handler~"Statement(); + static if (__traits(compiles, visit"~handler~"(sx))) + { + static if (isVoid) + { + visit"~handler~"(sx); + return; + } + else + { + if (Result r = visit"~handler~"(sx)) + return r; + return Result.init; + } + } + else static if (__traits(compiles, visitDefaultCase(s))) + { + static if (isVoid) + { + visitDefaultCase(sx); + return; + } + else + { + if (Result r = visitDefaultCase(s)) + return r; + return Result.init; + } + } + else + static assert(0, "~handler~"); + "; + } + assert(0); +} diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h index 6d1f85b3..b7403b5 100644 --- a/gcc/d/dmd/statement.h +++ b/gcc/d/dmd/statement.h @@ -65,7 +65,7 @@ enum STMTerror, STMTpeel, STMTexp, STMTdtorExp, - STMTcompile, + STMTmixin, STMTcompound, STMTcompoundDeclaration, STMTcompoundAsm, STMTunrolledLoop, STMTscope, @@ -143,7 +143,7 @@ public: GotoCaseStatement *isGotoCaseStatement() { return stmt == STMTgotoCase ? (GotoCaseStatement*)this : NULL; } BreakStatement *isBreakStatement() { return stmt == STMTbreak ? (BreakStatement*)this : NULL; } DtorExpStatement *isDtorExpStatement() { return stmt == STMTdtorExp ? (DtorExpStatement*)this : NULL; } - CompileStatement *isCompileStatement() { return stmt == STMTcompile ? (CompileStatement*)this : NULL; } + MixinStatement *isMixinStatement() { return stmt == STMTmixin ? (MixinStatement*)this : NULL; } ForwardingStatement *isForwardingStatement() { return stmt == STMTforwarding ? (ForwardingStatement*)this : NULL; } DoStatement *isDoStatement() { return stmt == STMTdo ? (DoStatement*)this : NULL; } ForStatement *isForStatement() { return stmt == STMTfor ? (ForStatement*)this : NULL; } @@ -206,12 +206,12 @@ public: void accept(Visitor *v) override { v->visit(this); } }; -class CompileStatement final : public Statement +class MixinStatement final : public Statement { public: Expressions *exps; - CompileStatement *syntaxCopy() override; + MixinStatement *syntaxCopy() override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index 694db28..f849ce1 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -145,43 +145,35 @@ extern(C++) Statement statementSemantic(Statement s, Scope* sc) version (CallbackAPI) Compiler.onStatementSemanticStart(s, sc); - scope v = new StatementSemanticVisitor(sc); - s.accept(v); + Statement result = statementSemanticVisit(s, sc); version (CallbackAPI) Compiler.onStatementSemanticDone(s, sc); - return v.result; + return result; } -package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor +package (dmd) +Statement statementSemanticVisit(Statement s, Scope* sc) { - alias visit = Visitor.visit; - Statement result; - Scope* sc; - - this(Scope* sc) scope - { - this.sc = sc; - } - private void setError() + void setError() { result = new ErrorStatement(); } - override void visit(Statement s) + void visitDefaultCase(Statement s) { result = s; } - override void visit(ErrorStatement s) + void visitError(ErrorStatement s) { result = s; } - override void visit(PeelStatement s) + void visitPeel(PeelStatement s) { /* "peel" off this wrapper, and don't run semantic() * on the result. @@ -189,7 +181,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = s.s; } - override void visit(ExpStatement s) + void visitExp(ExpStatement s) { /* https://dlang.org/spec/statement.html#expression-statement */ @@ -226,12 +218,17 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = s; } - override void visit(CompileStatement cs) + void visitDtorExp(DtorExpStatement s) + { + visitExp(s); + } + + void visitMixin(MixinStatement cs) { /* https://dlang.org/spec/statement.html#mixin-statement */ - //printf("CompileStatement::semantic() %s\n", exp.toChars()); + //printf("MixinStatement::semantic() %s\n", exp.toChars()); Statements* a = cs.flatten(sc); if (!a) return; @@ -239,7 +236,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = s.statementSemantic(sc); } - override void visit(CompoundStatement cs) + void visitCompound(CompoundStatement cs) { //printf("CompoundStatement::semantic(this = %p, sc = %p)\n", cs, sc); version (none) @@ -431,7 +428,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = cs; } - override void visit(UnrolledLoopStatement uls) + void visitUnrolledLoop(UnrolledLoopStatement uls) { //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", uls, sc); Scope* scd = sc.push(); @@ -454,7 +451,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = serror ? serror : uls; } - override void visit(ScopeStatement ss) + void visitScope(ScopeStatement ss) { //printf("ScopeStatement::semantic(sc = %p)\n", sc); if (!ss.statement) @@ -501,7 +498,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ss; } - override void visit(ForwardingStatement ss) + void visitForwarding(ForwardingStatement ss) { assert(ss.sym); for (Scope* csc = sc; !ss.sym.parent; csc = csc.enclosing) @@ -517,7 +514,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ss.statement; } - override void visit(WhileStatement ws) + void visitWhile(WhileStatement ws) { /* Rewrite as a for(;condition;) loop * https://dlang.org/spec/statement.html#while-statement @@ -544,7 +541,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = s; } - override void visit(DoStatement ds) + void visitDo(DoStatement ds) { /* https://dlang.org/spec/statement.html#do-statement */ @@ -580,7 +577,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ds; } - override void visit(ForStatement fs) + void visitFor(ForStatement fs) { /* https://dlang.org/spec/statement.html#for-statement */ @@ -674,7 +671,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = fs; } - override void visit(ForeachStatement fs) + void visitForeach(ForeachStatement fs) { /* https://dlang.org/spec/statement.html#foreach-statement */ @@ -1349,7 +1346,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor auto exp = (*exps)[i]; version (none) { - printf("[%d] p = %s %s, exp = %s %s\n", i, + printf("[%lu] p = %s %s, exp = %s %s\n", i, p.type ? p.type.toChars() : "?", p.ident.toChars(), exp.type.toChars(), exp.toChars()); } @@ -1360,7 +1357,11 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor if (ignoreRef) sc &= ~STC.ref_; p.type = p.type.addStorageClass(sc).typeSemantic(loc, sc2); if (!exp.implicitConvTo(p.type)) - return rangeError(); + { + fs.error("cannot implicilty convert range element of type `%s` to variable `%s` of type `%s`", + exp.type.toChars(), p.toChars(), p.type.toChars()); + return retError(); + } auto var = new VarDeclaration(loc, p.type, p.ident, new ExpInitializer(loc, exp)); var.storage_class |= STC.ctfe | STC.ref_ | STC.foreach_; @@ -1395,312 +1396,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } } - private static extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde, - Type tab, Scope* sc2, Dsymbol sapply) - { - version (none) - { - if (global.params.useDIP1000 == FeatureState.enabled) - { - message(loc, "To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`"); - } - (cast(FuncExp)flde).fd.tookAddressOf = 1; - } - else - { - if (global.params.useDIP1000 == FeatureState.enabled) - ++(cast(FuncExp)flde).fd.tookAddressOf; // allocate a closure unless the opApply() uses 'scope' - } - assert(tab.ty == Tstruct || tab.ty == Tclass); - assert(sapply); - /* Call: - * aggr.apply(flde) - */ - Expression ec; - ec = new DotIdExp(fs.loc, fs.aggr, sapply.ident); - ec = new CallExp(fs.loc, ec, flde); - ec = ec.expressionSemantic(sc2); - if (ec.op == EXP.error) - return null; - if (ec.type != Type.tint32) - { - fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars()); - return null; - } - return ec; - } - - private static extern(D) Expression applyDelegate(ForeachStatement fs, Expression flde, - Type tab, Scope* sc2) - { - Expression ec; - /* Call: - * aggr(flde) - */ - if (fs.aggr.op == EXP.delegate_ && (cast(DelegateExp)fs.aggr).func.isNested() && - !(cast(DelegateExp)fs.aggr).func.needThis()) - { - // https://issues.dlang.org/show_bug.cgi?id=3560 - fs.aggr = (cast(DelegateExp)fs.aggr).e1; - } - ec = new CallExp(fs.loc, fs.aggr, flde); - ec = ec.expressionSemantic(sc2); - if (ec.op == EXP.error) - return null; - if (ec.type != Type.tint32) - { - fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars()); - return null; - } - return ec; - } - - private static extern(D) Expression applyArray(ForeachStatement fs, Expression flde, - Type tab, Scope* sc2, Type tn, Type tnv) - { - Expression ec; - const dim = fs.parameters.length; - const loc = fs.loc; - /* Call: - * _aApply(aggr, flde) - */ - static immutable fntab = - [ - "cc", "cw", "cd", - "wc", "cc", "wd", - "dc", "dw", "dd" - ]; - - const(size_t) BUFFER_LEN = 7 + 1 + 2 + dim.sizeof * 3 + 1; - char[BUFFER_LEN] fdname; - int flag; - - switch (tn.ty) - { - case Tchar: flag = 0; break; - case Twchar: flag = 3; break; - case Tdchar: flag = 6; break; - default: - assert(0); - } - switch (tnv.ty) - { - case Tchar: flag += 0; break; - case Twchar: flag += 1; break; - case Tdchar: flag += 2; break; - default: - assert(0); - } - const(char)* r = (fs.op == TOK.foreach_reverse_) ? "R" : ""; - int j = snprintf(fdname.ptr, BUFFER_LEN, "_aApply%s%.*s%llu", r, 2, fntab[flag].ptr, cast(ulong)dim); - assert(j < BUFFER_LEN); - - FuncDeclaration fdapply; - TypeDelegate dgty; - auto params = new Parameters(); - params.push(new Parameter(STC.in_, tn.arrayOf(), null, null, null)); - auto dgparams = new Parameters(); - dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); - if (dim == 2) - dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); - dgty = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d)); - params.push(new Parameter(0, dgty, null, null, null)); - fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr); - - if (tab.isTypeSArray()) - fs.aggr = fs.aggr.castTo(sc2, tn.arrayOf()); - // paint delegate argument to the type runtime expects - Expression fexp = flde; - if (!dgty.equals(flde.type)) - { - fexp = new CastExp(loc, flde, flde.type); - fexp.type = dgty; - } - ec = new VarExp(Loc.initial, fdapply, false); - ec = new CallExp(loc, ec, fs.aggr, fexp); - ec.type = Type.tint32; // don't run semantic() on ec - return ec; - } - - private static extern(D) Expression applyAssocArray(ForeachStatement fs, Expression flde, Type tab) - { - auto taa = tab.isTypeAArray(); - Expression ec; - const dim = fs.parameters.length; - // Check types - Parameter p = (*fs.parameters)[0]; - bool isRef = (p.storageClass & STC.ref_) != 0; - Type ta = p.type; - if (dim == 2) - { - Type ti = (isRef ? taa.index.addMod(MODFlags.const_) : taa.index); - if (isRef ? !ti.constConv(ta) : !ti.implicitConvTo(ta)) - { - fs.error("`foreach`: index must be type `%s`, not `%s`", - ti.toChars(), ta.toChars()); - return null; - } - p = (*fs.parameters)[1]; - isRef = (p.storageClass & STC.ref_) != 0; - ta = p.type; - } - Type taav = taa.nextOf(); - if (isRef ? !taav.constConv(ta) : !taav.implicitConvTo(ta)) - { - fs.error("`foreach`: value must be type `%s`, not `%s`", - taav.toChars(), ta.toChars()); - return null; - } - - /* Call: - * extern(C) int _aaApply(void*, in size_t, int delegate(void*)) - * _aaApply(aggr, keysize, flde) - * - * extern(C) int _aaApply2(void*, in size_t, int delegate(void*, void*)) - * _aaApply2(aggr, keysize, flde) - */ - __gshared FuncDeclaration* fdapply = [null, null]; - __gshared TypeDelegate* fldeTy = [null, null]; - ubyte i = (dim == 2 ? 1 : 0); - if (!fdapply[i]) - { - auto params = new Parameters(); - params.push(new Parameter(0, Type.tvoid.pointerTo(), null, null, null)); - params.push(new Parameter(STC.const_, Type.tsize_t, null, null, null)); - auto dgparams = new Parameters(); - dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); - if (dim == 2) - dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); - fldeTy[i] = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d)); - params.push(new Parameter(0, fldeTy[i], null, null, null)); - fdapply[i] = FuncDeclaration.genCfunc(params, Type.tint32, i ? Id._aaApply2 : Id._aaApply); - } - - auto exps = new Expressions(); - exps.push(fs.aggr); - auto keysize = taa.index.size(); - if (keysize == SIZE_INVALID) - return null; - assert(keysize < keysize.max - target.ptrsize); - keysize = (keysize + (target.ptrsize - 1)) & ~(target.ptrsize - 1); - // paint delegate argument to the type runtime expects - Expression fexp = flde; - if (!fldeTy[i].equals(flde.type)) - { - fexp = new CastExp(fs.loc, flde, flde.type); - fexp.type = fldeTy[i]; - } - exps.push(new IntegerExp(Loc.initial, keysize, Type.tsize_t)); - exps.push(fexp); - ec = new VarExp(Loc.initial, fdapply[i], false); - ec = new CallExp(fs.loc, ec, exps); - ec.type = Type.tint32; // don't run semantic() on ec - return ec; - } - - private static extern(D) Statement loopReturn(Expression e, Statements* cases, const ref Loc loc) - { - if (!cases.length) - { - // Easy case, a clean exit from the loop - e = new CastExp(loc, e, Type.tvoid); // https://issues.dlang.org/show_bug.cgi?id=13899 - return new ExpStatement(loc, e); - } - // Construct a switch statement around the return value - // of the apply function. - Statement s; - auto a = new Statements(); - - // default: break; takes care of cases 0 and 1 - s = new BreakStatement(Loc.initial, null); - s = new DefaultStatement(Loc.initial, s); - a.push(s); - - // cases 2... - foreach (i, c; *cases) - { - s = new CaseStatement(Loc.initial, new IntegerExp(i + 2), c); - a.push(s); - } - - s = new CompoundStatement(loc, a); - return new SwitchStatement(loc, e, s, false); - } - /************************************* - * Turn foreach body into the function literal: - * int delegate(ref T param) { body } - * Params: - * sc = context - * fs = ForeachStatement - * tfld = type of function literal to be created (type of opApply() function if any), can be null - * Returns: - * Function literal created, as an expression - * null if error. - */ - static FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFunction tfld) - { - auto params = new Parameters(); - foreach (i, p; *fs.parameters) - { - StorageClass stc = STC.ref_ | (p.storageClass & STC.scope_); - Identifier id; - - p.type = p.type.typeSemantic(fs.loc, sc); - p.type = p.type.addStorageClass(p.storageClass); - if (tfld) - { - Parameter prm = tfld.parameterList[i]; - //printf("\tprm = %s%s\n", (prm.storageClass&STC.ref_?"ref ":"").ptr, prm.ident.toChars()); - stc = (prm.storageClass & STC.ref_) | (p.storageClass & STC.scope_); - if ((p.storageClass & STC.ref_) != (prm.storageClass & STC.ref_)) - { - if (!(prm.storageClass & STC.ref_)) - { - fs.error("`foreach`: cannot make `%s` `ref`", p.ident.toChars()); - return null; - } - goto LcopyArg; - } - id = p.ident; // argument copy is not need. - } - else if (p.storageClass & STC.ref_) - { - // default delegate parameters are marked as ref, then - // argument copy is not need. - id = p.ident; - } - else - { - // Make a copy of the ref argument so it isn't - // a reference. - LcopyArg: - id = Identifier.generateId("__applyArg", cast(int)i); - - Initializer ie = new ExpInitializer(fs.loc, new IdentifierExp(fs.loc, id)); - auto v = new VarDeclaration(fs.loc, p.type, p.ident, ie); - v.storage_class |= STC.temp | (stc & STC.scope_); - Statement s = new ExpStatement(fs.loc, v); - fs._body = new CompoundStatement(fs.loc, s, fs._body); - } - params.push(new Parameter(stc, p.type, id, null, null)); - } - // https://issues.dlang.org/show_bug.cgi?id=13840 - // Throwable nested function inside nothrow function is acceptable. - StorageClass stc = mergeFuncAttrs(STC.safe | STC.pure_ | STC.nogc, fs.func); - auto tf = new TypeFunction(ParameterList(params), Type.tint32, LINK.d, stc); - fs.cases = new Statements(); - fs.gotos = new ScopeStatements(); - auto fld = new FuncLiteralDeclaration(fs.loc, fs.endloc, tf, TOK.delegate_, fs); - fld.fbody = fs._body; - Expression flde = new FuncExp(fs.loc, fld); - flde = flde.expressionSemantic(sc); - fld.tookAddressOf = 0; - if (flde.op == EXP.error) - return null; - return cast(FuncExp)flde; - } - - override void visit(ForeachRangeStatement fs) + void visitForeachRange(ForeachRangeStatement fs) { /* https://dlang.org/spec/statement.html#foreach-range-statement */ @@ -1886,7 +1582,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = s.statementSemantic(sc); } - override void visit(IfStatement ifs) + void visitIf(IfStatement ifs) { /* https://dlang.org/spec/statement.html#IfStatement */ @@ -1959,6 +1655,20 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor // Save 'root' of two branches (then and else) at the point where it forks CtorFlow ctorflow_root = scd.ctorflow.clone(); + /* Rewrite `if (!__ctfe) A else B` as `if (__ctfe) B else A` + */ + NotExp notExp; + if (ifs.elsebody && + (notExp = ifs.condition.isNotExp()) !is null && + notExp.e1.isVarExp() && + notExp.e1.isVarExp().var.ident == Id.ctfe) + { + ifs.condition = notExp.e1; + auto sbody = ifs.ifbody; + ifs.ifbody = ifs.elsebody; + ifs.elsebody = sbody; + } + /* Detect `if (__ctfe)` */ if (ifs.isIfCtfeBlock()) @@ -1991,7 +1701,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ifs; } - override void visit(ConditionalStatement cs) + void visitConditional(ConditionalStatement cs) { //printf("ConditionalStatement::semantic()\n"); @@ -2020,7 +1730,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } } - override void visit(PragmaStatement ps) + void visitPragma(PragmaStatement ps) { /* https://dlang.org/spec/statement.html#pragma-statement */ @@ -2104,14 +1814,14 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ps._body; } - override void visit(StaticAssertStatement s) + void visitStaticAssert(StaticAssertStatement s) { s.sa.semantic2(sc); if (s.sa.errors) return setError(); } - override void visit(SwitchStatement ss) + void visitSwitch(SwitchStatement ss) { /* https://dlang.org/spec/statement.html#switch-statement */ @@ -2288,6 +1998,11 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor { s = new BreakStatement(ss.loc, null); // default for C is `default: break;` } + else if (!sc.needsCodegen()) + { + // something for the interpreter to deal with + s = new ExpStatement(ss.loc, new AssertExp(ss.loc, IntegerExp.literal!0)); + } else if (global.params.useSwitchError == CHECKENABLE.on && global.params.checkAction != CHECKACTION.halt) { @@ -2337,7 +2052,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } - if (!ss.condition.type.isString()) + if (!(ss.condition.type.isString() && sc.needsCodegen())) { sc.pop(); result = ss; @@ -2420,7 +2135,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ss; } - override void visit(CaseStatement cs) + void visitCase(CaseStatement cs) { SwitchStatement sw = sc.sw; bool errors = false; @@ -2566,7 +2281,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = cs; } - override void visit(CaseRangeStatement crs) + void visitCaseRange(CaseRangeStatement crs) { SwitchStatement sw = sc.sw; if (sw is null) @@ -2649,7 +2364,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = s; } - override void visit(DefaultStatement ds) + void visitDefault(DefaultStatement ds) { //printf("DefaultStatement::semantic()\n"); bool errors = false; @@ -2693,7 +2408,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ds; } - override void visit(GotoDefaultStatement gds) + void visitGotoDefault(GotoDefaultStatement gds) { /* https://dlang.org/spec/statement.html#goto-statement */ @@ -2712,7 +2427,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = gds; } - override void visit(GotoCaseStatement gcs) + void visitGotoCase(GotoCaseStatement gcs) { /* https://dlang.org/spec/statement.html#goto-statement */ @@ -2736,7 +2451,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = gcs; } - override void visit(ReturnStatement rs) + void visitReturn(ReturnStatement rs) { /* https://dlang.org/spec/statement.html#return-statement */ @@ -3129,7 +2844,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = rs; } - override void visit(BreakStatement bs) + void visitBreak(BreakStatement bs) { /* https://dlang.org/spec/statement.html#break-statement */ @@ -3207,7 +2922,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = bs; } - override void visit(ContinueStatement cs) + void visitContinue(ContinueStatement cs) { /* https://dlang.org/spec/statement.html#continue-statement */ @@ -3294,7 +3009,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = cs; } - override void visit(SynchronizedStatement ss) + void visitSynchronized(SynchronizedStatement ss) { /* https://dlang.org/spec/statement.html#synchronized-statement */ @@ -3416,7 +3131,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } } - override void visit(WithStatement ws) + void visitWith(WithStatement ws) { /* https://dlang.org/spec/statement.html#with-statement */ @@ -3451,14 +3166,16 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } else { - Type t = ws.exp.type.toBasetype(); + Type texp = ws.exp.type; + Type t = texp.toBasetype(); Expression olde = ws.exp; if (t.ty == Tpointer) { ws.exp = new PtrExp(ws.loc, ws.exp); ws.exp = ws.exp.expressionSemantic(sc); - t = ws.exp.type.toBasetype(); + texp = ws.exp.type; + t = texp.toBasetype(); } assert(t); @@ -3506,9 +3223,16 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor sym.parent = sc.scopesym; sym.endlinnum = ws.endloc.linnum; } + else if (auto tenum = texp.isTypeEnum()) + { + ws.exp = new TypeExp(ws.exp.loc, tenum); + sym = new WithScopeSymbol(ws); + sym.parent = sc.scopesym; + sym.endlinnum = ws.endloc.linnum; + } else { - ws.error("`with` expressions must be aggregate types or pointers to them, not `%s`", olde.type.toChars()); + ws.error("`with` expression types must be enums or aggregates or pointers to them, not `%s`", olde.type.toChars()); return setError(); } } @@ -3531,7 +3255,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } // https://dlang.org/spec/statement.html#TryStatement - override void visit(TryCatchStatement tcs) + void visitTryCatch(TryCatchStatement tcs) { //printf("TryCatchStatement.semantic()\n"); @@ -3635,7 +3359,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = tcs; } - override void visit(TryFinallyStatement tfs) + void visitTryFinally(TryFinallyStatement tfs) { //printf("TryFinallyStatement::semantic()\n"); tfs.tryBody = sc.tryBody; // chain on in-flight tryBody @@ -3675,7 +3399,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = tfs; } - override void visit(ScopeGuardStatement oss) + void visitScopeGuard(ScopeGuardStatement oss) { /* https://dlang.org/spec/statement.html#scope-guard-statement */ @@ -3725,7 +3449,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = oss; } - override void visit(ThrowStatement ts) + void visitThrow(ThrowStatement ts) { /* https://dlang.org/spec/statement.html#throw-statement */ @@ -3738,57 +3462,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } - /** - * Run semantic on `throw `. - * - * Params: - * loc = location of the `throw` - * exp = value to be thrown - * sc = enclosing scope - * - * Returns: true if the `throw` is valid, or false if an error was found - */ - extern(D) static bool throwSemantic(const ref Loc loc, ref Expression exp, Scope* sc) - { - if (!global.params.useExceptions) - { - loc.error("cannot use `throw` statements with -betterC"); - return false; - } - - if (!ClassDeclaration.throwable) - { - loc.error("cannot use `throw` statements because `object.Throwable` was not declared"); - return false; - } - - if (FuncDeclaration fd = sc.parent.isFuncDeclaration()) - fd.hasReturnExp |= 2; - - if (exp.op == EXP.new_) - { - NewExp ne = cast(NewExp) exp; - ne.thrownew = true; - } - - exp = exp.expressionSemantic(sc); - exp = resolveProperties(sc, exp); - exp = checkGC(sc, exp); - if (exp.op == EXP.error) - return false; - - checkThrowEscape(sc, exp, false); - - ClassDeclaration cd = exp.type.toBasetype().isClassHandle(); - if (!cd || ((cd != ClassDeclaration.throwable) && !ClassDeclaration.throwable.isBaseOf(cd, null))) - { - loc.error("can only throw class objects derived from `Throwable`, not type `%s`", exp.type.toChars()); - return false; - } - return true; - } - - override void visit(DebugStatement ds) + void visitDebug(DebugStatement ds) { if (ds.statement) { @@ -3800,7 +3474,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ds.statement; } - override void visit(GotoStatement gs) + void visitGoto(GotoStatement gs) { /* https://dlang.org/spec/statement.html#goto-statement */ @@ -3844,7 +3518,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = gs; } - override void visit(LabelStatement ls) + void visitLabel(LabelStatement ls) { //printf("LabelStatement::semantic()\n"); FuncDeclaration fd = sc.parent.isFuncDeclaration(); @@ -3878,7 +3552,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = ls; } - override void visit(AsmStatement s) + void visitAsm(AsmStatement s) { /* https://dlang.org/spec/statement.html#asm */ @@ -3887,7 +3561,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = asmSemantic(s, sc); } - override void visit(CompoundAsmStatement cas) + void visitCompoundAsm(CompoundAsmStatement cas) { //printf("CompoundAsmStatement()::semantic()\n"); // Apply postfix attributes of the asm block to each statement. @@ -3915,9 +3589,9 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } assert(sc.func); - if (!(cas.stc & STC.pure_) && sc.func.setImpure()) + if (!(cas.stc & STC.pure_) && sc.func.setImpure(cas.loc, "`asm` statement is assumed to be impure - mark it with `pure` if it is not")) cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not"); - if (!(cas.stc & STC.nogc) && sc.func.setGC()) + if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not")) cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not"); if (!(cas.stc & (STC.trusted | STC.safe))) { @@ -3928,7 +3602,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor result = cas; } - override void visit(ImportStatement imps) + void visitImport(ImportStatement imps) { /* https://dlang.org/spec/module.html#ImportDeclaration */ @@ -3967,8 +3641,375 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } result = imps; } + + mixin VisitStatement!void visit; + visit.VisitStatement(s); + return result; } +/** + * Run semantic on `throw `. + * + * Params: + * loc = location of the `throw` + * exp = value to be thrown + * sc = enclosing scope + * + * Returns: true if the `throw` is valid, or false if an error was found + */ +public bool throwSemantic(const ref Loc loc, ref Expression exp, Scope* sc) +{ + if (!global.params.useExceptions) + { + loc.error("cannot use `throw` statements with -betterC"); + return false; + } + + if (!ClassDeclaration.throwable) + { + loc.error("cannot use `throw` statements because `object.Throwable` was not declared"); + return false; + } + + if (FuncDeclaration fd = sc.parent.isFuncDeclaration()) + fd.hasReturnExp |= 2; + + if (exp.op == EXP.new_) + { + NewExp ne = cast(NewExp) exp; + ne.thrownew = true; + } + + exp = exp.expressionSemantic(sc); + exp = resolveProperties(sc, exp); + exp = checkGC(sc, exp); + if (exp.op == EXP.error) + return false; + if (!exp.type.isNaked()) + { + // @@@DEPRECATED_2.112@@@ + // Deprecated in 2.102, change into an error & return false in 2.112 + exp.loc.deprecation("cannot throw object of qualified type `%s`", exp.type.toChars()); + //return false; + } + checkThrowEscape(sc, exp, false); + + ClassDeclaration cd = exp.type.toBasetype().isClassHandle(); + if (!cd || ((cd != ClassDeclaration.throwable) && !ClassDeclaration.throwable.isBaseOf(cd, null))) + { + loc.error("can only throw class objects derived from `Throwable`, not type `%s`", exp.type.toChars()); + return false; + } + return true; +} + +private extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde, + Type tab, Scope* sc2, Dsymbol sapply) +{ + version (none) + { + if (global.params.useDIP1000 == FeatureState.enabled) + { + message(loc, "To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`"); + } + (cast(FuncExp)flde).fd.tookAddressOf = 1; + } + else + { + if (global.params.useDIP1000 == FeatureState.enabled) + ++(cast(FuncExp)flde).fd.tookAddressOf; // allocate a closure unless the opApply() uses 'scope' + } + assert(tab.ty == Tstruct || tab.ty == Tclass); + assert(sapply); + /* Call: + * aggr.apply(flde) + */ + Expression ec; + ec = new DotIdExp(fs.loc, fs.aggr, sapply.ident); + ec = new CallExp(fs.loc, ec, flde); + ec = ec.expressionSemantic(sc2); + if (ec.op == EXP.error) + return null; + if (ec.type != Type.tint32) + { + fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars()); + return null; + } + return ec; +} + +private extern(D) Expression applyDelegate(ForeachStatement fs, Expression flde, + Type tab, Scope* sc2) +{ + Expression ec; + /* Call: + * aggr(flde) + */ + if (fs.aggr.op == EXP.delegate_ && (cast(DelegateExp)fs.aggr).func.isNested() && + !(cast(DelegateExp)fs.aggr).func.needThis()) + { + // https://issues.dlang.org/show_bug.cgi?id=3560 + fs.aggr = (cast(DelegateExp)fs.aggr).e1; + } + ec = new CallExp(fs.loc, fs.aggr, flde); + ec = ec.expressionSemantic(sc2); + if (ec.op == EXP.error) + return null; + if (ec.type != Type.tint32) + { + fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars()); + return null; + } + return ec; +} + +private extern(D) Expression applyArray(ForeachStatement fs, Expression flde, + Type tab, Scope* sc2, Type tn, Type tnv) +{ + Expression ec; + const dim = fs.parameters.length; + const loc = fs.loc; + /* Call: + * _aApply(aggr, flde) + */ + static immutable fntab = + [ + "cc", "cw", "cd", + "wc", "cc", "wd", + "dc", "dw", "dd" + ]; + + const(size_t) BUFFER_LEN = 7 + 1 + 2 + dim.sizeof * 3 + 1; + char[BUFFER_LEN] fdname; + int flag; + + switch (tn.ty) + { + case Tchar: flag = 0; break; + case Twchar: flag = 3; break; + case Tdchar: flag = 6; break; + default: + assert(0); + } + switch (tnv.ty) + { + case Tchar: flag += 0; break; + case Twchar: flag += 1; break; + case Tdchar: flag += 2; break; + default: + assert(0); + } + const(char)* r = (fs.op == TOK.foreach_reverse_) ? "R" : ""; + int j = snprintf(fdname.ptr, BUFFER_LEN, "_aApply%s%.*s%llu", r, 2, fntab[flag].ptr, cast(ulong)dim); + assert(j < BUFFER_LEN); + + FuncDeclaration fdapply; + TypeDelegate dgty; + auto params = new Parameters(); + params.push(new Parameter(STC.in_, tn.arrayOf(), null, null, null)); + auto dgparams = new Parameters(); + dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); + if (dim == 2) + dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); + dgty = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d)); + params.push(new Parameter(0, dgty, null, null, null)); + fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr); + + if (tab.isTypeSArray()) + fs.aggr = fs.aggr.castTo(sc2, tn.arrayOf()); + // paint delegate argument to the type runtime expects + Expression fexp = flde; + if (!dgty.equals(flde.type)) + { + fexp = new CastExp(loc, flde, flde.type); + fexp.type = dgty; + } + ec = new VarExp(Loc.initial, fdapply, false); + ec = new CallExp(loc, ec, fs.aggr, fexp); + ec.type = Type.tint32; // don't run semantic() on ec + return ec; +} + +private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression flde, Type tab) +{ + auto taa = tab.isTypeAArray(); + Expression ec; + const dim = fs.parameters.length; + // Check types + Parameter p = (*fs.parameters)[0]; + bool isRef = (p.storageClass & STC.ref_) != 0; + Type ta = p.type; + if (dim == 2) + { + Type ti = (isRef ? taa.index.addMod(MODFlags.const_) : taa.index); + if (isRef ? !ti.constConv(ta) : !ti.implicitConvTo(ta)) + { + fs.error("`foreach`: index must be type `%s`, not `%s`", + ti.toChars(), ta.toChars()); + return null; + } + p = (*fs.parameters)[1]; + isRef = (p.storageClass & STC.ref_) != 0; + ta = p.type; + } + Type taav = taa.nextOf(); + if (isRef ? !taav.constConv(ta) : !taav.implicitConvTo(ta)) + { + fs.error("`foreach`: value must be type `%s`, not `%s`", + taav.toChars(), ta.toChars()); + return null; + } + + /* Call: + * extern(C) int _aaApply(void*, in size_t, int delegate(void*)) + * _aaApply(aggr, keysize, flde) + * + * extern(C) int _aaApply2(void*, in size_t, int delegate(void*, void*)) + * _aaApply2(aggr, keysize, flde) + */ + __gshared FuncDeclaration* fdapply = [null, null]; + __gshared TypeDelegate* fldeTy = [null, null]; + ubyte i = (dim == 2 ? 1 : 0); + if (!fdapply[i]) + { + auto params = new Parameters(); + params.push(new Parameter(0, Type.tvoid.pointerTo(), null, null, null)); + params.push(new Parameter(STC.const_, Type.tsize_t, null, null, null)); + auto dgparams = new Parameters(); + dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); + if (dim == 2) + dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null)); + fldeTy[i] = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d)); + params.push(new Parameter(0, fldeTy[i], null, null, null)); + fdapply[i] = FuncDeclaration.genCfunc(params, Type.tint32, i ? Id._aaApply2 : Id._aaApply); + } + + auto exps = new Expressions(); + exps.push(fs.aggr); + auto keysize = taa.index.size(); + if (keysize == SIZE_INVALID) + return null; + assert(keysize < keysize.max - target.ptrsize); + keysize = (keysize + (target.ptrsize - 1)) & ~(target.ptrsize - 1); + // paint delegate argument to the type runtime expects + Expression fexp = flde; + if (!fldeTy[i].equals(flde.type)) + { + fexp = new CastExp(fs.loc, flde, flde.type); + fexp.type = fldeTy[i]; + } + exps.push(new IntegerExp(Loc.initial, keysize, Type.tsize_t)); + exps.push(fexp); + ec = new VarExp(Loc.initial, fdapply[i], false); + ec = new CallExp(fs.loc, ec, exps); + ec.type = Type.tint32; // don't run semantic() on ec + return ec; +} + +private extern(D) Statement loopReturn(Expression e, Statements* cases, const ref Loc loc) +{ + if (!cases.length) + { + // Easy case, a clean exit from the loop + e = new CastExp(loc, e, Type.tvoid); // https://issues.dlang.org/show_bug.cgi?id=13899 + return new ExpStatement(loc, e); + } + // Construct a switch statement around the return value + // of the apply function. + Statement s; + auto a = new Statements(); + + // default: break; takes care of cases 0 and 1 + s = new BreakStatement(Loc.initial, null); + s = new DefaultStatement(Loc.initial, s); + a.push(s); + + // cases 2... + foreach (i, c; *cases) + { + s = new CaseStatement(Loc.initial, new IntegerExp(i + 2), c); + a.push(s); + } + + s = new CompoundStatement(loc, a); + return new SwitchStatement(loc, e, s, false); +} + +/************************************* + * Turn foreach body into the function literal: + * int delegate(ref T param) { body } + * Params: + * sc = context + * fs = ForeachStatement + * tfld = type of function literal to be created (type of opApply() function if any), can be null + * Returns: + * Function literal created, as an expression + * null if error. + */ +private FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFunction tfld) +{ + auto params = new Parameters(); + foreach (i, p; *fs.parameters) + { + StorageClass stc = STC.ref_ | (p.storageClass & STC.scope_); + Identifier id; + + p.type = p.type.typeSemantic(fs.loc, sc); + p.type = p.type.addStorageClass(p.storageClass); + if (tfld) + { + Parameter prm = tfld.parameterList[i]; + //printf("\tprm = %s%s\n", (prm.storageClass&STC.ref_?"ref ":"").ptr, prm.ident.toChars()); + stc = (prm.storageClass & STC.ref_) | (p.storageClass & STC.scope_); + if ((p.storageClass & STC.ref_) != (prm.storageClass & STC.ref_)) + { + if (!(prm.storageClass & STC.ref_)) + { + fs.error("`foreach`: cannot make `%s` `ref`", p.ident.toChars()); + return null; + } + goto LcopyArg; + } + id = p.ident; // argument copy is not need. + } + else if (p.storageClass & STC.ref_) + { + // default delegate parameters are marked as ref, then + // argument copy is not need. + id = p.ident; + } + else + { + // Make a copy of the ref argument so it isn't + // a reference. + LcopyArg: + id = Identifier.generateId("__applyArg", cast(int)i); + + Initializer ie = new ExpInitializer(fs.loc, new IdentifierExp(fs.loc, id)); + auto v = new VarDeclaration(fs.loc, p.type, p.ident, ie); + v.storage_class |= STC.temp | (stc & STC.scope_); + Statement s = new ExpStatement(fs.loc, v); + fs._body = new CompoundStatement(fs.loc, s, fs._body); + } + params.push(new Parameter(stc, p.type, id, null, null)); + } + // https://issues.dlang.org/show_bug.cgi?id=13840 + // Throwable nested function inside nothrow function is acceptable. + StorageClass stc = mergeFuncAttrs(STC.safe | STC.pure_ | STC.nogc, fs.func); + auto tf = new TypeFunction(ParameterList(params), Type.tint32, LINK.d, stc); + fs.cases = new Statements(); + fs.gotos = new ScopeStatements(); + auto fld = new FuncLiteralDeclaration(fs.loc, fs.endloc, tf, TOK.delegate_, fs); + fld.fbody = fs._body; + Expression flde = new FuncExp(fs.loc, fld); + flde = flde.expressionSemantic(sc); + fld.tookAddressOf = 0; + if (flde.op == EXP.error) + return null; + return cast(FuncExp)flde; +} + + void catchSemantic(Catch c, Scope* sc) { //printf("Catch::semantic(%s)\n", ident.toChars()); @@ -4735,8 +4776,8 @@ private Statements* flatten(Statement statement, Scope* sc) (*a)[0] = ls; return a; - case STMT.Compile: - auto cs = statement.isCompileStatement(); + case STMT.Mixin: + auto cs = statement.isMixinStatement(); OutBuffer buf; @@ -4747,13 +4788,16 @@ private Statements* flatten(Statement statement, Scope* sc) const len = buf.length; buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; - scope p = new Parser!ASTCodegen(cs.loc, sc._module, str, false, global.errorSink); + const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; + auto loc = adjustLocForMixin(str, cs.loc, global.params.mixinOut); + scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + p.transitionIn = global.params.vin; p.nextToken(); auto a = new Statements(); while (p.token.value != TOK.endOfFile) { - Statement s = p.parseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope); + Statement s = p.parseStatement(ParseStatementFlags.curlyScope); if (!s || global.errors != errors) return errorStatements(); a.push(s); diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index aec3a77..352c89e 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -274,6 +274,7 @@ enum TOK : ubyte __cdecl, __declspec, __stdcall, + __thread, __pragma, __int128, __attribute__, @@ -289,8 +290,6 @@ enum EXP : ubyte cast_, null_, assert_, - true_, - false_, array, call, address, @@ -307,13 +306,10 @@ enum EXP : ubyte dotType, slice, arrayLength, - version_, dollar, template_, dotTemplateDeclaration, declaration, - typeof_, - pragma_, dSymbol, typeid_, uadd, @@ -394,13 +390,11 @@ enum EXP : ubyte int64, float64, complex80, - char_, import_, delegate_, function_, mixin_, in_, - default_, break_, continue_, goto_, @@ -414,7 +408,6 @@ enum EXP : ubyte moduleString, // __MODULE__ functionString, // __FUNCTION__ prettyFunction, // __PRETTY_FUNCTION__ - shared_, pow, powAssign, vector, @@ -424,10 +417,11 @@ enum EXP : ubyte showCtfeContext, objcClassReference, vectorArray, - arrow, // -> compoundLiteral, // ( type-name ) { initializer-list } _Generic, interval, + + loweredAssignExp, } enum FirstCKeyword = TOK.inline; @@ -586,6 +580,7 @@ private immutable TOK[] keywords = TOK.__cdecl, TOK.__declspec, TOK.__stdcall, + TOK.__thread, TOK.__pragma, TOK.__int128, TOK.__attribute__, @@ -617,7 +612,7 @@ static immutable TOK[TOK.max + 1] Ckeywords = union_, unsigned, void_, volatile, while_, asm_, typeof_, _Alignas, _Alignof, _Atomic, _Bool, _Complex, _Generic, _Imaginary, _Noreturn, _Static_assert, _Thread_local, - _import, __cdecl, __declspec, __stdcall, __pragma, __int128, __attribute__, + _import, __cdecl, __declspec, __stdcall, __thread, __pragma, __int128, __attribute__, _assert ]; foreach (kw; Ckwds) @@ -889,6 +884,7 @@ extern (C++) struct Token TOK.__cdecl : "__cdecl", TOK.__declspec : "__declspec", TOK.__stdcall : "__stdcall", + TOK.__thread : "__thread", TOK.__pragma : "__pragma", TOK.__int128 : "__int128", TOK.__attribute__ : "__attribute__", diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h index 87361f32..6c1b979 100644 --- a/gcc/d/dmd/tokens.h +++ b/gcc/d/dmd/tokens.h @@ -283,6 +283,7 @@ enum class TOK : unsigned char cdecl_, declspec, stdcall, + thread, pragma, int128_, attribute__, @@ -299,8 +300,6 @@ enum class EXP : unsigned char cast_, null_, assert_, - true_, - false_, array, call, address, @@ -317,13 +316,10 @@ enum class EXP : unsigned char dotType, slice, arrayLength, - version_, dollar, template_, dotTemplateDeclaration, declaration, - typeof_, - pragma_, dSymbol, typeid_, uadd, @@ -404,13 +400,11 @@ enum class EXP : unsigned char int64, float64, complex80, - char_, import_, delegate_, function_, mixin_, in_, - default_, break_, continue_, goto_, @@ -424,7 +418,6 @@ enum class EXP : unsigned char moduleString, // __MODULE__ functionString, // __FUNCTION__ prettyFunction, // __PRETTY_FUNCTION__ - shared_, pow, powAssign, vector, @@ -434,7 +427,6 @@ enum class EXP : unsigned char showCtfeContext, objcClassReference, vectorArray, - arrow, // -> compoundLiteral, // ( type-name ) { initializer-list } _Generic_, interval, diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index de0129b..0f36353 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -118,55 +118,40 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data) data.setDim(cast(size_t)cntdata); data.zero(); - extern (C++) final class PointerBitmapVisitor : Visitor - { - alias visit = Visitor.visit; - public: - extern (D) this(Array!(ulong)* _data, ulong _sz_size_t) scope - { - this.data = _data; - this.sz_size_t = _sz_size_t; - } + ulong offset; + bool error; + void visit(Type t) + { void setpointer(ulong off) { ulong ptroff = off / sz_size_t; (*data)[cast(size_t)(ptroff / (8 * sz_size_t))] |= 1L << (ptroff % (8 * sz_size_t)); } - override void visit(Type t) + void visitType(Type t) { Type tb = t.toBasetype(); if (tb != t) - tb.accept(this); + visit(tb); } - override void visit(TypeError t) + void visitError(TypeError t) { - visit(cast(Type)t); + visitType(t); } - override void visit(TypeNext t) - { - assert(0); - } - - override void visit(TypeBasic t) + void visitBasic(TypeBasic t) { if (t.ty == Tvoid) setpointer(offset); } - override void visit(TypeVector t) - { - } - - override void visit(TypeArray t) + void visitVector(TypeVector t) { - assert(0); } - override void visit(TypeSArray t) + void visitSArray(TypeSArray t) { ulong arrayoff = offset; ulong nextsize = t.next.size(); @@ -176,95 +161,67 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data) for (ulong i = 0; i < dim; i++) { offset = arrayoff + i * nextsize; - t.next.accept(this); + visit(t.next); } offset = arrayoff; } - override void visit(TypeDArray t) + void visitDArray(TypeDArray t) { setpointer(offset + sz_size_t); } // dynamic array is {length,ptr} - override void visit(TypeAArray t) + void visitAArray(TypeAArray t) { setpointer(offset); } - override void visit(TypePointer t) + void visitPointer(TypePointer t) { if (t.nextOf().ty != Tfunction) // don't mark function pointers setpointer(offset); } - override void visit(TypeReference t) + void visitReference(TypeReference t) { setpointer(offset); } - override void visit(TypeClass t) + void visitClass(TypeClass t) { setpointer(offset); } - override void visit(TypeFunction t) + void visitFunction(TypeFunction t) { } - override void visit(TypeDelegate t) + void visitDelegate(TypeDelegate t) { setpointer(offset); } - // delegate is {context, function} - override void visit(TypeQualified t) + void visitEnum(TypeEnum t) { - assert(0); + visitType(t); } - // assume resolved - override void visit(TypeIdentifier t) + void visitTuple(TypeTuple t) { - assert(0); + visitType(t); } - override void visit(TypeInstance t) + void visitNull(TypeNull t) { - assert(0); - } - - override void visit(TypeTypeof t) - { - assert(0); - } - - override void visit(TypeReturn t) - { - assert(0); - } - - override void visit(TypeEnum t) - { - visit(cast(Type)t); - } - - override void visit(TypeTuple t) - { - visit(cast(Type)t); + // always a null pointer } - override void visit(TypeSlice t) + void visitNoreturn(TypeNoreturn t) { - assert(0); } - override void visit(TypeNull t) - { - // always a null pointer - } - - override void visit(TypeStruct t) + void visitStruct(TypeStruct t) { ulong structoff = offset; foreach (v; t.sym.fields) @@ -273,38 +230,43 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data) if (v.type.ty == Tclass) setpointer(offset); else - v.type.accept(this); + visit(v.type); } offset = structoff; } + void visitDefaultCase(Type t) + { + //printf("ty = %d\n", t.ty); + assert(0); + } + + mixin VisitType!void visit; + visit.VisitType(t); + } + + if (auto tc = t.isTypeClass()) + { // a "toplevel" class is treated as an instance, while TypeClass fields are treated as references - void visitClass(TypeClass t) + void visitTopLevelClass(TypeClass t) { ulong classoff = offset; // skip vtable-ptr and monitor if (t.sym.baseClass) - visitClass(cast(TypeClass)t.sym.baseClass.type); + visitTopLevelClass(t.sym.baseClass.type.isTypeClass()); foreach (v; t.sym.fields) { offset = classoff + v.offset; - v.type.accept(this); + visit(v.type); } offset = classoff; } - Array!(ulong)* data; - ulong offset; - ulong sz_size_t; - bool error; + visitTopLevelClass(tc); } - - scope PointerBitmapVisitor pbv = new PointerBitmapVisitor(data, sz_size_t); - if (t.ty == Tclass) - pbv.visitClass(cast(TypeClass)t); else - t.accept(pbv); - return pbv.error ? ulong.max : sz; + visit(t); + return error ? ulong.max : sz; } /** @@ -1314,6 +1276,19 @@ Expression semanticTraits(TraitsExp e, Scope* sc) return ErrorExp.get(); } + // https://issues.dlang.org/show_bug.cgi?id=19706 + // When getting the attributes of the instance of a + // templated member function semantic tiargs does + // not perform semantic3 on the instance. + // For more information see FuncDeclaration.functionSemantic. + // For getFunctionAttributes it is mandatory to do + // attribute inference. + if (fd && fd.parent && fd.parent.isTemplateInstance) + { + fd.functionSemantic3(); + tf = cast(TypeFunction)fd.type; + } + auto mods = new Expressions(); void addToMods(string str) @@ -1354,6 +1329,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) * "argptr" extern(D) void dstyle(...), use `__argptr` and `__arguments` * "stdarg" extern(C) void cstyle(int, ...), use core.stdc.stdarg * "typesafe" void typesafe(T[] ...) + * "KR" old K+R style */ // get symbol linkage as a string if (dim != 1) @@ -1388,6 +1364,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) case VarArg.variadic: style = (link == LINK.d) ? "argptr" : "stdarg"; break; + case VarArg.KRvariadic: style = "KR"; break; case VarArg.typesafe: style = "typesafe"; break; } auto se = new StringExp(e.loc, style); @@ -2246,65 +2223,65 @@ private void traitNotFound(TraitsExp e) // All possible traits __gshared Identifier*[59] idents = [ + &Id.allMembers, + &Id.child, + &Id.classInstanceAlignment, + &Id.classInstanceSize, + &Id.compiles, + &Id.derivedMembers, + &Id.fullyQualifiedName, + &Id.getAliasThis, + &Id.getAttributes, + &Id.getFunctionAttributes, + &Id.getFunctionVariadicStyle, + &Id.getLinkage, + &Id.getLocation, + &Id.getMember, + &Id.getOverloads, + &Id.getParameterStorageClasses, + &Id.getPointerBitmap, + &Id.getProtection, + &Id.getTargetInfo, + &Id.getUnitTests, + &Id.getVirtualFunctions, + &Id.getVirtualIndex, + &Id.getVirtualMethods, + &Id.getVisibility, + &Id.hasCopyConstructor, + &Id.hasMember, + &Id.hasPostblit, + &Id.identifier, &Id.isAbstractClass, + &Id.isAbstractFunction, &Id.isArithmetic, &Id.isAssociativeArray, - &Id.isDisabled, + &Id.isCopyable, &Id.isDeprecated, - &Id.isFuture, + &Id.isDisabled, &Id.isFinalClass, - &Id.isPOD, - &Id.isNested, + &Id.isFinalFunction, &Id.isFloating, + &Id.isFuture, &Id.isIntegral, - &Id.isScalar, - &Id.isStaticArray, - &Id.isUnsigned, - &Id.isVirtualFunction, - &Id.isVirtualMethod, - &Id.isAbstractFunction, - &Id.isFinalFunction, - &Id.isOverrideFunction, - &Id.isStaticFunction, + &Id.isLazy, &Id.isModule, + &Id.isNested, + &Id.isOut, + &Id.isOverrideFunction, &Id.isPackage, + &Id.isPOD, &Id.isRef, - &Id.isOut, - &Id.isLazy, &Id.isReturnOnStack, - &Id.hasMember, - &Id.identifier, - &Id.fullyQualifiedName, - &Id.getProtection, - &Id.getVisibility, - &Id.parent, - &Id.child, - &Id.getLinkage, - &Id.getMember, - &Id.getOverloads, - &Id.getVirtualFunctions, - &Id.getVirtualMethods, - &Id.classInstanceSize, - &Id.classInstanceAlignment, - &Id.allMembers, - &Id.derivedMembers, &Id.isSame, - &Id.compiles, - &Id.getAliasThis, - &Id.getAttributes, - &Id.getFunctionAttributes, - &Id.getFunctionVariadicStyle, - &Id.getParameterStorageClasses, - &Id.getUnitTests, - &Id.getVirtualIndex, - &Id.getPointerBitmap, + &Id.isScalar, + &Id.isStaticArray, + &Id.isStaticFunction, + &Id.isUnsigned, + &Id.isVirtualFunction, + &Id.isVirtualMethod, &Id.isZeroInit, - &Id.getTargetInfo, - &Id.getLocation, - &Id.hasPostblit, - &Id.hasCopyConstructor, - &Id.isCopyable, &Id.parameters, + &Id.parent, ]; StringTable!(bool)* stringTable = cast(StringTable!(bool)*) &traitsStringTable; diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d index 5844911..c588270 100644 --- a/gcc/d/dmd/transitivevisitor.d +++ b/gcc/d/dmd/transitivevisitor.d @@ -44,9 +44,9 @@ package mixin template ParseVisitMethods(AST) } } - override void visit(AST.CompileStatement s) + override void visit(AST.MixinStatement s) { - //printf("Visiting CompileStatement\n"); + //printf("Visiting MixinStatement\n"); visitArgs(s.exps.peekSlice()); } @@ -579,7 +579,7 @@ package mixin template ParseVisitMethods(AST) de.accept(this); } - override void visit(AST.CompileDeclaration d) + override void visit(AST.MixinDeclaration d) { //printf("Visiting compileDeclaration\n"); visitArgs(d.exps.peekSlice()); diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index c668199..f0decf2 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -290,6 +290,8 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb if (!sm) return helper3(); + if (sm.isAliasDeclaration) + sm.checkDeprecated(loc, sc); s = sm.toAlias(); } @@ -456,6 +458,17 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) return t.merge(); } + Type visitComplex(TypeBasic t) + { + if (!(sc.flags & SCOPE.Cfile)) + return visitType(t); + + auto tc = getComplexLibraryType(loc, sc, t.ty); + if (tc.ty == Terror) + return tc; + return tc.addMod(t.mod).merge(); + } + Type visitVector(TypeVector mtype) { const errors = global.errors; @@ -1185,19 +1198,31 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) // -preview=in: Always add `ref` when used with `extern(C++)` functions // Done here to allow passing opaque types with `in` - if (global.params.previewIn && (fparam.storageClass & (STC.in_ | STC.ref_)) == STC.in_) + if ((fparam.storageClass & (STC.in_ | STC.ref_)) == STC.in_) { switch (tf.linkage) { case LINK.cpp: - fparam.storageClass |= STC.ref_; + if (global.params.previewIn) + fparam.storageClass |= STC.ref_; break; case LINK.default_, LINK.d: break; default: - .error(loc, "cannot use `in` parameters with `extern(%s)` functions", - linkageToChars(tf.linkage)); - .errorSupplemental(loc, "parameter `%s` declared as `in` here", fparam.toChars()); + if (global.params.previewIn) + { + .error(loc, "cannot use `in` parameters with `extern(%s)` functions", + linkageToChars(tf.linkage)); + .errorSupplemental(loc, "parameter `%s` declared as `in` here", fparam.toChars()); + } + else + { + // Note that this deprecation will not trigger on `in ref` / `ref in` + // parameters, however the parser will trigger a deprecation on them. + .deprecation(loc, "using `in` parameters with `extern(%s)` functions is deprecated", + linkageToChars(tf.linkage)); + .deprecationSupplemental(loc, "parameter `%s` declared as `in` here", fparam.toChars()); + } break; } } @@ -1292,28 +1317,6 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) // error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with `ref`)"); } - /* Scope attribute is not necessary if the parameter type does not have pointers - */ - const sr = buildScopeRef(fparam.storageClass); - switch (sr) - { - case ScopeRef.Scope: - case ScopeRef.RefScope: - case ScopeRef.ReturnRef_Scope: - if (!fparam.type.hasPointers()) - fparam.storageClass &= ~STC.scope_; - break; - - case ScopeRef.ReturnScope: - case ScopeRef.Ref_ReturnScope: - if (!fparam.type.hasPointers()) - fparam.storageClass &= ~(STC.return_ | STC.scope_ | STC.returnScope); - break; - - default: - break; - } - // Remove redundant storage classes for type, they are already applied fparam.storageClass &= ~(STC.TYPECTOR); @@ -1786,12 +1789,14 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) case TOK.struct_: auto sd = new StructDeclaration(mtype.loc, mtype.id, false); + sd.alignment = mtype.packalign; declare(sd); mtype.resolved = visitStruct(new TypeStruct(sd)); break; case TOK.union_: auto ud = new UnionDeclaration(mtype.loc, mtype.id); + ud.alignment = mtype.packalign; declare(ud); mtype.resolved = visitStruct(new TypeStruct(ud)); break; @@ -1928,6 +1933,9 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) switch (type.ty) { default: return visitType(type); + case Tcomplex32: + case Tcomplex64: + case Tcomplex80: return visitComplex(type.isTypeBasic()); case Tvector: return visitVector(type.isTypeVector()); case Tsarray: return visitSArray(type.isTypeSArray()); case Tarray: return visitDArray(type.isTypeDArray()); @@ -2697,7 +2705,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type { void semanticOnMixin(Dsymbol member) { - if (auto compileDecl = member.isCompileDeclaration()) + if (auto compileDecl = member.isMixinDeclaration()) compileDecl.dsymbolSemantic(sc); else if (auto mixinTempl = member.isTemplateMixin()) mixinTempl.dsymbolSemantic(sc); @@ -2796,8 +2804,10 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type } mt.exp = exp2; - if (mt.exp.op == EXP.type || - mt.exp.op == EXP.scope_) + if ((mt.exp.op == EXP.type || mt.exp.op == EXP.scope_) && + // https://issues.dlang.org/show_bug.cgi?id=23863 + // compile time sequences are valid types + !mt.exp.type.isTypeTuple()) { if (!(sc.flags & SCOPE.Cfile) && // in (extended) C typeof may be used on types as with sizeof mt.exp.checkType()) @@ -3126,7 +3136,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type * Returns: * resulting expression with e.ident resolved */ -Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) +Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag flag) { Expression visitType(Type mt) { @@ -3624,7 +3634,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) * template opDispatch(name) if (isValid!name) { ... } */ uint errors = gagError ? global.startGagging() : 0; - e = dti.dotTemplateSemanticProp(sc, 0); + e = dti.dotTemplateSemanticProp(sc, DotExpFlag.none); if (gagError && global.endGagging(errors)) e = null; return returnExp(e); @@ -3730,6 +3740,9 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) { return noMember(mt, sc, e, ident, flag); } + // check before alias resolution; the alias itself might be deprecated! + if (s.isAliasDeclaration) + e.checkDeprecated(sc, s); s = s.toAlias(); if (auto em = s.isEnumMember()) @@ -3917,7 +3930,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) return mt.getProperty(sc, e.loc, ident, flag & 1); } - Expression res = mt.sym.getMemtype(Loc.initial).dotExp(sc, e, ident, 1); + Expression res = mt.sym.getMemtype(Loc.initial).dotExp(sc, e, ident, DotExpFlag.gag); if (!(flag & 1) && !res) { if (auto ns = mt.sym.search_correct(ident)) @@ -4599,6 +4612,74 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc, const bool isCfi } } + +/********************************************** + * Extract complex type from core.stdc.config + * Params: + * loc = for error messages + * sc = context + * ty = a complex or imaginary type + * Returns: + * Complex!float, Complex!double, Complex!real or null for error + */ + +Type getComplexLibraryType(const ref Loc loc, Scope* sc, TY ty) +{ + // singleton + __gshared Type complex_float; + __gshared Type complex_double; + __gshared Type complex_real; + + Type* pt; + Identifier id; + switch (ty) + { + case Timaginary32: + case Tcomplex32: id = Id.c_complex_float; pt = &complex_float; break; + case Timaginary64: + case Tcomplex64: id = Id.c_complex_double; pt = &complex_double; break; + case Timaginary80: + case Tcomplex80: id = Id.c_complex_real; pt = &complex_real; break; + default: + return Type.terror; + } + + if (*pt) + return *pt; + *pt = Type.terror; + + Module mConfig = Module.loadCoreStdcConfig(); + if (!mConfig) + { + error(loc, "`core.stdc.config` is required for complex numbers"); + return *pt; + } + + Dsymbol s = mConfig.searchX(Loc.initial, sc, id, IgnorePrivateImports); + if (!s) + { + error(loc, "`%s` not found in core.stdc.config", id.toChars()); + return *pt; + } + s = s.toAlias(); + if (auto t = s.getType()) + { + if (auto ts = t.toBasetype().isTypeStruct()) + { + *pt = ts; + return ts; + } + } + if (auto sd = s.isStructDeclaration()) + { + *pt = sd.type; + return sd.type; + } + + error(loc, "`%s` must be an alias for a complex struct", s.toChars()); + return *pt; +} + /******************************* Private *****************************************/ private: @@ -4909,7 +4990,7 @@ Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id) * Return: * null if error, else RootObject AST as parsed */ -RootObject compileTypeMixin(TypeMixin tm, Loc loc, Scope* sc) +RootObject compileTypeMixin(TypeMixin tm, ref const Loc loc, Scope* sc) { OutBuffer buf; if (expressionsToString(buf, sc, tm.exps)) @@ -4919,7 +5000,10 @@ RootObject compileTypeMixin(TypeMixin tm, Loc loc, Scope* sc) const len = buf.length; buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; - scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink); + const bool doUnittests = global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput; + auto locm = adjustLocForMixin(str, loc, global.params.mixinOut); + scope p = new Parser!ASTCodegen(locm, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + p.transitionIn = global.params.vin; p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d index 38a39b4..4f87d92 100644 --- a/gcc/d/dmd/typinf.d +++ b/gcc/d/dmd/typinf.d @@ -47,6 +47,7 @@ extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope { if (!global.params.useTypeInfo) { + global.gag = 0; if (e) .error(loc, "expression `%s` uses the GC and cannot be used with switch `-betterC`", e.toChars()); else diff --git a/gcc/d/dmd/visitor.d b/gcc/d/dmd/visitor.d index 8990ce4..7b059a0 100644 --- a/gcc/d/dmd/visitor.d +++ b/gcc/d/dmd/visitor.d @@ -89,6 +89,7 @@ public: void visit(ASTCodegen.ClassReferenceExp e) { visit(cast(ASTCodegen.Expression)e); } void visit(ASTCodegen.VoidInitExp e) { visit(cast(ASTCodegen.Expression)e); } void visit(ASTCodegen.ThrownExceptionExp e) { visit(cast(ASTCodegen.Expression)e); } + void visit(ASTCodegen.LoweredAssignExp e) { visit(cast(ASTCodegen.AssignExp)e); } } /** @@ -152,7 +153,7 @@ extern (C++) class SemanticTimeTransitiveVisitor : SemanticTimePermissiveVisitor // need to avoid infinite recursion. if (!(e.stageflags & stageToCBuffer)) { - int old = e.stageflags; + const old = e.stageflags; e.stageflags |= stageToCBuffer; foreach (el; *e.elements) if (el) @@ -240,6 +241,12 @@ extern (C++) class SemanticTimeTransitiveVisitor : SemanticTimePermissiveVisitor e.e1.accept(this); e.e2.accept(this); } + + override void visit(ASTCodegen.LoweredAssignExp e) + { + e.lowering.accept(this); + visit(cast(AssignExp)e); + } } extern (C++) class StoppableVisitor : Visitor diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h index ed9f9ce..3d8c3e6 100644 --- a/gcc/d/dmd/visitor.h +++ b/gcc/d/dmd/visitor.h @@ -17,7 +17,7 @@ class ErrorStatement; class PeelStatement; class ExpStatement; class DtorExpStatement; -class CompileStatement; +class MixinStatement; class CompoundStatement; class CompoundDeclarationStatement; class UnrolledLoopStatement; @@ -110,7 +110,7 @@ class AnonDeclaration; class PragmaDeclaration; class ConditionalDeclaration; class StaticIfDeclaration; -class CompileDeclaration; +class MixinDeclaration; class StaticForeachDeclaration; class UserAttributeDeclaration; class ForwardingAttribDeclaration; @@ -268,6 +268,7 @@ class UshrAssignExp; class CatAssignExp; class CatElemAssignExp; class CatDcharAssignExp; +class LoweredAssignExp; class AddExp; class MinExp; class CatExp; @@ -365,7 +366,7 @@ public: virtual void visit(SharedStaticDtorDeclaration *s) { visit((StaticDtorDeclaration *)s); } // AttribDeclarations - virtual void visit(CompileDeclaration *s) { visit((AttribDeclaration *)s); } + virtual void visit(MixinDeclaration *s) { visit((AttribDeclaration *)s); } virtual void visit(UserAttributeDeclaration *s) { visit((AttribDeclaration *)s); } virtual void visit(LinkDeclaration *s) { visit((AttribDeclaration *)s); } virtual void visit(AnonDeclaration *s) { visit((AttribDeclaration *)s); } @@ -396,7 +397,7 @@ public: virtual void visit(ReturnStatement *s) { visit((Statement *)s); } virtual void visit(LabelStatement *s) { visit((Statement *)s); } virtual void visit(StaticAssertStatement *s) { visit((Statement *)s); } - virtual void visit(CompileStatement *s) { visit((Statement *)s); } + virtual void visit(MixinStatement *s) { visit((Statement *)s); } virtual void visit(WhileStatement *s) { visit((Statement *)s); } virtual void visit(ForStatement *s) { visit((Statement *)s); } virtual void visit(DoStatement *s) { visit((Statement *)s); } @@ -659,6 +660,7 @@ public: virtual void visit(ClassReferenceExp *e) { visit((Expression *)e); } virtual void visit(VoidInitExp *e) { visit((Expression *)e); } virtual void visit(ThrownExceptionExp *e) { visit((Expression *)e); } + virtual void visit(LoweredAssignExp *e) { visit((AssignExp *)e); } }; class StoppableVisitor : public Visitor diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index aeafe43..23f2f0b 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -693,78 +693,22 @@ public: void visit (CatExp *e) final override { - Type *tb1 = e->e1->type->toBasetype (); - Type *tb2 = e->e2->type->toBasetype (); - Type *etype; - - if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray) - etype = tb1->nextOf (); - else - etype = tb2->nextOf (); - - tree result; - - if (e->e1->op == EXP::concatenate) + /* This error is only emitted during the code generation pass because + concatentation is allowed in CTFE. */ + if (global.params.betterC) { - /* Flatten multiple concatenations to an array. - So the expression ((a ~ b) ~ c) becomes [a, b, c] */ - int ndims = 2; - - for (Expression *ex = e->e1; ex->op == EXP::concatenate;) - { - if (ex->op == EXP::concatenate) - { - ex = ex->isCatExp ()->e1; - ndims++; - } - } - - /* Store all concatenation args to a temporary byte[][ndims] array. */ - Type *targselem = Type::tint8->arrayOf (); - tree var = build_local_temp (make_array_type (targselem, ndims)); - - /* Loop through each concatenation from right to left. */ - vec *elms = NULL; - CatExp *ce = e; - int dim = ndims - 1; - - for (Expression *oe = ce->e2; oe != NULL; - (ce->e1->op != EXP::concatenate - ? (oe = ce->e1) - : (ce = ce->e1->isCatExp (), oe = ce->e2))) - { - tree arg = d_array_convert (etype, oe); - tree index = size_int (dim); - CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg)); - - /* Finished pushing all arrays. */ - if (oe == ce->e1) - break; - - dim -= 1; - } - - /* Check there is no logic bug in constructing byte[][] of arrays. */ - gcc_assert (dim == 0); - tree init = build_constructor (TREE_TYPE (var), elms); - var = compound_expr (modify_expr (var, init), var); - - tree arrs = d_array_value (build_ctype (targselem->arrayOf ()), - size_int (ndims), build_address (var)); - - result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2, - build_typeinfo (e, e->type), arrs); - } - else - { - /* Handle single concatenation (a ~ b). */ - result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3, - build_typeinfo (e, e->type), - d_array_convert (etype, e->e1), - d_array_convert (etype, e->e2)); + error_at (make_location_t (e->loc), + "array concatenation of expression %qs requires the GC and " + "cannot be used with %<-fno-druntime%>", e->toChars ()); + this->result_ = error_mark_node; + return; } - this->result_ = result; + /* All concat expressions should have been rewritten to `_d_arraycatnTX` in + the semantic phase. */ + gcc_assert (e->lowering); + + this->result_ = build_expr (e->lowering); } /* Build an assignment operator expression. The right operand is implicitly @@ -1150,6 +1094,13 @@ public: this->result_ = build_assign (modifycode, t1, t2); } + /* Build an assignment expression that has been lowered in the front-end. */ + + void visit (LoweredAssignExp *e) final override + { + this->result_ = build_expr (e->lowering); + } + /* Build a throw expression. */ void visit (ThrowExp *e) final override @@ -2828,7 +2779,7 @@ public: /* Building sinit trees are delayed until after frontend semantic processing has complete. Build the static initializer now. */ - if (e->useStaticInit && !this->constp_) + if (e->useStaticInit && !this->constp_ && !e->sd->isCsymbol ()) { tree init = aggregate_initializer_decl (e->sd); diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def index 23f8b64..fd83cc9 100644 --- a/gcc/d/runtime.def +++ b/gcc/d/runtime.def @@ -112,13 +112,6 @@ DEF_D_RUNTIME (ALLOCMEMORY, "_d_allocmemory", RT(VOIDPTR), P1(SIZE_T), DEF_D_RUNTIME (ARRAYCOPY, "_d_arraycopy", RT(ARRAY_VOID), P3(SIZE_T, ARRAY_VOID, ARRAY_VOID), 0) -/* Used for concatenating two or more arrays together. Then `n' variant is - for when there is more than two arrays to handle. */ -DEF_D_RUNTIME (ARRAYCATT, "_d_arraycatT", RT(ARRAY_BYTE), - P3(CONST_TYPEINFO, ARRAY_BYTE, ARRAY_BYTE), 0) -DEF_D_RUNTIME (ARRAYCATNTX, "_d_arraycatnTX", RT(ARRAY_VOID), - P2(CONST_TYPEINFO, ARRAYARRAY_BYTE), 0) - /* Used for appending a single element to an array. */ DEF_D_RUNTIME (ARRAYAPPENDCTX, "_d_arrayappendcTX", RT(ARRAY_BYTE), P3(CONST_TYPEINFO, ARRAYPTR_BYTE, SIZE_T), 0) diff --git a/gcc/testsuite/gdc.dg/nogc1.d b/gcc/testsuite/gdc.dg/nogc1.d new file mode 100644 index 0000000..2894ef0 --- /dev/null +++ b/gcc/testsuite/gdc.dg/nogc1.d @@ -0,0 +1,8 @@ +// { dg-do compile } +// { dg-options "-fno-druntime" } +// { dg-shouldfail "expressions depend on GC" } + +string testConcat(string a, string b) +{ + return a ~ b; // { dg-error "requires the GC and cannot be used with .-fno-druntime." } +} diff --git a/gcc/testsuite/gdc.dg/rtti1.d b/gcc/testsuite/gdc.dg/rtti1.d index ed5f344..29b8265 100644 --- a/gcc/testsuite/gdc.dg/rtti1.d +++ b/gcc/testsuite/gdc.dg/rtti1.d @@ -11,8 +11,3 @@ bool testAAEqual(int[string] aa1, int[string] aa2) { return aa1 == aa2; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." } } - -string testConcat(string a, string b) -{ - return a ~ b; // { dg-error "requires .object.TypeInfo. and cannot be used with .-fno-rtti." } -} diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d index 870387c..0436371 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d @@ -48,7 +48,7 @@ namespace nameSpace extern void fn2(); } - extern double identity(double _param_0); + extern double identity(double __param_0_); } --- @@ -63,5 +63,5 @@ extern(C++, "nameSpace") void fn2() {} } - double identity(double) { return _param_0; } + double identity(double) { return __param_0; } } diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_functions.d b/gcc/testsuite/gdc.test/compilable/dtoh_functions.d index 1feff40..38607f6 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_functions.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_functions.d @@ -159,7 +159,7 @@ extern int32_t(*f)(int32_t ); extern void special(int32_t a = ptr->i, int32_t b = ptr->get(1, 2), int32_t j = (*f)(1)); -extern void variadic(int32_t _param_0, ...); +extern void variadic(int32_t __param_0_, ...); --- +/ diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d b/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d index b8e8d05..a8f5b99 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d @@ -110,7 +110,7 @@ struct InvalidNames final } }; -extern void useInvalid(InvalidNames _param_0); +extern void useInvalid(InvalidNames __param_0_); extern size_t offsetof(); diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d b/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d index 37b4507..ee86a5e 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d @@ -40,25 +40,25 @@ struct _d_dynamicArray final #endif enum class __c_not_special; -extern "C" void fn_long(long _param_0); +extern "C" void fn_long(long __param_0_); -extern "C" void fn_ulong(unsigned long _param_0); +extern "C" void fn_ulong(unsigned long __param_0_); -extern "C" void fn_longlong(long long _param_0); +extern "C" void fn_longlong(long long __param_0_); -extern "C" void fn_ulonglong(unsigned long long _param_0); +extern "C" void fn_ulonglong(unsigned long long __param_0_); -extern "C" void fn_long_double(long double _param_0); +extern "C" void fn_long_double(long double __param_0_); -extern "C" void fn_wchar_t(wchar_t _param_0); +extern "C" void fn_wchar_t(wchar_t __param_0_); -extern "C" void fn_complex_float(_Complex float _param_0); +extern "C" void fn_complex_float(_Complex float __param_0_); -extern "C" void fn_complex_double(_Complex double _param_0); +extern "C" void fn_complex_double(_Complex double __param_0_); -extern "C" void fn_complex_real(_Complex long double _param_0); +extern "C" void fn_complex_real(_Complex long double __param_0_); -extern "C" void fn_not_special(__c_not_special _param_0); +extern "C" void fn_not_special(__c_not_special __param_0_); --- +/ diff --git a/gcc/testsuite/gdc.test/compilable/imports/c23789.i b/gcc/testsuite/gdc.test/compilable/imports/c23789.i new file mode 100644 index 0000000..74d7e80 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/c23789.i @@ -0,0 +1,31 @@ +// https://issues.dlang.org/show_bug.cgi?id=23789 + +struct __declspec(align(64)) M128A { + char c; +}; + +typedef struct __declspec(align(32)) _M128B { + int x; +} M128B, *PM128A; + + +void testpl(p) +struct __declspec(align(2)) S *p; +{ +} + +///// + +struct __attribute__((aligned(64))) N128A { + char c; +}; + +typedef struct __attribute__((aligned(32))) _N128B { + int x; +} N128B, *PN128A; + + +void testpl2(p) +struct __attribute__((aligned(2))) S *p; +{ +} diff --git a/gcc/testsuite/gdc.test/compilable/interpret3.d b/gcc/testsuite/gdc.test/compilable/interpret3.d index 2c9a84e..1414263 100644 --- a/gcc/testsuite/gdc.test/compilable/interpret3.d +++ b/gcc/testsuite/gdc.test/compilable/interpret3.d @@ -7208,7 +7208,7 @@ struct S13630(T) { T[3] arr; - this(A...)(auto ref in A args) + this(A...)(const auto ref A args) { auto p = arr.ptr; @@ -7238,7 +7238,7 @@ struct Matrix13827(T, uint N) T[N] flat; } - this(A...)(auto ref in A args) + this(A...)(const auto ref A args) { uint k; diff --git a/gcc/testsuite/gdc.test/compilable/test18493.d b/gcc/testsuite/gdc.test/compilable/test18493.d new file mode 100644 index 0000000..558bf44 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test18493.d @@ -0,0 +1,19 @@ +// https://issues.dlang.org/show_bug.cgi?id=18493 +// REQUIRED_ARGS: -betterC + +struct S +{ + this(this) + { + } + + ~this() + { + } +} + +struct C +{ + S s1; + S s2; +} diff --git a/gcc/testsuite/gdc.test/compilable/test19688.d b/gcc/testsuite/gdc.test/compilable/test19688.d new file mode 100644 index 0000000..9cc4dd7 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test19688.d @@ -0,0 +1,13 @@ +/* TEST_OUTUT: +--- +--- +*/ +void test(string s = __FUNCTION__ ~ __MODULE__ ~ __FUNCTION__) +{ + assert(s == "test19688.maintest19688test19688.main"); +} + +void main() +{ + test(); +} diff --git a/gcc/testsuite/gdc.test/compilable/test21667.d b/gcc/testsuite/gdc.test/compilable/test21667.d new file mode 100644 index 0000000..6d83dc0 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21667.d @@ -0,0 +1,19 @@ +// Issue 21667 - scope parameter causes 'no size because of forward references' +// https://issues.dlang.org/show_bug.cgi?id=21667 +@safe: + +struct Foo +{ + void delegate(scope Foo) dg; +} + +struct M +{ + F.Type f; +} + +struct F +{ + enum Type {a} + void foo(scope M m) {} +} diff --git a/gcc/testsuite/gdc.test/compilable/test23789.d b/gcc/testsuite/gdc.test/compilable/test23789.d new file mode 100644 index 0000000..ddf7351 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23789.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=23789 +// EXTRA_FILES: imports/c23789.i + +import imports.c23789; + +static assert(M128A.alignof == 64); +static assert(_M128B.alignof == 32); +static assert(M128B.alignof == 32); + +static assert(N128A.alignof == 64); +static assert(_N128B.alignof == 32); +static assert(N128B.alignof == 32); diff --git a/gcc/testsuite/gdc.test/compilable/test23862.d b/gcc/testsuite/gdc.test/compilable/test23862.d new file mode 100644 index 0000000..c5b063b --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23862.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=23862 + +enum E { A, B } + +void test(E e) +{ + with (e) + switch (e) + { + case A: + case B: + default: + break; + } +} diff --git a/gcc/testsuite/gdc.test/compilable/test23863.d b/gcc/testsuite/gdc.test/compilable/test23863.d new file mode 100644 index 0000000..c3941ce --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23863.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=23863 + +alias AliasSeq(T...) = T; + +struct S +{ +} +alias Empty = S.tupleof; +Empty x; // accepts valid + +static assert(is(typeof(x))); +static assert(is(typeof(Empty))); +static assert(is(typeof(AliasSeq!(int)))); +static assert(is(typeof(Empty) == AliasSeq!())); +static assert(is(typeof(AliasSeq!()) == AliasSeq!())); diff --git a/gcc/testsuite/gdc.test/compilable/traits_getFunctionAttributes.d b/gcc/testsuite/gdc.test/compilable/traits_getFunctionAttributes.d index 1f25b26..f4defb4 100644 --- a/gcc/testsuite/gdc.test/compilable/traits_getFunctionAttributes.d +++ b/gcc/testsuite/gdc.test/compilable/traits_getFunctionAttributes.d @@ -1,9 +1,10 @@ module traits_getFunctionAttributes; +alias tuple(T...) = T; + void test_getFunctionAttributes() { - alias tuple(T...) = T; struct S { @@ -118,3 +119,14 @@ void test_getFunctionAttributes() static assert(__traits(getFunctionAttributes, systemDel) == tuple!("pure", "nothrow", "@nogc", "@system")); static assert(__traits(getFunctionAttributes, typeof(systemDel)) == tuple!("pure", "nothrow", "@nogc", "@system")); } + +void bug19706() +{ + struct S + { + static int fImpl(Ret)() { return Ret.init; } + + // tells us: `fImpl!int` is @system + static assert(__traits(getFunctionAttributes, fImpl!int) == tuple!("pure", "nothrow", "@nogc", "@safe")); + } +} diff --git a/gcc/testsuite/gdc.test/compilable/user_defined_attributes.d b/gcc/testsuite/gdc.test/compilable/user_defined_attributes.d new file mode 100644 index 0000000..169ca49 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/user_defined_attributes.d @@ -0,0 +1,22 @@ + +enum Test; + +@true @null @byte int x; +@(int) int y; +@"test" @`test2` @30 @'a' @__LINE__ void f(); + +@Test void h(); + +static assert( __traits(getAttributes, x)[0] == true); +static assert( __traits(getAttributes, x)[1] == null); +static assert(is(__traits(getAttributes, x)[2] == byte)); + +static assert(is(__traits(getAttributes, y)[0] == int)); + +static assert( __traits(getAttributes, f)[0] == "test"); +static assert( __traits(getAttributes, f)[1] == "test2"); +static assert( __traits(getAttributes, f)[2] == 30); +static assert( __traits(getAttributes, f)[3] == 'a'); +static assert( __traits(getAttributes, f)[4] == 6); + +static assert(is(__traits(getAttributes, h)[0] == enum)); diff --git a/gcc/testsuite/gdc.test/compilable/warn3882.d b/gcc/testsuite/gdc.test/compilable/warn3882.d index f02a87b..0474315 100644 --- a/gcc/testsuite/gdc.test/compilable/warn3882.d +++ b/gcc/testsuite/gdc.test/compilable/warn3882.d @@ -12,7 +12,7 @@ void test3882() /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=12619 -extern (C) @system nothrow pure void* memcpy(void* s1, in void* s2, size_t n); +extern (C) @system nothrow pure void* memcpy(void* s1, const void* s2, size_t n); // -> weakly pure void test12619() pure @@ -64,7 +64,7 @@ void test12909() const struct Foo13899 { - int opApply(immutable int delegate(in ref int) pure nothrow dg) pure nothrow + int opApply(immutable int delegate(const ref int) pure nothrow dg) pure nothrow { return 1; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic.d b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic.d index 8360e1a..523a183 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic.d +++ b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic.d @@ -4,15 +4,15 @@ TEST_OUTPUT: fail_compilation/attributediagnostic.d(24): Error: `@safe` function `attributediagnostic.layer2` cannot call `@system` function `attributediagnostic.layer1` fail_compilation/attributediagnostic.d(26): which calls `attributediagnostic.layer0` fail_compilation/attributediagnostic.d(28): which calls `attributediagnostic.system` -fail_compilation/attributediagnostic.d(30): which was inferred `@system` because of: +fail_compilation/attributediagnostic.d(30): which wasn't inferred `@safe` because of: fail_compilation/attributediagnostic.d(30): `asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not fail_compilation/attributediagnostic.d(25): `attributediagnostic.layer1` is declared here fail_compilation/attributediagnostic.d(46): Error: `@safe` function `D main` cannot call `@system` function `attributediagnostic.system1` -fail_compilation/attributediagnostic.d(35): which was inferred `@system` because of: +fail_compilation/attributediagnostic.d(35): which wasn't inferred `@safe` because of: fail_compilation/attributediagnostic.d(35): cast from `uint` to `int*` not allowed in safe code fail_compilation/attributediagnostic.d(33): `attributediagnostic.system1` is declared here fail_compilation/attributediagnostic.d(47): Error: `@safe` function `D main` cannot call `@system` function `attributediagnostic.system2` -fail_compilation/attributediagnostic.d(41): which was inferred `@system` because of: +fail_compilation/attributediagnostic.d(41): which wasn't inferred `@safe` because of: fail_compilation/attributediagnostic.d(41): `@safe` function `system2` cannot call `@system` `fsys` fail_compilation/attributediagnostic.d(39): `attributediagnostic.system2` is declared here --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nogc.d b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nogc.d new file mode 100644 index 0000000..e3dbee8 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nogc.d @@ -0,0 +1,56 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/attributediagnostic_nogc.d(21): Error: `@nogc` function `attributediagnostic_nogc.layer2` cannot call non-@nogc function `attributediagnostic_nogc.layer1` +fail_compilation/attributediagnostic_nogc.d(22): which calls `attributediagnostic_nogc.layer0` +fail_compilation/attributediagnostic_nogc.d(23): which calls `attributediagnostic_nogc.gc` +fail_compilation/attributediagnostic_nogc.d(27): which wasn't inferred `@nogc` because of: +fail_compilation/attributediagnostic_nogc.d(27): `asm` statement in function `attributediagnostic_nogc.gc` is assumed to use the GC - mark it with `@nogc` if it does not +fail_compilation/attributediagnostic_nogc.d(43): Error: `@nogc` function `D main` cannot call non-@nogc function `attributediagnostic_nogc.gc1` +fail_compilation/attributediagnostic_nogc.d(32): which wasn't inferred `@nogc` because of: +fail_compilation/attributediagnostic_nogc.d(32): cannot use `new` in `@nogc` function `attributediagnostic_nogc.gc1` +fail_compilation/attributediagnostic_nogc.d(44): Error: `@nogc` function `D main` cannot call non-@nogc function `attributediagnostic_nogc.gc2` +fail_compilation/attributediagnostic_nogc.d(38): which wasn't inferred `@nogc` because of: +fail_compilation/attributediagnostic_nogc.d(38): `@nogc` function `attributediagnostic_nogc.gc2` cannot call non-@nogc `fgc` +fail_compilation/attributediagnostic_nogc.d(45): Error: `@nogc` function `D main` cannot call non-@nogc function `attributediagnostic_nogc.gcClosure` +fail_compilation/attributediagnostic_nogc.d(48): which wasn't inferred `@nogc` because of: +fail_compilation/attributediagnostic_nogc.d(48): function `attributediagnostic_nogc.gcClosure` is `@nogc` yet allocates closure for `gcClosure()` with the GC +--- +*/ +#line 18 +// Issue 17374 - Improve inferred attribute error message +// https://issues.dlang.org/show_bug.cgi?id=17374 + +auto layer2() @nogc { layer1(); } +auto layer1() { layer0(); } +auto layer0() { gc(); } + +auto gc() +{ + asm {} +} + +auto gc1() +{ + int* x = new int; +} + +auto fgc = function void() {new int[10];}; +auto gc2() +{ + fgc(); +} + +void main() @nogc +{ + gc1(); + gc2(); + gcClosure(); +} + +auto gcClosure() +{ + int x; + int bar() { return x; } + return &bar; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nothrow.d b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nothrow.d new file mode 100644 index 0000000..7fea322 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nothrow.d @@ -0,0 +1,45 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/attributediagnostic_nothrow.d(21): Error: function `attributediagnostic_nothrow.layer1` is not `nothrow` +fail_compilation/attributediagnostic_nothrow.d(22): which calls `attributediagnostic_nothrow.layer0` +fail_compilation/attributediagnostic_nothrow.d(23): which calls `attributediagnostic_nothrow.gc` +fail_compilation/attributediagnostic_nothrow.d(27): which wasn't inferred `nothrow` because of: +fail_compilation/attributediagnostic_nothrow.d(27): `asm` statement is assumed to throw - mark it with `nothrow` if it does not +fail_compilation/attributediagnostic_nothrow.d(21): Error: function `attributediagnostic_nothrow.layer2` may throw but is marked as `nothrow` +fail_compilation/attributediagnostic_nothrow.d(43): Error: function `attributediagnostic_nothrow.gc1` is not `nothrow` +fail_compilation/attributediagnostic_nothrow.d(32): which wasn't inferred `nothrow` because of: +fail_compilation/attributediagnostic_nothrow.d(32): `object.Exception` is thrown but not caught +fail_compilation/attributediagnostic_nothrow.d(44): Error: function `attributediagnostic_nothrow.gc2` is not `nothrow` +fail_compilation/attributediagnostic_nothrow.d(41): Error: function `D main` may throw but is marked as `nothrow` +--- +*/ + +// Issue 17374 - Improve inferred attribute error message +// https://issues.dlang.org/show_bug.cgi?id=17374 + +auto layer2() nothrow { layer1(); } +auto layer1() { layer0(); } +auto layer0() { gc(); } + +auto gc() +{ + asm {} +} + +auto gc1() +{ + throw new Exception("msg"); +} + +auto fgc = function void() {throw new Exception("msg");}; +auto gc2() +{ + fgc(); +} + +void main() nothrow +{ + gc1(); + gc2(); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_pure.d b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_pure.d new file mode 100644 index 0000000..a120dab --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_pure.d @@ -0,0 +1,21 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/attributediagnostic_pure.d(20): Error: `pure` function `D main` cannot call impure function `attributediagnostic_pure.gc` +fail_compilation/attributediagnostic_pure.d(15): which wasn't inferred `pure` because of: +fail_compilation/attributediagnostic_pure.d(15): `asm` statement is assumed to be impure - mark it with `pure` if it is not +--- +*/ + +// Issue 17374 - Improve inferred attribute error message +// https://issues.dlang.org/show_bug.cgi?id=17374 + +auto gc() +{ + asm {} +} + +void main() pure +{ + gc(); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d index c980d76..802d1c2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d +++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d @@ -66,8 +66,8 @@ fail_compilation/bug9631.d(79): Error: function `bug9631.arg.f(int i, S s)` is n fail_compilation/bug9631.d(79): cannot pass argument `y` of type `bug9631.tem!().S` to parameter `bug9631.S s` fail_compilation/bug9631.d(80): Error: function literal `__lambda4(S s)` is not callable using argument types `(S)` fail_compilation/bug9631.d(80): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S s` -fail_compilation/bug9631.d(86): Error: constructor `bug9631.arg.A.this(S _param_0)` is not callable using argument types `(S)` -fail_compilation/bug9631.d(86): cannot pass argument `S(0)` of type `bug9631.tem!().S` to parameter `bug9631.S _param_0` +fail_compilation/bug9631.d(86): Error: constructor `bug9631.arg.A.this(S __param_0)` is not callable using argument types `(S)` +fail_compilation/bug9631.d(86): cannot pass argument `S(0)` of type `bug9631.tem!().S` to parameter `bug9631.S __param_0` --- */ void arg() @@ -89,8 +89,8 @@ void arg() /* TEST_OUTPUT: --- -fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S _param_0)` is not callable using argument types `(S)` -fail_compilation/bug9631.d(106): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S _param_0` +fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S __param_0)` is not callable using argument types `(S)` +fail_compilation/bug9631.d(106): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S __param_0` fail_compilation/bug9631.d(107): Error: none of the overloads of template `bug9631.targ.ft` are callable using argument types `!()(S)` fail_compilation/bug9631.d(105): Candidate is: `ft()(tem!().S)` fail_compilation/bug9631.d(109): Error: none of the overloads of template `bug9631.targ.ft2` are callable using argument types `!()(S, int)` diff --git a/gcc/testsuite/gdc.test/fail_compilation/ctfeblock.d b/gcc/testsuite/gdc.test/fail_compilation/ctfeblock.d index 2d8bf7a..9c90103 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ctfeblock.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ctfeblock.d @@ -19,7 +19,7 @@ struct T { } { L1: new T(); - a = 3; + a = 3; } goto L1; } @@ -31,3 +31,14 @@ L1: new T(); } } + +@nogc void test3() +{ + if (!__ctfe) + { + } + else + { + int* p = new int; + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecatedinref.d b/gcc/testsuite/gdc.test/fail_compilation/deprecatedinref.d new file mode 100644 index 0000000..20c3666 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/deprecatedinref.d @@ -0,0 +1,10 @@ +/* +REQUIRED_ARGS: -de +TEST_OUTPUT: +--- +fail_compilation/deprecatedinref.d(9): Deprecation: using `in ref` is deprecated, use `-preview=in` and `in` instead +fail_compilation/deprecatedinref.d(10): Deprecation: using `ref in` is deprecated, use `-preview=in` and `in` instead +--- +*/ +void foo(in ref int); +void foor(ref in int); diff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecations_preview_in.d b/gcc/testsuite/gdc.test/fail_compilation/deprecations_preview_in.d new file mode 100644 index 0000000..33cc904 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/deprecations_preview_in.d @@ -0,0 +1,11 @@ +/* +REQUIRED_ARGS: -de +TEST_OUTPUT: +--- +fail_compilation/deprecations_preview_in.d(1): Deprecation: using `in` parameters with `extern(C)` functions is deprecated +fail_compilation/deprecations_preview_in.d(1): parameter `__anonymous_param` declared as `in` here +--- +*/ + +#line 1 +extern(C) void fun1(in char*); diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10319.d b/gcc/testsuite/gdc.test/fail_compilation/diag10319.d index 7b2eca7..efc818f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag10319.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag10319.d @@ -1,17 +1,21 @@ /* TEST_OUTPUT: --- -fail_compilation/diag10319.d(29): Error: `pure` function `D main` cannot call impure function `diag10319.foo` -fail_compilation/diag10319.d(29): Error: `@safe` function `D main` cannot call `@system` function `diag10319.foo` -fail_compilation/diag10319.d(18): `diag10319.foo` is declared here -fail_compilation/diag10319.d(30): Error: `pure` function `D main` cannot call impure function `diag10319.bar!int.bar` -fail_compilation/diag10319.d(30): Error: `@safe` function `D main` cannot call `@system` function `diag10319.bar!int.bar` -fail_compilation/diag10319.d(23): which was inferred `@system` because of: -fail_compilation/diag10319.d(23): cannot take address of local `x` in `@safe` function `bar` -fail_compilation/diag10319.d(20): `diag10319.bar!int.bar` is declared here -fail_compilation/diag10319.d(29): Error: function `diag10319.foo` is not `nothrow` -fail_compilation/diag10319.d(30): Error: function `diag10319.bar!int.bar` is not `nothrow` -fail_compilation/diag10319.d(27): Error: function `D main` may throw but is marked as `nothrow` +fail_compilation/diag10319.d(33): Error: `pure` function `D main` cannot call impure function `diag10319.foo` +fail_compilation/diag10319.d(33): Error: `@safe` function `D main` cannot call `@system` function `diag10319.foo` +fail_compilation/diag10319.d(22): `diag10319.foo` is declared here +fail_compilation/diag10319.d(34): Error: `pure` function `D main` cannot call impure function `diag10319.bar!int.bar` +fail_compilation/diag10319.d(26): which wasn't inferred `pure` because of: +fail_compilation/diag10319.d(26): `pure` function `diag10319.bar!int.bar` cannot access mutable static data `g` +fail_compilation/diag10319.d(34): Error: `@safe` function `D main` cannot call `@system` function `diag10319.bar!int.bar` +fail_compilation/diag10319.d(27): which wasn't inferred `@safe` because of: +fail_compilation/diag10319.d(27): cannot take address of local `x` in `@safe` function `bar` +fail_compilation/diag10319.d(24): `diag10319.bar!int.bar` is declared here +fail_compilation/diag10319.d(33): Error: function `diag10319.foo` is not `nothrow` +fail_compilation/diag10319.d(34): Error: function `diag10319.bar!int.bar` is not `nothrow` +fail_compilation/diag10319.d(28): which wasn't inferred `nothrow` because of: +fail_compilation/diag10319.d(28): `object.Exception` is thrown but not caught +fail_compilation/diag10319.d(31): Error: function `D main` may throw but is marked as `nothrow` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10415.d b/gcc/testsuite/gdc.test/fail_compilation/diag10415.d index 1fde171..207f6a4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag10415.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag10415.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/diag10415.d(36): Error: none of the overloads of `x` are callable using argument types `(int) const` fail_compilation/diag10415.d(13): Candidates are: `diag10415.C.x()` -fail_compilation/diag10415.d(18): `diag10415.C.x(int _param_0)` +fail_compilation/diag10415.d(18): `diag10415.C.x(int __param_0)` fail_compilation/diag10415.d(39): Error: d.x is not an lvalue --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag11769.d b/gcc/testsuite/gdc.test/fail_compilation/diag11769.d index 2717de4..75047f5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag11769.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag11769.d @@ -2,9 +2,9 @@ TEST_OUTPUT: --- fail_compilation/diag11769.d(18): Error: `diag11769.foo!string.bar` called with argument types `(string)` matches both: -fail_compilation/diag11769.d(13): `diag11769.foo!string.bar(wstring _param_0)` +fail_compilation/diag11769.d(13): `diag11769.foo!string.bar(wstring __param_0)` and: -fail_compilation/diag11769.d(14): `diag11769.foo!string.bar(dstring _param_0)` +fail_compilation/diag11769.d(14): `diag11769.foo!string.bar(dstring __param_0)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14818.d b/gcc/testsuite/gdc.test/fail_compilation/diag14818.d index f9b535a..6147f32 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag14818.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag14818.d @@ -2,8 +2,8 @@ TEST_OUTPUT: --- fail_compilation/diag14818.d(40): Error: none of the overloads of `func` are callable using argument types `(string)` -fail_compilation/diag14818.d(18): Candidates are: `diag14818.foo(int _param_0)` -fail_compilation/diag14818.d(19): `diag14818.bar(double _param_0)` +fail_compilation/diag14818.d(18): Candidates are: `diag14818.foo(int __param_0)` +fail_compilation/diag14818.d(19): `diag14818.bar(double __param_0)` fail_compilation/diag14818.d(41): Error: template instance `diag14818.X!string` does not match any template declaration fail_compilation/diag14818.d(41): Candidates are: fail_compilation/diag14818.d(24): Foo(T) if (is(T == int)) diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag20268.d b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d new file mode 100644 index 0000000..a314561 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=20268 + +/* +TEST_OUTPUT: +--- +fail_compilation/diag20268.d(12): Error: none of the overloads of template `diag20268.__lambda4` are callable using argument types `!()(int)` +fail_compilation/diag20268.d(11): Candidate is: `__lambda4(__T1, __T2)(x, y)` +--- +*/ + +alias f = (x,y) => true; +auto x = f(1); diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d index bc0ee9d..a55ef73 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101b.d @@ -2,13 +2,13 @@ TEST_OUTPUT: --- fail_compilation/diag8101b.d(28): Error: none of the overloads of `foo` are callable using argument types `(double)` -fail_compilation/diag8101b.d(19): Candidates are: `diag8101b.S.foo(int _param_0)` -fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int _param_0, int _param_1)` -fail_compilation/diag8101b.d(30): Error: function `diag8101b.S.bar(int _param_0)` is not callable using argument types `(double)` -fail_compilation/diag8101b.d(30): cannot pass argument `1.0` of type `double` to parameter `int _param_0` +fail_compilation/diag8101b.d(19): Candidates are: `diag8101b.S.foo(int __param_0)` +fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int __param_0, int __param_1)` +fail_compilation/diag8101b.d(30): Error: function `diag8101b.S.bar(int __param_0)` is not callable using argument types `(double)` +fail_compilation/diag8101b.d(30): cannot pass argument `1.0` of type `double` to parameter `int __param_0` fail_compilation/diag8101b.d(33): Error: none of the overloads of `foo` are callable using a `const` object -fail_compilation/diag8101b.d(19): Candidates are: `diag8101b.S.foo(int _param_0)` -fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int _param_0, int _param_1)` +fail_compilation/diag8101b.d(19): Candidates are: `diag8101b.S.foo(int __param_0)` +fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int __param_0, int __param_1)` fail_compilation/diag8101b.d(35): Error: mutable method `diag8101b.S.bar` is not callable using a `const` object fail_compilation/diag8101b.d(22): Consider adding `const` or `inout` here --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9312.d b/gcc/testsuite/gdc.test/fail_compilation/diag9312.d index 94e3d3f..9830813 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag9312.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag9312.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag9312.d(10): Error: `with` expressions must be aggregate types or pointers to them, not `int` +fail_compilation/diag9312.d(10): Error: `with` expression types must be enums or aggregates or pointers to them, not `int` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9620.d b/gcc/testsuite/gdc.test/fail_compilation/diag9620.d index d99290c..4af87df 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag9620.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag9620.d @@ -1,8 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/diag9620.d(18): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo1` -fail_compilation/diag9620.d(19): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo2!().foo2` +fail_compilation/diag9620.d(20): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo1` +fail_compilation/diag9620.d(21): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo2!().foo2` +fail_compilation/diag9620.d(14): which wasn't inferred `pure` because of: +fail_compilation/diag9620.d(14): `pure` function `diag9620.foo2!().foo2` cannot access mutable static data `x` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9831.d b/gcc/testsuite/gdc.test/fail_compilation/diag9831.d index b990ced..c93a06a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag9831.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag9831.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag9831.d(13): Error: function `diag9831.main.__lambda3` cannot access variable `c` in frame of function `D main` +fail_compilation/diag9831.d(13): Error: function `diag9831.main.__lambda3(__T1)(x)` cannot access variable `c` in frame of function `D main` fail_compilation/diag9831.d(11): `c` declared here --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d b/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d index bf51363..6117439 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d +++ b/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d @@ -3,11 +3,11 @@ REQUIRED_ARGS: -de TEST_OUTPUT: --- fail_compilation/dip1000_deprecation.d(20): Deprecation: `@safe` function `main` calling `inferred` -fail_compilation/dip1000_deprecation.d(28): which would be `@system` because of: +fail_compilation/dip1000_deprecation.d(28): which wouldn't be `@safe` because of: fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned fail_compilation/dip1000_deprecation.d(22): Deprecation: `@safe` function `main` calling `inferredC` fail_compilation/dip1000_deprecation.d(39): which calls `dip1000_deprecation.inferred` -fail_compilation/dip1000_deprecation.d(28): which would be `@system` because of: +fail_compilation/dip1000_deprecation.d(28): which wouldn't be `@safe` because of: fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned fail_compilation/dip1000_deprecation.d(54): Deprecation: escaping reference to stack allocated value returned by `S(null)` fail_compilation/dip1000_deprecation.d(55): Deprecation: escaping reference to stack allocated value returned by `createS()` diff --git a/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d b/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d index ce81d6b..21a12ed 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d +++ b/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d @@ -8,8 +8,6 @@ fail_compilation/dtor_attributes.d(113): generated `Strict.~this` is impu fail_compilation/dtor_attributes.d(111): - HasDtor member fail_compilation/dtor_attributes.d(103): impure `HasDtor.~this` is declared here fail_compilation/dtor_attributes.d(118): Error: `@safe` function `dtor_attributes.test1` cannot call `@system` destructor `dtor_attributes.Strict.~this` -fail_compilation/dtor_attributes.d(113): which calls `dtor_attributes.Strict.~this` -fail_compilation/dtor_attributes.d(103): which calls `dtor_attributes.HasDtor.~this` fail_compilation/dtor_attributes.d(113): `dtor_attributes.Strict.~this` is declared here fail_compilation/dtor_attributes.d(113): generated `Strict.~this` is @system because of the following field's destructors: fail_compilation/dtor_attributes.d(111): - HasDtor member diff --git a/gcc/testsuite/gdc.test/fail_compilation/dtorfields_attributes.d b/gcc/testsuite/gdc.test/fail_compilation/dtorfields_attributes.d index 45b23ce..f6cab89 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/dtorfields_attributes.d +++ b/gcc/testsuite/gdc.test/fail_compilation/dtorfields_attributes.d @@ -9,7 +9,6 @@ fail_compilation/dtorfields_attributes.d(119): generated `Strict.~this` i fail_compilation/dtorfields_attributes.d(115): - HasDtor member fail_compilation/dtorfields_attributes.d(103): impure `HasDtor.~this` is declared here fail_compilation/dtorfields_attributes.d(117): Error: `@safe` constructor `dtorfields_attributes.Strict.this` cannot call `@system` destructor `dtorfields_attributes.Strict.~this` -fail_compilation/dtorfields_attributes.d(103): which calls `dtorfields_attributes.HasDtor.~this` fail_compilation/dtorfields_attributes.d(119): `dtorfields_attributes.Strict.~this` is declared here fail_compilation/dtorfields_attributes.d(119): generated `Strict.~this` is @system because of the following field's destructors: fail_compilation/dtorfields_attributes.d(115): - HasDtor member diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d index cfda8f4..a436197 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d @@ -8,10 +8,14 @@ fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arraysetassign!(SA[], SA)._d_arraysetassign` +$p:druntime/import/core/internal/array/arrayassign.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace` +$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit` fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arrayassign_l!(SA[], SA)._d_arrayassign_l` +$p:druntime/import/core/internal/array/arrayassign.d$-mixin-$n$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace` +$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit` fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here @@ -19,13 +23,18 @@ fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot fail_compilation/fail10968.d(49): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor` +$p:druntime/import/core/internal/array/construction.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace` +$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit` fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` fail_compilation/fail10968.d(50): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor` +$p:druntime/import/core/internal/array/construction.d$($n$): which calls `core.lifetime.copyEmplace!(SA, SA).copyEmplace` +$p:druntime/import/core/lifetime.d$($n$): which calls `fail10968.SA.__postblit` --- */ +#line 29 struct SA { this(this) diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11375.d b/gcc/testsuite/gdc.test/fail_compilation/fail11375.d index 7592a5a..cabf87a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail11375.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail11375.d @@ -1,8 +1,9 @@ /* TEST_OUTPUT: --- -fail_compilation/fail11375.d(17): Error: constructor `fail11375.D!().D.this` is not `nothrow` -fail_compilation/fail11375.d(15): Error: function `D main` may throw but is marked as `nothrow` +fail_compilation/fail11375.d(18): Error: constructor `fail11375.D!().D.this` is not `nothrow` + which calls `fail11375.B.this` +fail_compilation/fail11375.d(16): Error: function `D main` may throw but is marked as `nothrow` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12236.d b/gcc/testsuite/gdc.test/fail_compilation/fail12236.d index 738864c..824f5e4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12236.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail12236.d @@ -7,7 +7,7 @@ fail_compilation/fail12236.d(21): Error: forward reference to inferred return ty fail_compilation/fail12236.d(21): while evaluating `pragma(msg, f2(T)(T).mangleof)` fail_compilation/fail12236.d(27): Error: template instance `fail12236.f2!int` error instantiating fail_compilation/fail12236.d(31): Error: forward reference to inferred return type of function `__lambda1` -fail_compilation/fail12236.d(31): while evaluating `pragma(msg, __lambda1.mangleof)` +fail_compilation/fail12236.d(31): while evaluating `pragma(msg, __lambda1(__T1)(a).mangleof)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13120.d b/gcc/testsuite/gdc.test/fail_compilation/fail13120.d index f1cf340..6a1335e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail13120.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail13120.d @@ -17,13 +17,13 @@ void g1(char[] s) pure @nogc TEST_OUTPUT: --- fail_compilation/fail13120.d(35): Error: `pure` function `fail13120.h2` cannot call impure function `fail13120.g2!().g2` +fail_compilation/fail13120.d(30): which calls `fail13120.f2` fail_compilation/fail13120.d(35): Error: `@safe` function `fail13120.h2` cannot call `@system` function `fail13120.g2!().g2` fail_compilation/fail13120.d(27): `fail13120.g2!().g2` is declared here fail_compilation/fail13120.d(35): Error: `@nogc` function `fail13120.h2` cannot call non-@nogc function `fail13120.g2!().g2` --- */ void f2() {} - void g2()(char[] s) { foreach (dchar dc; s) diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13577.d b/gcc/testsuite/gdc.test/fail_compilation/fail13577.d new file mode 100644 index 0000000..79f9068 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail13577.d @@ -0,0 +1,28 @@ +// https://issues.dlang.org/show_bug.cgi?id=13577 + +/* +TEST_OUTPUT: +--- +fail_compilation/fail13577.d(27): Error: cannot implicilty convert range element of type `int[]` to variable `x` of type `immutable(int[])` +--- +*/ + +struct Tuple(Types...) +{ + Types items; + alias items this; +} + +struct Range(T) +{ + T[] arr; + alias ElemType = Tuple!(int, T); + ElemType front() { return typeof(return)(0, arr[0]); } + bool empty() { return false; } + void popFront() {} +} + +void main() +{ + foreach (immutable i, immutable x; Range!(int[])()) {} // Error +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16600.d b/gcc/testsuite/gdc.test/fail_compilation/fail16600.d index eb341c6..3bd600e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail16600.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail16600.d @@ -1,9 +1,9 @@ /* TEST_OUTPUT: --- fail_compilation/fail16600.d(22): Error: `fail16600.S.__ctor` called with argument types `(string) const` matches both: -fail_compilation/fail16600.d(16): `fail16600.S.this(string _param_0)` +fail_compilation/fail16600.d(16): `fail16600.S.this(string __param_0)` and: -fail_compilation/fail16600.d(17): `fail16600.S.this(string _param_0) immutable` +fail_compilation/fail16600.d(17): `fail16600.S.this(string __param_0) immutable` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17518.d b/gcc/testsuite/gdc.test/fail_compilation/fail17518.d index 385483c..cf2648d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17518.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17518.d @@ -1,8 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail17518.d(21): Error: constructor `fail17518.S.this(inout(Correct) _param_0) inout` is not callable using argument types `(Wrong)` -fail_compilation/fail17518.d(21): cannot pass argument `Wrong()` of type `Wrong` to parameter `inout(Correct) _param_0` +fail_compilation/fail17518.d(21): Error: constructor `fail17518.S.this(inout(Correct) __param_0) inout` is not callable using argument types `(Wrong)` +fail_compilation/fail17518.d(21): cannot pass argument `Wrong()` of type `Wrong` to parameter `inout(Correct) __param_0` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17955.d b/gcc/testsuite/gdc.test/fail_compilation/fail17955.d index 95eb5cc..0832919 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17955.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17955.d @@ -11,7 +11,7 @@ fail_compilation/fail17955.d(49): instantiated from here: `toRedis!(SysTi fail_compilation/fail17955.d(40): ... (2 instantiations, -v to show) ... fail_compilation/fail17955.d(32): instantiated from here: `indicesOf!(isRedisType, resetCodeExpireTime)` fail_compilation/fail17955.d(67): instantiated from here: `RedisStripped!(User, true)` -fail_compilation/fail17955.d(93): Error: need `this` for `fromISOExtString` of type `pure nothrow @nogc @safe immutable(SimpleTimeZone)(dstring _param_0)` +fail_compilation/fail17955.d(93): Error: need `this` for `fromISOExtString` of type `pure nothrow @nogc @safe immutable(SimpleTimeZone)(dstring __param_0)` fail_compilation/fail17955.d(95): Error: undefined identifier `DateTimeException` fail_compilation/fail17955.d(25): Error: variable `fail17955.isISOExtStringSerializable!(SysTime).isISOExtStringSerializable` - type `void` is inferred from initializer `fromISOExtString("")`, and variables cannot be of type `void` fail_compilation/fail17955.d(54): Error: function `fail17955.toRedis!(SysTime).toRedis` has no `return` statement, but is expected to return a value of type `string` diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail196.d b/gcc/testsuite/gdc.test/fail_compilation/fail196.d index 2c7d93f..53505f4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail196.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail196.d @@ -6,15 +6,15 @@ fail_compilation/fail196.d(27): Error: implicit string concatenation is error-pr fail_compilation/fail196.d(27): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\n assert(s == " fail_compilation/fail196.d(28): Error: semicolon needed to end declaration of `s`, instead of `foo` fail_compilation/fail196.d(27): `s` declared here -fail_compilation/fail196.d(28): Error: found `");\n\n s = q"` when expecting `;` following statement -fail_compilation/fail196.d(30): Error: found `";\n assert(s == "` when expecting `;` following statement -fail_compilation/fail196.d(31): Error: found `");\n\n s = q"` when expecting `;` following statement -fail_compilation/fail196.d(33): Error: found `{` when expecting `;` following statement -fail_compilation/fail196.d(33): Error: found `}` when expecting `;` following statement -fail_compilation/fail196.d(34): Error: found `foo` when expecting `;` following statement -fail_compilation/fail196.d(34): Error: found `}` when expecting `;` following statement -fail_compilation/fail196.d(36): Error: found `<` when expecting `;` following statement -fail_compilation/fail196.d(37): Error: found `foo` when expecting `;` following statement +fail_compilation/fail196.d(28): Error: found `");\n\n s = q"` when expecting `;` following statement `foo(xxx)` on line fail_compilation/fail196.d(28) +fail_compilation/fail196.d(30): Error: found `";\n assert(s == "` when expecting `;` following statement `[foo[xxx]]` on line fail_compilation/fail196.d(30) +fail_compilation/fail196.d(31): Error: found `");\n\n s = q"` when expecting `;` following statement `foo[xxx]` on line fail_compilation/fail196.d(31) +fail_compilation/fail196.d(33): Error: found `{` when expecting `;` following statement `foo` on line fail_compilation/fail196.d(33) +fail_compilation/fail196.d(33): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(33) +fail_compilation/fail196.d(34): Error: found `foo` when expecting `;` following statement `";\n assert(s == "` on line fail_compilation/fail196.d(33) +fail_compilation/fail196.d(34): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(34) +fail_compilation/fail196.d(36): Error: found `<` when expecting `;` following statement `");\n\n s = q" < foo` on line fail_compilation/fail196.d(34) +fail_compilation/fail196.d(37): Error: found `foo` when expecting `;` following statement `xxx >> ";\n assert(s == "` on line fail_compilation/fail196.d(36) fail_compilation/fail196.d(37): Error: found `<` instead of statement fail_compilation/fail196.d(43): Error: unterminated string constant starting at fail_compilation/fail196.d(43) fail_compilation/fail196.d(45): Error: found `End of File` when expecting `}` following compound statement diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19948.d b/gcc/testsuite/gdc.test/fail_compilation/fail19948.d index e8a9e77..ae67443 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19948.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19948.d @@ -1,5 +1,5 @@ // https://issues.dlang.org/show_bug.cgi?id=19948 - +// DISABLED: win32 /* TEST_OUTPUT: --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20609.d b/gcc/testsuite/gdc.test/fail_compilation/fail20609.d index 05b7c85..80a5d46 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail20609.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail20609.d @@ -4,7 +4,7 @@ fail_compilation/fail20609.d(26): Error: none of the overloads of `this` are callable using argument types `(int)` fail_compilation/fail20609.d(23): Candidate is: `fail20609.Foo.this(string[] args)` fail_compilation/fail20609.d(27): Error: none of the overloads of `this` are callable using argument types `(int)` -fail_compilation/fail20609.d(22): Candidates are: `fail20609.Foo.this(Object _param_0)` +fail_compilation/fail20609.d(22): Candidates are: `fail20609.Foo.this(Object __param_0)` fail_compilation/fail20609.d(23): `fail20609.Foo.this(string[] args)` fail_compilation/fail20609.d(37): Error: none of the overloads of `this` are callable using argument types `(int)` fail_compilation/fail20609.d(37): All possible candidates are marked as `deprecated` or `@disable` diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22202.d b/gcc/testsuite/gdc.test/fail_compilation/fail22202.d index 167d362..d865fd9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail22202.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22202.d @@ -3,7 +3,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail22202.d(21): Error: function `fail22202.fun(SystemCopy _param_0)` is not callable using argument types `(SystemCopy)` +fail_compilation/fail22202.d(21): Error: function `fail22202.fun(SystemCopy __param_0)` is not callable using argument types `(SystemCopy)` fail_compilation/fail22202.d(21): `inout ref inout(SystemCopy)(ref inout(SystemCopy) other)` copy constructor cannot be called from a `pure @safe nogc` context --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23773.d b/gcc/testsuite/gdc.test/fail_compilation/fail23773.d new file mode 100644 index 0000000..e6cdc3e --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23773.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=23773 + +/* +TEST_OUTPUT: +--- +fail_compilation/fail23773.d(14): Error: assignment cannot be used as a condition, perhaps `==` was meant? +--- +*/ + +void main() +{ + int i; + int[] arr; + assert(arr.length = i); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23822.d b/gcc/testsuite/gdc.test/fail_compilation/fail23822.d new file mode 100644 index 0000000..5cdd1fe --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23822.d @@ -0,0 +1,22 @@ +// https://issues.dlang.org/show_bug.cgi?id=23822 + +// REQUIRED_ARGS: -de + +/* +TEST_OUTPUT: +--- +fail_compilation/fail23822.d(21): Deprecation: alias `fail23822.S.value` is deprecated +--- +*/ + +alias Alias(alias A) = A; + +struct S +{ + deprecated alias value = Alias!5; +} + +void main() +{ + auto a = S.value; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23826.d b/gcc/testsuite/gdc.test/fail_compilation/fail23826.d new file mode 100644 index 0000000..3db243a --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23826.d @@ -0,0 +1,24 @@ +// https://issues.dlang.org/show_bug.cgi?id=23826 + +// REQUIRED_ARGS: -de + +/* +TEST_OUTPUT: +--- +fail_compilation/fail23826.d(23): Deprecation: alias `fail23826.S.value` is deprecated +--- +*/ + +alias Alias(alias A) = A; + +class S +{ + deprecated alias value = Alias!5; +} + +enum identity(alias A) = A; + +void main() +{ + auto a = identity!(S.value); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23861.d b/gcc/testsuite/gdc.test/fail_compilation/fail23861.d new file mode 100644 index 0000000..23c5407 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23861.d @@ -0,0 +1,25 @@ +// https://issues.dlang.org/show_bug.cgi?id=23861 + +/* +TEST_OUTPUT: +--- +fail_compilation/fail23861.d(24): Error: cannot implicitly convert expression `3` of type `int` to `Foo` +--- +*/ + +Foo global; + +struct Foo +{ + ref Foo get() + { + return global; + } + alias get this; +} + +void main() +{ + Foo g; + g = 3; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail332.d b/gcc/testsuite/gdc.test/fail_compilation/fail332.d index 91f8046..77e8cd8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail332.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail332.d @@ -1,14 +1,14 @@ /* TEST_OUTPUT: --- -fail_compilation/fail332.d(22): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `()` -fail_compilation/fail332.d(22): missing argument for parameter #1: `int _param_0` -fail_compilation/fail332.d(23): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `(typeof(null))` -fail_compilation/fail332.d(23): cannot pass argument `null` of type `typeof(null)` to parameter `int _param_0` -fail_compilation/fail332.d(25): Error: function `fail332.baz(int[] _param_0...)` is not callable using argument types `(string)` -fail_compilation/fail332.d(25): cannot pass argument `""` of type `string` to parameter `int[] _param_0...` -fail_compilation/fail332.d(26): Error: function `fail332.baz(int[] _param_0...)` is not callable using argument types `(int, typeof(null))` -fail_compilation/fail332.d(26): cannot pass argument `null` of type `typeof(null)` to parameter `int[] _param_0...` +fail_compilation/fail332.d(22): Error: function `fail332.foo(int __param_0, ...)` is not callable using argument types `()` +fail_compilation/fail332.d(22): missing argument for parameter #1: `int __param_0` +fail_compilation/fail332.d(23): Error: function `fail332.foo(int __param_0, ...)` is not callable using argument types `(typeof(null))` +fail_compilation/fail332.d(23): cannot pass argument `null` of type `typeof(null)` to parameter `int __param_0` +fail_compilation/fail332.d(25): Error: function `fail332.baz(int[] __param_0...)` is not callable using argument types `(string)` +fail_compilation/fail332.d(25): cannot pass argument `""` of type `string` to parameter `int[] __param_0...` +fail_compilation/fail332.d(26): Error: function `fail332.baz(int[] __param_0...)` is not callable using argument types `(int, typeof(null))` +fail_compilation/fail332.d(26): cannot pass argument `null` of type `typeof(null)` to parameter `int[] __param_0...` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d index b02fbb1..f57e746 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d @@ -4,7 +4,7 @@ TEST_OUTPUT: --- fail_compilation/fail4375q.d(17): Warning: else is dangling, add { } after condition at fail_compilation/fail4375q.d(13) -fail_compilation/fail4375q.d(14): Error: `with` expressions must be aggregate types or pointers to them, not `int` +fail_compilation/fail4375q.d(14): Error: `with` expression types must be enums or aggregates or pointers to them, not `int` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4559.d b/gcc/testsuite/gdc.test/fail_compilation/fail4559.d index 0101ae9..657c184 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4559.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4559.d @@ -1,10 +1,10 @@ /* -REQUIRED_ARGS: -o- -de +REQUIRED_ARGS: TEST_OUTPUT: --- -fail_compilation/fail4559.d(13): Deprecation: use `{ }` for an empty statement, not `;` -fail_compilation/fail4559.d(19): Deprecation: use `{ }` for an empty statement, not `;` -fail_compilation/fail4559.d(21): Deprecation: use `{ }` for an empty statement, not `;` +fail_compilation/fail4559.d(13): Error: use `{ }` for an empty statement, not `;` +fail_compilation/fail4559.d(19): Error: use `{ }` for an empty statement, not `;` +fail_compilation/fail4559.d(21): Error: use `{ }` for an empty statement, not `;` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_typeof.d b/gcc/testsuite/gdc.test/fail_compilation/fail_typeof.d index 392cebd..a3b4d1a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail_typeof.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail_typeof.d @@ -1,17 +1,14 @@ /* TEST_OUTPUT: --- -fail_compilation/fail_typeof.d(18): Error: undefined identifier `this` -fail_compilation/fail_typeof.d(23): Error: `this` is not in a class or struct scope -fail_compilation/fail_typeof.d(23): Error: `this` is only defined in non-static member functions, not `fail_typeof` -fail_compilation/fail_typeof.d(28): Error: undefined identifier `super` -fail_compilation/fail_typeof.d(33): Error: `super` is not in a class scope -fail_compilation/fail_typeof.d(33): Error: `super` is only allowed in non-static class member functions -fail_compilation/fail_typeof.d(40): Error: undefined identifier `this`, did you mean `typeof(this)`? -fail_compilation/fail_typeof.d(50): Error: undefined identifier `super` -fail_compilation/fail_typeof.d(55): Error: `super` is not in a class scope -fail_compilation/fail_typeof.d(55): Error: `super` is only allowed in non-static class member functions -fail_compilation/fail_typeof.d(63): Error: undefined identifier `this`, did you mean `typeof(this)`? -fail_compilation/fail_typeof.d(73): Error: undefined identifier `super`, did you mean `typeof(super)`? +fail_compilation/fail_typeof.d(15): Error: undefined identifier `this` +fail_compilation/fail_typeof.d(20): Error: `this` is not in a class or struct scope +fail_compilation/fail_typeof.d(25): Error: undefined identifier `super` +fail_compilation/fail_typeof.d(30): Error: `super` is not in a class scope +fail_compilation/fail_typeof.d(37): Error: undefined identifier `this`, did you mean `typeof(this)`? +fail_compilation/fail_typeof.d(47): Error: undefined identifier `super` +fail_compilation/fail_typeof.d(52): Error: `super` is not in a class scope +fail_compilation/fail_typeof.d(60): Error: undefined identifier `this`, did you mean `typeof(this)`? +fail_compilation/fail_typeof.d(70): Error: undefined identifier `super`, did you mean `typeof(super)`? --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10651.d b/gcc/testsuite/gdc.test/fail_compilation/ice10651.d index 1f87955..8b6c720 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice10651.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice10651.d @@ -1,7 +1,9 @@ /* TEST_OUTPUT: --- -fail_compilation/ice10651.d(11): Error: can only throw class objects derived from `Throwable`, not type `int*` +fail_compilation/ice10651.d(13): Error: can only throw class objects derived from `Throwable`, not type `int*` +fail_compilation/ice10651.d(19): Deprecation: cannot throw object of qualified type `immutable(Exception)` +fail_compilation/ice10651.d(20): Deprecation: cannot throw object of qualified type `const(Dummy)` --- */ @@ -10,3 +12,20 @@ void main() alias T = int; throw new T(); // ICE } + +void f() +{ + immutable c = new Exception(""); + if (c) throw c; + throw new const Dummy([]); +} + +class Dummy: Exception +{ + int[] data; + @safe pure nothrow this(immutable int[] data) immutable + { + super("Dummy"); + this.data = data; + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11626.d b/gcc/testsuite/gdc.test/fail_compilation/ice11626.d index 5dc5d5c..6d347bc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice11626.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice11626.d @@ -5,4 +5,4 @@ fail_compilation/ice11626.d(8): Error: undefined identifier `Bar` --- */ -void foo(in ref Bar) {} +void foo(const ref Bar) {} diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11982.d b/gcc/testsuite/gdc.test/fail_compilation/ice11982.d index ff5fae4..0f2ce41 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice11982.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice11982.d @@ -1,16 +1,19 @@ /* TEST_OUTPUT: --- -fail_compilation/ice11982.d(16): Error: basic type expected, not `scope` -fail_compilation/ice11982.d(16): Error: found `scope` when expecting `;` following statement -fail_compilation/ice11982.d(16): Error: basic type expected, not `}` -fail_compilation/ice11982.d(16): Error: missing `{ ... }` for function literal -fail_compilation/ice11982.d(16): Error: C style cast illegal, use `cast(funk)function _error_() +fail_compilation/ice11982.d(19): Error: basic type expected, not `scope` +fail_compilation/ice11982.d(19): Error: found `scope` when expecting `;` following statement `new _error_` on line fail_compilation/ice11982.d(19) +fail_compilation/ice11982.d(19): Error: basic type expected, not `}` +fail_compilation/ice11982.d(19): Error: missing `{ ... }` for function literal +fail_compilation/ice11982.d(19): Error: C style cast illegal, use `cast(funk)function _error_() { } ` -fail_compilation/ice11982.d(16): Error: found `}` when expecting `;` following statement -fail_compilation/ice11982.d(17): Error: found `End of File` when expecting `}` following compound statement +fail_compilation/ice11982.d(19): Error: found `}` when expecting `;` following statement `cast(funk)function _error_() +{ +} +` on line fail_compilation/ice11982.d(19) +fail_compilation/ice11982.d(20): Error: found `End of File` when expecting `}` following compound statement --- */ void main() { new scope ( funk ) function } diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice13225.d b/gcc/testsuite/gdc.test/fail_compilation/ice13225.d index 6988cd7..abc30ea 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice13225.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice13225.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/ice13225.d(12): Error: mixin `ice13225.S.M!(function (S _param_0) pure nothrow @nogc @safe => 0)` does not match template declaration `M(T)` +fail_compilation/ice13225.d(12): Error: mixin `ice13225.S.M!(function (S __param_0) pure nothrow @nogc @safe => 0)` does not match template declaration `M(T)` fail_compilation/ice13225.d(16): Error: undefined identifier `undefined` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23097.d b/gcc/testsuite/gdc.test/fail_compilation/ice23097.d index 4fd1f61..90cf03f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice23097.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice23097.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/ice23097.d(12): Error: undefined identifier `ICE` fail_compilation/ice23097.d(27): Error: template instance `ice23097.ice23097!(S23097)` error instantiating -fail_compilation/ice23097.d(27): Error: function `ice23097.ice23097!(S23097).ice23097(S23097 _param_0)` is not callable using argument types `(S23097)` +fail_compilation/ice23097.d(27): Error: function `ice23097.ice23097!(S23097).ice23097(S23097 __param_0)` is not callable using argument types `(S23097)` fail_compilation/ice23097.d(27): generating a copy constructor for `struct S23097` failed, therefore instances of it are uncopyable --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9540.d b/gcc/testsuite/gdc.test/fail_compilation/ice9540.d index 5276e83..456d3e12 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9540.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9540.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/ice9540.d(35): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int _param_0)` is not callable using argument types `()` +fail_compilation/ice9540.d(35): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int __param_0)` is not callable using argument types `()` fail_compilation/ice9540.d(35): too few arguments, expected 1, got 0 fail_compilation/ice9540.d(26): Error: template instance `ice9540.A.test.AddFront!(this, f)` error instantiating --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d index 11fddf0..d136144 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d @@ -23,7 +23,7 @@ fail_compilation/misc_parser_err_cov1.d(40): Error: semicolon expected following fail_compilation/misc_parser_err_cov1.d(40): Error: identifier or `new` expected following `.`, not `+` fail_compilation/misc_parser_err_cov1.d(41): Error: identifier or new keyword expected following `(...)`. fail_compilation/misc_parser_err_cov1.d(41): Error: expression expected, not `;` -fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following statement +fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following statement `(__error) + 0` on line fail_compilation/misc_parser_err_cov1.d(41) fail_compilation/misc_parser_err_cov1.d(43): Error: found `End of File` when expecting `}` following compound statement --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_parse.d b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_parse.d index 19e230e..096c499 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_parse.d +++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_parse.d @@ -1,13 +1,13 @@ /** TEST_OUTPUT: --- -fail_compilation/named_arguments_parse.d(10): Error: named arguments not allowed here fail_compilation/named_arguments_parse.d(13): Error: named arguments not allowed here fail_compilation/named_arguments_parse.d(14): Error: named arguments not allowed here --- */ -@(attribute: 3) + +// @(attribute: 3) Currently gives an ugly parse error, will be better when named template arguments are implemented void main() { mixin(thecode: "{}"); diff --git a/gcc/testsuite/gdc.test/fail_compilation/parseStc.d b/gcc/testsuite/gdc.test/fail_compilation/parseStc.d index c9c4288..d13006d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/parseStc.d +++ b/gcc/testsuite/gdc.test/fail_compilation/parseStc.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/parseStc.d(12): Error: missing closing `)` after `if (x` fail_compilation/parseStc.d(12): Error: use `{ }` for an empty statement, not `;` -fail_compilation/parseStc.d(12): Error: found `)` when expecting `;` following statement +fail_compilation/parseStc.d(12): Error: found `)` when expecting `;` following statement `1` on line fail_compilation/parseStc.d(12) fail_compilation/parseStc.d(13): Error: redundant attribute `const` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/previewin.d b/gcc/testsuite/gdc.test/fail_compilation/previewin.d index ca54093..d0e97c8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/previewin.d +++ b/gcc/testsuite/gdc.test/fail_compilation/previewin.d @@ -4,10 +4,10 @@ TEST_OUTPUT: --- fail_compilation/previewin.d(4): Error: function `previewin.takeFunction(void function(in real) f)` is not callable using argument types `(void function(real x) pure nothrow @nogc @safe)` fail_compilation/previewin.d(4): cannot pass argument `__lambda1` of type `void function(real x) pure nothrow @nogc @safe` to parameter `void function(in real) f` -fail_compilation/previewin.d(5): Error: function `previewin.takeFunction(void function(in real) f)` is not callable using argument types `(void function(const(real) x) pure nothrow @nogc @safe)` -fail_compilation/previewin.d(5): cannot pass argument `__lambda2` of type `void function(const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f` -fail_compilation/previewin.d(6): Error: function `previewin.takeFunction(void function(in real) f)` is not callable using argument types `(void function(ref const(real) x) pure nothrow @nogc @safe)` -fail_compilation/previewin.d(6): cannot pass argument `__lambda3` of type `void function(ref const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f` +fail_compilation/previewin.d(5): Error: function `previewin.takeFunction(void function(in real) f)` is not callable using argument types `(void function(scope const(real) x) pure nothrow @nogc @safe)` +fail_compilation/previewin.d(5): cannot pass argument `__lambda2` of type `void function(scope const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f` +fail_compilation/previewin.d(6): Error: function `previewin.takeFunction(void function(in real) f)` is not callable using argument types `(void function(ref scope const(real) x) pure nothrow @nogc @safe)` +fail_compilation/previewin.d(6): cannot pass argument `__lambda3` of type `void function(ref scope const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f` fail_compilation/previewin.d(15): Error: scope variable `arg` assigned to global variable `myGlobal` fail_compilation/previewin.d(16): Error: scope variable `arg` assigned to global variable `myGlobal` fail_compilation/previewin.d(17): Error: scope parameter `arg` may not be returned diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d index 829fb6a..2e7940f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d @@ -86,8 +86,8 @@ fail_compilation/retscope2.d(504): Error: scope variable `c` may not be returned /* TEST_OUTPUT: --- -fail_compilation/retscope2.d(604): Error: scope variable `_param_0` assigned to non-scope anonymous parameter calling `foo600` -fail_compilation/retscope2.d(604): Error: scope variable `_param_1` assigned to non-scope anonymous parameter calling `foo600` +fail_compilation/retscope2.d(604): Error: scope variable `__param_0` assigned to non-scope anonymous parameter calling `foo600` +fail_compilation/retscope2.d(604): Error: scope variable `__param_1` assigned to non-scope anonymous parameter calling `foo600` fail_compilation/retscope2.d(614): Error: template instance `retscope2.test600!(int*, int*)` error instantiating --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d index 5c581d1..ddeae81 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d @@ -25,7 +25,7 @@ int* test() @safe --- fail_compilation/retscope6.d(7034): Error: address of variable `i` assigned to `s` with longer lifetime fail_compilation/retscope6.d(7035): Error: address of variable `i` assigned to `s` with longer lifetime -fail_compilation/retscope6.d(7025): Error: scope variable `_param_2` assigned to `ref` variable `t` with longer lifetime +fail_compilation/retscope6.d(7025): Error: scope variable `__param_2` assigned to `ref` variable `t` with longer lifetime fail_compilation/retscope6.d(7037): Error: template instance `retscope6.S.emplace4!(int*)` error instantiating fail_compilation/retscope6.d(7037): Error: address of variable `i` assigned to `s` with longer lifetime --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d index 75dbe2d..b511535 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d +++ b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d @@ -4,7 +4,7 @@ TEST_OUTPUT: --- fail_compilation/systemvariables_deprecation.d(16): Deprecation: `@safe` function `main` calling `middle` fail_compilation/systemvariables_deprecation.d(21): which calls `systemvariables_deprecation.inferred` -fail_compilation/systemvariables_deprecation.d(27): which would be `@system` because of: +fail_compilation/systemvariables_deprecation.d(27): which wouldn't be `@safe` because of: fail_compilation/systemvariables_deprecation.d(27): cannot access `@system` variable `x0` in @safe code --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/testInference.d b/gcc/testsuite/gdc.test/fail_compilation/testInference.d index c0d5a05..145fc9e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/testInference.d +++ b/gcc/testsuite/gdc.test/fail_compilation/testInference.d @@ -138,8 +138,13 @@ immutable(void)* g10063(inout int* p) pure TEST_OUTPUT: --- fail_compilation/testInference.d(154): Error: `pure` function `testInference.bar14049` cannot call impure function `testInference.foo14049!int.foo14049` +fail_compilation/testInference.d(149): which calls `testInference.foo14049!int.foo14049.__lambda2` +fail_compilation/testInference.d(148): which calls `testInference.impure14049` +fail_compilation/testInference.d(143): which wasn't inferred `pure` because of: +fail_compilation/testInference.d(143): `pure` function `testInference.impure14049` cannot access mutable static data `i` --- */ +#line 143 auto impure14049() { static int i = 1; return i; } void foo14049(T)(T val) @@ -170,8 +175,10 @@ int* f14160() pure TEST_OUTPUT: --- fail_compilation/testInference.d(180): Error: `pure` function `testInference.test12422` cannot call impure function `testInference.test12422.bar12422!().bar12422` +fail_compilation/testInference.d(179): which calls `testInference.foo12422` --- */ +#line 175 int g12422; void foo12422() { ++g12422; } void test12422() pure @@ -184,9 +191,15 @@ void test12422() pure TEST_OUTPUT: --- fail_compilation/testInference.d(198): Error: `pure` function `testInference.test13729a` cannot call impure function `testInference.test13729a.foo` +fail_compilation/testInference.d(196): which wasn't inferred `pure` because of: +fail_compilation/testInference.d(196): `pure` function `testInference.test13729a.foo` cannot access mutable static data `g13729` fail_compilation/testInference.d(206): Error: `pure` function `testInference.test13729b` cannot call impure function `testInference.test13729b.foo!().foo` +fail_compilation/testInference.d(204): which wasn't inferred `pure` because of: +fail_compilation/testInference.d(204): `pure` function `testInference.test13729b.foo!().foo` cannot access mutable static data `g13729` --- */ + +#line 190 int g13729; void test13729a() pure @@ -229,8 +242,10 @@ void test17086_call () TEST_OUTPUT: --- fail_compilation/testInference.d(238): Error: `pure` function `testInference.test20047_pure_function` cannot call impure function `testInference.test20047_pure_function.bug` +fail_compilation/testInference.d(237): which calls `testInference.test20047_impure_function` --- */ +#line 234 void test20047_impure_function() {} void test20047_pure_function() pure { diff --git a/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d b/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d index 96511f5..50cebab 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d +++ b/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d @@ -6,7 +6,7 @@ TEST_OUTPUT: fail_compilation/testrvaluecpctor.d(16): Error: cannot define both an rvalue constructor and a copy constructor for `struct Foo` fail_compilation/testrvaluecpctor.d(24): Template instance `testrvaluecpctor.Foo!int.Foo.__ctor!(immutable(Foo!int), immutable(Foo!int))` creates an rvalue constructor for `struct Foo` fail_compilation/testrvaluecpctor.d(24): Error: none of the overloads of `__ctor` are callable using a `immutable` object -fail_compilation/testrvaluecpctor.d(18): Candidates are: `testrvaluecpctor.Foo!int.Foo.this(ref Foo!int rhs)` +fail_compilation/testrvaluecpctor.d(18): Candidates are: `testrvaluecpctor.Foo!int.Foo.this(ref scope Foo!int rhs)` fail_compilation/testrvaluecpctor.d(16): `__ctor(Rhs, this This)(scope Rhs rhs)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/var_func_attr.d b/gcc/testsuite/gdc.test/fail_compilation/var_func_attr.d new file mode 100644 index 0000000..8609d29 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/var_func_attr.d @@ -0,0 +1,35 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/var_func_attr.d(19): Error: cannot implicitly convert expression `__lambda8` of type `void function() nothrow @nogc @safe` to `void function() pure` +--- +*/ + +// Test the effect of function attributes on variables +// See: +// https://issues.dlang.org/show_bug.cgi?id=7432 +// https://github.com/dlang/dmd/pull/14199 +// Usually it's a no-op, but the attribute can apply to the function/delegate type of the variable +// The current behavior is weird, so this is a test of the current behavior, not necessarily the desired behavior + +// No-op +pure int x; + +// Applies to function type (existing code in dmd and Phobos relies on this) +pure void function() pf = () { + static int g; + g++; +}; + +// Function attributes currently don't apply to inferred types (somewhat surprisingly) +nothrow nf = () { + throw new Exception(""); +}; + +// Neither do they apply to indirections +alias F = void function(); + +pure F pf2 = () { + static int g; + g++; +}; diff --git a/gcc/testsuite/gdc.test/runnable/eh2.d b/gcc/testsuite/gdc.test/runnable/eh2.d index dc285a5..2b469d2 100644 --- a/gcc/testsuite/gdc.test/runnable/eh2.d +++ b/gcc/testsuite/gdc.test/runnable/eh2.d @@ -24,7 +24,7 @@ class Abc : Throwable { printf("foo 1\n"); x |= 4; - throw this; + throw cast() this; printf("foo 2\n"); x |= 8; } diff --git a/gcc/testsuite/gdc.test/runnable/imports/link11069z.d b/gcc/testsuite/gdc.test/runnable/imports/link11069z.d index 5987cb4..02301b9 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/link11069z.d +++ b/gcc/testsuite/gdc.test/runnable/imports/link11069z.d @@ -1,7 +1,7 @@ module imports.link11069z; struct Matrix(T, uint _M) { - int opCmp()(auto ref in Matrix b) const + int opCmp()(const auto ref Matrix b) const { return 0; } diff --git a/gcc/testsuite/gdc.test/runnable/imports/link13415a.d b/gcc/testsuite/gdc.test/runnable/imports/link13415a.d index de3bbe2..077671b 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/link13415a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/link13415a.d @@ -7,7 +7,7 @@ struct S(alias func) } } -extern(C) int printf(in char*, ...); +extern(C) int printf(const char*, ...); void f(int i = 77) { diff --git a/gcc/testsuite/gdc.test/runnable/imports/mainx23837.c b/gcc/testsuite/gdc.test/runnable/imports/mainx23837.c new file mode 100644 index 0000000..0c446ab --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/imports/mainx23837.c @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug?id=23837 + +struct stbrp_context +{ + int width; + int height; + int align; + int init_mode; + int heuristic; +}; diff --git a/gcc/testsuite/gdc.test/runnable/mangle.d b/gcc/testsuite/gdc.test/runnable/mangle.d index 7599e0e..6e8f2b2 100644 --- a/gcc/testsuite/gdc.test/runnable/mangle.d +++ b/gcc/testsuite/gdc.test/runnable/mangle.d @@ -571,12 +571,6 @@ void test12231() /***************************************************/ -int test2a(scope int a) { return a; } - -static assert(test2a.mangleof == "_D6mangle6test2aFiZi"); - -/***************************************************/ - class CC { int* p; diff --git a/gcc/testsuite/gdc.test/runnable/test19688.d b/gcc/testsuite/gdc.test/runnable/test19688.d deleted file mode 100644 index 9cc4dd7..0000000 --- a/gcc/testsuite/gdc.test/runnable/test19688.d +++ /dev/null @@ -1,13 +0,0 @@ -/* TEST_OUTUT: ---- ---- -*/ -void test(string s = __FUNCTION__ ~ __MODULE__ ~ __FUNCTION__) -{ - assert(s == "test19688.maintest19688test19688.main"); -} - -void main() -{ - test(); -} diff --git a/gcc/testsuite/gdc.test/runnable/test23837.d b/gcc/testsuite/gdc.test/runnable/test23837.d new file mode 100644 index 0000000..4e155b6 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test23837.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=23837 +// EXTRA_FILES: imports/mainx23837.c + +import imports.mainx23837; + +struct TexturePacker +{ + stbrp_context _context; +} + +int main() +{ + auto res = TexturePacker(); + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/test42.d b/gcc/testsuite/gdc.test/runnable/test42.d index 57045ba..436f707 100644 --- a/gcc/testsuite/gdc.test/runnable/test42.d +++ b/gcc/testsuite/gdc.test/runnable/test42.d @@ -2113,7 +2113,7 @@ void test12725() struct Matrix12728(T, uint m, uint n = m, ubyte f = 0) { - void foo(uint r)(auto ref in Matrix12728!(T, n, r) b) + void foo(uint r)(const auto ref Matrix12728!(T, n, r) b) { } } diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d index e57f52f..5017a76 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest46.d +++ b/gcc/testsuite/gdc.test/runnable/xtest46.d @@ -5016,18 +5016,18 @@ void test6763() { int n; - f6763(0); //With D2: Error: function main.f ((ref const const(int) _param_0)) is not callable using argument types (int) + f6763(0); //With D2: Error: function main.f ((ref const const(int) __param_0)) is not callable using argument types (int) c6763(0); r6763(n); static assert(__traits(compiles, r6763(0))); i6763(0); o6763(n); static assert(!__traits(compiles, o6763(0))); // https://issues.dlang.org/show_bug.cgi?id=6755 - static assert(typeof(f6763).stringof == "void(int _param_0)"); - static assert(typeof(c6763).stringof == "void(const(int) _param_0)"); - static assert(typeof(r6763).stringof == "void(ref int _param_0)"); - static assert(typeof(i6763).stringof == "void(in int _param_0)"); - static assert(typeof(o6763).stringof == "void(out int _param_0)"); + static assert(typeof(f6763).stringof == "void(int __param_0)"); + static assert(typeof(c6763).stringof == "void(const(int) __param_0)"); + static assert(typeof(r6763).stringof == "void(ref int __param_0)"); + static assert(typeof(i6763).stringof == "void(in int __param_0)"); + static assert(typeof(o6763).stringof == "void(out int __param_0)"); } /***************************************************/ @@ -5997,7 +5997,7 @@ void test7618(const int x = 1) { int func(ref int x) { return 1; } static assert(!__traits(compiles, func(x))); - // Error: function test.foo.func (ref int _param_0) is not callable using argument types (const(int)) + // Error: function test.foo.func (ref int __param_0) is not callable using argument types (const(int)) int delegate(ref int) dg = (ref int x) => 1; static assert(!__traits(compiles, dg(x))); @@ -6170,14 +6170,6 @@ static assert(!__traits(compiles, foo8220(typeof(0)))); // fail /***************************************************/ -void func8105(in ref int x) { } - -void test8105() -{ -} - -/***************************************************/ - template ParameterTypeTuple159(alias foo) { static if (is(typeof(foo) P == __parameters)) @@ -8300,7 +8292,6 @@ int main() test12503(); test8004(); test8064(); - test8105(); test159(); test12824(); test8283(); -- cgit v1.1 From 361a6fc4bc5d3073e8e19fba0af51380720e677a Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 10 Jul 2023 00:16:46 +0000 Subject: Daily bump. --- gcc/ChangeLog | 8 ++++++++ gcc/DATESTAMP | 2 +- gcc/d/ChangeLog | 17 +++++++++++++++++ gcc/testsuite/ChangeLog | 9 +++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73ec6c1..5ed58b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2023-07-09 Jan Hubicka + + * cfg.cc (check_bb_profile): Dump counts with relative frequency. + (dump_edge_info): Likewise. + (dump_bb_info): Likewise. + * profile-count.cc (profile_count::dump): Add comma between quality and + freq. + 2023-07-08 Jan Hubicka PR tree-optimization/110600 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 6ca206c..1d5dd3c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230709 +20230710 diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index a967772..f477aa4 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,20 @@ +2023-07-09 Iain Buclaw + + * dmd/MERGE: Merge upstream dmd 28a3b24c2e. + * dmd/VERSION: Bump version to v2.104.0-beta.1. + * d-codegen.cc (build_bounds_slice_condition): Update for new + front-end interface. + * d-lang.cc (d_init_options): Likewise. + (d_handle_option): Likewise. + (d_post_options): Initialize global.compileEnv. + * expr.cc (ExprVisitor::visit (CatExp *)): Replace code generation + with new front-end lowering. + (ExprVisitor::visit (LoweredAssignExp *)): New method. + (ExprVisitor::visit (StructLiteralExp *)): Don't generate static + initializer symbols for structs defined in C sources. + * runtime.def (ARRAYCATT): Remove. + (ARRAYCATNTX): Remove. + 2023-07-07 Iain Buclaw PR d/108842 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3fe5639..60ec7b1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2023-07-09 Iain Buclaw + + * gdc.dg/rtti1.d: Move array concat testcase to ... + * gdc.dg/nogc1.d: ... here. New test. + +2023-07-09 Jan Hubicka + + * gcc.dg/predict-22.c: Update template. + 2023-07-08 Jan Hubicka PR tree-optimization/110600 -- cgit v1.1 From d41a57c46df6f8f7dae0c0a8b349e734806a837b Mon Sep 17 00:00:00 2001 From: liuhongt Date: Mon, 3 Jul 2023 18:19:19 +0800 Subject: Add pre_reload splitter to detect fp min/max pattern. We have ix86_expand_sse_fp_minmax to detect min/max sematics, but it requires rtx_equal_p for cmp_op0/cmp_op1 and if_true/if_false, for the testcase in the PR, there's an extra move from cmp_op0 to if_true, and it failed ix86_expand_sse_fp_minmax. This patch adds pre_reload splitter to detect the min/max pattern. Operands order in MINSS matters for signed zero and NANs, since the instruction always returns second operand when any operand is NAN or both operands are zero. gcc/ChangeLog: PR target/110170 * config/i386/i386.md (*ieee_max3_1): New pre_reload splitter to detect fp max pattern. (*ieee_min3_1): Ditto, but for fp min pattern. gcc/testsuite/ChangeLog: * g++.target/i386/pr110170.C: New test. * gcc.target/i386/pr110170.c: New test. --- gcc/config/i386/i386.md | 43 +++++++++++++++ gcc/testsuite/g++.target/i386/pr110170.C | 90 ++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr110170.c | 21 ++++++++ 3 files changed, 154 insertions(+) create mode 100644 gcc/testsuite/g++.target/i386/pr110170.C create mode 100644 gcc/testsuite/gcc.target/i386/pr110170.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index e47ced1..621cdd9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -23163,6 +23163,49 @@ (set_attr "type" "sseadd") (set_attr "mode" "")]) +;; Operands order in min/max instruction matters for signed zero and NANs. +(define_insn_and_split "*ieee_max3_1" + [(set (match_operand:MODEF 0 "register_operand") + (unspec:MODEF + [(match_operand:MODEF 1 "register_operand") + (match_operand:MODEF 2 "register_operand") + (lt:MODEF + (match_operand:MODEF 3 "register_operand") + (match_operand:MODEF 4 "register_operand"))] + UNSPEC_BLENDV))] + "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH + && (rtx_equal_p (operands[1], operands[3]) + && rtx_equal_p (operands[2], operands[4])) + && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (match_dup 0) + (unspec:MODEF + [(match_dup 2) + (match_dup 1)] + UNSPEC_IEEE_MAX))]) + +(define_insn_and_split "*ieee_min3_1" + [(set (match_operand:MODEF 0 "register_operand") + (unspec:MODEF + [(match_operand:MODEF 1 "register_operand") + (match_operand:MODEF 2 "register_operand") + (lt:MODEF + (match_operand:MODEF 3 "register_operand") + (match_operand:MODEF 4 "register_operand"))] + UNSPEC_BLENDV))] + "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH + && (rtx_equal_p (operands[1], operands[4]) + && rtx_equal_p (operands[2], operands[3])) + && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (match_dup 0) + (unspec:MODEF + [(match_dup 2) + (match_dup 1)] + UNSPEC_IEEE_MIN))]) + ;; Make two stack loads independent: ;; fld aa fld aa ;; fld %st(0) -> fld bb diff --git a/gcc/testsuite/g++.target/i386/pr110170.C b/gcc/testsuite/g++.target/i386/pr110170.C new file mode 100644 index 0000000..e638b12 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr110170.C @@ -0,0 +1,90 @@ +/* { dg-do run { target sse4 } } */ +/* { dg-options " -O2 -msse4.1 -mfpmath=sse -std=gnu++20" } */ +#include + +#ifndef CHECK_H +#define CHECK_H "sse4_1-check.h" +#endif + +#ifndef TEST +#define TEST sse4_1_test +#endif + +#include CHECK_H + +void +__attribute__((noinline)) +__cond_swap(double* __x, double* __y) { + bool __r = (*__x < *__y); + auto __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} + +auto test1() { + double nan = -0.0; + double x = 0.0; + __cond_swap(&nan, &x); + return x == -0.0 && nan == 0.0; +} + +auto test1r() { + double nan = NAN; + double x = 1.0; + __cond_swap(&x, &nan); + return isnan(x) && signbit(x) == 0 && nan == 1.0; +} + +auto test2() { + double nan = NAN; + double x = -1.0; + __cond_swap(&nan, &x); + return isnan(x) && signbit(x) == 0 && nan == -1.0; +} + +auto test2r() { + double nan = NAN; + double x = -1.0; + __cond_swap(&x, &nan); + return isnan(x) && signbit(x) == 0 && nan == -1.0; +} + +auto test3() { + double nan = -NAN; + double x = 1.0; + __cond_swap(&nan, &x); + return isnan(x) && signbit(x) == 1 && nan == 1.0; +} + +auto test3r() { + double nan = -NAN; + double x = 1.0; + __cond_swap(&x, &nan); + return isnan(x) && signbit(x) == 1 && nan == 1.0; +} + +auto test4() { + double nan = -NAN; + double x = -1.0; + __cond_swap(&nan, &x); + return isnan(x) && signbit(x) == 1 && nan == -1.0; +} + +auto test4r() { + double nan = -NAN; + double x = -1.0; + __cond_swap(&x, &nan); + return isnan(x) && signbit(x) == 1 && nan == -1.0; +} + + +static void +TEST() +{ + if ( + !test1() || !test1r() + || !test2() || !test2r() + || !test3() || !test4r() + || !test4() || !test4r() + ) __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.target/i386/pr110170.c b/gcc/testsuite/gcc.target/i386/pr110170.c new file mode 100644 index 0000000..c72f733 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110170.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options " -O2 -msse4.1 -mfpmath=sse" } */ +/* { dg-final { scan-assembler-times {(?n)mins[sd]} 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times {(?n)maxs[sd]} 2 { target { ! ia32 } } } } */ +/* Ideally cond_swap_df is also optimized to minsd/maxsd. */ +/* { dg-final { scan-assembler-times {(?n)mins[sd]} 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times {(?n)maxs[sd]} 1 { target ia32 } } } */ + +void __cond_swap_df(double* __x, double* __y) { + _Bool __r = (*__x < *__y); + double __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} + +void __cond_swap_sf(float* __x, float* __y) { + _Bool __r = (*__x < *__y); + float __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} -- cgit v1.1 From 0cafc3b6272d1dd738e8d7e66e1d8741e08f74d3 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 10 Jul 2023 03:07:41 +0200 Subject: d: Merge upstream dmd, druntime 17ccd12af3, phobos 8d3800bee. D front-end changes: - Import dmd v2.104.0. - Assignment-style syntax is now allowed for `alias this'. - Overloading `extern(C)' functions is now an error. D runtime changes: - Import druntime v2.104.0. Phobos changes: - Import phobos v2.104.0. - Better static assert messages when instantiating `std.algorithm.iteration.permutations' with wrong inputs. - Added `std.system.instructionSetArchitecture' and `std.system.ISA'. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 17ccd12af3. * dmd/VERSION: Bump version to v2.104.0. * Make-lang.in (D_FRONTEND_OBJS): Rename d/apply.o to d/postordervisitor.o. * d-codegen.cc (make_location_t): Update for new front-end interface. (build_filename_from_loc): Likewise. (build_assert_call): Likewise. (build_array_bounds_call): Likewise. (build_bounds_index_condition): Likewise. (build_bounds_slice_condition): Likewise. (build_frame_type): Likewise. (get_frameinfo): Likewise. * d-diagnostic.cc (d_diagnostic_report_diagnostic): Likewise. * decl.cc (build_decl_tree): Likewise. (start_function): Likewise. * expr.cc (ExprVisitor::visit (NewExp *)): Replace code generation of `new pointer' with front-end lowering. * runtime.def (NEWITEMT): Remove. (NEWITEMIT): Remove. * toir.cc (IRVisitor::visit (LabelStatement *)): Update for new front-end interface. * typeinfo.cc (check_typeinfo_type): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 17ccd12af3. * src/MERGE: Merge upstream phobos 8d3800bee. gcc/testsuite/ChangeLog: * gdc.dg/asm4.d: Update test. --- gcc/d/Make-lang.in | 2 +- gcc/d/d-codegen.cc | 37 +-- gcc/d/d-diagnostic.cc | 2 +- gcc/d/decl.cc | 4 +- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/README.md | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/aggregate.d | 49 +++- gcc/d/dmd/apply.d | 188 ------------ gcc/d/dmd/canthrow.d | 11 +- gcc/d/dmd/chkformat.d | 2 + gcc/d/dmd/clone.d | 18 +- gcc/d/dmd/cond.d | 2 +- gcc/d/dmd/cparse.d | 117 ++++++-- gcc/d/dmd/cppmangle.d | 10 +- gcc/d/dmd/dcast.d | 4 + gcc/d/dmd/dclass.d | 9 +- gcc/d/dmd/declaration.d | 8 +- gcc/d/dmd/declaration.h | 29 +- gcc/d/dmd/delegatize.d | 2 +- gcc/d/dmd/denum.d | 7 +- gcc/d/dmd/dimport.d | 16 +- gcc/d/dmd/dinterpret.d | 1 - gcc/d/dmd/doc.d | 10 +- gcc/d/dmd/dsymbolsem.d | 26 +- gcc/d/dmd/dtemplate.d | 318 +++++++++++---------- gcc/d/dmd/escape.d | 36 +-- gcc/d/dmd/expression.d | 63 +++- gcc/d/dmd/expression.h | 3 +- gcc/d/dmd/expressionsem.d | 85 +++++- gcc/d/dmd/foreachvar.d | 2 +- gcc/d/dmd/func.d | 76 ++++- gcc/d/dmd/globals.d | 4 + gcc/d/dmd/globals.h | 28 +- gcc/d/dmd/gluelayer.d | 29 +- gcc/d/dmd/iasm.d | 9 +- gcc/d/dmd/id.d | 3 + gcc/d/dmd/identifier.d | 21 +- gcc/d/dmd/importc.d | 13 +- gcc/d/dmd/initsem.d | 3 + gcc/d/dmd/lexer.d | 12 +- gcc/d/dmd/location.d | 78 ++++- gcc/d/dmd/mtype.d | 6 +- gcc/d/dmd/nogc.d | 2 +- gcc/d/dmd/ob.d | 1 - gcc/d/dmd/opover.d | 52 ++-- gcc/d/dmd/optimize.d | 5 +- gcc/d/dmd/parse.d | 87 +++--- gcc/d/dmd/postordervisitor.d | 153 ++++++++++ gcc/d/dmd/semantic2.d | 4 +- gcc/d/dmd/sideeffect.d | 8 +- gcc/d/dmd/statementsem.d | 18 +- gcc/d/dmd/tokens.d | 2 +- gcc/d/dmd/traits.d | 4 +- gcc/d/dmd/transitivevisitor.d | 10 + gcc/d/dmd/typesem.d | 2 +- gcc/d/expr.cc | 18 +- gcc/d/runtime.def | 5 - gcc/d/toir.cc | 4 +- gcc/d/typeinfo.cc | 2 +- gcc/testsuite/gdc.dg/asm4.d | 2 +- gcc/testsuite/gdc.test/compilable/aliasdecl.d | 6 +- .../compilable/atomic_store_2_shared_classes.d | 13 + .../gdc.test/compilable/imports/library.c | 5 + gcc/testsuite/gdc.test/compilable/noreturn3.d | 8 +- gcc/testsuite/gdc.test/compilable/test22760.d | 15 + gcc/testsuite/gdc.test/compilable/test23874.d | 10 + gcc/testsuite/gdc.test/compilable/test23912.d | 17 ++ gcc/testsuite/gdc.test/compilable/test23913.d | 7 + gcc/testsuite/gdc.test/compilable/test23948.d | 29 ++ gcc/testsuite/gdc.test/fail_compilation/bug9631.d | 4 +- .../gdc.test/fail_compilation/chkformat.d | 7 +- .../gdc.test/fail_compilation/constraints_aggr.d | 4 +- .../gdc.test/fail_compilation/constraints_func1.d | 26 +- .../gdc.test/fail_compilation/constraints_func2.d | 28 +- .../gdc.test/fail_compilation/constraints_func3.d | 8 +- .../gdc.test/fail_compilation/constraints_func4.d | 8 +- .../gdc.test/fail_compilation/diag13942.d | 2 +- .../gdc.test/fail_compilation/diag16977.d | 2 +- .../gdc.test/fail_compilation/diag20268.d | 2 +- .../gdc.test/fail_compilation/diag23355.d | 4 +- gcc/testsuite/gdc.test/fail_compilation/diag8101.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/diag8648.d | 6 +- gcc/testsuite/gdc.test/fail_compilation/diag9004.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/diag9574.d | 19 -- .../fail_compilation/diag_template_alias.d | 2 +- .../gdc.test/fail_compilation/diag_template_this.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/diagin.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/e15876_3.d | 2 +- .../gdc.test/fail_compilation/fail12744.d | 4 +- .../gdc.test/fail_compilation/fail14669.d | 2 +- .../gdc.test/fail_compilation/fail15414.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail162.d | 2 +- .../gdc.test/fail_compilation/fail20730b.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail236.d | 2 +- .../gdc.test/fail_compilation/fail23626a.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail2456.d | 14 + gcc/testsuite/gdc.test/fail_compilation/fail2789.d | 4 +- gcc/testsuite/gdc.test/fail_compilation/fail8009.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail95.d | 2 +- .../gdc.test/fail_compilation/failcontracts.d | 4 +- .../gdc.test/fail_compilation/ice11856_1.d | 6 +- gcc/testsuite/gdc.test/fail_compilation/ice14130.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice14907.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice6538.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice9284.d | 2 +- .../fail_compilation/imports/import23873.d | 2 + .../fail_compilation/imports/spell23908a.d | 3 + .../fail_compilation/imports/spell23908b.d | 3 + .../fail_compilation/named_arguments_error.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/retscope.d | 2 +- .../gdc.test/fail_compilation/spell23908.d | 11 + .../gdc.test/fail_compilation/static_import.d | 8 + .../gdc.test/fail_compilation/test18385.d | 2 +- .../gdc.test/fail_compilation/test19107.d | 2 +- .../gdc.test/fail_compilation/test20245.d | 2 +- .../gdc.test/fail_compilation/test23873.d | 14 + .../gdc.test/fail_compilation/test23882.d | 37 +++ .../gdc.test/fail_compilation/test23905.d | 25 ++ .../gdc.test/fail_compilation/udaparams.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ufcs.d | 34 +++ gcc/testsuite/gdc.test/runnable/betterc.d | 11 + gcc/testsuite/gdc.test/runnable/eh2.d | 4 +- gcc/testsuite/gdc.test/runnable/funclit.d | 1 + gcc/testsuite/gdc.test/runnable/test20687.d | 28 ++ gcc/testsuite/gdc.test/runnable/testinvariant.d | 53 ++++ gcc/testsuite/gdc.test/runnable/variadic.d | 49 ++++ 127 files changed, 1536 insertions(+), 785 deletions(-) delete mode 100644 gcc/d/dmd/apply.d create mode 100644 gcc/d/dmd/postordervisitor.d create mode 100644 gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/library.c create mode 100644 gcc/testsuite/gdc.test/compilable/test22760.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23874.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23912.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23913.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23948.d delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/diag9574.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/spell23908.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/static_import.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23873.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23882.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23905.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ufcs.d create mode 100644 gcc/testsuite/gdc.test/runnable/test20687.d (limited to 'gcc') diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index 4fbf209..264ae03 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -81,7 +81,6 @@ D_FRONTEND_OBJS = \ d/access.o \ d/aggregate.o \ d/aliasthis.o \ - d/apply.o \ d/arrayop.o \ d/arraytypes.o \ d/attrib.o \ @@ -160,6 +159,7 @@ D_FRONTEND_OBJS = \ d/parse.o \ d/parsetimevisitor.o \ d/permissivevisitor.o \ + d/postordervisitor.o \ d/printast.o \ d/root-aav.o \ d/root-array.o \ diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 689d1c5..2738958 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -50,11 +50,11 @@ make_location_t (const Loc &loc) { location_t gcc_location = input_location; - if (loc.filename) + if (const char *filename = loc.filename ()) { - linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum); - linemap_line_start (line_table, loc.linnum, 0); - gcc_location = linemap_position_for_column (line_table, loc.charnum); + linemap_add (line_table, LC_ENTER, 0, filename, loc.linnum ()); + linemap_line_start (line_table, loc.linnum (), 0); + gcc_location = linemap_position_for_column (line_table, loc.charnum ()); linemap_add (line_table, LC_LEAVE, 0, NULL, 0); } @@ -1872,8 +1872,10 @@ void_okay_p (tree t) static tree build_filename_from_loc (const Loc &loc) { - const char *filename = loc.filename - ? loc.filename : d_function_chain->module->srcfile.toChars (); + const char *filename = loc.filename (); + + if (filename == NULL) + filename = d_function_chain->module->srcfile.toChars (); unsigned length = strlen (filename); tree str = build_string (length, filename); @@ -1890,17 +1892,17 @@ tree build_assert_call (const Loc &loc, libcall_fn libcall, tree msg) { tree file; - tree line = size_int (loc.linnum); + tree line = size_int (loc.linnum ()); switch (libcall) { case LIBCALL_ASSERT_MSG: case LIBCALL_UNITTEST_MSG: /* File location is passed as a D string. */ - if (loc.filename) + if (const char *filename = loc.filename ()) { - unsigned len = strlen (loc.filename); - tree str = build_string (len, loc.filename); + unsigned len = strlen (filename); + tree str = build_string (len, filename); TREE_TYPE (str) = make_array_type (Type::tchar, len); file = d_array_value (build_ctype (Type::tchar->arrayOf ()), @@ -1939,7 +1941,7 @@ build_array_bounds_call (const Loc &loc) { return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2, build_filename_from_loc (loc), - size_int (loc.linnum)); + size_int (loc.linnum ())); } } @@ -1968,7 +1970,8 @@ build_bounds_index_condition (IndexExp *ie, tree index, tree length) { boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4, build_filename_from_loc (ie->e2->loc), - size_int (ie->e2->loc.linnum), index, length); + size_int (ie->e2->loc.linnum ()), + index, length); } return build_condition (TREE_TYPE (index), condition, boundserr, index); @@ -2017,7 +2020,7 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length) boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP, Type::tvoid, 5, build_filename_from_loc (se->loc), - size_int (se->loc.linnum), + size_int (se->loc.linnum ()), lower, upper, length); } @@ -2659,8 +2662,8 @@ build_frame_type (tree ffi, FuncDeclaration *fd) of the calling function non-locally. So we add all parameters with nested refs to the function frame, this should also mean overriding methods will have the same frame layout when inheriting a contract. */ - if ((global.params.useIn == CHECKENABLEon && fd->frequire) - || (global.params.useOut == CHECKENABLEon && fd->fensure)) + if ((global.params.useIn == CHECKENABLEon && fd->frequire ()) + || (global.params.useOut == CHECKENABLEon && fd->fensure ())) { if (fd->parameters) { @@ -2870,8 +2873,8 @@ get_frameinfo (FuncDeclaration *fd) /* In checkNestedReference, references from contracts are not added to the closureVars array, so assume all parameters referenced. */ - if ((global.params.useIn == CHECKENABLEon && fd->frequire) - || (global.params.useOut == CHECKENABLEon && fd->fensure)) + if ((global.params.useIn == CHECKENABLEon && fd->frequire ()) + || (global.params.useOut == CHECKENABLEon && fd->fensure ())) FRAMEINFO_CREATES_FRAME (ffi) = 1; /* If however `fd` is nested (deeply) in a function that creates a diff --git a/gcc/d/d-diagnostic.cc b/gcc/d/d-diagnostic.cc index c3bde46..7e5b17c 100644 --- a/gcc/d/d-diagnostic.cc +++ b/gcc/d/d-diagnostic.cc @@ -189,7 +189,7 @@ d_diagnostic_report_diagnostic (const Loc &loc, int opt, const char *format, va_list argp; va_copy (argp, ap); - if (loc.filename || !verbatim) + if (loc.filename () || !verbatim) { rich_location rich_loc (line_table, make_location_t (loc)); diagnostic_info diagnostic; diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 0375ede..b866593 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -1083,7 +1083,7 @@ build_decl_tree (Dsymbol *d) location_t saved_location = input_location; /* Set input location, empty DECL_SOURCE_FILE can crash debug generator. */ - if (d->loc.filename) + if (d->loc.filename ()) input_location = make_location_t (d->loc); else input_location = make_location_t (Loc ("", 1, 0)); @@ -2064,7 +2064,7 @@ start_function (FuncDeclaration *fd) allocate_struct_function (fndecl, false); /* Store the end of the function. */ - if (fd->endloc.filename) + if (fd->endloc.filename ()) cfun->function_end_locus = make_location_t (fd->endloc); else cfun->function_end_locus = DECL_SOURCE_LOCATION (fndecl); diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 95ea67d..1cff48a 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -28a3b24c2e45de39cd3df528142fd06b6456e8fd +17ccd12af386543c0b9935bf7e0a8e701b903105 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/README.md b/gcc/d/dmd/README.md index 57f56f3..79215b7 100644 --- a/gcc/d/dmd/README.md +++ b/gcc/d/dmd/README.md @@ -99,7 +99,7 @@ Note that these groups have no strict meaning, the category assignments are a bi | [strictvisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/strictvisitor.d) | Visitor that forces derived classes to implement `visit` for every possible node | | [visitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/visitor.d) | A visitor implementing `visit` for all nodes present in the compiler | | [transitivevisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/transitivevisitor.d) | Provide a mixin template with visit methods for the parse time AST | -| [apply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/apply.d) | Depth-first expression visitor | +| [postordervisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/postordervisitor.d) | Depth-first expression visitor | | [sapply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/sapply.d) | Depth-first statement visitor | | [statement_rewrite_walker.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/statement_rewrite_walker.d) | Statement visitor that allows replacing the currently visited node | diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 7cf9127..d5aee89 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.104.0-beta.1 +v2.104.0 diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index 1306a10..42b926b 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -18,7 +18,6 @@ import core.stdc.stdio; import core.checkedint; import dmd.aliasthis; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; @@ -764,21 +763,18 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol if (s) { // Finish all constructors semantics to determine this.noDefaultCtor. - struct SearchCtor + static int searchCtor(Dsymbol s, void*) { - extern (C++) static int fp(Dsymbol s, void* ctxt) - { - auto f = s.isCtorDeclaration(); - if (f && f.semanticRun == PASS.initial) - f.dsymbolSemantic(null); - return 0; - } + auto f = s.isCtorDeclaration(); + if (f && f.semanticRun == PASS.initial) + f.dsymbolSemantic(null); + return 0; } for (size_t i = 0; i < members.length; i++) { auto sm = (*members)[i]; - sm.apply(&SearchCtor.fp, null); + sm.apply(&searchCtor, null); } } return s; @@ -814,3 +810,36 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol v.visit(this); } } + +/********************************* + * Iterate this dsymbol or members of this scoped dsymbol, then + * call `fp` with the found symbol and `params`. + * Params: + * symbol = the dsymbol or parent of members to call fp on + * fp = function pointer to process the iterated symbol. + * If it returns nonzero, the iteration will be aborted. + * ctx = context parameter passed to fp. + * Returns: + * nonzero if the iteration is aborted by the return value of fp, + * or 0 if it's completed. + */ +int apply(Dsymbol symbol, int function(Dsymbol, void*) fp, void* ctx) +{ + if (auto nd = symbol.isNspace()) + { + return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } ); + } + if (auto ad = symbol.isAttribDeclaration()) + { + return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, ctx); } ); + } + if (auto tm = symbol.isTemplateMixin()) + { + if (tm._scope) // if fwd reference + dsymbolSemantic(tm, null); // try to resolve it + + return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } ); + } + + return fp(symbol, ctx); +} diff --git a/gcc/d/dmd/apply.d b/gcc/d/dmd/apply.d deleted file mode 100644 index d18b81f..0000000 --- a/gcc/d/dmd/apply.d +++ /dev/null @@ -1,188 +0,0 @@ -/** - * A depth-first visitor for expressions. - * - * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved - * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) - * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) - * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/apply.d, _apply.d) - * Documentation: https://dlang.org/phobos/dmd_apply.html - * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d - */ - -module dmd.apply; - -import dmd.arraytypes; -import dmd.dsymbol; -import dmd.dsymbolsem; -import dmd.dtemplate; -import dmd.expression; -import dmd.root.array; -import dmd.visitor; - -bool walkPostorder(Expression e, StoppableVisitor v) -{ - scope PostorderExpressionVisitor pv = new PostorderExpressionVisitor(v); - e.accept(pv); - return v.stop; -} - -/********************************* - * Iterate this dsymbol or members of this scoped dsymbol, then - * call `fp` with the found symbol and `params`. - * Params: - * symbol = the dsymbol or parent of members to call fp on - * fp = function pointer to process the iterated symbol. - * If it returns nonzero, the iteration will be aborted. - * params = any parameters passed to fp. - * Returns: - * nonzero if the iteration is aborted by the return value of fp, - * or 0 if it's completed. - */ -int apply(FP, Params...)(Dsymbol symbol, FP fp, Params params) -{ - if (auto nd = symbol.isNspace()) - { - return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } ); - } - if (auto ad = symbol.isAttribDeclaration()) - { - return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, params); } ); - } - if (auto tm = symbol.isTemplateMixin()) - { - if (tm._scope) // if fwd reference - dsymbolSemantic(tm, null); // try to resolve it - - return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } ); - } - - return fp(symbol, params); -} - -/************************************** - * An Expression tree walker that will visit each Expression e in the tree, - * in depth-first evaluation order, and call fp(e,param) on it. - * fp() signals whether the walking continues with its return value: - * Returns: - * 0 continue - * 1 done - * It's a bit slower than using virtual functions, but more encapsulated and less brittle. - * Creating an iterator for this would be much more complex. - */ -private extern (C++) final class PostorderExpressionVisitor : StoppableVisitor -{ - alias visit = typeof(super).visit; -public: - StoppableVisitor v; - - extern (D) this(StoppableVisitor v) scope - { - this.v = v; - } - - bool doCond(Expression e) - { - if (!stop && e) - e.accept(this); - return stop; - } - - extern(D) bool doCond(Expression[] e) - { - for (size_t i = 0; i < e.length && !stop; i++) - doCond(e[i]); - return stop; - } - - bool applyTo(Expression e) - { - e.accept(v); - stop = v.stop; - return true; - } - - override void visit(Expression e) - { - applyTo(e); - } - - override void visit(NewExp e) - { - //printf("NewExp::apply(): %s\n", toChars()); - doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); - } - - override void visit(NewAnonClassExp e) - { - //printf("NewAnonClassExp::apply(): %s\n", toChars()); - doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); - } - - override void visit(TypeidExp e) - { - doCond(isExpression(e.obj)) || applyTo(e); - } - - override void visit(UnaExp e) - { - doCond(e.e1) || applyTo(e); - } - - override void visit(BinExp e) - { - doCond(e.e1) || doCond(e.e2) || applyTo(e); - } - - override void visit(AssertExp e) - { - //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); - doCond(e.e1) || doCond(e.msg) || applyTo(e); - } - - override void visit(CallExp e) - { - //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); - doCond(e.e1) || doCond(e.arguments.peekSlice()) || applyTo(e); - } - - override void visit(ArrayExp e) - { - //printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); - doCond(e.e1) || doCond(e.arguments.peekSlice()) || applyTo(e); - } - - override void visit(SliceExp e) - { - doCond(e.e1) || doCond(e.lwr) || doCond(e.upr) || applyTo(e); - } - - override void visit(ArrayLiteralExp e) - { - doCond(e.basis) || doCond(e.elements.peekSlice()) || applyTo(e); - } - - override void visit(AssocArrayLiteralExp e) - { - doCond(e.keys.peekSlice()) || doCond(e.values.peekSlice()) || applyTo(e); - } - - override void visit(StructLiteralExp e) - { - if (e.stageflags & stageApply) - return; - const old = e.stageflags; - e.stageflags |= stageApply; - doCond(e.elements.peekSlice()) || applyTo(e); - e.stageflags = old; - } - - override void visit(TupleExp e) - { - doCond(e.e0) || doCond(e.exps.peekSlice()) || applyTo(e); - } - - override void visit(CondExp e) - { - doCond(e.econd) || doCond(e.e1) || doCond(e.e2) || applyTo(e); - } -} diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d index 7dfec8a..09d39ca 100644 --- a/gcc/d/dmd/canthrow.d +++ b/gcc/d/dmd/canthrow.d @@ -14,7 +14,6 @@ module dmd.canthrow; import dmd.aggregate; -import dmd.apply; import dmd.arraytypes; import dmd.attrib; import dmd.astenums; @@ -26,6 +25,7 @@ import dmd.func; import dmd.globals; import dmd.init; import dmd.mtype; +import dmd.postordervisitor; import dmd.root.rootobject; import dmd.tokens; import dmd.visitor; @@ -133,16 +133,9 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN */ if (ce.f && ce.f == func) return; - Type t = ce.e1.type.toBasetype(); - auto tf = t.isTypeFunction(); + const tf = ce.calledFunctionType(); if (tf && tf.isnothrow) return; - else - { - auto td = t.isTypeDelegate(); - if (td && td.nextOf().isTypeFunction().isnothrow) - return; - } if (ce.f) checkFuncThrows(ce, ce.f); diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d index 21a1b5e..feaa3c7 100644 --- a/gcc/d/dmd/chkformat.d +++ b/gcc/d/dmd/chkformat.d @@ -177,6 +177,8 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre errorMsg(null, e, (c_longsize == 4 ? "uint" : "ulong"), t); else errorMsg(null, e, (c_longsize == 4 ? "int" : "long"), t); + if (t.isintegral() && t.size() != c_longsize) + errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize); } break; diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 60e373c..3586f20 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -106,18 +106,18 @@ FuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc) scope er = new NullExp(ad.loc, ad.type); // dummy rvalue scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue el.type = ad.type; - auto a = Expressions(1); + auto a = new Expressions(1); const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it. sc = sc.push(); sc.tinst = null; sc.minst = null; - a[0] = er; - auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet); + (*a)[0] = er; + auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet); if (!f) { - a[0] = el; - f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet); + (*a)[0] = el; + f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet); } sc = sc.pop(); @@ -465,7 +465,7 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc) */ scope er = new NullExp(ad.loc, null); // dummy rvalue scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue - auto a = Expressions(1); + auto a = new Expressions(1); bool hasIt(Type tthis) { @@ -476,9 +476,9 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc) FuncDeclaration rfc(Expression e) { - a[0] = e; - a[0].type = tthis; - return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(&a), FuncResolveFlag.quiet); + (*a)[0] = e; + (*a)[0].type = tthis; + return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(a), FuncResolveFlag.quiet); } f = rfc(er); diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index c40936c..fcb50e0 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -259,7 +259,7 @@ extern (C++) final class StaticForeach : RootObject auto sdecl = new StructDeclaration(loc, sid, false); sdecl.storage_class |= STC.static_; sdecl.members = new Dsymbols(); - auto fid = Identifier.idPool(tupleFieldName.ptr, tupleFieldName.length); + auto fid = Identifier.idPool(tupleFieldName); auto ty = new TypeTypeof(loc, new TupleExp(loc, e)); sdecl.members.push(new VarDeclaration(loc, ty, fid, null, 0)); auto r = cast(TypeStruct)sdecl.type; diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 9b7db1f..33669e3 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -324,6 +324,8 @@ final class CParser(AST) : Parser!AST // atomic-type-specifier or type_qualifier case TOK._Atomic: + case TOK.__attribute__: + Ldeclaration: { cparseDeclaration(LVL.local); @@ -2356,6 +2358,8 @@ final class CParser(AST) : Parser!AST cparseGnuAttributes(tagSpecifier); else if (token.value == TOK.__declspec) cparseDeclspec(tagSpecifier); + else if (token.value == TOK.__pragma) + uupragmaDirective(sloc); else break; } @@ -2710,7 +2714,7 @@ final class CParser(AST) : Parser!AST * * Params: * declarator = declarator kind - * t = base type to start with + * tbase = base type to start with * pident = set to Identifier if there is one, null if not * specifier = specifiers in and out * Returns: @@ -2718,12 +2722,26 @@ final class CParser(AST) : Parser!AST * symbol table for the parameter-type-list, which will contain any * declared struct, union or enum tags. */ - private AST.Type cparseDeclarator(DTR declarator, AST.Type t, + private AST.Type cparseDeclarator(DTR declarator, AST.Type tbase, out Identifier pident, ref Specifier specifier) { //printf("cparseDeclarator(%d, %p)\n", declarator, t); AST.Types constTypes; // all the Types that will need `const` applied to them + /* Insert tx -> t into + * ts -> ... -> t + * so that + * ts -> ... -> tx -> t + */ + static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t) + { + AST.Type* pt; + for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next) + { + } + *pt = tx; + } + AST.Type parseDecl(AST.Type t) { AST.Type ts; @@ -2789,20 +2807,6 @@ final class CParser(AST) : Parser!AST // parse DeclaratorSuffixes while (1) { - /* Insert tx -> t into - * ts -> ... -> t - * so that - * ts -> ... -> tx -> t - */ - static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t) - { - AST.Type* pt; - for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next) - { - } - *pt = tx; - } - switch (token.value) { case TOK.leftBracket: @@ -2915,7 +2919,17 @@ final class CParser(AST) : Parser!AST return ts; } - t = parseDecl(t); + auto t = parseDecl(tbase); + + if (specifier.vector_size) + { + auto length = new AST.IntegerExp(token.loc, specifier.vector_size / tbase.size(), AST.Type.tuns32); + auto tsa = new AST.TypeSArray(tbase, length); + AST.Type tv = new AST.TypeVector(tsa); + specifier.vector_size = 0; // used it up + + insertTx(t, tv, tbase); // replace tbase with tv + } /* Because const is transitive, cannot assemble types from * fragments. Instead, types to be annotated with const are put @@ -3553,7 +3567,19 @@ final class CParser(AST) : Parser!AST { nextToken(); check(TOK.leftParenthesis); - cparseConstantExp(); // TODO implement + if (token.value == TOK.int32Literal) + { + const n = token.unsvalue; + if (n < 1 || n & (n - 1) || ushort.max < n) + error("__attribute__((vector_size(%lld))) must be an integer positive power of 2 and be <= 32,768", cast(ulong)n); + specifier.vector_size = cast(uint) n; + nextToken(); + } + else + { + error("value for vector_size expected, not `%s`", token.toChars()); + nextToken(); + } check(TOK.rightParenthesis); } else @@ -3852,6 +3878,10 @@ final class CParser(AST) : Parser!AST else if (!tag) error("missing tag `identifier` after `%s`", Token.toChars(structOrUnion)); + // many ways and places to declare alignment + if (packalign.isUnknown() && !this.packalign.isUnknown()) + packalign.set(this.packalign.get()); + /* Need semantic information to determine if this is a declaration, * redeclaration, or reference to existing declaration. * Defer to the semantic() pass with a TypeTag. @@ -4694,6 +4724,7 @@ final class CParser(AST) : Parser!AST // atomic-type-specifier case TOK._Atomic: case TOK.typeof_: + case TOK.__attribute__: t = peek(t); if (t.value != TOK.leftParenthesis || !skipParens(t, &t)) @@ -4959,6 +4990,7 @@ final class CParser(AST) : Parser!AST bool dllexport; /// dllexport attribute bool _deprecated; /// deprecated attribute AST.Expression depMsg; /// deprecated message + uint vector_size; /// positive power of 2 multipe of base type size SCW scw; /// storage-class specifiers MOD mod; /// type qualifiers @@ -5400,6 +5432,24 @@ final class CParser(AST) : Parser!AST pragmaDirective(scanloc); return true; } + else if (n.ident == Id.ident) // #ident "string" + { + scan(&n); + if (n.value == TOK.string_ && n.ptr[0] == '"' && n.postfix == 0) + { + /* gcc inserts string into the .comment section in the object file. + * Just ignore it for now, but can support it later by writing + * the string to obj_exestr() + */ + //auto comment = n.ustring; + + scan(&n); + if (n.value == TOK.endOfFile || n.value == TOK.endOfLine) + return true; + } + error("\"string\" expected after `#ident`"); + return false; + } } if (n.ident != Id.undef) error("C preprocessor directive `#%s` is not supported", n.toChars()); @@ -5416,20 +5466,39 @@ final class CParser(AST) : Parser!AST private void uupragmaDirective(const ref Loc startloc) { const loc = startloc; - nextToken(); + nextToken(); // move past __pragma if (token.value != TOK.leftParenthesis) { - error(loc, "left parenthesis expected to follow `__pragma`"); + error(loc, "left parenthesis expected to follow `__pragma` instead of `%s`", token.toChars()); + nextToken(); return; } nextToken(); - if (token.value == TOK.identifier && token.ident == Id.pack) - pragmaPack(startloc, false); + + if (token.value == TOK.identifier) + { + if (token.ident == Id.pack) + pragmaPack(startloc, false); + else + { + nextToken(); + if (token.value == TOK.leftParenthesis) + cparseParens(); + } + + } + else if (token.value == TOK.endOfFile) + { + } + else if (token.value == TOK.rightParenthesis) + { + } else - error(loc, "unrecognized __pragma"); + error(loc, "unrecognized `__pragma(%s)`", token.toChars()); + if (token.value != TOK.rightParenthesis) { - error(loc, "right parenthesis expected to close `__pragma(...)`"); + error(loc, "right parenthesis expected to close `__pragma(...)` instead of `%s`", token.toChars()); return; } nextToken(); diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index 40092c3..ee1340d 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -446,7 +446,15 @@ private final class CppMangleVisitor : Visitor if (this.context.res.dyncast() == DYNCAST.dsymbol) parentti = this.context.res.asFuncDecl().parent.isTemplateInstance(); else - parentti = this.context.res.asType().toDsymbol(null).parent.isTemplateInstance(); + { + auto parent = this.context.res.asType().toDsymbol(null).parent; + parentti = parent.isTemplateInstance(); + // https://issues.dlang.org/show_bug.cgi?id=22760 + // The template instance may sometimes have the form + // S1!int.S1, therefore the above instruction might yield null + if (parentti is null && parent.parent) + parentti = parent.parent.isTemplateInstance(); + } return (*parentti.tiargs)[arg]; }()); scope (exit) this.context.pop(prev); diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 8ffbef3..6fcc280 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -71,6 +71,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t)) { + // no need for an extra cast when matching is exact + if (match == MATCH.convert && e.type.isTypeNoreturn()) { return specialNoreturnCast(e, t); @@ -88,6 +90,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) auto ad = isAggregate(e.type); if (ad && ad.aliasthis) { + if (!ad.type || ad.type.isTypeError()) + return e; auto ts = ad.type.isTypeStruct(); const adMatch = ts ? ts.implicitConvToWithoutAliasThis(t) diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d index e458593..1b8e8ef 100644 --- a/gcc/d/dmd/dclass.d +++ b/gcc/d/dmd/dclass.d @@ -17,7 +17,6 @@ import core.stdc.stdio; import core.stdc.string; import dmd.aggregate; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; @@ -867,7 +866,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration * Resolve forward references to all class member functions, * and determine whether this class is abstract. */ - static int func(Dsymbol s) + static int func(Dsymbol s, void*) { auto fd = s.isFuncDeclaration(); if (!fd) @@ -883,7 +882,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration for (size_t i = 0; i < members.length; i++) { auto s = (*members)[i]; - if (s.apply(&func)) + if (s.apply(&func, null)) { return yes(); } @@ -910,7 +909,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration * each of the virtual functions, * which will fill in the vtbl[] overrides. */ - static int virtualSemantic(Dsymbol s) + static int virtualSemantic(Dsymbol s, void*) { auto fd = s.isFuncDeclaration(); if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration()) @@ -921,7 +920,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration for (size_t i = 0; i < members.length; i++) { auto s = (*members)[i]; - s.apply(&virtualSemantic); + s.apply(&virtualSemantic,null); } } diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index 0e5df5e..cfa6988 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -44,6 +44,10 @@ import dmd.tokens; import dmd.typesem; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + /************************************ * Check to see the aggregate type is nested and its context pointer is * accessible from the current scope. @@ -633,9 +637,7 @@ extern (C++) final class TupleDeclaration : Declaration version (none) { buf.printf("_%s_%d", ident.toChars(), i); - const len = buf.offset; - const name = buf.extractSlice().ptr; - auto id = Identifier.idPool(name, len); + auto id = Identifier.idPool(buf.extractSlice()); auto arg = new Parameter(STC.in_, t, id, null); } else diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 7a69382..197091e 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -534,22 +534,19 @@ enum class BUILTIN : unsigned char Expression *eval_builtin(const Loc &loc, FuncDeclaration *fd, Expressions *arguments); BUILTIN isBuiltin(FuncDeclaration *fd); +struct ContractInfo; + class FuncDeclaration : public Declaration { public: - Statements *frequires; // in contracts - Ensures *fensures; // out contracts - Statement *frequire; // lowered in contract - Statement *fensure; // lowered out contract Statement *fbody; FuncDeclarations foverrides; // functions this function overrides - FuncDeclaration *fdrequire; // function that does the in contract - FuncDeclaration *fdensure; // function that does the out contract - Expressions *fdrequireParams; // argument list for __require - Expressions *fdensureParams; // argument list for __ensure +private: + ContractInfo *contracts; // contract information +public: const char *mangleString; // mangled symbol created from mangleExact() VarDeclaration *vresult; // result variable for out contracts @@ -686,6 +683,22 @@ public: static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false); FuncDeclaration *syntaxCopy(Dsymbol *) override; + Statements *frequires(); + Ensures *fensures(); + Statement *frequire(); + Statement *fensure(); + FuncDeclaration *fdrequire(); + FuncDeclaration *fdensure(); + Expressions *fdrequireParams(); + Expressions *fdensureParams(); + Statements *frequires(Statements *frs); + Ensures *fensures(Statements *fes); + Statement *frequire(Statement *fr); + Statement *fensure(Statement *fe); + FuncDeclaration *fdrequire(FuncDeclaration *fdr); + FuncDeclaration *fdensure(FuncDeclaration *fde); + Expressions *fdrequireParams(Expressions *fdrp); + Expressions *fdensureParams(Expressions *fdep); bool functionSemantic(); bool functionSemantic3(); bool equals(const RootObject * const o) const override final; diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d index fd95691..b135bfa 100644 --- a/gcc/d/dmd/delegatize.d +++ b/gcc/d/dmd/delegatize.d @@ -14,7 +14,6 @@ module dmd.delegatize; import core.stdc.stdio; -import dmd.apply; import dmd.astenums; import dmd.declaration; import dmd.dscope; @@ -27,6 +26,7 @@ import dmd.init; import dmd.initsem; import dmd.location; import dmd.mtype; +import dmd.postordervisitor; import dmd.statement; import dmd.tokens; import dmd.visitor; diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d index 221250b..87b40b8 100644 --- a/gcc/d/dmd/denum.d +++ b/gcc/d/dmd/denum.d @@ -169,7 +169,12 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol return defaultval; } //printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars()); - if (defaultval) + // https://issues.dlang.org/show_bug.cgi?id=23904 + // Return defaultval only if it is not ErrorExp. + // A speculative context may set defaultval to ErrorExp; + // subsequent non-speculative contexts need to be able + // to print the error. + if (defaultval && !defaultval.isErrorExp()) return defaultval; if (isCsymbol()) diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d index b653d9b..c4d5ddb 100644 --- a/gcc/d/dmd/dimport.d +++ b/gcc/d/dmd/dimport.d @@ -26,6 +26,7 @@ import dmd.location; import dmd.mtype; import dmd.visitor; +import core.stdc.stdio; /*********************************************************** */ extern (C++) final class Import : Dsymbol @@ -232,7 +233,20 @@ extern (C++) final class Import : Dsymbol * most likely because of parsing errors. * Therefore we cannot trust the resulting AST. */ - if (load(sc)) return; + if (load(sc)) + { + // https://issues.dlang.org/show_bug.cgi?id=23873 + // For imports that are not at module or function level, + // e.g. aggregate level, the import symbol is added to the + // symbol table and later semantic is performed on it. + // This leads to semantic analysis on an malformed AST + // which causes all kinds of segfaults. + // The fix is to note that the module has errors and avoid + // semantic analysis on it. + if(mod) + mod.errors = true; + return; + } if (!mod) return; // Failed diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 4ef6a39..5b27a07 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -16,7 +16,6 @@ module dmd.dinterpret; import core.stdc.stdio; import core.stdc.stdlib; import core.stdc.string; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d index 7674f77..3e60dc4 100644 --- a/gcc/d/dmd/doc.d +++ b/gcc/d/dmd/doc.d @@ -429,9 +429,9 @@ extern(C++) void gendocfile(Module m) if (m.filetype == FileType.ddoc) { const ploc = m.md ? &m.md.loc : &m.loc; - const loc = Loc(ploc.filename ? ploc.filename : srcfilename.ptr, - ploc.linnum, - ploc.charnum); + Loc loc = *ploc; + if (!loc.filename) + loc.filename = srcfilename.ptr; size_t commentlen = strlen(cast(char*)m.comment); Dsymbols a; @@ -4151,7 +4151,7 @@ private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, con private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset) { const incrementLoc = loc.linnum == 0 ? 1 : 0; - loc.linnum += incrementLoc; + loc.linnum = loc.linnum + incrementLoc; loc.charnum = 0; //printf("highlightText()\n"); bool leadingBlank = true; @@ -4256,7 +4256,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s lineQuoted = false; tableRowDetected = false; iLineStart = i + 1; - loc.linnum += incrementLoc; + loc.linnum = loc.linnum + incrementLoc; // update the paragraph start if we just entered a macro if (previousMacroLevel < macroLevel && iParagraphStart < iLineStart) diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 506946f..a5cd63b 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -17,7 +17,6 @@ import core.stdc.string; import dmd.aggregate; import dmd.aliasthis; -import dmd.apply; import dmd.arraytypes; import dmd.astcodegen; import dmd.astenums; @@ -78,6 +77,10 @@ import dmd.templateparamsem; import dmd.typesem; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + enum LOG = false; private uint setMangleOverride(Dsymbol s, const(char)[] sym) @@ -484,7 +487,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // Infering the type requires running semantic, // so mark the scope as ctfe if required - bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0; + bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0 || !sc.func; if (needctfe) { sc.flags |= SCOPE.condition; @@ -1366,9 +1369,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { static if (LOG) { - printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars()); + printf("Import::semantic('%s') %s\n", imp.toPrettyChars(), imp.id.toChars()); scope(exit) - printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg); + printf("-Import::semantic('%s'), pkg = %p\n", imp.toChars(), imp.pkg); } if (imp.semanticRun > PASS.initial) return; @@ -1434,7 +1437,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor imp.addPackageAccess(scopesym); } - imp.mod.dsymbolSemantic(null); + // if a module has errors it means that parsing has failed. + if (!imp.mod.errors) + imp.mod.dsymbolSemantic(null); if (imp.mod.needmoduleinfo) { @@ -1463,7 +1468,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else { Dsymbol s = imp.mod.search_correct(imp.names[i]); - if (s) + // https://issues.dlang.org/show_bug.cgi?id=23908 + // Don't suggest symbols from the importer's module + if (s && s.parent != importer) imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars()); else imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars()); @@ -7124,8 +7131,9 @@ bool determineFields(AggregateDeclaration ad) // determineFields can be called recursively from one of the fields's v.semantic ad.fields.setDim(0); - static int func(Dsymbol s, AggregateDeclaration ad) + static int func(Dsymbol s, void* ctx) { + auto ad = cast(AggregateDeclaration)ctx; auto v = s.isVarDeclaration(); if (!v) return 0; @@ -7141,7 +7149,7 @@ bool determineFields(AggregateDeclaration ad) if (v.aliasTuple) { // If this variable was really a tuple, process each element. - return v.aliasTuple.foreachVar(tv => tv.apply(&func, ad)); + return v.aliasTuple.foreachVar(tv => tv.apply(&func, cast(void*) ad)); } if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter)) @@ -7173,7 +7181,7 @@ bool determineFields(AggregateDeclaration ad) for (size_t i = 0; i < ad.members.length; i++) { auto s = (*ad.members)[i]; - if (s.apply(&func, ad)) + if (s.apply(&func, cast(void *)ad)) { if (ad.sizeok != Sizeok.none) { diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index ef743d6..5b98d2f 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -4141,185 +4141,207 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param goto Lnomatch; L2: - for (size_t i = 0; 1; i++) + if (!resolveTemplateInstantiation(t.tempinst.tiargs, &t.tempinst.tdtypes, tempdecl, tp, dedtypes)) + goto Lnomatch; + } + visit(cast(Type)t); + return; + + Lnomatch: + //printf("no match\n"); + result = MATCH.nomatch; + } + + /******************** + * Match template `parameters` to the target template instance. + * Example: + * struct Temp(U, int Z) {} + * void foo(T)(Temp!(T, 3)); + * foo(Temp!(int, 3)()); + * Input: + * this.parameters = template params of foo -> [T] + * tiargs = .tiargs -> [int, 3] + * tdtypes = .tdtypes -> [int, 3] + * tempdecl = -> [T, Z] + * tp = + * Output: + * dedtypes = deduced params of `foo(Temp!(int, 3)())` -> [int] + */ + private bool resolveTemplateInstantiation(Objects* tiargs, Objects* tdtypes, TemplateDeclaration tempdecl, TypeInstance tp, Objects* dedtypes) + { + for (size_t i = 0; 1; i++) + { + //printf("\ttest: tempinst.tiargs[%zu]\n", i); + RootObject o1 = null; + if (i < tiargs.length) + o1 = (*tiargs)[i]; + else if (i < tdtypes.length && i < tp.tempinst.tiargs.length) { - //printf("\ttest: tempinst.tiargs[%zu]\n", i); - RootObject o1 = null; - if (i < t.tempinst.tiargs.length) - o1 = (*t.tempinst.tiargs)[i]; - else if (i < t.tempinst.tdtypes.length && i < tp.tempinst.tiargs.length) - { - // Pick up default arg - o1 = t.tempinst.tdtypes[i]; - } - else if (i >= tp.tempinst.tiargs.length) - break; - //printf("\ttest: o1 = %s\n", o1.toChars()); - if (i >= tp.tempinst.tiargs.length) + // Pick up default arg + o1 = (*tdtypes)[i]; + } + else if (i >= tp.tempinst.tiargs.length) + break; + //printf("\ttest: o1 = %s\n", o1.toChars()); + if (i >= tp.tempinst.tiargs.length) + { + size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0); + while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg())) { - size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0); - while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg())) - { - i++; - } - if (i >= dim) - break; // match if all remained parameters are dependent - goto Lnomatch; + i++; } + if (i >= dim) + break; // match if all remained parameters are dependent + return false; + } - RootObject o2 = (*tp.tempinst.tiargs)[i]; - Type t2 = isType(o2); - //printf("\ttest: o2 = %s\n", o2.toChars()); - size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1) - ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND; - if (j != IDX_NOTFOUND && j == parameters.length - 1 && - (*parameters)[j].isTemplateTupleParameter()) - { - /* Given: + RootObject o2 = (*tp.tempinst.tiargs)[i]; + Type t2 = isType(o2); + //printf("\ttest: o2 = %s\n", o2.toChars()); + size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1) + ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND; + if (j != IDX_NOTFOUND && j == parameters.length - 1 && + (*parameters)[j].isTemplateTupleParameter()) + { + /* Given: * struct A(B...) {} * alias A!(int, float) X; * static if (is(X Y == A!(Z), Z...)) {} * deduce that Z is a tuple(int, float) */ - /* Create tuple from remaining args + /* Create tuple from remaining args */ - size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.length : t.tempinst.tdtypes.length) - i; - auto vt = new Tuple(vtdim); - for (size_t k = 0; k < vtdim; k++) - { - RootObject o; - if (k < t.tempinst.tiargs.length) - o = (*t.tempinst.tiargs)[i + k]; - else // Pick up default arg - o = t.tempinst.tdtypes[i + k]; - vt.objects[k] = o; - } - - Tuple v = cast(Tuple)(*dedtypes)[j]; - if (v) - { - if (!match(v, vt)) - goto Lnomatch; - } - else - (*dedtypes)[j] = vt; - break; - } - else if (!o1) - break; - - Type t1 = isType(o1); - Dsymbol s1 = isDsymbol(o1); - Dsymbol s2 = isDsymbol(o2); - Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1)); - Expression e2 = isExpression(o2); - version (none) + size_t vtdim = (tempdecl.isVariadic() ? tiargs.length : tdtypes.length) - i; + auto vt = new Tuple(vtdim); + for (size_t k = 0; k < vtdim; k++) { - Tuple v1 = isTuple(o1); - Tuple v2 = isTuple(o2); - if (t1) - printf("t1 = %s\n", t1.toChars()); - if (t2) - printf("t2 = %s\n", t2.toChars()); - if (e1) - printf("e1 = %s\n", e1.toChars()); - if (e2) - printf("e2 = %s\n", e2.toChars()); - if (s1) - printf("s1 = %s\n", s1.toChars()); - if (s2) - printf("s2 = %s\n", s2.toChars()); - if (v1) - printf("v1 = %s\n", v1.toChars()); - if (v2) - printf("v2 = %s\n", v2.toChars()); + RootObject o; + if (k < tiargs.length) + o = (*tiargs)[i + k]; + else // Pick up default arg + o = (*tdtypes)[i + k]; + vt.objects[k] = o; } - if (t1 && t2) + Tuple v = cast(Tuple)(*dedtypes)[j]; + if (v) { - if (!deduceType(t1, sc, t2, parameters, dedtypes)) - goto Lnomatch; + if (!match(v, vt)) + return false; } - else if (e1 && e2) - { - Le: - e1 = e1.ctfeInterpret(); + else + (*dedtypes)[j] = vt; + break; + } + else if (!o1) + break; - /* If it is one of the template parameters for this template, + Type t1 = isType(o1); + Dsymbol s1 = isDsymbol(o1); + Dsymbol s2 = isDsymbol(o2); + Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1)); + Expression e2 = isExpression(o2); + version (none) + { + Tuple v1 = isTuple(o1); + Tuple v2 = isTuple(o2); + if (t1) + printf("t1 = %s\n", t1.toChars()); + if (t2) + printf("t2 = %s\n", t2.toChars()); + if (e1) + printf("e1 = %s\n", e1.toChars()); + if (e2) + printf("e2 = %s\n", e2.toChars()); + if (s1) + printf("s1 = %s\n", s1.toChars()); + if (s2) + printf("s2 = %s\n", s2.toChars()); + if (v1) + printf("v1 = %s\n", v1.toChars()); + if (v2) + printf("v2 = %s\n", v2.toChars()); + } + + if (t1 && t2) + { + if (!deduceType(t1, sc, t2, parameters, dedtypes)) + return false; + } + else if (e1 && e2) + { + Le: + e1 = e1.ctfeInterpret(); + + /* If it is one of the template parameters for this template, * we should not attempt to interpret it. It already has a value. */ - if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter)) - { - /* + if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter)) + { + /* * (T:Number!(e2), int e2) */ - j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters); - if (j != IDX_NOTFOUND) - goto L1; - // The template parameter was not from this template - // (it may be from a parent template, for example) - } - - e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417 - e2 = e2.ctfeInterpret(); + j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters); + if (j != IDX_NOTFOUND) + goto L1; + // The template parameter was not from this template + // (it may be from a parent template, for example) + } - //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty); - //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty); - if (!e1.equals(e2)) - { - if (!e2.implicitConvTo(e1.type)) - goto Lnomatch; + e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417 + e2 = e2.ctfeInterpret(); - e2 = e2.implicitCastTo(sc, e1.type); - e2 = e2.ctfeInterpret(); - if (!e1.equals(e2)) - goto Lnomatch; - } - } - else if (e1 && t2 && t2.ty == Tident) + //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty); + //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty); + if (!e1.equals(e2)) { - j = templateParameterLookup(t2, parameters); - L1: - if (j == IDX_NOTFOUND) - { - t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); - if (e2) - goto Le; - goto Lnomatch; - } - if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null)) - goto Lnomatch; + if (!e2.implicitConvTo(e1.type)) + return false; + + e2 = e2.implicitCastTo(sc, e1.type); + e2 = e2.ctfeInterpret(); + if (!e1.equals(e2)) + return false; } - else if (s1 && s2) + } + else if (e1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); + L1: + if (j == IDX_NOTFOUND) { - Ls: - if (!s1.equals(s2)) - goto Lnomatch; + t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); + if (e2) + goto Le; + return false; } - else if (s1 && t2 && t2.ty == Tident) + if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null)) + return false; + } + else if (s1 && s2) + { + Ls: + if (!s1.equals(s2)) + return false; + } + else if (s1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); + if (j == IDX_NOTFOUND) { - j = templateParameterLookup(t2, parameters); - if (j == IDX_NOTFOUND) - { - t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); - if (s2) - goto Ls; - goto Lnomatch; - } - if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null)) - goto Lnomatch; + t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); + if (s2) + goto Ls; + return false; } - else - goto Lnomatch; + if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null)) + return false; } + else + return false; } - visit(cast(Type)t); - return; - - Lnomatch: - //printf("no match\n"); - result = MATCH.nomatch; + return true; } override void visit(TypeStruct t) diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index 4f1edaa..c0dd17f 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -377,13 +377,18 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, desc ~ " `%s` assigned to non-scope parameter calling `assert()`", v); return; } + + bool isThis = fdc && fdc.needThis() && fdc.vthis == vPar; // implicit `this` parameter to member function + const(char)* msg = + (isThis) ? (desc ~ " `%s` calling non-scope member function `%s.%s()`") : (fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`") : (fdc && !parId) ? (desc ~ " `%s` assigned to non-scope anonymous parameter calling `%s`") : (!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") : (desc ~ " `%s` assigned to non-scope anonymous parameter"); - if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc)) + auto param = isThis ? v : (parId ? parId : fdc); + if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, param, fdc)) { result = true; printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10); @@ -1746,20 +1751,8 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re /* Check each argument that is * passed as 'return scope'. */ - Type t1 = e.e1.type.toBasetype(); - TypeFunction tf; - TypeDelegate dg; - if (t1.ty == Tdelegate) - { - dg = t1.isTypeDelegate(); - tf = dg.next.isTypeFunction(); - } - else if (t1.ty == Tfunction) - tf = t1.isTypeFunction(); - else - return; - - if (!e.type.hasPointers()) + TypeFunction tf = e.calledFunctionType(); + if (!tf || !e.type.hasPointers()) return; if (e.arguments && e.arguments.length) @@ -1815,6 +1808,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re } } // If 'this' is returned, check it too + Type t1 = e.e1.type.toBasetype(); if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction) { DotVarExp dve = e.e1.isDotVarExp(); @@ -1880,7 +1874,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re /* If returning the result of a delegate call, the .ptr * field of the delegate must be checked. */ - if (dg) + if (t1.isTypeDelegate()) { if (tf.isreturn) escapeByValue(e.e1, er, live, retRefTransition); @@ -2066,13 +2060,8 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR /* If the function returns by ref, check each argument that is * passed as 'return ref'. */ - Type t1 = e.e1.type.toBasetype(); - TypeFunction tf; - if (t1.ty == Tdelegate) - tf = t1.isTypeDelegate().next.isTypeFunction(); - else if (t1.ty == Tfunction) - tf = t1.isTypeFunction(); - else + TypeFunction tf = e.calledFunctionType(); + if (!tf) return; if (tf.isref) { @@ -2107,6 +2096,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR } } // If 'this' is returned by ref, check it too + Type t1 = e.e1.type.toBasetype(); if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction) { DotVarExp dve = e.e1.isDotVarExp(); diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 067d22f..473efb8 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -19,7 +19,6 @@ import core.stdc.string; import dmd.aggregate; import dmd.aliasthis; -import dmd.apply; import dmd.arrayop; import dmd.arraytypes; import dmd.astenums; @@ -56,6 +55,7 @@ import dmd.nspace; import dmd.objc; import dmd.opover; import dmd.optimize; +import dmd.postordervisitor; import dmd.root.complex; import dmd.root.ctfloat; import dmd.root.filename; @@ -699,6 +699,20 @@ VarDeclaration expToVariable(Expression e) case EXP.super_: return (cast(ThisExp)e).var.isVarDeclaration(); + // Temporaries for rvalues that need destruction + // are of form: (T s = rvalue, s). For these cases + // we can just return var declaration of `s`. However, + // this is intentionally not calling `Expression.extractLast` + // because at this point we cannot infer the var declaration + // of more complex generated comma expressions such as the + // one for the array append hook. + case EXP.comma: + { + if (auto ve = e.isCommaExp().e2.isVarExp()) + return ve.var.isVarDeclaration(); + + return null; + } default: return null; } @@ -723,7 +737,6 @@ extern (C++) abstract class Expression : ASTNode Type type; // !=null means that semantic() has been run Loc loc; // file location const EXP op; // to minimize use of dynamic_cast - bool parens; // if this is a parenthesized expression extern (D) this(const ref Loc loc, EXP op) scope { @@ -1530,6 +1543,11 @@ extern (C++) abstract class Expression : ASTNode return false; if (sc.flags & (SCOPE.ctfe | SCOPE.debug_)) return false; + /* The original expression (`new S(...)`) will be verified instead. This + * is to keep errors related to the original code and not the lowering. + */ + if (f.ident == Id._d_newitemT) + return false; if (!f.isNogc()) { @@ -2338,6 +2356,7 @@ extern (C++) final class ComplexExp : Expression extern (C++) class IdentifierExp : Expression { Identifier ident; + bool parens; // if it appears as (identifier) extern (D) this(const ref Loc loc, Identifier ident) scope { @@ -3520,6 +3539,8 @@ extern (C++) final class CompoundLiteralExp : Expression */ extern (C++) final class TypeExp : Expression { + bool parens; // if this is a parenthesized expression + extern (D) this(const ref Loc loc, Type type) { super(loc, EXP.type); @@ -3672,7 +3693,7 @@ extern (C++) final class NewExp : Expression bool onstack; // allocate on stack bool thrownew; // this NewExp is the expression of a ThrowStatement - Expression lowering; // lowered druntime hook: `_d_newclass` + Expression lowering; // lowered druntime hook: `_d_new{class,itemT}` /// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around. /// The fields are still separate for backwards compatibility @@ -5188,6 +5209,7 @@ extern (C++) final class CallExp : UnaExp bool directcall; // true if a virtual call is devirtualized bool inDebugStatement; /// true if this was in a debug statement bool ignoreAttributes; /// don't enforce attributes (e.g. call @gc function in @nogc code) + bool isUfcsRewrite; /// the first argument was pushed in here by a UFCS rewrite VarDeclaration vthis2; // container for multi-context /// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around. @@ -5329,6 +5351,26 @@ extern (C++) final class CallExp : UnaExp } } +/** + * Get the called function type from a call expression + * Params: + * ce = function call expression. Must have had semantic analysis done. + * Returns: called function type, or `null` if error / no semantic analysis done + */ +TypeFunction calledFunctionType(CallExp ce) +{ + Type t = ce.e1.type; + if (!t) + return null; + t = t.toBasetype(); + if (auto tf = t.isTypeFunction()) + return tf; + else if (auto td = t.isTypeDelegate()) + return td.nextOf().isTypeFunction(); + else + return null; +} + FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null) { if (auto ae = e.isAddrExp()) @@ -7058,9 +7100,7 @@ extern (C++) final class FileInitExp : DefaultInitExp s = loc.isValid() ? loc.filename : sc._module.ident.toChars(); Expression e = new StringExp(loc, s.toDString()); - e = e.expressionSemantic(sc); - e = e.castTo(sc, type); - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) @@ -7082,8 +7122,7 @@ extern (C++) final class LineInitExp : DefaultInitExp override Expression resolveLoc(const ref Loc loc, Scope* sc) { Expression e = new IntegerExp(loc, loc.linnum, Type.tint32); - e = e.castTo(sc, type); - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) @@ -7106,9 +7145,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp { const auto s = (sc.callsc ? sc.callsc : sc)._module.toPrettyChars().toDString(); Expression e = new StringExp(loc, s); - e = e.expressionSemantic(sc); - e = e.castTo(sc, type); - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) @@ -7137,9 +7174,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp else s = ""; Expression e = new StringExp(loc, s.toDString()); - e = e.expressionSemantic(sc); - e.type = Type.tstring; - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index a4b18b9..770c3e7 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -83,7 +83,6 @@ public: Type *type; // !=NULL means that semantic() has been run Loc loc; // file location EXP op; // to minimize use of dynamic_cast - d_bool parens; // if this is a parenthesized expression size_t size() const; static void _init(); @@ -316,6 +315,7 @@ class IdentifierExp : public Expression { public: Identifier *ident; + d_bool parens; static IdentifierExp *create(const Loc &loc, Identifier *ident); bool isLvalue() override final; @@ -839,6 +839,7 @@ public: d_bool directcall; // true if a virtual call is devirtualized d_bool inDebugStatement; // true if this was in a debug statement d_bool ignoreAttributes; // don't enforce attributes (e.g. call @gc function in @nogc code) + d_bool isUfcsRewrite; // the first argument was pushed in here by a UFCS rewrite VarDeclaration *vthis2; // container for multi-context static CallExp *create(const Loc &loc, Expression *e, Expressions *exps); diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index cf4aac4..8ac8866 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -653,7 +653,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) if (!ce.names) ce.names = new Identifiers(); ce.names.shift(null); - + ce.isUfcsRewrite = true; return null; } @@ -1254,12 +1254,12 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = return ErrorExp.get(); e2 = resolveProperties(sc, e2); - Expressions a; + Expressions* a = new Expressions(); a.push(e2); for (size_t i = 0; i < os.a.length; i++) { - if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet)) + if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet)) { if (f.errors) return ErrorExp.get(); @@ -1378,10 +1378,10 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = return ErrorExp.get(); e2 = resolveProperties(sc, e2); - Expressions a; + Expressions* a = new Expressions(); a.push(e2); - FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet); + FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet); if (fd && fd.type) { if (fd.errors) @@ -3574,6 +3574,51 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor result = exp; } + /** + * Sets the `lowering` field of a `NewExp` to a call to `_d_newitemT` unless + * compiling with `-betterC` or within `__traits(compiles)`. + * + * Params: + * ne = the `NewExp` to lower + */ + private void tryLowerToNewItem(NewExp ne) + { + if (global.params.betterC || !sc.needsCodegen()) + return; + + auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT; + if (!verifyHookExist(ne.loc, *sc, hook, "new struct")) + return; + + /* Lower the memory allocation and initialization of `new T()` to + * `_d_newitemT!T()`. + */ + Expression id = new IdentifierExp(ne.loc, Id.empty); + id = new DotIdExp(ne.loc, id, Id.object); + auto tiargs = new Objects(); + /* + * Remove `inout`, `const`, `immutable` and `shared` to reduce the + * number of generated `_d_newitemT` instances. + */ + auto t = ne.type.nextOf.unqualify(MODFlags.wild | MODFlags.const_ | + MODFlags.immutable_ | MODFlags.shared_); + tiargs.push(t); + id = new DotTemplateInstanceExp(ne.loc, id, hook, tiargs); + + auto arguments = new Expressions(); + if (global.params.tracegc) + { + auto funcname = (sc.callsc && sc.callsc.func) ? + sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars(); + arguments.push(new StringExp(ne.loc, ne.loc.filename.toDString())); + arguments.push(new IntegerExp(ne.loc, ne.loc.linnum, Type.tint32)); + arguments.push(new StringExp(ne.loc, funcname.toDString())); + } + id = new CallExp(ne.loc, id, arguments); + + ne.lowering = id.expressionSemantic(sc); + } + override void visit(NewExp exp) { static if (LOGSEMANTIC) @@ -4007,6 +4052,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } exp.type = exp.type.pointerTo(); + tryLowerToNewItem(exp); } else if (tb.ty == Tarray) { @@ -4078,6 +4124,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } exp.type = exp.type.pointerTo(); + tryLowerToNewItem(exp); } else if (tb.ty == Taarray) { @@ -5192,7 +5239,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { s = (cast(TemplateExp)exp.e1).td; L2: - exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList, FuncResolveFlag.standard); + exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList, + exp.isUfcsRewrite ? FuncResolveFlag.ufcs : FuncResolveFlag.standard); if (!exp.f || exp.f.errors) return setError(); if (exp.f.needThis()) @@ -5301,6 +5349,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor buf.writeByte(')'); //printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco); + if (exp.isUfcsRewrite) + { + const arg = (*exp.argumentList.arguments)[0]; + .error(exp.loc, "no property `%s` for `%s` of type `%s`", exp.f.ident.toChars(), arg.toChars(), arg.type.toChars()); + .errorSupplemental(exp.loc, "the following error occured while looking for a UFCS match"); + } + .error(exp.loc, "%s `%s%s` is not callable using argument types `%s`", exp.f.kind(), exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList), buf.peekChars()); if (failMessage) @@ -6733,7 +6788,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.ident != Id.__sizeof) { - result = fieldLookup(exp.e1, sc, exp.ident); + result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow); return; } } @@ -9068,7 +9123,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor else if (sc.flags & SCOPE.Cfile && e1x.isDotIdExp()) { auto die = e1x.isDotIdExp(); - e1x = fieldLookup(die.e1, sc, die.ident); + e1x = fieldLookup(die.e1, sc, die.ident, die.arrow); } else if (auto die = e1x.isDotIdExp()) { @@ -11023,7 +11078,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be * used with `-betterC`, but only during CTFE. */ - if (global.params.betterC) + if (global.params.betterC || !sc.needsCodegen()) return; if (auto ce = exp.isCatExp()) @@ -13175,10 +13230,20 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag) Expression se = new ScopeExp(exp.loc, imp.pkg); return se.expressionSemantic(sc); } + + if (auto attr = s.isAttribDeclaration()) + { + if (auto sm = ie.sds.search(exp.loc, exp.ident, flags)) + { + auto es = new DsymbolExp(exp.loc, sm); + return es; + } + } + // BUG: handle other cases like in IdentifierExp::semantic() debug { - printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind()); + printf("s = %p '%s', kind = '%s'\n", s, s.toChars(), s.kind()); } assert(0); } diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d index 7a96469..1293057 100644 --- a/gcc/d/dmd/foreachvar.d +++ b/gcc/d/dmd/foreachvar.d @@ -15,7 +15,6 @@ import core.stdc.stdio; import core.stdc.stdlib; import core.stdc.string; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; @@ -33,6 +32,7 @@ import dmd.identifier; import dmd.init; import dmd.initsem; import dmd.mtype; +import dmd.postordervisitor; import dmd.printast; import dmd.root.array; import dmd.root.rootobject; diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 8e11ab1..a714d2d 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -59,6 +59,10 @@ import dmd.statementsem; import dmd.tokens; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + /// Inline Status enum ILS : ubyte { @@ -259,21 +263,30 @@ extern (C++) struct Ensure } /*********************************************************** + * Most functions don't have contracts, so save memory by grouping + * this information into a separate struct */ -extern (C++) class FuncDeclaration : Declaration +private struct ContractInfo { Statements* frequires; /// in contracts Ensures* fensures; /// out contracts Statement frequire; /// lowered in contract Statement fensure; /// lowered out contract - Statement fbody; /// function body - - FuncDeclarations foverrides; /// functions this function overrides FuncDeclaration fdrequire; /// function that does the in contract FuncDeclaration fdensure; /// function that does the out contract - Expressions* fdrequireParams; /// argument list for __require Expressions* fdensureParams; /// argument list for __ensure +} + +/*********************************************************** + */ +extern (C++) class FuncDeclaration : Declaration +{ + Statement fbody; /// function body + + FuncDeclarations foverrides; /// functions this function overrides + + private ContractInfo* contracts; /// contract information const(char)* mangleString; /// mangled symbol created from mangleExact() @@ -403,6 +416,44 @@ extern (C++) class FuncDeclaration : Declaration return new FuncDeclaration(loc, endloc, id, storage_class, type, noreturn); } + final nothrow pure @safe + { + private ref ContractInfo getContracts() + { + if (!contracts) + contracts = new ContractInfo(); + return *contracts; + } + + // getters + inout(Statements*) frequires() inout { return contracts ? contracts.frequires : null; } + inout(Ensures*) fensures() inout { return contracts ? contracts.fensures : null; } + inout(Statement) frequire() inout { return contracts ? contracts.frequire: null; } + inout(Statement) fensure() inout { return contracts ? contracts.fensure : null; } + inout(FuncDeclaration) fdrequire() inout { return contracts ? contracts.fdrequire : null; } + inout(FuncDeclaration) fdensure() inout { return contracts ? contracts.fdensure: null; } + inout(Expressions*) fdrequireParams() inout { return contracts ? contracts.fdrequireParams: null; } + inout(Expressions*) fdensureParams() inout { return contracts ? contracts.fdensureParams: null; } + + extern (D) private static string generateContractSetter(string field, string type) + { + return type ~ " " ~ field ~ "(" ~ type ~ " param)" ~ + "{ + if (!param && !contracts) return null; + return getContracts()." ~ field ~ " = param; + }"; + } + + mixin(generateContractSetter("frequires", "Statements*")); + mixin(generateContractSetter("fensures", "Ensures*")); + mixin(generateContractSetter("frequire", "Statement")); + mixin(generateContractSetter("fensure", "Statement")); + mixin(generateContractSetter("fdrequire", "FuncDeclaration")); + mixin(generateContractSetter("fdensure", "FuncDeclaration")); + mixin(generateContractSetter("fdrequireParams", "Expressions*")); + mixin(generateContractSetter("fdensureParams", "Expressions*")); + } + override FuncDeclaration syntaxCopy(Dsymbol s) { //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars()); @@ -2717,7 +2768,7 @@ extern (C++) class FuncDeclaration : Declaration */ static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0) { - return genCfunc(fparams, treturn, Identifier.idPool(name, cast(uint)strlen(name)), stc); + return genCfunc(fparams, treturn, Identifier.idPool(name[0 .. strlen(name)]), stc); } static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = 0) @@ -3199,6 +3250,7 @@ enum FuncResolveFlag : ubyte quiet = 1, /// do not issue error message on no match, just return `null`. overloadOnly = 2, /// only resolve overloads, i.e. do not issue error on ambiguous /// matches and need explicit this. + ufcs = 4, /// trying to resolve UFCS call } /******************************************* @@ -3316,12 +3368,22 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, } // no match, generate an error messages + if (flags & FuncResolveFlag.ufcs) + { + auto arg = (*fargs)[0]; + .error(loc, "no property `%s` for `%s` of type `%s`", s.ident.toChars(), arg.toChars(), arg.type.toChars()); + .errorSupplemental(loc, "the following error occured while looking for a UFCS match"); + } + if (!fd) { // all of overloads are templates if (td) { - .error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`", + const(char)* msg = "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`"; + if (!od && !td.overnext) + msg = "%s `%s.%s` is not callable using argument types `!(%s)%s`"; + .error(loc, msg, td.kind(), td.parent.toPrettyChars(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars()); diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 45b4528..0ac6042 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -26,6 +26,10 @@ import dmd.location; import dmd.lexer : CompileEnv; import dmd.utils; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + /// Defines a setting for how compiler warnings and deprecations are handled enum DiagnosticReporting : ubyte { diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 902cf83..66345ac 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -353,10 +353,11 @@ typedef unsigned long long uinteger_t; // file location struct Loc { - const char *filename; // either absolute or relative to cwd - unsigned linnum; - unsigned charnum; - +private: + unsigned _linnum; + unsigned short _charnum; + unsigned short fileIndex; +public: static void set(bool showColumns, MessageStyle messageStyle); static bool showColumns; @@ -364,18 +365,25 @@ struct Loc Loc() { - linnum = 0; - charnum = 0; - filename = NULL; + _linnum = 0; + _charnum = 0; + fileIndex = 0; } Loc(const char *filename, unsigned linnum, unsigned charnum) { - this->linnum = linnum; - this->charnum = charnum; - this->filename = filename; + this->linnum(linnum); + this->charnum(charnum); + this->filename(filename); } + uint32_t charnum() const; + uint32_t charnum(uint32_t num); + uint32_t linnum() const; + uint32_t linnum(uint32_t num); + const char *filename() const; + void filename(const char *name); + const char *toChars( bool showColumns = Loc::showColumns, MessageStyle messageStyle = Loc::messageStyle) const; diff --git a/gcc/d/dmd/gluelayer.d b/gcc/d/dmd/gluelayer.d index 7b52eff..1793700 100644 --- a/gcc/d/dmd/gluelayer.d +++ b/gcc/d/dmd/gluelayer.d @@ -48,25 +48,6 @@ version (NoBackend) } } } -else version (MARS) -{ - public import dmd.backend.cc : block, Blockx, Symbol; - public import dmd.backend.type : type; - public import dmd.backend.el : elem; - public import dmd.backend.code_x86 : code; - - extern (C++) - { - Statement asmSemantic(AsmStatement s, Scope* sc); - - void toObjFile(Dsymbol ds, bool multiobj); - - extern(C++) abstract class ObjcGlue - { - static void initialize(); - } - } -} else version (IN_GCC) { extern (C++) union tree_node; @@ -88,4 +69,12 @@ else version (IN_GCC) } } else - static assert(false, "Unsupported compiler backend"); +{ + public import dmd.backend.cc : block, Blockx, Symbol; + public import dmd.backend.type : type; + public import dmd.backend.el : elem; + public import dmd.backend.code_x86 : code; + public import dmd.iasm : asmSemantic; + public import dmd.objc_glue : ObjcGlue; + public import dmd.toobj : toObjFile; +} diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d index 66829da..1fdfe40 100644 --- a/gcc/d/dmd/iasm.d +++ b/gcc/d/dmd/iasm.d @@ -23,13 +23,14 @@ import dmd.tokens; import dmd.statement; import dmd.statementsem; -version (MARS) +version (IN_GCC) { - import dmd.iasmdmd; + import dmd.iasmgcc; } -else version (IN_GCC) +else { - import dmd.iasmgcc; + import dmd.iasmdmd; + version = MARS; } /************************ AsmStatement ***************************************/ diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d index a2271d5..a2daf60 100644 --- a/gcc/d/dmd/id.d +++ b/gcc/d/dmd/id.d @@ -315,6 +315,8 @@ immutable Msgtable[] msgtable = { "_d_newThrowable" }, { "_d_newclassT" }, { "_d_newclassTTrace" }, + { "_d_newitemT" }, + { "_d_newitemTTrace" }, { "_d_assert_fail" }, { "dup" }, { "_aaApply" }, @@ -549,6 +551,7 @@ immutable Msgtable[] msgtable = { "_pure", "pure" }, { "define" }, { "undef" }, + { "ident" }, ]; diff --git a/gcc/d/dmd/identifier.d b/gcc/d/dmd/identifier.d index 2233d77..b1c421c 100644 --- a/gcc/d/dmd/identifier.d +++ b/gcc/d/dmd/identifier.d @@ -274,12 +274,7 @@ nothrow: return idPool(s[0 .. len]); } - extern (D) static Identifier idPool(const(char)[] s) - { - return idPool(s, false); - } - - extern (D) private static Identifier idPool(const(char)[] s, bool isAnonymous) + extern (D) static Identifier idPool(const(char)[] s, bool isAnonymous = false) { auto sv = stringtable.update(s); auto id = sv.value; @@ -291,18 +286,18 @@ nothrow: return id; } - extern (D) static Identifier idPool(const(char)* s, size_t len, int value) - { - return idPool(s[0 .. len], value); - } - - extern (D) static Identifier idPool(const(char)[] s, int value) + /****************************************** + * Used for inserting keywords into the string table. + * Params: + * s = string for keyword + * value = TOK.xxxx for the keyword + */ + extern (D) static void idPool(const(char)[] s, TOK value) { auto sv = stringtable.insert(s, null); assert(sv); auto id = new Identifier(sv.toString(), value); sv.value = id; - return id; } /********************************** diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d index 97710b8..fe0aa17 100644 --- a/gcc/d/dmd/importc.d +++ b/gcc/d/dmd/importc.d @@ -108,11 +108,12 @@ Expression arrayFuncConv(Expression e, Scope* sc) * e = evaluates to an instance of a struct * sc = context * id = identifier of a field in that struct + * arrow = -> was used * Returns: * if successful `e.ident` * if not then `ErrorExp` and message is printed */ -Expression fieldLookup(Expression e, Scope* sc, Identifier id) +Expression fieldLookup(Expression e, Scope* sc, Identifier id, bool arrow) { e = e.expressionSemantic(sc); if (e.isErrorExp()) @@ -123,6 +124,9 @@ Expression fieldLookup(Expression e, Scope* sc, Identifier id) if (t.isTypePointer()) { t = t.isTypePointer().next; + auto pe = e.toChars(); + if (!arrow) + e.error("since `%s` is a pointer, use `%s->%s` instead of `%s.%s`", pe, pe, id.toChars(), pe, id.toChars()); e = new PtrExp(e.loc, e); } if (auto ts = t.isTypeStruct()) @@ -237,15 +241,16 @@ Expression castCallAmbiguity(Expression e, Scope* sc) case EXP.call: auto ce = (*pe).isCallExp(); - if (ce.e1.parens) + auto ie = ce.e1.isIdentifierExp(); + if (ie && ie.parens) { - ce.e1 = expressionSemantic(ce.e1, sc); + ce.e1 = expressionSemantic(ie, sc); if (ce.e1.op == EXP.type) { const numArgs = ce.arguments ? ce.arguments.length : 0; if (numArgs >= 1) { - ce.e1.parens = false; + ie.parens = false; Expression arg; foreach (a; (*ce.arguments)[]) { diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index 893d2a6..ca770bd 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -587,6 +587,9 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ */ t = t.toBasetype(); + if (auto tv = t.isTypeVector()) + t = tv.basetype; + /* If `{ expression }` return the expression initializer */ ExpInitializer isBraceExpression() diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 0ec468b..a878cc9 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -119,7 +119,7 @@ class Lexer this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, bool doDocComment, bool commentToken, ErrorSink errorSink, - const CompileEnv* compileEnv) pure scope + const CompileEnv* compileEnv) scope { scanloc = Loc(filename, 1, 1); // debug printf("Lexer::Lexer(%p)\n", base); @@ -573,7 +573,7 @@ class Lexer } break; } - Identifier id = Identifier.idPool(cast(char*)t.ptr, cast(uint)(p - t.ptr)); + Identifier id = Identifier.idPool((cast(char*)t.ptr)[0 .. p - t.ptr], false); t.ident = id; t.value = cast(TOK)id.getValue(); @@ -2672,9 +2672,9 @@ class Lexer return result; } - final Loc loc() pure @nogc + final Loc loc() @nogc { - scanloc.charnum = cast(uint)(1 + p - line); + scanloc.charnum = cast(ushort)(1 + p - line); version (LocOffset) scanloc.fileOffset = cast(uint)(p - base); return scanloc; @@ -3098,9 +3098,9 @@ class Lexer /************************** * `p` should be at start of next line */ - private void endOfLine() pure @nogc @safe + private void endOfLine() @nogc @safe { - scanloc.linnum++; + scanloc.linnum = scanloc.linnum + 1; line = p; } } diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d index 020d297..b2b3661 100644 --- a/gcc/d/dmd/location.d +++ b/gcc/d/dmd/location.d @@ -11,7 +11,10 @@ module dmd.location; +import core.stdc.stdio; + import dmd.common.outbuffer; +import dmd.root.array; import dmd.root.filename; version (DMDLIB) @@ -34,10 +37,9 @@ debug info etc. */ struct Loc { - /// zero-terminated filename string, either absolute or relative to cwd - const(char)* filename; - uint linnum; /// line number, starting from 1 - uint charnum; /// utf8 code unit index relative to start of line, starting from 1 + private uint _linnum; + private ushort _charnum; + private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename) version (LocOffset) uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0 @@ -46,6 +48,8 @@ struct Loc extern (C++) __gshared bool showColumns; extern (C++) __gshared MessageStyle messageStyle; + __gshared Array!(const(char)*) filenames; + nothrow: /******************************* @@ -60,19 +64,69 @@ nothrow: this.messageStyle = messageStyle; } - extern (D) this(const(char)* filename, uint linnum, uint charnum) pure + extern (D) this(const(char)* filename, uint linnum, uint charnum) { - this.linnum = linnum; - this.charnum = charnum; + this._linnum = linnum; + this._charnum = cast(ushort) charnum; this.filename = filename; } + /// utf8 code unit index relative to start of line, starting from 1 + extern (C++) uint charnum() const @nogc @safe + { + return _charnum; + } + + /// ditto + extern (C++) uint charnum(uint num) @nogc @safe + { + return _charnum = cast(ushort) num; + } + + /// line number, starting from 1 + extern (C++) uint linnum() const @nogc @safe + { + return _linnum; + } + + /// ditto + extern (C++) uint linnum(uint num) @nogc @safe + { + return _linnum = num; + } + + /*** + * Returns: filename for this location, null if none + */ + extern (C++) const(char)* filename() const @nogc + { + return fileIndex ? filenames[fileIndex - 1] : null; + } + + /*** + * Set file name for this location + * Params: + * name = file name for location, null for no file name + */ + extern (C++) void filename(const(char)* name) + { + if (name) + { + //printf("setting %s\n", name); + filenames.push(name); + fileIndex = cast(ushort)filenames.length; + assert(fileIndex); // no overflow + } + else + fileIndex = 0; + } + extern (C++) const(char)* toChars( bool showColumns = Loc.showColumns, - MessageStyle messageStyle = Loc.messageStyle) const pure nothrow + MessageStyle messageStyle = Loc.messageStyle) const nothrow { OutBuffer buf; - if (filename) + if (fileIndex) { buf.writestring(filename); } @@ -126,7 +180,7 @@ nothrow: * may lead to multiple equivalent filenames (`foo.d-mixin-`), * e.g., for test/runnable/test18880.d. */ - extern (D) bool opEquals(ref const(Loc) loc) const @trusted pure nothrow @nogc + extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc { import core.stdc.string : strcmp; @@ -137,7 +191,7 @@ nothrow: } /// ditto - extern (D) size_t toHash() const @trusted pure nothrow + extern (D) size_t toHash() const @trusted nothrow { import dmd.root.string : toDString; @@ -153,6 +207,6 @@ nothrow: */ bool isValid() const pure { - return filename !is null; + return fileIndex != 0; } } diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index badc579..cb3e6cd 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -2448,7 +2448,7 @@ extern (C++) abstract class Type : ASTNode //printf("%p %s, deco = %s, name = %s\n", this, toChars(), deco, name); assert(0 < length && length < namelen); // don't overflow the buffer - auto id = Identifier.idPool(name, length); + auto id = Identifier.idPool(name[0 .. length]); if (name != namebuf.ptr) free(name); @@ -7119,9 +7119,9 @@ bool isCopyable(Type t) assert(ctor); scope el = new IdentifierExp(Loc.initial, Id.p); // dummy lvalue el.type = cast() ts; - Expressions args; + Expressions* args = new Expressions(); args.push(el); - FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(&args), FuncResolveFlag.quiet); + FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(args), FuncResolveFlag.quiet); if (!f || f.storage_class & STC.disable) return false; } diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index a0f3e60..9a8f242 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -16,7 +16,6 @@ module dmd.nogc; import core.stdc.stdio; import dmd.aggregate; -import dmd.apply; import dmd.astenums; import dmd.declaration; import dmd.dscope; @@ -26,6 +25,7 @@ import dmd.func; import dmd.globals; import dmd.init; import dmd.mtype; +import dmd.postordervisitor; import dmd.tokens; import dmd.visitor; diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d index 89728b6..56243a0 100644 --- a/gcc/d/dmd/ob.d +++ b/gcc/d/dmd/ob.d @@ -20,7 +20,6 @@ import dmd.root.rootobject; import dmd.root.rmem; import dmd.aggregate; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.declaration; diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d index d7b90d7..0e64d9c 100644 --- a/gcc/d/dmd/opover.d +++ b/gcc/d/dmd/opover.d @@ -607,8 +607,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) //printf("BinExp::op_overload() (%s)\n", e.toChars()); Identifier id = opId(e); Identifier id_r = opId_r(e); - Expressions args1; - Expressions args2; int argsset = 0; AggregateDeclaration ad1 = isAggregate(e.e1.type); AggregateDeclaration ad2 = isAggregate(e.e2.type); @@ -701,6 +699,8 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) } } } + Expressions* args1 = new Expressions(); + Expressions* args2 = new Expressions(); if (s || s_r) { /* Try: @@ -709,16 +709,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) * and see which is better. */ args1.setDim(1); - args1[0] = e.e1; - expandTuples(&args1); + (*args1)[0] = e.e1; + expandTuples(args1); args2.setDim(1); - args2[0] = e.e2; - expandTuples(&args2); + (*args2)[0] = e.e2; + expandTuples(args2); argsset = 1; MatchAccumulator m; if (s) { - functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -727,7 +727,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) FuncDeclaration lastf = m.lastf; if (s_r) { - functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1)); + functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -791,16 +791,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (!argsset) { args1.setDim(1); - args1[0] = e.e1; - expandTuples(&args1); + (*args1)[0] = e.e1; + expandTuples(args1); args2.setDim(1); - args2[0] = e.e2; - expandTuples(&args2); + (*args2)[0] = e.e2; + expandTuples(args2); } MatchAccumulator m; if (s_r) { - functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -809,7 +809,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) FuncDeclaration lastf = m.lastf; if (s) { - functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1)); + functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -1197,7 +1197,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) return ErrorExp.get(); } Identifier id = opId(e); - Expressions args2; + Expressions* args2 = new Expressions(); AggregateDeclaration ad1 = isAggregate(e.e1.type); Dsymbol s = null; Objects* tiargs = null; @@ -1240,10 +1240,10 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) * a.opOpAssign(b) */ args2.setDim(1); - args2[0] = e.e2; - expandTuples(&args2); + (*args2)[0] = e.e2; + expandTuples(args2); MatchAccumulator m; - functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -1322,12 +1322,12 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop * b.opEquals(a) * and see which is better. */ - Expressions args1 = Expressions(1); - args1[0] = e.e1; - expandTuples(&args1); - Expressions args2 = Expressions(1); - args2[0] = e.e2; - expandTuples(&args2); + Expressions* args1 = new Expressions(1); + (*args1)[0] = e.e1; + expandTuples(args1); + Expressions* args2 = new Expressions(1); + (*args2)[0] = e.e2; + expandTuples(args2); MatchAccumulator m; if (0 && s && s_r) { @@ -1336,7 +1336,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop } if (s) { - functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) return ErrorExp.get(); } @@ -1344,7 +1344,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop int count = m.count; if (s_r) { - functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1)); + functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) return ErrorExp.get(); } diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index 61c385f..335310d 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -769,11 +769,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) return; if (e.arguments) { - Type t1 = e.e1.type.toBasetype(); - if (auto td = t1.isTypeDelegate()) - t1 = td.next; // t1 can apparently be void for __ArrayDtor(T) calls - if (auto tf = t1.isTypeFunction()) + if (auto tf = e.calledFunctionType()) { foreach (i, ref arg; (*e.arguments)[]) { diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index 68a2506..b7e0791 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -4515,10 +4515,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } if (_init) { - if (isThis) - error(token.loc, "cannot use syntax `alias this = %s`, use `alias %s this` instead", _init.toChars(), _init.toChars()); - else - error("alias cannot have initializer"); + error("alias cannot have initializer"); } v = new AST.AliasDeclaration(aliasLoc, ident, t); @@ -4780,23 +4777,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer addComment(s, comment); return a; } - version (none) + /* Look for: + * alias this = identifier; + */ + if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier) { - /* Look for: - * alias this = identifier; - */ - if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier) - { - check(TOK.this_); - check(TOK.assign); - auto s = new AliasThis(loc, token.ident); - nextToken(); - check(TOK.semicolon, "`alias this = Identifier`"); - auto a = new Dsymbols(); - a.push(s); - addComment(s, comment); - return a; - } + check(TOK.this_); + check(TOK.assign); + auto s = new AST.AliasThis(loc, token.ident); + nextToken(); + check(TOK.semicolon, "`alias this = Identifier`"); + auto a = new AST.Dsymbols(); + a.push(s); + addComment(s, comment); + return a; } /* Look for: * alias identifier = type; @@ -5032,7 +5026,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer stc = STC.ref_; nextToken(); } - if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly) + if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly && + token.value != TOK.goesTo) { // function type (parameters) { statements... } // delegate type (parameters) { statements... } @@ -5331,7 +5326,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer error("cannot use function constraints for non-template functions. Use `static if` instead"); } else - error("semicolon expected following function declaration"); + error("semicolon expected following function declaration, not `%s`", token.toChars()); } break; } @@ -7081,7 +7076,7 @@ LagainStc: private void checkParens(TOK value, AST.Expression e) { - if (precedence[e.op] == PREC.rel && !e.parens) + if (precedence[e.op] == PREC.rel) error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(value)); } @@ -8485,7 +8480,6 @@ LagainStc: // ( expression ) nextToken(); e = parseExpression(); - e.parens = true; check(loc, TOK.rightParenthesis); break; } @@ -8806,9 +8800,9 @@ LagainStc: nextToken(); return AST.ErrorExp.get(); } - e = new AST.TypeExp(loc, t); - e.parens = true; - e = parsePostExp(e); + auto te = new AST.TypeExp(loc, t); + te.parens = true; + e = parsePostExp(te); } else { @@ -9115,14 +9109,18 @@ LagainStc: private AST.Expression parseAndExp() { Loc loc = token.loc; + bool parens = token.value == TOK.leftParenthesis; auto e = parseCmpExp(); while (token.value == TOK.and) { - checkParens(TOK.and, e); - nextToken(); + if (!parens) + checkParens(TOK.and, e); + parens = nextToken() == TOK.leftParenthesis; auto e2 = parseCmpExp(); - checkParens(TOK.and, e2); + if (!parens) + checkParens(TOK.and, e2); e = new AST.AndExp(loc, e, e2); + parens = true; // don't call checkParens() for And loc = token.loc; } return e; @@ -9130,32 +9128,42 @@ LagainStc: private AST.Expression parseXorExp() { - const loc = token.loc; + Loc loc = token.loc; + bool parens = token.value == TOK.leftParenthesis; auto e = parseAndExp(); while (token.value == TOK.xor) { - checkParens(TOK.xor, e); - nextToken(); + if (!parens) + checkParens(TOK.xor, e); + parens = nextToken() == TOK.leftParenthesis; auto e2 = parseAndExp(); - checkParens(TOK.xor, e2); + if (!parens) + checkParens(TOK.xor, e2); e = new AST.XorExp(loc, e, e2); + parens = true; + loc = token.loc; } return e; } private AST.Expression parseOrExp() { - const loc = token.loc; + Loc loc = token.loc; + bool parens = token.value == TOK.leftParenthesis; auto e = parseXorExp(); while (token.value == TOK.or) { - checkParens(TOK.or, e); - nextToken(); + if (!parens) + checkParens(TOK.or, e); + parens = nextToken() == TOK.leftParenthesis; auto e2 = parseXorExp(); - checkParens(TOK.or, e2); + if (!parens) + checkParens(TOK.or, e2); e = new AST.OrExp(loc, e, e2); + parens = true; + loc = token.loc; } return e; } @@ -9206,6 +9214,7 @@ LagainStc: AST.Expression parseAssignExp() { + bool parens = token.value == TOK.leftParenthesis; AST.Expression e; e = parseCondExp(); if (e is null) @@ -9214,7 +9223,7 @@ LagainStc: // require parens for e.g. `t ? a = 1 : b = 2` void checkRequiredParens() { - if (e.op == EXP.question && !e.parens) + if (e.op == EXP.question && !parens) eSink.error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(token.value)); } diff --git a/gcc/d/dmd/postordervisitor.d b/gcc/d/dmd/postordervisitor.d new file mode 100644 index 0000000..a0c7115 --- /dev/null +++ b/gcc/d/dmd/postordervisitor.d @@ -0,0 +1,153 @@ +/** + * A depth-first visitor for expressions. + * + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved + * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) + * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/apply.d, _apply.d) + * Documentation: https://dlang.org/phobos/dmd_apply.html + * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d + */ + +module dmd.postordervisitor; + +import dmd.arraytypes; +import dmd.dtemplate; +import dmd.expression; +import dmd.root.array; +import dmd.visitor; + +bool walkPostorder(Expression e, StoppableVisitor v) +{ + scope PostorderExpressionVisitor pv = new PostorderExpressionVisitor(v); + e.accept(pv); + return v.stop; +} + +/************************************** + * An Expression tree walker that will visit each Expression e in the tree, + * in depth-first evaluation order, and call fp(e,param) on it. + * fp() signals whether the walking continues with its return value: + * Returns: + * 0 continue + * 1 done + * It's a bit slower than using virtual functions, but more encapsulated and less brittle. + * Creating an iterator for this would be much more complex. + */ +private extern (C++) final class PostorderExpressionVisitor : StoppableVisitor +{ + alias visit = typeof(super).visit; +public: + StoppableVisitor v; + + extern (D) this(StoppableVisitor v) scope + { + this.v = v; + } + + bool doCond(Expression e) + { + if (!stop && e) + e.accept(this); + return stop; + } + + extern(D) bool doCond(Expression[] e) + { + for (size_t i = 0; i < e.length && !stop; i++) + doCond(e[i]); + return stop; + } + + bool applyTo(Expression e) + { + e.accept(v); + stop = v.stop; + return true; + } + + override void visit(Expression e) + { + applyTo(e); + } + + override void visit(NewExp e) + { + //printf("NewExp::apply(): %s\n", toChars()); + doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); + } + + override void visit(NewAnonClassExp e) + { + //printf("NewAnonClassExp::apply(): %s\n", toChars()); + doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); + } + + override void visit(TypeidExp e) + { + doCond(isExpression(e.obj)) || applyTo(e); + } + + override void visit(UnaExp e) + { + doCond(e.e1) || applyTo(e); + } + + override void visit(BinExp e) + { + doCond(e.e1) || doCond(e.e2) || applyTo(e); + } + + override void visit(AssertExp e) + { + //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); + doCond(e.e1) || doCond(e.msg) || applyTo(e); + } + + override void visit(CallExp e) + { + //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); + doCond(e.e1) || doCond(e.arguments.peekSlice()) || applyTo(e); + } + + override void visit(ArrayExp e) + { + //printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars()); + doCond(e.e1) || doCond(e.arguments.peekSlice()) || applyTo(e); + } + + override void visit(SliceExp e) + { + doCond(e.e1) || doCond(e.lwr) || doCond(e.upr) || applyTo(e); + } + + override void visit(ArrayLiteralExp e) + { + doCond(e.basis) || doCond(e.elements.peekSlice()) || applyTo(e); + } + + override void visit(AssocArrayLiteralExp e) + { + doCond(e.keys.peekSlice()) || doCond(e.values.peekSlice()) || applyTo(e); + } + + override void visit(StructLiteralExp e) + { + if (e.stageflags & stageApply) + return; + const old = e.stageflags; + e.stageflags |= stageApply; + doCond(e.elements.peekSlice()) || applyTo(e); + e.stageflags = old; + } + + override void visit(TupleExp e) + { + doCond(e.e0) || doCond(e.exps.peekSlice()) || applyTo(e); + } + + override void visit(CondExp e) + { + doCond(e.econd) || doCond(e.e1) || doCond(e.e2) || applyTo(e); + } +} diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d index ee268d9..c40e72c 100644 --- a/gcc/d/dmd/semantic2.d +++ b/gcc/d/dmd/semantic2.d @@ -447,14 +447,12 @@ private extern(C++) final class Semantic2Visitor : Visitor const sameParams = tf1.parameterList == tf2.parameterList; // Allow the hack to declare overloads with different parameters/STC's - // @@@DEPRECATED_2.104@@@ - // Deprecated in 2020-08, make this an error in 2.104 if (parent1.isModule() && linkage1 != LINK.d && linkage1 != LINK.cpp && (!sameAttr || !sameParams) ) { - f2.deprecation("cannot overload `extern(%s)` function at %s", + f2.error("cannot overload `extern(%s)` function at %s", linkageToChars(f1._linkage), f1.loc.toChars()); return 0; diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d index 3f3e7e6..90b86df 100644 --- a/gcc/d/dmd/sideeffect.d +++ b/gcc/d/dmd/sideeffect.d @@ -11,7 +11,6 @@ module dmd.sideeffect; -import dmd.apply; import dmd.astenums; import dmd.declaration; import dmd.dscope; @@ -22,6 +21,7 @@ import dmd.globals; import dmd.identifier; import dmd.init; import dmd.mtype; +import dmd.postordervisitor; import dmd.tokens; import dmd.visitor; @@ -101,9 +101,11 @@ extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false) int callSideEffectLevel(FuncDeclaration f) { /* https://issues.dlang.org/show_bug.cgi?id=12760 - * ctor call always has side effects. + * https://issues.dlang.org/show_bug.cgi?id=16384 + * + * ctor calls and invariant calls always have side effects */ - if (f.isCtorDeclaration()) + if (f.isCtorDeclaration() || f.isInvariantDeclaration()) return 0; assert(f.type.ty == Tfunction); TypeFunction tf = cast(TypeFunction)f.type; diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index f849ce1..f0454163 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -1273,8 +1273,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) } else if (auto td = sfront.isTemplateDeclaration()) { - Expressions a; - if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(&a), FuncResolveFlag.quiet)) + if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(), FuncResolveFlag.quiet)) tfront = f.type; } else if (auto d = sfront.toAlias().isDeclaration()) @@ -2733,7 +2732,8 @@ Statement statementSemanticVisit(Statement s, Scope* sc) tbret = tret.toBasetype(); } - if (inferRef) // deduce 'auto ref' + // https://issues.dlang.org/show_bug.cgi?id=23914 + if (inferRef && !resType.isTypeNoreturn()) // deduce 'auto ref' tf.isref = false; if (tbret.ty != Tvoid && !resType.isTypeNoreturn()) // if non-void return @@ -3593,6 +3593,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc) cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not"); if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not")) cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not"); + // @@@DEPRECATED_2.114@@@ + // change deprecation() to error(), add `else` and remove `| STC.safe` + // to turn deprecation into an error when deprecation cycle is over + if (cas.stc & STC.safe) + cas.deprecation("`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead"); if (!(cas.stc & (STC.trusted | STC.safe))) { sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not"); @@ -4045,6 +4050,13 @@ void catchSemantic(Catch c, Scope* sc) // reference .object.Throwable c.type = getThrowable(); } + else if (!c.type.isNaked() && !c.type.isConst()) + { + // @@@DEPRECATED_2.113@@@ + // Deprecated in 2.103, change into an error & uncomment in 2.113 + deprecation(c.loc, "can only catch mutable or const qualified types, not `%s`", c.type.toChars()); + //c.errors = true; + } c.type = c.type.typeSemantic(c.loc, sc); if (c.type == Type.terror) { diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index 352c89e..5871762 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -593,7 +593,7 @@ shared static this() nothrow foreach (kw; keywords) { //printf("keyword[%d] = '%s'\n",kw, Token.tochars[kw].ptr); - Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw); + Identifier.idPool(Token.tochars[kw], kw); } } diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index 0f36353..53c8fb0 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -1215,7 +1215,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) { if (fd.overnext) { - deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", fd.toChars()); + deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", fd.toChars()); deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from"); } } @@ -1225,7 +1225,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) { if (td.overnext || td.funcroot) { - deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", td.ident.toChars()); + deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", td.ident.toChars()); deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from"); } } diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d index c588270..a82a268 100644 --- a/gcc/d/dmd/transitivevisitor.d +++ b/gcc/d/dmd/transitivevisitor.d @@ -161,6 +161,16 @@ package mixin template ParseVisitMethods(AST) s._body.accept(this); } + override void visit(AST.StaticForeachStatement s) + { + // printf("Visiting StaticForeachStatement\n"); + if (s.sfe.aggrfe) + s.sfe.aggrfe.accept(this); + + if (s.sfe.rangefe) + s.sfe.rangefe.accept(this); + } + override void visit(AST.IfStatement s) { //printf("Visiting IfStatement\n"); diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index f0decf2..09eef83 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -163,7 +163,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb /* Look for what user might have intended */ const p = mt.mutableOf().unSharedOf().toChars(); - auto id = Identifier.idPool(p, cast(uint)strlen(p)); + auto id = Identifier.idPool(p[0 .. strlen(p)]); if (const n = importHint(id.toString())) error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr); else if (auto s2 = sc.search_correct(id)) diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 23f2f0b..8fb1eea 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -2296,11 +2296,12 @@ public: return; } + /* This case should have been rewritten to `_d_newitemT' during the + semantic phase. */ + gcc_assert (e->lowering); + /* Generate: _d_newitemT() */ - libcall_fn libcall = htype->isZeroInit () - ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - tree arg = build_typeinfo (e, e->newtype); - new_call = build_libcall (libcall, tb, 1, arg); + new_call = build_expr (e->lowering); if (e->member || !e->arguments) { @@ -2423,11 +2424,12 @@ public: return; } - libcall_fn libcall = tpointer->next->isZeroInit (e->loc) - ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; + /* This case should have been rewritten to `_d_newitemT' during the + semantic phase. */ + gcc_assert (e->lowering); - tree arg = build_typeinfo (e, e->newtype); - result = build_libcall (libcall, tb, 1, arg); + /* Generate: _d_newitemT() */ + result = build_expr (e->lowering); if (e->arguments && e->arguments->length == 1) { diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def index fd83cc9..4d1ba09 100644 --- a/gcc/d/runtime.def +++ b/gcc/d/runtime.def @@ -70,11 +70,6 @@ DEF_D_RUNTIME (DYNAMIC_CAST, "_d_dynamic_cast", RT(OBJECT), DEF_D_RUNTIME (INTERFACE_CAST, "_d_interface_cast", RT(OBJECT), P2(OBJECT, CLASSINFO), 0) -/* Used when calling new on a pointer. The `i' variant is for when the - initializer is nonzero. */ -DEF_D_RUNTIME (NEWITEMT, "_d_newitemT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0) -DEF_D_RUNTIME (NEWITEMIT, "_d_newitemiT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0) - /* Used when calling new on an array. The `i' variant is for when the initializer is nonzero, and the `m' variant is when initializing a multi-dimensional array. */ diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc index 8bd6eb6..db6f71b 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -780,8 +780,8 @@ public: this->do_label (label); - if (this->is_return_label (s->ident) && this->func_->fensure != NULL) - this->build_stmt (this->func_->fensure); + if (this->is_return_label (s->ident) && this->func_->fensure () != NULL) + this->build_stmt (this->func_->fensure ()); else if (s->statement) this->build_stmt (s->statement); } diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index 1c5e50c..bf17438 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -1421,7 +1421,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr) /* If TypeInfo has not been declared, warn about each location once. */ static Loc warnloc; - if (loc.filename && !warnloc.equals (loc)) + if (loc.filename () && !warnloc.equals (loc)) { error_at (make_location_t (loc), "% could not be found, " diff --git a/gcc/testsuite/gdc.dg/asm4.d b/gcc/testsuite/gdc.dg/asm4.d index e243c08..db857af 100644 --- a/gcc/testsuite/gdc.dg/asm4.d +++ b/gcc/testsuite/gdc.dg/asm4.d @@ -6,7 +6,7 @@ module asm4; void test1() { asm pure nothrow @nogc @trusted {} - asm @safe {} + asm @system {} } void test2() pure nothrow @nogc @safe diff --git a/gcc/testsuite/gdc.test/compilable/aliasdecl.d b/gcc/testsuite/gdc.test/compilable/aliasdecl.d index 5bacbc6..74a674d 100644 --- a/gcc/testsuite/gdc.test/compilable/aliasdecl.d +++ b/gcc/testsuite/gdc.test/compilable/aliasdecl.d @@ -36,12 +36,12 @@ void main() enum a = 1; } - /+ struct S + struct S2 { int value; alias this = value; } - auto s = S(10); + auto s = S2(10); int n = s; - assert(n == 10); +/ + assert(n == 10); } diff --git a/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d b/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d new file mode 100644 index 0000000..0d8cd74 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d @@ -0,0 +1,13 @@ +// REQUIRED_ARGS: -preview=nosharedaccess +import core.atomic; + +class Foo +{ +} + +void oops() +{ + auto f0 = new shared Foo; + auto f1 = new shared Foo; + atomicStore(f0, f1); +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/library.c b/gcc/testsuite/gdc.test/compilable/imports/library.c new file mode 100644 index 0000000..4951e46 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/library.c @@ -0,0 +1,5 @@ +typedef enum SomeEnum +{ + foo = 0, + bar = -10000, +} SomeEnum; diff --git a/gcc/testsuite/gdc.test/compilable/noreturn3.d b/gcc/testsuite/gdc.test/compilable/noreturn3.d index 69689d2..2538a0d 100644 --- a/gcc/testsuite/gdc.test/compilable/noreturn3.d +++ b/gcc/testsuite/gdc.test/compilable/noreturn3.d @@ -91,8 +91,8 @@ auto ref forwardOrExit(ref int num) static assert( is(typeof(forwardOrExit(global)) == int)); -// // Must not infer ref due to the noreturn rvalue -static assert(!is(typeof(&forwardOrExit(global)))); +// Noreturn types do not affect `auto ref` deduction +static assert(is(typeof(&forwardOrExit(global)))); auto ref forwardOrExit2(ref int num) { @@ -104,8 +104,8 @@ auto ref forwardOrExit2(ref int num) static assert( is(typeof(forwardOrExit2(global)) == int)); -// // Must not infer ref due to the noreturn rvalue -static assert(!is(typeof(&forwardOrExit2(global)))); +// Noreturn types do not affect `auto ref` deduction +static assert(is(typeof(&forwardOrExit2(global)))); /*****************************************************************************/ diff --git a/gcc/testsuite/gdc.test/compilable/test22760.d b/gcc/testsuite/gdc.test/compilable/test22760.d new file mode 100644 index 0000000..5957db3 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22760.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=22760 + +extern(C++) void f(T)(T) +{ +} +struct S1(T) +{ + struct S2 + { + } +} +void fun() +{ + f(S1!int.S2()); +} diff --git a/gcc/testsuite/gdc.test/compilable/test23874.d b/gcc/testsuite/gdc.test/compilable/test23874.d new file mode 100644 index 0000000..81ee9d5 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23874.d @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug.cgi?id=23874 +// REQUIRED_ARGS: -profile=gc + +string myToString() +{ + return ""; +} + +enum x = myToString ~ ""; +immutable x2 = myToString ~ ""; diff --git a/gcc/testsuite/gdc.test/compilable/test23912.d b/gcc/testsuite/gdc.test/compilable/test23912.d new file mode 100644 index 0000000..d89d302 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23912.d @@ -0,0 +1,17 @@ +// https://issues.dlang.org/show_bug.cgi?id=23912 +// REQUIRED_ARGS: -preview=dip1000 + +struct Test +{ + string val; + + this(return scope string val) scope @safe {} + ~this() scope @safe {} +} + +void giver(scope string input) @safe +{ + accepts(Test(input)); +} + +void accepts(scope Test test) @safe {} diff --git a/gcc/testsuite/gdc.test/compilable/test23913.d b/gcc/testsuite/gdc.test/compilable/test23913.d new file mode 100644 index 0000000..e39c6de --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23913.d @@ -0,0 +1,7 @@ +// EXTRA_FILES: imports/library.c + +// https://issues.dlang.org/show_bug.cgi?id=23913 + +import imports.library; + +alias x = __traits(getMember, imports.library, "SomeEnum"); diff --git a/gcc/testsuite/gdc.test/compilable/test23948.d b/gcc/testsuite/gdc.test/compilable/test23948.d new file mode 100644 index 0000000..4f7b8da0 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23948.d @@ -0,0 +1,29 @@ +// https://issues.dlang.org/show_bug.cgi?id=23948 + +void foo1(const(char)* fun = __FILE__)() { + +} + +void foo2(const(char)* fun = __FILE_FULL_PATH__)() { + +} + +void foo3(const(char)* fun = __MODULE__)() { + +} + +void foo4(const(char)* fun = __FUNCTION__)() { + +} + +void foo5(const(char)* fun = __PRETTY_FUNCTION__)() { + +} + +void main() { + foo1(); + foo2(); + foo3(); + foo4(); + foo5(); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d index 802d1c2..f0a9456 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d +++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d @@ -91,9 +91,9 @@ TEST_OUTPUT: --- fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S __param_0)` is not callable using argument types `(S)` fail_compilation/bug9631.d(106): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S __param_0` -fail_compilation/bug9631.d(107): Error: none of the overloads of template `bug9631.targ.ft` are callable using argument types `!()(S)` +fail_compilation/bug9631.d(107): Error: template `bug9631.targ.ft` is not callable using argument types `!()(S)` fail_compilation/bug9631.d(105): Candidate is: `ft()(tem!().S)` -fail_compilation/bug9631.d(109): Error: none of the overloads of template `bug9631.targ.ft2` are callable using argument types `!()(S, int)` +fail_compilation/bug9631.d(109): Error: template `bug9631.targ.ft2` is not callable using argument types `!()(S, int)` fail_compilation/bug9631.d(108): Candidate is: `ft2(T)(S, T)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d index fa8915e..eb75f42 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d +++ b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d @@ -19,7 +19,11 @@ fail_compilation/chkformat.d(115): Deprecation: argument `& u` for format specif fail_compilation/chkformat.d(116): Deprecation: argument `16L` for format specification `"%c"` must be `char`, not `long` fail_compilation/chkformat.d(117): Deprecation: argument `17L` for format specification `"%c"` must be `char`, not `long` fail_compilation/chkformat.d(118): Deprecation: argument `& u` for format specification `"%s"` must be `char*`, not `int*` -fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*` +fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`$?:windows= +fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong` +fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system|32= +fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong` +fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system$ fail_compilation/chkformat.d(201): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long` fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 arguments fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long` @@ -81,6 +85,7 @@ void test18() { int u; printf("%s\n", &u); } void test19() { int u; printf("%ls\n", &u); } //void test20() { int u; char[] s; sprintf(&s[0], "%d\n", &u); } //void test21() { int u; fprintf(null, "%d\n", &u); } +void test20() { printf("%lu", ulong.init); } #line 200 diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d index 9f12ae6..a3ad34a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d @@ -2,12 +2,12 @@ EXTRA_FILES: imports/constraints.d TEST_OUTPUT: --- -fail_compilation/constraints_aggr.d(32): Error: none of the overloads of template `imports.constraints.C.f` are callable using argument types `!()(int)` +fail_compilation/constraints_aggr.d(32): Error: template `imports.constraints.C.f` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(60): Candidate is: `f(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_aggr.d(33): Error: none of the overloads of template `imports.constraints.C.g` are callable using argument types `!()()` +fail_compilation/constraints_aggr.d(33): Error: template `imports.constraints.C.g` is not callable using argument types `!()()` fail_compilation/imports/constraints.d(63): Candidate is: `g(this T)()` with `T = imports.constraints.C` must satisfy the following constraint: diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d index aac8760..fbb4aa9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d @@ -2,72 +2,72 @@ EXTRA_FILES: imports/constraints.d TEST_OUTPUT: --- -fail_compilation/constraints_func1.d(79): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(79): Error: template `imports.constraints.test1` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(80): Error: none of the overloads of template `imports.constraints.test2` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(80): Error: template `imports.constraints.test2` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(10): Candidate is: `test2(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(81): Error: none of the overloads of template `imports.constraints.test3` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(81): Error: template `imports.constraints.test3` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(11): Candidate is: `test3(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(82): Error: none of the overloads of template `imports.constraints.test4` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(82): Error: template `imports.constraints.test4` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(12): Candidate is: `test4(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(83): Error: none of the overloads of template `imports.constraints.test5` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(83): Error: template `imports.constraints.test5` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(13): Candidate is: `test5(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func1.d(84): Error: none of the overloads of template `imports.constraints.test6` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(84): Error: template `imports.constraints.test6` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(14): Candidate is: `test6(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T !P!T` -fail_compilation/constraints_func1.d(85): Error: none of the overloads of template `imports.constraints.test7` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(85): Error: template `imports.constraints.test7` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(15): Candidate is: `test7(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func1.d(86): Error: none of the overloads of template `imports.constraints.test8` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(86): Error: template `imports.constraints.test8` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(16): Candidate is: `test8(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(87): Error: none of the overloads of template `imports.constraints.test9` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(87): Error: template `imports.constraints.test9` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(17): Candidate is: `test9(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(88): Error: none of the overloads of template `imports.constraints.test10` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(88): Error: template `imports.constraints.test10` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(18): Candidate is: `test10(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(89): Error: none of the overloads of template `imports.constraints.test11` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(89): Error: template `imports.constraints.test11` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(19): Candidate is: `test11(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T !P!T` -fail_compilation/constraints_func1.d(90): Error: none of the overloads of template `imports.constraints.test12` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(90): Error: template `imports.constraints.test12` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(20): Candidate is: `test12(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(92): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int, int)` +fail_compilation/constraints_func1.d(92): Error: template `imports.constraints.test1` is not callable using argument types `!()(int, int)` fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d index a20426d..4b8ebd5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d @@ -2,83 +2,83 @@ EXTRA_FILES: imports/constraints.d TEST_OUTPUT: --- -fail_compilation/constraints_func2.d(94): Error: none of the overloads of template `imports.constraints.test13` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(94): Error: template `imports.constraints.test13` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(23): Candidate is: `test13(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T !P!T` -fail_compilation/constraints_func2.d(95): Error: none of the overloads of template `imports.constraints.test14` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(95): Error: template `imports.constraints.test14` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(24): Candidate is: `test14(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T N!T` -fail_compilation/constraints_func2.d(96): Error: none of the overloads of template `imports.constraints.test15` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(96): Error: template `imports.constraints.test15` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(25): Candidate is: `test15(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T !P!T` -fail_compilation/constraints_func2.d(97): Error: none of the overloads of template `imports.constraints.test16` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(97): Error: template `imports.constraints.test16` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(26): Candidate is: `test16(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func2.d(98): Error: none of the overloads of template `imports.constraints.test17` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(98): Error: template `imports.constraints.test17` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(27): Candidate is: `test17(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func2.d(99): Error: none of the overloads of template `imports.constraints.test18` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(99): Error: template `imports.constraints.test18` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(28): Candidate is: `test18(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func2.d(100): Error: none of the overloads of template `imports.constraints.test19` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(100): Error: template `imports.constraints.test19` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(29): Candidate is: `test19(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T !P!T N!T` -fail_compilation/constraints_func2.d(101): Error: none of the overloads of template `imports.constraints.test20` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(101): Error: template `imports.constraints.test20` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(30): Candidate is: `test20(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func2.d(102): Error: none of the overloads of template `imports.constraints.test21` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(102): Error: template `imports.constraints.test21` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(31): Candidate is: `test21(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func2.d(103): Error: none of the overloads of template `imports.constraints.test22` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(103): Error: template `imports.constraints.test22` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(32): Candidate is: `test22(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T !P!T` -fail_compilation/constraints_func2.d(104): Error: none of the overloads of template `imports.constraints.test23` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(104): Error: template `imports.constraints.test23` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(33): Candidate is: `test23(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T N!T !P!T` -fail_compilation/constraints_func2.d(105): Error: none of the overloads of template `imports.constraints.test24` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(105): Error: template `imports.constraints.test24` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(34): Candidate is: `test24(R)(R r)` with `R = int` must satisfy the following constraint: ` __traits(hasMember, R, "stuff")` -fail_compilation/constraints_func2.d(106): Error: none of the overloads of template `imports.constraints.test25` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(106): Error: template `imports.constraints.test25` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(35): Candidate is: `test25(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func2.d(107): Error: none of the overloads of template `imports.constraints.test26` are callable using argument types `!(float)(int)` +fail_compilation/constraints_func2.d(107): Error: template `imports.constraints.test26` is not callable using argument types `!(float)(int)` fail_compilation/imports/constraints.d(36): Candidate is: `test26(T, U)(U u)` with `T = float, U = int` diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d index 6f214b9..d16bdf0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d @@ -23,21 +23,21 @@ fail_compilation/imports/constraints.d(42): `overload(T, must satisfy one of the following constraints: ` N!T N!V` -fail_compilation/constraints_func3.d(56): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()` +fail_compilation/constraints_func3.d(56): Error: template `imports.constraints.variadic` is not callable using argument types `!()()` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` -fail_compilation/constraints_func3.d(57): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)` +fail_compilation/constraints_func3.d(57): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` with `A = int, T = ()` must satisfy the following constraint: ` N!int` -fail_compilation/constraints_func3.d(58): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)` +fail_compilation/constraints_func3.d(58): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` with `A = int, T = (int)` must satisfy the following constraint: ` N!int` -fail_compilation/constraints_func3.d(59): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)` +fail_compilation/constraints_func3.d(59): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` with `A = int, T = (int, int)` diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d index 4048bae..c4dea0e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d @@ -44,13 +44,13 @@ fail_compilation/imports/constraints.d(42): `overload(T, N!V` void overload(T, V)(T v1, V v2) if (N!T || N!V); ^ -fail_compilation/constraints_func4.d(93): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()` +fail_compilation/constraints_func4.d(93): Error: template `imports.constraints.variadic` is not callable using argument types `!()()` variadic(); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` void variadic(A, T...)(A a, T v) if (N!int); ^ -fail_compilation/constraints_func4.d(94): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)` +fail_compilation/constraints_func4.d(94): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)` variadic(0); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` @@ -60,7 +60,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T. ` N!int` void variadic(A, T...)(A a, T v) if (N!int); ^ -fail_compilation/constraints_func4.d(95): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)` +fail_compilation/constraints_func4.d(95): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)` variadic(0, 1); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` @@ -70,7 +70,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T. ` N!int` void variadic(A, T...)(A a, T v) if (N!int); ^ -fail_compilation/constraints_func4.d(96): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)` +fail_compilation/constraints_func4.d(96): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)` variadic(0, 1, 2); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d index aeee107..25e0515 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/diag13942.d(18): Error: template instance `isRawStaticArray!()` does not match template declaration `isRawStaticArray(T, A...)` -fail_compilation/diag13942.d(26): Error: none of the overloads of template `diag13942.to!double.to` are callable using argument types `!()()` +fail_compilation/diag13942.d(26): Error: template `diag13942.to!double.to` is not callable using argument types `!()()` fail_compilation/diag13942.d(17): Candidate is: `to(A...)(A args)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d index 73d6285..fc8f660 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/diag16977.d(25): Error: undefined identifier `undefined`, did you mean function `undefinedId`? fail_compilation/diag16977.d(26): Error: cannot implicitly convert expression `"\x01string"` of type `string` to `int` -fail_compilation/diag16977.d(27): Error: none of the overloads of template `diag16977.templ` are callable using argument types `!()(int)` +fail_compilation/diag16977.d(27): Error: template `diag16977.templ` is not callable using argument types `!()(int)` fail_compilation/diag16977.d(20): Candidate is: `templ(S)(S s)` with `S = int` must satisfy the following constraint: diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag20268.d b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d index a314561..053626a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag20268.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d @@ -3,7 +3,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag20268.d(12): Error: none of the overloads of template `diag20268.__lambda4` are callable using argument types `!()(int)` +fail_compilation/diag20268.d(12): Error: template `diag20268.__lambda4` is not callable using argument types `!()(int)` fail_compilation/diag20268.d(11): Candidate is: `__lambda4(__T1, __T2)(x, y)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag23355.d b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d index 586cbb0..a530eb6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag23355.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d @@ -2,10 +2,10 @@ TEST_OUTPUT: --- fail_compilation/diag23355.d(1): Error: undefined identifier `n` -fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi1` are callable using argument types `!()(int[4])` +fail_compilation/diag23355.d(4): Error: template `diag23355.ffi1` is not callable using argument types `!()(int[4])` fail_compilation/diag23355.d(1): Candidate is: `ffi1(T)(T[n] s)` fail_compilation/diag23355.d(2): Error: undefined identifier `n` -fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi2` are callable using argument types `!()(int[4])` +fail_compilation/diag23355.d(4): Error: template `diag23355.ffi2` is not callable using argument types `!()(int[4])` fail_compilation/diag23355.d(2): Candidate is: `ffi2()(T[n] s)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d index ddc74e2..4c8dfe8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d @@ -14,7 +14,7 @@ fail_compilation/diag8101.d(41): `diag8101.f_2(int, int, fail_compilation/diag8101.d(42): `diag8101.f_2(int, int, int, int, int)` fail_compilation/diag8101.d(43): `diag8101.f_2(int, int, int, int, int, int)` fail_compilation/diag8101.d(63): ... (1 more, -v to show) ... -fail_compilation/diag8101.d(65): Error: none of the overloads of template `diag8101.t_0` are callable using argument types `!()()` +fail_compilation/diag8101.d(65): Error: template `diag8101.t_0` is not callable using argument types `!()()` fail_compilation/diag8101.d(46): Candidate is: `t_0(T1)()` fail_compilation/diag8101.d(66): Error: none of the overloads of template `diag8101.t_1` are callable using argument types `!()()` fail_compilation/diag8101.d(48): Candidates are: `t_1(T1)()` diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d index a04ed7c..e48f569 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d @@ -2,13 +2,13 @@ TEST_OUTPUT: --- fail_compilation/diag8648.d(18): Error: undefined identifier `X` -fail_compilation/diag8648.d(29): Error: none of the overloads of template `diag8648.foo` are callable using argument types `!()(Foo!(int, 1))` +fail_compilation/diag8648.d(29): Error: template `diag8648.foo` is not callable using argument types `!()(Foo!(int, 1))` fail_compilation/diag8648.d(18): Candidate is: `foo(T, n)(X!(T, n))` fail_compilation/diag8648.d(20): Error: undefined identifier `a` -fail_compilation/diag8648.d(31): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, 1))` +fail_compilation/diag8648.d(31): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, 1))` fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))` fail_compilation/diag8648.d(20): Error: undefined identifier `a` -fail_compilation/diag8648.d(32): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, f))` +fail_compilation/diag8648.d(32): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, f))` fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d index 37d5bd8..30589bf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag9004.d(21): Error: none of the overloads of template `diag9004.bar` are callable using argument types `!()(Foo!int, int)` +fail_compilation/diag9004.d(21): Error: template `diag9004.bar` is not callable using argument types `!()(Foo!int, int)` fail_compilation/diag9004.d(14): Candidate is: `bar(FooT)(FooT foo, FooT.T x)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9574.d b/gcc/testsuite/gdc.test/fail_compilation/diag9574.d deleted file mode 100644 index b280b3b..0000000 --- a/gcc/testsuite/gdc.test/fail_compilation/diag9574.d +++ /dev/null @@ -1,19 +0,0 @@ -/* -TEST_OUTPUT: ---- -fail_compilation/diag9574.d(12): Error: cannot use syntax `alias this = x`, use `alias x this` instead -fail_compilation/diag9574.d(18): Error: cannot use syntax `alias this = x`, use `alias x this` instead ---- -*/ - -struct S -{ - int x; - alias this = x; -} - -class C -{ - int x; - alias this = x; -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d b/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d index bbfb5a0..151bb42 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/diag_template_alias.d(1): Error: identifier expected for template `alias` parameter fail_compilation/diag_template_alias.d(1): Error: found `alias` when expecting `(` -fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration +fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration, not `(` fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `(` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d b/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d index 778f68e..25de03c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/diag_template_this.d(1): Error: identifier expected for template `this` parameter fail_compilation/diag_template_this.d(1): Error: found `this` when expecting `(` -fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration +fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration, not `(` fail_compilation/diag_template_this.d(1): Error: declaration expected, not `(` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diagin.d b/gcc/testsuite/gdc.test/fail_compilation/diagin.d index 0d1f8f1..1748e92 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diagin.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diagin.d @@ -4,7 +4,7 @@ TEST_OUTPUT: --- fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()` fail_compilation/diagin.d(14): too few arguments, expected 1, got 0 -fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])` +fail_compilation/diagin.d(16): Error: template `diagin.foo1` is not callable using argument types `!()(bool[])` fail_compilation/diagin.d(20): Candidate is: `foo1(T)(in T v, string)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d index fe7d546..0ac7229 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d @@ -21,7 +21,7 @@ __error__ } } )` -fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration +fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration, not `End of File` --- */ d(={for diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d index 2056c0e..711e57f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d @@ -14,10 +14,10 @@ fail_compilation/fail12744.d(61): Error: template instance `fail12744.bar12744L! fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `out` fail_compilation/fail12744.d(62): Error: template instance `fail12744.bar12744L!(foo12744O)` error instantiating fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `out` -fail_compilation/fail12744.d(67): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744O)(int)` +fail_compilation/fail12744.d(67): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744O)(int)` fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)` fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `lazy` -fail_compilation/fail12744.d(68): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744L)(int)` +fail_compilation/fail12744.d(68): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744L)(int)` fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d index 5621ecc..45fe146 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d @@ -4,7 +4,7 @@ TEST_OUTPUT: fail_compilation/fail14669.d(11): Error: `auto` can only be used as part of `auto ref` for template function parameters fail_compilation/fail14669.d(16): Error: template instance `fail14669.foo1!()` error instantiating fail_compilation/fail14669.d(12): Error: `auto` can only be used as part of `auto ref` for template function parameters -fail_compilation/fail14669.d(17): Error: none of the overloads of template `fail14669.foo2` are callable using argument types `!()(int)` +fail_compilation/fail14669.d(17): Error: template `fail14669.foo2` is not callable using argument types `!()(int)` fail_compilation/fail14669.d(12): Candidate is: `foo2()(auto int a)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d index 1fb6e23..ed576b5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d @@ -5,7 +5,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `fun` +fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not the overload set `fun` fail_compilation/fail15414.d(20): the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail162.d b/gcc/testsuite/gdc.test/fail_compilation/fail162.d index a537f10..c79f8d8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail162.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail162.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail162.d(25): Error: none of the overloads of template `fail162.testHelper` are callable using argument types `!()(string, string)` +fail_compilation/fail162.d(25): Error: template `fail162.testHelper` is not callable using argument types `!()(string, string)` fail_compilation/fail162.d(10): Candidate is: `testHelper(A...)()` fail_compilation/fail162.d(30): Error: template instance `fail162.test!("hello", "world")` error instantiating --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d index 00dd9fd..d36bb0b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d @@ -3,7 +3,7 @@ REQUIRED_ARGS: -verrors=spec -o- TEST_OUTPUT: --- (spec:1) fail_compilation/fail20730b.d-mixin-43(43): Error: C style cast illegal, use `cast(int)mod` -fail_compilation/fail20730b.d(26): Error: none of the overloads of template `fail20730b.atomicOp` are callable using argument types `!("+=")(shared(uint), int)` +fail_compilation/fail20730b.d(26): Error: template `fail20730b.atomicOp` is not callable using argument types `!("+=")(shared(uint), int)` fail_compilation/fail20730b.d(41): Candidate is: `atomicOp(string op, T, V1)(shared ref T val, V1 mod)` with `op = "+=", T = uint, diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail236.d b/gcc/testsuite/gdc.test/fail_compilation/fail236.d index 626ec00..accc0e1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail236.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail236.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/fail236.d(14): Error: undefined identifier `x` -fail_compilation/fail236.d(22): Error: none of the overloads of template `fail236.Templ2` are callable using argument types `!()(int)` +fail_compilation/fail236.d(22): Error: template `fail236.Templ2` is not callable using argument types `!()(int)` fail_compilation/fail236.d(12): Candidate is: `Templ2(alias a)(x)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d b/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d index 2943f1a..559e0e2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- fail_compilation/fail23626a.d(10): Deprecation: function `fail23626a.ambig` cannot overload `extern(D)` function at fail_compilation/fail23626a.d(9) -fail_compilation/fail23626a.d(13): Deprecation: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12) +fail_compilation/fail23626a.d(13): Error: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12) fail_compilation/fail23626a.d(16): Error: function `fail23626a.ambigCxx(int a)` conflicts with previous declaration at fail_compilation/fail23626a.d(15) --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2456.d b/gcc/testsuite/gdc.test/fail_compilation/fail2456.d index 08e11da..5d7d6ee 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail2456.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail2456.d @@ -108,3 +108,17 @@ void test2456b() catch (Throwable) {} // NG } } + +/* +TEST_OUTPUT: +--- +fail_compilation/fail2456.d(121): Deprecation: can only catch mutable or const qualified types, not `immutable(Exception)` +--- +*/ +void main() { + try { + throw new Exception(""); + } catch (immutable Exception e) { + assert(0); + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2789.d b/gcc/testsuite/gdc.test/fail_compilation/fail2789.d index 2d6c8e2..261e412 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail2789.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail2789.d @@ -61,8 +61,8 @@ auto f6() { return ""; } // string(), conflict TEST_OUTPUT: --- fail_compilation/fail2789.d(67): Error: function `fail2789.f_ExternC1()` conflicts with previous declaration at fail_compilation/fail2789.d(66) -fail_compilation/fail2789.d(70): Deprecation: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69) -fail_compilation/fail2789.d(73): Deprecation: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72) +fail_compilation/fail2789.d(70): Error: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69) +fail_compilation/fail2789.d(73): Error: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72) --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d index 96489d9..a4844bf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail8009.d(9): Error: none of the overloads of template `fail8009.filter` are callable using argument types `!()(void)` +fail_compilation/fail8009.d(9): Error: template `fail8009.filter` is not callable using argument types `!()(void)` fail_compilation/fail8009.d(8): Candidate is: `filter(R)(scope bool delegate(ref BAD!R) func)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail95.d b/gcc/testsuite/gdc.test/fail_compilation/fail95.d index a1b3906..7065bc1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail95.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail95.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail95.d(19): Error: none of the overloads of template `fail95.A` are callable using argument types `!()(int)` +fail_compilation/fail95.d(19): Error: template `fail95.A` is not callable using argument types `!()(int)` fail_compilation/fail95.d(11): Candidate is: `A(alias T)(T)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d index 6612a67..9ba2970 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d +++ b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d @@ -4,8 +4,8 @@ fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function lite fail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode` fail_compilation/failcontracts.d(19): Error: function declaration without return type. (Note that constructors are always named `this`) fail_compilation/failcontracts.d(19): Error: no identifier for declarator `test1()` -fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration -fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration +fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration, not `bode` +fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration, not `bode` fail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator fail_compilation/failcontracts.d(22): Error: found `T` when expecting `)` fail_compilation/failcontracts.d(22): Error: enum declaration is invalid diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d index 24e39da..448e629 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d @@ -1,8 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/ice11856_1.d(16): Error: none of the overloads of template `ice11856_1.g` are callable using argument types `!()(A)` -fail_compilation/ice11856_1.d(14): Candidate is: `g(T)(T x)` +fail_compilation/ice11856_1.d(18): Error: no property `g` for `A()` of type `A` +fail_compilation/ice11856_1.d(18): the following error occured while looking for a UFCS match +fail_compilation/ice11856_1.d(18): Error: template `ice11856_1.g` is not callable using argument types `!()(A)` +fail_compilation/ice11856_1.d(16): Candidate is: `g(T)(T x)` with `T = A` must satisfy the following constraint: ` is(typeof(x.f()))` diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d index c64fb84..151bf17 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/ice14130.d(10): Error: undefined identifier `Undef` -fail_compilation/ice14130.d(14): Error: none of the overloads of template `ice14130.foo` are callable using argument types `!()(int)` +fail_compilation/ice14130.d(14): Error: template `ice14130.foo` is not callable using argument types `!()(int)` fail_compilation/ice14130.d(10): Candidate is: `foo(R, F = Undef)(R r, F s = 0)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d index e1d7aac..5d676cd 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d @@ -6,7 +6,7 @@ fail_compilation/ice14907.d(19): while looking for match for `S!()` fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion fail_compilation/ice14907.d(20): while looking for match for `f!()` fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion -fail_compilation/ice14907.d(21): Error: none of the overloads of template `ice14907.f` are callable using argument types `!()()` +fail_compilation/ice14907.d(21): Error: template `ice14907.f` is not callable using argument types `!()()` fail_compilation/ice14907.d(15): Candidate is: `f(int v = f)()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d index 1c6cf4b..af7c554 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d @@ -7,7 +7,7 @@ TEST_OUTPUT: --- fail_compilation/ice6538.d(23): Error: expression `super` is not a valid template value argument -fail_compilation/ice6538.d(28): Error: none of the overloads of template `ice6538.D.foo` are callable using argument types `!()()` +fail_compilation/ice6538.d(28): Error: template `ice6538.D.foo` is not callable using argument types `!()()` fail_compilation/ice6538.d(23): Candidate is: `foo()()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d index 00602d2..47fd44c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/ice9284.d(14): Error: none of the overloads of template `ice9284.C.__ctor` are callable using argument types `!()(int)` +fail_compilation/ice9284.d(14): Error: template `ice9284.C.__ctor` is not callable using argument types `!()(int)` fail_compilation/ice9284.d(12): Candidate is: `__ctor()(string)` fail_compilation/ice9284.d(20): Error: template instance `ice9284.C.__ctor!()` error instantiating --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d b/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d new file mode 100644 index 0000000..39334cf --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d @@ -0,0 +1,2 @@ +static if ; +else auto x diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d new file mode 100644 index 0000000..4c369e3 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d @@ -0,0 +1,3 @@ +module imports.spell23908a; + +import imports.spell23908b : nonexistent; diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d new file mode 100644 index 0000000..316b4fe --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d @@ -0,0 +1,3 @@ +module imports.spell23908b; + +import imports.spell23908a; diff --git a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d index 0900e60..5129f30 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d +++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d @@ -15,7 +15,7 @@ fail_compilation/named_arguments_error.d(38): Error: no named argument `element` fail_compilation/named_arguments_error.d(39): Error: no named argument `number` allowed for scalar fail_compilation/named_arguments_error.d(40): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string` fail_compilation/named_arguments_error.d(41): Error: named arguments with Implicit Function Template Instantiation are not supported yet -fail_compilation/named_arguments_error.d(41): Error: none of the overloads of template `named_arguments_error.tempfun` are callable using argument types `!()(string, int)` +fail_compilation/named_arguments_error.d(41): Error: template `named_arguments_error.tempfun` is not callable using argument types `!()(string, int)` fail_compilation/named_arguments_error.d(45): Candidate is: `tempfun(T, U)(T t, U u)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d index 7bc5e96..50cfdd3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d @@ -403,7 +403,7 @@ class Foo13 /* TEST_OUTPUT: --- -fail_compilation/retscope.d(1205): Error: scope variable `f14` assigned to non-scope parameter `this` calling `foo` +fail_compilation/retscope.d(1205): Error: scope variable `f14` calling non-scope member function `f14.foo()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/spell23908.d b/gcc/testsuite/gdc.test/fail_compilation/spell23908.d new file mode 100644 index 0000000..a7501e1 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/spell23908.d @@ -0,0 +1,11 @@ +/* +EXTRA_FILES: imports/spell23908a.d imports/spell23908b.d +TEST_OUTPUT: +--- +fail_compilation/imports/spell23908a.d(3): Error: module `imports.spell23908b` import `nonexistent` not found +--- +*/ + +// https://issues.dlang.org/show_bug.cgi?id=23908 + +import imports.spell23908a; diff --git a/gcc/testsuite/gdc.test/fail_compilation/static_import.d b/gcc/testsuite/gdc.test/fail_compilation/static_import.d new file mode 100644 index 0000000..24b7bc1 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/static_import.d @@ -0,0 +1,8 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/static_import.d(8): Error: static import `core` cannot have an import bind list +--- +*/ + +static import core.stdc.stdio : p = q; diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18385.d b/gcc/testsuite/gdc.test/fail_compilation/test18385.d index 3f87885..2e48192 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test18385.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test18385.d @@ -2,7 +2,7 @@ REQUIRED_ARGS: -de TEST_OUTPUT: --- -fail_compilation/test18385.d(13): Deprecation: function `test18385.foo` cannot overload `extern(C)` function at fail_compilation/test18385.d(12) +fail_compilation/test18385.d(13): Error: function `test18385.foo` cannot overload `extern(C)` function at fail_compilation/test18385.d(12) --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19107.d b/gcc/testsuite/gdc.test/fail_compilation/test19107.d index 93d86bf..c802122 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test19107.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test19107.d @@ -2,7 +2,7 @@ EXTRA_FILES: imports/imp19661.d imports/test19107a.d imports/test19107b.d TEST_OUTPUT: --- -fail_compilation/test19107.d(24): Error: none of the overloads of template `test19107.all` are callable using argument types `!((c) => c)(string[])` +fail_compilation/test19107.d(24): Error: template `test19107.all` is not callable using argument types `!((c) => c)(string[])` fail_compilation/test19107.d(18): Candidate is: `all(alias pred, T)(T t)` with `pred = __lambda2, T = string[]` diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20245.d b/gcc/testsuite/gdc.test/fail_compilation/test20245.d index 98caa03..3c43c5c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test20245.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test20245.d @@ -9,7 +9,7 @@ fail_compilation/test20245.d(27): Error: cannot take address of `scope` variable fail_compilation/test20245.d(33): Error: reference to local variable `x` assigned to non-scope parameter `ptr` calling `escape` fail_compilation/test20245.d(34): Error: copying `&x` into allocated memory escapes a reference to parameter `x` fail_compilation/test20245.d(50): Error: reference to local variable `price` assigned to non-scope `this.minPrice` -fail_compilation/test20245.d(69): Error: reference to local variable `this` assigned to non-scope parameter `msg` calling `this` +fail_compilation/test20245.d(69): Error: reference to local variable `this` calling non-scope member function `this.this()` fail_compilation/test20245.d(89): Error: reference to local variable `this` assigned to non-scope parameter `content` calling `listUp` fail_compilation/test20245.d(82): which is not `scope` because of `charPtr = content` --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23873.d b/gcc/testsuite/gdc.test/fail_compilation/test23873.d new file mode 100644 index 0000000..bb6a71d --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23873.d @@ -0,0 +1,14 @@ +// https://issues.dlang.org/show_bug.cgi?id=23873 + +/* +TEST_OUTPUT: +--- +fail_compilation/imports/import23873.d(1): Error: (expression) expected following `static if` +fail_compilation/imports/import23873.d(1): Error: declaration expected following attribute, not `;` +fail_compilation/imports/import23873.d(3): Error: no identifier for declarator `x` +--- +*/ +struct Foo +{ + import imports.import23873; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23882.d b/gcc/testsuite/gdc.test/fail_compilation/test23882.d new file mode 100644 index 0000000..f6b57c4 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23882.d @@ -0,0 +1,37 @@ +// https://issues.dlang.org/show_bug.cgi?id=23882 + +/* +TEST_OUTPUT: +--- +fail_compilation/test23882.d(26): Error: `typeof((*YC).S).init` is used as a type +--- +*/ + +struct G(H) +{ + Tuple!(R) S; +} + +struct BB(H) +{ + H* YC; + alias YC this; +} + +struct R +{ + BB!(G!float) CB; + alias CB this; + + this(typeof(CB.S).init); +} + +struct Tuple(Specs) +{ + Specs expand; + + this(Specs values) + { + expand = values; + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23905.d b/gcc/testsuite/gdc.test/fail_compilation/test23905.d new file mode 100644 index 0000000..5b30fa8 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23905.d @@ -0,0 +1,25 @@ +// https://issues.dlang.org/show_bug.cgi?id=23905 + +/* +TEST_OUTPUT: +--- +fail_compilation/test23905.d(24): Error: enum `test23905.Foo` is opaque and has no default initializer +--- +*/ + +struct SumType(T) +{ + T storage; + + bool opEquals(Rhs)(Rhs rhs) + if (is(typeof(Rhs.init))) + { + } + +} + +enum Foo; + +void main(){ + SumType!Foo data = Foo.init; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d index 453ebba..76df55f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d +++ b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d @@ -23,7 +23,7 @@ fail_compilation/udaparams.d(57): Error: identifier expected for template value fail_compilation/udaparams.d(57): Error: found `@` when expecting `)` fail_compilation/udaparams.d(57): Error: basic type expected, not `3` fail_compilation/udaparams.d(57): Error: found `3` when expecting `)` -fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration +fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration, not `)` fail_compilation/udaparams.d(57): Error: declaration expected, not `)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ufcs.d b/gcc/testsuite/gdc.test/fail_compilation/ufcs.d new file mode 100644 index 0000000..501ef81 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/ufcs.d @@ -0,0 +1,34 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/ufcs.d(25): Error: no property `regularF` for `s` of type `S` +fail_compilation/ufcs.d(25): the following error occured while looking for a UFCS match +fail_compilation/ufcs.d(25): Error: function `ufcs.regularF()` is not callable using argument types `(S)` +fail_compilation/ufcs.d(25): expected 0 argument(s), not 1 +fail_compilation/ufcs.d(26): Error: no property `templateF` for `s` of type `S` +fail_compilation/ufcs.d(26): the following error occured while looking for a UFCS match +fail_compilation/ufcs.d(26): Error: template `ufcs.templateF` is not callable using argument types `!()(S)` +fail_compilation/ufcs.d(31): Candidate is: `templateF()()` +fail_compilation/ufcs.d(27): Error: no property `templateO` for `s` of type `S` +fail_compilation/ufcs.d(27): the following error occured while looking for a UFCS match +fail_compilation/ufcs.d(27): Error: none of the overloads of template `ufcs.templateO` are callable using argument types `!()(S)` +fail_compilation/ufcs.d(33): Candidates are: `templateO()(int x)` +fail_compilation/ufcs.d(34): `templateO()(float y)` +--- +*/ + +struct S { } + +void f() +{ + S s; + s.regularF(); + s.templateF(); + s.templateO(); +} + +void regularF(); +void templateF()(); + +void templateO()(int x); +void templateO()(float y); diff --git a/gcc/testsuite/gdc.test/runnable/betterc.d b/gcc/testsuite/gdc.test/runnable/betterc.d index 74967e9..3d8f7da 100644 --- a/gcc/testsuite/gdc.test/runnable/betterc.d +++ b/gcc/testsuite/gdc.test/runnable/betterc.d @@ -42,6 +42,7 @@ extern (C) void main() test18472(); testRuntimeLowerings(); test18457(); + test20737(); } /*******************************************/ @@ -199,3 +200,13 @@ void test18457() } assert(dtor == 1); } + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=20737 +int tlsVar; + +int test20737() +{ + tlsVar = 123; + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/eh2.d b/gcc/testsuite/gdc.test/runnable/eh2.d index 2b469d2..775e83d 100644 --- a/gcc/testsuite/gdc.test/runnable/eh2.d +++ b/gcc/testsuite/gdc.test/runnable/eh2.d @@ -72,11 +72,11 @@ int main() a.test(); Abc.x |= 0x40; } - catch (shared(Abc) b) + catch (Abc b) { Abc.x |= 0x80; printf("Caught %p, x = x%x\n", b, Abc.x); - assert(a is b); + assert(cast() a is b); assert(Abc.x == 0xB5); } printf("Success!\n"); diff --git a/gcc/testsuite/gdc.test/runnable/funclit.d b/gcc/testsuite/gdc.test/runnable/funclit.d index e6e4fec1..c4b70dc 100644 --- a/gcc/testsuite/gdc.test/runnable/funclit.d +++ b/gcc/testsuite/gdc.test/runnable/funclit.d @@ -1263,6 +1263,7 @@ void assign16271(T)(ref T a, T b) void test16271() { int x; + (delegate ref => x)() = -1; assert(x == -1); (ref () => x )() = 1; assert(x == 1); func16271!(ref () => x) = 2; assert(x == 2); assign16271(x, 3); assert(x == 3); diff --git a/gcc/testsuite/gdc.test/runnable/test20687.d b/gcc/testsuite/gdc.test/runnable/test20687.d new file mode 100644 index 0000000..47c33f1 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test20687.d @@ -0,0 +1,28 @@ +// PERMUTE_ARGS: +// https://issues.dlang.org/show_bug.cgi?id=20687 + +struct S +{ + void foo(){} +} + +void main() +{ + S i; + enum fpe = &S.foo; + const fp = &S.foo; + const dg = &i.foo; + + // Allow these + static dgfp = &S.foo; + static const dgfpc = &S.foo; + static immutable dgfpi = &S.foo; + __gshared dgfpg = &S.foo; + __gshared const dgfpgc = &S.foo; + __gshared immutable dgfpgi = &S.foo; + + static foreach (v; [fp, dgfpc, dgfpi, dgfpgc, dgfpgi]) + static assert(fpe == v); + + assert(fp == dg.funcptr && fp == dgfp && fp == dgfpg); +} diff --git a/gcc/testsuite/gdc.test/runnable/testinvariant.d b/gcc/testsuite/gdc.test/runnable/testinvariant.d index d3b3b6f..0ce8557 100644 --- a/gcc/testsuite/gdc.test/runnable/testinvariant.d +++ b/gcc/testsuite/gdc.test/runnable/testinvariant.d @@ -176,6 +176,58 @@ void test13147() s.test(); } +/***************************************************/ +// https://issues.dlang.org/show_bug.cgi?id=16384 + +struct S(T) +{ + T x = 5; + invariant { assert(x == 6); } + invariant { assert(x > 0); } + + void foo() {} +} + +void f(int i) pure { assert( i == 6); } + +struct S2(T) +{ + T x = 5; + invariant { f(x); } + invariant { assert(x > 0); } + + void foo() {} +} + +void test16384() +{ + string s; + S!int y; + try + { + y.foo(); + } + catch(Error) + { + s = "needs to be thrown"; + } + + assert(s == "needs to be thrown"); + + S2!int y2; + + try + { + y2.foo(); + } + catch(Error) + { + s = "needs to be thrown2"; + } + + assert(s == "needs to be thrown2"); +} + /***************************************************/ @@ -183,6 +235,7 @@ void main() { testinvariant(); test6453(); + test16384(); test13113(); test13147(); } diff --git a/gcc/testsuite/gdc.test/runnable/variadic.d b/gcc/testsuite/gdc.test/runnable/variadic.d index 2d0736d..7e9473c 100644 --- a/gcc/testsuite/gdc.test/runnable/variadic.d +++ b/gcc/testsuite/gdc.test/runnable/variadic.d @@ -1119,6 +1119,53 @@ void test15417() /***************************************/ +// https://issues.dlang.org/show_bug.cgi?id=21425 + +import core.stdc.stdarg; +import core.stdc.stdio; + +extern(C) void f5(int dummy, ...) +{ + va_list ap; + + va_start(ap, dummy); + int x = va_arg!int(ap); + assert(x == 5); + va_end(ap); + + va_start(ap, dummy); + int y = va_arg!int(ap); + assert(y == 5); + va_end(ap); +} + +void test21425() +{ + f5(0, 5); +} + +/*********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=23409 + +import core.stdc.string; + +void printf10(const(char)* fmt, ...){ + char[30] s; + for(int i = 0; i < 10; i++){ + va_list args; + va_start(args, fmt); + vsprintf(s.ptr, fmt, args); + va_end(args); + assert(strcmp(s.ptr, "Hello world\n") == 0); + } +} + +void test23409() +{ + printf10("Hello %s\n".ptr, "world".ptr); +} + +/***************************************/ int main() { @@ -1169,6 +1216,8 @@ int main() testCopy(); test14179(); test15417(); + test21425(); + test23409(); return 0; } -- cgit v1.1 From 4814b63c3c2326cb5d7baa63882da60ac011bd97 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 10 Jul 2023 09:04:29 +0100 Subject: i386: Add AVX512 support for STV of SI/DImode rotation by constant. Following Uros' suggestion, this patch adds support for AVX512VL's vpro[lr][dq] instructions to the recently added scalar-to-vector (STV) enhancements to handle DImode and SImode rotations by a constant. For the test cases: unsigned long long rot1(unsigned long long x) { return (x>>1) | (x<<63); } void mem1(unsigned long long *p) { *p = rot1(*p); } with -m32 -O2 -mavx512vl, we currently generate: rot1: movl 4(%esp), %eax movl 8(%esp), %edx movl %eax, %ecx shrdl $1, %edx, %eax shrdl $1, %ecx, %edx ret mem1: movl 4(%esp), %eax vmovq (%eax), %xmm0 vpshufd $20, %xmm0, %xmm0 vpsrlq $1, %xmm0, %xmm0 vpshufd $136, %xmm0, %xmm0 vmovq %xmm0, (%eax) ret with this patch, we now generate: rot1: vmovq 4(%esp), %xmm0 vprorq $1, %xmm0, %xmm0 vmovd %xmm0, %eax vpextrd $1, %xmm0, %edx ret mem1: movl 4(%esp), %eax vmovq (%eax), %xmm0 vprorq $1, %xmm0, %xmm0 vmovq %xmm0, (%eax) ret 2023-07-10 Roger Sayle gcc/ChangeLog * config/i386/i386-features.cc (compute_convert_gain): Tweak gains/costs for ROTATE/ROTATERT by integer constant on AVX512VL. (general_scalar_chain::convert_rotate): On TARGET_AVX512F generate avx512vl_rolv2di or avx412vl_rolv4si when appropriate. gcc/testsuite/ChangeLog * gcc.target/i386/avx512vl-stv-rotatedi-1.c: New test case. --- gcc/config/i386/i386-features.cc | 8 ++++- .../gcc.target/i386/avx512vl-stv-rotatedi-1.c | 35 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-stv-rotatedi-1.c (limited to 'gcc') diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index 2e751d1..4d69251 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -585,7 +585,9 @@ general_scalar_chain::compute_convert_gain () case ROTATE: case ROTATERT: igain += m * ix86_cost->shift_const; - if (smode == DImode) + if (TARGET_AVX512F) + igain -= ix86_cost->sse_op; + else if (smode == DImode) { int bits = INTVAL (XEXP (src, 1)); if ((bits & 0x0f) == 0) @@ -1225,6 +1227,8 @@ general_scalar_chain::convert_rotate (enum rtx_code code, rtx op0, rtx op1, emit_insn_before (pat, insn); result = gen_lowpart (V2DImode, tmp1); } + else if (TARGET_AVX512F) + result = simplify_gen_binary (code, V2DImode, op0, op1); else if (bits == 16 || bits == 48) { rtx tmp1 = gen_reg_rtx (V8HImode); @@ -1269,6 +1273,8 @@ general_scalar_chain::convert_rotate (enum rtx_code code, rtx op0, rtx op1, emit_insn_before (pat, insn); result = gen_lowpart (V4SImode, tmp1); } + else if (TARGET_AVX512F) + result = simplify_gen_binary (code, V4SImode, op0, op1); else { if (code == ROTATE) diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-stv-rotatedi-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-stv-rotatedi-1.c new file mode 100644 index 0000000..2f0ead8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-stv-rotatedi-1.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2 -mavx512vl" } */ + +unsigned long long rot1(unsigned long long x) { return (x>>1) | (x<<63); } +unsigned long long rot2(unsigned long long x) { return (x>>2) | (x<<62); } +unsigned long long rot3(unsigned long long x) { return (x>>3) | (x<<61); } +unsigned long long rot4(unsigned long long x) { return (x>>4) | (x<<60); } +unsigned long long rot5(unsigned long long x) { return (x>>5) | (x<<59); } +unsigned long long rot6(unsigned long long x) { return (x>>6) | (x<<58); } +unsigned long long rot7(unsigned long long x) { return (x>>7) | (x<<57); } +unsigned long long rot8(unsigned long long x) { return (x>>8) | (x<<56); } +unsigned long long rot9(unsigned long long x) { return (x>>9) | (x<<55); } +unsigned long long rot10(unsigned long long x) { return (x>>10) | (x<<54); } +unsigned long long rot15(unsigned long long x) { return (x>>15) | (x<<49); } +unsigned long long rot16(unsigned long long x) { return (x>>16) | (x<<48); } +unsigned long long rot17(unsigned long long x) { return (x>>17) | (x<<47); } +unsigned long long rot20(unsigned long long x) { return (x>>20) | (x<<44); } +unsigned long long rot24(unsigned long long x) { return (x>>24) | (x<<40); } +unsigned long long rot30(unsigned long long x) { return (x>>30) | (x<<34); } +unsigned long long rot31(unsigned long long x) { return (x>>31) | (x<<33); } +unsigned long long rot32(unsigned long long x) { return (x>>32) | (x<<32); } +unsigned long long rot33(unsigned long long x) { return (x>>33) | (x<<31); } +unsigned long long rot34(unsigned long long x) { return (x>>34) | (x<<30); } +unsigned long long rot40(unsigned long long x) { return (x>>40) | (x<<24); } +unsigned long long rot42(unsigned long long x) { return (x>>42) | (x<<22); } +unsigned long long rot48(unsigned long long x) { return (x>>48) | (x<<16); } +unsigned long long rot50(unsigned long long x) { return (x>>50) | (x<<14); } +unsigned long long rot56(unsigned long long x) { return (x>>56) | (x<<8); } +unsigned long long rot58(unsigned long long x) { return (x>>58) | (x<<6); } +unsigned long long rot60(unsigned long long x) { return (x>>60) | (x<<4); } +unsigned long long rot61(unsigned long long x) { return (x>>61) | (x<<3); } +unsigned long long rot62(unsigned long long x) { return (x>>62) | (x<<2); } +unsigned long long rot63(unsigned long long x) { return (x>>63) | (x<<1); } + +/* { dg-final { scan-assembler-times "vpro\[lr\]q" 29 } } */ -- cgit v1.1 From 12b78b0b42d53019eb2c500d386094194e90ad16 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 10 Jul 2023 09:06:52 +0100 Subject: i386: Add new insvti_lowpart_1 and insvdi_lowpart_1 patterns. This patch implements another of Uros' suggestions, to investigate a insvti_lowpart_1 pattern to improve TImode parameter passing on x86_64. In PR 88873, the RTL the middle-end expands for passing V2DF in TImode is subtly different from what it does for V2DI in TImode, sufficiently so that my explanations for why insvti_lowpart_1 isn't required don't apply in this case. This patch adds an insvti_lowpart_1 pattern, complementing the existing insvti_highpart_1 pattern, and also a 32-bit variant, insvdi_lowpart_1. Because the middle-end represents 128-bit constants using CONST_WIDE_INT and 64-bit constants using CONST_INT, it's easiest to treat these as different patterns, rather than attempt parameterization. This patch also includes a peephole2 (actually a pair) to transform xchg instructions into mov instructions, when one of the destinations is unused. This optimization is required to produce the optimal code sequences below. For the 64-bit case: __int128 foo(__int128 x, unsigned long long y) { __int128 m = ~((__int128)~0ull); __int128 t = x & m; __int128 r = t | y; return r; } Before: xchgq %rdi, %rsi movq %rdx, %rax xorl %esi, %esi xorl %edx, %edx orq %rsi, %rax orq %rdi, %rdx ret After: movq %rdx, %rax movq %rsi, %rdx ret For the 32-bit case: long long bar(long long x, int y) { long long mask = ~0ull << 32; long long t = x & mask; long long r = t | (unsigned int)y; return r; } Before: pushl %ebx movl 12(%esp), %edx xorl %ebx, %ebx xorl %eax, %eax movl 16(%esp), %ecx orl %ebx, %edx popl %ebx orl %ecx, %eax ret After: movl 12(%esp), %eax movl 8(%esp), %edx ret 2023-07-10 Roger Sayle gcc/ChangeLog * config/i386/i386.md (peephole2): Transform xchg insn with a REG_UNUSED note to a (simple) move. (*insvti_lowpart_1): New define_insn_and_split. (*insvdi_lowpart_1): Likewise. gcc/testsuite/ChangeLog * gcc.target/i386/insvdi_lowpart-1.c: New test case. * gcc.target/i386/insvti_lowpart-1.c: Likewise. --- gcc/config/i386/i386.md | 66 ++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/insvdi_lowpart-1.c | 13 +++++ gcc/testsuite/gcc.target/i386/insvti_lowpart-1.c | 13 +++++ 3 files changed, 92 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/insvdi_lowpart-1.c create mode 100644 gcc/testsuite/gcc.target/i386/insvti_lowpart-1.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 621cdd9..844deea 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3243,6 +3243,30 @@ [(parallel [(set (match_dup 1) (match_dup 2)) (set (match_dup 2) (match_dup 1))])]) +;; Convert xchg with a REG_UNUSED note to a mov (variant #1). +(define_peephole2 + [(parallel [(set (match_operand:SWI 0 "general_reg_operand") + (match_operand:SWI 1 "general_reg_operand")) + (set (match_dup 1) (match_dup 0))])] + "((REGNO (operands[0]) != AX_REG + && REGNO (operands[1]) != AX_REG) + || optimize_size < 2 + || !optimize_insn_for_size_p ()) + && peep2_reg_dead_p (1, operands[0])" + [(set (match_dup 1) (match_dup 0))]) + +;; Convert xchg with a REG_UNUSED note to a mov (variant #2). +(define_peephole2 + [(parallel [(set (match_operand:SWI 0 "general_reg_operand") + (match_operand:SWI 1 "general_reg_operand")) + (set (match_dup 1) (match_dup 0))])] + "((REGNO (operands[0]) != AX_REG + && REGNO (operands[1]) != AX_REG) + || optimize_size < 2 + || !optimize_insn_for_size_p ()) + && peep2_reg_dead_p (1, operands[1])" + [(set (match_dup 0) (match_dup 1))]) + ;; Convert moves to/from AX_REG into xchg with -Oz. (define_peephole2 [(set (match_operand:SWI48 0 "general_reg_operand") @@ -3573,6 +3597,48 @@ split_double_concat (TImode, operands[0], operands[4], operands[2]); DONE; }) + +(define_insn_and_split "*insvti_lowpart_1" + [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r") + (any_or_plus:TI + (and:TI + (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m") + (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n")) + (zero_extend:TI + (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))] + "TARGET_64BIT + && CONST_WIDE_INT_P (operands[3]) + && CONST_WIDE_INT_NUNITS (operands[3]) == 2 + && CONST_WIDE_INT_ELT (operands[3], 0) == 0 + && CONST_WIDE_INT_ELT (operands[3], 1) == -1" + "#" + "&& reload_completed" + [(const_int 0)] +{ + operands[4] = gen_highpart (DImode, operands[1]); + split_double_concat (TImode, operands[0], operands[2], operands[4]); + DONE; +}) + +(define_insn_and_split "*insvdi_lowpart_1" + [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r") + (any_or_plus:DI + (and:DI + (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m") + (match_operand:DI 3 "const_int_operand" "n,n,n,n")) + (zero_extend:DI + (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))] + "!TARGET_64BIT + && CONST_INT_P (operands[3]) + && UINTVAL (operands[3]) == 0xffffffff00000000ll" + "#" + "&& reload_completed" + [(const_int 0)] +{ + operands[4] = gen_highpart (SImode, operands[1]); + split_double_concat (DImode, operands[0], operands[2], operands[4]); + DONE; +}) ;; Floating point push instructions. diff --git a/gcc/testsuite/gcc.target/i386/insvdi_lowpart-1.c b/gcc/testsuite/gcc.target/i386/insvdi_lowpart-1.c new file mode 100644 index 0000000..4d94fec --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/insvdi_lowpart-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2" } */ + +long long foo(long long x, int y) +{ + long long mask = ~0ull << 32; + long long t = x & mask; + long long r = t | (unsigned int)y; + return r; +} + +/* { dg-final { scan-assembler-not "xorl" } } */ +/* { dg-final { scan-assembler-not "orq" } } */ diff --git a/gcc/testsuite/gcc.target/i386/insvti_lowpart-1.c b/gcc/testsuite/gcc.target/i386/insvti_lowpart-1.c new file mode 100644 index 0000000..4e1fbbb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/insvti_lowpart-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2" } */ + +__int128 foo(__int128 x, unsigned long long y) +{ + __int128 m = ~((__int128)~0ull); + __int128 t = x & m; + __int128 r = t | y; + return r; +} + +/* { dg-final { scan-assembler-not "xorl" } } */ +/* { dg-final { scan-assembler-not "orq" } } */ -- cgit v1.1 From 63ae6bc60c0f67fb2791991bf4b6e7e0a907d420 Mon Sep 17 00:00:00 2001 From: Xi Ruoyao Date: Thu, 6 Jul 2023 23:08:57 +0800 Subject: vect: Fix vectorized BIT_FIELD_REF for signed bit-fields [PR110557] If a bit-field is signed and it's wider than the output type, we must ensure the extracted result sign-extended. But this was not handled correctly. For example: int x : 8; long y : 55; bool z : 1; The vectorized extraction of y was: vect__ifc__49.29_110 = MEM [(struct Item *)vectp_a.27_108]; vect_patt_38.30_112 = vect__ifc__49.29_110 & { 9223372036854775552, 9223372036854775552 }; vect_patt_39.31_113 = vect_patt_38.30_112 >> 8; vect_patt_40.32_114 = VIEW_CONVERT_EXPR(vect_patt_39.31_113); This is obviously incorrect. This pach has implemented it as: vect__ifc__25.16_62 = MEM [(struct Item *)vectp_a.14_60]; vect_patt_31.17_63 = VIEW_CONVERT_EXPR(vect__ifc__25.16_62); vect_patt_32.18_64 = vect_patt_31.17_63 << 1; vect_patt_33.19_65 = vect_patt_32.18_64 >> 9; gcc/ChangeLog: PR tree-optimization/110557 * tree-vect-patterns.cc (vect_recog_bitfield_ref_pattern): Ensure the output sign-extended if necessary. gcc/testsuite/ChangeLog: PR tree-optimization/110557 * g++.dg/vect/pr110557.cc: New test. --- gcc/testsuite/g++.dg/vect/pr110557.cc | 37 +++++++++++++++++++++ gcc/tree-vect-patterns.cc | 62 ++++++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/vect/pr110557.cc (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/vect/pr110557.cc b/gcc/testsuite/g++.dg/vect/pr110557.cc new file mode 100644 index 0000000..e1fbe1c --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr110557.cc @@ -0,0 +1,37 @@ +// { dg-additional-options "-mavx" { target { avx_runtime } } } + +static inline long +min (long a, long b) +{ + return a < b ? a : b; +} + +struct Item +{ + int x : 8; + long y : 55; + bool z : 1; +}; + +__attribute__ ((noipa)) long +test (Item *a, int cnt) +{ + long size = 0; + for (int i = 0; i < cnt; i++) + size = min ((long)a[i].y, size); + return size; +} + +int +main () +{ + struct Item items[] = { + { 1, -1 }, + { 2, -2 }, + { 3, -3 }, + { 4, -4 }, + }; + + if (test (items, 4) != -4) + __builtin_trap (); +} diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index 1bc36b0..c0832e8 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -2566,7 +2566,7 @@ vect_recog_widen_sum_pattern (vec_info *vinfo, Widening with mask first, shift later: container = (type_out) container; masked = container & (((1 << bitsize) - 1) << bitpos); - result = patt2 >> masked; + result = masked >> bitpos; Widening with shift first, mask last: container = (type_out) container; @@ -2578,6 +2578,15 @@ vect_recog_widen_sum_pattern (vec_info *vinfo, result = masked >> bitpos; result = (type_out) result; + If the bitfield is signed and it's wider than type_out, we need to + keep the result sign-extended: + container = (type) container; + masked = container << (prec - bitsize - bitpos); + result = (type_out) (masked >> (prec - bitsize)); + + Here type is the signed variant of the wider of type_out and the type + of container. + The shifting is always optional depending on whether bitpos != 0. */ @@ -2636,14 +2645,22 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, if (BYTES_BIG_ENDIAN) shift_n = prec - shift_n - mask_width; + bool ref_sext = (!TYPE_UNSIGNED (TREE_TYPE (bf_ref)) && + TYPE_PRECISION (ret_type) > mask_width); + bool load_widen = (TYPE_PRECISION (TREE_TYPE (container)) < + TYPE_PRECISION (ret_type)); + /* We move the conversion earlier if the loaded type is smaller than the - return type to enable the use of widening loads. */ - if (TYPE_PRECISION (TREE_TYPE (container)) < TYPE_PRECISION (ret_type) - && !useless_type_conversion_p (TREE_TYPE (container), ret_type)) - { - pattern_stmt - = gimple_build_assign (vect_recog_temp_ssa_var (ret_type), - NOP_EXPR, container); + return type to enable the use of widening loads. And if we need a + sign extension, we need to convert the loaded value early to a signed + type as well. */ + if (ref_sext || load_widen) + { + tree type = load_widen ? ret_type : container_type; + if (ref_sext) + type = gimple_signed_type (type); + pattern_stmt = gimple_build_assign (vect_recog_temp_ssa_var (type), + NOP_EXPR, container); container = gimple_get_lhs (pattern_stmt); container_type = TREE_TYPE (container); prec = tree_to_uhwi (TYPE_SIZE (container_type)); @@ -2671,7 +2688,7 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, shift_first = true; tree result; - if (shift_first) + if (shift_first && !ref_sext) { tree shifted = container; if (shift_n) @@ -2694,14 +2711,27 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, } else { - tree mask = wide_int_to_tree (container_type, - wi::shifted_mask (shift_n, mask_width, - false, prec)); - pattern_stmt - = gimple_build_assign (vect_recog_temp_ssa_var (container_type), - BIT_AND_EXPR, container, mask); - tree masked = gimple_assign_lhs (pattern_stmt); + tree temp = vect_recog_temp_ssa_var (container_type); + if (!ref_sext) + { + tree mask = wide_int_to_tree (container_type, + wi::shifted_mask (shift_n, + mask_width, + false, prec)); + pattern_stmt = gimple_build_assign (temp, BIT_AND_EXPR, + container, mask); + } + else + { + HOST_WIDE_INT shl = prec - shift_n - mask_width; + shift_n += shl; + pattern_stmt = gimple_build_assign (temp, LSHIFT_EXPR, + container, + build_int_cst (sizetype, + shl)); + } + tree masked = gimple_assign_lhs (pattern_stmt); append_pattern_def_seq (vinfo, stmt_info, pattern_stmt, vectype); pattern_stmt = gimple_build_assign (vect_recog_temp_ssa_var (container_type), -- cgit v1.1 From 92eeb32df4f134e96265631511b6b26609aa9c12 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 28 Jun 2023 01:36:53 -0300 Subject: ada: Add leafy mode for zero-call-used-regs Document leafy mode. gcc/ada/ * doc/gnat_rm/security_hardening_features.rst (Register Scrubbing): Document leafy mode. * gnat_rm.texi: Regenerate. --- gcc/ada/doc/gnat_rm/security_hardening_features.rst | 6 ++++++ gcc/ada/gnat_rm.texi | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst b/gcc/ada/doc/gnat_rm/security_hardening_features.rst index ad165cd..1432859 100644 --- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst +++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst @@ -34,6 +34,12 @@ subprograms. pragma Machine_Attribute (Bar, "zero_call_used_regs", "all"); -- Before returning, Bar scrubs all call-clobbered registers. + function Baz return Integer; + pragma Machine_Attribute (Bar, "zero_call_used_regs", "leafy"); + -- Before returning, Bar scrubs call-clobbered registers, either + -- those it uses itself, if it can be identified as a leaf + -- function, or all of them otherwise. + For usage and more details on the command-line option, on the ``zero_call_used_regs`` attribute, and on their use with other diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index b28e6eb..817ba0b 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -19,7 +19,7 @@ @copying @quotation -GNAT Reference Manual , Jul 04, 2023 +GNAT Reference Manual , Jul 10, 2023 AdaCore @@ -29191,6 +29191,12 @@ pragma Machine_Attribute (Foo, "zero_call_used_regs", "used"); function Bar return Integer; pragma Machine_Attribute (Bar, "zero_call_used_regs", "all"); -- Before returning, Bar scrubs all call-clobbered registers. + +function Baz return Integer; +pragma Machine_Attribute (Bar, "zero_call_used_regs", "leafy"); +-- Before returning, Bar scrubs call-clobbered registers, either +-- those it uses itself, if it can be identified as a leaf +-- function, or all of them otherwise. @end example For usage and more details on the command-line option, on the -- cgit v1.1 From 4a58185d67029f866577a551888cabf2ac71d9b8 Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Wed, 28 Jun 2023 13:56:26 +0000 Subject: ada: Adapt proof of System.Arith_Double to remove CVC4 The proof of System.Arith_Double still required the use of CVC4, now replaced by its successor cvc5. Adapt the proof to be able to remove CVC4 in the proof of run-time units. gcc/ada/ * libgnat/s-aridou.adb (Lemma_Div_Mult): New simple lemma. (Lemma_Powers_Of_2_Commutation): State post in else branch. (Lemma_Div_Pow2): Introduce local lemma and use it. (Scaled_Divide): Use cut operations in assertions, lemmas, new assertions. Introduce local lemma and use it. --- gcc/ada/libgnat/s-aridou.adb | 84 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/libgnat/s-aridou.adb b/gcc/ada/libgnat/s-aridou.adb index 831590c..7ebf868 100644 --- a/gcc/ada/libgnat/s-aridou.adb +++ b/gcc/ada/libgnat/s-aridou.adb @@ -301,6 +301,11 @@ is Pre => A * S = B * S + R and then S /= 0, Post => A = B + R / S; + procedure Lemma_Div_Mult (X : Big_Natural; Y : Big_Positive) + with + Ghost, + Post => X / Y * Y > X - Y; + procedure Lemma_Double_Big_2xxSingle with Ghost, @@ -639,6 +644,7 @@ is is null; procedure Lemma_Div_Ge (X, Y, Z : Big_Integer) is null; procedure Lemma_Div_Lt (X, Y, Z : Big_Natural) is null; + procedure Lemma_Div_Mult (X : Big_Natural; Y : Big_Positive) is null; procedure Lemma_Double_Big_2xxSingle is null; procedure Lemma_Double_Shift (X : Double_Uns; S, S1 : Double_Uns) is null; procedure Lemma_Double_Shift (X : Single_Uns; S, S1 : Natural) is null; @@ -1449,6 +1455,10 @@ is (Double_Uns'(2 ** (M - 1)), 2, Double_Uns'(2**M)); pragma Assert (Big (Double_Uns'(2))**M = Big_2xx (M)); end if; + else + pragma Assert + (Big (Double_Uns'(2))**M = + (if M < Double_Size then Big_2xx (M) else Big_2xxDouble)); end if; end Lemma_Powers_Of_2_Commutation; @@ -1537,6 +1547,19 @@ is "Q is the quotient of X by Div"); procedure Lemma_Div_Pow2 (X : Double_Uns; I : Natural) is + + -- Local lemmas + + procedure Lemma_Mult_Le (X, Y, Z : Double_Uns) + with + Ghost, + Pre => X <= 1, + Post => X * Z <= Z; + + procedure Lemma_Mult_Le (X, Y, Z : Double_Uns) is null; + + -- Local variables + Div1 : constant Double_Uns := Double_Uns'(2) ** I; Div2 : constant Double_Uns := Double_Uns'(2); Left : constant Double_Uns := X / Div1 / Div2; @@ -1544,8 +1567,12 @@ is pragma Assert (R2 <= Div2 - 1); R1 : constant Double_Uns := X - X / Div1 * Div1; pragma Assert (R1 < Div1); + + -- Start of processing for Lemma_Div_Pow2 + begin pragma Assert (X = Left * (Div1 * Div2) + R2 * Div1 + R1); + Lemma_Mult_Le (R2, Div2 - 1, Div1); pragma Assert (R2 * Div1 + R1 < Div1 * Div2); Lemma_Quot_Rem (X, Div1 * Div2, Left, R2 * Div1 + R1); pragma Assert (Left = X / (Div1 * Div2)); @@ -2937,7 +2964,10 @@ is Big_2xxSingle * Big (Double_Uns (D (3))) + Big (Double_Uns (D (4)))); pragma Assert - (Big (D (1) & D (2)) < Big (Zu)); + (By (Big (D (1) & D (2)) < Big (Zu), + Big_2xxDouble * (Big (Zu) - Big (D (1) & D (2))) > + Big_2xxSingle * Big (Double_Uns (D (3))) + + Big (Double_Uns (D (4))))); -- Loop to compute quotient digits, runs twice for Qd (1) and Qd (2) @@ -2962,7 +2992,7 @@ is -- Local ghost variables Qd1 : Single_Uns := 0 with Ghost; - D234 : Big_Integer with Ghost; + D234 : Big_Integer with Ghost, Relaxed_Initialization; D123 : constant Big_Integer := Big3 (D (1), D (2), D (3)) with Ghost; D4 : constant Big_Integer := Big (Double_Uns (D (4))) @@ -3015,8 +3045,10 @@ is Lemma_Div_Lt (Big3 (D (J), D (J + 1), D (J + 2)), Big_2xxSingle, Big (Zu)); - pragma Assert (Big (Double_Uns (Qd (J))) >= - Big3 (D (J), D (J + 1), D (J + 2)) / Big (Zu)); + pragma Assert + (By (Big (Double_Uns (Qd (J))) >= + Big3 (D (J), D (J + 1), D (J + 2)) / Big (Zu), + Big (Double_Uns (Qd (J))) = Big_2xxSingle - 1)); else Qd (J) := Lo ((D (J) & D (J + 1)) / Zhi); @@ -3025,6 +3057,7 @@ is end if; pragma Assert (for all K in 1 .. J => Qd (K)'Initialized); + Lemma_Div_Mult (Big3 (D (J), D (J + 1), D (J + 2)), Big (Zu)); Lemma_Gt_Mult (Big (Double_Uns (Qd (J))), Big3 (D (J), D (J + 1), D (J + 2)) / Big (Zu), @@ -3094,6 +3127,11 @@ is Qd (J) := Qd (J) - 1; pragma Assert (Qd (J) = Prev); + pragma Assert (Qd (J)'Initialized); + if J = 2 then + pragma Assert (Qd (J - 1)'Initialized); + end if; + pragma Assert (for all K in 1 .. J => Qd (K)'Initialized); end; pragma Assert @@ -3156,11 +3194,18 @@ is else pragma Assert (Qd1 = Qd (1)); pragma Assert - (Mult * Big_2xx (Scale) = + (By (Mult * Big_2xx (Scale) = Big_2xxSingle * Big (Double_Uns (Qd (1))) * Big (Zu) + Big (Double_Uns (Qd (2))) * Big (Zu) + Big_2xxSingle * Big (Double_Uns (D (3))) - + Big (Double_Uns (D (4)))); + + Big (Double_Uns (D (4))), + By (Mult * Big_2xx (Scale) = + Big_2xxSingle * Big (Double_Uns (Qd (1))) * Big (Zu) + + Big3 (D (2), D (3), D (4)) + Big3 (S1, S2, S3), + Mult * Big_2xx (Scale) = + Big_2xxSingle * Big (Double_Uns (Qd (1))) * Big (Zu) + + D234))); + end if; end loop; end; @@ -3193,11 +3238,32 @@ is Ru := Shift_Right (Ru, Scale); - Lemma_Shift_Right (Zu, Scale); + declare + -- Local lemma required to help automatic provers + procedure Lemma_Div_Congruent + (X, Y : Big_Natural; + Z : Big_Positive) + with + Ghost, + Pre => X = Y, + Post => X / Z = Y / Z; + + procedure Lemma_Div_Congruent + (X, Y : Big_Natural; + Z : Big_Positive) + is null; - Zu := Shift_Right (Zu, Scale); + begin + Lemma_Shift_Right (Zu, Scale); + Lemma_Div_Congruent (Big (Zu), + Big (Double_Uns'(abs Z)) * Big_2xx (Scale), + Big_2xx (Scale)); + + Zu := Shift_Right (Zu, Scale); - Lemma_Simplify (Big (Double_Uns'(abs Z)), Big_2xx (Scale)); + Lemma_Simplify (Big (Double_Uns'(abs Z)), Big_2xx (Scale)); + pragma Assert (Big (Zu) = Big (Double_Uns'(abs Z))); + end; end if; pragma Assert (Big (Ru) = abs Big_R); -- cgit v1.1 From 61736805341e4fabd1c5e0f46b15b459ad98179e Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 28 Jun 2023 01:36:51 -0300 Subject: ada: hardcfr: mark throw-expected functions Adjust documentation to reflect the introduction of -fhardcfr-check-noreturn-calls=no-xthrow. gcc/ada/ * doc/gnat_rm/security_hardening_features.rst (Control Flow Redundancy): Add -fhardcfr-check-noreturn-calls=no-xthrow. * gnat_rm.texi: Regenerate. --- gcc/ada/doc/gnat_rm/security_hardening_features.rst | 17 +++++++++-------- gcc/ada/gnat_rm.texi | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst b/gcc/ada/doc/gnat_rm/security_hardening_features.rst index 1432859..cf8c8a2 100644 --- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst +++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst @@ -493,17 +493,18 @@ gets modified as follows: end; -Verification may also be performed before No_Return calls, whether -only nothrow ones, with -:switch:`-fhardcfr-check-noreturn-calls=nothrow`, or all of them, with -:switch:`-fhardcfr-check-noreturn-calls=always`. The default is -:switch:`-fhardcfr-check-noreturn-calls=never` for this feature, that -disables checking before No_Return calls. +Verification may also be performed before No_Return calls, whether all +of them, with :switch:`-fhardcfr-check-noreturn-calls=always`; all but +internal subprograms involved in exception-raising or -reraising, with +:switch:`-fhardcfr-check-noreturn-calls=no-xthrow` (default); only +nothrow ones, with :switch:`-fhardcfr-check-noreturn-calls=nothrow`; +or none, with :switch:`-fhardcfr-check-noreturn-calls=never`. When a No_Return call returns control to its caller through an exception, verification may have already been performed before the -call, if :switch:`-fhardcfr-check-noreturn-calls=always` is in effect. -The compiler arranges for already-checked No_Return calls without a +call, if :switch:`-fhardcfr-check-noreturn-calls=always` or +:switch:`-fhardcfr-check-noreturn-calls=no-xthrow` is in effect. The +compiler arranges for already-checked No_Return calls without a preexisting handler to bypass the implicitly-added cleanup handler and thus the redundant check, but a local exception or cleanup handler, if present, will modify the set of visited blocks, and checking will take diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 817ba0b..988bb77 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -29634,17 +29634,18 @@ exception end; @end example -Verification may also be performed before No_Return calls, whether -only nothrow ones, with -@code{-fhardcfr-check-noreturn-calls=nothrow}, or all of them, with -@code{-fhardcfr-check-noreturn-calls=always}. The default is -@code{-fhardcfr-check-noreturn-calls=never} for this feature, that -disables checking before No_Return calls. +Verification may also be performed before No_Return calls, whether all +of them, with @code{-fhardcfr-check-noreturn-calls=always}; all but +internal subprograms involved in exception-raising or -reraising, with +@code{-fhardcfr-check-noreturn-calls=no-xthrow} (default); only +nothrow ones, with @code{-fhardcfr-check-noreturn-calls=nothrow}; +or none, with @code{-fhardcfr-check-noreturn-calls=never}. When a No_Return call returns control to its caller through an exception, verification may have already been performed before the -call, if @code{-fhardcfr-check-noreturn-calls=always} is in effect. -The compiler arranges for already-checked No_Return calls without a +call, if @code{-fhardcfr-check-noreturn-calls=always} or +@code{-fhardcfr-check-noreturn-calls=no-xthrow} is in effect. The +compiler arranges for already-checked No_Return calls without a preexisting handler to bypass the implicitly-added cleanup handler and thus the redundant check, but a local exception or cleanup handler, if present, will modify the set of visited blocks, and checking will take -- cgit v1.1 From d4d6eda9427ff4616c49092cd92e4e99f16300ed Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 28 Jun 2023 01:36:53 -0300 Subject: ada: hardcfr: optionally disable in leaf functions Document -fhardcfr-skip-leaf. gcc/ada/ * doc/gnat_rm/security_hardening_features.rst (Control Flow Hardening): Document -fhardcfr-skip-leaf. * gnat_rm.texi: Regenerate. --- gcc/ada/doc/gnat_rm/security_hardening_features.rst | 5 +++++ gcc/ada/gnat_rm.texi | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst b/gcc/ada/doc/gnat_rm/security_hardening_features.rst index cf8c8a2..e057af2e 100644 --- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst +++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst @@ -369,6 +369,11 @@ basic blocks take note as control flows through them, and, before returning, subprograms verify that the taken notes are consistent with the control-flow graph. +The performance impact of verification on leaf subprograms can be much +higher, while the averted risks are much lower on them. +Instrumentation can be disabled for leaf subprograms with +:switch:`-fhardcfr-skip-leaf`. + Functions with too many basic blocks, or with multiple return points, call a run-time function to perform the verification. Other functions perform the verification inline before returning. diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 988bb77..0d11be0 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -29515,6 +29515,11 @@ basic blocks take note as control flows through them, and, before returning, subprograms verify that the taken notes are consistent with the control-flow graph. +The performance impact of verification on leaf subprograms can be much +higher, while the averted risks are much lower on them. +Instrumentation can be disabled for leaf subprograms with +@code{-fhardcfr-skip-leaf}. + Functions with too many basic blocks, or with multiple return points, call a run-time function to perform the verification. Other functions perform the verification inline before returning. -- cgit v1.1 From 9105cd9062520969092fe4ecb3ce5ef34b2dfaaf Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Thu, 22 Jun 2023 13:43:00 -0400 Subject: ada: Documentation for mixed declarations and statements This patch documents the new feature that allows declarations mixed with statements, primarily by referring to the RFC. gcc/ada/ * doc/gnat_rm/gnat_language_extensions.rst (Local Declarations Without Block): Document the feature very briefly, and refer the reader to the RFC for details and examples. * gnat_rm.texi: Regenerate. * gnat_ugn.texi: Regenerate. --- gcc/ada/doc/gnat_rm/gnat_language_extensions.rst | 21 +++++ gcc/ada/gnat_rm.texi | 111 ++++++++++++++--------- gcc/ada/gnat_ugn.texi | 4 +- 3 files changed, 91 insertions(+), 45 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst index 220345d..42d6413 100644 --- a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst +++ b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst @@ -45,6 +45,27 @@ file, or in a ``.adc`` file corresponding to your project. Curated Extensions ================== +Local Declarations Without Block +-------------------------------- + +A basic_declarative_item may appear at the place of any statement. +This avoids the heavy syntax of block_statements just to declare +something locally. + +Link to the original RFC: +https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-local-vars-without-block.md +For example: + +.. code-block:: ada + + if X > 5 then + X := X + 1; + + Squared : constant Integer := X**2; + + X := X + Squared; + end if; + Conditional when constructs --------------------------- diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 0d11be0..066c066 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -881,6 +881,7 @@ GNAT language extensions Curated Extensions +* Local Declarations Without Block:: * Conditional when constructs:: * Case pattern matching:: * Fixed lower bounds for array types and subtypes:: @@ -28574,6 +28575,7 @@ for serious projects, and is only means as a playground/technology preview. @menu +* Local Declarations Without Block:: * Conditional when constructs:: * Case pattern matching:: * Fixed lower bounds for array types and subtypes:: @@ -28585,8 +28587,31 @@ for serious projects, and is only means as a playground/technology preview. @end menu -@node Conditional when constructs,Case pattern matching,,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions conditional-when-constructs}@anchor{436} +@node Local Declarations Without Block,Conditional when constructs,,Curated Extensions +@anchor{gnat_rm/gnat_language_extensions local-declarations-without-block}@anchor{436} +@subsection Local Declarations Without Block + + +A basic_declarative_item may appear at the place of any statement. +This avoids the heavy syntax of block_statements just to declare +something locally. + +Link to the original RFC: +@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-local-vars-without-block.md} +For example: + +@example +if X > 5 then + X := X + 1; + + Squared : constant Integer := X**2; + + X := X + Squared; +end if; +@end example + +@node Conditional when constructs,Case pattern matching,Local Declarations Without Block,Curated Extensions +@anchor{gnat_rm/gnat_language_extensions conditional-when-constructs}@anchor{437} @subsection Conditional when constructs @@ -28658,7 +28683,7 @@ Link to the original RFC: @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-conditional-when-constructs.rst} @node Case pattern matching,Fixed lower bounds for array types and subtypes,Conditional when constructs,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions case-pattern-matching}@anchor{437} +@anchor{gnat_rm/gnat_language_extensions case-pattern-matching}@anchor{438} @subsection Case pattern matching @@ -28790,7 +28815,7 @@ Link to the original RFC: @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-pattern-matching.rst} @node Fixed lower bounds for array types and subtypes,Prefixed-view notation for calls to primitive subprograms of untagged types,Case pattern matching,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions fixed-lower-bounds-for-array-types-and-subtypes}@anchor{438} +@anchor{gnat_rm/gnat_language_extensions fixed-lower-bounds-for-array-types-and-subtypes}@anchor{439} @subsection Fixed lower bounds for array types and subtypes @@ -28844,7 +28869,7 @@ Link to the original RFC: @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-fixed-lower-bound.rst} @node Prefixed-view notation for calls to primitive subprograms of untagged types,Expression defaults for generic formal functions,Fixed lower bounds for array types and subtypes,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions prefixed-view-notation-for-calls-to-primitive-subprograms-of-untagged-types}@anchor{439} +@anchor{gnat_rm/gnat_language_extensions prefixed-view-notation-for-calls-to-primitive-subprograms-of-untagged-types}@anchor{43a} @subsection Prefixed-view notation for calls to primitive subprograms of untagged types @@ -28897,7 +28922,7 @@ Link to the original RFC: @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-prefixed-untagged.rst} @node Expression defaults for generic formal functions,String interpolation,Prefixed-view notation for calls to primitive subprograms of untagged types,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions expression-defaults-for-generic-formal-functions}@anchor{43a} +@anchor{gnat_rm/gnat_language_extensions expression-defaults-for-generic-formal-functions}@anchor{43b} @subsection Expression defaults for generic formal functions @@ -28926,7 +28951,7 @@ Link to the original RFC: @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-expression-functions-as-default-for-generic-formal-function-parameters.rst} @node String interpolation,Constrained attribute for generic objects,Expression defaults for generic formal functions,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions string-interpolation}@anchor{43b} +@anchor{gnat_rm/gnat_language_extensions string-interpolation}@anchor{43c} @subsection String interpolation @@ -29092,7 +29117,7 @@ Here is a link to the original RFC : @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-string-interpolation.rst} @node Constrained attribute for generic objects,Static aspect on intrinsic functions,String interpolation,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions constrained-attribute-for-generic-objects}@anchor{43c} +@anchor{gnat_rm/gnat_language_extensions constrained-attribute-for-generic-objects}@anchor{43d} @subsection Constrained attribute for generic objects @@ -29100,7 +29125,7 @@ The @code{Constrained} attribute is permitted for objects of generic types. The result indicates whether the corresponding actual is constrained. @node Static aspect on intrinsic functions,,Constrained attribute for generic objects,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions static-aspect-on-intrinsic-functions}@anchor{43d} +@anchor{gnat_rm/gnat_language_extensions static-aspect-on-intrinsic-functions}@anchor{43e} @subsection @code{Static} aspect on intrinsic functions @@ -29109,7 +29134,7 @@ and the compiler will evaluate some of these intrinsics statically, in particular the @code{Shift_Left} and @code{Shift_Right} intrinsics. @node Experimental Language Extensions,,Curated Extensions,GNAT language extensions -@anchor{gnat_rm/gnat_language_extensions experimental-language-extensions}@anchor{67}@anchor{gnat_rm/gnat_language_extensions id2}@anchor{43e} +@anchor{gnat_rm/gnat_language_extensions experimental-language-extensions}@anchor{67}@anchor{gnat_rm/gnat_language_extensions id2}@anchor{43f} @section Experimental Language Extensions @@ -29120,7 +29145,7 @@ particular the @code{Shift_Left} and @code{Shift_Right} intrinsics. @end menu @node Pragma Storage_Model,Simpler accessibility model,,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions pragma-storage-model}@anchor{43f} +@anchor{gnat_rm/gnat_language_extensions pragma-storage-model}@anchor{440} @subsection Pragma Storage_Model @@ -29135,7 +29160,7 @@ Here is a link to the full RFC: @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-storage-model.rst} @node Simpler accessibility model,,Pragma Storage_Model,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions simpler-accessibility-model}@anchor{440} +@anchor{gnat_rm/gnat_language_extensions simpler-accessibility-model}@anchor{441} @subsection Simpler accessibility model @@ -29148,7 +29173,7 @@ Here is a link to the full RFC: @indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-simpler-accessibility.md} @node Security Hardening Features,Obsolescent Features,GNAT language extensions,Top -@anchor{gnat_rm/security_hardening_features doc}@anchor{441}@anchor{gnat_rm/security_hardening_features id1}@anchor{442}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15} +@anchor{gnat_rm/security_hardening_features doc}@anchor{442}@anchor{gnat_rm/security_hardening_features id1}@anchor{443}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15} @chapter Security Hardening Features @@ -29170,7 +29195,7 @@ change. @end menu @node Register Scrubbing,Stack Scrubbing,,Security Hardening Features -@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{443} +@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{444} @section Register Scrubbing @@ -29206,7 +29231,7 @@ programming languages, see @cite{Using the GNU Compiler Collection (GCC)}. @c Stack Scrubbing: @node Stack Scrubbing,Hardened Conditionals,Register Scrubbing,Security Hardening Features -@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{444} +@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{445} @section Stack Scrubbing @@ -29350,7 +29375,7 @@ Bar_Callable_Ptr. @c Hardened Conditionals: @node Hardened Conditionals,Hardened Booleans,Stack Scrubbing,Security Hardening Features -@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{445} +@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{446} @section Hardened Conditionals @@ -29440,7 +29465,7 @@ be used with other programming languages supported by GCC. @c Hardened Booleans: @node Hardened Booleans,Control Flow Redundancy,Hardened Conditionals,Security Hardening Features -@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{446} +@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{447} @section Hardened Booleans @@ -29501,7 +29526,7 @@ and more details on that attribute, see @cite{Using the GNU Compiler Collection @c Control Flow Redundancy: @node Control Flow Redundancy,,Hardened Booleans,Security Hardening Features -@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{447} +@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{448} @section Control Flow Redundancy @@ -29667,7 +29692,7 @@ see @cite{Using the GNU Compiler Collection (GCC)}. These options can be used with other programming languages supported by GCC. @node Obsolescent Features,Compatibility and Porting Guide,Security Hardening Features,Top -@anchor{gnat_rm/obsolescent_features doc}@anchor{448}@anchor{gnat_rm/obsolescent_features id1}@anchor{449}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16} +@anchor{gnat_rm/obsolescent_features doc}@anchor{449}@anchor{gnat_rm/obsolescent_features id1}@anchor{44a}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16} @chapter Obsolescent Features @@ -29686,7 +29711,7 @@ compatibility purposes. @end menu @node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id2}@anchor{44a}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{44b} +@anchor{gnat_rm/obsolescent_features id2}@anchor{44b}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{44c} @section pragma No_Run_Time @@ -29699,7 +29724,7 @@ preferred usage is to use an appropriately configured run-time that includes just those features that are to be made accessible. @node pragma Ravenscar,pragma Restricted_Run_Time,pragma No_Run_Time,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id3}@anchor{44c}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{44d} +@anchor{gnat_rm/obsolescent_features id3}@anchor{44d}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{44e} @section pragma Ravenscar @@ -29708,7 +29733,7 @@ The pragma @code{Ravenscar} has exactly the same effect as pragma is part of the new Ada 2005 standard. @node pragma Restricted_Run_Time,pragma Task_Info,pragma Ravenscar,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id4}@anchor{44e}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{44f} +@anchor{gnat_rm/obsolescent_features id4}@anchor{44f}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{450} @section pragma Restricted_Run_Time @@ -29718,7 +29743,7 @@ preferred since the Ada 2005 pragma @code{Profile} is intended for this kind of implementation dependent addition. @node pragma Task_Info,package System Task_Info s-tasinf ads,pragma Restricted_Run_Time,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id5}@anchor{450}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{451} +@anchor{gnat_rm/obsolescent_features id5}@anchor{451}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{452} @section pragma Task_Info @@ -29744,7 +29769,7 @@ in the spec of package System.Task_Info in the runtime library. @node package System Task_Info s-tasinf ads,,pragma Task_Info,Obsolescent Features -@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{452}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{453} +@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{453}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{454} @section package System.Task_Info (@code{s-tasinf.ads}) @@ -29754,7 +29779,7 @@ to support the @code{Task_Info} pragma. The predefined Ada package standard replacement for GNAT’s @code{Task_Info} functionality. @node Compatibility and Porting Guide,GNU Free Documentation License,Obsolescent Features,Top -@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{455} +@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{455}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{456} @chapter Compatibility and Porting Guide @@ -29776,7 +29801,7 @@ applications developed in other Ada environments. @end menu @node Writing Portable Fixed-Point Declarations,Compatibility with Ada 83,,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{457} +@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{457}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{458} @section Writing Portable Fixed-Point Declarations @@ -29898,7 +29923,7 @@ If you follow this scheme you will be guaranteed that your fixed-point types will be portable. @node Compatibility with Ada 83,Compatibility between Ada 95 and Ada 2005,Writing Portable Fixed-Point Declarations,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{459} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{459}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{45a} @section Compatibility with Ada 83 @@ -29926,7 +29951,7 @@ following subsections treat the most likely issues to be encountered. @end menu @node Legal Ada 83 programs that are illegal in Ada 95,More deterministic semantics,,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{45a}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{45b} +@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{45b}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{45c} @subsection Legal Ada 83 programs that are illegal in Ada 95 @@ -30026,7 +30051,7 @@ the fix is usually simply to add the @code{(<>)} to the generic declaration. @end itemize @node More deterministic semantics,Changed semantics,Legal Ada 83 programs that are illegal in Ada 95,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{45d} +@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{45d}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{45e} @subsection More deterministic semantics @@ -30054,7 +30079,7 @@ which open select branches are executed. @end itemize @node Changed semantics,Other language compatibility issues,More deterministic semantics,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{45e}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{45f} +@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{45f}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{460} @subsection Changed semantics @@ -30096,7 +30121,7 @@ covers only the restricted range. @end itemize @node Other language compatibility issues,,Changed semantics,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{460}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{461} +@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{461}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{462} @subsection Other language compatibility issues @@ -30129,7 +30154,7 @@ include @code{pragma Interface} and the floating point type attributes @end itemize @node Compatibility between Ada 95 and Ada 2005,Implementation-dependent characteristics,Compatibility with Ada 83,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{462}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{463} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{463}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{464} @section Compatibility between Ada 95 and Ada 2005 @@ -30201,7 +30226,7 @@ can declare a function returning a value from an anonymous access type. @end itemize @node Implementation-dependent characteristics,Compatibility with Other Ada Systems,Compatibility between Ada 95 and Ada 2005,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{464}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{465} +@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{465}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{466} @section Implementation-dependent characteristics @@ -30224,7 +30249,7 @@ transition from certain Ada 83 compilers. @end menu @node Implementation-defined pragmas,Implementation-defined attributes,,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{466}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{467} +@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{467}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{468} @subsection Implementation-defined pragmas @@ -30246,7 +30271,7 @@ avoiding compiler rejection of units that contain such pragmas; they are not relevant in a GNAT context and hence are not otherwise implemented. @node Implementation-defined attributes,Libraries,Implementation-defined pragmas,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{468}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{469} +@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{469}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{46a} @subsection Implementation-defined attributes @@ -30260,7 +30285,7 @@ Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and @code{Type_Class}. @node Libraries,Elaboration order,Implementation-defined attributes,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{46a}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{46b} +@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{46b}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{46c} @subsection Libraries @@ -30289,7 +30314,7 @@ be preferable to retrofit the application using modular types. @end itemize @node Elaboration order,Target-specific aspects,Libraries,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{46c}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{46d} +@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{46d}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{46e} @subsection Elaboration order @@ -30325,7 +30350,7 @@ pragmas either globally (as an effect of the `-gnatE' switch) or locally @end itemize @node Target-specific aspects,,Elaboration order,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{46e}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{46f} +@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{46f}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{470} @subsection Target-specific aspects @@ -30338,10 +30363,10 @@ on the robustness of the original design. Moreover, Ada 95 (and thus Ada 2005 and Ada 2012) are sometimes incompatible with typical Ada 83 compiler practices regarding implicit packing, the meaning of the Size attribute, and the size of access values. -GNAT’s approach to these issues is described in @ref{470,,Representation Clauses}. +GNAT’s approach to these issues is described in @ref{471,,Representation Clauses}. @node Compatibility with Other Ada Systems,Representation Clauses,Implementation-dependent characteristics,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{471}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{472} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{472}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{473} @section Compatibility with Other Ada Systems @@ -30384,7 +30409,7 @@ far beyond this minimal set, as described in the next section. @end itemize @node Representation Clauses,Compatibility with HP Ada 83,Compatibility with Other Ada Systems,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{473}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{470} +@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{474}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{471} @section Representation Clauses @@ -30477,7 +30502,7 @@ with thin pointers. @end itemize @node Compatibility with HP Ada 83,,Representation Clauses,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{474}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{475} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{475}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{476} @section Compatibility with HP Ada 83 @@ -30507,7 +30532,7 @@ extension of package System. @end itemize @node GNU Free Documentation License,Index,Compatibility and Porting Guide,Top -@anchor{share/gnu_free_documentation_license doc}@anchor{476}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{477} +@anchor{share/gnu_free_documentation_license doc}@anchor{477}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{478} @chapter GNU Free Documentation License diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index 37d914c..2721251 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -19,7 +19,7 @@ @copying @quotation -GNAT User's Guide for Native Platforms , Jul 06, 2023 +GNAT User's Guide for Native Platforms , Jul 10, 2023 AdaCore @@ -29531,8 +29531,8 @@ to permit their use in free software. @printindex ge -@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ } @anchor{d1}@w{ } +@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ } @c %**end of body @bye -- cgit v1.1 From bcc2c7fa6ed8b7dbb0e3ba11e40958f1b99b83d0 Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Thu, 29 Jun 2023 12:14:39 +0000 Subject: ada: Simplify assertion to remove CodePeer message CodePeer is correctly warning on a test always true in an assertion. It can be rewritten without loss of proof to avoid that message. gcc/ada/ * libgnat/s-aridou.adb (Lemma_Powers_Of_2_Commutation): Rewrite assertion. --- gcc/ada/libgnat/s-aridou.adb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/libgnat/s-aridou.adb b/gcc/ada/libgnat/s-aridou.adb index 7ebf868..2f1fbd5 100644 --- a/gcc/ada/libgnat/s-aridou.adb +++ b/gcc/ada/libgnat/s-aridou.adb @@ -1456,9 +1456,7 @@ is pragma Assert (Big (Double_Uns'(2))**M = Big_2xx (M)); end if; else - pragma Assert - (Big (Double_Uns'(2))**M = - (if M < Double_Size then Big_2xx (M) else Big_2xxDouble)); + pragma Assert (Big (Double_Uns'(2))**M = Big_2xx (M)); end if; end Lemma_Powers_Of_2_Commutation; -- cgit v1.1 From f068a49d95001971e39ab68835e525bb78c65b80 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 29 Jun 2023 08:52:59 -0600 Subject: ada: Add typedefs to snames.h-tmpl A future patch will change sname.h-tmpl to use enums rather than preprocessor defines. In order to do this, first introduce some typedefs that can be used in gcc-interface. gcc/ada/ * snames.h-tmpl (Name_Id, Attribute_Id, Convention_Id) (Pragma_Id): New typedefs. (Get_Attribute_Id, Get_Pragma_Id): Use typedef. --- gcc/ada/snames.h-tmpl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/snames.h-tmpl b/gcc/ada/snames.h-tmpl index b15792a..95b3c77 100644 --- a/gcc/ada/snames.h-tmpl +++ b/gcc/ada/snames.h-tmpl @@ -28,6 +28,7 @@ /* Name_Id values */ +typedef Int Name_Id; #define Name_ !! TEMPLATE INSERTION POINT /* Define the function to return one of the numeric values below. Note @@ -35,8 +36,9 @@ than 256 entries is represented that way in Ada. The operand is a Chars field value. */ +typedef Byte Attribute_Id; #define Get_Attribute_Id snames__get_attribute_id -extern unsigned char Get_Attribute_Id (int); +extern Attribute_Id Get_Attribute_Id (int); /* Define the numeric values for attributes. */ @@ -44,6 +46,7 @@ extern unsigned char Get_Attribute_Id (int); /* Define the numeric values for the conventions. */ +typedef Byte Convention_Id; #define Convention_ !! TEMPLATE INSERTION POINT /* Define the function to check if a Name_Id value is a valid pragma */ @@ -56,8 +59,9 @@ extern Boolean Is_Pragma_Name (Name_Id); than 256 entries is represented that way in Ada. The operand is a Chars field value. */ +typedef Byte Pragma_Id; #define Get_Pragma_Id snames__get_pragma_id -extern unsigned char Get_Pragma_Id (int); +extern Pragma_Id Get_Pragma_Id (int); /* Define the numeric values for the pragmas. */ -- cgit v1.1 From 6de9362acda4acd1462ca04c056f89f542c35ff4 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Jun 2023 17:14:44 +0200 Subject: ada: Follow-up fix for compilation issue with recent MinGW-w64 versions It turns out that adaint.c includes other Windows header files than just windows.h, so defining WIN32_LEAN_AND_MEAN is not sufficient for it. gcc/ada/ * adaint.c [_WIN32]: Undefine 'abort' macro. --- gcc/ada/adaint.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index 8522094..2a193ef 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -227,6 +227,9 @@ UINT __gnat_current_ccs_encoding; #elif defined (_WIN32) +/* Cannot redefine abort here. */ +#undef abort + #define WIN32_LEAN_AND_MEAN #include #include -- cgit v1.1 From 95504a2303faa5f8abee259eea57856085a114a4 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Fri, 7 Jul 2023 07:37:02 +0000 Subject: doc: Document arm_v8_1m_main_cde_mve_fp The arm_v8_1m_main_cde_mve_fp family of effective targets was not documented when it was introduced. 2023-07-07 Christophe Lyon gcc/ * doc/sourcebuild.texi (arm_v8_1m_main_cde_mve_fp): Document. --- gcc/doc/sourcebuild.texi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 526020c..ffb6eb1 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2186,10 +2186,16 @@ the Custom Datapath Extension (CDE) and floating-point (VFP). Some multilibs may be incompatible with these options. @item arm_v8_1m_main_cde_mve -ARM target supports options to generate instructions from ARMv8.1-M with +Arm target supports options to generate instructions from Arm.1-M with the Custom Datapath Extension (CDE) and M-Profile Vector Extension (MVE). Some multilibs may be incompatible with these options. +@item arm_v8_1m_main_cde_mve_fp +ARM target supports options to generate instructions from ARMv8.1-M +with the Custom Datapath Extension (CDE) and M-Profile Vector +Extension (MVE) with floating-point support. Some multilibs may be +incompatible with these options. + @item arm_pacbti_hw Test system supports executing Pointer Authentication and Branch Target Identification instructions. -- cgit v1.1 From 7199b591649b81fef4d78e34a40bc7f474b22051 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Fri, 7 Jul 2023 07:41:59 +0000 Subject: testsuite: Add _link flavor for several arm_arch* and arm* effective-targets For arm targets, we generate many effective-targets with check_effective_target_FUNC_multilib and check_effective_target_arm_arch_FUNC_multilib which check if we can link and execute a simple program with a given set of flags/multilibs. In some cases however, it's possible to link but not to execute a program, so this patch adds similar _link effective-targets which only check if link succeeds. The patch does not uupdate the documentation as it already lacks the numerous existing related effective-targets. 2023-07-07 Christophe Lyon gcc/testsuite/ * lib/target-supports.exp (arm_*FUNC_link): New effective-targets. --- gcc/testsuite/lib/target-supports.exp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index b16853d..33482b2 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -5129,6 +5129,14 @@ foreach { armfunc armflag armdefs } { return "$flags FLAG" } + proc check_effective_target_arm_arch_FUNC_link { } { + return [check_no_compiler_messages arm_arch_FUNC_link executable { + #include + int dummy; + int main (void) { return 0; } + } [add_options_for_arm_arch_FUNC ""]] + } + proc check_effective_target_arm_arch_FUNC_multilib { } { return [check_runtime arm_arch_FUNC_multilib { int @@ -5906,6 +5914,7 @@ proc add_options_for_arm_v8_2a_bf16_neon { flags } { # arm_v8m_main_cde: Armv8-m CDE (Custom Datapath Extension). # arm_v8m_main_cde_fp: Armv8-m CDE with FP registers. # arm_v8_1m_main_cde_mve: Armv8.1-m CDE with MVE. +# arm_v8_1m_main_cde_mve_fp: Armv8.1-m CDE with MVE with FP support. # Usage: # /* { dg-require-effective-target arm_v8m_main_cde_ok } */ # /* { dg-add-options arm_v8m_main_cde } */ @@ -5965,6 +5974,24 @@ foreach { armfunc armflag armdef arminc } { return "$flags $et_FUNC_flags" } + proc check_effective_target_FUNC_link { } { + if { ! [check_effective_target_FUNC_ok] } { + return 0; + } + return [check_no_compiler_messages FUNC_link executable { + #if !(DEF) + #error "DEF failed" + #endif + #include + INC + int + main (void) + { + return 0; + } + } [add_options_for_FUNC ""]] + } + proc check_effective_target_FUNC_multilib { } { if { ! [check_effective_target_FUNC_ok] } { return 0; -- cgit v1.1 From eca10aaa3954af3dab56eccc208c90273c2b1732 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Mon, 26 Jun 2023 14:39:47 +0000 Subject: arm: Fix MVE intrinsics support with LTO (PR target/110268) After the recent MVE intrinsics re-implementation, LTO stopped working because the intrinsics would no longer be defined. The main part of the patch is simple and similar to what we do for AArch64: - call handle_arm_mve_h() from arm_init_mve_builtins to declare the intrinsics when the compiler is in LTO mode - actually implement arm_builtin_decl for MVE. It was just a bit tricky to handle __ARM_MVE_PRESERVE_USER_NAMESPACE: its value in the user code cannot be guessed at LTO time, so we always have to assume that it was not defined. The led to a few fixes in the way we register MVE builtins as placeholders or not. Without this patch, we would just omit some versions of the inttrinsics when __ARM_MVE_PRESERVE_USER_NAMESPACE is true. In fact, like for the C/C++ placeholders, we need to always keep entries for all of them to ensure that we have a consistent numbering scheme. 2023-06-26 Christophe Lyon PR target/110268 gcc/ * config/arm/arm-builtins.cc (arm_init_mve_builtins): Handle LTO. (arm_builtin_decl): Hahndle MVE builtins. * config/arm/arm-mve-builtins.cc (builtin_decl): New function. (add_unique_function): Fix handling of __ARM_MVE_PRESERVE_USER_NAMESPACE. (add_overloaded_function): Likewise. * config/arm/arm-protos.h (builtin_decl): New declaration. gcc/testsuite/ * gcc.target/arm/pr110268-1.c: New test. * gcc.target/arm/pr110268-2.c: New test. --- gcc/config/arm/arm-builtins.cc | 11 +++++- gcc/config/arm/arm-mve-builtins.cc | 61 ++++++++++++++++--------------- gcc/config/arm/arm-protos.h | 1 + gcc/testsuite/gcc.target/arm/pr110268-1.c | 12 ++++++ gcc/testsuite/gcc.target/arm/pr110268-2.c | 23 ++++++++++++ 5 files changed, 78 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr110268-1.c create mode 100644 gcc/testsuite/gcc.target/arm/pr110268-2.c (limited to 'gcc') diff --git a/gcc/config/arm/arm-builtins.cc b/gcc/config/arm/arm-builtins.cc index 36365e4..fca7dca 100644 --- a/gcc/config/arm/arm-builtins.cc +++ b/gcc/config/arm/arm-builtins.cc @@ -1918,6 +1918,15 @@ arm_init_mve_builtins (void) arm_builtin_datum *d = &mve_builtin_data[i]; arm_init_builtin (fcode, d, "__builtin_mve"); } + + if (in_lto_p) + { + arm_mve::handle_arm_mve_types_h (); + /* Under LTO, we cannot know whether + __ARM_MVE_PRESERVE_USER_NAMESPACE was defined, so assume it + was not. */ + arm_mve::handle_arm_mve_h (false); + } } /* Set up all the NEON builtins, even builtins for instructions that are not @@ -2723,7 +2732,7 @@ arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) case ARM_BUILTIN_GENERAL: return arm_general_builtin_decl (subcode); case ARM_BUILTIN_MVE: - return error_mark_node; + return arm_mve::builtin_decl (subcode); default: gcc_unreachable (); } diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc index 7033e41..413d810 100644 --- a/gcc/config/arm/arm-mve-builtins.cc +++ b/gcc/config/arm/arm-mve-builtins.cc @@ -493,6 +493,16 @@ handle_arm_mve_h (bool preserve_user_namespace) preserve_user_namespace); } +/* Return the function decl with MVE function subcode CODE, or error_mark_node + if no such function exists. */ +tree +builtin_decl (unsigned int code) +{ + if (code >= vec_safe_length (registered_functions)) + return error_mark_node; + return (*registered_functions)[code]->decl; +} + /* Return true if CANDIDATE is equivalent to MODEL_TYPE for overloading purposes. */ static bool @@ -849,7 +859,6 @@ function_builder::add_function (const function_instance &instance, ? integer_zero_node : simulate_builtin_function_decl (input_location, name, fntype, code, NULL, attrs); - registered_function &rfn = *ggc_alloc (); rfn.instance = instance; rfn.decl = decl; @@ -889,15 +898,12 @@ function_builder::add_unique_function (const function_instance &instance, gcc_assert (!*rfn_slot); *rfn_slot = &rfn; - /* Also add the non-prefixed non-overloaded function, if the user namespace - does not need to be preserved. */ - if (!preserve_user_namespace) - { - char *noprefix_name = get_name (instance, false, false); - tree attrs = get_attributes (instance); - add_function (instance, noprefix_name, fntype, attrs, requires_float, - false, false); - } + /* Also add the non-prefixed non-overloaded function, as placeholder + if the user namespace does not need to be preserved. */ + char *noprefix_name = get_name (instance, false, false); + attrs = get_attributes (instance); + add_function (instance, noprefix_name, fntype, attrs, requires_float, + false, preserve_user_namespace); /* Also add the function under its overloaded alias, if we want a separate decl for each instance of an overloaded function. */ @@ -905,20 +911,17 @@ function_builder::add_unique_function (const function_instance &instance, if (strcmp (name, overload_name) != 0) { /* Attribute lists shouldn't be shared. */ - tree attrs = get_attributes (instance); + attrs = get_attributes (instance); bool placeholder_p = !(m_direct_overloads || force_direct_overloads); add_function (instance, overload_name, fntype, attrs, requires_float, false, placeholder_p); - /* Also add the non-prefixed overloaded function, if the user namespace - does not need to be preserved. */ - if (!preserve_user_namespace) - { - char *noprefix_overload_name = get_name (instance, false, true); - tree attrs = get_attributes (instance); - add_function (instance, noprefix_overload_name, fntype, attrs, - requires_float, false, placeholder_p); - } + /* Also add the non-prefixed overloaded function, as placeholder + if the user namespace does not need to be preserved. */ + char *noprefix_overload_name = get_name (instance, false, true); + attrs = get_attributes (instance); + add_function (instance, noprefix_overload_name, fntype, attrs, + requires_float, false, preserve_user_namespace || placeholder_p); } obstack_free (&m_string_obstack, name); @@ -948,15 +951,15 @@ function_builder::add_overloaded_function (const function_instance &instance, = add_function (instance, name, m_overload_type, NULL_TREE, requires_float, true, m_direct_overloads); m_overload_names.put (name, &rfn); - if (!preserve_user_namespace) - { - char *noprefix_name = get_name (instance, false, true); - registered_function &noprefix_rfn - = add_function (instance, noprefix_name, m_overload_type, - NULL_TREE, requires_float, true, - m_direct_overloads); - m_overload_names.put (noprefix_name, &noprefix_rfn); - } + + /* Also add the non-prefixed function, as placeholder if the + user namespace does not need to be preserved. */ + char *noprefix_name = get_name (instance, false, true); + registered_function &noprefix_rfn + = add_function (instance, noprefix_name, m_overload_type, + NULL_TREE, requires_float, true, + preserve_user_namespace || m_direct_overloads); + m_overload_names.put (noprefix_name, &noprefix_rfn); } } diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 7d73c66..6186921 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -232,6 +232,7 @@ const unsigned int ARM_BUILTIN_CLASS = (1 << ARM_BUILTIN_SHIFT) - 1; namespace arm_mve { void handle_arm_mve_types_h (); void handle_arm_mve_h (bool); + tree builtin_decl (unsigned); tree resolve_overloaded_builtin (location_t, unsigned int, vec *); bool check_builtin_call (location_t, vec, unsigned int, diff --git a/gcc/testsuite/gcc.target/arm/pr110268-1.c b/gcc/testsuite/gcc.target/arm/pr110268-1.c new file mode 100644 index 0000000..1243e4b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr110268-1.c @@ -0,0 +1,12 @@ +/* { dg-do link } */ +/* { dg-require-effective-target arm_arch_v8_1m_main_link } */ /* Make sure we have suitable multilibs to link successfully. */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O2 -flto" } */ + +#include + +int main(int argc, char* argv[]) +{ + return vaddvq(__arm_vdupq_n_s8 (argc)); +} diff --git a/gcc/testsuite/gcc.target/arm/pr110268-2.c b/gcc/testsuite/gcc.target/arm/pr110268-2.c new file mode 100644 index 0000000..823e708 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr110268-2.c @@ -0,0 +1,23 @@ +/* { dg-do link } */ +/* { dg-require-effective-target arm_arch_v8_1m_main_link } */ /* Make sure we have suitable multilibs to link successfully. */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O2 -flto" } */ + +/* Check MVE intrinsics with LTO with __ARM_MVE_PRESERVE_USER_NAMESPACE and a + user-overridden intrinsic. */ + +#define __ARM_MVE_PRESERVE_USER_NAMESPACE +#include + +int global_int; +int32_t vaddvq(int8x16_t x) +{ + return global_int + __arm_vgetq_lane_s8 (x, 0); +} + +int main(int argc, char* argv[]) +{ + global_int = argc; + return vaddvq(__arm_vdupq_n_s8 (argc)); +} -- cgit v1.1 From a3ad2301d2f4aab2deeb286fa5bd0282260bfd0a Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Mon, 10 Jul 2023 16:12:59 +0800 Subject: GCSE: Export 'insert_insn_end_basic_block' as global function Since VSETVL PASS in RISC-V port is using common part of 'insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)' and we will also this helper function in riscv.cc for the following patches. So extract the common part codes of 'insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)', the new function of the common part is also call 'insert_insn_end_basic_block (rtx_insn *pat, basic_block bb)' but with different arguments. And call 'insert_insn_end_basic_block (rtx_insn *pat, basic_block bb)' in 'insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)' and VSETVL PASS in RISC-V port. Remove redundant codes of VSETVL PASS in RISC-V port. gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (add_label_notes): Remove it. (insert_insn_end_basic_block): Ditto. (pass_vsetvl::commit_vsetvls): Adapt for new helper function. * gcse.cc (insert_insn_end_basic_block): Export as global function. * gcse.h (insert_insn_end_basic_block): Ditto. --- gcc/config/riscv/riscv-vsetvl.cc | 128 ++------------------------------------- gcc/gcse.cc | 29 ++++++--- gcc/gcse.h | 1 + 3 files changed, 25 insertions(+), 133 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index ab47901..586dc8e 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -98,6 +98,7 @@ along with GCC; see the file COPYING3. If not see #include "lcm.h" #include "predict.h" #include "profile-count.h" +#include "gcse.h" #include "riscv-vsetvl.h" using namespace rtl_ssa; @@ -763,127 +764,6 @@ insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn, return VSETVL_DISCARD_RESULT; } -/* If X contains any LABEL_REF's, add REG_LABEL_OPERAND notes for them - to INSN. If such notes are added to an insn which references a - CODE_LABEL, the LABEL_NUSES count is incremented. We have to add - that note, because the following loop optimization pass requires - them. */ - -/* ??? If there was a jump optimization pass after gcse and before loop, - then we would not need to do this here, because jump would add the - necessary REG_LABEL_OPERAND and REG_LABEL_TARGET notes. */ - -static void -add_label_notes (rtx x, rtx_insn *rinsn) -{ - enum rtx_code code = GET_CODE (x); - int i, j; - const char *fmt; - - if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x)) - { - /* This code used to ignore labels that referred to dispatch tables to - avoid flow generating (slightly) worse code. - - We no longer ignore such label references (see LABEL_REF handling in - mark_jump_label for additional information). */ - - /* There's no reason for current users to emit jump-insns with - such a LABEL_REF, so we don't have to handle REG_LABEL_TARGET - notes. */ - gcc_assert (!JUMP_P (rinsn)); - add_reg_note (rinsn, REG_LABEL_OPERAND, label_ref_label (x)); - - if (LABEL_P (label_ref_label (x))) - LABEL_NUSES (label_ref_label (x))++; - - return; - } - - for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--) - { - if (fmt[i] == 'e') - add_label_notes (XEXP (x, i), rinsn); - else if (fmt[i] == 'E') - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - add_label_notes (XVECEXP (x, i, j), rinsn); - } -} - -/* Add EXPR to the end of basic block BB. - - This is used by both the PRE and code hoisting. */ - -static void -insert_insn_end_basic_block (rtx_insn *rinsn, basic_block cfg_bb) -{ - rtx_insn *end_rinsn = BB_END (cfg_bb); - rtx_insn *new_insn; - rtx_insn *pat, *pat_end; - - pat = rinsn; - gcc_assert (pat && INSN_P (pat)); - - pat_end = pat; - while (NEXT_INSN (pat_end) != NULL_RTX) - pat_end = NEXT_INSN (pat_end); - - /* If the last end_rinsn is a jump, insert EXPR in front. Similarly we need - to take care of trapping instructions in presence of non-call exceptions. - */ - - if (JUMP_P (end_rinsn) - || (NONJUMP_INSN_P (end_rinsn) - && (!single_succ_p (cfg_bb) - || single_succ_edge (cfg_bb)->flags & EDGE_ABNORMAL))) - { - /* FIXME: What if something in jump uses value set in new end_rinsn? */ - new_insn = emit_insn_before_noloc (pat, end_rinsn, cfg_bb); - } - - /* Likewise if the last end_rinsn is a call, as will happen in the presence - of exception handling. */ - else if (CALL_P (end_rinsn) - && (!single_succ_p (cfg_bb) - || single_succ_edge (cfg_bb)->flags & EDGE_ABNORMAL)) - { - /* Keeping in mind targets with small register classes and parameters - in registers, we search backward and place the instructions before - the first parameter is loaded. Do this for everyone for consistency - and a presumption that we'll get better code elsewhere as well. */ - - /* Since different machines initialize their parameter registers - in different orders, assume nothing. Collect the set of all - parameter registers. */ - end_rinsn = find_first_parameter_load (end_rinsn, BB_HEAD (cfg_bb)); - - /* If we found all the parameter loads, then we want to insert - before the first parameter load. - - If we did not find all the parameter loads, then we might have - stopped on the head of the block, which could be a CODE_LABEL. - If we inserted before the CODE_LABEL, then we would be putting - the end_rinsn in the wrong basic block. In that case, put the - end_rinsn after the CODE_LABEL. Also, respect NOTE_INSN_BASIC_BLOCK. - */ - while (LABEL_P (end_rinsn) || NOTE_INSN_BASIC_BLOCK_P (end_rinsn)) - end_rinsn = NEXT_INSN (end_rinsn); - - new_insn = emit_insn_before_noloc (pat, end_rinsn, cfg_bb); - } - else - new_insn = emit_insn_after_noloc (pat, end_rinsn, cfg_bb); - - while (1) - { - if (INSN_P (pat)) - add_label_notes (PATTERN (pat), new_insn); - if (pat == pat_end) - break; - pat = NEXT_INSN (pat); - } -} - /* Get VL/VTYPE information for INSN. */ static vl_vtype_info get_vl_vtype_info (const insn_info *insn) @@ -4126,13 +4006,13 @@ pass_vsetvl::commit_vsetvls (void) emit_insn (new_pat); rtx_insn *rinsn = get_insns (); end_sequence (); - insert_insn_end_basic_block (rinsn, cfg_bb); + rtx_insn *new_insn = insert_insn_end_basic_block (rinsn, cfg_bb); if (dump_file) { fprintf (dump_file, "\nInsert vsetvl insn %d at the end of :\n", - INSN_UID (rinsn), cfg_bb->index); - print_rtl_single (dump_file, rinsn); + INSN_UID (new_insn), cfg_bb->index); + print_rtl_single (dump_file, new_insn); } } diff --git a/gcc/gcse.cc b/gcc/gcse.cc index 8413c9a..f689c0c 100644 --- a/gcc/gcse.cc +++ b/gcc/gcse.cc @@ -2013,20 +2013,16 @@ process_insert_insn (struct gcse_expr *expr) return prepare_copy_insn (reg, exp); } -/* Add EXPR to the end of basic block BB. - - This is used by both the PRE and code hoisting. */ +/* Return the INSN which is added at the end of the block BB with + same instruction pattern with PAT. */ -static void -insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb) +rtx_insn * +insert_insn_end_basic_block (rtx_insn *pat, basic_block bb) { rtx_insn *insn = BB_END (bb); rtx_insn *new_insn; - rtx reg = expr->reaching_reg; - int regno = REGNO (reg); - rtx_insn *pat, *pat_end; + rtx_insn *pat_end; - pat = process_insert_insn (expr); gcc_assert (pat && INSN_P (pat)); pat_end = pat; @@ -2086,6 +2082,21 @@ insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb) break; pat = NEXT_INSN (pat); } + return new_insn; +} + +/* Add EXPR to the end of basic block BB. + + This is used by both the PRE and code hoisting. */ + +static void +insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb) +{ + rtx reg = expr->reaching_reg; + int regno = REGNO (reg); + + rtx_insn *insn = process_insert_insn (expr); + rtx_insn *new_insn = insert_insn_end_basic_block (insn, bb); gcse_create_count++; diff --git a/gcc/gcse.h b/gcc/gcse.h index 5582b29..e68afdc 100644 --- a/gcc/gcse.h +++ b/gcc/gcse.h @@ -41,5 +41,6 @@ extern struct target_gcse *this_target_gcse; void gcse_cc_finalize (void); extern bool gcse_or_cprop_is_too_expensive (const char *); +extern rtx_insn *insert_insn_end_basic_block (rtx_insn *, basic_block); #endif -- cgit v1.1 From 1e2e5713a6dbd36ac48e8cf78f0eeb303d820afe Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Mon, 10 Jul 2023 21:57:36 +0800 Subject: doc: Add doc for RISC-V Operand Modifiers Document `z` and `i` operand modifiers, we have much more modifiers other than those two, but they are the only two implement on both GCC and LLVM, consider the compatibility I would like to document those two first, and then review other modifiers later to see if any other should expose and implement on RISC-V LLVM too. gcc/ChangeLog: * doc/extend.texi (RISC-V Operand Modifiers): New. --- gcc/doc/extend.texi | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index bfbc1d6..d88fd75 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -11533,6 +11533,16 @@ The list below describes the supported modifiers and their effects for LoongArch @item @code{z} @tab Print the operand in its unmodified form, followed by a comma. @end multitable +@anchor{riscvOperandmodifiers} +@subsubsection RISC-V Operand Modifiers + +The list below describes the supported modifiers and their effects for RISC-V. + +@multitable @columnfractions .10 .90 +@headitem Modifier @tab Description +@item @code{z} @tab Print ''@code{zero}'' instead of 0 if the operand is an immediate with a value of zero. +@item @code{i} @tab Print the character ''@code{i}'' if the operand is an immediate. +@end multitable @lowersections @include md.texi -- cgit v1.1 From 2c60368ab5706a870a1a3be190acc4d673672c30 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Mon, 10 Jul 2023 10:59:40 -0400 Subject: c++: redeclare_class_template and ttps [PR110523] Now that we cache level-lowered ttps we can end up processing the same ttp multiple times via (multiple calls to) redeclare_class_template, so we can't assume a ttp's DECL_CONTEXT is initially empty. PR c++/110523 gcc/cp/ChangeLog: * pt.cc (redeclare_class_template): Relax the ttp DECL_CONTEXT assert, and downgrade it to a checking assert. gcc/testsuite/ChangeLog: * g++.dg/template/ttp37.C: New test. --- gcc/cp/pt.cc | 3 ++- gcc/testsuite/g++.dg/template/ttp37.C | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/ttp37.C (limited to 'gcc') diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d7d774f..076f788 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -6388,7 +6388,8 @@ redeclare_class_template (tree type, tree parms, tree cons) DECL_CONTEXT of the template for which they are a parameter. */ if (TREE_CODE (parm) == TEMPLATE_DECL) { - gcc_assert (DECL_CONTEXT (parm) == NULL_TREE); + gcc_checking_assert (DECL_CONTEXT (parm) == NULL_TREE + || DECL_CONTEXT (parm) == tmpl); DECL_CONTEXT (parm) = tmpl; } } diff --git a/gcc/testsuite/g++.dg/template/ttp37.C b/gcc/testsuite/g++.dg/template/ttp37.C new file mode 100644 index 0000000..c5f4e99 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp37.C @@ -0,0 +1,15 @@ +// PR c++/110523 + +template class> +class basic_json; + +template +struct json_pointer { + template class> + friend class basic_json; +}; + +template struct json_pointer; +template struct json_pointer; +template struct json_pointer; +template struct json_pointer; -- cgit v1.1 From 2d7c95e31431a297060c94697af84f498abf97a2 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 10 Jul 2023 21:52:54 +0200 Subject: reorg: Change return type of predicate functions from int to bool Also change some internal variables and function arguments from int to bool. gcc/ChangeLog: * reorg.cc (stop_search_p): Change return type from int to bool and adjust function body accordingly. (resource_conflicts_p): Ditto. (insn_references_resource_p): Change return type from int to bool. (insn_sets_resource_p): Ditto. (redirect_with_delay_slots_safe_p): Ditto. (condition_dominates_p): Change return type from int to bool and adjust function body accordingly. (redirect_with_delay_list_safe_p): Ditto. (check_annul_list_true_false): Ditto. Change "annul_true_p" function argument to bool. (steal_delay_list_from_target): Change "pannul_p" function argument to bool pointer. Change "must_annul" and "used_annul" variables from int to bool. (steal_delay_list_from_fallthrough): Ditto. (own_thread_p): Change return type from int to bool and adjust function body accordingly. Change "allow_fallthrough" function argument to bool. (reorg_redirect_jump): Change return type from int to bool. (fill_simple_delay_slots): Change "non_jumps_p" function argument from int to bool. Change "maybe_never" varible to bool. (fill_slots_from_thread): Change "likely", "thread_if_true" and "own_thread" function arguments to bool. Change "lose" and "must_annul" variables to bool. (delete_from_delay_slot): Change "had_barrier" variable to bool. (try_merge_delay_insns): Change "annul_p" variable to bool. (fill_eager_delay_slots): Change "own_target" and "own_fallthrouhg" variables to bool. (rest_of_handle_delay_slots): Change return type from int to void and adjust function body accordingly. --- gcc/reorg.cc | 233 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 116 deletions(-) (limited to 'gcc') diff --git a/gcc/reorg.cc b/gcc/reorg.cc index ed32c91..8129046 100644 --- a/gcc/reorg.cc +++ b/gcc/reorg.cc @@ -174,10 +174,10 @@ static int *uid_to_ruid; /* Highest valid index in `uid_to_ruid'. */ static int max_uid; -static int stop_search_p (rtx_insn *, int); -static int resource_conflicts_p (struct resources *, struct resources *); -static int insn_references_resource_p (rtx, struct resources *, bool); -static int insn_sets_resource_p (rtx, struct resources *, bool); +static bool stop_search_p (rtx_insn *, bool); +static bool resource_conflicts_p (struct resources *, struct resources *); +static bool insn_references_resource_p (rtx, struct resources *, bool); +static bool insn_sets_resource_p (rtx, struct resources *, bool); static rtx_code_label *find_end_label (rtx); static rtx_insn *emit_delay_sequence (rtx_insn *, const vec &, int); @@ -188,35 +188,35 @@ static void note_delay_statistics (int, int); static int get_jump_flags (const rtx_insn *, rtx); static int mostly_true_jump (rtx); static rtx get_branch_condition (const rtx_insn *, rtx); -static int condition_dominates_p (rtx, const rtx_insn *); -static int redirect_with_delay_slots_safe_p (rtx_insn *, rtx, rtx); -static int redirect_with_delay_list_safe_p (rtx_insn *, rtx, - const vec &); -static int check_annul_list_true_false (int, const vec &); +static bool condition_dominates_p (rtx, const rtx_insn *); +static bool redirect_with_delay_slots_safe_p (rtx_insn *, rtx, rtx); +static bool redirect_with_delay_list_safe_p (rtx_insn *, rtx, + const vec &); +static bool check_annul_list_true_false (bool, const vec &); static void steal_delay_list_from_target (rtx_insn *, rtx, rtx_sequence *, vec *, struct resources *, struct resources *, struct resources *, - int, int *, int *, + int, int *, bool *, rtx *); static void steal_delay_list_from_fallthrough (rtx_insn *, rtx, rtx_sequence *, vec *, struct resources *, struct resources *, struct resources *, - int, int *, int *); + int, int *, bool *); static void try_merge_delay_insns (rtx_insn *, rtx_insn *); static rtx_insn *redundant_insn (rtx, rtx_insn *, const vec &); -static int own_thread_p (rtx, rtx, int); +static bool own_thread_p (rtx, rtx, bool); static void update_block (rtx_insn *, rtx_insn *); -static int reorg_redirect_jump (rtx_jump_insn *, rtx); +static bool reorg_redirect_jump (rtx_jump_insn *, rtx); static void update_reg_dead_notes (rtx_insn *, rtx_insn *); static void fix_reg_dead_note (rtx_insn *, rtx); static void update_reg_unused_notes (rtx_insn *, rtx); -static void fill_simple_delay_slots (int); +static void fill_simple_delay_slots (bool); static void fill_slots_from_thread (rtx_jump_insn *, rtx, rtx, rtx, - int, int, int, int, + bool, bool, bool, int, int *, vec *); static void fill_eager_delay_slots (void); static void relax_delay_slots (rtx_insn *); @@ -247,31 +247,31 @@ simplejump_or_return_p (rtx insn) slots. LABELS_P indicates that labels should terminate the search. In all cases, jumps terminate the search. */ -static int -stop_search_p (rtx_insn *insn, int labels_p) +static bool +stop_search_p (rtx_insn *insn, bool labels_p) { if (insn == 0) - return 1; + return true; /* If the insn can throw an exception that is caught within the function, it may effectively perform a jump from the viewpoint of the function. Therefore act like for a jump. */ if (can_throw_internal (insn)) - return 1; + return true; switch (GET_CODE (insn)) { case NOTE: case CALL_INSN: case DEBUG_INSN: - return 0; + return false; case CODE_LABEL: return labels_p; case JUMP_INSN: case BARRIER: - return 1; + return true; case INSN: /* OK unless it contains a delay slot or is an `asm' insn of some type. @@ -288,12 +288,12 @@ stop_search_p (rtx_insn *insn, int labels_p) /* Return TRUE if any resources are marked in both RES1 and RES2 or if either resource set contains a volatile memory reference. Otherwise, return FALSE. */ -static int +static bool resource_conflicts_p (struct resources *res1, struct resources *res2) { if ((res1->cc && res2->cc) || (res1->memory && res2->memory) || res1->volatil || res2->volatil) - return 1; + return true; return hard_reg_set_intersect_p (res1->regs, res2->regs); } @@ -307,7 +307,7 @@ resource_conflicts_p (struct resources *res1, struct resources *res2) ourselves, and this is the way it used to work, but it means duplicating a large block of complex code. */ -static int +static bool insn_references_resource_p (rtx insn, struct resources *res, bool include_delayed_effects) { @@ -322,7 +322,7 @@ insn_references_resource_p (rtx insn, struct resources *res, INCLUDE_DELAYED_EFFECTS is set if the actions of that routine should be included. */ -static int +static bool insn_sets_resource_p (rtx insn, struct resources *res, bool include_delayed_effects) { @@ -562,8 +562,8 @@ delete_from_delay_slot (rtx_insn *insn) { rtx_insn *trial, *seq_insn, *prev; rtx_sequence *seq; + bool had_barrier = false; int i; - int had_barrier = 0; /* We first must find the insn containing the SEQUENCE with INSN in its delay slot. Do this by finding an insn, TRIAL, where @@ -578,7 +578,7 @@ delete_from_delay_slot (rtx_insn *insn) seq = as_a (PATTERN (seq_insn)); if (NEXT_INSN (seq_insn) && BARRIER_P (NEXT_INSN (seq_insn))) - had_barrier = 1; + had_barrier = true; /* Create a delay list consisting of all the insns other than the one we are deleting (unless we were the only one). */ @@ -856,10 +856,10 @@ get_branch_condition (const rtx_insn *insn, rtx target) return 0; } -/* Return nonzero if CONDITION is more strict than the condition of +/* Return true if CONDITION is more strict than the condition of INSN, i.e., if INSN will always branch if CONDITION is true. */ -static int +static bool condition_dominates_p (rtx condition, const rtx_insn *insn) { rtx other_condition = get_branch_condition (insn, JUMP_LABEL (insn)); @@ -868,24 +868,24 @@ condition_dominates_p (rtx condition, const rtx_insn *insn) if (rtx_equal_p (condition, other_condition) || other_condition == const_true_rtx) - return 1; + return true; else if (condition == const_true_rtx || other_condition == 0) - return 0; + return false; other_code = GET_CODE (other_condition); if (GET_RTX_LENGTH (code) != 2 || GET_RTX_LENGTH (other_code) != 2 || ! rtx_equal_p (XEXP (condition, 0), XEXP (other_condition, 0)) || ! rtx_equal_p (XEXP (condition, 1), XEXP (other_condition, 1))) - return 0; + return false; return comparison_dominates_p (code, other_code); } -/* Return nonzero if redirecting JUMP to NEWLABEL does not invalidate +/* Return true if redirecting JUMP to NEWLABEL does not invalidate any insns already in the delay slot of JUMP. */ -static int +static bool redirect_with_delay_slots_safe_p (rtx_insn *jump, rtx newlabel, rtx seq) { int flags, i; @@ -914,16 +914,16 @@ redirect_with_delay_slots_safe_p (rtx_insn *jump, rtx newlabel, rtx seq) return (i == pat->len ()); } -/* Return nonzero if redirecting JUMP to NEWLABEL does not invalidate +/* Return true if redirecting JUMP to NEWLABEL does not invalidate any insns we wish to place in the delay slot of JUMP. */ -static int +static bool redirect_with_delay_list_safe_p (rtx_insn *jump, rtx newlabel, const vec &delay_list) { /* Make sure all the insns in DELAY_LIST would still be valid after threading the jump. If they are still - valid, then return nonzero. */ + valid, then return true. */ int flags = get_jump_flags (jump, newlabel); unsigned int delay_insns = delay_list.length (); @@ -948,10 +948,10 @@ redirect_with_delay_list_safe_p (rtx_insn *jump, rtx newlabel, /* DELAY_LIST is a list of insns that have already been placed into delay slots. See if all of them have the same annulling status as ANNUL_TRUE_P. - If not, return 0; otherwise return 1. */ + If not, return false; otherwise return true. */ -static int -check_annul_list_true_false (int annul_true_p, +static bool +check_annul_list_true_false (bool annul_true_p, const vec &delay_list) { rtx_insn *trial; @@ -959,9 +959,9 @@ check_annul_list_true_false (int annul_true_p, FOR_EACH_VEC_ELT (delay_list, i, trial) if ((annul_true_p && INSN_FROM_TARGET_P (trial)) || (!annul_true_p && !INSN_FROM_TARGET_P (trial))) - return 0; + return false; - return 1; + return true; } /* INSN branches to an insn whose pattern SEQ is a SEQUENCE. Given that @@ -979,7 +979,7 @@ check_annul_list_true_false (int annul_true_p, PANNUL_P points to a nonzero value if we already know that we need to annul INSN. If this routine determines that annulling is needed, - it may set that value nonzero. + it may set that value to true. PNEW_THREAD points to a location that is to receive the place at which execution should continue. */ @@ -991,13 +991,13 @@ steal_delay_list_from_target (rtx_insn *insn, rtx condition, rtx_sequence *seq, struct resources *needed, struct resources *other_needed, int slots_to_fill, int *pslots_filled, - int *pannul_p, rtx *pnew_thread) + bool *pannul_p, rtx *pnew_thread) { int slots_remaining = slots_to_fill - *pslots_filled; int total_slots_filled = *pslots_filled; auto_vec new_delay_list; - int must_annul = *pannul_p; - int used_annul = 0; + bool must_annul = *pannul_p; + bool used_annul = false; int i; struct resources cc_set; rtx_insn **redundant; @@ -1070,10 +1070,10 @@ steal_delay_list_from_target (rtx_insn *insn, rtx condition, rtx_sequence *seq, && ! may_trap_or_fault_p (PATTERN (trial))))) ? eligible_for_delay (insn, total_slots_filled, trial, flags) : (must_annul || (delay_list->is_empty () && new_delay_list.is_empty ())) - && (must_annul = 1, - check_annul_list_true_false (0, *delay_list) - && check_annul_list_true_false (0, new_delay_list) - && eligible_for_annul_false (insn, total_slots_filled, + && (must_annul = true, + check_annul_list_true_false (false, *delay_list) + && check_annul_list_true_false (false, new_delay_list) + && eligible_for_annul_false (insn, total_slots_filled, trial, flags))) { if (must_annul) @@ -1082,7 +1082,7 @@ steal_delay_list_from_target (rtx_insn *insn, rtx condition, rtx_sequence *seq, slots, it messes up the dwarf info. */ if (RTX_FRAME_RELATED_P (trial)) return; - used_annul = 1; + used_annul = true; } rtx_insn *temp = copy_delay_slot_insn (trial); INSN_FROM_TARGET_P (temp) = 1; @@ -1112,7 +1112,7 @@ steal_delay_list_from_target (rtx_insn *insn, rtx condition, rtx_sequence *seq, number of slots filled. */ *pslots_filled = total_slots_filled; if (used_annul) - *pannul_p = 1; + *pannul_p = true; rtx_insn *temp; FOR_EACH_VEC_ELT (new_delay_list, i, temp) @@ -1132,12 +1132,12 @@ steal_delay_list_from_fallthrough (rtx_insn *insn, rtx condition, struct resources *needed, struct resources *other_needed, int slots_to_fill, int *pslots_filled, - int *pannul_p) + bool *pannul_p) { int i; int flags; - int must_annul = *pannul_p; - int used_annul = 0; + bool must_annul = *pannul_p; + bool used_annul = false; flags = get_jump_flags (insn, JUMP_LABEL (insn)); @@ -1171,12 +1171,12 @@ steal_delay_list_from_fallthrough (rtx_insn *insn, rtx condition, || (! insn_sets_resource_p (trial, other_needed, false) && ! may_trap_or_fault_p (PATTERN (trial))))) ? eligible_for_delay (insn, *pslots_filled, trial, flags) - : (must_annul || delay_list->is_empty ()) && (must_annul = 1, - check_annul_list_true_false (1, *delay_list) + : (must_annul || delay_list->is_empty ()) && (must_annul = true, + check_annul_list_true_false (true, *delay_list) && eligible_for_annul_true (insn, *pslots_filled, trial, flags))) { if (must_annul) - used_annul = 1; + used_annul = true; delete_from_delay_slot (trial); add_to_delay_list (trial, delay_list); @@ -1188,7 +1188,7 @@ steal_delay_list_from_fallthrough (rtx_insn *insn, rtx condition, } if (used_annul) - *pannul_p = 1; + *pannul_p = true; } /* Try merging insns starting at THREAD which match exactly the insns in @@ -1205,7 +1205,7 @@ try_merge_delay_insns (rtx_insn *insn, rtx_insn *thread) { rtx_insn *trial, *next_trial; rtx_insn *delay_insn = as_a (XVECEXP (PATTERN (insn), 0, 0)); - int annul_p = JUMP_P (delay_insn) && INSN_ANNULLED_BRANCH_P (delay_insn); + bool annul_p = JUMP_P (delay_insn) && INSN_ANNULLED_BRANCH_P (delay_insn); int slot_number = 1; int num_slots = XVECLEN (PATTERN (insn), 0); rtx next_to_match = XVECEXP (PATTERN (insn), 0, slot_number); @@ -1230,7 +1230,7 @@ try_merge_delay_insns (rtx_insn *insn, rtx_insn *thread) mark_referenced_resources (XVECEXP (PATTERN (insn), 0, i), &needed, true); - for (trial = thread; !stop_search_p (trial, 1); trial = next_trial) + for (trial = thread; !stop_search_p (trial, true); trial = next_trial) { rtx pat = PATTERN (trial); rtx oldtrial = trial; @@ -1599,23 +1599,22 @@ redundant_insn (rtx insn, rtx_insn *target, const vec &delay_list) return 0; } -/* Return 1 if THREAD can only be executed in one way. If LABEL is nonzero, +/* Return true if THREAD can only be executed in one way. If LABEL is nonzero, it is the target of the branch insn being scanned. If ALLOW_FALLTHROUGH - is nonzero, we are allowed to fall into this thread; otherwise, we are - not. + is true, we are allowed to fall into this thread; otherwise, we are not. If LABEL is used more than one or we pass a label other than LABEL before finding an active insn, we do not own this thread. */ -static int -own_thread_p (rtx thread, rtx label, int allow_fallthrough) +static bool +own_thread_p (rtx thread, rtx label, bool allow_fallthrough) { rtx_insn *active_insn; rtx_insn *insn; /* We don't own the function end. */ if (thread == 0 || ANY_RETURN_P (thread)) - return 0; + return false; /* We have a non-NULL insn. */ rtx_insn *thread_insn = as_a (thread); @@ -1626,10 +1625,10 @@ own_thread_p (rtx thread, rtx label, int allow_fallthrough) for (insn = thread_insn; insn != active_insn; insn = NEXT_INSN (insn)) if (LABEL_P (insn) && (insn != label || LABEL_NUSES (insn) != 1)) - return 0; + return false; if (allow_fallthrough) - return 1; + return true; /* Ensure that we reach a BARRIER before any insn or label. */ for (insn = prev_nonnote_insn (thread_insn); @@ -1640,9 +1639,9 @@ own_thread_p (rtx thread, rtx label, int allow_fallthrough) || (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) != USE && GET_CODE (PATTERN (insn)) != CLOBBER)) - return 0; + return false; - return 1; + return true; } /* Called when INSN is being moved from a location near the target of a jump. @@ -1666,7 +1665,7 @@ update_block (rtx_insn *insn, rtx_insn *where) /* Similar to REDIRECT_JUMP except that we update the BB_TICKS entry for the basic block containing the jump. */ -static int +static bool reorg_redirect_jump (rtx_jump_insn *jump, rtx nlabel) { incr_ticks_for_insn (jump); @@ -1801,7 +1800,7 @@ get_label_before (rtx_insn *insn, rtx sibling) /* Scan a function looking for insns that need a delay slot and find insns to put into the delay slot. - NON_JUMPS_P is nonzero if we are to only try to fill non-jump insns (such + NON_JUMPS_P is true if we are to only try to fill non-jump insns (such as calls). We do these first since we don't want jump insns (that are easier to fill) to get the only insns that could be used for non-jump insns. When it is zero, only try to fill JUMP_INSNs. @@ -1813,7 +1812,7 @@ get_label_before (rtx_insn *insn, rtx sibling) through FINAL_SEQUENCE. */ static void -fill_simple_delay_slots (int non_jumps_p) +fill_simple_delay_slots (bool non_jumps_p) { rtx_insn *insn, *trial, *next_trial; rtx pat; @@ -1953,7 +1952,7 @@ fill_simple_delay_slots (int non_jumps_p) } mark_referenced_resources (insn, &needed, false); - for (trial = prev_nonnote_insn (insn); ! stop_search_p (trial, 1); + for (trial = prev_nonnote_insn (insn); ! stop_search_p (trial, true); trial = next_trial) { next_trial = prev_nonnote_insn (trial); @@ -2066,7 +2065,7 @@ fill_simple_delay_slots (int non_jumps_p) && ! can_throw_internal (insn) && !JUMP_P (insn)) { - int maybe_never = 0; + bool maybe_never = false; rtx pat, trial_delay; CLEAR_RESOURCE (&needed); @@ -2075,9 +2074,9 @@ fill_simple_delay_slots (int non_jumps_p) mark_referenced_resources (insn, &needed, true); if (CALL_P (insn)) - maybe_never = 1; + maybe_never = true; - for (trial = next_nonnote_insn (insn); !stop_search_p (trial, 1); + for (trial = next_nonnote_insn (insn); !stop_search_p (trial, true); trial = next_trial) { next_trial = next_nonnote_insn (trial); @@ -2133,7 +2132,7 @@ fill_simple_delay_slots (int non_jumps_p) /* If this is a call, we might not get here. */ if (CALL_P (trial_delay)) - maybe_never = 1; + maybe_never = true; } /* If there are slots left to fill and our search was stopped by an @@ -2186,7 +2185,7 @@ fill_simple_delay_slots (int non_jumps_p) fill_slots_from_thread (jump_insn, const_true_rtx, next_active_insn (JUMP_LABEL_AS_INSN (insn)), NULL, 1, 1, own_thread_p (JUMP_LABEL (insn), - JUMP_LABEL (insn), 0), + JUMP_LABEL (insn), false), slots_to_fill, &slots_filled, &delay_list); if (!delay_list.is_empty ()) @@ -2272,7 +2271,7 @@ follow_jumps (rtx label, rtx_insn *jump, bool *crossing) OPPOSITE_THREAD is the thread in the opposite direction. It is used to see if any potential delay slot insns set things needed there. - LIKELY is nonzero if it is extremely likely that the branch will be + LIKELY is true if it is extremely likely that the branch will be taken and THREAD_IF_TRUE is set. This is used for the branch at the end of a loop back up to the top. @@ -2285,15 +2284,15 @@ follow_jumps (rtx label, rtx_insn *jump, bool *crossing) static void fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, - rtx thread_or_return, rtx opposite_thread, int likely, - int thread_if_true, int own_thread, int slots_to_fill, + rtx thread_or_return, rtx opposite_thread, bool likely, + bool thread_if_true, bool own_thread, int slots_to_fill, int *pslots_filled, vec *delay_list) { rtx new_thread; struct resources opposite_needed, set, needed; rtx_insn *trial; - int lose = 0; - int must_annul = 0; + bool lose = false; + bool must_annul = false; int flags; /* Validate our arguments. */ @@ -2449,14 +2448,14 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, thread = trial; pat = PATTERN (trial); if ((must_annul || delay_list->is_empty ()) && (thread_if_true - ? check_annul_list_true_false (0, *delay_list) + ? check_annul_list_true_false (false, *delay_list) && eligible_for_annul_false (insn, *pslots_filled, trial, flags) - : check_annul_list_true_false (1, *delay_list) + : check_annul_list_true_false (true, *delay_list) && eligible_for_annul_true (insn, *pslots_filled, trial, flags))) { rtx_insn *temp; - must_annul = 1; + must_annul = true; winner: /* If we own this thread, delete the insn. If this is the @@ -2554,7 +2553,7 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, } /* This insn can't go into a delay slot. */ - lose = 1; + lose = true; mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL); mark_referenced_resources (trial, &needed, true); if (filter_flags) @@ -2626,7 +2625,7 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition, /* If we owned the thread and are told that it branched elsewhere, make sure we own the thread at the new location. */ if (own_thread && trial != new_thread) - own_thread = own_thread_p (new_thread, new_thread, 0); + own_thread = own_thread_p (new_thread, new_thread, false); } else if (! thread_if_true) steal_delay_list_from_fallthrough (insn, condition, sequence, @@ -2778,8 +2777,8 @@ fill_eager_delay_slots (void) rtx_insn *fallthrough_insn; auto_vec delay_list; rtx_jump_insn *jump_insn; - int own_target; - int own_fallthrough; + bool own_target; + bool own_fallthrough; int prediction, slots_to_fill, slots_filled; insn = unfilled_slots_base[i]; @@ -2816,18 +2815,19 @@ fill_eager_delay_slots (void) to do a lot of this for unconditional branches. */ insn_at_target = first_active_target_insn (target_label); - own_target = own_thread_p (target_label, target_label, 0); + own_target = own_thread_p (target_label, target_label, false); if (condition == const_true_rtx) { - own_fallthrough = 0; + own_fallthrough = false; fallthrough_insn = 0; prediction = 2; } else { fallthrough_insn = next_active_insn (jump_insn); - own_fallthrough = own_thread_p (NEXT_INSN (jump_insn), NULL_RTX, 1); + own_fallthrough = own_thread_p (NEXT_INSN (jump_insn), + NULL_RTX, true); prediction = mostly_true_jump (jump_insn); } @@ -2838,9 +2838,9 @@ fill_eager_delay_slots (void) if (prediction > 0) { fill_slots_from_thread (jump_insn, condition, insn_at_target, - fallthrough_insn, prediction == 2, 1, - own_target, - slots_to_fill, &slots_filled, &delay_list); + fallthrough_insn, prediction == 2, true, + own_target, slots_to_fill, + &slots_filled, &delay_list); if (delay_list.is_empty () && own_fallthrough) { @@ -2852,22 +2852,24 @@ fill_eager_delay_slots (void) insn_at_target = first_active_target_insn (target_label); fill_slots_from_thread (jump_insn, condition, fallthrough_insn, - insn_at_target, 0, 0, own_fallthrough, - slots_to_fill, &slots_filled, - &delay_list); + insn_at_target, false, false, + own_fallthrough, slots_to_fill, + &slots_filled, &delay_list); } } else { if (own_fallthrough) fill_slots_from_thread (jump_insn, condition, fallthrough_insn, - insn_at_target, 0, 0, own_fallthrough, - slots_to_fill, &slots_filled, &delay_list); + insn_at_target, false, false, + own_fallthrough, slots_to_fill, + &slots_filled, &delay_list); if (delay_list.is_empty ()) fill_slots_from_thread (jump_insn, condition, insn_at_target, - next_active_insn (insn), 0, 1, own_target, - slots_to_fill, &slots_filled, &delay_list); + next_active_insn (insn), false, true, + own_target, slots_to_fill, + &slots_filled, &delay_list); } if (!delay_list.is_empty ()) @@ -3454,10 +3456,10 @@ relax_delay_slots (rtx_insn *first) /* If we own the thread opposite the way this insn branches, see if we can merge its delay slots with following insns. */ if (INSN_FROM_TARGET_P (pat->insn (1)) - && own_thread_p (NEXT_INSN (insn), 0, 1)) + && own_thread_p (NEXT_INSN (insn), 0, true)) try_merge_delay_insns (insn, next); else if (! INSN_FROM_TARGET_P (pat->insn (1)) - && own_thread_p (target_label, target_label, 0)) + && own_thread_p (target_label, target_label, false)) try_merge_delay_insns (insn, next_active_insn (as_a (target_label))); @@ -3613,8 +3615,8 @@ make_return_insns (rtx_insn *first) && --LABEL_NUSES (real_simple_return_label) == 0) delete_related_insns (real_simple_return_label); - fill_simple_delay_slots (1); - fill_simple_delay_slots (0); + fill_simple_delay_slots (true); + fill_simple_delay_slots (false); } /* Try to find insns to place in delay slots. */ @@ -3623,8 +3625,8 @@ static void dbr_schedule (rtx_insn *first) { rtx_insn *insn, *next, *epilogue_insn = 0; - int i; bool need_return_insns; + int i; /* If the current function has no insns other than the prologue and epilogue, then do not try to fill any delay slots. */ @@ -3693,8 +3695,8 @@ dbr_schedule (rtx_insn *first) reorg_pass_number < MAX_REORG_PASSES; reorg_pass_number++) { - fill_simple_delay_slots (1); - fill_simple_delay_slots (0); + fill_simple_delay_slots (true); + fill_simple_delay_slots (false); if (!targetm.no_speculation_in_delay_slots_p ()) fill_eager_delay_slots (); relax_delay_slots (first); @@ -3834,13 +3836,11 @@ dbr_schedule (rtx_insn *first) } /* Run delay slot optimization. */ -static unsigned int +static void rest_of_handle_delay_slots (void) { if (DELAY_SLOTS) dbr_schedule (get_insns ()); - - return 0; } namespace { @@ -3869,7 +3869,8 @@ public: bool gate (function *) final override; unsigned int execute (function *) final override { - return rest_of_handle_delay_slots (); + rest_of_handle_delay_slots (); + return 0; } }; // class pass_delay_slots -- cgit v1.1 From e9251fea2debebfebe1f762a4a8d5b3b1d4c75ef Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 10 Jul 2023 17:16:17 +0200 Subject: d: Merge upstream dmd, druntime a88e1335f7, phobos 1921d29df. D front-end changes: - Import dmd v2.104.1. - Deprecation phase ended for access to private method when overloaded with public method. D runtime changes: - Import druntime v2.104.1. - Linux input header translations were added to druntime. - Integration with the Valgrind `memcheck' tool has been added to the garbage collector. Phobos changes: - Import phobos v2.104.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd a88e1335f7. * dmd/VERSION: Bump version to v2.104.1. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime a88e1335f7. * src/MERGE: Merge upstream phobos 1921d29df. * config.h.in: Regenerate. * configure: Regenerate. * configure.ac (libphobos-checking): Add valgrind flag. (DRUNTIME_LIBRARIES_VALGRIND): Call. * libdruntime/Makefile.am (DRUNTIME_CSOURCES): Add etc/valgrind/valgrind_.c. (DRUNTIME_DSOURCES): Add etc/valgrind/valgrind.d. (DRUNTIME_DSOURCES_LINUX): Add core/sys/linux/input.d, core/sys/linux/input_event_codes.d, core/sys/linux/uinput.d. * libdruntime/Makefile.in: Regenerate. * m4/druntime/libraries.m4 (DRUNTIME_LIBRARIES_VALGRIND): Define. --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/README.md | 1 - gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/access.d | 4 - gcc/d/dmd/attrib.d | 3 +- gcc/d/dmd/canthrow.d | 4 +- gcc/d/dmd/cparse.d | 2 +- gcc/d/dmd/dcast.d | 1 + gcc/d/dmd/declaration.d | 2 +- gcc/d/dmd/dinterpret.d | 28 +++--- gcc/d/dmd/dmangle.d | 2 +- gcc/d/dmd/dmodule.d | 19 +++- gcc/d/dmd/dsymbolsem.d | 51 ++++++++-- gcc/d/dmd/dtemplate.d | 64 ++++++------- gcc/d/dmd/dtoh.d | 2 +- gcc/d/dmd/escape.d | 36 ++----- gcc/d/dmd/expression.d | 25 +++-- gcc/d/dmd/expressionsem.d | 103 +++++++++----------- gcc/d/dmd/hdrgen.d | 8 +- gcc/d/dmd/initsem.d | 14 ++- gcc/d/dmd/inline.d | 4 +- gcc/d/dmd/lexer.d | 2 +- gcc/d/dmd/mtype.d | 19 ++-- gcc/d/dmd/opover.d | 8 +- gcc/d/dmd/optimize.d | 2 +- gcc/d/dmd/parse.d | 21 +++- gcc/d/dmd/root/array.d | 18 ++++ gcc/d/dmd/semantic2.d | 7 ++ gcc/d/dmd/semantic3.d | 4 +- gcc/d/dmd/statementsem.d | 30 ++++-- gcc/d/dmd/traits.d | 6 +- gcc/d/dmd/transitivevisitor.d | 8 +- gcc/d/dmd/typesem.d | 12 +-- gcc/testsuite/gdc.test/compilable/b20938.d | 3 +- gcc/testsuite/gdc.test/compilable/commontype.d | 12 +-- .../gdc.test/compilable/imports/pkg20008/package.d | 9 ++ .../gdc.test/compilable/imports/pkg20008/submod.d | 2 + .../compilable/imports/pkg20008/subpkg/package.d | 7 ++ .../compilable/imports/pkg20008/subpkg/subsubmod.d | 9 ++ .../gdc.test/compilable/imports/test9692b.d | 2 +- gcc/testsuite/gdc.test/compilable/issue24018.d | 10 ++ gcc/testsuite/gdc.test/compilable/stc_traits.d | 106 ++++++++++----------- gcc/testsuite/gdc.test/compilable/test13668.d | 2 +- gcc/testsuite/gdc.test/compilable/test16635.d | 2 +- gcc/testsuite/gdc.test/compilable/test17143.d | 2 +- gcc/testsuite/gdc.test/compilable/test17373.d | 4 +- gcc/testsuite/gdc.test/compilable/test17545.d | 2 +- gcc/testsuite/gdc.test/compilable/test19728.d | 14 +-- gcc/testsuite/gdc.test/compilable/test20008.d | 6 ++ gcc/testsuite/gdc.test/compilable/test21282.d | 2 +- gcc/testsuite/gdc.test/compilable/test21330.d | 4 +- gcc/testsuite/gdc.test/compilable/test23965.d | 11 +++ gcc/testsuite/gdc.test/compilable/test23978.d | 30 ++++++ gcc/testsuite/gdc.test/compilable/test23979.d | 17 ++++ gcc/testsuite/gdc.test/compilable/test23986.d | 11 +++ gcc/testsuite/gdc.test/compilable/test24013.d | 43 +++++++++ gcc/testsuite/gdc.test/compilable/test24017.d | 11 +++ gcc/testsuite/gdc.test/compilable/test9692.d | 4 +- gcc/testsuite/gdc.test/compilable/testInference.d | 6 +- .../gdc.test/fail_compilation/callconst.d | 16 ++++ .../gdc.test/fail_compilation/casttuple.d | 6 +- .../gdc.test/fail_compilation/cppmangle.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/dassert.d | 2 +- .../gdc.test/fail_compilation/diag13884.d | 2 +- .../gdc.test/fail_compilation/diag14876.d | 2 +- .../gdc.test/fail_compilation/dtor_attributes.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/e15876_1.d | 13 +-- gcc/testsuite/gdc.test/fail_compilation/e15876_2.d | 9 +- gcc/testsuite/gdc.test/fail_compilation/e15876_3.d | 27 +++--- gcc/testsuite/gdc.test/fail_compilation/e15876_4.d | 23 ++--- gcc/testsuite/gdc.test/fail_compilation/e15876_5.d | 11 ++- .../gdc.test/fail_compilation/enum_init.d | 2 + .../gdc.test/fail_compilation/fail12436.d | 2 +- .../gdc.test/fail_compilation/fail15755.d | 2 +- .../gdc.test/fail_compilation/fail16772.d | 3 +- .../gdc.test/fail_compilation/fail19209.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail196.d | 38 ++++---- .../gdc.test/fail_compilation/fail21206.d | 3 +- .../gdc.test/fail_compilation/fail21275.d | 5 +- gcc/testsuite/gdc.test/fail_compilation/fail222.d | 4 +- .../gdc.test/fail_compilation/fail22729.d | 39 ++++++++ .../gdc.test/fail_compilation/fail23745.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail315.d | 15 +-- .../gdc.test/fail_compilation/funcpostattr.d | 21 ++++ gcc/testsuite/gdc.test/fail_compilation/ice11965.d | 9 +- gcc/testsuite/gdc.test/fail_compilation/ice11982.d | 17 ++-- gcc/testsuite/gdc.test/fail_compilation/ice12574.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice14424.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/ice15855.d | 21 ++-- .../fail_compilation/imports/issue23947a.d | 8 ++ .../gdc.test/fail_compilation/issue20422.d | 9 +- .../gdc.test/fail_compilation/issue23947.d | 10 ++ gcc/testsuite/gdc.test/fail_compilation/lexer4.d | 2 +- .../fail_compilation/misc_parser_err_cov1.d | 3 +- .../gdc.test/fail_compilation/missingbrace.d | 10 ++ gcc/testsuite/gdc.test/fail_compilation/retscope.d | 2 +- .../gdc.test/fail_compilation/test20245.d | 2 +- .../gdc.test/fail_compilation/test21025.d | 25 +++++ .../gdc.test/fail_compilation/test23968.d | 23 +++++ .../gdc.test/fail_compilation/test23982.d | 36 +++++++ .../gdc.test/fail_compilation/typeerrors.d | 2 +- .../gdc.test/fail_compilation/unmatchedbrace.d | 10 ++ gcc/testsuite/gdc.test/runnable/functype.d | 2 +- gcc/testsuite/gdc.test/runnable/interface2.d | 4 +- gcc/testsuite/gdc.test/runnable/link10425.d | 2 +- gcc/testsuite/gdc.test/runnable/sdtor.d | 36 +++++++ gcc/testsuite/gdc.test/runnable/template9.d | 3 +- gcc/testsuite/gdc.test/runnable/test23959.d | 30 ++++++ gcc/testsuite/gdc.test/runnable/testcontracts.d | 2 +- gcc/testsuite/gdc.test/runnable/uda.d | 42 ++++---- gcc/testsuite/gdc.test/runnable/xtest46.d | 10 +- gcc/testsuite/gdc.test/runnable/xtest46_gc.d | 10 +- 112 files changed, 983 insertions(+), 449 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/imports/pkg20008/package.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/pkg20008/submod.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/package.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/subsubmod.d create mode 100644 gcc/testsuite/gdc.test/compilable/issue24018.d create mode 100644 gcc/testsuite/gdc.test/compilable/test20008.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23965.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23978.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23979.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23986.d create mode 100644 gcc/testsuite/gdc.test/compilable/test24013.d create mode 100644 gcc/testsuite/gdc.test/compilable/test24017.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/callconst.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail22729.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/funcpostattr.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/issue23947a.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/issue23947.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/missingbrace.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test21025.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23968.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23982.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/unmatchedbrace.d create mode 100644 gcc/testsuite/gdc.test/runnable/test23959.d (limited to 'gcc') diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 1cff48a..308d51b 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -17ccd12af386543c0b9935bf7e0a8e701b903105 +a88e1335f7ea767ef438c34998f5d1f26008c586 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/README.md b/gcc/d/dmd/README.md index 79215b7..4fd7831 100644 --- a/gcc/d/dmd/README.md +++ b/gcc/d/dmd/README.md @@ -174,7 +174,6 @@ Note that these groups have no strict meaning, the category assignments are a bi | [cond.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/cond.d) | Evaluate `static if`, `version` `debug ` | | [staticcond.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/staticcond.d) | Lazily evaluate static conditions for `static if`, `static assert` and template constraints | | [delegatize.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/delegatize.d) | Converts expression to delegates for `lazy` parameters | -| [eh.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/eh.d) | Generate tables for exception handling | | [nspace.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/nspace.d) | Namespace for `extern (C++, Module)` | | [intrange.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/intrange.d) | [Value range propagation](https://digitalmars.com/articles/b62.html) | | [dimport.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/dimport.d) | Renamed imports (`import aliasSymbol = pkg1.pkg2.symbol`) | diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index d5aee89..9c46eea 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.104.0 +v2.104.1 diff --git a/gcc/d/dmd/access.d b/gcc/d/dmd/access.d index f2d68d5..668129a 100644 --- a/gcc/d/dmd/access.d +++ b/gcc/d/dmd/access.d @@ -16,17 +16,13 @@ module dmd.access; import dmd.aggregate; import dmd.astenums; import dmd.dclass; -import dmd.declaration; import dmd.dmodule; import dmd.dscope; import dmd.dstruct; import dmd.dsymbol; -import dmd.errors; import dmd.expression; -import dmd.func; import dmd.globals; import dmd.location; -import dmd.mtype; import dmd.tokens; private enum LOG = false; diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d index c08382c..ff4ebe8 100644 --- a/gcc/d/dmd/attrib.d +++ b/gcc/d/dmd/attrib.d @@ -653,7 +653,8 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration { Module m = sc._module; - // While isAncestorPackageOf does an equality check, the fix for issue 17441 adds a check to see if + // https://issues.dlang.org/show_bug.cgi?id=17441 + // While isAncestorPackageOf does an equality check, the fix for the issue adds a check to see if // each package's .isModule() properites are equal. // // Properties generated from `package(foo)` i.e. visibility.pkg have .isModule() == null. diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d index 09d39ca..89d5519 100644 --- a/gcc/d/dmd/canthrow.d +++ b/gcc/d/dmd/canthrow.d @@ -80,7 +80,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN if (!f.isDtorDeclaration()) errorSupplementalInferredAttr(f, 10, false, STC.nothrow_); - e.checkOverridenDtor(null, f, dd => dd.type.toTypeFunction().isnothrow, "not nothrow"); + e.checkOverriddenDtor(null, f, dd => dd.type.toTypeFunction().isnothrow, "not nothrow"); } else if (func) { @@ -118,7 +118,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN { auto sd = ts.sym; const id = ce.f.ident; - if (sd.postblit && isArrayConstructionOrAssign(id)) + if (sd.postblit && isArrayConstruction(id)) { checkFuncThrows(ce, sd.postblit); return; diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 33669e3..1b6b2bb 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -4235,7 +4235,7 @@ final class CParser(AST) : Parser!AST return false; /* https://issues.dlang.org/show_bug.cgi?id=22267 - Fix issue 22267: If the parser encounters the following + If the parser encounters the following `identifier variableName = (expression);` the initializer is not identified as such since the parentheses cause the parser to keep walking indefinitely diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 6fcc280..b2aa643 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -2922,6 +2922,7 @@ Type typeMerge(Scope* sc, EXP op, ref Expression pe1, ref Expression pe2) ubyte mod = MODmerge(t1.mod, t2.mod); t1 = t1.castMod(mod); t2 = t2.castMod(mod); + return Lret(t1); } Lagain: diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index cfa6988..5559b93 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -599,7 +599,7 @@ extern (C++) final class TupleDeclaration : Declaration override const(char)* kind() const { - return "tuple"; + return "sequence"; } override Type getType() diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 5b27a07..cb74a07 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -2412,7 +2412,7 @@ public: continue; if (ex.op == EXP.voidExpression) { - e.error("CTFE internal error: void element `%s` in tuple", exp.toChars()); + e.error("CTFE internal error: void element `%s` in sequence", exp.toChars()); assert(0); } @@ -3890,7 +3890,7 @@ public: newval = copyLiteral(newval).copy(); assignInPlace(oldval, newval); } - else if (wantCopy && e.op == EXP.assign) + else if (wantCopy && (e.op == EXP.assign || e.op == EXP.loweredAssignExp)) { // Currently postblit/destructor calls on static array are done // in the druntime internal functions so they don't appear in AST. @@ -4299,7 +4299,7 @@ public: rb.newval = newval; rb.refCopy = wantRef || cow; rb.needsPostblit = sd && sd.postblit && e.op != EXP.blit && e.e2.isLvalue(); - rb.needsDtor = sd && sd.dtor && e.op == EXP.assign; + rb.needsDtor = sd && sd.dtor && (e.op == EXP.assign || e.op == EXP.loweredAssignExp); if (Expression ex = rb.assignTo(existingAE, cast(size_t)lowerbound, cast(size_t)upperbound)) return ex; @@ -4773,12 +4773,11 @@ public: result = CTFEExp.voidexp; return; } - else if (isArrayConstructionOrAssign(fd.ident)) + else if (isArrayConstruction(fd.ident)) { - // In expressionsem.d, the following lowerings were performed: - // * `T[x] ea = eb;` to `_d_array{,set}ctor(ea[], eb[]);`. - // * `ea = eb` to `_d_array{,setassign,assign_l,assign_r}(ea[], eb)`. - // The following code will rewrite them back to `ea = eb` and + // In expressionsem.d, `T[x] ea = eb;` was lowered to: + // `_d_array{,set}ctor(ea[], eb[]);`. + // The following code will rewrite it back to `ea = eb` and // then interpret that expression. if (fd.ident == Id._d_arrayctor) @@ -4791,17 +4790,14 @@ public: ea = ea.isCastExp.e1; Expression eb = (*e.arguments)[1]; - if (eb.isCastExp() && fd.ident != Id._d_arraysetctor) + if (eb.isCastExp() && fd.ident == Id._d_arrayctor) eb = eb.isCastExp.e1; - Expression rewrittenExp; - if (fd.ident == Id._d_arrayctor || fd.ident == Id._d_arraysetctor) - rewrittenExp = new ConstructExp(e.loc, ea, eb); - else - rewrittenExp = new AssignExp(e.loc, ea, eb); + ConstructExp ce = new ConstructExp(e.loc, ea, eb); + ce.type = ea.type; - rewrittenExp.type = ea.type; - result = interpret(rewrittenExp, istate); + ce.type = ea.type; + result = interpret(ce, istate); return; } diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d index 72a4476..ad1e816 100644 --- a/gcc/d/dmd/dmangle.d +++ b/gcc/d/dmd/dmangle.d @@ -888,7 +888,7 @@ public: buf.writeByte('V'); if (ea.op == EXP.tuple) { - ea.error("tuple is not a valid template value argument"); + ea.error("sequence is not a valid template value argument"); continue; } // Now that we know it is not an alias, we MUST obtain a value diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 149a5b1..f00dec7 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -53,6 +53,10 @@ import dmd.target; import dmd.utils; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + // function used to call semantic3 on a module's dependencies void semantic3OnDependencies(Module m) { @@ -615,9 +619,18 @@ extern (C++) final class Module : Package if (FileName.equals(srcfile.toString(), "object.d")) { .error(loc, "cannot find source code for runtime library file 'object.d'"); - errorSupplemental(loc, "dmd might not be correctly installed. Run 'dmd -man' for installation instructions."); - const dmdConfFile = global.inifilename.length ? FileName.canonicalName(global.inifilename) : "not found"; - errorSupplemental(loc, "config file: %.*s", cast(int)dmdConfFile.length, dmdConfFile.ptr); + version (IN_LLVM) + { + errorSupplemental(loc, "ldc2 might not be correctly installed."); + errorSupplemental(loc, "Please check your ldc2.conf configuration file."); + errorSupplemental(loc, "Installation instructions can be found at http://wiki.dlang.org/LDC."); + } + version (MARS) + { + errorSupplemental(loc, "dmd might not be correctly installed. Run 'dmd -man' for installation instructions."); + const dmdConfFile = global.inifilename.length ? FileName.canonicalName(global.inifilename) : "not found"; + errorSupplemental(loc, "config file: %.*s", cast(int)dmdConfFile.length, dmdConfFile.ptr); + } } else if (FileName.ext(this.arg) || !loc.isValid()) { diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index a5cd63b..622e286 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -587,6 +587,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor const loc = (s ? s : dsym).loc; loc.errorSupplemental("required by type `%s`", dsym.type.toChars()); } + errorSupplemental(dsym.loc, "see https://dlang.org/spec/struct.html#opaque_struct_unions"); + errorSupplemental(dsym.loc, "perhaps declare a variable with pointer type `%s*` instead", dsym.type.toChars()); // Flag variable as error to avoid invalid error messages due to unknown size dsym.type = Type.terror; @@ -693,7 +695,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor size_t tedim = te.exps.length; if (tedim != nelems) { - error(dsym.loc, "tuple of %d elements cannot be assigned to tuple of %d elements", cast(int)tedim, cast(int)nelems); + error(dsym.loc, "sequence of %d elements cannot be assigned to sequence of %d elements", cast(int)tedim, cast(int)nelems); for (size_t u = tedim; u < nelems; u++) // fill dummy expression te.exps.push(ErrorExp.get()); } @@ -2042,7 +2044,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { } else - ns.exp.error("compile time string constant (or tuple) expected, not `%s`", + ns.exp.error("compile time string constant (or sequence) expected, not `%s`", ns.exp.toChars()); attribSemantic(ns); } @@ -2712,7 +2714,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (i + 1 != tempdecl.parameters.length && tp.isTemplateTupleParameter()) { - tempdecl.error("template tuple parameter must be last one"); + tempdecl.error("template sequence parameter must be the last one"); tempdecl.errors = true; } } @@ -3963,13 +3965,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor hgs.fullQual = true; // https://issues.dlang.org/show_bug.cgi?id=23745 - // If the potentially overriden function contains errors, + // If the potentially overridden function contains errors, // inform the user to fix that one first if (fd.errors) { error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?", funcdecl.toChars(), fd.toPrettyChars()); - errorSupplemental(fd.loc, "Function `%s` contains errors in its declaration, therefore it cannot be correctly overriden", + errorSupplemental(fd.loc, "Function `%s` contains errors in its declaration, therefore it cannot be correctly overridden", fd.toPrettyChars()); } else @@ -3985,7 +3987,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { error(funcdecl.loc, "function `%s` does not override any function, did you mean to override %s `%s`?", funcdeclToChars, s.kind, s.toPrettyChars()); - errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overriden"); + errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overridden"); } } else @@ -5897,6 +5899,31 @@ void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds) }); } +/****************************************************** + * Verifies if the given Identifier is a DRuntime hook. It uses the hooks + * defined in `id.d`. + * + * Params: + * id = Identifier to verify + * Returns: + * true if `id` is a DRuntime hook + * false otherwise + */ +private bool isDRuntimeHook(Identifier id) +{ + return id == Id._d_HookTraceImpl || + id == Id._d_newclassT || id == Id._d_newclassTTrace || + id == Id._d_arraycatnTX || id == Id._d_arraycatnTXTrace || + id == Id._d_newThrowable || id == Id._d_delThrowable || + id == Id._d_arrayassign_l || id == Id._d_arrayassign_r || + id == Id._d_arraysetassign || id == Id._d_arraysetctor || + id == Id._d_arrayctor || + id == Id._d_arraysetlengthTImpl || id == Id._d_arraysetlengthT || + id == Id._d_arraysetlengthTTrace || + id == Id._d_arrayappendT || id == Id._d_arrayappendTTrace || + id == Id._d_arrayappendcTXImpl; +} + void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList argumentList) { //printf("[%s] TemplateInstance.dsymbolSemantic('%s', this=%p, gag = %d, sc = %p)\n", tempinst.loc.toChars(), tempinst.toChars(), tempinst, global.gag, sc); @@ -6376,8 +6403,20 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList tempinst.deferred = &deferred; //printf("Run semantic3 on %s\n", toChars()); + + /* https://issues.dlang.org/show_bug.cgi?id=23965 + * DRuntime hooks are not deprecated, but may be used for deprecated + * types. Deprecations are disabled while analysing hooks to avoid + * spurious error messages. + */ + auto saveUseDeprecated = global.params.useDeprecated; + if (sc.isDeprecated() && isDRuntimeHook(tempinst.name)) + global.params.useDeprecated = DiagnosticReporting.off; + tempinst.trySemantic3(sc2); + global.params.useDeprecated = saveUseDeprecated; + for (size_t i = 0; i < deferred.length; i++) { //printf("+ run deferred semantic3 on %s\n", deferred[i].toChars()); diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 5b98d2f..f2ab694 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -1302,36 +1302,19 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol /************************************************* * Match function arguments against a specific template function. - * Input: - * ti - * sc instantiation scope - * fd - * tthis 'this' argument if !NULL - * argumentList arguments to function - * Output: - * fd Partially instantiated function declaration - * ti.tdtypes Expression/Type deduced template arguments + * + * Params: + * ti = template instance. `ti.tdtypes` will be set to Expression/Type deduced template arguments + * sc = instantiation scope + * fd = Partially instantiated function declaration, which is set to an instantiated function declaration + * tthis = 'this' argument if !NULL + * argumentList = arguments to function + * * Returns: * match pair of initial and inferred template arguments */ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateInstance ti, Scope* sc, ref FuncDeclaration fd, Type tthis, ArgumentList argumentList) { - size_t nfparams; - size_t nfargs; - size_t ntargs; // array size of tiargs - size_t fptupindex = IDX_NOTFOUND; - MATCH match = MATCH.exact; - MATCH matchTiargs = MATCH.exact; - ParameterList fparameters; // function parameter list - VarArg fvarargs; // function varargs - uint wildmatch = 0; - size_t inferStart = 0; - - Loc instLoc = ti.loc; - Objects* tiargs = ti.tiargs; - auto dedargs = new Objects(parameters.length); - Objects* dedtypes = &ti.tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T - version (none) { printf("\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\n", toChars()); @@ -1348,8 +1331,10 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol assert(_scope); + auto dedargs = new Objects(parameters.length); dedargs.zero(); + Objects* dedtypes = &ti.tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T dedtypes.setDim(parameters.length); dedtypes.zero(); @@ -1393,8 +1378,12 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol } } - ntargs = 0; - if (tiargs) + size_t ntargs = 0; // array size of tiargs + size_t inferStart = 0; // index of first parameter to infer + const Loc instLoc = ti.loc; + MATCH matchTiargs = MATCH.exact; + + if (auto tiargs = ti.tiargs) { // Set initial template arguments ntargs = tiargs.length; @@ -1460,9 +1449,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol } } - fparameters = fd.getParameterList(); - nfparams = fparameters.length; // number of function parameters - nfargs = argumentList.length; // number of function arguments + ParameterList fparameters = fd.getParameterList(); // function parameter list + const nfparams = fparameters.length; // number of function parameters + const nfargs = argumentList.length; // number of function arguments if (argumentList.hasNames) return matcherror(); // TODO: resolve named args Expressions* fargs = argumentList.arguments; // TODO: resolve named args @@ -1473,6 +1462,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol * void foo(T, A...)(T t, A a); * void main() { foo(1,2,3); } */ + size_t fptupindex = IDX_NOTFOUND; if (tp) // if variadic { // TemplateTupleParameter always makes most lesser matching. @@ -1515,6 +1505,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol } } + MATCH match = MATCH.exact; if (toParent().isModule()) tthis = null; if (tthis) @@ -1579,6 +1570,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple.toChars() : NULL); size_t argi = 0; size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs + uint inoutMatch = 0; // for debugging only for (size_t parami = 0; parami < nfparams; parami++) { Parameter fparam = fparameters[parami]; @@ -1643,7 +1635,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol MATCH m; if (ubyte wm = deduceWildHelper(farg.type, &tt, tid)) { - wildmatch |= wm; + inoutMatch |= wm; m = MATCH.constant; } else @@ -1896,10 +1888,10 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol if (fparameters.varargs == VarArg.typesafe && parami + 1 == nfparams && argi + 1 < nfargs) goto Lvarargs; - uint wm = 0; - MATCH m = deduceType(oarg, paramscope, prmtype, parameters, dedtypes, &wm, inferStart); - //printf("\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\n", __LINE__, m, wm, wildmatch); - wildmatch |= wm; + uint im = 0; + MATCH m = deduceType(oarg, paramscope, prmtype, parameters, dedtypes, &im, inferStart); + //printf("\tL%d deduceType m = %d, im = x%x, inoutMatch = x%x\n", __LINE__, m, im, inoutMatch); + inoutMatch |= im; /* If no match, see if the argument can be matched by using * implicit conversions. @@ -2087,7 +2079,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol { uint wm = 0; m = deduceType(arg, paramscope, ta.next, parameters, dedtypes, &wm, inferStart); - wildmatch |= wm; + inoutMatch |= wm; } if (m == MATCH.nomatch) return nomatch(); diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index f00b8db..b9bbad0 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -2450,7 +2450,7 @@ public: { debug (Debug_DtoH) mixin(traceVisit!e); - // Valid in most cases, others should be overriden below + // Valid in most cases, others should be overridden below // to use the appropriate operators (:: and ->) buf.writestring(e.toString()); } diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index c0dd17f..efd6bea 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -93,22 +93,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf, bool isMutable; // true if reference to mutable } - /* Store escapeBy as static data escapeByStorage so we can keep reusing the same - * arrays rather than reallocating them. - */ - __gshared EscapeBy[] escapeByStorage; - auto escapeBy = escapeByStorage; - if (escapeBy.length < len) - { - auto newPtr = cast(EscapeBy*)mem.xrealloc(escapeBy.ptr, len * EscapeBy.sizeof); - // Clear the new section - memset(newPtr + escapeBy.length, 0, (len - escapeBy.length) * EscapeBy.sizeof); - escapeBy = newPtr[0 .. len]; - escapeByStorage = escapeBy; - } - else - escapeBy = escapeBy[0 .. len]; - + auto escapeBy = new EscapeBy[len]; const paramLength = tf.parameterList.length; // Fill in escapeBy[] with arguments[], ethis, and outerVars[] @@ -181,7 +166,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf, if (!(eb.isMutable || eb2.isMutable)) return; - if (!tf.islive && !(global.params.useDIP1000 == FeatureState.enabled && sc.func.setUnsafe())) + if (!tf.islive && !(global.params.useDIP1000 == FeatureState.enabled && sc.func && sc.func.setUnsafe())) return; if (!gag) @@ -228,13 +213,6 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf, escape(i, eb, false); } - /* Reset the arrays in escapeBy[] so we can reuse them next time through - */ - foreach (ref eb; escapeBy) - { - eb.er.reset(); - } - return errors; } @@ -387,8 +365,9 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, (!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") : (desc ~ " `%s` assigned to non-scope anonymous parameter"); - auto param = isThis ? v : (parId ? parId : fdc); - if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, param, fdc)) + if (isThis ? + sc.setUnsafeDIP1000(gag, arg.loc, msg, arg, fdc.toParent2(), fdc) : + sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc)) { result = true; printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10); @@ -508,7 +487,7 @@ bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, Pa const byRef = param.isReference() && !(param.storageClass & STC.scope_) && !(param.storageClass & STC.returnScope); // fixme: it's possible to infer returnScope without scope with vaIsFirstRef - scope e = new AssignExp(arg.loc, firstArg, arg); + auto e = new AssignExp(arg.loc, firstArg, arg); return checkAssignEscape(sc, e, gag, byRef); } @@ -2487,6 +2466,9 @@ bool isReferenceToMutable(Type t) } break; + case Tnull: + return false; + default: assert(0); } diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 473efb8..35f11af 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -1242,7 +1242,7 @@ extern (C++) abstract class Expression : ASTNode if (!f.isDtorDeclaration()) errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.pure_); - checkOverridenDtor(sc, f, dd => dd.type.toTypeFunction().purity != PURE.impure, "impure"); + checkOverriddenDtor(sc, f, dd => dd.type.toTypeFunction().purity != PURE.impure, "impure"); return true; } return false; @@ -1261,7 +1261,7 @@ extern (C++) abstract class Expression : ASTNode * check = current check (e.g. whether it's pure) * checkName = the kind of check (e.g. `"pure"`) */ - extern (D) final void checkOverridenDtor(Scope* sc, FuncDeclaration f, + extern (D) final void checkOverriddenDtor(Scope* sc, FuncDeclaration f, scope bool function(DtorDeclaration) check, const string checkName ) { auto dd = f.isDtorDeclaration(); @@ -1314,7 +1314,7 @@ extern (C++) abstract class Expression : ASTNode field.loc.errorSupplemental(" - %s %s", field.type.toChars(), field.toChars()); if (fieldSd.dtor.isGenerated()) - checkOverridenDtor(sc, fieldSd.dtor, check, checkName); + checkOverriddenDtor(sc, fieldSd.dtor, check, checkName); else fieldSd.dtor.loc.errorSupplemental(" %.*s `%s.~this` is declared here", cast(int) checkName.length, checkName.ptr, fieldSd.toChars()); @@ -1505,7 +1505,7 @@ extern (C++) abstract class Expression : ASTNode errorSupplementalInferredAttr(f, /*max depth*/ 10, /*deprecation*/ false, STC.safe); .errorSupplemental(f.loc, "`%s` is declared here", prettyChars); - checkOverridenDtor(sc, f, dd => dd.type.toTypeFunction().trust > TRUST.system, "@system"); + checkOverriddenDtor(sc, f, dd => dd.type.toTypeFunction().trust > TRUST.system, "@system"); return true; } @@ -1569,7 +1569,7 @@ extern (C++) abstract class Expression : ASTNode f.errorSupplementalInferredAttr(/*max depth*/ 10, /*deprecation*/ false, STC.nogc); } - checkOverridenDtor(sc, f, dd => dd.type.toTypeFunction().isnogc, "non-@nogc"); + checkOverriddenDtor(sc, f, dd => dd.type.toTypeFunction().isnogc, "non-@nogc"); return true; } @@ -4512,7 +4512,7 @@ extern (C++) abstract class BinExp : Expression Type t2 = e2.type; // T opAssign floating yields a floating. Prevent truncating conversions (float to int). - // See issue 3841. + // See https://issues.dlang.org/show_bug.cgi?id=3841. // Should we also prevent double to float (type.isfloating() && type.size() < t2.size()) ? if (op == EXP.addAssign || op == EXP.minAssign || op == EXP.mulAssign || op == EXP.divAssign || op == EXP.modAssign || @@ -7425,23 +7425,20 @@ extern(D) Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag } /** - * Verify if the given identifier is any of - * _d_array{ctor,setctor,setassign,assign_l, assign_r}. + * Verify if the given identifier is _d_array{,set}ctor. * * Params: * id = the identifier to verify * * Returns: - * `true` if the identifier corresponds to a construction of assignement - * runtime hook, `false` otherwise. + * `true` if the identifier corresponds to a construction runtime hook, + * `false` otherwise. */ -bool isArrayConstructionOrAssign(const Identifier id) +bool isArrayConstruction(const Identifier id) { import dmd.id : Id; - return id == Id._d_arrayctor || id == Id._d_arraysetctor || - id == Id._d_arrayassign_l || id == Id._d_arrayassign_r || - id == Id._d_arraysetassign; + return id == Id._d_arrayctor || id == Id._d_arraysetctor; } /****************************** diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 8ac8866..be597df 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -387,34 +387,6 @@ Expression checkNoreturnVarAccess(Expression exp) } /****************************** - * Check the tail CallExp is really property function call. - * Bugs: - * This doesn't appear to do anything. - */ -private bool checkPropertyCall(Expression e) -{ - e = lastComma(e); - - if (auto ce = e.isCallExp()) - { - if (ce.f) - { - auto tf = ce.f.type.isTypeFunction(); - /* If a forward reference to ce.f, try to resolve it - */ - if (!tf.deco && ce.f.semanticRun < PASS.semanticdone) - { - ce.f.dsymbolSemantic(null); - tf = ce.f.type.isTypeFunction(); - } - } - else if (!ce.e1.type.isFunction_Delegate_PtrToFunction()) - assert(0); - } - return false; -} - -/****************************** * Find symbol in accordance with the UFCS name look up rule */ private Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident) @@ -489,6 +461,15 @@ private Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident) if (auto dti = ue.isDotTemplateInstanceExp()) { + // https://issues.dlang.org/show_bug.cgi?id=23968 + // Typically, deprecated alias declarations are caught + // when `TemplateInstance.findTempDecl` is called, + // however, in this case the tempdecl field is updated + // therefore `findTempDecl` will return immediately + // and not get the chance to issue the deprecation. + if (s.isAliasDeclaration()) + s.checkDeprecated(ue.loc, sc); + auto ti = new TemplateInstance(loc, s.ident, dti.ti.tiargs); if (!ti.updateTempDecl(sc, s)) return ErrorExp.get(); @@ -717,7 +698,6 @@ private Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 } else if (ex && !e) { - checkPropertyCall(ex); ex = new AssignExp(loc, ex, e2); return ex.expressionSemantic(sc); } @@ -726,7 +706,6 @@ private Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 // strict setter prints errors if fails e = e.expressionSemantic(sc); } - checkPropertyCall(e); return e; } else @@ -736,9 +715,13 @@ private Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 auto arguments = new Expressions(1); (*arguments)[0] = eleft; e = new CallExp(loc, e, arguments); + + // https://issues.dlang.org/show_bug.cgi?id=24017 + if (sc.flags & SCOPE.debug_) + e.isCallExp().inDebugStatement = true; + e = e.expressionSemantic(sc); - checkPropertyCall(e); - return e.expressionSemantic(sc); + return e; } } @@ -1189,6 +1172,13 @@ L1: */ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc) { + // https://issues.dlang.org/show_bug.cgi?id=24013 + // traits(getOverloads) inserts an alias to select the overload. + // When searching for the right this we need to use the aliased + // overload/function, not the alias. + outerFunc = outerFunc.toAliasFunc(); + calledFunc = calledFunc.toAliasFunc(); + auto thisAd = outerFunc.isMemberLocal(); if (!thisAd) return false; @@ -1386,15 +1376,6 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = { if (fd.errors) return ErrorExp.get(); - if (!checkSymbolAccess(sc, fd)) - { - // @@@DEPRECATED_2.105@@@ - // When turning into error, uncomment the return statement - TypeFunction tf = fd.type.isTypeFunction(); - deprecation(loc, "function `%s` of type `%s` is not accessible from module `%s`", - fd.toPrettyChars(), tf.toChars, sc._module.toChars); - //return ErrorExp.get(); - } assert(fd.type.ty == Tfunction); Expression e = new CallExp(loc, e1, e2); return e.expressionSemantic(sc); @@ -1409,14 +1390,6 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = TypeFunction tf = fd.type.isTypeFunction(); if (!e2 || tf.isref) { - if (!checkSymbolAccess(sc, fd)) - { - // @@@DEPRECATED_2.105@@@ - // When turning into error, uncomment the return statement - deprecation(loc, "function `%s` of type `%s` is not accessible from module `%s`", - fd.toPrettyChars(), tf.toChars, sc._module.toChars); - //return ErrorExp.get(); - } Expression e = new CallExp(loc, e1); if (e2) { @@ -3404,7 +3377,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (ve && ve.var && exp.parens && !ve.var.isStatic() && !(sc.stc & STC.static_) && sc.func && sc.func.needThis && ve.var.isMember2()) { - // printf("apply fix for issue 9490: add `this.` to `%s`...\n", e.toChars()); + // printf("apply fix for bugzilla issue 9490: add `this.` to `%s`...\n", e.toChars()); e = new DotVarExp(exp.loc, new ThisExp(exp.loc), ve.var, false); } //printf("e = %s %s\n", Token.toChars(e.op), e.toChars()); @@ -4092,9 +4065,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (arg.op == EXP.error) return setError(); arg = arg.optimize(WANTvalue); - if (arg.op == EXP.int64 && cast(sinteger_t)arg.toInteger() < 0) + if (arg.op == EXP.int64 && (target.isLP64 ? + cast(sinteger_t)arg.toInteger() : cast(int)arg.toInteger()) < 0) { - exp.error("negative array index `%s`", arg.toChars()); + exp.error("negative array dimension `%s`", (*exp.arguments)[i].toChars()); return setError(); } (*exp.arguments)[i] = arg; @@ -5024,7 +4998,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (!exp.ignoreAttributes) checkFunctionAttributes(exp, sc, exp.f); - checkAccess(exp.loc, sc, ue.e1, exp.f); + + // Cut-down version of checkAccess() that doesn't use the "most visible" version of exp.f. + // We've already selected an overload here. + const parent = exp.f.toParent(); + if (parent && parent.isTemplateInstance()) + { + // already a deprecation + } + else if (!checkSymbolAccess(sc, exp.f)) + { + exp.error("%s `%s` of type `%s` is not accessible from module `%s`", + exp.f.kind(), exp.f.toPrettyChars(), exp.f.type.toChars(), sc._module.toChars); + return setError(); + } + if (!exp.f.needThis()) { exp.e1 = Expression.combine(ue.e1, new VarExp(exp.loc, exp.f, false)); @@ -7828,7 +7816,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.to.ty == Ttuple) { - exp.error("cannot cast `%s` of type `%s` to tuple type `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars()); + exp.error("cannot cast `%s` of type `%s` to type sequence `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars()); return setError(); } @@ -8174,7 +8162,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (!exp.lwr || !exp.upr) { - exp.error("need upper and lower bound to slice tuple"); + exp.error("need upper and lower bound to slice a sequence"); return setError(); } } @@ -9219,7 +9207,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Expression e = null; if (dim != tup2.exps.length) { - exp.error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.length); + exp.error("mismatched sequence lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.length); return setError(); } if (dim == 0) @@ -10363,6 +10351,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (global.params.verbose) message("lowered %s =>\n %s", ae.toChars(), res.toChars()); + res = new LoweredAssignExp(ae, res); + res.type = ae.type; + return res; } diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index a159c2f..62e0d49 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -927,7 +927,7 @@ public: } if (d.decl.length == 0 || (hgs.hdrgen && d.decl.length == 1 && (*d.decl)[0].isUnitTestDeclaration())) { - // hack for bugzilla 8081 + // hack for https://issues.dlang.org/show_bug.cgi?id=8081 if (hasSTC) buf.writeByte(' '); buf.writestring("{}"); } @@ -2217,13 +2217,13 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg { buf.writeByte('('); e.e0.expressionPrettyPrint(buf, hgs); - buf.writestring(", tuple("); + buf.writestring(", AliasSeq!("); argsToBuffer(e.exps, buf, hgs); buf.writestring("))"); } else { - buf.writestring("tuple("); + buf.writestring("AliasSeq!("); argsToBuffer(e.exps, buf, hgs); buf.writeByte(')'); } @@ -4141,7 +4141,7 @@ string EXPtoString(EXP op) EXP.delegatePointer : "delegateptr", EXP.delegateFunctionPointer : "delegatefuncptr", EXP.remove : "remove", - EXP.tuple : "tuple", + EXP.tuple : "sequence", EXP.traits : "__traits", EXP.overloadSet : "__overloadset", EXP.void_ : "void", diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index ca770bd..ee288d1 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -582,7 +582,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ Initializer visitC(CInitializer ci) { - //printf("CInitializer::semantic() (%s) %s\n", t.toChars(), ci.toChars()); + //printf("CInitializer::semantic() tx: %s t: %s ci: %s\n", (tx ? tx.toChars() : "".ptr), t.toChars(), ci.toChars()); /* Rewrite CInitializer into ExpInitializer, ArrayInitializer, or StructInitializer */ t = t.toBasetype(); @@ -770,7 +770,6 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ return err(); } const nfields = sd.fields.length; - size_t fieldi = 0; for (size_t index = 0; index < ci.initializerList.length; ) @@ -807,6 +806,12 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ { if (fieldi == nfields) break; + if (index == 0 && ci.initializerList.length == 1 && di.initializer.isCInitializer()) + { + ci = di.initializer.isCInitializer(); + continue; + } + VarDeclaration field; while (1) // skip field if it overlaps with previously seen fields { @@ -954,10 +959,13 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ return initializerSemantic(ai, sc, tx, needInterpret); } else if (ExpInitializer ei = isBraceExpression()) + { return visitExp(ei); + } else { - assert(0); + error(ci.loc, "unrecognized C initializer `%s`", ci.toChars()); + return err(); } } diff --git a/gcc/d/dmd/inline.d b/gcc/d/dmd/inline.d index 8e63122..afab831 100644 --- a/gcc/d/dmd/inline.d +++ b/gcc/d/dmd/inline.d @@ -21,8 +21,8 @@ import dmd.expression; * Perform the "inline copying" of a default argument for a function parameter. * * Todo: - * The hack for bugzilla 4820 case is still questionable. Perhaps would have to - * handle a delegate expression with 'null' context properly in front-end. + * The hack for https://issues.dlang.org/show_bug.cgi?id=4820 case is still questionable. + * Perhaps would have to handle a delegate expression with 'null' context properly in front-end. */ public Expression inlineCopy(Expression e, Scope* sc) { diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index a878cc9..add1ce6 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -2205,7 +2205,7 @@ class Lexer p++; if ((flags & f) && !err) { - error("unrecognized token"); + error("repeated integer suffix `%c`", p[-1]); err = true; } flags = cast(FLAGS)(flags | f); diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index cb3e6cd..7ecd402 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -2054,7 +2054,7 @@ extern (C++) abstract class Type : ASTNode return Type.terror; auto t = fd.type.nextOf(); - if (!t) // issue 14185 + if (!t) // https://issues.dlang.org/show_bug.cgi?id=14185 return Type.terror; t = t.substWildTo(mod == 0 ? MODFlags.mutable : mod); return t; @@ -4597,10 +4597,9 @@ extern (C++) final class TypeFunction : TypeNext // show qualification when toChars() is the same but types are different // https://issues.dlang.org/show_bug.cgi?id=19948 // when comparing the type with strcmp, we need to drop the qualifier - auto at = arg.type.mutableOf().toChars(); - bool qual = !arg.type.equals(par.type) && strcmp(at, par.type.mutableOf().toChars()) == 0; - if (qual) - at = arg.type.toPrettyChars(true); + bool qual = !arg.type.mutableOf().equals(par.type.mutableOf()) && + strcmp(arg.type.mutableOf().toChars(), par.type.mutableOf().toChars()) == 0; + auto at = qual ? arg.type.toPrettyChars(true) : arg.type.toChars(); OutBuffer buf; // only mention rvalue if it's relevant const rv = !arg.isLvalue() && par.isReference(); @@ -4940,7 +4939,7 @@ extern (C++) final class TypeFunction : TypeNext } if (tb.ty == Ttuple) { - error(loc, "functions cannot return a tuple"); + error(loc, "functions cannot return a sequence (use `std.typecons.Tuple`)"); next = Type.terror; } if (!isref && (tb.ty == Tstruct || tb.ty == Tsarray)) @@ -5105,7 +5104,7 @@ extern (C++) final class TypeDelegate : TypeNext * This is a shell containing a TraitsExp that can be * either resolved to a type or to a symbol. * - * The point is to allow AliasDeclarationY to use `__traits()`, see issue 7804. + * The point is to allow AliasDeclarationY to use `__traits()`, see https://issues.dlang.org/show_bug.cgi?id=7804. */ extern (C++) final class TypeTraits : Type { @@ -6218,7 +6217,7 @@ extern (C++) final class TypeTuple : Type { Expression e = (*exps)[i]; if (e.type.ty == Ttuple) - e.error("cannot form tuple of tuples"); + e.error("cannot form sequence of sequences"); auto arg = new Parameter(STC.undefined_, e.type, null, null, null); (*arguments)[i] = arg; } @@ -6273,7 +6272,7 @@ extern (C++) final class TypeTuple : Type override const(char)* kind() const { - return "tuple"; + return "sequence"; } override TypeTuple syntaxCopy() @@ -7271,7 +7270,7 @@ private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct, { /* Although a copy constructor may exist, no suitable match was found. * i.e: `inout` constructor creates `const` object, not mutable. - * Fallback to using the original generic error before bugzilla 22202. + * Fallback to using the original generic error before https://issues.dlang.org/show_bug.cgi?id=22202. */ goto Lnocpctor; } diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d index 0e64d9c..8b42a91 100644 --- a/gcc/d/dmd/opover.d +++ b/gcc/d/dmd/opover.d @@ -416,9 +416,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) * op(e1.aliasthis) */ //printf("att una %s e1 = %s\n", EXPtoString(op).ptr, this.e1.type.toChars()); - e.e1 = resolveAliasThis(sc, e.e1, true); - if (e.e1) + if (auto e1 = resolveAliasThis(sc, e.e1, true)) + { + e.e1 = e1; continue; + } break; } break; @@ -1043,7 +1045,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) size_t dim = tup1.exps.length; if (dim != tup2.exps.length) { - e.error("mismatched tuple lengths, `%d` and `%d`", + e.error("mismatched sequence lengths, `%d` and `%d`", cast(int)dim, cast(int)tup2.exps.length); return ErrorExp.get(); } diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index 335310d..f98e7c7 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -189,7 +189,7 @@ private Expression fromConstInitializer(int result, Expression e1) { // If it is a comma expression involving a declaration, we mustn't // perform a copy -- we'd get two declarations of the same variable. - // See bugzilla 4465. + // See https://issues.dlang.org/show_bug.cgi?id=4465. if (e.op == EXP.comma && e.isCommaExp().e1.isDeclarationExp()) e = e1; else if (e.type != e1.type && e1.type && e1.type.ty != Tident) diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index b7e0791..eeaef8d 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -1155,6 +1155,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.leftCurly: { + const lcLoc = token.loc; const lookingForElseSave = lookingForElse; lookingForElse = Loc(); @@ -1164,6 +1165,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { /* { */ error("matching `}` expected, not `%s`", token.toChars()); + eSink.errorSupplemental(lcLoc, "unmatched `{`"); } else nextToken(); @@ -1405,6 +1407,15 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer break; } default: + Token* tk; + if (skipAttributes(&token, &tk) && tk.ptr != token.ptr || + token.value == TOK.static_ || token.value == TOK.extern_) + { + error("`%s` token is not allowed in postfix position", + Token.toChars(token.value)); + nextToken(); + continue; + } return storageClass; } storageClass = appendStorageClass(storageClass, stc); @@ -6006,6 +6017,7 @@ LagainStc: } case TOK.leftCurly: { + const lcLoc = token.loc; const lookingForElseSave = lookingForElse; lookingForElse = Loc.initial; @@ -6028,7 +6040,14 @@ LagainStc: s = new AST.CompoundStatement(loc, statements); if (flags & (ParseStatementFlags.scope_ | ParseStatementFlags.curlyScope)) s = new AST.ScopeStatement(loc, s, token.loc); - check(TOK.rightCurly, "compound statement"); + if (token.value != TOK.rightCurly) + { + error(token.loc, "matching `}` expected following compound statement, not `%s`", + token.toChars()); + eSink.errorSupplemental(lcLoc, "unmatched `{`"); + } + else + nextToken(); lookingForElse = lookingForElseSave; break; } diff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d index d1c61be..f36ddb4 100644 --- a/gcc/d/dmd/root/array.d +++ b/gcc/d/dmd/root/array.d @@ -251,6 +251,18 @@ public: length++; } + /// Insert 'count' copies of 'value' at 'index' position + void insert(size_t index, size_t count, T value) pure nothrow + { + if (count == 0) + return; + reserve(count); + if (length != index) + memmove(data.ptr + index + count, data.ptr + index, (length - index) * T.sizeof); + data[index .. index + count] = value; + length += count; + } + void setDim(size_t newdim) pure nothrow { if (length < newdim) @@ -458,6 +470,12 @@ unittest arrayA.insert(0, [7, 8]); arrayA.insert(arrayA.length, [0, 9]); assert(arrayA[] == [7, 8, 5, 1, 2, 6, 0, 9]); + arrayA.insert(4, 3, 8); + assert(arrayA[] == [7, 8, 5, 1, 8, 8, 8, 2, 6, 0, 9]); + arrayA.insert(0, 3, 8); + assert(arrayA[] == [8, 8, 8, 7, 8, 5, 1, 8, 8, 8, 2, 6, 0, 9]); + arrayA.insert(arrayA.length, 3, 8); + assert(arrayA[] == [8, 8, 8, 7, 8, 5, 1, 8, 8, 8, 2, 6, 0, 9, 8, 8, 8]); } /** diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d index c40e72c..3cbf14f 100644 --- a/gcc/d/dmd/semantic2.d +++ b/gcc/d/dmd/semantic2.d @@ -657,6 +657,13 @@ private extern(C++) final class Semantic2Visitor : Visitor { foreach (base; cd.interfaces) { + // https://issues.dlang.org/show_bug.cgi?id=22729 + // interfaces that have errors or that + // inherit from interfaces that have errors + // might have an uninitialized vtable + if (!base.sym.vtbl.length) + continue; + // first entry is ClassInfo reference auto methods = base.sym.vtbl[base.sym.vtblOffset .. $]; diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index 33c2f02..e4ca22a 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -1367,6 +1367,8 @@ private extern(C++) final class Semantic3Visitor : Visitor if (isCppNonMappableType(f.next.toBasetype())) { funcdecl.error("cannot return type `%s` because its linkage is `extern(C++)`", f.next.toChars()); + if (f.next.isTypeDArray()) + errorSupplemental(funcdecl.loc, "slices are specific to D and do not have a counterpart representation in C++", f.next.toChars()); funcdecl.errors = true; } foreach (i, param; f.parameterList) @@ -1605,7 +1607,7 @@ private struct FuncDeclSem3 sc = s; } - /* Checks that the overriden functions (if any) have in contracts if + /* Checks that the overridden functions (if any) have in contracts if * funcdecl has an in contract. */ void checkInContractOverrides() diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index f0454163..2def253 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -257,8 +257,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) continue; } - Statements* flt = s.flatten(sc); - if (flt) + if (auto flt = s.flatten(sc)) { cs.statements.remove(i); cs.statements.insert(i, flt); @@ -279,6 +278,24 @@ Statement statementSemanticVisit(Statement s, Scope* sc) ++i; continue; // look for errors in rest of statements } + + // expand tuple variables in order to attach destruction/exception logic + if (auto es = s.isExpStatement()) + { + if (es.exp && es.exp.isDeclarationExp()) + { + auto de = es.exp.isDeclarationExp(); + auto vd = de.declaration.isVarDeclaration(); + if (vd && vd.aliasTuple && vd.aliasTuple.objects.length) + { + auto j = i; + cs.statements.insert(i, vd.aliasTuple.objects.length - 1, null); + vd.aliasTuple.foreachVar((v) { (*cs.statements)[j++] = toStatement(v); }); + s = (*cs.statements)[i]; + } + } + } + Statement sentry; Statement sexception; Statement sfinally; @@ -384,12 +401,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc) /* Flatten them in place */ - void flatten(Statements* statements) + void flattenStatements(ref Statements statements) { for (size_t i = 0; i < statements.length;) { - Statement s = (*statements)[i]; - if (s) + if (auto s = statements[i]) { if (auto flt = s.flatten(sc)) { @@ -406,7 +422,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) * 'semantic' may return another CompoundStatement * (eg. CaseRangeStatement), so flatten it here. */ - flatten(cs.statements); + flattenStatements(*cs.statements); foreach (s; *cs.statements) { @@ -4298,7 +4314,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState const bool skipCheck = isStatic && needExpansion; if (!skipCheck && (dim < 1 || dim > 2)) { - fs.error("only one (value) or two (key,value) arguments for tuple `foreach`"); + fs.error("only one (value) or two (key,value) arguments allowed for sequence `foreach`"); return returnEarly(); } diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index 53c8fb0..caebf1c 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -1556,7 +1556,9 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (auto imp = s.isImport()) { // https://issues.dlang.org/show_bug.cgi?id=9692 - s = imp.mod; + // https://issues.dlang.org/show_bug.cgi?id=20008 + if (imp.pkg) + s = imp.pkg; } // https://issues.dlang.org/show_bug.cgi?id=16044 @@ -2116,7 +2118,7 @@ private bool isSame(RootObject o1, RootObject o2, Scope* sc) return true; } - // issue 12001, allow isSame, , + // https://issues.dlang.org/show_bug.cgi?id=12001, allow isSame, , Type t1 = isType(o1); Type t2 = isType(o2); if (t1 && t2 && t1.equals(t2)) diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d index a82a268..376c12f 100644 --- a/gcc/d/dmd/transitivevisitor.d +++ b/gcc/d/dmd/transitivevisitor.d @@ -162,14 +162,14 @@ package mixin template ParseVisitMethods(AST) } override void visit(AST.StaticForeachStatement s) - { + { // printf("Visiting StaticForeachStatement\n"); - if (s.sfe.aggrfe) + if (s.sfe.aggrfe) s.sfe.aggrfe.accept(this); - if (s.sfe.rangefe) + if (s.sfe.rangefe) s.sfe.rangefe.accept(this); - } + } override void visit(AST.IfStatement s) { diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 09eef83..d092395 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -121,7 +121,7 @@ private void resolveTupleIndex(const ref Loc loc, Scope* sc, Dsymbol s, out Expr const(uinteger_t) d = eindex.toUInteger(); if (d >= tup.objects.length) { - .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong)tup.objects.length); + .error(loc, "sequence index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong)tup.objects.length); pt = Type.terror; return; } @@ -525,7 +525,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) uinteger_t d = mtype.dim.toUInteger(); if (d >= tup.objects.length) { - .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tup.objects.length); + .error(loc, "sequence index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tup.objects.length); return error(); } @@ -621,7 +621,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) uinteger_t d = mtype.dim.toUInteger(); if (d >= tt.arguments.length) { - .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tt.arguments.length); + .error(loc, "sequence index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tt.arguments.length); return error(); } Type telem = (*tt.arguments)[cast(size_t)d].type; @@ -1684,7 +1684,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) Type tbn = tn.toBasetype(); if (tbn.ty != Ttuple) { - .error(loc, "can only slice tuple types, not `%s`", tbn.toChars()); + .error(loc, "can only slice type sequences, not `%s`", tbn.toChars()); return error(); } TypeTuple tt = cast(TypeTuple)tbn; @@ -2436,7 +2436,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden } else { - error(loc, "no property `%s` for tuple `%s`", ident.toChars(), mt.toChars()); + error(loc, "no property `%s` for sequence `%s`", ident.toChars(), mt.toChars()); e = ErrorExp.get(); } return e; @@ -2563,7 +2563,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type const d = mt.dim.toUInteger(); if (d >= tup.objects.length) { - error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong) tup.objects.length); + error(loc, "sequence index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong) tup.objects.length); return returnError(); } diff --git a/gcc/testsuite/gdc.test/compilable/b20938.d b/gcc/testsuite/gdc.test/compilable/b20938.d index ba3565a..b3aa46c 100644 --- a/gcc/testsuite/gdc.test/compilable/b20938.d +++ b/gcc/testsuite/gdc.test/compilable/b20938.d @@ -1,4 +1,5 @@ -// issue 20938 - Cannot create const arrays mixing immutable and mutable structs with indirections +// https://issues.dlang.org/show_bug.cgi?id=20938 +// Cannot create const arrays mixing immutable and mutable structs with indirections struct S { int[] a; } enum A { a } enum B { b } diff --git a/gcc/testsuite/gdc.test/compilable/commontype.d b/gcc/testsuite/gdc.test/compilable/commontype.d index abe956c..a980ace 100644 --- a/gcc/testsuite/gdc.test/compilable/commontype.d +++ b/gcc/testsuite/gdc.test/compilable/commontype.d @@ -117,18 +117,18 @@ static assert(is( X!( Ei, Ei ) == Ei )); static assert(is( X!( Ei, const(Ei) ) == const(Ei) )); static assert(is( X!( Ei, immutable(Ei) ) == const(Ei) )); static assert(is( X!( Eb, Eb ) == Eb )); -static assert(is( X!( Eb, const(Eb) ) == int )); -static assert(is( X!( Eb, immutable(Eb) ) == int )); +static assert(is( X!( Eb, const(Eb) ) == const(Eb) )); +static assert(is( X!( Eb, immutable(Eb) ) == const(Eb) )); static assert(is( X!( Ei, Eb ) == int )); static assert(is( X!( Ei, const(Eb) ) == int )); static assert(is( X!( Ei, immutable(Eb) ) == int )); static assert(is( X!( Ec, Ec ) == Ec )); -static assert(is( X!( Ec, const(Ec) ) == const(char) )); -static assert(is( X!( Ec, immutable(Ec) ) == const(char) )); +static assert(is( X!( Ec, const(Ec) ) == const(Ec) )); +static assert(is( X!( Ec, immutable(Ec) ) == const(Ec) )); static assert(is( X!( Ew, Ew ) == Ew )); -static assert(is( X!( Ew, const(Ew) ) == const(wchar) )); -static assert(is( X!( Ew, immutable(Ew) ) == const(wchar) )); +static assert(is( X!( Ew, const(Ew) ) == const(Ew) )); +static assert(is( X!( Ew, immutable(Ew) ) == const(Ew) )); static assert(is( X!( Ew, Ec ) == dchar )); static assert(is( X!( Ew, const(Ec) ) == dchar )); static assert(is( X!( Ew, immutable(Ec) ) == dchar )); diff --git a/gcc/testsuite/gdc.test/compilable/imports/pkg20008/package.d b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/package.d new file mode 100644 index 0000000..ecd1568 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/package.d @@ -0,0 +1,9 @@ +module pkg20008; + +import pkg20008.submod; + +enum T2 { y } +enum T3 { z } + +static assert([__traits(allMembers, pkg20008)] == ["object", "pkg20008", "T2", "T3"]); +static assert([__traits(allMembers, pkg20008.submod)] == ["object", "T1"]); diff --git a/gcc/testsuite/gdc.test/compilable/imports/pkg20008/submod.d b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/submod.d new file mode 100644 index 0000000..a38a5e8 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/submod.d @@ -0,0 +1,2 @@ +module pkg20008.submod; +enum T1 { x } diff --git a/gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/package.d b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/package.d new file mode 100644 index 0000000..cf3e4df --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/package.d @@ -0,0 +1,7 @@ +module pkg20008.subpkg; + +import pkg20008.subpkg.subsubmod; + +enum T9 { x } + +static assert([__traits(allMembers, pkg20008.subpkg)] == ["object", "pkg20008", "T9"]); diff --git a/gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/subsubmod.d b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/subsubmod.d new file mode 100644 index 0000000..69a416a --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/pkg20008/subpkg/subsubmod.d @@ -0,0 +1,9 @@ +module pkg20008.subpkg.subsubmod; + +import pkg20008.subpkg; +import pkg20008.subpkg.subsubmod; + +enum T8 { x } + +static assert([__traits(allMembers, pkg20008.subpkg)] == ["object", "pkg20008", "T9"]); +static assert([__traits(allMembers, pkg20008.subpkg.subsubmod)] == ["object", "pkg20008", "T8"]); diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9692b.d b/gcc/testsuite/gdc.test/compilable/imports/test9692b.d index 25be84b..dab7a98 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9692b.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9692b.d @@ -1,2 +1,2 @@ module imports.test9692b; -int j; +int k; diff --git a/gcc/testsuite/gdc.test/compilable/issue24018.d b/gcc/testsuite/gdc.test/compilable/issue24018.d new file mode 100644 index 0000000..559710c --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue24018.d @@ -0,0 +1,10 @@ +struct S +{ + @disable this(); +} + +void main() +{ + S[] s; + s = s ~ s; +} diff --git a/gcc/testsuite/gdc.test/compilable/stc_traits.d b/gcc/testsuite/gdc.test/compilable/stc_traits.d index c5c4e5f..71d1731 100644 --- a/gcc/testsuite/gdc.test/compilable/stc_traits.d +++ b/gcc/testsuite/gdc.test/compilable/stc_traits.d @@ -2,59 +2,59 @@ /* TEST_OUTPUT: --- -100 tuple() -101 tuple("return", "ref") -102 tuple("ref") -103 tuple() -104 tuple("ref") -105 tuple() -106 tuple() -107 tuple("ref") -108 tuple("ref") -109 tuple("ref") -110 tuple("ref") -111 tuple() -112 tuple("ref") -113 tuple("ref") -114 tuple("ref") -115 tuple("ref") -116 tuple() -117 tuple("ref") -118 tuple("ref") -119 tuple() -120 tuple("ref") -121 tuple() -122 tuple("ref") -123 tuple("in") -124 tuple("in") -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("return", "ref") -m-mixin tuple("return", "ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple() -m-mixin tuple() -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("ref") -m-mixin tuple("ref") -m tuple("in") -m-mixin tuple("in") +100 AliasSeq!() +101 AliasSeq!("return", "ref") +102 AliasSeq!("ref") +103 AliasSeq!() +104 AliasSeq!("ref") +105 AliasSeq!() +106 AliasSeq!() +107 AliasSeq!("ref") +108 AliasSeq!("ref") +109 AliasSeq!("ref") +110 AliasSeq!("ref") +111 AliasSeq!() +112 AliasSeq!("ref") +113 AliasSeq!("ref") +114 AliasSeq!("ref") +115 AliasSeq!("ref") +116 AliasSeq!() +117 AliasSeq!("ref") +118 AliasSeq!("ref") +119 AliasSeq!() +120 AliasSeq!("ref") +121 AliasSeq!() +122 AliasSeq!("ref") +123 AliasSeq!("in") +124 AliasSeq!("in") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("return", "ref") +m-mixin AliasSeq!("return", "ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!() +m-mixin AliasSeq!() +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("ref") +m-mixin AliasSeq!("ref") +m AliasSeq!("in") +m-mixin AliasSeq!("in") --- */ diff --git a/gcc/testsuite/gdc.test/compilable/test13668.d b/gcc/testsuite/gdc.test/compilable/test13668.d index d69c764..2cf758c 100644 --- a/gcc/testsuite/gdc.test/compilable/test13668.d +++ b/gcc/testsuite/gdc.test/compilable/test13668.d @@ -3,7 +3,7 @@ /* TEST_OUTPUT: --- -tuple("id", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory") +AliasSeq!("id", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory") genProps --- */ diff --git a/gcc/testsuite/gdc.test/compilable/test16635.d b/gcc/testsuite/gdc.test/compilable/test16635.d index 5f3d0ba..dcdd35b 100644 --- a/gcc/testsuite/gdc.test/compilable/test16635.d +++ b/gcc/testsuite/gdc.test/compilable/test16635.d @@ -39,7 +39,7 @@ void test16635_1() Vector2 b = Vector2(3, 4); // this line causes application to run infinitely - // Already fixed. It was issue 16621 + // Already fixed. It was https://issues.dlang.org/show_bug.cgi?id=16621 Vector2 c = a + b; // OK <- this line seg faults without the above line diff --git a/gcc/testsuite/gdc.test/compilable/test17143.d b/gcc/testsuite/gdc.test/compilable/test17143.d index 4ec0295..272d659 100644 --- a/gcc/testsuite/gdc.test/compilable/test17143.d +++ b/gcc/testsuite/gdc.test/compilable/test17143.d @@ -13,4 +13,4 @@ Tuple!T tuple(T...)(T args) enum foo = tuple(1, 2).expand; static assert(typeof(foo).stringof == "(int, int)"); -static assert(foo.stringof == "tuple(1, 2)"); +static assert(foo.stringof == "AliasSeq!(1, 2)"); diff --git a/gcc/testsuite/gdc.test/compilable/test17373.d b/gcc/testsuite/gdc.test/compilable/test17373.d index 9a5ee64..1f83f51 100644 --- a/gcc/testsuite/gdc.test/compilable/test17373.d +++ b/gcc/testsuite/gdc.test/compilable/test17373.d @@ -28,5 +28,5 @@ interface ConnectionStream : Stream void close(); } -static assert(__traits(getOverloads, ConnectionStream, "connected").stringof == "tuple(connected)"); -static assert(__traits(getOverloads, ConnectionStream, "close").stringof == "tuple(close)"); +static assert(__traits(getOverloads, ConnectionStream, "connected").stringof == "AliasSeq!(connected)"); +static assert(__traits(getOverloads, ConnectionStream, "close").stringof == "AliasSeq!(close)"); diff --git a/gcc/testsuite/gdc.test/compilable/test17545.d b/gcc/testsuite/gdc.test/compilable/test17545.d index 6285418..d1ba7cd 100644 --- a/gcc/testsuite/gdc.test/compilable/test17545.d +++ b/gcc/testsuite/gdc.test/compilable/test17545.d @@ -1,6 +1,6 @@ /* TEST_OUTPUT: --- -tuple((Attrib)) +AliasSeq!((Attrib)) --- */ diff --git a/gcc/testsuite/gdc.test/compilable/test19728.d b/gcc/testsuite/gdc.test/compilable/test19728.d index 551ac0f..73ed9c4 100644 --- a/gcc/testsuite/gdc.test/compilable/test19728.d +++ b/gcc/testsuite/gdc.test/compilable/test19728.d @@ -1,13 +1,13 @@ /* TEST_OUTPUT: --- -tuple((A), (B)) -tuple((A), (B), 0) -tuple((A), (B), (A)) -tuple((A), (B), (A), (B)) -tuple((A), (B), (A), (B)) -tuple((A), (B), (A), (B), (A), (B), (A), (B)) -tuple((Attr)) +AliasSeq!((A), (B)) +AliasSeq!((A), (B), 0) +AliasSeq!((A), (B), (A)) +AliasSeq!((A), (B), (A), (B)) +AliasSeq!((A), (B), (A), (B)) +AliasSeq!((A), (B), (A), (B), (A), (B), (A), (B)) +AliasSeq!((Attr)) --- */ diff --git a/gcc/testsuite/gdc.test/compilable/test20008.d b/gcc/testsuite/gdc.test/compilable/test20008.d new file mode 100644 index 0000000..5a37248 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test20008.d @@ -0,0 +1,6 @@ +/* +REQUIRED_ARGS: -Icompilable/imports -c -o- +EXTRA_FILES: imports/pkg20008/package.d imports/pkg20008/submod.d imports/pkg20008/subpkg/package.d imports/pkg20008/subpkg/subsubmod.d +*/ +import pkg20008; +import pkg20008.subpkg; diff --git a/gcc/testsuite/gdc.test/compilable/test21282.d b/gcc/testsuite/gdc.test/compilable/test21282.d index 761a6a6..276591f 100644 --- a/gcc/testsuite/gdc.test/compilable/test21282.d +++ b/gcc/testsuite/gdc.test/compilable/test21282.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -tuple(func) +AliasSeq!(func) --- */ // https://issues.dlang.org/show_bug.cgi?id=21282 diff --git a/gcc/testsuite/gdc.test/compilable/test21330.d b/gcc/testsuite/gdc.test/compilable/test21330.d index 4abf367..66f9e29 100644 --- a/gcc/testsuite/gdc.test/compilable/test21330.d +++ b/gcc/testsuite/gdc.test/compilable/test21330.d @@ -2,8 +2,8 @@ REQUIRED_ARGS: -unittest TEST_OUTPUT: --- -tuple(__unittest_L14_C5_1, __unittest_L14_C5_2) -tuple(__unittest_L14_C5_2) +AliasSeq!(__unittest_L14_C5_1, __unittest_L14_C5_2) +AliasSeq!(__unittest_L14_C5_2) --- */ // https://issues.dlang.org/show_bug.cgi?id=21330 diff --git a/gcc/testsuite/gdc.test/compilable/test23965.d b/gcc/testsuite/gdc.test/compilable/test23965.d new file mode 100644 index 0000000..36e4e42 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23965.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=23965 +// REQUIRED_ARGS: -de +deprecated: + +struct S {} + +void fun() +{ + S[] arr; + arr ~= S(); +} diff --git a/gcc/testsuite/gdc.test/compilable/test23978.d b/gcc/testsuite/gdc.test/compilable/test23978.d new file mode 100644 index 0000000..cc30f72 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23978.d @@ -0,0 +1,30 @@ +// REQUIRED_ARGS: -preview=dip1021 -lowmem +// https://issues.dlang.org/show_bug.cgi?id=23978 + +// Note: this is a memory corruption bug. +// Memory returned by `GC.realloc` retains references to old memory in it, +// mostly because of the smallarray optimization for `Array(T)`. +// If this fails again, it might not be consistent, so try running it multiple times. + +class LUBench { } +void lup(ulong , ulong , int , int = 1) +{ + new LUBench; +} +void lup_3200(ulong iters, ulong flops) +{ + lup(iters, flops, 3200); +} +void raytrace() +{ + struct V + { + float x, y, z; + auto normalize() { } + struct Tid { } + auto spawnLinked() { } + string[] namesByTid; + class MessageBox { } + auto cross() { } + } +} diff --git a/gcc/testsuite/gdc.test/compilable/test23979.d b/gcc/testsuite/gdc.test/compilable/test23979.d new file mode 100644 index 0000000..f7eb2c5 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23979.d @@ -0,0 +1,17 @@ +// REQUIRED_ARGS: -o- +// https://issues.dlang.org/show_bug.cgi?id=23979 +// Issue 23979 - ICE on failed alias this attempt on pointer expression + +class A {} + +void h() +{ + const auto classPtr = SPtr.init; + assert(!__traits(compiles, *classPtr)); +} + +struct SPtr +{ + A ptr() { return A.init; } + alias ptr this; +} diff --git a/gcc/testsuite/gdc.test/compilable/test23986.d b/gcc/testsuite/gdc.test/compilable/test23986.d new file mode 100644 index 0000000..6bbf1c2 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23986.d @@ -0,0 +1,11 @@ +// REQUIRED_ARGS: -preview=dip1021 -o- +// https://issues.dlang.org/show_bug.cgi?id=23986 +// dip1021 asserts on `typeof(null)` parameter +@safe: + +void f(typeof(null) obj, int* x) {} + +void g() +{ + f(null, null); +} diff --git a/gcc/testsuite/gdc.test/compilable/test24013.d b/gcc/testsuite/gdc.test/compilable/test24013.d new file mode 100644 index 0000000..132ada6 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test24013.d @@ -0,0 +1,43 @@ +// https://issues.dlang.org/show_bug.cgi?id=24013 + +struct PropDescriptor(T) +{ + void define(T delegate() aGetter, string aName) {} +} + +enum Get; + +mixin template PropertyPublisherImpl() +{ + void collectPublicationsFromPairs(T)() + { + foreach (member; __traits(derivedMembers, T)) + foreach (overload; __traits(getOverloads, T, member)) + { + alias Attributes = __traits(getAttributes, overload); + static if (Attributes.length != 0) + { + auto descriptor = new PropDescriptor!size_t; + auto dg = &overload; + descriptor.define(dg, member); + } + } + } +} + +void main() +{ + class Bar + { + size_t _field; + mixin PropertyPublisherImpl; + this() + { + collectPublicationsFromPairs!Bar; + } + @Get size_t field() + { + return _field; + } + } +} diff --git a/gcc/testsuite/gdc.test/compilable/test24017.d b/gcc/testsuite/gdc.test/compilable/test24017.d new file mode 100644 index 0000000..0d03978 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test24017.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=24017 + +// REQUIRED_ARGS: -debug + +void writeln(string) {} + +void main() nothrow +{ + debug writeln("Hello"); + debug "Hello".writeln; +} diff --git a/gcc/testsuite/gdc.test/compilable/test9692.d b/gcc/testsuite/gdc.test/compilable/test9692.d index 57131b8..cb5da6a 100644 --- a/gcc/testsuite/gdc.test/compilable/test9692.d +++ b/gcc/testsuite/gdc.test/compilable/test9692.d @@ -4,5 +4,5 @@ module test9692; import test9692a; import imports.test9692b; -enum x = [__traits(allMembers, imports.test9692b)]; // ok -enum y = [__traits(allMembers, test9692a)]; // ng: should work +static assert([__traits(allMembers, imports.test9692b)] == ["object", "k"]); // ok +static assert([__traits(allMembers, test9692a)] == ["object", "j"]); // ng: should work diff --git a/gcc/testsuite/gdc.test/compilable/testInference.d b/gcc/testsuite/gdc.test/compilable/testInference.d index 31b1049..bddbaf42 100644 --- a/gcc/testsuite/gdc.test/compilable/testInference.d +++ b/gcc/testsuite/gdc.test/compilable/testInference.d @@ -171,9 +171,9 @@ template map7017(fun...) if (fun.length >= 1) auto map7017() { struct Result { - this(int dummy){} // impure member function -> inferred to pure by fixing issue 10329 + this(int dummy){} // impure member function -> inferred to pure by fixing https://issues.dlang.org/show_bug.cgi?id=10329 } - return Result(0); // impure call -> inferred to pure by fixing issue 10329 + return Result(0); // impure call -> inferred to pure by fixing https://issues.dlang.org/show_bug.cgi?id=10329 } } @@ -588,7 +588,7 @@ auto fb10148(T)() static assert(is(typeof(&fc) == void delegate())); fa10148(); } - // [1] this is now inferred to @safe by implementing issue 7511 + // [1] this is now inferred to @safe by implementing https://issues.dlang.org/show_bug.cgi?id=7511 this(S a) {} } diff --git a/gcc/testsuite/gdc.test/fail_compilation/callconst.d b/gcc/testsuite/gdc.test/fail_compilation/callconst.d new file mode 100644 index 0000000..74c1902 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/callconst.d @@ -0,0 +1,16 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/callconst.d(13): Error: function `callconst.func(ref X)` is not callable using argument types `(const(X))` +fail_compilation/callconst.d(13): cannot pass argument `x` of type `const(X)` to parameter `ref X` +--- +*/ +struct X {} + +void main() +{ + auto x = const X(); + func(x); +} + +void func(ref X); diff --git a/gcc/testsuite/gdc.test/fail_compilation/casttuple.d b/gcc/testsuite/gdc.test/fail_compilation/casttuple.d index d08de08b5..89e5f3d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/casttuple.d +++ b/gcc/testsuite/gdc.test/fail_compilation/casttuple.d @@ -1,9 +1,9 @@ /* TEST_OUTPUT: --- -fail_compilation/casttuple.d(104): Error: cannot cast `__tup1_field_0` of type `int` to tuple type `(string)` -fail_compilation/casttuple.d(107): Error: cannot cast `tuple(__tup2_field_0, __tup2_field_1)` of type `(int, int)` to tuple type `(string, string)` -fail_compilation/casttuple.d(111): Error: cannot cast `tuple(foo, 123)` of type `(int, int)` to tuple type `(string, string)` +fail_compilation/casttuple.d(104): Error: cannot cast `__tup1_field_0` of type `int` to type sequence `(string)` +fail_compilation/casttuple.d(107): Error: cannot cast `AliasSeq!(__tup2_field_0, __tup2_field_1)` of type `(int, int)` to type sequence `(string, string)` +fail_compilation/casttuple.d(111): Error: cannot cast `AliasSeq!(foo, 123)` of type `(int, int)` to type sequence `(string, string)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/cppmangle.d b/gcc/testsuite/gdc.test/fail_compilation/cppmangle.d index 8134afb..b3c89b4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/cppmangle.d +++ b/gcc/testsuite/gdc.test/fail_compilation/cppmangle.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/cppmangle.d(11): Error: expected valid identifier for C++ namespace but got `` fail_compilation/cppmangle.d(15): Error: expected valid identifier for C++ namespace but got `0num` -fail_compilation/cppmangle.d(19): Error: compile time string constant (or tuple) expected, not `2` +fail_compilation/cppmangle.d(19): Error: compile time string constant (or sequence) expected, not `2` fail_compilation/cppmangle.d(23): Error: expected valid identifier for C++ namespace but got `invalid@namespace` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/dassert.d b/gcc/testsuite/gdc.test/fail_compilation/dassert.d index 8a81317..c18a28d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/dassert.d +++ b/gcc/testsuite/gdc.test/fail_compilation/dassert.d @@ -2,7 +2,7 @@ REQUIRED_ARGS: -checkaction=context TEST_OUTPUT: --- -fail_compilation/dassert.d(14): Error: expression `tuple(0, 0)` of type `(int, int)` does not have a boolean value +fail_compilation/dassert.d(14): Error: expression `AliasSeq!(0, 0)` of type `(int, int)` does not have a boolean value fail_compilation/dassert.d(21): Error: assignment cannot be used as a condition, perhaps `==` was meant? fail_compilation/dassert.d(29): Error: assignment cannot be used as a condition, perhaps `==` was meant? fail_compilation/dassert.d(40): Error: expression `issue()` of type `void` does not have a boolean value diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13884.d b/gcc/testsuite/gdc.test/fail_compilation/diag13884.d index fe47c83..14af2c8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag13884.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag13884.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag13884.d(14): Error: functions cannot return a tuple +fail_compilation/diag13884.d(14): Error: functions cannot return a sequence (use `std.typecons.Tuple`) fail_compilation/diag13884.d(21): instantiated from here: `MapResult!((t) => t.tupleof, Foo[])` fail_compilation/diag13884.d(14): instantiated from here: `map!(Foo[])` --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14876.d b/gcc/testsuite/gdc.test/fail_compilation/diag14876.d index 0ca0360..4beea95 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag14876.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag14876.d @@ -8,7 +8,7 @@ fail_compilation/diag14876.d(20): Deprecation: class `diag14876.Dep` is deprecat fail_compilation/diag14876.d(21): Deprecation: class `diag14876.Dep` is deprecated fail_compilation/diag14876.d(22): Deprecation: class `diag14876.Dep` is deprecated fail_compilation/diag14876.d(23): Deprecation: class `diag14876.Dep` is deprecated -fail_compilation/diag14876.d(23): Error: can only slice tuple types, not `diag14876.Dep` +fail_compilation/diag14876.d(23): Error: can only slice type sequences, not `diag14876.Dep` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d b/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d index 21a12ed..02d9558 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d +++ b/gcc/testsuite/gdc.test/fail_compilation/dtor_attributes.d @@ -30,7 +30,7 @@ struct HasDtor ~this() {} } -// The user-defined dtor is overriden by a generated dtor calling both +// The user-defined dtor is overridden by a generated dtor calling both // - HasDtor.~this // - Strict.~this struct Strict diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d index 92e0734..0152cde 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d @@ -1,12 +1,13 @@ /* TEST_OUTPUT: --- -fail_compilation/e15876_1.d(16): Error: valid scope identifiers are `exit`, `failure`, or `success`, not `x` -fail_compilation/e15876_1.d(17): Error: found `End of File` when expecting `)` -fail_compilation/e15876_1.d(17): Error: found `End of File` instead of statement -fail_compilation/e15876_1.d(17): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/e15876_1.d(17): Error: found `End of File` when expecting `]` -fail_compilation/e15876_1.d(17): Error: no identifier for declarator `o[() +fail_compilation/e15876_1.d(17): Error: valid scope identifiers are `exit`, `failure`, or `success`, not `x` +fail_compilation/e15876_1.d(18): Error: found `End of File` when expecting `)` +fail_compilation/e15876_1.d(18): Error: found `End of File` instead of statement +fail_compilation/e15876_1.d(18): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/e15876_1.d(17): unmatched `{` +fail_compilation/e15876_1.d(18): Error: found `End of File` when expecting `]` +fail_compilation/e15876_1.d(18): Error: no identifier for declarator `o[() { scope(exit) __error__ } diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_2.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_2.d index 10ff7d5..92164a4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/e15876_2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_2.d @@ -1,10 +1,11 @@ /* TEST_OUTPUT: --- -fail_compilation/e15876_2.d(15): Error: identifier expected following `template` -fail_compilation/e15876_2.d(15): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/e15876_2.d(15): Error: found `End of File` when expecting `]` -fail_compilation/e15876_2.d(15): Error: no identifier for declarator `o[() +fail_compilation/e15876_2.d(16): Error: identifier expected following `template` +fail_compilation/e15876_2.d(16): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/e15876_2.d(15): unmatched `{` +fail_compilation/e15876_2.d(16): Error: found `End of File` when expecting `]` +fail_compilation/e15876_2.d(16): Error: no identifier for declarator `o[() { ; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d index 0ac7229..0482e87 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d @@ -1,18 +1,19 @@ /* TEST_OUTPUT: --- -fail_compilation/e15876_3.d(27): Error: unexpected `(` in declarator -fail_compilation/e15876_3.d(27): Error: basic type expected, not `=` -fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `(` -fail_compilation/e15876_3.d(28): Error: found `End of File` instead of statement -fail_compilation/e15876_3.d(28): Error: expression expected, not `End of File` -fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `;` following `for` condition -fail_compilation/e15876_3.d(28): Error: expression expected, not `End of File` -fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `)` -fail_compilation/e15876_3.d(28): Error: found `End of File` instead of statement -fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `)` -fail_compilation/e15876_3.d(28): Error: no identifier for declarator `d(_error_ = () +fail_compilation/e15876_3.d(28): Error: unexpected `(` in declarator +fail_compilation/e15876_3.d(28): Error: basic type expected, not `=` +fail_compilation/e15876_3.d(29): Error: found `End of File` when expecting `(` +fail_compilation/e15876_3.d(29): Error: found `End of File` instead of statement +fail_compilation/e15876_3.d(29): Error: expression expected, not `End of File` +fail_compilation/e15876_3.d(29): Error: found `End of File` when expecting `;` following `for` condition +fail_compilation/e15876_3.d(29): Error: expression expected, not `End of File` +fail_compilation/e15876_3.d(29): Error: found `End of File` when expecting `)` +fail_compilation/e15876_3.d(29): Error: found `End of File` instead of statement +fail_compilation/e15876_3.d(29): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/e15876_3.d(28): unmatched `{` +fail_compilation/e15876_3.d(29): Error: found `End of File` when expecting `)` +fail_compilation/e15876_3.d(29): Error: no identifier for declarator `d(_error_ = () { for (__error__ 0; 0) @@ -21,7 +22,7 @@ __error__ } } )` -fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration, not `End of File` +fail_compilation/e15876_3.d(29): Error: semicolon expected following function declaration, not `End of File` --- */ d(={for diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d index f4bd407..e5c3bbf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d +++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d @@ -1,17 +1,18 @@ /* TEST_OUTPUT: --- -fail_compilation/e15876_4.d(25): Error: found `)` when expecting `(` -fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `(` -fail_compilation/e15876_4.d(26): Error: found `End of File` instead of statement -fail_compilation/e15876_4.d(26): Error: expression expected, not `End of File` -fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `;` following `for` condition -fail_compilation/e15876_4.d(26): Error: expression expected, not `End of File` -fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `)` -fail_compilation/e15876_4.d(26): Error: found `End of File` instead of statement -fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `)` -fail_compilation/e15876_4.d(26): Error: no identifier for declarator `typeof(() +fail_compilation/e15876_4.d(26): Error: found `)` when expecting `(` +fail_compilation/e15876_4.d(27): Error: found `End of File` when expecting `(` +fail_compilation/e15876_4.d(27): Error: found `End of File` instead of statement +fail_compilation/e15876_4.d(27): Error: expression expected, not `End of File` +fail_compilation/e15876_4.d(27): Error: found `End of File` when expecting `;` following `for` condition +fail_compilation/e15876_4.d(27): Error: expression expected, not `End of File` +fail_compilation/e15876_4.d(27): Error: found `End of File` when expecting `)` +fail_compilation/e15876_4.d(27): Error: found `End of File` instead of statement +fail_compilation/e15876_4.d(27): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/e15876_4.d(26): unmatched `{` +fail_compilation/e15876_4.d(27): Error: found `End of File` when expecting `)` +fail_compilation/e15876_4.d(27): Error: no identifier for declarator `typeof(() { for (__error__ 0; 0) diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_5.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_5.d index 96b23e2..6bebc29 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/e15876_5.d +++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_5.d @@ -1,11 +1,12 @@ /* TEST_OUTPUT: --- -fail_compilation/e15876_5.d(16): Error: basic type expected, not `End of File` -fail_compilation/e15876_5.d(16): Error: semicolon expected to close `alias` declaration, not `End of File` -fail_compilation/e15876_5.d(16): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/e15876_5.d(16): Error: found `End of File` when expecting `]` -fail_compilation/e15876_5.d(16): Error: no identifier for declarator `p[() +fail_compilation/e15876_5.d(17): Error: basic type expected, not `End of File` +fail_compilation/e15876_5.d(17): Error: semicolon expected to close `alias` declaration, not `End of File` +fail_compilation/e15876_5.d(17): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/e15876_5.d(16): unmatched `{` +fail_compilation/e15876_5.d(17): Error: found `End of File` when expecting `]` +fail_compilation/e15876_5.d(17): Error: no identifier for declarator `p[() { alias ; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/enum_init.d b/gcc/testsuite/gdc.test/fail_compilation/enum_init.d index 8344a47..c968f5e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/enum_init.d +++ b/gcc/testsuite/gdc.test/fail_compilation/enum_init.d @@ -58,6 +58,8 @@ TEST_OUTPUT: --- fail_compilation/enum_init.d(306): Error: variable `enum_init.fooOB.ob` - no definition of struct `S` fail_compilation/enum_init.d(302): required by type `OpaqueBase` +fail_compilation/enum_init.d(306): see https://dlang.org/spec/struct.html#opaque_struct_unions +fail_compilation/enum_init.d(306): perhaps declare a variable with pointer type `OpaqueBase*` instead --- */ #line 300 diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12436.d b/gcc/testsuite/gdc.test/fail_compilation/fail12436.d index 5bdf0d5..415e362 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12436.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail12436.d @@ -12,7 +12,7 @@ alias Tuple!(int, int) TupleType; TEST_OUTPUT: --- fail_compilation/fail12436.d(18): Error: functions cannot return a function -fail_compilation/fail12436.d(19): Error: functions cannot return a tuple +fail_compilation/fail12436.d(19): Error: functions cannot return a sequence (use `std.typecons.Tuple`) --- */ FuncType test1(); diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15755.d b/gcc/testsuite/gdc.test/fail_compilation/fail15755.d index 8fd2b51..502eedc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail15755.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail15755.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail15755.d(28): Error: `tuple(123)` has no effect +fail_compilation/fail15755.d(28): Error: `AliasSeq!(123)` has no effect --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16772.d b/gcc/testsuite/gdc.test/fail_compilation/fail16772.d index e77951d3..0bc9751 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail16772.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail16772.d @@ -1,7 +1,8 @@ // https://issues.dlang.org/show_bug.cgi?id=16772 /* TEST_OUTPUT: --- -fail_compilation/fail16772.d(7): Error: function `fail16772.ice16772` cannot return type `ubyte[]` because its linkage is `extern(C++)` +fail_compilation/fail16772.d(8): Error: function `fail16772.ice16772` cannot return type `ubyte[]` because its linkage is `extern(C++)` +fail_compilation/fail16772.d(8): slices are specific to D and do not have a counterpart representation in C++ --- */ extern(C++) ubyte[] ice16772() { return []; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19209.d b/gcc/testsuite/gdc.test/fail_compilation/fail19209.d index ceede5e..56b8581 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19209.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19209.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/fail19209.d(16): Error: function `fail19209.Spammer.method()` does not override any function, did you mean to override variable `fail19209.Spam.method`? -fail_compilation/fail19209.d(16): Functions are the only declarations that may be overriden +fail_compilation/fail19209.d(16): Functions are the only declarations that may be overridden --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail196.d b/gcc/testsuite/gdc.test/fail_compilation/fail196.d index 53505f4..cdad5c4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail196.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail196.d @@ -1,24 +1,26 @@ /* TEST_OUTPUT: --- -fail_compilation/fail196.d(27): Error: delimited string must end in `)"` -fail_compilation/fail196.d(27): Error: implicit string concatenation is error-prone and disallowed in D -fail_compilation/fail196.d(27): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\n assert(s == " -fail_compilation/fail196.d(28): Error: semicolon needed to end declaration of `s`, instead of `foo` -fail_compilation/fail196.d(27): `s` declared here -fail_compilation/fail196.d(28): Error: found `");\n\n s = q"` when expecting `;` following statement `foo(xxx)` on line fail_compilation/fail196.d(28) -fail_compilation/fail196.d(30): Error: found `";\n assert(s == "` when expecting `;` following statement `[foo[xxx]]` on line fail_compilation/fail196.d(30) -fail_compilation/fail196.d(31): Error: found `");\n\n s = q"` when expecting `;` following statement `foo[xxx]` on line fail_compilation/fail196.d(31) -fail_compilation/fail196.d(33): Error: found `{` when expecting `;` following statement `foo` on line fail_compilation/fail196.d(33) -fail_compilation/fail196.d(33): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(33) -fail_compilation/fail196.d(34): Error: found `foo` when expecting `;` following statement `";\n assert(s == "` on line fail_compilation/fail196.d(33) -fail_compilation/fail196.d(34): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(34) -fail_compilation/fail196.d(36): Error: found `<` when expecting `;` following statement `");\n\n s = q" < foo` on line fail_compilation/fail196.d(34) -fail_compilation/fail196.d(37): Error: found `foo` when expecting `;` following statement `xxx >> ";\n assert(s == "` on line fail_compilation/fail196.d(36) -fail_compilation/fail196.d(37): Error: found `<` instead of statement -fail_compilation/fail196.d(43): Error: unterminated string constant starting at fail_compilation/fail196.d(43) -fail_compilation/fail196.d(45): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/fail196.d(45): Error: found `End of File` when expecting `}` following compound statement +fail_compilation/fail196.d(29): Error: delimited string must end in `)"` +fail_compilation/fail196.d(29): Error: implicit string concatenation is error-prone and disallowed in D +fail_compilation/fail196.d(29): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\n assert(s == " +fail_compilation/fail196.d(30): Error: semicolon needed to end declaration of `s`, instead of `foo` +fail_compilation/fail196.d(29): `s` declared here +fail_compilation/fail196.d(30): Error: found `");\n\n s = q"` when expecting `;` following statement `foo(xxx)` on line fail_compilation/fail196.d(30) +fail_compilation/fail196.d(32): Error: found `";\n assert(s == "` when expecting `;` following statement `[foo[xxx]]` on line fail_compilation/fail196.d(32) +fail_compilation/fail196.d(33): Error: found `");\n\n s = q"` when expecting `;` following statement `foo[xxx]` on line fail_compilation/fail196.d(33) +fail_compilation/fail196.d(35): Error: found `{` when expecting `;` following statement `foo` on line fail_compilation/fail196.d(35) +fail_compilation/fail196.d(35): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(35) +fail_compilation/fail196.d(36): Error: found `foo` when expecting `;` following statement `";\n assert(s == "` on line fail_compilation/fail196.d(35) +fail_compilation/fail196.d(36): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(36) +fail_compilation/fail196.d(38): Error: found `<` when expecting `;` following statement `");\n\n s = q" < foo` on line fail_compilation/fail196.d(36) +fail_compilation/fail196.d(39): Error: found `foo` when expecting `;` following statement `xxx >> ";\n assert(s == "` on line fail_compilation/fail196.d(38) +fail_compilation/fail196.d(39): Error: found `<` instead of statement +fail_compilation/fail196.d(45): Error: unterminated string constant starting at fail_compilation/fail196.d(45) +fail_compilation/fail196.d(47): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/fail196.d(36): unmatched `{` +fail_compilation/fail196.d(47): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/fail196.d(28): unmatched `{` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21206.d b/gcc/testsuite/gdc.test/fail_compilation/fail21206.d index c3d648e..b3b42f3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail21206.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail21206.d @@ -1,7 +1,8 @@ // https://issues.dlang.org/show_bug.cgi?id=21206 /* TEST_OUTPUT: --- -fail_compilation/fail21206.d(9): Error: function `fail21206.Obj.toString` cannot return type `string` because its linkage is `extern(C++)` +fail_compilation/fail21206.d(10): Error: function `fail21206.Obj.toString` cannot return type `string` because its linkage is `extern(C++)` +fail_compilation/fail21206.d(10): slices are specific to D and do not have a counterpart representation in C++ --- */ extern(C++) struct Obj diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21275.d b/gcc/testsuite/gdc.test/fail_compilation/fail21275.d index 69cdf1a..b7bbcfa 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail21275.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail21275.d @@ -1,12 +1,11 @@ // https://issues.dlang.org/show_bug.cgi?id=21275 -// REQUIRED_ARGS: -de // EXTRA_FILES: imports/fail21275a.d /* TEST_OUTPUT: --- -fail_compilation/fail21275.d(18): Deprecation: function `imports.fail21275a.Foo.x` of type `ref int() return` is not accessible from module `fail21275` -fail_compilation/fail21275.d(21): Deprecation: function `imports.fail21275a.Bar.x` of type `int(int)` is not accessible from module `fail21275` +fail_compilation/fail21275.d(17): Error: function `imports.fail21275a.Foo.x` of type `ref int() return` is not accessible from module `fail21275` +fail_compilation/fail21275.d(20): Error: function `imports.fail21275a.Bar.x` of type `int(int)` is not accessible from module `fail21275` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail222.d b/gcc/testsuite/gdc.test/fail_compilation/fail222.d index 30eb014..e196b25 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail222.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail222.d @@ -1,10 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/fail222.d(11): Error: template `fail222.getMixin(TArg..., int i = 0)()` template tuple parameter must be last one +fail_compilation/fail222.d(11): Error: template `fail222.getMixin(TArg..., int i = 0)()` template sequence parameter must be the last one fail_compilation/fail222.d(18): Error: template instance `getMixin!()` does not match template declaration `getMixin(TArg..., int i = 0)()` fail_compilation/fail222.d(21): Error: template instance `fail222.Thing!()` error instantiating -fail_compilation/fail222.d(23): Error: template `fail222.fooBar(A..., B...)()` template tuple parameter must be last one +fail_compilation/fail222.d(23): Error: template `fail222.fooBar(A..., B...)()` template sequence parameter must be the last one --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22729.d b/gcc/testsuite/gdc.test/fail_compilation/fail22729.d new file mode 100644 index 0000000..38bbfee --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22729.d @@ -0,0 +1,39 @@ +// https://issues.dlang.org/show_bug.cgi?id=22729 + +/* +TEST_OUTPUT: +--- +fail_compilation/fail22729.d(12): Error: field `getChildAtPosition` not allowed in interface +--- +*/ + +interface ContainerFunctionSetI +{ + Tuple!(WidgetI) getChildAtPosition; +} + +interface WidgetI : ContainerFunctionSetI +{ +} + +class Form : WidgetI +{ +} + +template Tuple(Specs) +{ + enum areCompatibleTuples(Tup2)(Tuple tup1, Tup2 tup2) + { + tup1.field == tup2; + } + + struct Tuple + { + Specs field; + + bool opEquals(R)(R) if (areCompatibleTuples!R) + { + } + + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23745.d b/gcc/testsuite/gdc.test/fail_compilation/fail23745.d index eda9e1e..46d92f0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail23745.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23745.d @@ -5,7 +5,7 @@ TEST_OUTPUT: --- fail_compilation/fail23745.d(21): Error: undefined identifier `UndefinedType` fail_compilation/fail23745.d(14): Error: function `fun` does not override any function, did you mean to override `fail23745.A.fun`? -fail_compilation/fail23745.d(21): Function `fail23745.A.fun` contains errors in its declaration, therefore it cannot be correctly overriden +fail_compilation/fail23745.d(21): Function `fail23745.A.fun` contains errors in its declaration, therefore it cannot be correctly overridden --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail315.d b/gcc/testsuite/gdc.test/fail_compilation/fail315.d index c7fd78f..1a7e0f3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail315.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail315.d @@ -1,13 +1,14 @@ /* TEST_OUTPUT: --- -fail_compilation/fail315.d-mixin-16(16): Error: found `;` when expecting `,` -fail_compilation/fail315.d-mixin-16(16): Error: expression expected, not `}` -fail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `,` -fail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `]` -fail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `;` following `return` statement -fail_compilation/fail315.d-mixin-16(16): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/fail315.d(21): Error: template instance `fail315.foo!()` error instantiating +fail_compilation/fail315.d-mixin-17(17): Error: found `;` when expecting `,` +fail_compilation/fail315.d-mixin-17(17): Error: expression expected, not `}` +fail_compilation/fail315.d-mixin-17(17): Error: found `End of File` when expecting `,` +fail_compilation/fail315.d-mixin-17(17): Error: found `End of File` when expecting `]` +fail_compilation/fail315.d-mixin-17(17): Error: found `End of File` when expecting `;` following `return` statement +fail_compilation/fail315.d-mixin-17(17): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/fail315.d-mixin-17(17): unmatched `{` +fail_compilation/fail315.d(22): Error: template instance `fail315.foo!()` error instantiating --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/funcpostattr.d b/gcc/testsuite/gdc.test/fail_compilation/funcpostattr.d new file mode 100644 index 0000000..b50db05 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/funcpostattr.d @@ -0,0 +1,21 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/funcpostattr.d(11): Error: `deprecated` token is not allowed in postfix position +fail_compilation/funcpostattr.d(11): Error: `extern` token is not allowed in postfix position +fail_compilation/funcpostattr.d(15): Error: `static` token is not allowed in postfix position +fail_compilation/funcpostattr.d(15): Error: `ref` token is not allowed in postfix position +fail_compilation/funcpostattr.d(20): Error: `override` token is not allowed in postfix position +--- +*/ +void foo() deprecated extern; + +void main() { + int i; + int foo() static ref => i; +} + +class C +{ + void foo() override {} +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11965.d b/gcc/testsuite/gdc.test/fail_compilation/ice11965.d index c8db60f..9e6da3b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice11965.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice11965.d @@ -1,10 +1,11 @@ /* TEST_OUTPUT: --- -fail_compilation/ice11965.d(15): Error: no identifier for declarator `b*` -fail_compilation/ice11965.d(15): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/ice11965.d(15): Error: found `End of File` when expecting `]` -fail_compilation/ice11965.d(15): Error: no identifier for declarator `u[() +fail_compilation/ice11965.d(16): Error: no identifier for declarator `b*` +fail_compilation/ice11965.d(16): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/ice11965.d(15): unmatched `{` +fail_compilation/ice11965.d(16): Error: found `End of File` when expecting `]` +fail_compilation/ice11965.d(16): Error: no identifier for declarator `u[() { b* A; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11982.d b/gcc/testsuite/gdc.test/fail_compilation/ice11982.d index 0f2ce41..0886df6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice11982.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice11982.d @@ -1,19 +1,20 @@ /* TEST_OUTPUT: --- -fail_compilation/ice11982.d(19): Error: basic type expected, not `scope` -fail_compilation/ice11982.d(19): Error: found `scope` when expecting `;` following statement `new _error_` on line fail_compilation/ice11982.d(19) -fail_compilation/ice11982.d(19): Error: basic type expected, not `}` -fail_compilation/ice11982.d(19): Error: missing `{ ... }` for function literal -fail_compilation/ice11982.d(19): Error: C style cast illegal, use `cast(funk)function _error_() +fail_compilation/ice11982.d(20): Error: basic type expected, not `scope` +fail_compilation/ice11982.d(20): Error: found `scope` when expecting `;` following statement `new _error_` on line fail_compilation/ice11982.d(20) +fail_compilation/ice11982.d(20): Error: basic type expected, not `}` +fail_compilation/ice11982.d(20): Error: missing `{ ... }` for function literal +fail_compilation/ice11982.d(20): Error: C style cast illegal, use `cast(funk)function _error_() { } ` -fail_compilation/ice11982.d(19): Error: found `}` when expecting `;` following statement `cast(funk)function _error_() +fail_compilation/ice11982.d(20): Error: found `}` when expecting `;` following statement `cast(funk)function _error_() { } -` on line fail_compilation/ice11982.d(19) -fail_compilation/ice11982.d(20): Error: found `End of File` when expecting `}` following compound statement +` on line fail_compilation/ice11982.d(20) +fail_compilation/ice11982.d(21): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/ice11982.d(20): unmatched `{` --- */ void main() { new scope ( funk ) function } diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice12574.d b/gcc/testsuite/gdc.test/fail_compilation/ice12574.d index 93e5f1d..ecb0fd6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice12574.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice12574.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/ice12574.d(40): Error: tuple index `2` out of bounds `[0 .. 2]` +fail_compilation/ice12574.d(40): Error: sequence index `2` out of bounds `[0 .. 2]` fail_compilation/ice12574.d(53): Error: template instance `ice12574.reduce!("a", "a").reduce!(Tuple!(int, int, int))` error instantiating --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14424.d b/gcc/testsuite/gdc.test/fail_compilation/ice14424.d index c99522d..b0e0cd6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice14424.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice14424.d @@ -3,7 +3,7 @@ /* TEST_OUTPUT: --- -fail_compilation/ice14424.d(13): Error: `tuple(__unittest_L3_C1)` has no effect +fail_compilation/ice14424.d(13): Error: `AliasSeq!(__unittest_L3_C1)` has no effect --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice15855.d b/gcc/testsuite/gdc.test/fail_compilation/ice15855.d index b26fe4c..f7ad390 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice15855.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice15855.d @@ -2,16 +2,17 @@ /* TEST_OUTPUT: --- -fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `(` -fail_compilation/ice15855.d(27): Error: found `End of File` instead of statement -fail_compilation/ice15855.d(27): Error: expression expected, not `End of File` -fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `;` following `for` condition -fail_compilation/ice15855.d(27): Error: expression expected, not `End of File` -fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `)` -fail_compilation/ice15855.d(27): Error: found `End of File` instead of statement -fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `}` following compound statement -fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `]` -fail_compilation/ice15855.d(27): Error: no identifier for declarator `a[() +fail_compilation/ice15855.d(28): Error: found `End of File` when expecting `(` +fail_compilation/ice15855.d(28): Error: found `End of File` instead of statement +fail_compilation/ice15855.d(28): Error: expression expected, not `End of File` +fail_compilation/ice15855.d(28): Error: found `End of File` when expecting `;` following `for` condition +fail_compilation/ice15855.d(28): Error: expression expected, not `End of File` +fail_compilation/ice15855.d(28): Error: found `End of File` when expecting `)` +fail_compilation/ice15855.d(28): Error: found `End of File` instead of statement +fail_compilation/ice15855.d(28): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/ice15855.d(27): unmatched `{` +fail_compilation/ice15855.d(28): Error: found `End of File` when expecting `]` +fail_compilation/ice15855.d(28): Error: no identifier for declarator `a[() { for (__error__ 0; 0) diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/issue23947a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/issue23947a.d new file mode 100644 index 0000000..270bf5f --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/issue23947a.d @@ -0,0 +1,8 @@ +module imports.issue23947a; + +struct X { } +struct Y { } +class Class { + private void handle(X x) { } + public void handle(Y y) { } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue20422.d b/gcc/testsuite/gdc.test/fail_compilation/issue20422.d index 1964f8a..9dcab00 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/issue20422.d +++ b/gcc/testsuite/gdc.test/fail_compilation/issue20422.d @@ -1,12 +1,19 @@ // https://issues.dlang.org/show_bug.cgi?id=20422 /* +REQUIRED_ARGS: -m32 TEST_OUTPUT: --- -fail_compilation/issue20422.d(11): Error: missing length argument for array +fail_compilation/issue20422.d(15): Error: missing length argument for array +fail_compilation/issue20422.d(16): Error: negative array dimension `-1` +fail_compilation/issue20422.d(17): Error: negative array dimension `-2147483648` +fail_compilation/issue20422.d(18): Error: too many arguments for array --- */ void main() { new int[]; + new int[-1]; + new int[](int.min); + new int[](1, 2); } diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue23947.d b/gcc/testsuite/gdc.test/fail_compilation/issue23947.d new file mode 100644 index 0000000..d73cd85 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/issue23947.d @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug.cgi?id=23947 +/* +TEST_OUTPUT: +--- +fail_compilation/issue23947.d(10): Error: function `imports.issue23947a.Class.handle` of type `void(X x)` is not accessible from module `issue23947` +--- +*/ +import imports.issue23947a; + +void main() { Class.init.handle(X.init); } diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer4.d b/gcc/testsuite/gdc.test/fail_compilation/lexer4.d index c9db264..c4bdb4f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/lexer4.d +++ b/gcc/testsuite/gdc.test/fail_compilation/lexer4.d @@ -8,7 +8,7 @@ fail_compilation/lexer4.d(26): Error: binary digit expected, not `2` fail_compilation/lexer4.d(27): Error: octal digit expected, not `8` fail_compilation/lexer4.d(27): Error: octal literals larger than 7 are no longer supported fail_compilation/lexer4.d(28): Error: decimal digit expected, not `a` -fail_compilation/lexer4.d(29): Error: unrecognized token +fail_compilation/lexer4.d(29): Error: repeated integer suffix `U` fail_compilation/lexer4.d(30): Error: exponent required for hex float fail_compilation/lexer4.d(31): Error: lower case integer suffix 'l' is not allowed. Please use 'L' instead fail_compilation/lexer4.d(32): Error: use 'i' suffix instead of 'I' diff --git a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d index d136144..a719b12 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d @@ -24,7 +24,8 @@ fail_compilation/misc_parser_err_cov1.d(40): Error: identifier or `new` expected fail_compilation/misc_parser_err_cov1.d(41): Error: identifier or new keyword expected following `(...)`. fail_compilation/misc_parser_err_cov1.d(41): Error: expression expected, not `;` fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following statement `(__error) + 0` on line fail_compilation/misc_parser_err_cov1.d(41) -fail_compilation/misc_parser_err_cov1.d(43): Error: found `End of File` when expecting `}` following compound statement +fail_compilation/misc_parser_err_cov1.d(43): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/misc_parser_err_cov1.d(33): unmatched `{` --- */ module misc_parser_err_cov1; diff --git a/gcc/testsuite/gdc.test/fail_compilation/missingbrace.d b/gcc/testsuite/gdc.test/fail_compilation/missingbrace.d new file mode 100644 index 0000000..5c8166ea --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/missingbrace.d @@ -0,0 +1,10 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/missingbrace.d(11): Error: matching `}` expected following compound statement, not `End of File` +fail_compilation/missingbrace.d(9): unmatched `{` +--- +*/ +void main() +{ + int a; diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d index 50cfdd3..c08747f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d @@ -403,7 +403,7 @@ class Foo13 /* TEST_OUTPUT: --- -fail_compilation/retscope.d(1205): Error: scope variable `f14` calling non-scope member function `f14.foo()` +fail_compilation/retscope.d(1205): Error: scope variable `f14` calling non-scope member function `Foo14.foo()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20245.d b/gcc/testsuite/gdc.test/fail_compilation/test20245.d index 3c43c5c..a6bbba2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test20245.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test20245.d @@ -9,7 +9,7 @@ fail_compilation/test20245.d(27): Error: cannot take address of `scope` variable fail_compilation/test20245.d(33): Error: reference to local variable `x` assigned to non-scope parameter `ptr` calling `escape` fail_compilation/test20245.d(34): Error: copying `&x` into allocated memory escapes a reference to parameter `x` fail_compilation/test20245.d(50): Error: reference to local variable `price` assigned to non-scope `this.minPrice` -fail_compilation/test20245.d(69): Error: reference to local variable `this` calling non-scope member function `this.this()` +fail_compilation/test20245.d(69): Error: reference to local variable `this.content[]` calling non-scope member function `Exception.this()` fail_compilation/test20245.d(89): Error: reference to local variable `this` assigned to non-scope parameter `content` calling `listUp` fail_compilation/test20245.d(82): which is not `scope` because of `charPtr = content` --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21025.d b/gcc/testsuite/gdc.test/fail_compilation/test21025.d new file mode 100644 index 0000000..8564199 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test21025.d @@ -0,0 +1,25 @@ +// https://issues.dlang.org/show_bug.cgi?id=21025 +// REQUIRED_ARGS: -preview=dip1021 + +/* +TEST_OUTPUT: +--- +fail_compilation/test21025.d(15): Error: variable `r` cannot be read at compile time +fail_compilation/test21025.d(15): called from here: `binaryFun(r, r)` +fail_compilation/test21025.d(24): Error: template `test21025.uniq` is not callable using argument types `!()(void[])` +fail_compilation/test21025.d(14): Candidate is: `uniq()(int[] r)` +--- +*/ + +void uniq()(int[] r) +if (binaryFun(r, r)) {} + +bool binaryFun(T, U)(T, U) +{ + return true; +} + +void generateStatements() +{ + uniq([]); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23968.d b/gcc/testsuite/gdc.test/fail_compilation/test23968.d new file mode 100644 index 0000000..4456e75 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23968.d @@ -0,0 +1,23 @@ +// https://issues.dlang.org/show_bug.cgi?id=23968 + +// REQUIRED_ARGS: -de + +/* +TEST_OUTPUT: +--- +fail_compilation/test23968.d(22): Deprecation: alias `test23968.a` is deprecated +--- +*/ + +int fun()(int) +{ + return 0; +} + +deprecated alias a = fun; + +void main() +{ + int v; + int y = v.a!(); // No deprecation? +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23982.d b/gcc/testsuite/gdc.test/fail_compilation/test23982.d new file mode 100644 index 0000000..f8eee23 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23982.d @@ -0,0 +1,36 @@ +/* +REQUIRED_ARGS: -preview=dip1000 +TEST_OUTPUT: +--- +fail_compilation/test23982.d(35): Error: scope variable `a` assigned to non-scope parameter `a` calling `foo2` +fail_compilation/test23982.d(26): which is not `scope` because of `b = a` +--- +*/ +// https://issues.dlang.org/show_bug.cgi?id=23982 +// Issue 23982 - segfault when printing scope inference failure +@safe: + +struct B() +{ + this(int* a) + { + this.a = a; + } + int* a; +} + +class C() +{ + int* foo2(int* a) + { + auto b = B!()(a); + return b.a; + } +} + +void main() +{ + scope int* a; + C!() c; + c.foo2(a); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d index 9d527b7..404a4c0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d +++ b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/typeerrors.d(32): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. -fail_compilation/typeerrors.d(37): Error: tuple index `4` out of bounds `[0 .. 4]` +fail_compilation/typeerrors.d(37): Error: sequence index `4` out of bounds `[0 .. 4]` fail_compilation/typeerrors.d(39): Error: variable `x` cannot be read at compile time fail_compilation/typeerrors.d(40): Error: cannot have array of `void()` fail_compilation/typeerrors.d(41): Error: cannot have array of scope `typeerrors.C` diff --git a/gcc/testsuite/gdc.test/fail_compilation/unmatchedbrace.d b/gcc/testsuite/gdc.test/fail_compilation/unmatchedbrace.d new file mode 100644 index 0000000..30dc3b5 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/unmatchedbrace.d @@ -0,0 +1,10 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/unmatchedbrace.d(11): Error: matching `}` expected, not `End of File` +fail_compilation/unmatchedbrace.d(8): unmatched `{` +--- +*/ +@safe { + // + struct S {} diff --git a/gcc/testsuite/gdc.test/runnable/functype.d b/gcc/testsuite/gdc.test/runnable/functype.d index 5dad618..cdeb418 100644 --- a/gcc/testsuite/gdc.test/runnable/functype.d +++ b/gcc/testsuite/gdc.test/runnable/functype.d @@ -301,7 +301,7 @@ void test10734() void test14656() { - //void unaryFun()(auto int a) pure nothrow @safe @nogc {} // changed to invalid by fixing issue 14669 + //void unaryFun()(auto int a) pure nothrow @safe @nogc {} // changed to invalid by fixing https://issues.dlang.org/show_bug.cgi?id=14669 alias Identity(F) = F; //unaryFun!()(41); static void fun(int n) pure nothrow @safe @nogc {} diff --git a/gcc/testsuite/gdc.test/runnable/interface2.d b/gcc/testsuite/gdc.test/runnable/interface2.d index fabbbfd..603e4b2 100644 --- a/gcc/testsuite/gdc.test/runnable/interface2.d +++ b/gcc/testsuite/gdc.test/runnable/interface2.d @@ -962,11 +962,11 @@ void test1747() assert(pia == pc + n); assert(id.mA() == 1); - assert(id.mB() == 2); // OK <- NG (bugzilla 2013 case) + assert(id.mB() == 2); // OK <- NG (https://issues.dlang.org/show_bug.cgi?id=2013 case) assert(id.mD() == 3); assert(ic.mA() == 1); - assert(ic.mB() == 2); // OK <- NG (bugzilla 2013 case) + assert(ic.mB() == 2); // OK <- NG (https://issues.dlang.org/show_bug.cgi?id=2013 case) assert(ib.mA() == 1); assert(ib.mB() == 2); // OK <- NG diff --git a/gcc/testsuite/gdc.test/runnable/link10425.d b/gcc/testsuite/gdc.test/runnable/link10425.d index d082516..ae135ea 100644 --- a/gcc/testsuite/gdc.test/runnable/link10425.d +++ b/gcc/testsuite/gdc.test/runnable/link10425.d @@ -10,7 +10,7 @@ void main() * the TypeInfo object on comdat section (done by TypeInfoDeclaration::toObjFile), * even if the associated struct belongs *non-root modules*. * - * And, from 2.062, issue 7511 is implemented. + * And, from 2.062, https://issues.dlang.org/show_bug.cgi?id=7511 is implemented. * The attribute inference for member functions in instantiated struct may modify * their actual mangled names. Then TypeInfo object compiled in this module would * use wrong symbol names, to link non-template opEquals/opCmp/toHash/toString diff --git a/gcc/testsuite/gdc.test/runnable/sdtor.d b/gcc/testsuite/gdc.test/runnable/sdtor.d index e6b3238..be15cb2 100644 --- a/gcc/testsuite/gdc.test/runnable/sdtor.d +++ b/gcc/testsuite/gdc.test/runnable/sdtor.d @@ -4814,6 +4814,41 @@ void testPR12012() } /**********************************/ +// https://issues.dlang.org/show_bug.cgi?id=24010 + +alias AliasSeq(TList...) = TList; + +__gshared int x24010 = 7; + +struct A24010 { + int x; + ~this() { + printf("A.~this\n"); + x24010 += 1; + } +} + +struct B24010 { + ~this() { + printf("B.~this\n"); + x24010 *= 10; + } +} + +void test24010() +{ + { + AliasSeq!(A24010, B24010) params; + printf("statement\n"); + params[0].x = 3; + printf(".x = %d\n", params[0].x); + assert(params[0].x == 3); + assert(x24010 == 7); + } + assert(x24010 == 71); +} + +/**********************************/ int main() { @@ -4954,6 +4989,7 @@ int main() test67(); test68(); testPR12012(); + test24010(); printf("Success\n"); return 0; diff --git a/gcc/testsuite/gdc.test/runnable/template9.d b/gcc/testsuite/gdc.test/runnable/template9.d index cb3de5b..dbad3f1 100644 --- a/gcc/testsuite/gdc.test/runnable/template9.d +++ b/gcc/testsuite/gdc.test/runnable/template9.d @@ -4689,7 +4689,8 @@ struct S14604 } alias Id14604(alias thing) = thing; alias c14604 = Id14604!(S14604.opDispatch!"go"); // ok -alias d14604 = Id14604!(S14604.go); // issue 14604, 'Error: template instance opDispatch!"go" cannot resolve forward reference' +// https://issues.dlang.org/show_bug.cgi?id=14604 +alias d14604 = Id14604!(S14604.go); // 'Error: template instance opDispatch!"go" cannot resolve forward reference' /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=14735 diff --git a/gcc/testsuite/gdc.test/runnable/test23959.d b/gcc/testsuite/gdc.test/runnable/test23959.d new file mode 100644 index 0000000..3288373 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test23959.d @@ -0,0 +1,30 @@ +// https://issues.dlang.org/show_bug.cgi?id=23959; + +struct ST() +{ + int i; + this(this) {} +} + +alias S = ST!(); + +void poison() +{ + static S g; + auto s = g; +} + +S[1] sa; + +void fun(S[] values...) +{ + sa[] = values; +} + +int main() +{ + fun(S(1)); + assert(sa[0].i); + + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/testcontracts.d b/gcc/testsuite/gdc.test/runnable/testcontracts.d index e79c6a0..439040b 100644 --- a/gcc/testsuite/gdc.test/runnable/testcontracts.d +++ b/gcc/testsuite/gdc.test/runnable/testcontracts.d @@ -936,7 +936,7 @@ void test9383() /*******************************************/ // https://issues.dlang.org/show_bug.cgi?id=15524 -// Different from issue 9383 cases, closed variable size is bigger than REGSIZE. +// Different from https://issues.dlang.org/show_bug.cgi?id=9383 cases, closed variable size is bigger than REGSIZE. class A15524 { diff --git a/gcc/testsuite/gdc.test/runnable/uda.d b/gcc/testsuite/gdc.test/runnable/uda.d index 1d01098..d4e4c2a 100644 --- a/gcc/testsuite/gdc.test/runnable/uda.d +++ b/gcc/testsuite/gdc.test/runnable/uda.d @@ -2,30 +2,30 @@ EXTRA_FILES: imports/a9741.d TEST_OUTPUT: --- -tuple(3, 4, 7, (SSS)) -tuple(3, 4, 7, (SSS)) +AliasSeq!(3, 4, 7, (SSS)) +AliasSeq!(3, 4, 7, (SSS)) 7 SSS -tuple("hello") -tuple('c') -tuple((FFF)) -tuple(10) -tuple(20) -tuple(30) -tuple((Test6)) -tuple(Test7(3, "foo")) -tuple((Test8!"foo")) -tuple((Test9!"foo")) -tuple(Test10(3)) -tuple(Test11(3)) -tuple(10) -tuple(20) -tuple() -tuple(40) +AliasSeq!("hello") +AliasSeq!('c') +AliasSeq!((FFF)) +AliasSeq!(10) +AliasSeq!(20) +AliasSeq!(30) +AliasSeq!((Test6)) +AliasSeq!(Test7(3, "foo")) +AliasSeq!((Test8!"foo")) +AliasSeq!((Test9!"foo")) +AliasSeq!(Test10(3)) +AliasSeq!(Test11(3)) +AliasSeq!(10) +AliasSeq!(20) +AliasSeq!() +AliasSeq!(40) B9741 -tuple((A9741)) -tuple(1) -tuple(2) +AliasSeq!((A9741)) +AliasSeq!(1) +AliasSeq!(2) --- RUN_OUTPUT: diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d index 5017a76..972de90 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest46.d +++ b/gcc/testsuite/gdc.test/runnable/xtest46.d @@ -13,17 +13,17 @@ runnable/xtest46.d(2964): Deprecation: alias this for classes/interfaces is depr int(int i, long j = 7L) long C10390(C10390(C10390())) -tuple(height) -tuple(get, get) -tuple(clear) -tuple(draw, draw) +AliasSeq!(height) +AliasSeq!(get, get) +AliasSeq!(clear) +AliasSeq!(draw, draw) const(int) string[] double[] double[] {} runnable/xtest46.d(4670): Deprecation: alias this for classes/interfaces is deprecated -tuple("m") +AliasSeq!("m") true TFunction1: extern (C) void function() --- diff --git a/gcc/testsuite/gdc.test/runnable/xtest46_gc.d b/gcc/testsuite/gdc.test/runnable/xtest46_gc.d index 224625c..aab6227 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest46_gc.d +++ b/gcc/testsuite/gdc.test/runnable/xtest46_gc.d @@ -14,17 +14,17 @@ runnable/xtest46_gc.d-mixin-33(2996): Deprecation: alias this for classes/interf int(int i, long j = 7L) long C10390(C10390()) -tuple(height) -tuple(get, get) -tuple(clear) -tuple(draw, draw) +AliasSeq!(height) +AliasSeq!(get, get) +AliasSeq!(clear) +AliasSeq!(draw, draw) const(int) string[] double[] double[] {} runnable/xtest46_gc.d-mixin-33(4702): Deprecation: alias this for classes/interfaces is deprecated -tuple("m") +AliasSeq!("m") true TFunction1: extern (C) void function() --- -- cgit v1.1 From 01991146d8c9d6627b1ffba59f37c037ec33d513 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Mon, 10 Jul 2023 17:51:23 -0500 Subject: rs6000: Remove redundant MEM_P predicate usage The quad_memory_operand and vsx_quad_dform_memory_operand predicates contain a (match_code "mem") test, making their MEM_P usage redundant. Remove them. 2023-07-10 Peter Bergner gcc/ * config/rs6000/predicates.md (quad_memory_operand): Remove redundant MEM_P usage. (vsx_quad_dform_memory_operand): Likewise. --- gcc/config/rs6000/predicates.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 8479331..3552d90 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -912,7 +912,7 @@ if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI) return false; - if (GET_MODE_SIZE (mode) != 16 || !MEM_P (op) || MEM_ALIGN (op) < 128) + if (GET_MODE_SIZE (mode) != 16 || MEM_ALIGN (op) < 128) return false; return quad_address_p (XEXP (op, 0), mode, false); @@ -924,7 +924,7 @@ (define_predicate "vsx_quad_dform_memory_operand" (match_code "mem") { - if (!TARGET_P9_VECTOR || !MEM_P (op) || GET_MODE_SIZE (mode) != 16) + if (!TARGET_P9_VECTOR || GET_MODE_SIZE (mode) != 16) return false; return quad_address_p (XEXP (op, 0), mode, false); -- cgit v1.1 From 322d17ae51ea0137167424e0018d7fa355948f9f Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 11 Jul 2023 00:16:56 +0000 Subject: Daily bump. --- gcc/ChangeLog | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 49 ++++++++++++++++++++++++++ gcc/cp/ChangeLog | 6 ++++ gcc/d/ChangeLog | 30 ++++++++++++++++ gcc/testsuite/ChangeLog | 38 ++++++++++++++++++++ 6 files changed, 217 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ed58b4..cd7076b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,96 @@ +2023-07-10 Peter Bergner + + * config/rs6000/predicates.md (quad_memory_operand): Remove redundant + MEM_P usage. + (vsx_quad_dform_memory_operand): Likewise. + +2023-07-10 Uros Bizjak + + * reorg.cc (stop_search_p): Change return type from int to bool + and adjust function body accordingly. + (resource_conflicts_p): Ditto. + (insn_references_resource_p): Change return type from int to bool. + (insn_sets_resource_p): Ditto. + (redirect_with_delay_slots_safe_p): Ditto. + (condition_dominates_p): Change return type from int to bool + and adjust function body accordingly. + (redirect_with_delay_list_safe_p): Ditto. + (check_annul_list_true_false): Ditto. Change "annul_true_p" + function argument to bool. + (steal_delay_list_from_target): Change "pannul_p" function + argument to bool pointer. Change "must_annul" and "used_annul" + variables from int to bool. + (steal_delay_list_from_fallthrough): Ditto. + (own_thread_p): Change return type from int to bool and adjust + function body accordingly. Change "allow_fallthrough" function + argument to bool. + (reorg_redirect_jump): Change return type from int to bool. + (fill_simple_delay_slots): Change "non_jumps_p" function + argument from int to bool. Change "maybe_never" varible to bool. + (fill_slots_from_thread): Change "likely", "thread_if_true" and + "own_thread" function arguments to bool. Change "lose" and + "must_annul" variables to bool. + (delete_from_delay_slot): Change "had_barrier" variable to bool. + (try_merge_delay_insns): Change "annul_p" variable to bool. + (fill_eager_delay_slots): Change "own_target" and "own_fallthrouhg" + variables to bool. + (rest_of_handle_delay_slots): Change return type from int to void + and adjust function body accordingly. + +2023-07-10 Kito Cheng + + * doc/extend.texi (RISC-V Operand Modifiers): New. + +2023-07-10 Ju-Zhe Zhong + + * config/riscv/riscv-vsetvl.cc (add_label_notes): Remove it. + (insert_insn_end_basic_block): Ditto. + (pass_vsetvl::commit_vsetvls): Adapt for new helper function. + * gcse.cc (insert_insn_end_basic_block): Export as global function. + * gcse.h (insert_insn_end_basic_block): Ditto. + +2023-07-10 Christophe Lyon + + PR target/110268 + * config/arm/arm-builtins.cc (arm_init_mve_builtins): Handle LTO. + (arm_builtin_decl): Hahndle MVE builtins. + * config/arm/arm-mve-builtins.cc (builtin_decl): New function. + (add_unique_function): Fix handling of + __ARM_MVE_PRESERVE_USER_NAMESPACE. + (add_overloaded_function): Likewise. + * config/arm/arm-protos.h (builtin_decl): New declaration. + +2023-07-10 Christophe Lyon + + * doc/sourcebuild.texi (arm_v8_1m_main_cde_mve_fp): Document. + +2023-07-10 Xi Ruoyao + + PR tree-optimization/110557 + * tree-vect-patterns.cc (vect_recog_bitfield_ref_pattern): + Ensure the output sign-extended if necessary. + +2023-07-10 Roger Sayle + + * config/i386/i386.md (peephole2): Transform xchg insn with a + REG_UNUSED note to a (simple) move. + (*insvti_lowpart_1): New define_insn_and_split. + (*insvdi_lowpart_1): Likewise. + +2023-07-10 Roger Sayle + + * config/i386/i386-features.cc (compute_convert_gain): Tweak + gains/costs for ROTATE/ROTATERT by integer constant on AVX512VL. + (general_scalar_chain::convert_rotate): On TARGET_AVX512F generate + avx512vl_rolv2di or avx412vl_rolv4si when appropriate. + +2023-07-10 liuhongt + + PR target/110170 + * config/i386/i386.md (*ieee_max3_1): New pre_reload + splitter to detect fp max pattern. + (*ieee_min3_1): Ditto, but for fp min pattern. + 2023-07-09 Jan Hubicka * cfg.cc (check_bb_profile): Dump counts with relative frequency. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 1d5dd3c..2dbd21e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230710 +20230711 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 4f94ccf..6890c5b 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,52 @@ +2023-07-10 Eric Botcazou + + * adaint.c [_WIN32]: Undefine 'abort' macro. + +2023-07-10 Tom Tromey + + * snames.h-tmpl (Name_Id, Attribute_Id, Convention_Id) + (Pragma_Id): New typedefs. + (Get_Attribute_Id, Get_Pragma_Id): Use typedef. + +2023-07-10 Yannick Moy + + * libgnat/s-aridou.adb (Lemma_Powers_Of_2_Commutation): Rewrite + assertion. + +2023-07-10 Bob Duff + + * doc/gnat_rm/gnat_language_extensions.rst + (Local Declarations Without Block): Document the feature very + briefly, and refer the reader to the RFC for details and examples. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2023-07-10 Alexandre Oliva + + * doc/gnat_rm/security_hardening_features.rst (Control Flow + Hardening): Document -fhardcfr-skip-leaf. + * gnat_rm.texi: Regenerate. + +2023-07-10 Alexandre Oliva + + * doc/gnat_rm/security_hardening_features.rst (Control Flow + Redundancy): Add -fhardcfr-check-noreturn-calls=no-xthrow. + * gnat_rm.texi: Regenerate. + +2023-07-10 Yannick Moy + + * libgnat/s-aridou.adb (Lemma_Div_Mult): New simple lemma. + (Lemma_Powers_Of_2_Commutation): State post in else branch. + (Lemma_Div_Pow2): Introduce local lemma and use it. + (Scaled_Divide): Use cut operations in assertions, lemmas, new + assertions. Introduce local lemma and use it. + +2023-07-10 Alexandre Oliva + + * doc/gnat_rm/security_hardening_features.rst (Register + Scrubbing): Document leafy mode. + * gnat_rm.texi: Regenerate. + 2023-07-06 Claire Dross * gcc-interface/Make-lang.in: Add object files of specification diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 76fbc80..3db03db 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2023-07-10 Patrick Palka + + PR c++/110523 + * pt.cc (redeclare_class_template): Relax the ttp DECL_CONTEXT + assert, and downgrade it to a checking assert. + 2023-06-30 Patrick Palka * cp-tree.h (TEMPLATE_PARM_DESCENDANTS): Harden. diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index f477aa4..50750bb 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,33 @@ +2023-07-10 Iain Buclaw + + * dmd/MERGE: Merge upstream dmd a88e1335f7. + * dmd/VERSION: Bump version to v2.104.1. + +2023-07-10 Iain Buclaw + + * dmd/MERGE: Merge upstream dmd 17ccd12af3. + * dmd/VERSION: Bump version to v2.104.0. + * Make-lang.in (D_FRONTEND_OBJS): Rename d/apply.o to + d/postordervisitor.o. + * d-codegen.cc (make_location_t): Update for new front-end interface. + (build_filename_from_loc): Likewise. + (build_assert_call): Likewise. + (build_array_bounds_call): Likewise. + (build_bounds_index_condition): Likewise. + (build_bounds_slice_condition): Likewise. + (build_frame_type): Likewise. + (get_frameinfo): Likewise. + * d-diagnostic.cc (d_diagnostic_report_diagnostic): Likewise. + * decl.cc (build_decl_tree): Likewise. + (start_function): Likewise. + * expr.cc (ExprVisitor::visit (NewExp *)): Replace code generation of + `new pointer' with front-end lowering. + * runtime.def (NEWITEMT): Remove. + (NEWITEMIT): Remove. + * toir.cc (IRVisitor::visit (LabelStatement *)): Update for new + front-end interface. + * typeinfo.cc (check_typeinfo_type): Likewise. + 2023-07-09 Iain Buclaw * dmd/MERGE: Merge upstream dmd 28a3b24c2e. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 60ec7b1..e710abd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,41 @@ +2023-07-10 Patrick Palka + + PR c++/110523 + * g++.dg/template/ttp37.C: New test. + +2023-07-10 Christophe Lyon + + PR target/110268 + * gcc.target/arm/pr110268-1.c: New test. + * gcc.target/arm/pr110268-2.c: New test. + +2023-07-10 Christophe Lyon + + * lib/target-supports.exp (arm_*FUNC_link): New effective-targets. + +2023-07-10 Xi Ruoyao + + PR tree-optimization/110557 + * g++.dg/vect/pr110557.cc: New test. + +2023-07-10 Roger Sayle + + * gcc.target/i386/insvdi_lowpart-1.c: New test case. + * gcc.target/i386/insvti_lowpart-1.c: Likewise. + +2023-07-10 Roger Sayle + + * gcc.target/i386/avx512vl-stv-rotatedi-1.c: New test case. + +2023-07-10 Iain Buclaw + + * gdc.dg/asm4.d: Update test. + +2023-07-10 liuhongt + + * g++.target/i386/pr110170.C: New test. + * gcc.target/i386/pr110170.c: New test. + 2023-07-09 Iain Buclaw * gdc.dg/rtti1.d: Move array concat testcase to ... -- cgit v1.1 From 312839653b8295599c63cae90278a87af528edad Mon Sep 17 00:00:00 2001 From: Xi Ruoyao Date: Tue, 11 Jul 2023 15:55:54 +0800 Subject: testsuite: Unbreak pr110557.cc where long is 32-bit On ports with 32-bit long, the test produced excess errors: gcc/testsuite/g++.dg/vect/pr110557.cc:12:8: warning: width of 'Item::y' exceeds its type Reported-by: Prathamesh Kulkarni gcc/testsuite/ChangeLog: * g++.dg/vect/pr110557.cc: Use long long instead of long for 64-bit type. (test): Remove an unnecessary cast. --- gcc/testsuite/g++.dg/vect/pr110557.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/vect/pr110557.cc b/gcc/testsuite/g++.dg/vect/pr110557.cc index e1fbe1c..effb67e 100644 --- a/gcc/testsuite/g++.dg/vect/pr110557.cc +++ b/gcc/testsuite/g++.dg/vect/pr110557.cc @@ -1,7 +1,9 @@ // { dg-additional-options "-mavx" { target { avx_runtime } } } -static inline long -min (long a, long b) +typedef long long i64; + +static inline i64 +min (i64 a, i64 b) { return a < b ? a : b; } @@ -9,16 +11,16 @@ min (long a, long b) struct Item { int x : 8; - long y : 55; + i64 y : 55; bool z : 1; }; -__attribute__ ((noipa)) long +__attribute__ ((noipa)) i64 test (Item *a, int cnt) { - long size = 0; + i64 size = 0; for (int i = 0; i < cnt; i++) - size = min ((long)a[i].y, size); + size = min (a[i].y, size); return size; } -- cgit v1.1 From 8957121b8bf4be7eb7f9de31b810ea01594a670e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 3 Jul 2023 00:33:18 +0200 Subject: ada: Fix wrong resolution for hidden discriminant in predicate The problem occurs for hidden discriminants of private discriminated types. gcc/ada/ * sem_ch13.adb (Replace_Type_References_Generic.Visible_Component): In the case of private discriminated types, return a discriminant only if it is listed in the discriminant part of the declaration. --- gcc/ada/sem_ch13.adb | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index c3ea8d63..4f97094 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -15569,15 +15569,11 @@ package body Sem_Ch13 is function Visible_Component (Comp : Name_Id) return Entity_Id is E : Entity_Id; + begin - -- Types with nameable components are record, task, and protected - -- types, and discriminated private types. + -- Types with nameable components are record, task, protected types - if Ekind (T) in E_Record_Type - | E_Task_Type - | E_Protected_Type - or else (Is_Private_Type (T) and then Has_Discriminants (T)) - then + if Ekind (T) in E_Record_Type | E_Task_Type | E_Protected_Type then -- This is a sequential search, which seems acceptable -- efficiency-wise, given the typical size of component -- lists, protected operation lists, task item lists, and @@ -15591,6 +15587,45 @@ package body Sem_Ch13 is Next_Entity (E); end loop; + + -- Private discriminated types may have visible discriminants + + elsif Is_Private_Type (T) and then Has_Discriminants (T) then + declare + Decl : constant Node_Id := Declaration_Node (T); + Spec : constant List_Id := + Discriminant_Specifications (Original_Node (Decl)); + + Discr : Node_Id; + + begin + -- Loop over the discriminants listed in the discriminant part + -- of the private type declaration to find one with a matching + -- name; then, if it exists, return the discriminant entity of + -- the same name in the type, which is that of its full view. + + if Present (Spec) then + Discr := First (Spec); + + while Present (Discr) loop + if Chars (Defining_Identifier (Discr)) = Comp then + Discr := First_Discriminant (T); + + while Present (Discr) loop + if Chars (Discr) = Comp then + return Discr; + end if; + + Next_Discriminant (Discr); + end loop; + + pragma Assert (False); + end if; + + Next (Discr); + end loop; + end if; + end; end if; -- Nothing by that name -- cgit v1.1 From 6be7d5e91e47c5432391b03de9f89e7ec6072eda Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Mon, 3 Jul 2023 12:01:01 -0400 Subject: ada: Avoid renaming_decl in case of constrained array This patch avoids rewriting "X: S := F(...);" as "X: S renames F(...);". That rewrite is incorrect if S is a constrained array subtype, because it changes the semantics. In the original, the bounds of X are that of S. But constraints are ignored in renamings, so the bounds of X would come from F'Result. This can cause spurious Constraint_Errors in some obscure cases. It causes unnecessary checks to be inserted, and even when such checks pass (more common case), they might be less efficient. gcc/ada/ * exp_ch3.adb (Expand_N_Object_Declaration): Avoid transforming to a renaming in case of constrained array that comes from source. --- gcc/ada/exp_ch3.adb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index daf27fb..db27a5f 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -7275,6 +7275,13 @@ package body Exp_Ch3 is Rewrite_As_Renaming : Boolean := False; -- Whether to turn the declaration into a renaming at the end + Nominal_Subtype_Is_Constrained_Array : constant Boolean := + Comes_From_Source (Obj_Def) + and then Is_Array_Type (Typ) and then Is_Constrained (Typ); + -- Used to avoid rewriting as a renaming for constrained arrays, + -- which is only a problem for source arrays; others have the + -- correct bounds (see below). + -- Start of processing for Expand_N_Object_Declaration begin @@ -8030,7 +8037,14 @@ package body Exp_Ch3 is or else (Nkind (Expr_Q) = N_Slice and then OK_To_Rename_Ref (Prefix (Expr_Q)) - and then not Special_Ret_Obj)); + and then not Special_Ret_Obj)) + + -- If we have "X : S := ...;", and S is a constrained array + -- subtype, then we cannot rename, because renamings ignore + -- the constraints of S, so that would change the semantics + -- (sliding would not occur on the initial value). + + and then not Nominal_Subtype_Is_Constrained_Array; -- If the type needs finalization and is not inherently limited, -- then the target is adjusted after the copy and attached to the -- cgit v1.1 From 4736ddd11874fe215662ac18877ce8eded1f5976 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 11 Jul 2023 10:40:19 +0200 Subject: tree-optimization/110614 - SLP splat and re-align (optimized) The following properly guards the re-align (optimized) paths used on old power CPUs for the added case of SLP splats from non-grouped loads. Testcases are existing in dg-torture. PR tree-optimization/110614 * tree-vect-data-refs.cc (vect_supportable_dr_alignment): SLP splats are not suitable for re-align ops. --- gcc/tree-vect-data-refs.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index ab2af10..9edc898 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -6829,10 +6829,11 @@ vect_supportable_dr_alignment (vec_info *vinfo, dr_vec_info *dr_info, same alignment, instead it depends on the SLP group size. */ if (loop_vinfo && STMT_SLP_TYPE (stmt_info) - && !multiple_p (LOOP_VINFO_VECT_FACTOR (loop_vinfo) - * (DR_GROUP_SIZE - (DR_GROUP_FIRST_ELEMENT (stmt_info))), - TYPE_VECTOR_SUBPARTS (vectype))) + && (!STMT_VINFO_GROUPED_ACCESS (stmt_info) + || !multiple_p (LOOP_VINFO_VECT_FACTOR (loop_vinfo) + * (DR_GROUP_SIZE + (DR_GROUP_FIRST_ELEMENT (stmt_info))), + TYPE_VECTOR_SUBPARTS (vectype)))) ; else if (!loop_vinfo || (nested_in_vect_loop -- cgit v1.1 From 6c96d1e4e877d045f7e0c22786244653d2e1cf99 Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Mon, 10 Jul 2023 19:35:47 +0800 Subject: VECT: Add COND_LEN_* operations for loop control with length targets Hi, Richard and Richi. This patch is adding cond_len_* operations pattern for target support loop control with length. These patterns will be used in these following case: 1. Integer division: void f (int32_t *restrict a, int32_t *restrict b, int32_t *restrict c, int n) { for (int i = 0; i < n; ++i) { a[i] = b[i] / c[i]; } } ARM SVE IR: ... max_mask_36 = .WHILE_ULT (0, bnd.5_32, { 0, ... }); Loop: ... # loop_mask_29 = PHI ... vect__4.8_28 = .MASK_LOAD (_33, 32B, loop_mask_29); ... vect__6.11_25 = .MASK_LOAD (_20, 32B, loop_mask_29); vect__8.12_24 = .COND_DIV (loop_mask_29, vect__4.8_28, vect__6.11_25, vect__4.8_28); ... .MASK_STORE (_1, 32B, loop_mask_29, vect__8.12_24); ... next_mask_37 = .WHILE_ULT (_2, bnd.5_32, { 0, ... }); ... For target like RVV who support loop control with length, we want to see IR as follows: Loop: ... # loop_len_29 = SELECT_VL ... vect__4.8_28 = .LEN_MASK_LOAD (_33, 32B, loop_len_29); ... vect__6.11_25 = .LEN_MASK_LOAD (_20, 32B, loop_len_29); vect__8.12_24 = .COND_LEN_DIV (dummp_mask, vect__4.8_28, vect__6.11_25, vect__4.8_28, loop_len_29, bias); ... .LEN_MASK_STORE (_1, 32B, loop_len_29, vect__8.12_24); ... next_mask_37 = .WHILE_ULT (_2, bnd.5_32, { 0, ... }); ... Notice here, we use dummp_mask = { -1, -1, .... , -1 } 2. Integer conditional division: Similar case with (1) but with condtion: void f (int32_t *restrict a, int32_t *restrict b, int32_t *restrict c, int32_t * cond, int n) { for (int i = 0; i < n; ++i) { if (cond[i]) a[i] = b[i] / c[i]; } } ARM SVE: ... max_mask_76 = .WHILE_ULT (0, bnd.6_52, { 0, ... }); Loop: ... # loop_mask_55 = PHI ... vect__4.9_56 = .MASK_LOAD (_51, 32B, loop_mask_55); mask__29.10_58 = vect__4.9_56 != { 0, ... }; vec_mask_and_61 = loop_mask_55 & mask__29.10_58; ... vect__6.13_62 = .MASK_LOAD (_24, 32B, vec_mask_and_61); ... vect__8.16_66 = .MASK_LOAD (_1, 32B, vec_mask_and_61); vect__10.17_68 = .COND_DIV (vec_mask_and_61, vect__6.13_62, vect__8.16_66, vect__6.13_62); ... .MASK_STORE (_2, 32B, vec_mask_and_61, vect__10.17_68); ... next_mask_77 = .WHILE_ULT (_3, bnd.6_52, { 0, ... }); Here, ARM SVE use vec_mask_and_61 = loop_mask_55 & mask__29.10_58; to gurantee the correct result. However, target with length control can not perform this elegant flow, for RVV, we would expect: Loop: ... loop_len_55 = SELECT_VL ... mask__29.10_58 = vect__4.9_56 != { 0, ... }; ... vect__10.17_68 = .COND_LEN_DIV (mask__29.10_58, vect__6.13_62, vect__8.16_66, vect__6.13_62, loop_len_55, bias); ... Here we expect COND_LEN_DIV predicated by a real mask which is the outcome of comparison: mask__29.10_58 = vect__4.9_56 != { 0, ... }; and a real length which is produced by loop control : loop_len_55 = SELECT_VL 3. conditional Floating-point operations (no -ffast-math): void f (float *restrict a, float *restrict b, int32_t *restrict cond, int n) { for (int i = 0; i < n; ++i) { if (cond[i]) a[i] = b[i] + a[i]; } } ARM SVE IR: max_mask_70 = .WHILE_ULT (0, bnd.6_46, { 0, ... }); ... # loop_mask_49 = PHI ... mask__27.10_52 = vect__4.9_50 != { 0, ... }; vec_mask_and_55 = loop_mask_49 & mask__27.10_52; ... vect__9.17_62 = .COND_ADD (vec_mask_and_55, vect__6.13_56, vect__8.16_60, vect__6.13_56); ... next_mask_71 = .WHILE_ULT (_22, bnd.6_46, { 0, ... }); ... For RVV, we would expect IR: ... loop_len_49 = SELECT_VL ... mask__27.10_52 = vect__4.9_50 != { 0, ... }; ... vect__9.17_62 = .COND_LEN_ADD (mask__27.10_52, vect__6.13_56, vect__8.16_60, vect__6.13_56, loop_len_49, bias); ... 4. Conditional un-ordered reduction: int32_t f (int32_t *restrict a, int32_t *restrict cond, int n) { int32_t result = 0; for (int i = 0; i < n; ++i) { if (cond[i]) result += a[i]; } return result; } ARM SVE IR: Loop: # vect_result_18.7_37 = PHI ... # loop_mask_40 = PHI ... mask__17.11_43 = vect__4.10_41 != { 0, ... }; vec_mask_and_46 = loop_mask_40 & mask__17.11_43; ... vect__33.16_51 = .COND_ADD (vec_mask_and_46, vect_result_18.7_37, vect__7.14_47, vect_result_18.7_37); ... next_mask_58 = .WHILE_ULT (_15, bnd.6_36, { 0, ... }); ... Epilogue: _53 = .REDUC_PLUS (vect__33.16_51); [tail call] For RVV, we expect: Loop: # vect_result_18.7_37 = PHI ... loop_len_40 = SELECT_VL ... mask__17.11_43 = vect__4.10_41 != { 0, ... }; ... vect__33.16_51 = .COND_LEN_ADD (mask__17.11_43, vect_result_18.7_37, vect__7.14_47, vect_result_18.7_37, loop_len_40, bias); ... next_mask_58 = .WHILE_ULT (_15, bnd.6_36, { 0, ... }); ... Epilogue: _53 = .REDUC_PLUS (vect__33.16_51); [tail call] I name these patterns as "cond_len_*" since I want the length operand comes after mask operand and all other operands except length operand same order as "cond_*" patterns. Such order will make life easier in the following loop vectorizer support. gcc/ChangeLog: * doc/md.texi: Add COND_LEN_* operations for loop control with length. * internal-fn.cc (cond_len_unary_direct): Ditto. (cond_len_binary_direct): Ditto. (cond_len_ternary_direct): Ditto. (expand_cond_len_unary_optab_fn): Ditto. (expand_cond_len_binary_optab_fn): Ditto. (expand_cond_len_ternary_optab_fn): Ditto. (direct_cond_len_unary_optab_supported_p): Ditto. (direct_cond_len_binary_optab_supported_p): Ditto. (direct_cond_len_ternary_optab_supported_p): Ditto. * internal-fn.def (COND_LEN_ADD): Ditto. (COND_LEN_SUB): Ditto. (COND_LEN_MUL): Ditto. (COND_LEN_DIV): Ditto. (COND_LEN_MOD): Ditto. (COND_LEN_RDIV): Ditto. (COND_LEN_MIN): Ditto. (COND_LEN_MAX): Ditto. (COND_LEN_FMIN): Ditto. (COND_LEN_FMAX): Ditto. (COND_LEN_AND): Ditto. (COND_LEN_IOR): Ditto. (COND_LEN_XOR): Ditto. (COND_LEN_SHL): Ditto. (COND_LEN_SHR): Ditto. (COND_LEN_FMA): Ditto. (COND_LEN_FMS): Ditto. (COND_LEN_FNMA): Ditto. (COND_LEN_FNMS): Ditto. (COND_LEN_NEG): Ditto. * optabs.def (OPTAB_D): Ditto. --- gcc/doc/md.texi | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/internal-fn.cc | 15 ++++++++++ gcc/internal-fn.def | 38 +++++++++++++++++++++++++ gcc/optabs.def | 24 ++++++++++++++++ 4 files changed, 157 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index b30a824..cbcb992 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -7234,6 +7234,86 @@ for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++) op0[i] = op1[i] ? fma (op2[i], op3[i], op4[i]) : op5[i]; @end smallexample +@cindex @code{cond_len_add@var{mode}} instruction pattern +@cindex @code{cond_len_sub@var{mode}} instruction pattern +@cindex @code{cond_len_mul@var{mode}} instruction pattern +@cindex @code{cond_len_div@var{mode}} instruction pattern +@cindex @code{cond_len_udiv@var{mode}} instruction pattern +@cindex @code{cond_len_mod@var{mode}} instruction pattern +@cindex @code{cond_len_umod@var{mode}} instruction pattern +@cindex @code{cond_len_and@var{mode}} instruction pattern +@cindex @code{cond_len_ior@var{mode}} instruction pattern +@cindex @code{cond_len_xor@var{mode}} instruction pattern +@cindex @code{cond_len_smin@var{mode}} instruction pattern +@cindex @code{cond_len_smax@var{mode}} instruction pattern +@cindex @code{cond_len_umin@var{mode}} instruction pattern +@cindex @code{cond_len_umax@var{mode}} instruction pattern +@cindex @code{cond_len_fmin@var{mode}} instruction pattern +@cindex @code{cond_len_fmax@var{mode}} instruction pattern +@cindex @code{cond_len_ashl@var{mode}} instruction pattern +@cindex @code{cond_len_ashr@var{mode}} instruction pattern +@cindex @code{cond_len_lshr@var{mode}} instruction pattern +@item @samp{cond_len_add@var{mode}} +@itemx @samp{cond_len_sub@var{mode}} +@itemx @samp{cond_len_mul@var{mode}} +@itemx @samp{cond_len_div@var{mode}} +@itemx @samp{cond_len_udiv@var{mode}} +@itemx @samp{cond_len_mod@var{mode}} +@itemx @samp{cond_len_umod@var{mode}} +@itemx @samp{cond_len_and@var{mode}} +@itemx @samp{cond_len_ior@var{mode}} +@itemx @samp{cond_len_xor@var{mode}} +@itemx @samp{cond_len_smin@var{mode}} +@itemx @samp{cond_len_smax@var{mode}} +@itemx @samp{cond_len_umin@var{mode}} +@itemx @samp{cond_len_umax@var{mode}} +@itemx @samp{cond_len_fmin@var{mode}} +@itemx @samp{cond_len_fmax@var{mode}} +@itemx @samp{cond_len_ashl@var{mode}} +@itemx @samp{cond_len_ashr@var{mode}} +@itemx @samp{cond_len_lshr@var{mode}} +When operand 1 is true and element index < operand 5 + operand 6, perform an operation on operands 2 and 3 and +store the result in operand 0, otherwise store operand 4 in operand 0. +The operation only works for the operands are vectors. + +@smallexample +for (i = 0; i < ops[5] + ops[6]; i++) + op0[i] = op1[i] ? op2[i] @var{op} op3[i] : op4[i]; +@end smallexample + +where, for example, @var{op} is @code{+} for @samp{cond_len_add@var{mode}}. + +When defined for floating-point modes, the contents of @samp{op3[i]} +are not interpreted if @samp{op1[i]} is false, just like they would not +be in a normal C @samp{?:} condition. + +Operands 0, 2, 3 and 4 all have mode @var{m}. Operand 1 is a scalar +integer if @var{m} is scalar, otherwise it has the mode returned by +@code{TARGET_VECTORIZE_GET_MASK_MODE}. Operand 5 has whichever +integer mode the target prefers. + +@samp{cond_@var{op}@var{mode}} generally corresponds to a conditional +form of @samp{@var{op}@var{mode}3}. As an exception, the vector forms +of shifts correspond to patterns like @code{vashl@var{mode}3} rather +than patterns like @code{ashl@var{mode}3}. + +@cindex @code{cond_len_fma@var{mode}} instruction pattern +@cindex @code{cond_len_fms@var{mode}} instruction pattern +@cindex @code{cond_len_fnma@var{mode}} instruction pattern +@cindex @code{cond_len_fnms@var{mode}} instruction pattern +@item @samp{cond_len_fma@var{mode}} +@itemx @samp{cond_len_fms@var{mode}} +@itemx @samp{cond_len_fnma@var{mode}} +@itemx @samp{cond_len_fnms@var{mode}} +Like @samp{cond_len_add@var{m}}, except that the conditional operation +takes 3 operands rather than two. For example, the vector form of +@samp{cond_len_fma@var{mode}} is equivalent to: + +@smallexample +for (i = 0; i < ops[6] + ops[7]; i++) + op0[i] = op1[i] ? fma (op2[i], op3[i], op4[i]) : op5[i]; +@end smallexample + @cindex @code{neg@var{mode}cc} instruction pattern @item @samp{neg@var{mode}cc} Similar to @samp{mov@var{mode}cc} but for conditional negation. Conditionally diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 278db7b..f9aaf66 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -183,6 +183,9 @@ init_internal_fns () #define cond_unary_direct { 1, 1, true } #define cond_binary_direct { 1, 1, true } #define cond_ternary_direct { 1, 1, true } +#define cond_len_unary_direct { 1, 1, true } +#define cond_len_binary_direct { 1, 1, true } +#define cond_len_ternary_direct { 1, 1, true } #define while_direct { 0, 2, false } #define fold_extract_direct { 2, 2, false } #define fold_left_direct { 1, 1, false } @@ -3869,6 +3872,15 @@ expand_convert_optab_fn (internal_fn fn, gcall *stmt, convert_optab optab, #define expand_cond_ternary_optab_fn(FN, STMT, OPTAB) \ expand_direct_optab_fn (FN, STMT, OPTAB, 5) +#define expand_cond_len_unary_optab_fn(FN, STMT, OPTAB) \ + expand_direct_optab_fn (FN, STMT, OPTAB, 5) + +#define expand_cond_len_binary_optab_fn(FN, STMT, OPTAB) \ + expand_direct_optab_fn (FN, STMT, OPTAB, 6) + +#define expand_cond_len_ternary_optab_fn(FN, STMT, OPTAB) \ + expand_direct_optab_fn (FN, STMT, OPTAB, 7) + #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \ expand_direct_optab_fn (FN, STMT, OPTAB, 3) @@ -3964,6 +3976,9 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types, #define direct_cond_unary_optab_supported_p direct_optab_supported_p #define direct_cond_binary_optab_supported_p direct_optab_supported_p #define direct_cond_ternary_optab_supported_p direct_optab_supported_p +#define direct_cond_len_unary_optab_supported_p direct_optab_supported_p +#define direct_cond_len_binary_optab_supported_p direct_optab_supported_p +#define direct_cond_len_ternary_optab_supported_p direct_optab_supported_p #define direct_mask_load_optab_supported_p convert_optab_supported_p #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index 238b7ee..ea750a9 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -72,6 +72,10 @@ along with GCC; see the file COPYING3. If not see - fold_left: for scalar = FN (scalar, vector), keyed off the vector mode - check_ptrs: used for check_{raw,war}_ptrs + - cond_len_unary: a conditional unary optab, such as cond_len_neg + - cond_len_binary: a conditional binary optab, such as cond_len_add + - cond_len_ternary: a conditional ternary optab, such as cond_len_fma_rev + DEF_INTERNAL_SIGNED_OPTAB_FN defines an internal function that maps to one of two optabs, depending on the signedness of an input. SIGNED_OPTAB and UNSIGNED_OPTAB are the optabs for signed and @@ -248,6 +252,40 @@ DEF_INTERNAL_OPTAB_FN (COND_FNMS, ECF_CONST, cond_fnms, cond_ternary) DEF_INTERNAL_OPTAB_FN (COND_NEG, ECF_CONST, cond_neg, cond_unary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_ADD, ECF_CONST, cond_len_add, cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_SUB, ECF_CONST, cond_len_sub, cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_MUL, ECF_CONST, cond_len_smul, cond_len_binary) +DEF_INTERNAL_SIGNED_OPTAB_FN (COND_LEN_DIV, ECF_CONST, first, cond_len_sdiv, + cond_len_udiv, cond_len_binary) +DEF_INTERNAL_SIGNED_OPTAB_FN (COND_LEN_MOD, ECF_CONST, first, cond_len_smod, + cond_len_umod, cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_RDIV, ECF_CONST, cond_len_sdiv, cond_len_binary) +DEF_INTERNAL_SIGNED_OPTAB_FN (COND_LEN_MIN, ECF_CONST, first, cond_len_smin, + cond_len_umin, cond_len_binary) +DEF_INTERNAL_SIGNED_OPTAB_FN (COND_LEN_MAX, ECF_CONST, first, cond_len_smax, + cond_len_umax, cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_FMIN, ECF_CONST, cond_len_fmin, cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_FMAX, ECF_CONST, cond_len_fmax, cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_AND, ECF_CONST | ECF_NOTHROW, cond_len_and, + cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_IOR, ECF_CONST | ECF_NOTHROW, cond_len_ior, + cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_XOR, ECF_CONST | ECF_NOTHROW, cond_len_xor, + cond_len_binary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_SHL, ECF_CONST | ECF_NOTHROW, cond_len_ashl, + cond_len_binary) +DEF_INTERNAL_SIGNED_OPTAB_FN (COND_LEN_SHR, ECF_CONST | ECF_NOTHROW, first, + cond_len_ashr, cond_len_lshr, cond_len_binary) + +DEF_INTERNAL_OPTAB_FN (COND_LEN_FMA, ECF_CONST, cond_len_fma, cond_len_ternary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_FMS, ECF_CONST, cond_len_fms, cond_len_ternary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_FNMA, ECF_CONST, cond_len_fnma, + cond_len_ternary) +DEF_INTERNAL_OPTAB_FN (COND_LEN_FNMS, ECF_CONST, cond_len_fnms, + cond_len_ternary) + +DEF_INTERNAL_OPTAB_FN (COND_LEN_NEG, ECF_CONST, cond_len_neg, cond_len_unary) + DEF_INTERNAL_OPTAB_FN (RSQRT, ECF_CONST, rsqrt, unary) DEF_INTERNAL_OPTAB_FN (REDUC_PLUS, ECF_CONST | ECF_NOTHROW, diff --git a/gcc/optabs.def b/gcc/optabs.def index 73c9a0c..3dae228 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -254,6 +254,30 @@ OPTAB_D (cond_fms_optab, "cond_fms$a") OPTAB_D (cond_fnma_optab, "cond_fnma$a") OPTAB_D (cond_fnms_optab, "cond_fnms$a") OPTAB_D (cond_neg_optab, "cond_neg$a") +OPTAB_D (cond_len_add_optab, "cond_len_add$a") +OPTAB_D (cond_len_sub_optab, "cond_len_sub$a") +OPTAB_D (cond_len_smul_optab, "cond_len_mul$a") +OPTAB_D (cond_len_sdiv_optab, "cond_len_div$a") +OPTAB_D (cond_len_smod_optab, "cond_len_mod$a") +OPTAB_D (cond_len_udiv_optab, "cond_len_udiv$a") +OPTAB_D (cond_len_umod_optab, "cond_len_umod$a") +OPTAB_D (cond_len_and_optab, "cond_len_and$a") +OPTAB_D (cond_len_ior_optab, "cond_len_ior$a") +OPTAB_D (cond_len_xor_optab, "cond_len_xor$a") +OPTAB_D (cond_len_ashl_optab, "cond_len_ashl$a") +OPTAB_D (cond_len_ashr_optab, "cond_len_ashr$a") +OPTAB_D (cond_len_lshr_optab, "cond_len_lshr$a") +OPTAB_D (cond_len_smin_optab, "cond_len_smin$a") +OPTAB_D (cond_len_smax_optab, "cond_len_smax$a") +OPTAB_D (cond_len_umin_optab, "cond_len_umin$a") +OPTAB_D (cond_len_umax_optab, "cond_len_umax$a") +OPTAB_D (cond_len_fmin_optab, "cond_len_fmin$a") +OPTAB_D (cond_len_fmax_optab, "cond_len_fmax$a") +OPTAB_D (cond_len_fma_optab, "cond_len_fma$a") +OPTAB_D (cond_len_fms_optab, "cond_len_fms$a") +OPTAB_D (cond_len_fnma_optab, "cond_len_fnma$a") +OPTAB_D (cond_len_fnms_optab, "cond_len_fnms$a") +OPTAB_D (cond_len_neg_optab, "cond_len_neg$a") OPTAB_D (cmov_optab, "cmov$a6") OPTAB_D (cstore_optab, "cstore$a4") OPTAB_D (ctrap_optab, "ctrap$a4") -- cgit v1.1 From e5c64efb1367459dbc2d2e29856f23908cb503c1 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Tue, 11 Jul 2023 21:21:03 +0800 Subject: Fix typo in the testcase. Antony Polukhin 2023-07-11 09:51:58 UTC There's a typo at https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/testsuite/g%2B%2B.target/i386/pr110170.C;h=e638b12a5ee2264ecef77acca86432a9f24b103b;hb=d41a57c46df6f8f7dae0c0a8b349e734806a837b#l87 It should be `|| !test3() || !test3r()` rather than `|| !test3() || !test4r()` gcc/testsuite/ChangeLog: PR target/110170 * g++.target/i386/pr110170.C: Fix typo. --- gcc/testsuite/g++.target/i386/pr110170.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/g++.target/i386/pr110170.C b/gcc/testsuite/g++.target/i386/pr110170.C index e638b12..21cca8f 100644 --- a/gcc/testsuite/g++.target/i386/pr110170.C +++ b/gcc/testsuite/g++.target/i386/pr110170.C @@ -84,7 +84,7 @@ TEST() if ( !test1() || !test1r() || !test2() || !test2r() - || !test3() || !test4r() + || !test3() || !test3r() || !test4() || !test4r() ) __builtin_abort(); } -- cgit v1.1 From b76d71564925abcabe6f5ad61d904b23c682cdfb Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 11 Jul 2023 10:05:19 -0400 Subject: c++: coercing variable template from current inst [PR110580] Here during ahead of time coercion of the variable template-id v1, since we pass only the innermost arguments to coerce_template_parms (and outer arguments are still dependent at this point), substitution of the default template argument V=U just lowers U from level 2 to level 1 rather than replacing it with int as expected. Thus after coercion we incorrectly end up with (effectively) v1 instead of v1. Coercion of a class/alias template-id on the other hand always passes all levels arguments, which avoids this issue. So this patch makes us do the same for variable template-ids. PR c++/110580 gcc/cp/ChangeLog: * pt.cc (lookup_template_variable): Pass all levels of arguments to coerce_template_parms, and use the parameters from the most general template. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/var-templ83.C: New test. --- gcc/cp/pt.cc | 4 +++- gcc/testsuite/g++.dg/cpp1y/var-templ83.C | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/var-templ83.C (limited to 'gcc') diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 076f788..fa15b75 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10345,7 +10345,9 @@ lookup_template_variable (tree templ, tree arglist, tsubst_flags_t complain) if (flag_concepts && variable_concept_p (templ)) return build_concept_check (templ, arglist, tf_none); - tree parms = DECL_INNERMOST_TEMPLATE_PARMS (templ); + tree gen_templ = most_general_template (templ); + tree parms = DECL_INNERMOST_TEMPLATE_PARMS (gen_templ); + arglist = add_outermost_template_args (templ, arglist); arglist = coerce_template_parms (parms, arglist, templ, complain); if (arglist == error_mark_node) return error_mark_node; diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ83.C b/gcc/testsuite/g++.dg/cpp1y/var-templ83.C new file mode 100644 index 0000000..f5268f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ83.C @@ -0,0 +1,16 @@ +// PR c++/110580 +// { dg-do compile { target c++14 } } + +template +struct A { + template + static constexpr bool v1 = __is_same(U, V); + + template + static constexpr bool v2 = !__is_same(U, V); + + static_assert(v1, ""); + static_assert(v2, ""); +}; + +template struct A; -- cgit v1.1 From 40b91158c373fb17e26c161ddb453792e8746678 Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Tue, 11 Jul 2023 15:28:42 +0100 Subject: [modula2] Improve uninitialized variable analysis by combining basic blocks This patch combines basic blocks for static analysis of uninitialized variables providing that they are not the top of a loop, are not reached by a conditional and are not reached after a procedure call. It also avoids checking array accesses for static analysis. Finally the patch adds switch modifiers to allow static analysis to include conditional branches for subsequent basic block analysis. gcc/ChangeLog: * doc/gm2.texi (-Wuninit-variable-checking=) New item. gcc/m2/ChangeLog: * gm2-compiler/M2BasicBlock.def (InitBasicBlocksFromRange): New parameter ScopeSym. * gm2-compiler/M2BasicBlock.mod (ConvertQuads2BasicBlock): New parameter ScopeSym. (InitBasicBlocksFromRange): New parameter ScopeSym. Call ConvertQuads2BasicBlock with ScopeSym. (DisplayBasicBlocks): Uncomment. * gm2-compiler/M2Code.mod: Replace VariableAnalysis with ScopeBlockVariableAnalysis. (InitialDeclareAndOptiomize): Add parameter scope. (SecondDeclareAndOptimize): Add parameter scope. * gm2-compiler/M2GCCDeclare.mod (DeclareConstructor): Add scope parameter to DeclareTypesConstantsProceduresInRange. (DeclareTypesConstantsProceduresInRange): New parameter scope. Pass scope to DisplayQuadRange. Reformatted. * gm2-compiler/M2GenGCC.def (ConvertQuadsToTree): New parameter scope. * gm2-compiler/M2GenGCC.mod (ConvertQuadsToTree): New parameter scope. * gm2-compiler/M2Optimize.mod (KnownReachable): New parameter scope. * gm2-compiler/M2Options.def (SetUninitVariableChecking): Add arg parameter. * gm2-compiler/M2Options.mod (SetUninitVariableChecking): Add arg parameter and set boolean UninitVariableChecking and UninitVariableConditionalChecking. (UninitVariableConditionalChecking): New boolean set to FALSE. * gm2-compiler/M2Quads.def (IsGoto): New procedure function. (DisplayQuadRange): Add scope parameter. (LoopAnalysis): Add scope parameter. * gm2-compiler/M2Quads.mod: Import PutVarArrayRef. (IsGoto): New procedure function. (LoopAnalysis): Add scope parameter and use MetaErrorT1 instead of WarnStringAt. (BuildStaticArray): Call PutVarArrayRef. (BuildDynamicArray): Call PutVarArrayRef. (DisplayQuadRange): Add scope parameter. (GetM2OperatorDesc): Add relational condition cases. * gm2-compiler/M2Scope.def (ScopeProcedure): Add parameter. * gm2-compiler/M2Scope.mod (DisplayScope): Pass scopeSym to DisplayQuadRange. (ForeachScopeBlockDo): Pass scopeSym to p. * gm2-compiler/M2SymInit.def (VariableAnalysis): Rename to ... (ScopeBlockVariableAnalysis): ... this. * gm2-compiler/M2SymInit.mod (ScopeBlockVariableAnalysis): Add scope parameter. (bbEntry): New pointer to record. (bbArray): New array. (bbFreeList): New variable. (errorList): New list. (IssueConditional): New procedure. (GenerateNoteFlow): New procedure. (IssueWarning): New procedure. (IsUniqueWarning): New procedure. (CheckDeferredRecordAccess): Re-implement. (CheckBinary): Add warning and lst parameters. (CheckUnary): Add warning and lst parameters. (CheckXIndr): Add warning and lst parameters. (CheckIndrX): Add warning and lst parameters. (CheckBecomes): Add warning and lst parameters. (CheckComparison): Add warning and lst parameters. (CheckReadBeforeInitQuad): Add warning and lst parameters to all Check procedures. Add all case quadruple clauses. (FilterCheckReadBeforeInitQuad): Add warning and lst parameters. (CheckReadBeforeInitFirstBasicBlock): Add warning and lst parameters. (bbArrayKill): New procedure. (DumpBBEntry): New procedure. (DumpBBArray): New procedure. (DumpBBSequence): New procedure. (TestBBSequence): New procedure. (CreateBBPermultations): New procedure. (ScopeBlockVariableAnalysis): New procedure. (GetOp3): New procedure. (GenerateCFG): New procedure. (NewEntry): New procedure. (AppendEntry): New procedure. (init): Initialize bbFreeList and errorList. * gm2-compiler/SymbolTable.def (PutVarArrayRef): New procedure. (IsVarArrayRef): New procedure function. * gm2-compiler/SymbolTable.mod (SymVar): ArrayRef new field. (MakeVar): Set ArrayRef to FALSE. (PutVarArrayRef): New procedure. (IsVarArrayRef): New procedure function. * gm2-gcc/init.cc (_M2_M2SymInit_init): New prototype. (init_PerCompilationInit): Add call to _M2_M2SymInit_init. * gm2-gcc/m2options.h (M2Options_SetUninitVariableChecking): New definition. * gm2-lang.cc (gm2_langhook_handle_option): Add new case OPT_Wuninit_variable_checking_. * lang.opt: Wuninit-variable-checking= new entry. gcc/testsuite/ChangeLog: * gm2/switches/uninit-variable-checking/cascade/fail/cascadedif.mod: New test. * gm2/switches/uninit-variable-checking/cascade/fail/switches-uninit-variable-checking-cascade-fail.exp: New test. Signed-off-by: Gaius Mulley --- gcc/doc/gm2.texi | 11 + gcc/m2/gm2-compiler/M2BasicBlock.def | 3 +- gcc/m2/gm2-compiler/M2BasicBlock.mod | 22 +- gcc/m2/gm2-compiler/M2Code.mod | 45 +- gcc/m2/gm2-compiler/M2GCCDeclare.mod | 36 +- gcc/m2/gm2-compiler/M2GenGCC.def | 2 +- gcc/m2/gm2-compiler/M2GenGCC.mod | 4 +- gcc/m2/gm2-compiler/M2Optimize.mod | 3 +- gcc/m2/gm2-compiler/M2Options.def | 12 +- gcc/m2/gm2-compiler/M2Options.mod | 182 +++--- gcc/m2/gm2-compiler/M2Quads.def | 12 +- gcc/m2/gm2-compiler/M2Quads.mod | 68 ++- gcc/m2/gm2-compiler/M2Scope.def | 2 +- gcc/m2/gm2-compiler/M2Scope.mod | 4 +- gcc/m2/gm2-compiler/M2SymInit.def | 7 +- gcc/m2/gm2-compiler/M2SymInit.mod | 671 ++++++++++++++++++--- gcc/m2/gm2-compiler/SymbolTable.def | 15 + gcc/m2/gm2-compiler/SymbolTable.mod | 45 ++ gcc/m2/gm2-gcc/init.cc | 2 + gcc/m2/gm2-gcc/m2options.h | 2 +- gcc/m2/gm2-lang.cc | 5 +- gcc/m2/lang.opt | 4 + .../cascade/fail/cascadedif.mod | 25 + ...tches-uninit-variable-checking-cascade-fail.exp | 37 ++ 24 files changed, 979 insertions(+), 240 deletions(-) create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/cascadedif.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/switches-uninit-variable-checking-cascade-fail.exp (limited to 'gcc') diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi index ae87434..8d5d95f 100644 --- a/gcc/doc/gm2.texi +++ b/gcc/doc/gm2.texi @@ -664,6 +664,17 @@ issue a warning if a variable is used before it is initialized. The checking only occurs in the first basic block in each procedure. It does not check parameters, array types or set types. +@item -Wuninit-variable-checking=all,known,cond +issue a warning if a variable is used before it is initialized. +The checking will only occur in the first basic block in each +procedure if @samp{known} is specified. If @samp{cond} or @samp{all} +is specified then checking continues into conditional branches of the +flow graph. All checking will stop when a procedure call is invoked +or the top of a loop is encountered. +The option @samp{-Wall} will turn on this flag with +@samp{-Wuninit-variable-checking=known}. +The @samp{-Wuninit-variable-checking=all} will increase compile time. + @c the following warning options are complete but need to be @c regression tested against all other front ends @c to ensure the options do not conflict. diff --git a/gcc/m2/gm2-compiler/M2BasicBlock.def b/gcc/m2/gm2-compiler/M2BasicBlock.def index 44606dd..3a67ea6 100644 --- a/gcc/m2/gm2-compiler/M2BasicBlock.def +++ b/gcc/m2/gm2-compiler/M2BasicBlock.def @@ -60,7 +60,8 @@ PROCEDURE InitBasicBlocks (sb: ScopeBlock) : BasicBlock ; reachable are removed. *) -PROCEDURE InitBasicBlocksFromRange (start, end: CARDINAL) : BasicBlock ; +PROCEDURE InitBasicBlocksFromRange (ScopeSym: CARDINAL; + start, end: CARDINAL) : BasicBlock ; (* diff --git a/gcc/m2/gm2-compiler/M2BasicBlock.mod b/gcc/m2/gm2-compiler/M2BasicBlock.mod index 1d005f6..d3eb135 100644 --- a/gcc/m2/gm2-compiler/M2BasicBlock.mod +++ b/gcc/m2/gm2-compiler/M2BasicBlock.mod @@ -35,12 +35,15 @@ FROM M2Quads IMPORT IsReferenced, IsConditional, IsUnConditional, IsCall, IsInitialisingConst, IsPseudoQuad, IsDefOrModFile, GetNextQuad, GetQuad, QuadOperator, - SubQuad ; + SubQuad, DisplayQuadRange ; FROM M2Scope IMPORT ScopeBlock, ForeachScopeBlockDo ; FROM M2GenGCC IMPORT ConvertQuadsToTree ; +CONST + Debugging = FALSE ; + TYPE BasicBlock = POINTER TO RECORD StartQuad : CARDINAL ; (* First Quad in Basic Block *) @@ -77,10 +80,15 @@ END InitBasicBlocks ; reachable are removed. *) -PROCEDURE InitBasicBlocksFromRange (start, end: CARDINAL) : BasicBlock ; +PROCEDURE InitBasicBlocksFromRange (ScopeSym: CARDINAL; + start, end: CARDINAL) : BasicBlock ; BEGIN HeadOfBasicBlock := NIL ; - ConvertQuads2BasicBlock(start, end) ; + ConvertQuads2BasicBlock (ScopeSym, start, end) ; + IF Debugging + THEN + DisplayBasicBlocks (HeadOfBasicBlock) + END ; RETURN( HeadOfBasicBlock ) END InitBasicBlocksFromRange ; @@ -144,7 +152,7 @@ END New ; which has only has one entry and exit point. *) -PROCEDURE ConvertQuads2BasicBlock (Start, End: CARDINAL) ; +PROCEDURE ConvertQuads2BasicBlock (ScopeSym: CARDINAL; Start, End: CARDINAL) ; VAR LastQuadDefMod, LastQuadConditional, @@ -154,6 +162,10 @@ VAR CurrentBB : BasicBlock ; LastBB : BasicBlock ; BEGIN + IF Debugging + THEN + DisplayQuadRange (ScopeSym, Start, End) + END ; (* Algorithm to perform Basic Block: @@ -323,7 +335,6 @@ END Sub ; DisplayBasicBlocks - displays the basic block data structure. *) -(* PROCEDURE DisplayBasicBlocks (bb: BasicBlock) ; VAR b: BasicBlock ; @@ -347,7 +358,6 @@ BEGIN WriteString(' end ') ; WriteCard(EndQuad, 6) ; END END DisplayBlock ; -*) BEGIN diff --git a/gcc/m2/gm2-compiler/M2Code.mod b/gcc/m2/gm2-compiler/M2Code.mod index c4069e9..d2ace72 100644 --- a/gcc/m2/gm2-compiler/M2Code.mod +++ b/gcc/m2/gm2-compiler/M2Code.mod @@ -45,7 +45,7 @@ FROM M2Quads IMPORT CountQuads, GetFirstQuad, DisplayQuadList, DisplayQuadRange, BackPatchSubrangesAndOptParam, LoopAnalysis, ForLoopAnalysis, GetQuad, QuadOperator ; -FROM M2SymInit IMPORT VariableAnalysis ; +FROM M2SymInit IMPORT ScopeBlockVariableAnalysis ; FROM M2Pass IMPORT SetPassToNoPass, SetPassToCodeGeneration ; @@ -293,16 +293,16 @@ END Code ; InitialDeclareAndCodeBlock - declares all objects within scope, *) -PROCEDURE InitialDeclareAndOptimize (start, end: CARDINAL) ; +PROCEDURE InitialDeclareAndOptimize (scope: CARDINAL; start, end: CARDINAL) ; BEGIN - Count := CountQuads() ; - FreeBasicBlocks(InitBasicBlocksFromRange(start, end)) ; - BasicB := Count - CountQuads() ; - Count := CountQuads() ; - - FoldBranches(start, end) ; - Jump := Count - CountQuads() ; - Count := CountQuads() + Count := CountQuads () ; + FreeBasicBlocks (InitBasicBlocksFromRange (scope, start, end)) ; + BasicB := Count - CountQuads () ; + Count := CountQuads () ; + + FoldBranches (start, end) ; + Jump := Count - CountQuads () ; + Count := CountQuads () END InitialDeclareAndOptimize ; @@ -310,24 +310,25 @@ END InitialDeclareAndOptimize ; DeclareAndCodeBlock - declares all objects within scope, *) -PROCEDURE SecondDeclareAndOptimize (start, end: CARDINAL) ; +PROCEDURE SecondDeclareAndOptimize (scope: CARDINAL; + start, end: CARDINAL) ; BEGIN REPEAT FoldConstants(start, end) ; DeltaConst := Count - CountQuads () ; Count := CountQuads () ; - FreeBasicBlocks(InitBasicBlocksFromRange (start, end)) ; + FreeBasicBlocks(InitBasicBlocksFromRange (scope, start, end)) ; DeltaBasicB := Count - CountQuads () ; Count := CountQuads () ; - FreeBasicBlocks (InitBasicBlocksFromRange (start, end)) ; + FreeBasicBlocks (InitBasicBlocksFromRange (scope, start, end)) ; FoldBranches(start, end) ; DeltaJump := Count - CountQuads () ; Count := CountQuads () ; - FreeBasicBlocks(InitBasicBlocksFromRange (start, end)) ; + FreeBasicBlocks(InitBasicBlocksFromRange (scope, start, end)) ; INC (DeltaBasicB, Count - CountQuads ()) ; Count := CountQuads () ; @@ -375,20 +376,6 @@ END Init ; (* - BasicBlockVariableAnalysis - -*) - -PROCEDURE BasicBlockVariableAnalysis (start, end: CARDINAL) ; -VAR - bb: BasicBlock ; -BEGIN - bb := InitBasicBlocksFromRange(start, end) ; - ForeachBasicBlockDo (bb, VariableAnalysis) ; - KillBasicBlocks (bb) -END BasicBlockVariableAnalysis ; - - -(* DisplayQuadsInScope - *) @@ -416,7 +403,7 @@ BEGIN OptimTimes := 1 ; Current := CountQuads () ; ForeachScopeBlockDo (sb, InitialDeclareAndOptimize) ; - ForeachScopeBlockDo (sb, BasicBlockVariableAnalysis) ; + ForeachScopeBlockDo (sb, ScopeBlockVariableAnalysis) ; REPEAT ForeachScopeBlockDo (sb, SecondDeclareAndOptimize) ; Previous := Current ; diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod index c502726..eaa3255 100644 --- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod +++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod @@ -1610,13 +1610,13 @@ BEGIN THEN InternalError ('trying to declare the NulSym') END ; - IF IsConstructor(sym) AND (NOT GccKnowsAbout(sym)) + IF IsConstructor (sym) AND (NOT GccKnowsAbout (sym)) THEN - WalkConstructor(sym, TraverseDependants) ; - DeclareTypesConstantsProceduresInRange(quad, quad) ; - Assert(IsConstructorDependants(sym, IsFullyDeclared)) ; - PushValue(sym) ; - DeclareConstantFromTree(sym, PopConstructorTree(tokenno)) + WalkConstructor (sym, TraverseDependants) ; + DeclareTypesConstantsProceduresInRange (GetScope (sym), quad, quad) ; + Assert (IsConstructorDependants (sym, IsFullyDeclared)) ; + PushValue (sym) ; + DeclareConstantFromTree (sym, PopConstructorTree (tokenno)) END END DeclareConstructor ; @@ -2539,24 +2539,24 @@ END FoldConstants ; DeclareTypesConstantsProceduresInRange - *) -PROCEDURE DeclareTypesConstantsProceduresInRange (start, end: CARDINAL) ; +PROCEDURE DeclareTypesConstantsProceduresInRange (scope, start, end: CARDINAL) ; VAR n, m: CARDINAL ; BEGIN IF DisplayQuadruples THEN - DisplayQuadRange(start, end) + DisplayQuadRange (scope, start, end) END ; REPEAT n := NoOfElementsInSet(ToDoList) ; - WHILE ResolveConstantExpressions(DeclareConstFully, start, end) DO + WHILE ResolveConstantExpressions (DeclareConstFully, start, end) DO END ; (* we need to evaluate some constant expressions to resolve these types *) IF DeclaredOutstandingTypes (FALSE) THEN END ; m := NoOfElementsInSet(ToDoList) - UNTIL (NOT ResolveConstantExpressions(DeclareConstFully, start, end)) AND + UNTIL (NOT ResolveConstantExpressions (DeclareConstFully, start, end)) AND (n=m) END DeclareTypesConstantsProceduresInRange ; @@ -2620,16 +2620,16 @@ VAR s, t: CARDINAL ; sb : ScopeBlock ; BEGIN - sb := InitScopeBlock(scope) ; - PushBinding(scope) ; + sb := InitScopeBlock (scope) ; + PushBinding (scope) ; REPEAT - s := NoOfElementsInSet(ToDoList) ; + s := NoOfElementsInSet (ToDoList) ; (* ForeachLocalSymDo(scope, DeclareTypeInfo) ; *) - ForeachScopeBlockDo(sb, DeclareTypesConstantsProceduresInRange) ; - t := NoOfElementsInSet(ToDoList) ; + ForeachScopeBlockDo (sb, DeclareTypesConstantsProceduresInRange) ; + t := NoOfElementsInSet (ToDoList) ; UNTIL s=t ; - PopBinding(scope) ; - KillScopeBlock(sb) + PopBinding (scope) ; + KillScopeBlock (sb) END DeclareTypesConstantsProcedures ; @@ -2691,7 +2691,7 @@ BEGIN WalkTypesInProcedure(scope) ; DeclareProcedure(scope) ; ForeachInnerModuleDo(scope, WalkTypesInModule) ; - DeclareTypesConstantsProcedures(scope) ; + DeclareTypesConstantsProcedures (scope) ; ForeachInnerModuleDo(scope, DeclareTypesConstantsProcedures) ; DeclareLocalVariables(scope) ; ForeachInnerModuleDo(scope, DeclareModuleVariables) ; diff --git a/gcc/m2/gm2-compiler/M2GenGCC.def b/gcc/m2/gm2-compiler/M2GenGCC.def index 646e09e..b132bf0 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.def +++ b/gcc/m2/gm2-compiler/M2GenGCC.def @@ -45,7 +45,7 @@ EXPORT QUALIFIED ConvertQuadsToTree, ResolveConstantExpressions, the GCC tree structure. *) -PROCEDURE ConvertQuadsToTree (Start, End: CARDINAL) ; +PROCEDURE ConvertQuadsToTree (Scope: CARDINAL; Start, End: CARDINAL) ; (* diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod index 8b877e2..0955106 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.mod +++ b/gcc/m2/gm2-compiler/M2GenGCC.mod @@ -395,7 +395,7 @@ BEGIN THEN RETURN FALSE END ; - scope := GetScope(scope) + scope := GetScope (scope) END ; InternalError ('expecting scope to eventually reach a module or defimp symbol') ELSE @@ -410,7 +410,7 @@ END IsExportedGcc ; the GCC tree structure. *) -PROCEDURE ConvertQuadsToTree (Start, End: CARDINAL) ; +PROCEDURE ConvertQuadsToTree (Scope: CARDINAL; Start, End: CARDINAL) ; BEGIN REPEAT CodeStatement (Start) ; diff --git a/gcc/m2/gm2-compiler/M2Optimize.mod b/gcc/m2/gm2-compiler/M2Optimize.mod index 416eb42..408e958 100644 --- a/gcc/m2/gm2-compiler/M2Optimize.mod +++ b/gcc/m2/gm2-compiler/M2Optimize.mod @@ -351,7 +351,8 @@ BEGIN END RemoveProcedures ; -PROCEDURE KnownReachable (Start, End: CARDINAL) ; +PROCEDURE KnownReachable (Scope: CARDINAL; + Start, End: CARDINAL) ; VAR Op : QuadOperator ; Op1, Op2, Op3: CARDINAL ; diff --git a/gcc/m2/gm2-compiler/M2Options.def b/gcc/m2/gm2-compiler/M2Options.def index 722e56c..d8d3845 100644 --- a/gcc/m2/gm2-compiler/M2Options.def +++ b/gcc/m2/gm2-compiler/M2Options.def @@ -73,6 +73,7 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck, VariantValueChecking, UnusedVariableChecking, UnusedParameterChecking, UninitVariableChecking, SetUninitVariableChecking, + UninitVariableConditionalChecking, SetUnusedVariableChecking, SetUnusedParameterChecking, Quiet, LineDirectives, StrictTypeChecking, CPreProcessor, Xcode, ExtendedOpaque, @@ -162,6 +163,10 @@ VAR UnusedParameterChecking, (* Should we warn about unused parameters? *) UninitVariableChecking, (* Should we warn about accessing *) (* uninitialized variables in the first bb? *) + UninitVariableConditionalChecking, + (* Should we warn about accessing *) + (* uninitialized variables in subsequent *) + (* basic blocks? *) LowerCaseKeywords, (* Should keywords in errors be in lower? *) DebugBuiltins, (* Should we always call a real function? *) AutoInit, (* -fauto-init assigns pointers to NIL. *) @@ -922,10 +927,13 @@ PROCEDURE SetShared (value: BOOLEAN) ; (* - SetUninitVariableChecking - sets the UninitVariableChecking flag to value. + SetUninitVariableChecking - sets the UninitVariableChecking flag to value + or UninitVariableConditionalChecking to value. + Arg can be "known", "known,cond", "cond,known" + or "all". *) -PROCEDURE SetUninitVariableChecking (value: BOOLEAN) ; +PROCEDURE SetUninitVariableChecking (value: BOOLEAN; arg: ADDRESS) : INTEGER ; (* diff --git a/gcc/m2/gm2-compiler/M2Options.mod b/gcc/m2/gm2-compiler/M2Options.mod index 84fcb57..1174a0d 100644 --- a/gcc/m2/gm2-compiler/M2Options.mod +++ b/gcc/m2/gm2-compiler/M2Options.mod @@ -28,7 +28,7 @@ FROM M2Search IMPORT SetDefExtension, SetModExtension ; FROM PathName IMPORT DumpPathName, AddInclude ; FROM M2Printf IMPORT printf0, printf1, fprintf1 ; FROM FIO IMPORT StdErr ; -FROM libc IMPORT exit ; +FROM libc IMPORT exit, printf ; FROM Debug IMPORT Halt ; FROM m2linemap IMPORT location_t ; FROM m2configure IMPORT FullPathCPP ; @@ -1369,84 +1369,114 @@ END SetShared ; SetUninitVariableChecking - sets the UninitVariableChecking flag to value. *) -PROCEDURE SetUninitVariableChecking (value: BOOLEAN) ; +PROCEDURE SetUninitVariableChecking (value: BOOLEAN; arg: ADDRESS) : INTEGER ; +VAR + s: String ; BEGIN - UninitVariableChecking := value + IF Debugging + THEN + IF value + THEN + printf ("SetUninitVariableChecking (TRUE, %s)\n", arg) + ELSE + printf ("SetUninitVariableChecking (FALSE, %s)\n", arg) + END + END ; + s := InitStringCharStar (arg) ; + IF EqualArray (s, "all") OR + EqualArray (s, "known,cond") OR + EqualArray (s, "cond,known") OR + EqualArray (s, "cond") + THEN + UninitVariableChecking := value ; + UninitVariableConditionalChecking := value ; + s := KillString (s) ; + RETURN 1 + ELSIF EqualArray (s, "known") + THEN + UninitVariableChecking := value ; + UninitVariableConditionalChecking := NOT value ; + s := KillString (s) ; + RETURN 1 + ELSE + s := KillString (s) ; + RETURN 0 + END END SetUninitVariableChecking ; - BEGIN - cflag := FALSE ; (* -c. *) - RuntimeModuleOverride := InitString (DefaultRuntimeModuleOverride) ; - CppArgs := InitString ('') ; - Pim := TRUE ; - Pim2 := FALSE ; - Pim3 := FALSE ; - Pim4 := TRUE ; - PositiveModFloorDiv := FALSE ; - Iso := FALSE ; - SeenSources := FALSE ; - Statistics := FALSE ; - StyleChecking := FALSE ; - CompilerDebugging := FALSE ; - GenerateDebugging := FALSE ; - Optimizing := FALSE ; - Pedantic := FALSE ; - Verbose := FALSE ; - Quiet := TRUE ; - CC1Quiet := TRUE ; - Profiling := FALSE ; - DisplayQuadruples := FALSE ; - OptimizeBasicBlock := FALSE ; - OptimizeUncalledProcedures := FALSE ; - OptimizeCommonSubExpressions := FALSE ; - NilChecking := FALSE ; - WholeDivChecking := FALSE ; - WholeValueChecking := FALSE ; - FloatValueChecking := FALSE ; - IndexChecking := FALSE ; - RangeChecking := FALSE ; - ReturnChecking := FALSE ; - CaseElseChecking := FALSE ; - CPreProcessor := FALSE ; - LineDirectives := FALSE ; - ExtendedOpaque := FALSE ; - UnboundedByReference := FALSE ; - VerboseUnbounded := FALSE ; - PedanticParamNames := FALSE ; - PedanticCast := FALSE ; - Xcode := FALSE ; - DumpSystemExports := FALSE ; - GenerateSwig := FALSE ; - Exceptions := TRUE ; - DebugBuiltins := FALSE ; - ForcedLocation := FALSE ; - WholeProgram := FALSE ; - DebugTraceQuad := FALSE ; - DebugTraceAPI := FALSE ; - DebugFunctionLineNumbers := FALSE ; - GenerateStatementNote := FALSE ; - LowerCaseKeywords := FALSE ; - UnusedVariableChecking := FALSE ; - UnusedParameterChecking := FALSE ; - StrictTypeChecking := TRUE ; - AutoInit := FALSE ; - SaveTemps := FALSE ; - ScaffoldDynamic := TRUE ; - ScaffoldStatic := FALSE ; - ScaffoldMain := FALSE ; - UselistFilename := NIL ; - GenModuleList := FALSE ; - GenModuleListFilename := NIL ; - SharedFlag := FALSE ; - Barg := NIL ; - MDarg := NIL ; - MMDarg := NIL ; - MQarg := NIL ; - SaveTempsDir := NIL ; - DumpDir := NIL ; - UninitVariableChecking := FALSE ; - M2Prefix := InitString ('') ; - M2PathName := InitString ('') + cflag := FALSE ; (* -c. *) + RuntimeModuleOverride := InitString (DefaultRuntimeModuleOverride) ; + CppArgs := InitString ('') ; + Pim := TRUE ; + Pim2 := FALSE ; + Pim3 := FALSE ; + Pim4 := TRUE ; + PositiveModFloorDiv := FALSE ; + Iso := FALSE ; + SeenSources := FALSE ; + Statistics := FALSE ; + StyleChecking := FALSE ; + CompilerDebugging := FALSE ; + GenerateDebugging := FALSE ; + Optimizing := FALSE ; + Pedantic := FALSE ; + Verbose := FALSE ; + Quiet := TRUE ; + CC1Quiet := TRUE ; + Profiling := FALSE ; + DisplayQuadruples := FALSE ; + OptimizeBasicBlock := FALSE ; + OptimizeUncalledProcedures := FALSE ; + OptimizeCommonSubExpressions := FALSE ; + NilChecking := FALSE ; + WholeDivChecking := FALSE ; + WholeValueChecking := FALSE ; + FloatValueChecking := FALSE ; + IndexChecking := FALSE ; + RangeChecking := FALSE ; + ReturnChecking := FALSE ; + CaseElseChecking := FALSE ; + CPreProcessor := FALSE ; + LineDirectives := FALSE ; + ExtendedOpaque := FALSE ; + UnboundedByReference := FALSE ; + VerboseUnbounded := FALSE ; + PedanticParamNames := FALSE ; + PedanticCast := FALSE ; + Xcode := FALSE ; + DumpSystemExports := FALSE ; + GenerateSwig := FALSE ; + Exceptions := TRUE ; + DebugBuiltins := FALSE ; + ForcedLocation := FALSE ; + WholeProgram := FALSE ; + DebugTraceQuad := FALSE ; + DebugTraceAPI := FALSE ; + DebugFunctionLineNumbers := FALSE ; + GenerateStatementNote := FALSE ; + LowerCaseKeywords := FALSE ; + UnusedVariableChecking := FALSE ; + UnusedParameterChecking := FALSE ; + StrictTypeChecking := TRUE ; + AutoInit := FALSE ; + SaveTemps := FALSE ; + ScaffoldDynamic := TRUE ; + ScaffoldStatic := FALSE ; + ScaffoldMain := FALSE ; + UselistFilename := NIL ; + GenModuleList := FALSE ; + GenModuleListFilename := NIL ; + SharedFlag := FALSE ; + Barg := NIL ; + MDarg := NIL ; + MMDarg := NIL ; + MQarg := NIL ; + SaveTempsDir := NIL ; + DumpDir := NIL ; + UninitVariableChecking := FALSE ; + UninitVariableConditionalChecking := FALSE ; + M2Prefix := InitString ('') ; + M2PathName := InitString ('') END M2Options. diff --git a/gcc/m2/gm2-compiler/M2Quads.def b/gcc/m2/gm2-compiler/M2Quads.def index ef6c06c..cd011ba 100644 --- a/gcc/m2/gm2-compiler/M2Quads.def +++ b/gcc/m2/gm2-compiler/M2Quads.def @@ -106,6 +106,7 @@ EXPORT QUALIFIED StartBuildDefFile, StartBuildModFile, EndBuildFile, IsBackReference, IsUnConditional, IsConditional, IsBackReferenceConditional, + IsGoto, IsCall, IsReturn, IsProcedureScope, @@ -250,6 +251,13 @@ PROCEDURE IsBackReferenceConditional (q: CARDINAL) : BOOLEAN ; (* + IsGoto - returns true if QuadNo is a goto operation. +*) + +PROCEDURE IsGoto (QuadNo: CARDINAL) : BOOLEAN ; + + +(* IsCall - returns true if QuadNo is a call operation. *) @@ -382,7 +390,7 @@ PROCEDURE DisplayQuadList ; DisplayQuadRange - displays all quads in list range, start..end. *) -PROCEDURE DisplayQuadRange (start, end: CARDINAL) ; +PROCEDURE DisplayQuadRange (scope: CARDINAL; start, end: CARDINAL) ; (* @@ -2591,7 +2599,7 @@ PROCEDURE BuildStmtNote (offset: INTEGER) ; LoopAnalysis - checks whether an infinite loop exists. *) -PROCEDURE LoopAnalysis (Current, End: CARDINAL) ; +PROCEDURE LoopAnalysis (Scope: CARDINAL; Current, End: CARDINAL) ; (* diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod index dc73265..5ed2252 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -126,6 +126,7 @@ FROM SymbolTable IMPORT ModeOfAddr, GetMode, PutMode, GetSymName, IsUnknown, GetUnboundedRecordType, GetUnboundedAddressOffset, GetUnboundedHighOffset, + PutVarArrayRef, ForeachFieldEnumerationDo, ForeachLocalSymDo, GetExported, PutImported, GetSym, GetLibName, @@ -588,6 +589,7 @@ BEGIN RETURN( TRUE ) END + ELSE END ; i := GetNextQuad (i) END ; @@ -712,6 +714,16 @@ END IsQuadA ; (* + IsGoto - returns true if QuadNo is a goto operation. +*) + +PROCEDURE IsGoto (QuadNo: CARDINAL) : BOOLEAN ; +BEGIN + RETURN( IsQuadA (QuadNo, GotoOp) ) +END IsGoto ; + + +(* IsCall - returns true if QuadNo is a call operation. *) @@ -10667,7 +10679,7 @@ END IsInfiniteLoop ; LoopAnalysis - checks whether an infinite loop exists. *) -PROCEDURE LoopAnalysis (Current, End: CARDINAL) ; +PROCEDURE LoopAnalysis (Scope: CARDINAL; Current, End: CARDINAL) ; VAR op : QuadOperator ; op1, op2, op3: CARDINAL ; @@ -10683,10 +10695,18 @@ BEGIN (* found a loop - ie a branch which goes back in quadruple numbers *) IF IsInfiniteLoop(Current) THEN + MetaErrorT1 (QuadToTokenNo(op3), + 'it is very likely (although not absolutely certain) that the top of an infinite loop exists here in {%1Wad}', + Scope) ; + MetaErrorT1 (QuadToTokenNo(Current), + 'and the bottom of the infinite loop is ends here in {%1Wad} or alternatively a component of this loop is never executed', + Scope) ; +(* WarnStringAt(InitString('it is very likely (although not absolutely certain) that the top of an infinite loop is here'), QuadToTokenNo(op3)) ; WarnStringAt(InitString('and the bottom of the infinite loop is ends here or alternatively a component of this loop is never executed'), QuadToTokenNo(Current)) +*) END END END ; @@ -11216,6 +11236,7 @@ BEGIN (* BuildDesignatorArray may have detected des is a constant. *) PutVarConst (Adr, IsVarConst (Array)) END ; + PutVarArrayRef (Adr, TRUE) ; (* From now on it must reference the array element by its lvalue - so we create the type of the referenced entity @@ -11246,15 +11267,15 @@ BEGIN THEN (* ti has no type since constant *) ti := MakeTemporary (tok, ImmediateValue) ; - PutVar(ti, Cardinal) ; + PutVar (ti, Cardinal) ; GenQuadO (tok, ElementSizeOp, ti, arrayType, 1, TRUE) ELSE INC(dim) ; tk := MakeTemporary (tok, RightValue) ; - PutVar(tk, Cardinal) ; + PutVar (tk, Cardinal) ; GenHigh (tok, tk, dim, arraySym) ; tl := MakeTemporary (tok, RightValue) ; - PutVar(tl, Cardinal) ; + PutVar (tl, Cardinal) ; GenQuadO (tok, AddOp, tl, tk, MakeConstLit (tok, MakeKey ('1'), Cardinal), TRUE) ; tj := calculateMultipicand (tok, arraySym, arrayType, dim) ; ti := MakeTemporary (tok, RightValue) ; @@ -11385,6 +11406,7 @@ BEGIN GenQuad (MultOp, tk, ti, tj) ; Adr := MakeTemporary (combinedTok, LeftValue) ; + PutVarArrayRef (Adr, TRUE) ; (* Ok must reference by address - but we contain the type of the referenced entity @@ -13168,14 +13190,14 @@ END DisplayQuadList ; DisplayQuadRange - displays all quads in list range, start..end. *) -PROCEDURE DisplayQuadRange (start, end: CARDINAL) ; +PROCEDURE DisplayQuadRange (scope: CARDINAL; start, end: CARDINAL) ; VAR f: QuadFrame ; BEGIN - printf0('Quadruples:\n') ; - WHILE (start<=end) AND (start#0) DO - DisplayQuad(start) ; - f := GetQF(start) ; + printf0 ('Quadruples for scope: ') ; WriteOperand (scope) ; printf0 ('\n') ; + WHILE (start <= end) AND (start # 0) DO + DisplayQuad (start) ; + f := GetQF (start) ; start := f^.Next END END DisplayQuadRange ; @@ -13194,10 +13216,10 @@ BEGIN IF QuadrupleGeneration THEN WHILE QuadNo#0 DO - f := GetQF(QuadNo) ; + f := GetQF (QuadNo) ; WITH f^ DO i := Operand3 ; (* Next Link along the BackPatch *) - ManipulateReference(QuadNo, Value) (* Filling in the BackPatch. *) + ManipulateReference (QuadNo, Value) (* Filling in the BackPatch. *) END ; QuadNo := i END @@ -13596,17 +13618,17 @@ PROCEDURE WriteOperand (Sym: CARDINAL) ; VAR n: Name ; BEGIN - IF Sym=NulSym + IF Sym = NulSym THEN - printf0('') + printf0 ('') ELSE - n := GetSymName(Sym) ; - printf1('%a', n) ; - IF IsVar(Sym) OR IsConst(Sym) + n := GetSymName (Sym) ; + printf1 ('%a', n) ; + IF IsVar (Sym) OR IsConst (Sym) THEN - printf0('[') ; WriteMode(GetMode(Sym)) ; printf0(']') + printf0 ('[') ; WriteMode (GetMode (Sym)) ; printf0(']') END ; - printf1('(%d)', Sym) + printf1 ('(%d)', Sym) END END WriteOperand ; @@ -13666,7 +13688,15 @@ BEGIN LogicalOrOp : RETURN InitString ('{%kOR}') | LogicalAndOp: RETURN InitString ('{%kAND}') | InclOp : RETURN InitString ('{%kINCL}') | - ExclOp : RETURN InitString ('{%kEXCL}') + ExclOp : RETURN InitString ('{%kEXCL}') | + IfEquOp : RETURN InitString ('=') | + IfLessEquOp : RETURN InitString ('<=') | + IfGreEquOp : RETURN InitString ('>=') | + IfGreOp : RETURN InitString ('>') | + IfLessOp : RETURN InitString ('<') | + IfNotEquOp : RETURN InitString ('#') | + IfInOp : RETURN InitString ('IN') | + IfNotInOp : RETURN InitString ('NOT IN') ELSE RETURN NIL diff --git a/gcc/m2/gm2-compiler/M2Scope.def b/gcc/m2/gm2-compiler/M2Scope.def index 9aed024..c1b684e 100644 --- a/gcc/m2/gm2-compiler/M2Scope.def +++ b/gcc/m2/gm2-compiler/M2Scope.def @@ -37,7 +37,7 @@ EXPORT QUALIFIED ScopeBlock, ScopeProcedure, TYPE ScopeBlock ; - ScopeProcedure = PROCEDURE (CARDINAL, CARDINAL) ; + ScopeProcedure = PROCEDURE (CARDINAL, CARDINAL, CARDINAL) ; (* diff --git a/gcc/m2/gm2-compiler/M2Scope.mod b/gcc/m2/gm2-compiler/M2Scope.mod index d840bf5..106c2a8 100644 --- a/gcc/m2/gm2-compiler/M2Scope.mod +++ b/gcc/m2/gm2-compiler/M2Scope.mod @@ -349,7 +349,7 @@ BEGIN END ; printf0 ("\n") ; - DisplayQuadRange (low, high) ; + DisplayQuadRange (scopeSym, low, high) ; IF next#NIL THEN DisplayScope (next) @@ -428,7 +428,7 @@ BEGIN enter (sb) ; IF (low # 0) AND (high # 0) THEN - p (low, high) + p (scopeSym, low, high) END ; leave (sb) END ; diff --git a/gcc/m2/gm2-compiler/M2SymInit.def b/gcc/m2/gm2-compiler/M2SymInit.def index 2ea6bfc..d0e39fb 100644 --- a/gcc/m2/gm2-compiler/M2SymInit.def +++ b/gcc/m2/gm2-compiler/M2SymInit.def @@ -45,12 +45,11 @@ PROCEDURE GetFieldInitialized (desc: InitDesc; fieldlist: List) : BOOLEAN ; (* - VariableAnalysis - checks to see whether a variable is: - - read before it has been initialized + ScopeBlockVariableAnalysis - checks to see whether a variable is + read before it has been initialized. *) -PROCEDURE VariableAnalysis (Start, End: CARDINAL) ; +PROCEDURE ScopeBlockVariableAnalysis (Scope: CARDINAL; Start, End: CARDINAL) ; PROCEDURE PrintSymInit (desc: InitDesc) ; diff --git a/gcc/m2/gm2-compiler/M2SymInit.mod b/gcc/m2/gm2-compiler/M2SymInit.mod index 18200af..a5457ec 100644 --- a/gcc/m2/gm2-compiler/M2SymInit.mod +++ b/gcc/m2/gm2-compiler/M2SymInit.mod @@ -23,17 +23,28 @@ IMPLEMENTATION MODULE M2SymInit ; FROM Storage IMPORT ALLOCATE, DEALLOCATE ; FROM M2Debug IMPORT Assert ; +FROM M2Printf IMPORT printf0, printf1, printf2, printf3, printf4 ; FROM libc IMPORT printf ; FROM NameKey IMPORT Name, NulName, KeyToCharStar ; -FROM M2Options IMPORT UninitVariableChecking ; -FROM M2MetaError IMPORT MetaErrorT1 ; + +FROM M2Options IMPORT UninitVariableChecking, UninitVariableConditionalChecking, + CompilerDebugging ; + +FROM M2MetaError IMPORT MetaErrorT1, MetaErrorStringT1, MetaErrorStringT2 ; FROM M2LexBuf IMPORT UnknownTokenNo ; +FROM DynamicStrings IMPORT String, InitString, Mark, ConCat, InitString ; +FROM M2Error IMPORT InternalError ; + +FROM M2BasicBlock IMPORT BasicBlock, + InitBasicBlocks, InitBasicBlocksFromRange, + KillBasicBlocks, FreeBasicBlocks, + ForeachBasicBlockDo ; IMPORT Indexing ; FROM Lists IMPORT List, InitList, GetItemFromList, PutItemIntoList, IsItemInList, IncludeItemIntoList, NoOfItemsInList, - RemoveItemFromList, ForeachItemInListDo, KillList ; + RemoveItemFromList, ForeachItemInListDo, KillList, DuplicateList ; FROM SymbolTable IMPORT NulSym, ModeOfAddr, IsVar, IsRecord, GetSType, GetNth, IsRecordField, IsSet, IsArray, IsProcedure, @@ -43,10 +54,14 @@ FROM SymbolTable IMPORT NulSym, ModeOfAddr, IsVar, IsRecord, GetSType, IsConst, IsConstString, NoOfParam, IsVarParam, ForeachLocalSymDo, IsTemporary, ModeOfAddr, IsReallyPointer, IsUnbounded, - IsVarient, IsFieldVarient, GetVarient ; + IsVarient, IsFieldVarient, GetVarient, + IsVarArrayRef ; + +FROM M2Quads IMPORT QuadOperator, GetQuadOtok, GetQuad, GetNextQuad, + IsNewLocalVar, IsReturn, IsKillLocalVar, IsConditional, + IsUnConditional, IsBackReference, IsCall, IsGoto, + GetM2OperatorDesc, Opposite, DisplayQuadRange ; -FROM M2Quads IMPORT QuadOperator, GetQuadOtok, GetQuad, GetNextQuad ; -FROM M2Options IMPORT CompilerDebugging ; FROM M2Printf IMPORT printf0, printf1, printf2 ; FROM M2GCCDeclare IMPORT PrintSym ; @@ -78,9 +93,32 @@ TYPE next : symAlias ; END ; + bbEntry = POINTER TO RECORD + start, end: CARDINAL ; + (* Is this the first bb? *) + first, + (* Does it end with a call? *) + endCall, + (* Does it end with a goto? *) + endGoto, + (* Does it end with a conditional? *) + endCond, + (* Does it form part of a loop? *) + topOfLoop: BOOLEAN ; + indexBB, + nextQuad, + condQuad, + nextBB, + condBB : CARDINAL ; + next : bbEntry ; + END ; + VAR aliasArray: Indexing.Index ; freeList : symAlias ; + bbArray : Indexing.Index ; + bbFreeList: bbEntry ; + errorList : List ; (* Ensure that we only generate one set of warnings per token. *) (* @@ -427,11 +465,115 @@ END ContainsVariant ; (* + IssueConditional - +*) + +PROCEDURE IssueConditional (quad: CARDINAL; conditional: BOOLEAN) ; +VAR + op : QuadOperator ; + op1, op2, op3 : CARDINAL ; + op1tok, op2tok, op3tok, qtok: CARDINAL ; + overflowChecking : BOOLEAN ; + s : String ; +BEGIN + GetQuadOtok (quad, qtok, op, op1, op2, op3, overflowChecking, + op1tok, op2tok, op3tok) ; + IF IsUniqueWarning (qtok) + THEN + op1tok := DefaultTokPos (op1tok, qtok) ; + op2tok := DefaultTokPos (op2tok, qtok) ; + op3tok := DefaultTokPos (op3tok, qtok) ; + IF NOT conditional + THEN + op := Opposite (op) + END ; + s := InitString ('depending upon the result of {%1Oad} ') ; + s := ConCat (s, Mark (GetM2OperatorDesc (op))) ; + s := ConCat (s, InitString (' {%2ad}')) ; + MetaErrorStringT2 (qtok, s, op1, op2) + END +END IssueConditional ; + + +(* + GenerateNoteFlow - +*) + +PROCEDURE GenerateNoteFlow (lst: List; n: CARDINAL; warning: BOOLEAN) ; +VAR + i : CARDINAL ; + ip1Ptr, + iPtr : bbEntry ; +BEGIN + IF NOT warning + THEN + (* Only issue flow messages for non warnings. *) + i := 1 ; + WHILE i <= n DO + iPtr := Indexing.GetIndice (bbArray, i) ; + IF iPtr^.endCond + THEN + IF i < n + THEN + ip1Ptr := Indexing.GetIndice (bbArray, i+1) ; + IssueConditional (iPtr^.end, iPtr^.condBB = ip1Ptr^.indexBB) + END + END ; + INC (i) + END + END +END GenerateNoteFlow ; + + +(* + IssueWarning - issue a warning or note at tok location. +*) + +PROCEDURE IssueWarning (tok: CARDINAL; + before, after: ARRAY OF CHAR; + sym: CARDINAL; warning: BOOLEAN) ; +VAR + s: String ; +BEGIN + s := InitString (before) ; + IF warning + THEN + s := ConCat (s, Mark (InitString ('{%1Wad}'))) + ELSE + s := ConCat (s, Mark (InitString ('{%1Oad}'))) + END ; + s := ConCat (s, Mark (InitString (after))) ; + MetaErrorStringT1 (tok, s, sym) +END IssueWarning ; + + +(* + IsUniqueWarning - return TRUE if a warning has not been issued at tok. + It remembers tok and subsequent calls will always return FALSE. +*) + +PROCEDURE IsUniqueWarning (tok: CARDINAL) : BOOLEAN ; +BEGIN + IF NOT IsItemInList (errorList, tok) + THEN + IncludeItemIntoList (errorList, tok) ; + RETURN TRUE + ELSE + RETURN FALSE + END +END IsUniqueWarning ; + + +(* CheckDeferredRecordAccess - *) PROCEDURE CheckDeferredRecordAccess (procsym: CARDINAL; tok: CARDINAL; - sym: CARDINAL; canDereference: BOOLEAN) ; + sym: CARDINAL; + canDereference, warning: BOOLEAN; + lst: List; i: CARDINAL) ; +VAR + unique: BOOLEAN ; BEGIN IF IsVar (sym) THEN @@ -459,32 +601,49 @@ BEGIN ELSIF IsComponent (sym) THEN Trace ("checkReadInit IsComponent (%d) is true)", sym) ; - IF NOT GetVarComponentInitialized (sym) + IF (NOT GetVarComponentInitialized (sym)) AND IsUniqueWarning (tok) THEN - MetaErrorT1 (tok, - 'attempting to access {%1Wad} before it has been initialized', - sym) + GenerateNoteFlow (lst, i, warning) ; + IssueWarning (tok, + 'attempting to access ', + ' before it has been initialized', + sym, warning) END ELSIF (GetMode (sym) = LeftValue) AND canDereference THEN Trace ("checkReadInit GetMode (%d) = LeftValue and canDereference (LeftValue and RightValue VarCheckReadInit)", sym) ; + unique := TRUE ; IF NOT VarCheckReadInit (sym, LeftValue) THEN - MetaErrorT1 (tok, - 'attempting to access the address of {%1Wad} before it has been initialized', - sym) + unique := IsUniqueWarning (tok) ; + IF unique + THEN + GenerateNoteFlow (lst, i, warning) ; + IssueWarning (tok, + 'attempting to access the address of ', + ' before it has been initialized', + sym, warning) + END END ; IF NOT VarCheckReadInit (sym, RightValue) THEN - MetaErrorT1 (tok, - 'attempting to access {%1Wad} before it has been initialized', sym) + IF unique + THEN + GenerateNoteFlow (lst, i, warning) ; + IssueWarning (tok, + 'attempting to access ', ' before it has been initialized', + sym, warning) + END END ELSE Trace ("checkReadInit call VarCheckReadInit using GetMode (%d)", sym) ; - IF NOT VarCheckReadInit (sym, GetMode (sym)) + IF (NOT VarCheckReadInit (sym, GetMode (sym))) AND IsUniqueWarning (tok) THEN - MetaErrorT1 (tok, - 'attempting to access {%1Wad} before it has been initialized', sym) + GenerateNoteFlow (lst, i, warning) ; + IssueWarning (tok, + 'attempting to access ', + ' before it has been initialized', + sym, warning) END END END @@ -757,7 +916,7 @@ BEGIN (IsGlobalVar (sym) OR IsVarAParam (sym) OR ContainsVariant (GetSType (sym)) OR IsArray (GetSType (sym)) OR IsSet (GetSType (sym)) OR - IsUnbounded (GetSType (sym))) + IsUnbounded (GetSType (sym)) OR IsVarArrayRef (sym)) END IsExempt ; @@ -768,10 +927,11 @@ END IsExempt ; PROCEDURE CheckBinary (procSym, op1tok, op1, op2tok, op2, - op3tok, op3: CARDINAL) ; + op3tok, op3: CARDINAL; warning: BOOLEAN; + lst: List; i: CARDINAL) ; BEGIN - CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE) ; - CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) ; + CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE, warning, lst, i) ; + CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ; SetVarInitialized (op1, FALSE) END CheckBinary ; @@ -782,9 +942,10 @@ END CheckBinary ; PROCEDURE CheckUnary (procSym, lhstok, lhs, - rhstok, rhs: CARDINAL) ; + rhstok, rhs: CARDINAL; warning: BOOLEAN; + lst: List; i: CARDINAL) ; BEGIN - CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE) ; + CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, lst, i) ; SetVarInitialized (lhs, FALSE) END CheckUnary ; @@ -793,13 +954,15 @@ END CheckUnary ; CheckXIndr - *) -PROCEDURE CheckXIndr (procSym, lhstok, lhs, type, rhstok, rhs: CARDINAL) ; +PROCEDURE CheckXIndr (procSym, lhstok, lhs, type, + rhstok, rhs: CARDINAL; warning: BOOLEAN; + bblst: List; i: CARDINAL) ; VAR lst : List ; vsym: CARDINAL ; BEGIN - CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE) ; - CheckDeferredRecordAccess (procSym, lhstok, lhs, FALSE) ; + CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, bblst, i) ; + CheckDeferredRecordAccess (procSym, lhstok, lhs, FALSE, warning, bblst, i) ; (* Now see if we know what lhs is pointing to and set fields if necessary. *) vsym := getAlias (lhs) ; IF (vsym # lhs) AND (GetSType (vsym) = type) @@ -824,11 +987,13 @@ END CheckXIndr ; CheckIndrX - *) -PROCEDURE CheckIndrX (procSym, lhstok, lhs, type, rhstok, rhs: CARDINAL) ; +PROCEDURE CheckIndrX (procSym, lhstok, lhs, type, rhstok, rhs: CARDINAL; + warning: BOOLEAN; + lst: List; i: CARDINAL) ; BEGIN - CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE) ; - CheckDeferredRecordAccess (procSym, rhstok, rhs, TRUE) ; - SetVarInitialized (lhs, FALSE) + CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, lst, i) ; + CheckDeferredRecordAccess (procSym, rhstok, rhs, TRUE, warning, lst, i) ; + SetVarInitialized (lhs, IsVarAParam (rhs)) END CheckIndrX ; @@ -846,12 +1011,13 @@ END CheckRecordField ; CheckBecomes - *) -PROCEDURE CheckBecomes (procSym, destok, des, exprtok, expr: CARDINAL) ; +PROCEDURE CheckBecomes (procSym, destok, des, exprtok, expr: CARDINAL; + warning: BOOLEAN; bblst: List; i: CARDINAL) ; VAR lst : List ; vsym: CARDINAL ; BEGIN - CheckDeferredRecordAccess (procSym, exprtok, expr, FALSE) ; + CheckDeferredRecordAccess (procSym, exprtok, expr, FALSE, warning, bblst, i) ; SetupAlias (des, expr) ; SetVarInitialized (des, FALSE) ; (* Now see if we know what lhs is pointing to and set fields if necessary. *) @@ -872,10 +1038,11 @@ END CheckBecomes ; CheckComparison - *) -PROCEDURE CheckComparison (procSym, op1tok, op1, op2tok, op2: CARDINAL) ; +PROCEDURE CheckComparison (procSym, op1tok, op1, op2tok, op2: CARDINAL; + warning: BOOLEAN; lst: List; i: CARDINAL) ; BEGIN - CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE) ; - CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE) + CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE, warning, lst, i) ; + CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE, warning, lst, i) END CheckComparison ; @@ -916,7 +1083,8 @@ END stop ; CheckReadBeforeInitQuad - *) -PROCEDURE CheckReadBeforeInitQuad (procSym: CARDINAL; quad: CARDINAL) : BOOLEAN ; +PROCEDURE CheckReadBeforeInitQuad (procSym: CARDINAL; quad: CARDINAL; + warning: BOOLEAN; lst: List; i: CARDINAL) : BOOLEAN ; VAR op : QuadOperator ; op1, op2, op3 : CARDINAL ; @@ -949,7 +1117,7 @@ BEGIN IfLessOp, IfLessEquOp, IfGreOp, - IfGreEquOp : CheckComparison (procSym, op1tok, op1, op2tok, op2) | + IfGreEquOp : CheckComparison (procSym, op1tok, op1, op2tok, op2, warning, lst, i) | TryOp, ReturnOp, CallOp, @@ -960,26 +1128,27 @@ BEGIN (* Variable references. *) InclOp, - ExclOp : CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE) ; - CheckDeferredRecordAccess (procSym, op1tok, op1, TRUE) ; - CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) | - NegateOp : CheckUnary (procSym, op1tok, op1, op3tok, op3) | - BecomesOp : CheckBecomes (procSym, op1tok, op1, op3tok, op3) | + ExclOp : CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE, warning, lst, i) ; + CheckDeferredRecordAccess (procSym, op1tok, op1, TRUE, warning, lst, i) ; + CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) | + NegateOp : CheckUnary (procSym, op1tok, op1, op3tok, op3, warning, lst, i) | + BecomesOp : CheckBecomes (procSym, op1tok, op1, op3tok, op3, warning, lst, i) | UnboundedOp, FunctValueOp, + StandardFunctionOp, HighOp, SizeOp : SetVarInitialized (op1, FALSE) | AddrOp : CheckAddr (procSym, op1tok, op1, op3tok, op3) | ReturnValueOp : SetVarInitialized (op1, FALSE) | NewLocalVarOp : | - ParamOp : CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE) ; - CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) ; + ParamOp : CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE, warning, lst, i) ; + CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ; IF (op1 > 0) AND (op1 <= NoOfParam (op2)) AND IsVarParam (op2, op1) THEN SetVarInitialized (op3, TRUE) END | - ArrayOp : CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE) ; + ArrayOp : CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ; SetVarInitialized (op1, TRUE) | RecordFieldOp : CheckRecordField (procSym, op1tok, op1, op2tok, op2) | LogicalShiftOp, @@ -1002,14 +1171,43 @@ BEGIN DivFloorOp, ModTruncOp, DivTruncOp : CheckBinary (procSym, - op1tok, op1, op2tok, op2, op3tok, op3) | - XIndrOp : CheckXIndr (procSym, op1tok, op1, op2, op3tok, op3) | - IndrXOp : CheckIndrX (procSym, op1tok, op1, op2, op3tok, op3) | - RangeCheckOp : | + op1tok, op1, op2tok, op2, op3tok, op3, warning, lst, i) | + XIndrOp : CheckXIndr (procSym, op1tok, op1, op2, op3tok, op3, warning, lst, i) | + IndrXOp : CheckIndrX (procSym, op1tok, op1, op2, op3tok, op3, warning, lst, i) | SaveExceptionOp : SetVarInitialized (op1, FALSE) | - RestoreExceptionOp: CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE) + RestoreExceptionOp: CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE, warning, lst, i) | + + SubrangeLowOp, + SubrangeHighOp : InternalError ('quadruples should have been resolved') | + ElementSizeOp, + BuiltinConstOp, (* Nothing to do, it is assigning a constant to op1 (also a const). *) + BuiltinTypeInfoOp, (* Likewise assigning op1 (const) with a type. *) + ProcedureScopeOp, + InitEndOp, + InitStartOp, + FinallyStartOp, + FinallyEndOp, + CatchBeginOp, + CatchEndOp, + ThrowOp, + StartDefFileOp, + StartModFileOp, + EndFileOp, + CodeOnOp, + CodeOffOp, + ProfileOnOp, + ProfileOffOp, + OptimizeOnOp, + OptimizeOffOp, + InlineOp, + LineNumberOp, + StatementNoteOp, + SavePriorityOp, + RestorePriorityOp, + RangeCheckOp, + ModuleScopeOp, + ErrorOp : | - ELSE END ; RETURN FALSE END CheckReadBeforeInitQuad ; @@ -1019,7 +1217,9 @@ END CheckReadBeforeInitQuad ; FilterCheckReadBeforeInitQuad - *) -PROCEDURE FilterCheckReadBeforeInitQuad (procSym: CARDINAL; start: CARDINAL) : BOOLEAN ; +PROCEDURE FilterCheckReadBeforeInitQuad (procSym: CARDINAL; start: CARDINAL; + warning: BOOLEAN; + lst: List; i: CARDINAL) : BOOLEAN ; VAR Op : QuadOperator ; Op1, Op2, Op3: CARDINAL ; @@ -1027,7 +1227,7 @@ BEGIN GetQuad (start, Op, Op1, Op2, Op3) ; IF (Op # RangeCheckOp) AND (Op # StatementNoteOp) THEN - RETURN CheckReadBeforeInitQuad (procSym, start) + RETURN CheckReadBeforeInitQuad (procSym, start, warning, lst, i) END ; RETURN FALSE END FilterCheckReadBeforeInitQuad ; @@ -1038,43 +1238,366 @@ END FilterCheckReadBeforeInitQuad ; *) PROCEDURE CheckReadBeforeInitFirstBasicBlock (procSym: CARDINAL; - start, end: CARDINAL) ; + start, end: CARDINAL; + warning: BOOLEAN; + lst: List; i: CARDINAL) ; BEGIN - ForeachLocalSymDo (procSym, SetVarUninitialized) ; LOOP - IF FilterCheckReadBeforeInitQuad (procSym, start) OR (start = end) + IF FilterCheckReadBeforeInitQuad (procSym, start, warning, lst, i) THEN - RETURN END ; - start := GetNextQuad (start) + IF start = end + THEN + RETURN + ELSE + start := GetNextQuad (start) + END END END CheckReadBeforeInitFirstBasicBlock ; (* - VariableAnalysis - checks to see whether a variable is: + bbArrayKill - +*) + +PROCEDURE bbArrayKill ; +VAR + i, h : CARDINAL ; + bbPtr: bbEntry ; +BEGIN + h := Indexing.HighIndice (bbArray) ; + i := 1 ; + WHILE i <= h DO + bbPtr := Indexing.GetIndice (bbArray, i) ; + bbPtr^.next := bbFreeList ; + bbFreeList := bbPtr ; + INC (i) + END ; + bbArray := Indexing.KillIndex (bbArray) +END bbArrayKill ; - read before it has been initialized + +(* + DumpBBEntry - *) -PROCEDURE VariableAnalysis (Start, End: CARDINAL) ; +PROCEDURE DumpBBEntry (bbPtr: bbEntry; procSym: CARDINAL) ; +BEGIN + printf4 ("bb %d: scope %d: quads: %d .. %d", + bbPtr^.indexBB, procSym, bbPtr^.start, bbPtr^.end) ; + IF bbPtr^.first + THEN + printf0 (" first") + END ; + IF bbPtr^.endCall + THEN + printf0 (" endcall") + END ; + IF bbPtr^.endGoto + THEN + printf0 (" endgoto") + END ; + IF bbPtr^.endCond + THEN + printf0 (" endcond") + END ; + IF bbPtr^.topOfLoop + THEN + printf0 (" topofloop") + END ; + IF bbPtr^.condBB # 0 + THEN + printf1 (" cond %d", bbPtr^.condBB) + END ; + IF bbPtr^.nextBB # 0 + THEN + printf1 (" next %d", bbPtr^.nextBB) + END ; + printf0 ("\n") +END DumpBBEntry ; + + +(* + DumpBBArray - +*) + +PROCEDURE DumpBBArray (procSym: CARDINAL) ; VAR - Op : QuadOperator ; - Op1, Op2, Op3: CARDINAL ; + bbPtr: bbEntry ; + i, n : CARDINAL ; BEGIN - IF UninitVariableChecking + i := 1 ; + n := Indexing.HighIndice (bbArray) ; + WHILE i <= n DO + bbPtr := Indexing.GetIndice (bbArray, i) ; + DumpBBEntry (bbPtr, procSym) ; + INC (i) + END ; + i := 1 ; + WHILE i <= n DO + bbPtr := Indexing.GetIndice (bbArray, i) ; + printf4 ("bb %d: scope %d: quads: %d .. %d\n", + bbPtr^.indexBB, procSym, bbPtr^.start, bbPtr^.end) ; + DisplayQuadRange (procSym, bbPtr^.start, bbPtr^.end) ; + INC (i) + END +END DumpBBArray ; + + +(* + DumpBBSequence - +*) + +PROCEDURE DumpBBSequence (procSym: CARDINAL; lst: List) ; +VAR + arrayindex, + listindex, n: CARDINAL ; +BEGIN + n := NoOfItemsInList (lst) ; + listindex := 1 ; + printf0 ("=============\n"); + printf0 (" checking sequence:"); + WHILE listindex <= n DO + arrayindex := GetItemFromList (lst, listindex) ; + printf1 (" [%d]", listindex) ; + INC (listindex) + END ; + printf0 ("\n") +END DumpBBSequence ; + + +(* + TestBBSequence - +*) + +PROCEDURE TestBBSequence (procSym: CARDINAL; lst: List) ; +VAR + bbPtr : bbEntry ; + bbi, + i, n : CARDINAL ; + warning: BOOLEAN ; (* Should we issue a warning rather than a note? *) +BEGIN + IF Debugging THEN - GetQuad (Start, Op, Op1, Op2, Op3) ; - CASE Op OF + DumpBBSequence (procSym, lst) + END ; + ForeachLocalSymDo (procSym, SetVarUninitialized) ; + initBlock ; + n := NoOfItemsInList (lst) ; + i := 1 ; + warning := TRUE ; + WHILE i <= n DO + bbi := GetItemFromList (lst, i) ; + bbPtr := Indexing.GetIndice (bbArray, bbi) ; + CheckReadBeforeInitFirstBasicBlock (procSym, bbPtr^.start, bbPtr^.end, warning, lst, i) ; + IF bbPtr^.endCond + THEN + (* Check to see if we are moving into an conditional block in which case + we will issue a note. *) + warning := FALSE + END ; + INC (i) + END ; + killBlock +END TestBBSequence ; - NewLocalVarOp: initBlock ; - CheckReadBeforeInitFirstBasicBlock (Op3, Start, End) ; - killBlock +(* + CreateBBPermultations - +*) + +PROCEDURE CreateBBPermultations (procSym: CARDINAL; i: CARDINAL; lst: List) ; +VAR + duplst: List ; + iPtr : bbEntry ; +BEGIN + IF i = 0 + THEN + TestBBSequence (procSym, lst) + ELSE + iPtr := Indexing.GetIndice (bbArray, i) ; + IF iPtr^.topOfLoop + THEN + TestBBSequence (procSym, lst) ELSE + duplst := DuplicateList (lst) ; + IncludeItemIntoList (duplst, i) ; + IF iPtr^.endCall + THEN + TestBBSequence (procSym, duplst) + ELSIF iPtr^.endGoto + THEN + CreateBBPermultations (procSym, iPtr^.nextBB, duplst) + ELSIF UninitVariableConditionalChecking AND iPtr^.endCond + THEN + CreateBBPermultations (procSym, iPtr^.nextBB, duplst) ; + CreateBBPermultations (procSym, iPtr^.condBB, duplst) + ELSIF iPtr^.endCond + THEN + TestBBSequence (procSym, duplst) + ELSE + (* Fall through. *) + CreateBBPermultations (procSym, iPtr^.nextBB, duplst) + END ; + KillList (duplst) END END -END VariableAnalysis ; +END CreateBBPermultations ; + + +(* + ScopeBlockVariableAnalysis - checks to see whether a variable is + read before it has been initialized. +*) + +PROCEDURE ScopeBlockVariableAnalysis (Scope: CARDINAL; + Start, End: CARDINAL) ; +VAR + bb : BasicBlock ; + lst: List ; +BEGIN + IF UninitVariableChecking + THEN + bbArray := Indexing.InitIndex (1) ; + bb := InitBasicBlocksFromRange (Scope, Start, End) ; + ForeachBasicBlockDo (bb, AppendEntry) ; + KillBasicBlocks (bb) ; + GenerateCFG ; + IF Scope # NulSym + THEN + InitList (lst) ; + IF Debugging + THEN + DumpBBArray (Scope) ; + IF UninitVariableConditionalChecking + THEN + printf0 ("UninitVariableConditionalChecking is TRUE\n") + END + END ; + CreateBBPermultations (Scope, 1, lst) ; + KillList (lst) + END ; + bbArrayKill + END +END ScopeBlockVariableAnalysis ; + + +(* + GetOp3 - +*) + +PROCEDURE GetOp3 (quad: CARDINAL) : CARDINAL ; +VAR + op: QuadOperator ; + op1, op2, op3: CARDINAL ; +BEGIN + GetQuad (quad, op, op1, op2, op3) ; + RETURN op3 +END GetOp3 ; + + +(* + getBBindex - return the basic block index which starts with quad. +*) + +PROCEDURE getBBindex (quad: CARDINAL) : CARDINAL ; +VAR + iPtr : bbEntry ; + i, high: CARDINAL ; +BEGIN + i := 1 ; + high := Indexing.HighIndice (bbArray) ; + WHILE i <= high DO + iPtr := Indexing.GetIndice (bbArray, i) ; + IF iPtr^.start = quad + THEN + RETURN iPtr^.indexBB + END ; + INC (i) + END ; + RETURN 0 +END getBBindex ; + + +(* + GenerateCFG - +*) + +PROCEDURE GenerateCFG ; +VAR + iPtr : bbEntry ; + next, + i, high: CARDINAL ; +BEGIN + i := 1 ; + high := Indexing.HighIndice (bbArray) ; + WHILE i <= high DO + iPtr := Indexing.GetIndice (bbArray, i) ; + IF IsKillLocalVar (iPtr^.end) OR IsReturn (iPtr^.end) + THEN + (* Nothing to do as we have reached the end of this scope. *) + ELSE + next := GetNextQuad (iPtr^.end) ; + iPtr^.nextQuad := next ; + iPtr^.nextBB := getBBindex (next) ; + IF iPtr^.endCond + THEN + iPtr^.condQuad := GetOp3 (iPtr^.end) ; + iPtr^.condBB := getBBindex (iPtr^.condQuad) + END + END ; + INC (i) + END +END GenerateCFG ; + + +(* + NewEntry - +*) + +PROCEDURE NewEntry () : bbEntry ; +VAR + bbPtr: bbEntry ; +BEGIN + IF bbFreeList = NIL + THEN + NEW (bbPtr) + ELSE + bbPtr := bbFreeList ; + bbFreeList := bbFreeList^.next + END ; + RETURN bbPtr +END NewEntry ; + + +(* + AppendEntry - +*) + +PROCEDURE AppendEntry (Start, End: CARDINAL) ; +VAR + bbPtr: bbEntry ; + high : CARDINAL ; +BEGIN + high := Indexing.HighIndice (bbArray) ; + bbPtr := NewEntry () ; + WITH bbPtr^ DO + start := Start ; + end := End ; + first := high = 0 ; + endCall := IsCall (End) ; + endGoto := IsGoto (End) ; + endCond := IsConditional (End) ; + topOfLoop := IsBackReference (Start) ; + indexBB := high + 1 ; + nextQuad := 0 ; + condQuad := 0 ; + nextBB := 0 ; + condBB := 0 ; + next := NIL + END ; + Indexing.PutIndice (bbArray, high + 1, bbPtr) +END AppendEntry ; (* @@ -1298,7 +1821,9 @@ END SetupAlias ; PROCEDURE init ; BEGIN - freeList := NIL + freeList := NIL ; + bbFreeList := NIL ; + InitList (errorList) END init ; diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def index c861cff..8c4feed 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.def +++ b/gcc/m2/gm2-compiler/SymbolTable.def @@ -158,6 +158,7 @@ EXPORT QUALIFIED NulSym, PutDefLink, PutModLink, PutModuleBuiltin, + PutVarArrayRef, IsVarArrayRef, PutConstSet, PutConstructor, @@ -3562,6 +3563,20 @@ PROCEDURE PutModuleBuiltin (sym: CARDINAL; value: BOOLEAN) ; (* + PutVarArrayRef - assigns ArrayRef field with value. +*) + +PROCEDURE PutVarArrayRef (sym: CARDINAL; value: BOOLEAN) ; + + +(* + IsVarArrayRef - returns ArrayRef field value. +*) + +PROCEDURE IsVarArrayRef (sym: CARDINAL) : BOOLEAN ; + + +(* VarCheckReadInit - returns TRUE if sym has been initialized. *) diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod index c10e20c..73528b5 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.mod +++ b/gcc/m2/gm2-compiler/SymbolTable.mod @@ -525,6 +525,8 @@ TYPE IsWritten : BOOLEAN ; (* Is variable written to? *) IsSSA : BOOLEAN ; (* Is variable a SSA? *) IsConst : BOOLEAN ; (* Is variable read/only? *) + ArrayRef : BOOLEAN ; (* Is variable used to point *) + (* to an array? *) InitState : LRInitDesc ; (* Initialization state. *) At : Where ; (* Where was sym declared/used *) ReadUsageList, (* list of var read quads *) @@ -4260,6 +4262,7 @@ BEGIN IsWritten := FALSE ; IsSSA := FALSE ; IsConst := FALSE ; + ArrayRef := FALSE ; InitWhereDeclaredTok(tok, At) ; InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used. *) InitList(ReadUsageList[RightValue]) ; @@ -6905,6 +6908,48 @@ END PutConst ; (* + PutVarArrayRef - assigns ArrayRef field with value. +*) + +PROCEDURE PutVarArrayRef (sym: CARDINAL; value: BOOLEAN) ; +VAR + pSym: PtrToSymbol ; +BEGIN + pSym := GetPsym(sym) ; + WITH pSym^ DO + CASE SymbolType OF + + VarSym: Var.ArrayRef := value + + ELSE + InternalError ('expecting VarSym') + END + END +END PutVarArrayRef ; + + +(* + IsVarArrayRef - returns ArrayRef field value. +*) + +PROCEDURE IsVarArrayRef (sym: CARDINAL) : BOOLEAN ; +VAR + pSym: PtrToSymbol ; +BEGIN + pSym := GetPsym(sym) ; + WITH pSym^ DO + CASE SymbolType OF + + VarSym: RETURN (Var.ArrayRef) + + ELSE + InternalError ('expecting VarSym') + END + END +END IsVarArrayRef ; + + +(* PutFieldRecord - places a field, FieldName and FieldType into a record, Sym. VarSym is a optional varient symbol which can be returned by a call to GetVarient(fieldsymbol). The created field diff --git a/gcc/m2/gm2-gcc/init.cc b/gcc/m2/gm2-gcc/init.cc index 834a84e..7bf79cc 100644 --- a/gcc/m2/gm2-gcc/init.cc +++ b/gcc/m2/gm2-gcc/init.cc @@ -103,6 +103,7 @@ EXTERN void _M2_dtoa_init (int argc, char *argv[], char *envp[]); EXTERN void _M2_ldtoa_init (int argc, char *argv[], char *envp[]); EXTERN void _M2_M2Check_init (int argc, char *argv[], char *envp[]); EXTERN void _M2_M2SSA_init (int argc, char *argv[], char *envp[]); +EXTERN void _M2_M2SymInit_init (int argc, char *argv[], char *envp[]); EXTERN void exit (int); EXTERN void M2Comp_compile (const char *filename); EXTERN void RTExceptions_DefaultErrorCatch (void); @@ -195,6 +196,7 @@ init_PerCompilationInit (const char *filename) _M2_PCBuild_init (0, NULL, NULL); _M2_Sets_init (0, NULL, NULL); _M2_M2SSA_init (0, NULL, NULL); + _M2_M2SymInit_init (0, NULL, NULL); _M2_M2Check_init (0, NULL, NULL); M2Comp_compile (filename); } diff --git a/gcc/m2/gm2-gcc/m2options.h b/gcc/m2/gm2-gcc/m2options.h index e203fce4..dd79509 100644 --- a/gcc/m2/gm2-gcc/m2options.h +++ b/gcc/m2/gm2-gcc/m2options.h @@ -136,7 +136,7 @@ EXTERN void M2Options_SetM2Prefix (const char *arg); EXTERN char *M2Options_GetM2Prefix (void); EXTERN void M2Options_SetM2PathName (const char *arg); EXTERN char *M2Options_GetM2PathName (void); -EXTERN void M2Options_SetUninitVariableChecking (bool value); +EXTERN int M2Options_SetUninitVariableChecking (bool value, const char *arg); #undef EXTERN diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc index ae999a3..c21d29b 100644 --- a/gcc/m2/gm2-lang.cc +++ b/gcc/m2/gm2-lang.cc @@ -470,8 +470,9 @@ gm2_langhook_handle_option ( M2Options_SetUnusedParameterChecking (value); return 1; case OPT_Wuninit_variable_checking: - M2Options_SetUninitVariableChecking (value); - return 1; + return M2Options_SetUninitVariableChecking (value, "known"); + case OPT_Wuninit_variable_checking_: + return M2Options_SetUninitVariableChecking (value, arg); case OPT_fm2_strict_type: M2Options_SetStrictTypeChecking (value); return 1; diff --git a/gcc/m2/lang.opt b/gcc/m2/lang.opt index 6dbdf9d..730a1a2 100644 --- a/gcc/m2/lang.opt +++ b/gcc/m2/lang.opt @@ -297,6 +297,10 @@ Wuninit-variable-checking Modula-2 turns on compile time analysis in the first basic block of a procedure detecting access to uninitialized data. +Wuninit-variable-checking= +Modula-2 Joined +turns on compile time analysis to detect access to uninitialized variables, the checking can be specified by: known,cond,all. + B Modula-2 ; Documented in c.opt diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/cascadedif.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/cascadedif.mod new file mode 100644 index 0000000..4468ce0 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/cascadedif.mod @@ -0,0 +1,25 @@ +MODULE cascadedif ; + + +PROCEDURE test ; +VAR + i: CARDINAL ; + p: CARDINAL ; +BEGIN + i := 1 ; + IF i = 1 + THEN + IF p = 1 + THEN + END + ELSE + IF p = 2 + THEN + END + END +END test ; + + +BEGIN + test +END cascadedif. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/switches-uninit-variable-checking-cascade-fail.exp b/gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/switches-uninit-variable-checking-cascade-fail.exp new file mode 100644 index 0000000..f5e0c07 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/cascade/fail/switches-uninit-variable-checking-cascade-fail.exp @@ -0,0 +1,37 @@ +# Expect driver script for GCC Regression Tests +# Copyright (C) 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file was written by Gaius Mulley (gaius.mulley@southwales.ac.uk) +# for GNU Modula-2. + +if $tracelevel then { + strace $tracelevel +} + +# load support procs +load_lib gm2-torture.exp + +gm2_init_pim "${srcdir}/gm2/switches/uninit-variable-checking/cascade/fail" -Wuninit-variable-checking=all + +foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $testcase] then { + continue + } + + gm2-torture-fail $testcase +} -- cgit v1.1 From 5d9fc2aced3a2128527afd4a627424542f238471 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 11 Jul 2023 15:57:33 +0100 Subject: testsuite: Require vectors of doubles for pr97428.c The pr97428.c test assumes support for vectors of doubles, but some targets only support vectors of floats, causing this test to fail with such targets. Limit this test to targets that support vectors of doubles then. gcc/testsuite/ * gcc.dg/vect/pr97428.c: Limit to `vect_double' targets. --- gcc/testsuite/gcc.dg/vect/pr97428.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/pr97428.c b/gcc/testsuite/gcc.dg/vect/pr97428.c index bbd743a..ad64160 100644 --- a/gcc/testsuite/gcc.dg/vect/pr97428.c +++ b/gcc/testsuite/gcc.dg/vect/pr97428.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ typedef struct { double re, im; } dcmlx_t; typedef struct { double re[4], im[4]; } dcmlx4_t; -- cgit v1.1 From 85bd9a549c044ea618b28cc13350d0e769bb3579 Mon Sep 17 00:00:00 2001 From: Carl Love Date: Tue, 11 Jul 2023 12:28:47 -0400 Subject: rs6000: Update the vsx-vector-6.* tests. The vsx-vector-6.h file is included into the processor specific test files vsx-vector-6.p7.c, vsx-vector-6.p8.c, and vsx-vector-6.p9.c. The .h file contains a large number of vsx vector built-in tests. The processor specific files contain the number of instructions that the tests are expected to generate for that processor. The tests are compile only. This patch reworks the tests into a series of files for related tests. The new tests consist of a runnable test to verify the built-in argument types and the functional correctness of each built-in. There is also a compile only test that verifies the built-ins generate the expected number of instructions for the various built-in tests. gcc/testsuite/ * gcc.target/powerpc/vsx-vector-6-func-1op.h: New test file. * gcc.target/powerpc/vsx-vector-6-func-1op-run.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-1op.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-2lop.h: New test file. * gcc.target/powerpc/vsx-vector-6-func-2lop-run.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-2lop.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-2op.h: New test file. * gcc.target/powerpc/vsx-vector-6-func-2op-run.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-2op.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-3op.h: New test file. * gcc.target/powerpc/vsx-vector-6-func-3op-run.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-3op.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-cmp-all.h: New test file. * gcc.target/powerpc/vsx-vector-6-func-cmp-all-run.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-cmp-all.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-cmp.h: New test file. * gcc.target/powerpc/vsx-vector-6-func-cmp-run.c: New test file. * gcc.target/powerpc/vsx-vector-6-func-cmp.c: New test file. * gcc.target/powerpc/vsx-vector-6.h: Remove test file. * gcc.target/powerpc/vsx-vector-6.p7.c: Remove test file. * gcc.target/powerpc/vsx-vector-6.p8.c: Remove test file. * gcc.target/powerpc/vsx-vector-6.p9.c: Remove test file. --- .../gcc.target/powerpc/vsx-vector-6-func-1op-run.c | 98 +++++++++ .../gcc.target/powerpc/vsx-vector-6-func-1op.c | 22 ++ .../gcc.target/powerpc/vsx-vector-6-func-1op.h | 43 ++++ .../powerpc/vsx-vector-6-func-2lop-run.c | 177 ++++++++++++++++ .../gcc.target/powerpc/vsx-vector-6-func-2lop.c | 14 ++ .../gcc.target/powerpc/vsx-vector-6-func-2lop.h | 47 +++++ .../gcc.target/powerpc/vsx-vector-6-func-2op-run.c | 96 +++++++++ .../gcc.target/powerpc/vsx-vector-6-func-2op.c | 21 ++ .../gcc.target/powerpc/vsx-vector-6-func-2op.h | 42 ++++ .../gcc.target/powerpc/vsx-vector-6-func-3op-run.c | 229 +++++++++++++++++++++ .../gcc.target/powerpc/vsx-vector-6-func-3op.c | 17 ++ .../gcc.target/powerpc/vsx-vector-6-func-3op.h | 73 +++++++ .../powerpc/vsx-vector-6-func-cmp-all-run.c | 147 +++++++++++++ .../gcc.target/powerpc/vsx-vector-6-func-cmp-all.c | 17 ++ .../gcc.target/powerpc/vsx-vector-6-func-cmp-all.h | 76 +++++++ .../gcc.target/powerpc/vsx-vector-6-func-cmp-run.c | 92 +++++++++ .../gcc.target/powerpc/vsx-vector-6-func-cmp.c | 16 ++ .../gcc.target/powerpc/vsx-vector-6-func-cmp.h | 40 ++++ gcc/testsuite/gcc.target/powerpc/vsx-vector-6.h | 154 -------------- gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p7.c | 43 ---- gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p8.c | 43 ---- gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p9.c | 42 ---- 22 files changed, 1267 insertions(+), 282 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op-run.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.h create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop-run.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.h create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op-run.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.h create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op-run.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.h create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all-run.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.h create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-run.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.h delete mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6.h delete mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p7.c delete mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p8.c delete mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p9.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op-run.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op-run.c new file mode 100644 index 0000000..f1114dc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op-run.c @@ -0,0 +1,98 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#define DEBUG 0 + +/* Functional test of the one operand vector builtins. */ +#include "vsx-vector-6-func-1op.h" + +/* Macros to check the results of the builtin tests. */ +#define FLOAT_CHECK(NAME) \ + f_result = float_##NAME(f_src); \ + \ + if ((f_result[0] != f_##NAME##_expected[0]) || \ + (f_result[1] != f_##NAME##_expected[1]) || \ + (f_result[2] != f_##NAME##_expected[2]) || \ + (f_result[3] != f_##NAME##_expected[3])) \ + { \ + if (DEBUG) { \ + printf("ERROR: vec_%s (float) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = %f; result[0] = %f\n", \ + f_##NAME##_expected[0], f_result[0]); \ + printf(" expected[1] = %f; result[1] = %f\n", \ + f_##NAME##_expected[1], f_result[1]); \ + printf(" expected[2] = %f; result[2] = %f\n", \ + f_##NAME##_expected[2], f_result[2]); \ + printf(" expected[3] = %f; result[3] = %f\n", \ + f_##NAME##_expected[3], f_result[3]); \ + } else \ + abort(); \ + } + +#define DOUBLE_CHECK(NAME) \ + d_result = double_##NAME(d_src); \ + \ + if ((d_result[0] != d_##NAME##_expected[0]) \ + || (d_result[1] != d_##NAME##_expected[1])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (double) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = %f; result[0] = %f\n", \ + d_##NAME##_expected[0], d_result[0]); \ + printf(" expected[1] = %f; result[1] = %f\n", \ + d_##NAME##_expected[1], d_result[1]); \ + } \ + else \ + abort(); \ + } + +int +main () { + vector float f_src = { 125.44, 23.04, -338.56, 17.64}; + vector float f_result; + vector float f_abs_expected = { 125.44, 23.04, 338.56, 17.64}; + vector float f_ceil_expected = { 126.0, 24.0, -338, 18.0}; + vector float f_floor_expected = { 125.0, 23.0, -339, 17.0}; + vector float f_nearbyint_expected = { 125.0, 23.0, -339, 18.0}; + vector float f_rint_expected = { 125.0, 23.0, -339, 18.0}; + vector float f_sqrt_expected = { 11.2, 4.8, 18.4, 4.2}; + vector float f_trunc_expected = { 125.0, 23.0, -338, 17}; + + vector double d_src = { 125.44, -338.56}; + vector double d_src_sqrt = { 125.44, 338.56}; + vector double d_abs_src; + vector double d_result; + vector double d_abs_expected = { 125.44, 338.56}; + vector double d_ceil_expected = { 126.0, -338.0}; + vector double d_floor_expected = { 125.0, -339.0}; + vector double d_nearbyint_expected = { 125.0, -339.0}; + vector double d_rint_expected = { 125.0, -339.0}; + vector double d_sqrt_expected = { 11.2, 18.4}; + vector double d_trunc_expected = { 125.0, -338.0}; + + /* Run tests. */ + FLOAT_CHECK (abs) + FLOAT_CHECK (ceil) + FLOAT_CHECK (floor) + FLOAT_CHECK (nearbyint) + FLOAT_CHECK (rint) + FLOAT_CHECK (trunc) + + DOUBLE_CHECK (abs) + DOUBLE_CHECK (ceil) + DOUBLE_CHECK (floor) + DOUBLE_CHECK (nearbyint) + DOUBLE_CHECK (rint) + DOUBLE_CHECK (trunc) + + /* Need to make sure the arguments for sqrt are always positive. Do this + test last as we have to change the input for the test. */ + d_src = vec_abs (d_src); + DOUBLE_CHECK (sqrt) + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.c new file mode 100644 index 0000000..ee905ac --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + +/* This file just generates calls to the various builtins and verifies the + expected number of instructions for each builtin were generated. */ + +#include "vsx-vector-6-func-1op.h" + +/* { dg-final { scan-assembler-times {\mxvabssp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrspip\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrspim\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrspi\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrspic\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrspiz\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvabsdp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrdpip\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrdpim\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrdpi\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrdpic\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvrdpiz\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvsqrtdp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.h b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.h new file mode 100644 index 0000000..e128198 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-1op.h @@ -0,0 +1,43 @@ +/* The goal is to have both compile tests which verify the desired instruction + generation and to functionally test the builtins for correctness. This is + done in separate test files, vsx-vector-6-func-1op.c and + vsx-vector-6-func-1op-run.c. The vsx-vector-6-func-1op.c test file only + generates the calls so the instruction counts do not include the counts + of the instructions generated as part of the result testing. The result + checking code differs for BE/LE. */ + +#include +#include +#include + +void abort (void); + +#define FLOAT_TEST(NAME) \ + vector float __attribute__ ((noipa)) \ + float_##NAME (vector float f_src) \ + { \ + return vec_##NAME(f_src); \ + } + +FLOAT_TEST (abs) +FLOAT_TEST (ceil) +FLOAT_TEST (floor) +FLOAT_TEST (nearbyint) +FLOAT_TEST (rint) +FLOAT_TEST (trunc) + +#define DOUBLE_TEST(NAME) \ + vector double __attribute__ ((noipa)) \ + double_##NAME (vector double d_src) \ + { \ + return vec_##NAME(d_src); \ + } + + +DOUBLE_TEST (abs) +DOUBLE_TEST (ceil) +DOUBLE_TEST (floor) +DOUBLE_TEST (nearbyint) +DOUBLE_TEST (rint) +DOUBLE_TEST (trunc) +DOUBLE_TEST (sqrt) diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop-run.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop-run.c new file mode 100644 index 0000000..3d7319d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop-run.c @@ -0,0 +1,177 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#define DEBUG 0 + +/* Functional test of the two operand logical vector builtins. */ +#include "vsx-vector-6-func-2lop.h" + +/* Macros to check the results of the builtin tests. */ +#define FLOAT_CHECK(NAME) \ + f_result = vec_##NAME (f_src_a, f_src_b); \ + \ + if ((f_result[0] != f_##NAME##_expected[0]) \ + || (f_result[1] != f_##NAME##_expected[1]) \ + || (f_result[2] != f_##NAME##_expected[2]) \ + || (f_result[3] != f_##NAME##_expected[3])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (float) expected value does not match\n", \ + #NAME); \ + for (i = 0; i < 4; i++) \ + { \ + conv_result.f[i] = f_result[i]; \ + printf(" expected[%d] = 0x%x; result[%d] = 0x%x\n", i, \ + conv_exp.u[i], i, conv_result.u[i]); \ + } \ + } \ + else \ + abort(); \ + } + +#define DOUBLE_CHECK(NAME) \ + d_result = vec_##NAME (d_src_a, d_src_b); \ + \ + if ((d_result[0] != d_##NAME##_expected[0]) \ + || (d_result[1] != d_##NAME##_expected[1])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (double) expected value does not match\n", \ + #NAME); \ + for (i = 0; i < 2; i++) \ + { \ + conv_result.d[i] = d_result[i]; \ + printf(" expected[%d] = 0x%lx; result[%d] = 0x%lx\n", i, \ + conv_exp.ul, i, conv_result.ul); \ + } \ + } \ + else \ + abort(); \ + } + +int +main () { + int i; + + vector float f_src_a = { 1.0, 2.0, 3.0, 4.0}; + vector float f_src_b = { 1.0, 3.0, -3.0, 2.0}; + vector float f_and_expected, f_andc_expected, f_nor_expected, f_or_expected; + vector float f_xor_expected; + vector float f_result; + + vector double d_src_a = { 8.0, 10.0}; + vector double d_src_b = { 12.0, 2.0}; + vector double d_and_expected, d_andc_expected, d_nor_expected; + vector double d_result; + vector double d_or_expected, d_xor_expected; + + /* Calculate expected results. */ + /* AND, float */ + for (i = 0; i < 4; i++) + { + conv_src_a.f[i] = f_src_a[i]; + conv_src_b.f[i] = f_src_b[i]; + conv_exp.u[i] = conv_src_a.u[i] & conv_src_b.u[i]; + f_and_expected[i] = conv_exp.f[i]; + } + + /* ANDC, float */ + for (i = 0; i < 4; i++) + { + conv_src_a.f[i] = f_src_a[i]; + conv_src_b.f[i] = f_src_b[i]; + conv_exp.u[i] = conv_src_a.u[i] & ~conv_src_b.u[i]; + f_andc_expected[i] = conv_exp.f[i]; + } + + /* NOR, max */ + for (i = 0; i < 4; i++) + { + conv_src_a.f[i] = f_src_a[i]; + conv_src_b.f[i] = f_src_b[i]; + conv_exp.u[i] = ~(conv_src_a.u[i] | conv_src_b.u[i]); + f_nor_expected[i] = conv_exp.f[i]; + } + + /* OR, float */ + for (i = 0; i < 4; i++) + { + conv_src_a.f[i] = f_src_a[i]; + conv_src_b.f[i] = f_src_b[i]; + conv_exp.u[i] = conv_src_a.u[i] | conv_src_b.u[i]; + f_or_expected[i] = conv_exp.f[i]; + } + + /* XOR, float */ + for (i = 0; i < 4; i++) + { + conv_src_a.f[i] = f_src_a[i]; + conv_src_b.f[i] = f_src_b[i]; + conv_exp.u[i] = conv_src_a.u[i] ^ conv_src_b.u[i]; + f_xor_expected[i] = conv_exp.f[i]; + } + + /* AND, double */ + for (i = 0; i < 2; i++) + { + conv_src_a.d[i] = d_src_a[i]; + conv_src_b.d[i] = d_src_b[i]; + conv_exp.ul[i] = conv_src_a.ul[i] & conv_src_b.ul[i]; + d_and_expected[i] = conv_exp.d[i]; + } + + /* ANDC, double */ + for (i = 0; i < 2; i++) + { + conv_src_a.d[i] = d_src_a[i]; + conv_src_b.d[i] = d_src_b[i]; + conv_exp.ul[i] = conv_src_a.ul[i] & ~conv_src_b.ul[i]; + d_andc_expected[i] = conv_exp.d[i]; + } + + /* NOR, double */ + for (i = 0; i < 2; i++) + { + conv_src_a.d[i] = d_src_a[i]; + conv_src_b.d[i] = d_src_b[i]; + conv_exp.ul[i] = ~(conv_src_a.ul[i] | conv_src_b.ul[i]); + d_nor_expected[i] = conv_exp.d[i]; + } + + /* OR, double */ + for (i = 0; i < 2; i++) + { + conv_src_a.d[i] = d_src_a[i]; + conv_src_b.d[i] = d_src_b[i]; + conv_exp.ul[i] = conv_src_a.ul[i] | conv_src_b.ul[i]; + d_or_expected[i] = conv_exp.d[i]; + } + + /* XOR, double */ + for (i = 0; i < 2; i++) + { + conv_src_a.d[i] = d_src_a[i]; + conv_src_b.d[i] = d_src_b[i]; + conv_exp.ul[i] = conv_src_a.ul[i] ^ conv_src_b.ul[i]; + d_xor_expected[i] = conv_exp.d[i]; + } + + /* Run tests. */ + FLOAT_CHECK (and) + FLOAT_CHECK (andc) + FLOAT_CHECK (nor) + FLOAT_CHECK (or) + FLOAT_CHECK (xor) + + DOUBLE_CHECK (and) + DOUBLE_CHECK (andc) + DOUBLE_CHECK (nor) + DOUBLE_CHECK (or) + DOUBLE_CHECK (xor) + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.c new file mode 100644 index 0000000..5ec221b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + +/* This file just generates calls to the various builtins and verifies the + expected number of instructions for each builtin were generated. */ + +#include "vsx-vector-6-func-2lop.h" + +/* { dg-final { scan-assembler-times {\mxxland\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxxlandc\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxxlnor\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxxlxor\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxxlor\M} 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.h b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.h new file mode 100644 index 0000000..d1c7cad --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2lop.h @@ -0,0 +1,47 @@ +/* The goal is to have both compile tests which verify the desired instruction + generation and to functionally test the builtins for correctness. This is + done in separate test files, vsx-vector-6-func-2lop.c and + vsx-vector-6-func-2lop-run.c. The vsx-vector-6-func-2lop.c test file only + generates the calls so the instruction counts do not include the counts of + the instructions generated as part of the result testing. The result + checking code differs for BE/LE. */ + + +#include +#include +#include + +union conv_t { + vector float f; + vector unsigned int u; + vector double d; + vector unsigned long ul; +} conv_result, conv_exp, conv_src_a, conv_src_b; + +void abort (void); + +#define FLOAT_TEST(NAME) \ + vector float __attribute__ ((noipa)) \ + float_##NAME (vector float f_src_a, vector float f_src_b) \ + { \ + return vec_##NAME (f_src_a, f_src_b); \ + } + +FLOAT_TEST (and) +FLOAT_TEST (andc) +FLOAT_TEST (nor) +FLOAT_TEST (or) +FLOAT_TEST (xor) + +#define DOUBLE_TEST(NAME) \ + vector double __attribute__ ((noipa)) \ + double_##NAME (vector double d_src_a, vector double d_src_b) \ + { \ + return vec_##NAME (d_src_a, d_src_b); \ + } + +DOUBLE_TEST (and) +DOUBLE_TEST (andc) +DOUBLE_TEST (nor) +DOUBLE_TEST (or) +DOUBLE_TEST (xor) diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op-run.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op-run.c new file mode 100644 index 0000000..24c4db5 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op-run.c @@ -0,0 +1,96 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#define DEBUG 0 + +/* Functional test of the two operand vector builtins. */ +#include "vsx-vector-6-func-2op.h" + +/* Macros to check the results of the builtin tests. */ +#define FLOAT_CHECK(NAME) \ + f_result = float_##NAME(f_src_a, f_src_b); \ + \ + if ((f_result[0] != f_##NAME##_expected[0]) \ + || (f_result[1] != f_##NAME##_expected[1]) \ + || (f_result[2] != f_##NAME##_expected[2]) \ + || (f_result[3] != f_##NAME##_expected[3])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (float) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = %f; result[0] = %f\n", \ + f_##NAME##_expected[0], f_result[0]); \ + printf(" expected[1] = %f; result[1] = %f\n", \ + f_##NAME##_expected[1], f_result[1]); \ + printf(" expected[2] = %f; result[2] = %f\n", \ + f_##NAME##_expected[2], f_result[2]); \ + printf(" expected[3] = %f; result[3] = %f\n", \ + f_##NAME##_expected[3], f_result[3]); \ + } \ + else \ + abort(); \ + } + +#define DOUBLE_CHECK(NAME) \ + d_result = vec_##NAME (d_src_a, d_src_b); \ + \ + if ((d_result[0] != d_##NAME##_expected[0]) \ + || (d_result[1] != d_##NAME##_expected[1])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s(double) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = %f; result[0] = %f\n", \ + d_##NAME##_expected[0], d_result[0]); \ + printf(" expected[1] = %f; result[1] = %f\n", \ + d_##NAME##_expected[1], d_result[1]); \ + } \ + else \ + abort(); \ + } + +void abort (void); + +int +main () { + int i; + vector float f_src_a = { 126.0, 23.0, -338.0, 17.0}; + vector float f_src_b = { 2.00, -4.0, 1.0, 4.0}; + vector float f_result; + vector float f_add_expected = { 128.0, 19.0, -337.0, 21.0}; + vector float f_div_expected = { 63.0, -5.75, -338, 4.25}; + vector float f_max_expected = { 126.0, 23.0, 1.0, 17.0}; + vector float f_min_expected = { 2.0, -4.0, -338.0, 4.0}; + vector float f_mul_expected = { 252, -92.0, -338, 68.0}; + vector float f_sub_expected = { 124.0, 27.0, -339.0, 13.0}; + + vector double d_src_a = { 125.44, -338.56}; + vector double d_src_b = { 4.0, -2.0}; + vector double d_result; + vector double d_add_expected = { 129.44, -340.56}; + vector double d_div_expected = { 31.360000, 169.280000}; + vector double d_max_expected = { 125.44, -2.0}; + vector double d_min_expected = { 4.0, -338.56}; + vector double d_mul_expected = { 501.760000, 677.120000}; + vector double d_sub_expected = { 121.440000, -336.560000}; + + /* Run tests. */ + FLOAT_CHECK (add) + FLOAT_CHECK (div) + FLOAT_CHECK (max) + FLOAT_CHECK (min) + FLOAT_CHECK (mul) + FLOAT_CHECK (sub) + + DOUBLE_CHECK (add) + DOUBLE_CHECK (div) + DOUBLE_CHECK (max) + DOUBLE_CHECK (min) + DOUBLE_CHECK (mul) + DOUBLE_CHECK (sub) + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.c new file mode 100644 index 0000000..62f4530 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + +/* This file just generates calls to the various builtins and verifies the + expected number of instructions for each builtin were generated. */ + +#include "vsx-vector-6-func-2op.h" + +/* { dg-final { scan-assembler-times {\mxvaddsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvdivsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmulsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvsubsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvadddp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvdivdp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmuldp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvsubdp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmaxsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvminsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.h b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.h new file mode 100644 index 0000000..d965809 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-2op.h @@ -0,0 +1,42 @@ +/* The goal is to have both compile tests which verify the desired instruction + generation and to functionally test the builtins for correctness. This is + done in separate test files, vsx-vector-6-func-2op.c and + vsx-vector-6-func-2op-run.c. The vsx-vector-6-func-2opc test file only + generates the calls so the instruction counts do not include the counts of + the instructions generated as part of the result testing. The result + checking code differs for BE/LE. */ + + +#include +#include +#include + +void abort (void); + +#define FLOAT_TEST(NAME) \ + vector float __attribute__ ((noipa)) \ + float_##NAME(vector float f_src_a, vector float f_src_b) \ + { \ + return vec_##NAME (f_src_a, f_src_b); \ + } + +FLOAT_TEST (add) +FLOAT_TEST (div) +FLOAT_TEST (max) +FLOAT_TEST (min) +FLOAT_TEST (mul) +FLOAT_TEST (sub) + +#define DOUBLE_TEST(NAME) \ + vector double __attribute__ ((noipa)) \ + double_##NAME(vector double d_src_a, vector double d_src_b) \ + { \ + return vec_##NAME (d_src_a, d_src_b); \ + } + +DOUBLE_TEST (add) +DOUBLE_TEST (div) +DOUBLE_TEST (max) +DOUBLE_TEST (min) +DOUBLE_TEST (mul) +DOUBLE_TEST (sub) diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op-run.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op-run.c new file mode 100644 index 0000000..2e6ab93 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op-run.c @@ -0,0 +1,229 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#define DEBUG 0 + +/* Functional test of the one operand vector builtins. */ +#include "vsx-vector-6-func-3op.h" + +/* Macros to check the results of the builtin tests. */ +#define FLOAT_CHECK(NAME) \ + f_result = vec_##NAME (f_src_a, f_src_b, f_src_c); \ + \ + if ((f_result[0] != f_##NAME##_expected[0]) \ + || (f_result[1] != f_##NAME##_expected[1]) \ + || (f_result[2] != f_##NAME##_expected[2]) \ + || (f_result[3] != f_##NAME##_expected[3])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (float) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = %f; result[0] = %f\n", \ + f_##NAME##_expected[0], f_result[0]); \ + printf(" expected[1] = %f; result[1] = %f\n", \ + f_##NAME##_expected[1], f_result[1]); \ + printf(" expected[2] = %f; result[2] = %f\n", \ + f_##NAME##_expected[2], f_result[2]); \ + printf(" expected[3] = %f; result[3] = %f\n", \ + f_##NAME##_expected[3], f_result[3]); \ + } \ + else \ + abort(); \ + } + +#define DOUBLE_CHECK(NAME) \ + d_result = vec_##NAME (d_src_a, d_src_b, d_src_c); \ + \ + if ((d_result[0] != d_##NAME##_expected[0]) \ + || (d_result[1] != d_##NAME##_expected[1])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (double) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = %f; result[0] = %f\n", \ + d_##NAME##_expected[0], d_result[0]); \ + printf(" expected[1] = %f; result[1] = %f\n", \ + d_##NAME##_expected[1], d_result[1]); \ + } \ + else \ + abort(); \ + } + +void __attribute__ ((noipa)) +short_tests (vector short ss_src_a, vector short ss_src_b, vector int si_src_c, + vector unsigned short us_src_a, vector unsigned short us_src_b, + vector unsigned int ui_src_c, vector int si_expected, + vector unsigned int ui_expected) +{ + /* These tests were put into a function to ensure the compiler doesn't try to + compute the results at compile time. */ + vector int si_result; + vector unsigned int ui_result; + + /* Vector multiply-sum saturated */ + ui_result = short_msums_unsigned (us_src_a, us_src_b, ui_src_c); + if ((ui_result[0] != ui_expected[0]) + || (ui_result[1] != ui_expected[1]) + || (ui_result[2] != ui_expected[2]) + || (ui_result[3] != ui_expected[3])) +#if DEBUG + { + printf("ERROR: vec_msums (unsigned) expected value does not match\n"); + printf(" expected[0] = %d; result[0] = %d\n", + ui_expected[0], ui_result[0]); + printf(" expected[1] = %d; result[1] = %d\n", + ui_expected[1], ui_result[1]); + printf(" expected[2] = %d; result[2] = %d\n", + ui_expected[2], ui_result[2]); + printf(" expected[3] = %d; result[3] = %d\n", + ui_expected[3], ui_result[3]); + } +#else + abort(); +#endif + + si_result = short_msums_signed (ss_src_a, ss_src_b, si_src_c); + if ((si_result[0] != si_expected[0]) + || (si_result[1] != si_expected[1]) + || (si_result[2] != si_expected[2]) + || (si_result[3] != si_expected[3])) +#if DEBUG + { + printf("ERROR: vec_msums (signed) expected value does not match\n"); + printf(" expected[0] = %d; result[0] = %d\n", + si_expected[0], si_result[0]); + printf(" expected[1] = %d; result[1] = %d\n", + si_expected[1], si_result[1]); + printf(" expected[2] = %d; result[2] = %d\n", + si_expected[2], si_result[2]); + printf(" expected[3] = %d; result[3] = %d\n", + si_expected[3], si_result[3]); + } +#else + abort(); +#endif +} + +void __attribute__ ((noipa)) +vector_sel_test (vector double d_src_a, vector double d_src_b, + vector unsigned long long ull_src_c, + vector bool long long bll_src_c , + vector double d_selectb_expected, + vector double d_selectu_expected) +{ + vector double d_result; + + /* Vector select */ + d_result = double_sel_test (d_src_a, d_src_b, ull_src_c); + + if ((d_result[0] != d_selectu_expected[0]) + || (d_result[1] != d_selectu_expected[1])) +#if DEBUG + { + printf("ERROR: vec_sel (double, unsigned long long) expected value does not match\n"); + printf(" expected[0] = %f; result[0] = %f\n", + d_selectu_expected[0], d_result[0]); + printf(" expected[1] = %f; result[1] = %f\n", + d_selectu_expected[1], d_result[1]); + } +#else + abort(); +#endif + + d_result = bool_sel_test (d_src_a, d_src_b, bll_src_c); + + if ((d_result[0] != d_selectb_expected[0]) + || (d_result[1] != d_selectb_expected[1])) +#if DEBUG + { + printf("ERROR: vec_sel (double, bool long long) expected value does not match\n"); + printf(" expected[0] = %f; result[0] = %f\n", + d_selectb_expected[0], d_result[0]); + printf(" expected[1] = %f; result[1] = %f\n", + d_selectb_expected[1], d_result[1]); + } +#else + abort(); +#endif +} + +void __attribute__ ((noipa)) +vector_permute_test (vector double d_src_a, vector double d_src_b, + vector unsigned char uc_src_c, + vector double d_perm_expected) +{ + vector double d_result; + + /* Vector permute */ + d_result = double_permute_test (d_src_a, d_src_b, uc_src_c); + + if ((d_result[0] != d_perm_expected[0]) + || (d_result[1] != d_perm_expected[1])) +#if DEBUG + { + printf("ERROR: vec_perm (double, unsigned char) expected value does not match\n"); + printf(" expected[0] = %f; result[0] = %f\n", + d_perm_expected[0], d_result[0]); + printf(" expected[1] = %f; result[1] = %f\n", + d_perm_expected[1], d_result[1]); + } +#else + abort(); +#endif + +} + +int +main () { + int i; + + vector unsigned char uc_src_c = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; + vector short ss_src_a = { 1, 2, 3, 4, 5, 6, 7, 8}; + vector short ss_src_b = { -10, 20, 30, 40, 50, 60, 70, 80}; + vector int si_src_c = { 13, -27, 39, 48}; + vector int si_expected = {43, 223, 649, 1178}; + vector unsigned short us_src_a = { 31, 32, 33, 34, 1, 2, 3, 4}; + vector unsigned short us_src_b = { 11, 7, 30, 90, 39, 48, 28, 64}; + vector unsigned int ui_src_c = { 13, 17, 39, 91}; + + vector unsigned int ui_expected = {578, 4067, 174, 431}; + vector float f_src_a = { 126.0, 23.0, -338.0, 17.0}; + vector float f_src_b = { 2.0, -4.0, 1.0, 4.0}; + vector float f_src_c = { 6.0, -8.0, 7.0, 5.0}; + vector float f_madd_expected = { 258.0, -100.0, -331.0, 73.0}; + vector float f_msub_expected = { 246.0, -84.0, -345.0, 63.0}; + vector float f_result; + + vector unsigned long long ull_src_c = {0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF}; + vector bool long long bll_src_c = {0, 0}; + vector double d_src_a = { 125.44, -338.56}; + vector double d_src_b = { 4.0, -2.0}; + vector double d_src_c = { 7.0, -3.0}; + vector double d_madd_expected = { 508.76, 674.12}; + vector double d_msub_expected = { 494.76, 680.12}; + vector double d_selectb_expected = { 125.44, -338.56}; + vector double d_selectu_expected = { 4.0, -2.0}; + vector double d_perm_expected = { 125.44, -338.56}; + vector double d_result; + + /* Run tests. */ + short_tests (ss_src_a, ss_src_b, si_src_c, us_src_a, us_src_b, + ui_src_c, si_expected, ui_expected); + + FLOAT_CHECK (madd) + FLOAT_CHECK (msub) + + DOUBLE_CHECK (madd) + DOUBLE_CHECK (msub) + + vector_sel_test (d_src_a, d_src_b, ull_src_c, bll_src_c, d_selectb_expected, + d_selectu_expected); + vector_permute_test (d_src_a, d_src_b, uc_src_c, d_perm_expected); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.c new file mode 100644 index 0000000..e21030b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + +/* This file just generates calls to the various builtins and verifies the + expected number of instructions for each builtin were generated. */ + +#include "vsx-vector-6-func-3op.h" + +/* { dg-final { scan-assembler-times {\mvmsumshs\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvmsumuhs\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmaddmsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmaddmdp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmsubmsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmsubmdp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\m(?:v|xx)permr?\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxxsel\M} 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.h b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.h new file mode 100644 index 0000000..66965ae --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-3op.h @@ -0,0 +1,73 @@ +/* The goal is to have both compile tests which verify the desired instruction + generation and to functionally test the builtins for correctness. This is + done in separate test files, vsx-vector-6-func-3op.c and + vsx-vector-6-func-3op-run.c. The vsx-vector-6-func-3op.c test file only + generates the calls so the instruction counts do not include the counts of + the instructions generated as part of the result testing. The result + checking code differs for BE/LE. */ + +#include +#include +#include + +void abort (void); + +/* Macro to create call to builtin. */ +#define FLOAT_TEST(NAME) \ + vector float __attribute__ ((noipa)) \ + float_##NAME(vector float f_src_a, vector float f_src_b, \ + vector float f_src_c) \ + { \ + return vec_##NAME (f_src_a, f_src_b, f_src_c); \ + } + +FLOAT_TEST (madd) +FLOAT_TEST (msub) + +#define DOUBLE_TEST(NAME) \ + vector double __attribute__ ((noipa)) \ + double_##NAME(vector double d_src_a, vector double d_src_b, \ + vector double d_src_c) \ + { \ + return vec_##NAME (d_src_a, d_src_b, d_src_c); \ + } + +DOUBLE_TEST (madd) +DOUBLE_TEST (msub) + +vector unsigned int __attribute__ ((noipa)) +short_msums_unsigned (vector unsigned short us_src_a, + vector unsigned short us_src_b, + vector unsigned int ui_src_c) +{ + return vec_msums (us_src_a, us_src_b, ui_src_c); +} + +vector int __attribute__ ((noipa)) +short_msums_signed (vector short ss_src_a, vector short ss_src_b, + vector int si_src_c) +{ + return vec_msums (ss_src_a, ss_src_b, si_src_c); +} + +vector double __attribute__ ((noipa)) +double_sel_test (vector double d_src_a, vector double d_src_b, + vector unsigned long long ull_src_c) +{ + return vec_sel (d_src_a, d_src_b, ull_src_c); + } + +vector double __attribute__ ((noipa)) +bool_sel_test (vector double d_src_a, vector double d_src_b, + vector bool long long bll_src_c) +{ + return vec_sel (d_src_a, d_src_b, bll_src_c); +} + +vector double __attribute__ ((noipa)) +double_permute_test (vector double d_src_a, vector double d_src_b, + vector unsigned char uc_src_c) +{ + return vec_perm (d_src_a, d_src_b, uc_src_c); +} + diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all-run.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all-run.c new file mode 100644 index 0000000..223f5bd --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all-run.c @@ -0,0 +1,147 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#define DEBUG 0 + +#include "vsx-vector-6-func-cmp-all.h" + +#define FLOAT_1ARG_CHECK(NAME) \ + f_result = vec_##NAME (f_src); \ + \ + if (f_result != f_##NAME##_expected) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (float) expected value does not match\n", \ + #NAME); \ + printf(" expected = %d; result = %d\n", \ + f_##NAME##_expected, f_result); \ + } \ + else \ + abort(); \ + } + +#define FLOAT_2ARG_CHECK(NAME) \ + f_result = vec_##NAME (f_src_a, f_src_b); \ + \ + if (f_result != f_##NAME##_expected) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (float, float) expected value does not match\n", \ + #NAME); \ + printf(" expected = %d; result = %d\n", \ + f_##NAME##_expected, f_result); \ + } \ + else \ + abort(); \ + } + +#define DOUBLE_1ARG_CHECK(NAME ) \ + d_result = vec_##NAME (d_src); \ + \ + if (d_result != d_##NAME##_expected) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (double) expected value does not match\n", \ + #NAME); \ + printf(" expected = %d; result = %d\n", \ + d_##NAME##_expected, d_result); \ + } \ + else \ + abort(); \ + } + +#define DOUBLE_2ARG_CHECK(NAME) \ + d_result = vec_##NAME (d_src_a, d_src_b); \ + \ + if (d_result != d_##NAME##_expected) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (double, double) expected value does not match\n", \ + #NAME); \ + printf(" expected = %d; result = %d\n", \ + d_##NAME##_expected, d_result); \ + } \ + else \ + abort(); \ + } + +int +main () { + vector float f_src = {126.0, 23.0, -338.0, 17.0}; + vector float f_src_a = {126.0, 23.0, -338.0, 17.0}; + vector float f_src_b = {2.00, 23.0, 1.0, 4.0}; + bool f_result; + bool f_all_eq_expected = 0; + bool f_all_gt_expected = 0; + bool f_all_ge_expected = 0; + bool f_all_lt_expected = 0; + bool f_all_le_expected = 0; + bool f_all_nan_expected = 0; + bool f_all_numeric_expected = 1; + bool f_any_eq_expected = 1; + bool f_any_gt_expected = 1; + bool f_any_ge_expected = 1; + bool f_any_lt_expected = 1; + bool f_any_le_expected = 1; + bool f_any_nan_expected = 0; + bool f_any_numeric_expected = 1; + + vector double d_src = { 125.44, -338.56}; + vector double d_src_a = { 125.44, -338.56}; + vector double d_src_b = d_src_a; + bool d_result; + bool d_all_eq_expected = 1; + bool d_all_gt_expected = 0; + bool d_all_ge_expected = 1; + bool d_all_lt_expected = 0; + bool d_all_le_expected = 1; + bool d_all_nan_expected = 0; + bool d_all_numeric_expected = 1; + bool d_any_eq_expected = 1; + bool d_any_gt_expected = 0; + bool d_any_ge_expected = 1; + bool d_any_lt_expected = 0; + bool d_any_le_expected = 1; + bool d_any_nan_expected = 0; + bool d_any_numeric_expected = 1; + + /* Run tests. */ + FLOAT_1ARG_CHECK (all_nan) + FLOAT_1ARG_CHECK (all_numeric) + FLOAT_1ARG_CHECK (any_nan) + FLOAT_1ARG_CHECK (any_numeric) + + FLOAT_2ARG_CHECK (all_eq) + FLOAT_2ARG_CHECK (all_gt) + FLOAT_2ARG_CHECK (all_ge) + FLOAT_2ARG_CHECK (all_lt) + FLOAT_2ARG_CHECK (all_le) + FLOAT_2ARG_CHECK (any_eq) + FLOAT_2ARG_CHECK (any_gt) + FLOAT_2ARG_CHECK (any_ge) + FLOAT_2ARG_CHECK (any_lt) + FLOAT_2ARG_CHECK (any_le) + + DOUBLE_1ARG_CHECK (all_nan) + DOUBLE_1ARG_CHECK (all_numeric) + DOUBLE_1ARG_CHECK (any_nan) + DOUBLE_1ARG_CHECK (any_numeric) + + DOUBLE_2ARG_CHECK (all_eq) + DOUBLE_2ARG_CHECK (all_gt) + DOUBLE_2ARG_CHECK (all_ge) + DOUBLE_2ARG_CHECK (all_lt) + DOUBLE_2ARG_CHECK (all_le) + DOUBLE_2ARG_CHECK (any_eq) + DOUBLE_2ARG_CHECK (any_gt) + DOUBLE_2ARG_CHECK (any_ge) + DOUBLE_2ARG_CHECK (any_lt) + DOUBLE_2ARG_CHECK (any_le) + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.c new file mode 100644 index 0000000..da9c6aa2 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + +/* This file just generates calls to the various builtins and verifies the + expected number of instructions for each builtin were generated. */ + +#include "vsx-vector-6-func-cmp-all.h" + +/* { dg-final { scan-assembler-times {\mxvcmpeqsp\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgtsp\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgesp\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpeqdp\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgedp\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgtdp\M} 4 } } */ + + diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.h b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.h new file mode 100644 index 0000000..efd2688 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-all.h @@ -0,0 +1,76 @@ +/* The goal is to have both compile tests which verify the desired instruction + generation and to functionally test the builtins for correctness. This is + done in separate test files, vsx-vector-6-func-cmp-all.c and + vsx-vector-6-func-cmp-all-run.c. The vsx-vector-6-func-cmp-all.c test file + only generates the calls so the instruction counts do not include the counts + of the instructions generated as part of the result testing. The result + checking code differs for BE/LE. */ + +#include +#include +#include +#include + +void abort (void); + +#define FLOAT_1ARG_TEST(NAME) \ + bool __attribute__ ((noipa)) \ + float_1arg_##NAME (vector float f_src, bool f_##NAME##_expected) \ + { \ + return vec_##NAME (f_src); \ + } + +FLOAT_1ARG_TEST (all_nan) +FLOAT_1ARG_TEST (all_numeric) +FLOAT_1ARG_TEST (any_nan) +FLOAT_1ARG_TEST (any_numeric) + +#define FLOAT_2ARG_TEST(NAME) \ + bool __attribute__ ((noipa)) \ + float_2arg_##NAME (vector float f_src_a, vector float f_src_b, \ + bool f_##NAME##_expected) \ + { \ + return vec_##NAME (f_src_a, f_src_b); \ + } + +FLOAT_2ARG_TEST (all_eq) +FLOAT_2ARG_TEST (all_gt) +FLOAT_2ARG_TEST (all_ge) +FLOAT_2ARG_TEST (all_lt) +FLOAT_2ARG_TEST (all_le) +FLOAT_2ARG_TEST (any_eq) +FLOAT_2ARG_TEST (any_gt) +FLOAT_2ARG_TEST (any_ge) +FLOAT_2ARG_TEST (any_lt) +FLOAT_2ARG_TEST (any_le) + +#define DOUBLE_1ARG_TEST(NAME ) \ + bool __attribute__ ((noipa)) \ + double_1arg_##NAME (vector double d_src, bool d_##NAME##_expected) \ + { \ + return vec_##NAME (d_src); \ + } + +DOUBLE_1ARG_TEST (all_nan) +DOUBLE_1ARG_TEST (all_numeric) +DOUBLE_1ARG_TEST (any_nan) +DOUBLE_1ARG_TEST (any_numeric) + +#define DOUBLE_2ARG_TEST(NAME) \ + bool __attribute__ ((noipa)) \ + double_2arg_##NAME (vector double d_src_a, vector double d_src_b, \ + bool d_##NAME##_expected) \ + { \ + return vec_##NAME (d_src_a, d_src_b); \ + } + +DOUBLE_2ARG_TEST (all_eq) +DOUBLE_2ARG_TEST (all_gt) +DOUBLE_2ARG_TEST (all_ge) +DOUBLE_2ARG_TEST (all_lt) +DOUBLE_2ARG_TEST (all_le) +DOUBLE_2ARG_TEST (any_eq) +DOUBLE_2ARG_TEST (any_gt) +DOUBLE_2ARG_TEST (any_ge) +DOUBLE_2ARG_TEST (any_lt) +DOUBLE_2ARG_TEST (any_le) diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-run.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-run.c new file mode 100644 index 0000000..f751ef6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp-run.c @@ -0,0 +1,92 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#define DEBUG 0 + +/* This file just generates calls to the various builtins and verifies the + expected number of instructions for each builtin were generated. */ + +#include "vsx-vector-6-func-cmp.h" + +/* Macros to check the results of the builtin tests. */ +#define FLOAT_CHECK(NAME) \ + f_result = vec_##NAME (f_src_a, f_src_b); \ + \ + if ((f_result[0] != f_##NAME##_expected[0]) \ + || (f_result[1] != f_##NAME##_expected[1]) \ + || (f_result[2] != f_##NAME##_expected[2]) \ + || (f_result[3] != f_##NAME##_expected[3])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (float) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = 0x%x; result[0] =0x%x\n", \ + f_##NAME##_expected[0], f_result[0]); \ + printf(" expected[1] = 0x%x; result[1] = 0x%x\n", \ + f_##NAME##_expected[1], f_result[1]); \ + printf(" expected[2] = 0x%x; result[2] = 0x%x\n", \ + f_##NAME##_expected[2], f_result[2]); \ + printf(" expected[3] = 0x%x; result[3] = 0x%x\n", \ + f_##NAME##_expected[3], f_result[3]); \ + } \ + else \ + abort(); \ + } + +#define DOUBLE_CHECK(NAME) \ + d_result = vec_##NAME (d_src_a, d_src_b); \ + \ + if ((d_result[0] != d_##NAME##_expected[0]) \ + || (d_result[1] != d_##NAME##_expected[1])) \ + { \ + if (DEBUG) \ + { \ + printf("ERROR: vec_%s (double) expected value does not match\n", \ + #NAME); \ + printf(" expected[0] = 0x%lx; result[0] = 0x%lx\n", \ + d_##NAME##_expected[0], d_result[0]); \ + printf(" expected[1] = 0x%lx; result[1] = 0x%lx\n", \ + d_##NAME##_expected[1], d_result[1]); \ + } \ + else \ + abort(); \ + } + +int +main () { + int i; + vector float f_src_a = { 126.0, 23.0, -338.0, 17.0}; + vector float f_src_b = { 2.00, 23.0, 1.0, 4.0}; + vector bool f_result; + vector bool int f_cmpeq_expected = {0x0, 0xFFFFFFFF, 0x0, 0x0}; + vector bool int f_cmpgt_expected = {0xFFFFFFFF, 0x0, 0x0, 0xFFFFFFFF}; + vector bool int f_cmpge_expected = {0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0xFFFFFFFF}; + vector bool int f_cmplt_expected = {0x0, 0x0, 0xFFFFFFFF, 0x0}; + vector bool int f_cmple_expected = {0x0, 0xFFFFFFFF, 0xFFFFFFFF, 0x0}; + + vector double d_src_a = { 125.44, -338.56}; + vector double d_src_b = { 4.0, -338.56}; + vector bool long long d_result; + vector bool long long d_cmpeq_expected = {0x0, 0xFFFFFFFFFFFFFFFF}; + vector bool long long d_cmpgt_expected = {0xFFFFFFFFFFFFFFFF, 0x0}; + vector bool long long d_cmpge_expected = {0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF}; + vector bool long long d_cmplt_expected = {0x0, 0x0}; + vector bool long long d_cmple_expected = {0x0, 0xFFFFFFFFFFFFFFFF}; + + FLOAT_CHECK (cmpeq) + FLOAT_CHECK (cmpgt) + FLOAT_CHECK (cmpge) + FLOAT_CHECK (cmplt) + FLOAT_CHECK (cmple) + + DOUBLE_CHECK (cmpeq) + DOUBLE_CHECK (cmpgt) + DOUBLE_CHECK (cmpge) + DOUBLE_CHECK (cmplt) + DOUBLE_CHECK (cmple) + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.c new file mode 100644 index 0000000..5215d8c --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + + +/* This file just generates calls to the various builtins and verifies the + expected number of instructions for each builtin were generated. */ + +#include "vsx-vector-6-func-cmp.h" + +/* { dg-final { scan-assembler-times {\mxvcmpeqsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgtsp\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgesp\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpeqdp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgedp\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvcmpgtdp\M} 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.h b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.h new file mode 100644 index 0000000..cf90cedf --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-func-cmp.h @@ -0,0 +1,40 @@ +/* The goal is to have both compile tests which verify the desired instruction + generation and to functionally test the builtins for correctness. This is + done in separate test files, vsx-vector-6-func-cmp.c and + vsx-vector-6-func-cmp-run.c. The vsx-vector-6-func-cmp.c test file only + generates the calls so the instruction counts do not include the counts of + the instructions generated as part of the result testing. The result + checking code differs for BE/LE. */ + +#include +#include +#include + +void abort (void); + +#define FLOAT_TEST(NAME) \ + vector bool int __attribute__ ((noipa)) \ + float_##NAME (vector float f_src_a, vector float f_src_b) \ + { \ + return vec_##NAME (f_src_a, f_src_b); \ + } + +FLOAT_TEST (cmpeq) +FLOAT_TEST (cmpgt) +FLOAT_TEST (cmpge) +FLOAT_TEST (cmplt) +FLOAT_TEST (cmple) + +#define DOUBLE_TEST(NAME) \ + vector bool long long __attribute__ ((noipa)) \ + double_##NAME (vector double d_src_a, vector double d_src_b) \ + { \ + return vec_##NAME (d_src_a, d_src_b); \ + } + +DOUBLE_TEST (cmpeq) +DOUBLE_TEST (cmpgt) +DOUBLE_TEST (cmpge) +DOUBLE_TEST (cmplt) +DOUBLE_TEST (cmple) + diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.h b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.h deleted file mode 100644 index 0106e8d..0000000 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.h +++ /dev/null @@ -1,154 +0,0 @@ -/* This test code is included into vsx-vector-6.p7.c, vsx-vector-6.p8.c - and vsx-vector-6.p9.c. The .c files have the tests for the number - of instructions generated for each cpu type. */ - -#include - -typedef struct { - vector double d; - vector float f; - vector long sl; - vector int si; - vector short ss; - vector char sc; - vector unsigned int ui; - vector unsigned short int us; - vector unsigned char uc; - vector bool long long bll; - vector bool long bl; - vector bool int bi; - vector bool short bs; - vector bool char bc; -} opnd_t; - -void -func_1op (opnd_t *dst, opnd_t *src) -{ - dst[0].d = vec_abs (src[0].d); - dst[1].d = vec_ceil (src[1].d); - dst[2].d = vec_floor (src[2].d); - dst[3].d = vec_nearbyint (src[3].d); - dst[4].d = vec_rint (src[4].d); - dst[5].d = vec_sqrt (src[5].d); - dst[6].d = vec_trunc (src[6].d); - dst[7].f = vec_trunc (src[7].f); -} - -void -func_2op (opnd_t *dst, opnd_t *src0, opnd_t *src1) -{ - dst[0].d = vec_add (src0[0].d, src1[0].d); - dst[1].d = vec_div (src0[1].d, src1[1].d); - dst[2].d = vec_max (src0[2].d, src1[2].d); - dst[3].uc = vec_max (src0[3].uc, src1[3].uc); - dst[4].d = vec_min (src0[4].d, src1[4].d); - dst[5].d = vec_mul (src0[5].d, src1[5].d); - dst[6].d = vec_sub (src0[6].d, src1[6].d); -} - -void -func_2lop (opnd_t *dst, opnd_t *src0, opnd_t *src1) -{ - dst[0].d = vec_and (src0[0].d, src1[0].d); - dst[1].d = vec_and (src0[1].d, src1[1].bl); - dst[2].d = vec_and (src0[2].bl, src1[2].d); - - dst[3].d = vec_andc (src0[3].d, src1[3].d); - dst[4].d = vec_andc (src0[4].d, src1[4].bl); - dst[5].d = vec_andc (src0[5].bl, src1[5].d); - dst[6].d = vec_andc (src0[6].bll, src1[6].d); - dst[7].d = vec_andc (src0[7].d, src1[7].bll); - dst[8].bi = vec_andc (src0[8].bi, src1[8].bi); - dst[9].bs = vec_andc (src0[9].bs, src1[9].bs); - dst[10].bc = vec_andc (src0[10].bc, src1[10].bc); - dst[11].f = vec_andc (src0[11].f, src1[11].f); - dst[12].f = vec_andc (src0[12].bi, src1[12].f); - dst[13].f = vec_andc (src0[13].f, src1[13].bi); - dst[14].d = vec_andc (src0[14].bll, src1[14].d); - dst[15].d = vec_andc (src0[15].d, src1[15].bll); - - dst[16].d = vec_nor (src0[16].d, src1[16].d); - dst[17].f = vec_nor (src0[17].f, src1[17].f); - dst[18].bi = vec_nor (src0[18].bi, src1[18].bi); - dst[19].bs = vec_nor (src0[19].bs, src1[19].bs); - dst[20].bc = vec_nor (src0[20].bc, src1[20].bc); - - dst[21].d = vec_or (src0[21].d, src1[21].d); - dst[22].d = vec_or (src0[22].d, src1[22].bl); - dst[23].d = vec_or (src0[23].bl, src1[23].d); - dst[24].d = vec_or (src0[24].bll, src1[24].d); - dst[25].d = vec_or (src0[25].d, src1[25].bll); - dst[26].f = vec_or (src0[26].f, src1[26].f); - dst[27].bi = vec_or (src0[27].bi, src1[27].bi); - dst[28].bs = vec_or (src0[28].bs, src1[28].bs); - dst[29].bc = vec_or (src0[29].bc, src1[29].bc); - - dst[30].d = vec_xor (src0[30].d, src1[30].d); - dst[31].d = vec_xor (src0[31].d, src1[31].bl); - dst[32].d = vec_xor (src0[32].bl, src1[32].d); -} - -void -func_cmp (opnd_t *dst, opnd_t *src0, opnd_t *src1) -{ - dst[0].bl = vec_cmpeq (src0[0].d, src1[0].d); - dst[1].bl = vec_cmpgt (src0[1].d, src1[1].d); - dst[2].bl = vec_cmpge (src0[2].d, src1[2].d); - dst[3].bl = vec_cmplt (src0[3].d, src1[3].d); - dst[4].bl = vec_cmple (src0[4].d, src1[4].d); -} - -void -func_all_cmp (int *dst, opnd_t *src0, opnd_t *src1) -{ - dst[0] = vec_all_eq (src0[0].d, src1[0].d); - dst[1] = vec_all_ge (src0[1].d, src1[1].d); - dst[2] = vec_all_gt (src0[2].d, src1[2].d); - dst[3] = vec_all_le (src0[3].d, src1[3].d); - dst[4] = vec_all_lt (src0[4].d, src1[4].d); - dst[5] = vec_all_nan (src0[5].d); - dst[6] = vec_all_ne (src0[6].d, src1[6].d); - dst[7] = vec_all_nge (src0[7].d, src1[7].d); - dst[8] = vec_all_ngt (src0[8].d, src1[8].d); - dst[9] = vec_all_nle (src0[9].d, src1[9].d); - dst[10] = vec_all_nlt (src0[10].d, src1[10].d); - dst[11] = vec_all_numeric (src0[11].d); - dst[12] = vec_any_eq (src0[12].d, src1[12].d); - dst[13] = vec_any_ge (src0[13].d, src1[13].d); - dst[14] = vec_any_gt (src0[14].d, src1[14].d); - dst[15] = vec_any_le (src0[15].d, src1[15].d); - dst[16] = vec_any_lt (src0[16].d, src1[16].d); - dst[17] = vec_any_nan (src0[17].d); - dst[18] = vec_any_ne (src0[18].d, src1[18].d); - dst[19] = vec_any_nge (src0[19].d, src1[19].d); - dst[20] = vec_any_ngt (src0[20].d, src1[20].d); - dst[21] = vec_any_nle (src0[21].d, src1[21].d); - dst[22] = vec_any_nlt (src0[22].d, src1[22].d); - dst[23] = vec_any_numeric (src0[23].d); -} - -void -func_3op (opnd_t *dst, opnd_t *src0, opnd_t *src1, opnd_t *src2) -{ - dst[0].d = vec_madd (src0[0].d, src1[0].d, src2[0].d); - dst[1].d = vec_msub (src0[1].d, src1[1].d, src2[1].d); - dst[2].d = vec_nmadd (src0[2].d, src1[2].d, src2[2].d); - dst[3].d = vec_nmsub (src0[3].d, src1[3].d, src2[3].d); - - dst[4].f = vec_madd (src0[4].f, src1[4].f, src2[4].f); - dst[5].f = vec_msub (src0[5].f, src1[5].f, src2[5].f); - dst[6].f = vec_nmsub (src0[6].f, src1[6].f, src2[6].f); - dst[7].f = vec_nmadd (src0[7].f, src1[7].f, src2[7].f); - -#if defined (__BIG_ENDIAN__) || defined (_ARCH_PWR9) - dst[8].d = vec_perm (src0[8].d, src1[8].d, src2[8].uc); -#else - dst[8].d = vec_perm (src0[8].d, src1[8].d, ~src2[8].uc); -#endif - - dst[9].d = vec_sel (src0[9].d, src1[9].d, src2[9].d); - dst[10].d = vec_sel (src0[10].d, src1[10].d, src2[10].bl); - - dst[11].si = vec_msums(src0[11].ss, src1[11].ss, src2[11].si); - dst[12].ui = vec_msums(src0[12].us, src1[12].us, src2[12].ui); -} diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p7.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p7.c deleted file mode 100644 index ff560dd..0000000 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p7.c +++ /dev/null @@ -1,43 +0,0 @@ -/* { dg-do compile { target lp64 } } */ -/* { dg-skip-if "" { powerpc*-*-darwin* } } */ -/* { dg-require-effective-target powerpc_vsx_ok } */ -/* { dg-options "-O2 -mdejagnu-cpu=power7" } */ - -/* Source code for the test in vsx-vector-6.h */ -#include "vsx-vector-6.h" - -/* { dg-final { scan-assembler-times {\mvmaxub\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvmsumshs\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvmsumuhs\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvperm\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvabsdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvadddp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpeqdp\M} 9 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpgedp\M} 10 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpgtdp\M} 10 } } */ -/* { dg-final { scan-assembler-times {\mxvdivdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmadd[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmadd[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmsub[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmsub[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmuldp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmadd[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmadd[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmsub[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmsub[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpi\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpic\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpim\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpip\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpiz\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrspiz\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvsqrtdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvsubdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxxland\M} 3 } } */ -/* { dg-final { scan-assembler-times {\mxxlandc\M} 13 } } */ -/* { dg-final { scan-assembler-times {\mxxlnor\M} 5 } } */ -/* { dg-final { scan-assembler-times {\mxxlor\M} 9 } } */ -/* { dg-final { scan-assembler-times {\mxxlxor\M} 3 } } */ -/* { dg-final { scan-assembler-times {\mxxsel\M} 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p8.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p8.c deleted file mode 100644 index 49f5bf5..0000000 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p8.c +++ /dev/null @@ -1,43 +0,0 @@ -/* { dg-do compile { target lp64 } } */ -/* { dg-skip-if "" { powerpc*-*-darwin* } } */ -/* { dg-require-effective-target powerpc_p8vector_ok } */ -/* { dg-options "-O2 -mdejagnu-cpu=power8" } */ - -/* Source code for the test in vsx-vector-6.h */ -#include "vsx-vector-6.h" - -/* { dg-final { scan-assembler-times {\mvmaxub\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvmsumshs\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvmsumuhs\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvperm\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvabsdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvadddp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpeqdp\M} 9 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpgedp\M} 10 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpgtdp\M} 10 } } */ -/* { dg-final { scan-assembler-times {\mxvdivdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmadd[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmadd[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmsub[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmsub[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmuldp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmadd[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmadd[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmsub[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmsub[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpi\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpic\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpim\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpip\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpiz\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrspiz\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvsqrtdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvsubdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxxland\M} 3 } } */ -/* { dg-final { scan-assembler-times {\mxxlandc\M} 13 } } */ -/* { dg-final { scan-assembler-times {\mxxlnor\M} 5 } } */ -/* { dg-final { scan-assembler-times {\mxxlor\M} 9 } } */ -/* { dg-final { scan-assembler-times {\mxxlxor\M} 3 } } */ -/* { dg-final { scan-assembler-times {\mxxsel\M} 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p9.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p9.c deleted file mode 100644 index 3fdd9f6..0000000 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6.p9.c +++ /dev/null @@ -1,42 +0,0 @@ -/* { dg-do compile { target lp64 } } */ -/* { dg-skip-if "" { powerpc*-*-darwin* } } */ -/* { dg-require-effective-target powerpc_p9vector_ok } */ -/* { dg-options "-O2 -mdejagnu-cpu=power9" } */ - -/* Source code for the test in vsx-vector-6.h */ -#include "vsx-vector-6.h" - -/* { dg-final { scan-assembler-times {\mvmaxub\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvmsumshs\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mvmsumuhs\M} 1 } } */ -/* { dg-final { scan-assembler-times {\m(?:v|xx)permr?\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvabsdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvadddp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpeqdp\M} 9 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpgedp\M} 10 } } */ -/* { dg-final { scan-assembler-times {\mxvcmpgtdp\M} 10 } } */ -/* { dg-final { scan-assembler-times {\mxvdivdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmadd[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmadd[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmaxdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmindp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmsub[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmuldp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmadd[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmadd[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmsub[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvnmsub[am]sp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpi\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpic\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpim\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpip\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrdpiz\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvrspiz\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvsqrtdp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxvmsub[am]dp\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mxxland\M} 3 } } */ -/* { dg-final { scan-assembler-times {\mxxlandc\M} 13 } } */ -/* { dg-final { scan-assembler-times {\mxxlnor\M} 5 } } */ -/* { dg-final { scan-assembler-times {\mxxlor\M} 9 } } */ -/* { dg-final { scan-assembler-times {\mxxlxor\M} 3 } } */ -/* { dg-final { scan-assembler-times {\mxxsel\M} 2 } } */ -- cgit v1.1 From 47bd559829726f44b9c545cd96db49e57f1fd3c4 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 11 Jul 2023 18:33:52 +0200 Subject: cfg+gcse: Change return type of predicate functions from int to bool Also change some internal variables from int to bool. gcc/ChangeLog: * cfghooks.cc (verify_flow_info): Change "err" variable to bool. * cfghooks.h (struct cfg_hooks): Change return type of verify_flow_info from integer to bool. * cfgrtl.cc (can_delete_note_p): Change return type from int to bool. (can_delete_label_p): Ditto. (rtl_verify_flow_info): Change return type from int to bool and adjust function body accordingly. Change "err" variable to bool. (rtl_verify_flow_info_1): Ditto. (free_bb_for_insn): Change return type to void. (rtl_merge_blocks): Change "b_empty" variable to bool. (try_redirect_by_replacing_jump): Change "fallthru" variable to bool. (verify_hot_cold_block_grouping): Change return type from int to bool. Change "err" variable to bool. (rtl_verify_edges): Ditto. (rtl_verify_bb_insns): Ditto. (rtl_verify_bb_pointers): Ditto. (rtl_verify_bb_insn_chain): Ditto. (rtl_verify_fallthru): Ditto. (rtl_verify_bb_layout): Ditto. (purge_all_dead_edges): Change "purged" variable to bool. * cfgrtl.h (free_bb_for_insn): Change return type from int to void. * postreload-gcse.cc (expr_hasher::equal): Change "equiv_p" to bool. (load_killed_in_block_p): Change return type from int to bool and adjust function body accordingly. (oprs_unchanged_p): Return true/false. (rest_of_handle_gcse2): Change return type to void. * tree-cfg.cc (gimple_verify_flow_info): Change return type from int to bool. Change "err" variable to bool. --- gcc/cfghooks.cc | 38 +++++------ gcc/cfghooks.h | 2 +- gcc/cfgrtl.cc | 170 +++++++++++++++++++++++++------------------------ gcc/cfgrtl.h | 2 +- gcc/postreload-gcse.cc | 34 +++++----- gcc/tree-cfg.cc | 56 ++++++++-------- 6 files changed, 155 insertions(+), 147 deletions(-) (limited to 'gcc') diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc index 5456403..37e0dbc 100644 --- a/gcc/cfghooks.cc +++ b/gcc/cfghooks.cc @@ -102,7 +102,7 @@ DEBUG_FUNCTION void verify_flow_info (void) { size_t *edge_checksum; - int err = 0; + bool err = false; basic_block bb, last_bb_seen; basic_block *last_visited; @@ -118,14 +118,14 @@ verify_flow_info (void) && bb != BASIC_BLOCK_FOR_FN (cfun, bb->index)) { error ("bb %d on wrong place", bb->index); - err = 1; + err = true; } if (bb->prev_bb != last_bb_seen) { error ("prev_bb of %d should be %d, not %d", bb->index, last_bb_seen->index, bb->prev_bb->index); - err = 1; + err = true; } last_bb_seen = bb; @@ -142,18 +142,18 @@ verify_flow_info (void) { error ("verify_flow_info: Block %i has loop_father, but there are no loops", bb->index); - err = 1; + err = true; } if (bb->loop_father == NULL && current_loops != NULL) { error ("verify_flow_info: Block %i lacks loop_father", bb->index); - err = 1; + err = true; } if (!bb->count.verify ()) { error ("verify_flow_info: Wrong count of block %i", bb->index); - err = 1; + err = true; } /* FIXME: Graphite and SLJL and target code still tends to produce edges with no probability. */ @@ -161,13 +161,13 @@ verify_flow_info (void) && !bb->count.initialized_p () && !flag_graphite && 0) { error ("verify_flow_info: Missing count of block %i", bb->index); - err = 1; + err = true; } if (bb->flags & ~cfun->cfg->bb_flags_allocated) { error ("verify_flow_info: unallocated flag set on BB %d", bb->index); - err = 1; + err = true; } FOR_EACH_EDGE (e, ei, bb->succs) @@ -176,7 +176,7 @@ verify_flow_info (void) { error ("verify_flow_info: Duplicate edge %i->%i", e->src->index, e->dest->index); - err = 1; + err = true; } /* FIXME: Graphite and SLJL and target code still tends to produce edges with no probability. */ @@ -185,13 +185,13 @@ verify_flow_info (void) { error ("Uninitialized probability of edge %i->%i", e->src->index, e->dest->index); - err = 1; + err = true; } if (!e->probability.verify ()) { error ("verify_flow_info: Wrong probability of edge %i->%i", e->src->index, e->dest->index); - err = 1; + err = true; } last_visited [e->dest->index] = bb; @@ -208,14 +208,14 @@ verify_flow_info (void) fprintf (stderr, "\nSuccessor: "); dump_edge_info (stderr, e, TDF_DETAILS, 1); fprintf (stderr, "\n"); - err = 1; + err = true; } if (e->flags & ~cfun->cfg->edge_flags_allocated) { error ("verify_flow_info: unallocated edge flag set on %d -> %d", e->src->index, e->dest->index); - err = 1; + err = true; } edge_checksum[e->dest->index] += (size_t) e; @@ -223,7 +223,7 @@ verify_flow_info (void) if (n_fallthru > 1) { error ("wrong amount of branch edges after unconditional jump %i", bb->index); - err = 1; + err = true; } FOR_EACH_EDGE (e, ei, bb->preds) @@ -236,7 +236,7 @@ verify_flow_info (void) fputs ("\nSuccessor: ", stderr); dump_edge_info (stderr, e, TDF_DETAILS, 1); fputc ('\n', stderr); - err = 1; + err = true; } if (ei.index != e->dest_idx) @@ -249,7 +249,7 @@ verify_flow_info (void) fputs ("\nSuccessor: ", stderr); dump_edge_info (stderr, e, TDF_DETAILS, 1); fputc ('\n', stderr); - err = 1; + err = true; } edge_checksum[e->dest->index] -= (size_t) e; @@ -272,7 +272,7 @@ verify_flow_info (void) if (edge_checksum[bb->index]) { error ("basic block %i edge lists are corrupted", bb->index); - err = 1; + err = true; } /* Clean up. */ @@ -280,7 +280,9 @@ verify_flow_info (void) free (edge_checksum); if (cfg_hooks->verify_flow_info) - err |= cfg_hooks->verify_flow_info (); + if (cfg_hooks->verify_flow_info ()) + err = true; + if (err) internal_error ("verify_flow_info failed"); timevar_pop (TV_CFG_VERIFY); diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h index 7c87712..fe405ef 100644 --- a/gcc/cfghooks.h +++ b/gcc/cfghooks.h @@ -78,7 +78,7 @@ struct cfg_hooks const char *name; /* Debugging. */ - int (*verify_flow_info) (void); + bool (*verify_flow_info) (void); void (*dump_bb) (FILE *, basic_block, int, dump_flags_t); void (*dump_bb_for_graph) (pretty_printer *, basic_block); diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc index 1d84b29..36e43d0 100644 --- a/gcc/cfgrtl.cc +++ b/gcc/cfgrtl.cc @@ -83,11 +83,11 @@ static void fixup_reorder_chain (void); void verify_insn_chain (void); static void fixup_fallthru_exit_predecessor (void); -static int can_delete_note_p (const rtx_note *); -static int can_delete_label_p (const rtx_code_label *); +static bool can_delete_note_p (const rtx_note *); +static bool can_delete_label_p (const rtx_code_label *); static basic_block rtl_split_edge (edge); static bool rtl_move_block_after (basic_block, basic_block); -static int rtl_verify_flow_info (void); +static bool rtl_verify_flow_info (void); static basic_block cfg_layout_split_block (basic_block, void *); static edge cfg_layout_redirect_edge_and_branch (edge, basic_block); static basic_block cfg_layout_redirect_edge_and_branch_force (edge, basic_block); @@ -97,14 +97,14 @@ static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block); static edge rtl_redirect_edge_and_branch (edge, basic_block); static basic_block rtl_split_block (basic_block, void *); static void rtl_dump_bb (FILE *, basic_block, int, dump_flags_t); -static int rtl_verify_flow_info_1 (void); +static bool rtl_verify_flow_info_1 (void); static void rtl_make_forwarder_block (edge); static bool rtl_bb_info_initialized_p (basic_block bb); /* Return true if NOTE is not one of the ones that must be kept paired, so that we may simply delete it. */ -static int +static bool can_delete_note_p (const rtx_note *note) { switch (NOTE_KIND (note)) @@ -121,7 +121,7 @@ can_delete_note_p (const rtx_note *note) /* True if a given label can be deleted. */ -static int +static bool can_delete_label_p (const rtx_code_label *label) { return (!LABEL_PRESERVE_P (label) @@ -450,14 +450,13 @@ compute_bb_for_insn (void) /* Release the basic_block_for_insn array. */ -unsigned int +void free_bb_for_insn (void) { rtx_insn *insn; for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if (!BARRIER_P (insn)) BLOCK_FOR_INSN (insn) = NULL; - return 0; } namespace { @@ -865,7 +864,7 @@ rtl_merge_blocks (basic_block a, basic_block b) rtx_insn *b_head = BB_HEAD (b), *b_end = BB_END (b), *a_end = BB_END (a); rtx_insn *del_first = NULL, *del_last = NULL; rtx_insn *b_debug_start = b_end, *b_debug_end = b_end; - int b_empty = 0; + bool b_empty = false; if (dump_file) fprintf (dump_file, "Merging block %d into block %d...\n", b->index, @@ -880,7 +879,7 @@ rtl_merge_blocks (basic_block a, basic_block b) /* Detect basic blocks with nothing but a label. This can happen in particular at the end of a function. */ if (b_head == b_end) - b_empty = 1; + b_empty = true; del_first = del_last = b_head; b_head = NEXT_INSN (b_head); @@ -891,7 +890,7 @@ rtl_merge_blocks (basic_block a, basic_block b) if (NOTE_INSN_BASIC_BLOCK_P (b_head)) { if (b_head == b_end) - b_empty = 1; + b_empty = true; if (! del_last) del_first = b_head; @@ -1056,7 +1055,7 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout) basic_block src = e->src; rtx_insn *insn = BB_END (src); rtx set; - int fallthru = 0; + bool fallthru = false; /* If we are partitioning hot/cold basic blocks, we don't want to mess up unconditional or indirect jumps that cross between hot @@ -1096,7 +1095,7 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout) { if (dump_file) fprintf (dump_file, "Removing jump %i.\n", INSN_UID (insn)); - fallthru = 1; + fallthru = true; /* Selectively unlink whole insn chain. */ if (in_cfglayout) @@ -2496,11 +2495,11 @@ fixup_partitions (void) between hot/cold partitions. This condition will not be true until after reorder_basic_blocks is called. */ -static int +static bool verify_hot_cold_block_grouping (void) { basic_block bb; - int err = 0; + bool err = false; bool switched_sections = false; int current_partition = BB_UNPARTITIONED; @@ -2520,7 +2519,7 @@ verify_hot_cold_block_grouping (void) { error ("multiple hot/cold transitions found (bb %i)", bb->index); - err = 1; + err = true; } else switched_sections = true; @@ -2541,10 +2540,10 @@ verify_hot_cold_block_grouping (void) successor edges. Also verify that the dominance relationship between hot/cold blocks is sane. */ -static int +static bool rtl_verify_edges (void) { - int err = 0; + bool err = false; basic_block bb; FOR_EACH_BB_REVERSE_FN (bb, cfun) @@ -2567,7 +2566,7 @@ rtl_verify_edges (void) { error ("verify_flow_info: " "REG_BR_PROB is set but cfg probability is not"); - err = 1; + err = true; } } else if (XINT (note, 0) @@ -2577,7 +2576,7 @@ rtl_verify_edges (void) error ("verify_flow_info: REG_BR_PROB does not match cfg %i %i", XINT (note, 0), BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ()); - err = 1; + err = true; } } @@ -2597,31 +2596,31 @@ rtl_verify_edges (void) if (!is_crossing) { error ("EDGE_CROSSING incorrectly set across same section"); - err = 1; + err = true; } if (e->flags & EDGE_FALLTHRU) { error ("fallthru edge crosses section boundary in bb %i", e->src->index); - err = 1; + err = true; } if (e->flags & EDGE_EH) { error ("EH edge crosses section boundary in bb %i", e->src->index); - err = 1; + err = true; } if (JUMP_P (BB_END (bb)) && !CROSSING_JUMP_P (BB_END (bb))) { error ("No region crossing jump at section boundary in bb %i", bb->index); - err = 1; + err = true; } } else if (is_crossing) { error ("EDGE_CROSSING missing across section boundary"); - err = 1; + err = true; } if ((e->flags & ~(EDGE_DFS_BACK @@ -2652,18 +2651,18 @@ rtl_verify_edges (void) print_rtl_with_bb (stderr, get_insns (), TDF_BLOCKS | TDF_DETAILS); error ("Region crossing jump across same section in bb %i", bb->index); - err = 1; + err = true; } if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) { error ("missing REG_EH_REGION note at the end of bb %i", bb->index); - err = 1; + err = true; } if (n_eh > 1) { error ("too many exception handling edges in bb %i", bb->index); - err = 1; + err = true; } if (n_branch && (!JUMP_P (BB_END (bb)) @@ -2671,35 +2670,35 @@ rtl_verify_edges (void) || any_condjump_p (BB_END (bb)))))) { error ("too many outgoing branch edges from bb %i", bb->index); - err = 1; + err = true; } if (n_fallthru && any_uncondjump_p (BB_END (bb))) { error ("fallthru edge after unconditional jump in bb %i", bb->index); - err = 1; + err = true; } if (n_branch != 1 && any_uncondjump_p (BB_END (bb))) { error ("wrong number of branch edges after unconditional jump" " in bb %i", bb->index); - err = 1; + err = true; } if (n_branch != 1 && any_condjump_p (BB_END (bb)) && JUMP_LABEL (BB_END (bb)) != BB_HEAD (fallthru->dest)) { error ("wrong amount of branch edges after conditional jump" " in bb %i", bb->index); - err = 1; + err = true; } if (n_abnormal_call && !CALL_P (BB_END (bb))) { error ("abnormal call edges for non-call insn in bb %i", bb->index); - err = 1; + err = true; } if (n_sibcall && !CALL_P (BB_END (bb))) { error ("sibcall edges for non-call insn in bb %i", bb->index); - err = 1; + err = true; } if (n_abnormal > n_eh && !(CALL_P (BB_END (bb)) @@ -2709,7 +2708,7 @@ rtl_verify_edges (void) || any_uncondjump_p (BB_END (bb)))) { error ("abnormal edges for no purpose in bb %i", bb->index); - err = 1; + err = true; } int has_eh = -1; @@ -2721,7 +2720,7 @@ rtl_verify_edges (void) continue; error ("EH incoming edge mixed with non-EH incoming edges " "in bb %i", bb->index); - err = 1; + err = true; break; } } @@ -2743,11 +2742,11 @@ rtl_verify_edges (void) block starts with a basic block note, and that basic block notes and control flow jumps are not found in the middle of the block. */ -static int +static bool rtl_verify_bb_insns (void) { rtx_insn *x; - int err = 0; + bool err = false; basic_block bb; FOR_EACH_BB_REVERSE_FN (bb, cfun) @@ -2762,7 +2761,7 @@ rtl_verify_bb_insns (void) { error ("NOTE_INSN_BASIC_BLOCK is missing for block %d", bb->index); - err = 1; + err = true; } x = NEXT_INSN (x); @@ -2772,7 +2771,7 @@ rtl_verify_bb_insns (void) { error ("NOTE_INSN_BASIC_BLOCK is missing for block %d", bb->index); - err = 1; + err = true; } if (BB_END (bb) == x) @@ -2785,7 +2784,7 @@ rtl_verify_bb_insns (void) { error ("NOTE_INSN_BASIC_BLOCK %d in middle of basic block %d", INSN_UID (x), bb->index); - err = 1; + err = true; } if (x == BB_END (bb)) @@ -2806,10 +2805,10 @@ rtl_verify_bb_insns (void) /* Verify that block pointers for instructions in basic blocks, headers and footers are set appropriately. */ -static int +static bool rtl_verify_bb_pointers (void) { - int err = 0; + bool err = false; basic_block bb; /* Check the general integrity of the basic blocks. */ @@ -2820,7 +2819,7 @@ rtl_verify_bb_pointers (void) if (!(bb->flags & BB_RTL)) { error ("BB_RTL flag not set for block %d", bb->index); - err = 1; + err = true; } FOR_BB_INSNS (bb, insn) @@ -2830,7 +2829,7 @@ rtl_verify_bb_pointers (void) INSN_UID (insn), BLOCK_FOR_INSN (insn) ? BLOCK_FOR_INSN (insn)->index : 0, bb->index); - err = 1; + err = true; } for (insn = BB_HEADER (bb); insn; insn = NEXT_INSN (insn)) @@ -2839,7 +2838,7 @@ rtl_verify_bb_pointers (void) { error ("insn %d in header of bb %d has non-NULL basic block", INSN_UID (insn), bb->index); - err = 1; + err = true; } for (insn = BB_FOOTER (bb); insn; insn = NEXT_INSN (insn)) if (!BARRIER_P (insn) @@ -2847,7 +2846,7 @@ rtl_verify_bb_pointers (void) { error ("insn %d in footer of bb %d has non-NULL basic block", INSN_UID (insn), bb->index); - err = 1; + err = true; } } @@ -2873,16 +2872,19 @@ rtl_verify_bb_pointers (void) In future it can be extended check a lot of other stuff as well (reachability of basic blocks, life information, etc. etc.). */ -static int +static bool rtl_verify_flow_info_1 (void) { - int err = 0; + bool err = false; - err |= rtl_verify_bb_pointers (); + if (rtl_verify_bb_pointers ()) + err = true; - err |= rtl_verify_bb_insns (); + if (rtl_verify_bb_insns ()) + err = true; - err |= rtl_verify_edges (); + if (rtl_verify_edges ()) + err = true; return err; } @@ -2891,11 +2893,11 @@ rtl_verify_flow_info_1 (void) are correct, and that instructions are in exactly one bb and have correct block pointers. */ -static int +static bool rtl_verify_bb_insn_chain (void) { basic_block bb; - int err = 0; + bool err = false; rtx_insn *x; rtx_insn *last_head = get_last_insn (); basic_block *bb_info; @@ -2920,7 +2922,7 @@ rtl_verify_bb_insn_chain (void) { error ("insn %d outside of basic blocks has non-NULL bb field", INSN_UID (x)); - err = 1; + err = true; } } @@ -2928,7 +2930,7 @@ rtl_verify_bb_insn_chain (void) { error ("end insn %d for block %d not found in the insn stream", INSN_UID (end), bb->index); - err = 1; + err = true; } /* Work backwards from the end to the head of the basic block @@ -2941,7 +2943,7 @@ rtl_verify_bb_insn_chain (void) { error ("insn %d is in multiple basic blocks (%d and %d)", INSN_UID (x), bb->index, bb_info[INSN_UID (x)]->index); - err = 1; + err = true; } bb_info[INSN_UID (x)] = bb; @@ -2953,7 +2955,7 @@ rtl_verify_bb_insn_chain (void) { error ("head insn %d for block %d not found in the insn stream", INSN_UID (head), bb->index); - err = 1; + err = true; } last_head = PREV_INSN (x); @@ -2968,7 +2970,7 @@ rtl_verify_bb_insn_chain (void) { error ("insn %d outside of basic blocks has non-NULL bb field", INSN_UID (x)); - err = 1; + err = true; } } free (bb_info); @@ -2979,11 +2981,11 @@ rtl_verify_bb_insn_chain (void) /* Verify that fallthru edges point to adjacent blocks in layout order and that barriers exist after non-fallthru blocks. */ -static int +static bool rtl_verify_fallthru (void) { basic_block bb; - int err = 0; + bool err = false; FOR_EACH_BB_REVERSE_FN (bb, cfun) { @@ -3000,7 +3002,7 @@ rtl_verify_fallthru (void) if (!insn || NOTE_INSN_BASIC_BLOCK_P (insn)) { error ("missing barrier after block %i", bb->index); - err = 1; + err = true; break; } if (BARRIER_P (insn)) @@ -3017,7 +3019,7 @@ rtl_verify_fallthru (void) error ("verify_flow_info: Incorrect blocks for fallthru %i->%i", e->src->index, e->dest->index); - err = 1; + err = true; } else for (insn = NEXT_INSN (BB_END (e->src)); insn != BB_HEAD (e->dest); @@ -3028,7 +3030,7 @@ rtl_verify_fallthru (void) e->src->index, e->dest->index); error ("wrong insn in the fallthru edge"); debug_rtx (insn); - err = 1; + err = true; } } } @@ -3040,11 +3042,11 @@ rtl_verify_fallthru (void) instructions, verify that all expected instructions are inside the basic blocks, and that all returns are followed by barriers. */ -static int +static bool rtl_verify_bb_layout (void) { basic_block bb; - int err = 0; + bool err = false; rtx_insn *x, *y; int num_bb_notes; rtx_insn * const rtx_first = get_insns (); @@ -3118,20 +3120,25 @@ rtl_verify_bb_layout (void) - check that all fallthru edge points to the adjacent blocks - verify that there is a single hot/cold partition boundary after bbro */ -static int +static bool rtl_verify_flow_info (void) { - int err = 0; + bool err = false; - err |= rtl_verify_flow_info_1 (); + if (rtl_verify_flow_info_1 ()) + err = true; - err |= rtl_verify_bb_insn_chain (); + if (rtl_verify_bb_insn_chain ()) + err = true; - err |= rtl_verify_fallthru (); + if (rtl_verify_fallthru ()) + err = true; - err |= rtl_verify_bb_layout (); + if (rtl_verify_bb_layout ()) + err = true; - err |= verify_hot_cold_block_grouping (); + if (verify_hot_cold_block_grouping ()) + err = true; return err; } @@ -3310,7 +3317,7 @@ purge_dead_edges (basic_block bb) gcc_assert (single_succ_edge (bb)->flags == (EDGE_SIBCALL | EDGE_ABNORMAL)); - return 0; + return false; } /* If we don't see a jump insn, we don't know exactly why the block would @@ -3360,15 +3367,12 @@ purge_dead_edges (basic_block bb) bool purge_all_dead_edges (void) { - int purged = false; + bool purged = false; basic_block bb; FOR_EACH_BB_FN (bb, cfun) - { - bool purged_here = purge_dead_edges (bb); - - purged |= purged_here; - } + if (purge_dead_edges (bb)) + purged = true; return purged; } @@ -5018,8 +5022,8 @@ rtl_split_block_before_cond_jump (basic_block bb) return NULL; } -/* Return 1 if BB ends with a call, possibly followed by some - instructions that must stay with the call, 0 otherwise. */ +/* Return true if BB ends with a call, possibly followed by some + instructions that must stay with the call, false otherwise. */ static bool rtl_block_ends_with_call_p (basic_block bb) @@ -5035,7 +5039,7 @@ rtl_block_ends_with_call_p (basic_block bb) return (CALL_P (insn)); } -/* Return 1 if BB ends with a conditional branch, 0 otherwise. */ +/* Return true if BB ends with a conditional branch, false otherwise. */ static bool rtl_block_ends_with_condjump_p (const_basic_block bb) diff --git a/gcc/cfgrtl.h b/gcc/cfgrtl.h index e295134..e175a28 100644 --- a/gcc/cfgrtl.h +++ b/gcc/cfgrtl.h @@ -26,7 +26,7 @@ extern void delete_insn_chain (rtx, rtx_insn *, bool); extern basic_block create_basic_block_structure (rtx_insn *, rtx_insn *, rtx_note *, basic_block); extern void compute_bb_for_insn (void); -extern unsigned int free_bb_for_insn (void); +extern void free_bb_for_insn (void); extern rtx_insn *entry_of_function (void); extern void update_bb_for_insn (basic_block); extern bool contains_no_active_insn_p (const_basic_block); diff --git a/gcc/postreload-gcse.cc b/gcc/postreload-gcse.cc index 1f374ea..f4a560d 100644 --- a/gcc/postreload-gcse.cc +++ b/gcc/postreload-gcse.cc @@ -141,7 +141,7 @@ expr_hasher::hash (const expr *exp) inline bool expr_hasher::equal (const expr *exp1, const expr *exp2) { - int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true); + bool equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true); gcc_assert (!equiv_p || exp1->hash == exp2->hash); return equiv_p; @@ -244,7 +244,7 @@ static void record_last_set_info (rtx, const_rtx, void *); static void record_opr_changes (rtx_insn *); static void find_mem_conflicts (rtx, const_rtx, void *); -static int load_killed_in_block_p (int, rtx, bool); +static bool load_killed_in_block_p (int, rtx, bool); static void reset_opr_set_tables (void); /* Hash table support. */ @@ -529,7 +529,7 @@ oprs_unchanged_p (rtx x, rtx_insn *insn, bool after_insn) const char *fmt; if (x == 0) - return 1; + return true; code = GET_CODE (x); switch (code) @@ -544,7 +544,7 @@ oprs_unchanged_p (rtx x, rtx_insn *insn, bool after_insn) case MEM: if (load_killed_in_block_p (INSN_CUID (insn), x, after_insn)) - return 0; + return false; else return oprs_unchanged_p (XEXP (x, 0), insn, after_insn); @@ -555,7 +555,7 @@ oprs_unchanged_p (rtx x, rtx_insn *insn, bool after_insn) case LABEL_REF: case ADDR_VEC: case ADDR_DIFF_VEC: - return 1; + return true; case PRE_DEC: case PRE_INC: @@ -564,7 +564,7 @@ oprs_unchanged_p (rtx x, rtx_insn *insn, bool after_insn) case PRE_MODIFY: case POST_MODIFY: if (after_insn) - return 0; + return false; break; default: @@ -576,15 +576,15 @@ oprs_unchanged_p (rtx x, rtx_insn *insn, bool after_insn) if (fmt[i] == 'e') { if (! oprs_unchanged_p (XEXP (x, i), insn, after_insn)) - return 0; + return false; } else if (fmt[i] == 'E') for (j = 0; j < XVECLEN (x, i); j++) if (! oprs_unchanged_p (XVECEXP (x, i, j), insn, after_insn)) - return 0; + return false; } - return 1; + return true; } @@ -628,7 +628,7 @@ find_mem_conflicts (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, the hash table construction or redundancy elimination phases start processing a new basic block. */ -static int +static bool load_killed_in_block_p (int uid_limit, rtx x, bool after_insn) { struct modifies_mem *list_entry = modifies_mem_list; @@ -651,7 +651,7 @@ load_killed_in_block_p (int uid_limit, rtx x, bool after_insn) to pure functions are never put on the list, so we need not worry about them. */ if (CALL_P (setter)) - return 1; + return true; /* SETTER must be an insn of some kind that sets memory. Call note_stores to examine each hunk of memory that is modified. @@ -660,11 +660,11 @@ load_killed_in_block_p (int uid_limit, rtx x, bool after_insn) mems_conflict_p = 0; note_stores (setter, find_mem_conflicts, x); if (mems_conflict_p) - return 1; + return true; list_entry = list_entry->next; } - return 0; + return false; } @@ -930,7 +930,7 @@ get_avail_load_store_reg (rtx_insn *insn) } } -/* Return nonzero if the predecessors of BB are "well behaved". */ +/* Return true if the predecessors of BB are "well behaved". */ static bool bb_has_well_behaved_predecessors (basic_block bb) @@ -1416,12 +1416,11 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED) -static unsigned int +static void rest_of_handle_gcse2 (void) { gcse_after_reload_main (get_insns ()); rebuild_jump_labels (get_insns ()); - return 0; } namespace { @@ -1455,7 +1454,8 @@ public: unsigned int execute (function *) final override { - return rest_of_handle_gcse2 (); + rest_of_handle_gcse2 (); + return 0; } }; // class pass_gcse2 diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 4989906..938d063 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -165,7 +165,7 @@ static edge gimple_try_redirect_by_replacing_jump (edge, basic_block); /* Various helpers. */ static inline bool stmt_starts_bb_p (gimple *, gimple *); -static int gimple_verify_flow_info (void); +static bool gimple_verify_flow_info (void); static void gimple_make_forwarder_block (edge); static gimple *first_non_label_stmt (basic_block); static bool verify_gimple_transaction (gtransaction *); @@ -5654,10 +5654,10 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow, bool ice) /* Verifies that the flow information is OK. */ -static int +static bool gimple_verify_flow_info (void) { - int err = 0; + bool err = false; basic_block bb; gimple_stmt_iterator gsi; gimple *stmt; @@ -5668,21 +5668,21 @@ gimple_verify_flow_info (void) || ENTRY_BLOCK_PTR_FOR_FN (cfun)->il.gimple.phi_nodes) { error ("ENTRY_BLOCK has IL associated with it"); - err = 1; + err = true; } if (EXIT_BLOCK_PTR_FOR_FN (cfun)->il.gimple.seq || EXIT_BLOCK_PTR_FOR_FN (cfun)->il.gimple.phi_nodes) { error ("EXIT_BLOCK has IL associated with it"); - err = 1; + err = true; } FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) if (e->flags & EDGE_FALLTHRU) { error ("fallthru to exit from bb %d", e->src->index); - err = 1; + err = true; } FOR_EACH_BB_FN (bb, cfun) @@ -5707,28 +5707,28 @@ gimple_verify_flow_info (void) { error ("nonlocal label %qD is not first in a sequence " "of labels in bb %d", label, bb->index); - err = 1; + err = true; } if (prev_stmt && EH_LANDING_PAD_NR (label) != 0) { error ("EH landing pad label %qD is not first in a sequence " "of labels in bb %d", label, bb->index); - err = 1; + err = true; } if (label_to_block (cfun, label) != bb) { error ("label %qD to block does not match in bb %d", label, bb->index); - err = 1; + err = true; } if (decl_function_context (label) != current_function_decl) { error ("label %qD has incorrect context in bb %d", label, bb->index); - err = 1; + err = true; } } @@ -5742,7 +5742,7 @@ gimple_verify_flow_info (void) { error ("control flow in the middle of basic block %d", bb->index); - err = 1; + err = true; } if (stmt_ends_bb_p (stmt)) @@ -5752,7 +5752,7 @@ gimple_verify_flow_info (void) { error ("label %qD in the middle of basic block %d", gimple_label_label (label_stmt), bb->index); - err = 1; + err = true; } /* Check that no statements appear between a returns_twice call @@ -5781,7 +5781,7 @@ gimple_verify_flow_info (void) error ("returns_twice call is %s in basic block %d", misplaced, bb->index); print_gimple_stmt (stderr, stmt, 0, TDF_SLIM); - err = 1; + err = true; } } if (!is_gimple_debug (stmt)) @@ -5797,7 +5797,8 @@ gimple_verify_flow_info (void) if (gimple_code (stmt) == GIMPLE_LABEL) continue; - err |= verify_eh_edges (stmt); + if (verify_eh_edges (stmt)) + err = true; if (is_ctrl_stmt (stmt)) { @@ -5806,7 +5807,7 @@ gimple_verify_flow_info (void) { error ("fallthru edge after a control statement in bb %d", bb->index); - err = 1; + err = true; } } @@ -5819,7 +5820,7 @@ gimple_verify_flow_info (void) { error ("true/false edge after a non-GIMPLE_COND in bb %d", bb->index); - err = 1; + err = true; } } @@ -5842,7 +5843,7 @@ gimple_verify_flow_info (void) { error ("wrong outgoing edge flags at end of bb %d", bb->index); - err = 1; + err = true; } } break; @@ -5851,7 +5852,7 @@ gimple_verify_flow_info (void) if (simple_goto_p (stmt)) { error ("explicit goto at end of bb %d", bb->index); - err = 1; + err = true; } else { @@ -5864,7 +5865,7 @@ gimple_verify_flow_info (void) { error ("wrong outgoing edge flags at end of bb %d", bb->index); - err = 1; + err = true; } } break; @@ -5880,13 +5881,13 @@ gimple_verify_flow_info (void) | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))) { error ("wrong outgoing edge flags at end of bb %d", bb->index); - err = 1; + err = true; } if (single_succ (bb) != EXIT_BLOCK_PTR_FOR_FN (cfun)) { error ("return edge does not point to exit in bb %d", bb->index); - err = 1; + err = true; } break; @@ -5916,7 +5917,7 @@ gimple_verify_flow_info (void) { error ("found default case not at the start of " "case vector"); - err = 1; + err = true; continue; } if (CASE_LOW (prev) @@ -5927,7 +5928,7 @@ gimple_verify_flow_info (void) fprintf (stderr," is greater than "); print_generic_expr (stderr, c); fprintf (stderr," but comes before it.\n"); - err = 1; + err = true; } prev = c; } @@ -5941,7 +5942,7 @@ gimple_verify_flow_info (void) { error ("extra outgoing edge %d->%d", bb->index, e->dest->index); - err = 1; + err = true; } e->dest->aux = (void *)2; @@ -5950,7 +5951,7 @@ gimple_verify_flow_info (void) { error ("wrong outgoing edge flags at end of bb %d", bb->index); - err = 1; + err = true; } } @@ -5963,7 +5964,7 @@ gimple_verify_flow_info (void) if (label_bb->aux != (void *)2) { error ("missing edge %i->%i", bb->index, label_bb->index); - err = 1; + err = true; } } @@ -5973,7 +5974,8 @@ gimple_verify_flow_info (void) break; case GIMPLE_EH_DISPATCH: - err |= verify_eh_dispatch_edge (as_a (stmt)); + if (verify_eh_dispatch_edge (as_a (stmt))) + err = true; break; default: -- cgit v1.1 From 3b2c523ae31b68fc3b8363b458a55eec53a44365 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Tue, 11 Jul 2023 21:21:25 +0200 Subject: Fortran: formal symbol attributes for intrinsic procedures [PR110288] gcc/fortran/ChangeLog: PR fortran/110288 * symbol.cc (gfc_copy_formal_args_intr): When deriving the formal argument attributes from the actual ones for intrinsic procedure calls, take special care of CHARACTER arguments that we do not wrongly treat them formally as deferred-length. gcc/testsuite/ChangeLog: PR fortran/110288 * gfortran.dg/findloc_10.f90: New test. --- gcc/fortran/symbol.cc | 7 +++++++ gcc/testsuite/gfortran.dg/findloc_10.f90 | 13 +++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/findloc_10.f90 (limited to 'gcc') diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc index 37a9e8f..90023f0 100644 --- a/gcc/fortran/symbol.cc +++ b/gcc/fortran/symbol.cc @@ -4725,6 +4725,13 @@ gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src, formal_arg->sym->attr.flavor = FL_VARIABLE; formal_arg->sym->attr.dummy = 1; + /* Do not treat an actual deferred-length character argument wrongly + as template for the formal argument. */ + if (formal_arg->sym->ts.type == BT_CHARACTER + && !(formal_arg->sym->attr.allocatable + || formal_arg->sym->attr.pointer)) + formal_arg->sym->ts.deferred = false; + if (formal_arg->sym->ts.type == BT_CHARACTER) formal_arg->sym->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL); diff --git a/gcc/testsuite/gfortran.dg/findloc_10.f90 b/gcc/testsuite/gfortran.dg/findloc_10.f90 new file mode 100644 index 0000000..4d5ecd2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/findloc_10.f90 @@ -0,0 +1,13 @@ +! { dg-do run } +! { dg-options "-fdump-tree-original" } +! PR fortran/110288 - FINDLOC and deferred-length character arguments + +program test + character(len=:), allocatable :: array(:) + character(len=:), allocatable :: value + array = ["bb", "aa"] + value = "aa" + if (findloc (array, value, dim=1) /= 2) stop 1 +end program test + +! { dg-final { scan-tree-dump "_gfortran_findloc2_s1 \\(.*, \\.array, \\.value\\)" "original" } } -- cgit v1.1 From 6726bca472645cdc91ae596a9f71de43a8158bbc Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Tue, 11 Jul 2023 13:54:15 -0400 Subject: testsuite: Skip failing analyzer tests on AIX. Some of the analyzer out-of-bounds-diagram tests fail on AIX. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/out-of-bounds-diagram-4.c: Skip on AIX. * gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c: Same. * gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c: Same. * gcc.dg/analyzer/out-of-bounds-diagram-7.c: Same. * gcc.dg/analyzer/out-of-bounds-diagram-13.c: Same. * gcc.dg/analyzer/out-of-bounds-diagram-15.c: Same. --- gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c | 1 + gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c | 1 + gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c | 1 + gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c | 1 + gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c | 1 + gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c | 1 + 6 files changed, 6 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c index dcd1263..9b2d6b304 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-13.c @@ -1,4 +1,5 @@ /* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ +/* { dg-skip-if "" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c index e2a6381..411b84c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-15.c @@ -1,6 +1,7 @@ /* Regression test for ICE with short values of --param=analyzer-text-art-string-ellipsis-threshold=. */ /* { dg-additional-options "-fdiagnostics-text-art-charset=unicode --param=analyzer-text-art-string-ellipsis-threshold=0" } */ +/* { dg-skip-if "" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c index ec8e4ab..d5d7248 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-4.c @@ -1,4 +1,5 @@ /* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ +/* { dg-skip-if "" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c index e82bce9..a0cdcbe 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c @@ -1,4 +1,5 @@ /* { dg-additional-options "-fdiagnostics-text-art-charset=ascii" } */ +/* { dg-skip-if "" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c index 48fa12f..3111a6f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c @@ -1,4 +1,5 @@ /* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ +/* { dg-skip-if "" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c index 25a9acc..5e3f9a7 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-7.c @@ -1,4 +1,5 @@ /* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */ +/* { dg-skip-if "" { powerpc-ibm-aix* } } */ #include -- cgit v1.1 From 9aabf81f40f0ee130646ab5e60d158218d1276cc Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Tue, 11 Jul 2023 14:38:28 +0800 Subject: RISC-V: Optimize permutation codegen with vcompress This patch is to recognize specific permutation pattern which can be applied compress approach. Consider this following case: typedef int8_t vnx64i __attribute__ ((vector_size (64))); 1, 2, 3, 5, 7, 9, 10, 11, 12, 14, 15, 17, 19, 21, 22, 23, 26, 28, 30, 31, \ 37, 38, 41, 46, 47, 53, 54, 55, 60, 61, 62, 63, 76, 77, 78, 79, 80, 81, \ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, \ 100, 101, 102, 103, 104, 105, 106, 107 void __attribute__ ((noinline, noclone)) test_1 (int8_t *x, int8_t *y, int8_t *out) { vnx64i v1 = *(vnx64i*)x; vnx64i v2 = *(vnx64i*)y; vnx64i v3 = __builtin_shufflevector (v1, v2, MASK_64); *(vnx64i*)out = v3; } https://godbolt.org/z/P33nev6cW Before this patch: lui a4,%hi(.LANCHOR0) addi a4,a4,%lo(.LANCHOR0) vl4re8.v v4,0(a4) li a4,64 vsetvli a5,zero,e8,m4,ta,mu vl4re8.v v20,0(a0) vl4re8.v v16,0(a1) vmv.v.x v12,a4 vrgather.vv v8,v20,v4 vmsgeu.vv v0,v4,v12 vsub.vv v4,v4,v12 vrgather.vv v8,v16,v4,v0.t vs4r.v v8,0(a2) ret After this patch: lui a4,%hi(.LANCHOR0) addi a4,a4,%lo(.LANCHOR0) vsetvli a5,zero,e8,m4,ta,ma vl4re8.v v12,0(a1) vl4re8.v v8,0(a0) vlm.v v0,0(a4) vslideup.vi v4,v12,20 vcompress.vm v4,v8,v0 vs4r.v v4,0(a2) ret gcc/ChangeLog: * config/riscv/riscv-protos.h (enum insn_type): Add vcompress optimization. * config/riscv/riscv-v.cc (emit_vlmax_compress_insn): Ditto. (shuffle_compress_patterns): Ditto. (expand_vec_perm_const_1): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-2.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-3.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-4.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-5.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-6.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-1.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-2.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-3.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-4.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-5.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-6.c: New test. --- gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv-v.cc | 156 +++++++++++++++ .../riscv/rvv/autovec/vls-vlmax/compress-1.c | 21 ++ .../riscv/rvv/autovec/vls-vlmax/compress-2.c | 46 +++++ .../riscv/rvv/autovec/vls-vlmax/compress-3.c | 60 ++++++ .../riscv/rvv/autovec/vls-vlmax/compress-4.c | 81 ++++++++ .../riscv/rvv/autovec/vls-vlmax/compress-5.c | 85 ++++++++ .../riscv/rvv/autovec/vls-vlmax/compress-6.c | 95 +++++++++ .../riscv/rvv/autovec/vls-vlmax/compress_run-1.c | 27 +++ .../riscv/rvv/autovec/vls-vlmax/compress_run-2.c | 51 +++++ .../riscv/rvv/autovec/vls-vlmax/compress_run-3.c | 79 ++++++++ .../riscv/rvv/autovec/vls-vlmax/compress_run-4.c | 117 +++++++++++ .../riscv/rvv/autovec/vls-vlmax/compress_run-5.c | 149 ++++++++++++++ .../riscv/rvv/autovec/vls-vlmax/compress_run-6.c | 222 +++++++++++++++++++++ 14 files changed, 1190 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-6.c (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 5766e35..6cd5c66 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -148,6 +148,7 @@ enum insn_type RVV_WIDEN_TERNOP = 4, RVV_SCALAR_MOV_OP = 4, /* +1 for VUNDEF according to vector.md. */ RVV_SLIDE_OP = 4, /* Dest, VUNDEF, source and offset. */ + RVV_COMPRESS_OP = 4, }; enum vlmul_type { diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 8d5bed7..1a61f9a 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1040,6 +1040,24 @@ emit_vlmax_decompress_insn (rtx target, rtx op0, rtx op1, rtx mask) emit_vlmax_masked_gather_mu_insn (target, op1, sel, mask); } +/* Emit compress instruction. */ +static void +emit_vlmax_compress_insn (unsigned icode, rtx *ops) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (dest_mode).require (); + insn_expander e (RVV_COMPRESS_OP, + /* HAS_DEST_P */ true, + /* FULLY_UNMASKED_P */ false, + /* USE_REAL_MERGE_P */ true, + /* HAS_AVL_P */ true, + /* VLMAX_P */ true, dest_mode, + mask_mode); + + e.set_policy (TAIL_ANY); + e.emit_insn ((enum insn_code) icode, ops); +} + /* Emit merge instruction. */ static machine_mode @@ -2573,6 +2591,142 @@ shuffle_merge_patterns (struct expand_vec_perm_d *d) return true; } +/* Recognize the patterns that we can use compress operation to shuffle the + vectors. The perm selector of compress pattern is divided into 2 part: + The first part is the random index number < NUNITS. + The second part is consecutive last N index number >= NUNITS. + + E.g. + v = VEC_PERM_EXPR (v0, v1, selector), + selector = { 0, 2, 6, 7 } + + We can transform such pattern into: + + op1 = vcompress (op0, mask) + mask = { 1, 0, 1, 0 } + v = op1. */ + +static bool +shuffle_compress_patterns (struct expand_vec_perm_d *d) +{ + machine_mode vmode = d->vmode; + poly_int64 vec_len = d->perm.length (); + + if (!vec_len.is_constant ()) + return false; + + int vlen = vec_len.to_constant (); + + /* It's not worthwhile the compress pattern has elemenets < 4 + and we can't modulo indices for compress pattern. */ + if (known_ge (d->perm[vlen - 1], vlen * 2) || vlen < 4) + return false; + + /* Compress pattern doesn't work for one vector. */ + if (d->one_vector_p) + return false; + + /* Compress point is the point that all elements value with index i >= + compress point of the selector are all consecutive series increasing and + each selector value >= NUNTIS. In this case, we could compress all elements + of i < compress point into the op1. */ + int compress_point = -1; + for (int i = 0; i < vlen; i++) + { + if (compress_point < 0 && known_ge (d->perm[i], vec_len)) + { + compress_point = i; + break; + } + } + + /* We don't apply compress approach if we can't find the compress point. */ + if (compress_point < 0) + return false; + + /* It must be series increasing from compress point. */ + if (!d->perm.series_p (compress_point, 1, d->perm[compress_point], 1)) + return false; + + /* We can only apply compress approach when all index values from 0 to + compress point are increasing. */ + for (int i = 1; i < compress_point; i++) + if (known_le (d->perm[i], d->perm[i - 1])) + return false; + + /* Check whether we need to slideup op1 to apply compress approach. + + E.g. For index = { 0, 2, 6, 7}, since d->perm[i - 1] = 7 which + is 2 * NUNITS - 1, so we don't need to slide up. + + For index = { 0, 2, 5, 6}, we need to slide op1 up before + we apply compress approach. */ + bool need_slideup_p = maybe_ne (d->perm[vlen - 1], 2 * vec_len - 1); + + /* If we leave it directly be handled by general gather, + the code sequence will be: + VECTOR LOAD selector + GEU mask, selector, NUNITS + GATHER dest, op0, selector + SUB selector, selector, NUNITS + GATHER dest, op1, selector, mask + Each ALU operation is considered as COST = 1 and VECTOR LOAD is considered + as COST = 4. So, we consider the general gather handling COST = 9. + TODO: This cost is not accurate, we can adjust it by tune info. */ + int general_cost = 9; + + /* If we can use compress approach, the code squence will be: + MASK LOAD mask + COMPRESS op1, op0, mask + If it needs slide up, it will be: + MASK LOAD mask + SLIDEUP op1 + COMPRESS op1, op0, mask + By default, mask load COST = 2. + TODO: This cost is not accurate, we can adjust it by tune info. */ + int compress_cost = 4; + + if (general_cost <= compress_cost) + return false; + + /* Build a mask that is true when selector element is true. */ + machine_mode mask_mode = get_mask_mode (vmode).require (); + rvv_builder builder (mask_mode, vlen, 1); + for (int i = 0; i < vlen; i++) + { + bool is_compress_index = false; + for (int j = 0; j < compress_point; j++) + { + if (known_eq (d->perm[j], i)) + { + is_compress_index = true; + break; + } + } + if (is_compress_index) + builder.quick_push (CONST1_RTX (BImode)); + else + builder.quick_push (CONST0_RTX (BImode)); + } + rtx mask = force_reg (mask_mode, builder.build ()); + + rtx merge = d->op1; + if (need_slideup_p) + { + int slideup_cnt = vlen - (d->perm[vlen - 1].to_constant () % vlen) - 1; + rtx ops[] = {d->target, RVV_VUNDEF (vmode), d->op1, + gen_int_mode (slideup_cnt, Pmode)}; + insn_code icode = code_for_pred_slide (UNSPEC_VSLIDEUP, vmode); + emit_vlmax_slide_insn (icode, ops); + merge = d->target; + } + + insn_code icode = code_for_pred_compress (vmode); + rtx ops[] = {d->target, merge, d->op0, mask}; + emit_vlmax_compress_insn (icode, ops); + return true; +} + /* Recognize decompress patterns: 1. VEC_PERM_EXPR op0 and op1 @@ -2696,6 +2850,8 @@ expand_vec_perm_const_1 (struct expand_vec_perm_d *d) { if (shuffle_merge_patterns (d)) return true; + if (shuffle_compress_patterns (d)) + return true; if (shuffle_decompress_patterns (d)) return true; if (shuffle_generic_patterns (d)) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c new file mode 100644 index 0000000..5983757 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include + +typedef int8_t vnx4i __attribute__ ((vector_size (4))); +typedef uint8_t vnx4ui __attribute__ ((vector_size (4))); + +#define MASK_4 0, 2, 6, 7 + +vnx4i __attribute__ ((noinline, noclone)) test_1 (vnx4i x, vnx4i y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +vnx4ui __attribute__ ((noinline, noclone)) test_2 (vnx4ui x, vnx4ui y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +/* { dg-final { scan-assembler-times {\tvcompress\.vm} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-2.c new file mode 100644 index 0000000..c6cd7bb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-2.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include + +typedef int8_t vnx8i __attribute__ ((vector_size (8))); +typedef int16_t vnx4i __attribute__ ((vector_size (8))); +typedef uint8_t vnx8ui __attribute__ ((vector_size (8))); +typedef uint16_t vnx4ui __attribute__ ((vector_size (8))); +typedef _Float16 vnx4f __attribute__ ((vector_size (8))); + +#define MASK_4 1, 3, 6, 7 +#define MASK_8 2, 3, 5, 6, 11, 12, 13, 14 + +vnx8i __attribute__ ((noinline, noclone)) +test_1 (vnx8i x, vnx8i y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4i __attribute__ ((noinline, noclone)) +test_2 (vnx4i x, vnx4i y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +vnx8ui __attribute__ ((noinline, noclone)) +test_3 (vnx8ui x, vnx8ui y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4ui __attribute__ ((noinline, noclone)) +test_4 (vnx4ui x, vnx4ui y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +vnx4f __attribute__ ((noinline, noclone)) +test_5 (vnx4f x, vnx4f y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +/* { dg-final { scan-assembler-times {\tvcompress\.vm} 5 } } */ +/* { dg-final { scan-assembler-times {\tvslideup} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-3.c new file mode 100644 index 0000000..0fc2cef --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-3.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include + +typedef int8_t vnx16i __attribute__ ((vector_size (16))); +typedef int16_t vnx8i __attribute__ ((vector_size (16))); +typedef int32_t vnx4i __attribute__ ((vector_size (16))); +typedef uint8_t vnx16ui __attribute__ ((vector_size (16))); +typedef uint16_t vnx8ui __attribute__ ((vector_size (16))); +typedef uint32_t vnx4ui __attribute__ ((vector_size (16))); +typedef _Float16 vnx8f __attribute__ ((vector_size (16))); +typedef float vnx4f __attribute__ ((vector_size (16))); + +#define MASK_4 0, 2, 5, 6 +#define MASK_8 0, 1, 2, 5, 10, 11, 12, 13 +#define MASK_16 1, 3, 4, 6, 7, 8, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27 + +vnx16i __attribute__ ((noinline, noclone)) test_1 (vnx16i x, vnx16i y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8i __attribute__ ((noinline, noclone)) test_2 (vnx8i x, vnx8i y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4i __attribute__ ((noinline, noclone)) test_3 (vnx4i x, vnx4i y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +vnx16ui __attribute__ ((noinline, noclone)) test_4 (vnx16ui x, vnx16ui y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8ui __attribute__ ((noinline, noclone)) test_5 (vnx8ui x, vnx8ui y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4ui __attribute__ ((noinline, noclone)) test_6 (vnx4ui x, vnx4ui y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +vnx8f __attribute__ ((noinline, noclone)) test_7 (vnx8f x, vnx8f y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4f __attribute__ ((noinline, noclone)) test_8 (vnx4f x, vnx4f y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 8 } } */ +/* { dg-final { scan-assembler-times {\tvslideup} 8 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-4.c new file mode 100644 index 0000000..54b89ed --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-4.c @@ -0,0 +1,81 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include + +typedef int8_t vnx32i __attribute__ ((vector_size (32))); +typedef int16_t vnx16i __attribute__ ((vector_size (32))); +typedef int32_t vnx8i __attribute__ ((vector_size (32))); +typedef int64_t vnx4i __attribute__ ((vector_size (32))); +typedef uint8_t vnx32ui __attribute__ ((vector_size (32))); +typedef uint16_t vnx16ui __attribute__ ((vector_size (32))); +typedef uint32_t vnx8ui __attribute__ ((vector_size (32))); +typedef uint64_t vnx4ui __attribute__ ((vector_size (32))); +typedef _Float16 vnx16f __attribute__ ((vector_size (32))); +typedef float vnx8f __attribute__ ((vector_size (32))); +typedef double vnx4f __attribute__ ((vector_size (32))); + +#define MASK_4 1, 2, 5, 6 +#define MASK_8 1, 2, 5, 7, 11, 12, 13, 14 +#define MASK_16 0, 3, 5, 7, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 +#define MASK_32 \ + 3, 4, 6, 7, 9, 10, 14, 15, 17, 20, 21, 22, 24, 27, 29, 31, 34, 35, 36, 37, \ + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49 + +vnx32i __attribute__ ((noinline, noclone)) test_1 (vnx32i x, vnx32i y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16i __attribute__ ((noinline, noclone)) test_2 (vnx16i x, vnx16i y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8i __attribute__ ((noinline, noclone)) test_3 (vnx8i x, vnx8i y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4i __attribute__ ((noinline, noclone)) test_4 (vnx4i x, vnx4i y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +vnx32ui __attribute__ ((noinline, noclone)) test_5 (vnx32ui x, vnx32ui y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16ui __attribute__ ((noinline, noclone)) test_6 (vnx16ui x, vnx16ui y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8ui __attribute__ ((noinline, noclone)) test_7 (vnx8ui x, vnx8ui y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4ui __attribute__ ((noinline, noclone)) test_8 (vnx4ui x, vnx4ui y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +vnx16f __attribute__ ((noinline, noclone)) test_9 (vnx16f x, vnx16f y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8f __attribute__ ((noinline, noclone)) test_10 (vnx8f x, vnx8f y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx4f __attribute__ ((noinline, noclone)) test_11 (vnx4f x, vnx4f y) +{ + return __builtin_shufflevector (x, y, MASK_4); +} + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 11 } } */ +/* { dg-final { scan-assembler-times {\tvslideup} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-5.c new file mode 100644 index 0000000..4b27502 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-5.c @@ -0,0 +1,85 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include + +typedef int8_t vnx64i __attribute__ ((vector_size (64))); +typedef int16_t vnx32i __attribute__ ((vector_size (64))); +typedef int32_t vnx16i __attribute__ ((vector_size (64))); +typedef int64_t vnx8i __attribute__ ((vector_size (64))); +typedef uint8_t vnx64ui __attribute__ ((vector_size (64))); +typedef uint16_t vnx32ui __attribute__ ((vector_size (64))); +typedef uint32_t vnx16ui __attribute__ ((vector_size (64))); +typedef uint64_t vnx8ui __attribute__ ((vector_size (64))); +typedef _Float16 vnx32f __attribute__ ((vector_size (64))); +typedef float vnx16f __attribute__ ((vector_size (64))); +typedef double vnx8f __attribute__ ((vector_size (64))); + +#define MASK_4 0, 2, 5, 6 +#define MASK_8 0, 1, 5, 7, 11, 12, 13, 14 +#define MASK_16 0, 2, 3, 8, 10, 11, 12, 14, 24, 25, 26, 27, 28, 29, 30, 31 +#define MASK_32 \ + 4, 5, 6, 7, 9, 10, 12, 14, 18, 20, 22, 23, 25, 27, 28, 29, 35, 36, 37, 38, \ + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 +#define MASK_64 \ + 1, 2, 3, 5, 7, 9, 10, 11, 12, 14, 15, 17, 19, 21, 22, 23, 26, 28, 30, 31, \ + 37, 38, 41, 46, 47, 53, 54, 55, 60, 61, 62, 63, 76, 77, 78, 79, 80, 81, \ + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, \ + 100, 101, 102, 103, 104, 105, 106, 107 + +vnx64i __attribute__ ((noinline, noclone)) test_1 (vnx64i x, vnx64i y) +{ + return __builtin_shufflevector (x, y, MASK_64); +} + +vnx32i __attribute__ ((noinline, noclone)) test_2 (vnx32i x, vnx32i y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16i __attribute__ ((noinline, noclone)) test_3 (vnx16i x, vnx16i y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8i __attribute__ ((noinline, noclone)) test_4 (vnx8i x, vnx8i y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx64ui __attribute__ ((noinline, noclone)) test_5 (vnx64ui x, vnx64ui y) +{ + return __builtin_shufflevector (x, y, MASK_64); +} + +vnx32ui __attribute__ ((noinline, noclone)) test_6 (vnx32ui x, vnx32ui y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16ui __attribute__ ((noinline, noclone)) test_7 (vnx16ui x, vnx16ui y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8ui __attribute__ ((noinline, noclone)) test_8 (vnx8ui x, vnx8ui y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +vnx32f __attribute__ ((noinline, noclone)) test_9 (vnx32f x, vnx32f y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16f __attribute__ ((noinline, noclone)) test_10 (vnx16f x, vnx16f y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx8f __attribute__ ((noinline, noclone)) test_11 (vnx8f x, vnx8f y) +{ + return __builtin_shufflevector (x, y, MASK_8); +} + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-6.c new file mode 100644 index 0000000..4b85c71 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress-6.c @@ -0,0 +1,95 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include + +typedef int8_t vnx128i __attribute__ ((vector_size (128))); +typedef int16_t vnx64i __attribute__ ((vector_size (128))); +typedef int32_t vnx32i __attribute__ ((vector_size (128))); +typedef int64_t vnx16i __attribute__ ((vector_size (128))); +typedef uint8_t vnx128ui __attribute__ ((vector_size (128))); +typedef uint16_t vnx64ui __attribute__ ((vector_size (128))); +typedef uint32_t vnx32ui __attribute__ ((vector_size (128))); +typedef uint64_t vnx16ui __attribute__ ((vector_size (128))); +typedef _Float16 vnx64f __attribute__ ((vector_size (128))); +typedef float vnx32f __attribute__ ((vector_size (128))); +typedef double vnx16f __attribute__ ((vector_size (128))); + +#define MASK_4 0, 3, 6, 7 +#define MASK_8 0, 2, 3, 4, 10, 11, 12, 13 +#define MASK_16 2, 3, 4, 6, 7, 8, 9, 12, 20, 21, 22, 23, 24, 25, 26, 27 +#define MASK_32 \ + 0, 1, 3, 4, 7, 8, 12, 13, 14, 19, 21, 22, 23, 27, 29, 31, 41, 42, 43, 44, \ + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 +#define MASK_64 \ + 0, 2, 3, 4, 5, 7, 11, 13, 14, 16, 17, 19, 20, 22, 23, 24, 27, 28, 30, 31, \ + 35, 37, 39, 40, 44, 45, 46, 53, 54, 56, 61, 63, 68, 69, 70, 71, 72, 73, \ + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, \ + 92, 93, 94, 95, 96, 97, 98, 99 + +#define MASK_128 \ + 1, 3, 4, 5, 6, 7, 8, 10, 12, 14, 15, 16, 17, 18, 22, 25, 28, 29, 30, 31, 36, \ + 37, 40, 41, 42, 43, 44, 46, 52, 54, 55, 58, 61, 62, 64, 67, 68, 69, 70, \ + 71, 76, 77, 78, 80, 82, 83, 84, 86, 87, 88, 91, 94, 95, 99, 102, 104, 106, \ + 110, 112, 115, 116, 125, 126, 127, 144, 145, 146, 147, 148, 149, 150, 151, \ + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, \ + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, \ + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, \ + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207 + +vnx128i __attribute__ ((noinline, noclone)) test_1 (vnx128i x, vnx128i y) +{ + return __builtin_shufflevector (x, y, MASK_128); +} + +vnx64i __attribute__ ((noinline, noclone)) test_2 (vnx64i x, vnx64i y) +{ + return __builtin_shufflevector (x, y, MASK_64); +} + +vnx32i __attribute__ ((noinline, noclone)) test_3 (vnx32i x, vnx32i y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16i __attribute__ ((noinline, noclone)) test_4 (vnx16i x, vnx16i y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx128ui __attribute__ ((noinline, noclone)) test_5 (vnx128ui x, vnx128ui y) +{ + return __builtin_shufflevector (x, y, MASK_128); +} + +vnx64ui __attribute__ ((noinline, noclone)) test_6 (vnx64ui x, vnx64ui y) +{ + return __builtin_shufflevector (x, y, MASK_64); +} + +vnx32ui __attribute__ ((noinline, noclone)) test_7 (vnx32ui x, vnx32ui y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16ui __attribute__ ((noinline, noclone)) test_8 (vnx16ui x, vnx16ui y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +vnx64f __attribute__ ((noinline, noclone)) test_9 (vnx64f x, vnx64f y) +{ + return __builtin_shufflevector (x, y, MASK_64); +} + +vnx32f __attribute__ ((noinline, noclone)) test_10 (vnx32f x, vnx32f y) +{ + return __builtin_shufflevector (x, y, MASK_32); +} + +vnx16f __attribute__ ((noinline, noclone)) test_11 (vnx16f x, vnx16f y) +{ + return __builtin_shufflevector (x, y, MASK_16); +} + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-1.c new file mode 100644 index 0000000..a2c1312 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-1.c @@ -0,0 +1,27 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include +#include "compress-1.c" + +int +main (void) +{ + vnx4i test_1_x = {0, 1, 2, 4}; + vnx4i test_1_y = {4, 5, 7, 8}; + vnx4i test_1_except = {0, 2, 7, 8}; + vnx4i test_1_real; + test_1_real = test_1 (test_1_x, test_1_y); + for (int i = 0; i < 4; i++) + assert (test_1_real[i] == test_1_except[i]); + + vnx4ui test_2_x = {0, 1, 2, 4}; + vnx4ui test_2_y = {4, 5, 6, 8}; + vnx4ui test_2_except = {0, 2, 6, 8}; + vnx4ui test_2_real; + test_2_real = test_2 (test_2_x, test_2_y); + for (int i = 0; i < 4; i++) + assert (test_2_real[i] == test_2_except[i]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-2.c new file mode 100644 index 0000000..9f9f152 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-2.c @@ -0,0 +1,51 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include +#include "compress-2.c" + +int +main (void) +{ + vnx8i test_1_x = {0, 1, 2, 3, 5, 6, 7, 8}; + vnx8i test_1_y = {8, 9, 10, 11, 13, 14, 15, 16}; + vnx8i test_1_except = {2, 3, 6, 7, 11, 13, 14, 15}; + vnx8i test_1_real; + test_1_real = test_1 (test_1_x, test_1_y); + for (int i = 0; i < 8; i++) + assert (test_1_real[i] == test_1_except[i]); + + vnx4i test_2_x = {1, 2, 3, 4}; + vnx4i test_2_y = {5, 6, 7, 8}; + vnx4i test_2_except = {2, 4, 7, 8}; + vnx4i test_2_real; + test_2_real = test_2 (test_2_x, test_2_y); + for (int i = 0; i < 4; i++) + assert (test_2_real[i] == test_2_except[i]); + + vnx8ui test_3_x = {0, 1, 2, 3, 4, 5, 6, 8}; + vnx8ui test_3_y = {8, 9, 10, 11, 12, 13, 15, 16}; + vnx8ui test_3_except = {2, 3, 5, 6, 11, 12, 13, 15}; + vnx8ui test_3_real; + test_3_real = test_3 (test_3_x, test_3_y); + for (int i = 0; i < 8; i++) + assert (test_3_real[i] == test_3_except[i]); + + vnx4ui test_4_x = {1, 2, 3, 4}; + vnx4ui test_4_y = {4, 5, 6, 8}; + vnx4ui test_4_except = {2, 4, 6, 8}; + vnx4ui test_4_real; + test_4_real = test_4 (test_4_x, test_4_y); + for (int i = 0; i < 4; i++) + assert (test_4_real[i] == test_4_except[i]); + + vnx4f test_5_x = {0, 1, 3, 4}; + vnx4f test_5_y = {4, 5, 6, 7}; + vnx4f test_5_except = {1, 4, 6, 7}; + vnx4f test_5_real; + test_5_real = test_5 (test_5_x, test_5_y); + for (int i = 0; i < 4; i++) + assert (test_5_real[i] == test_5_except[i]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-3.c new file mode 100644 index 0000000..8a29a5b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-3.c @@ -0,0 +1,79 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include +#include "compress-3.c" + +int +main (void) +{ + vnx16i test_1_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16i test_1_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16i test_1_except + = {1, 3, 4, 6, 7, 8, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}; + vnx16i test_1_real; + test_1_real = test_1 (test_1_x, test_1_y); + for (int i = 0; i < 16; i++) + assert (test_1_real[i] == test_1_except[i]); + + vnx8i test_2_x = {0, 1, 2, 3, 4, 5, 6, 7}; + vnx8i test_2_y = {8, 9, 10, 11, 12, 13, 14, 15}; + vnx8i test_2_except = {0, 1, 2, 5, 10, 11, 12, 13}; + vnx8i test_2_real; + test_2_real = test_2 (test_2_x, test_2_y); + for (int i = 0; i < 8; i++) + assert (test_2_real[i] == test_2_except[i]); + + vnx4i test_3_x = {0, 1, 2, 3}; + vnx4i test_3_y = {4, 5, 6, 7}; + vnx4i test_3_except = {0, 2, 5, 6}; + vnx4i test_3_real; + test_3_real = test_3 (test_3_x, test_3_y); + for (int i = 0; i < 4; i++) + assert (test_3_real[i] == test_3_except[i]); + + vnx16ui test_4_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16ui test_4_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16ui test_4_except + = {1, 3, 4, 6, 7, 8, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}; + vnx16ui test_4_real; + test_4_real = test_4 (test_4_x, test_4_y); + for (int i = 0; i < 16; i++) + assert (test_4_real[i] == test_4_except[i]); + + vnx8ui test_5_x = {0, 1, 2, 3, 4, 5, 6, 7}; + vnx8ui test_5_y = {8, 9, 10, 11, 12, 13, 14, 15}; + vnx8ui test_5_except = {0, 1, 2, 5, 10, 11, 12, 13}; + vnx8ui test_5_real; + test_5_real = test_5 (test_5_x, test_5_y); + for (int i = 0; i < 8; i++) + assert (test_5_real[i] == test_5_except[i]); + + vnx4ui test_6_x = {0, 1, 2, 3}; + vnx4ui test_6_y = {4, 5, 6, 7}; + vnx4ui test_6_except = {0, 2, 5, 6}; + vnx4ui test_6_real; + test_6_real = test_6 (test_6_x, test_6_y); + for (int i = 0; i < 4; i++) + assert (test_6_real[i] == test_6_except[i]); + + vnx8f test_7_x = {0, 1, 2, 3, 4, 5, 6, 7}; + vnx8f test_7_y = {8, 9, 10, 11, 12, 13, 14, 15}; + vnx8f test_7_except = {0, 1, 2, 5, 10, 11, 12, 13}; + vnx8f test_7_real; + test_7_real = test_7 (test_7_x, test_7_y); + for (int i = 0; i < 8; i++) + assert (test_7_real[i] == test_7_except[i]); + + vnx4f test_8_x = {0, 1, 2, 3}; + vnx4f test_8_y = {4, 5, 6, 7}; + vnx4f test_8_except = {0, 2, 5, 6}; + vnx4f test_8_real; + test_8_real = test_8 (test_8_x, test_8_y); + for (int i = 0; i < 4; i++) + assert (test_8_real[i] == test_8_except[i]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-4.c new file mode 100644 index 0000000..42b3fa1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-4.c @@ -0,0 +1,117 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include +#include "compress-4.c" + +int +main (void) +{ + vnx32i test_1_x + = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; + vnx32i test_1_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64}; + vnx32i test_1_except + = {4, 5, 7, 8, 10, 11, 15, 16, 18, 21, 22, 23, 25, 28, 30, 32, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49}; + vnx32i test_1_real; + test_1_real = test_1 (test_1_x, test_1_y); + for (int i = 0; i < 32; i++) + assert (test_1_real[i] == test_1_except[i]); + + vnx16i test_2_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16i test_2_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31, 32}; + vnx16i test_2_except + = {0, 3, 5, 7, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}; + vnx16i test_2_real; + test_2_real = test_2 (test_2_x, test_2_y); + for (int i = 0; i < 16; i++) + assert (test_2_real[i] == test_2_except[i]); + + vnx8i test_3_x = {0, 1, 2, 4, 5, 6, 7, 8}; + vnx8i test_3_y = {8, 10, 11, 12, 13, 14, 15, 16}; + vnx8i test_3_except = {1, 2, 6, 8, 12, 13, 14, 15}; + vnx8i test_3_real; + test_3_real = test_3 (test_3_x, test_3_y); + for (int i = 0; i < 8; i++) + assert (test_3_real[i] == test_3_except[i]); + + vnx4i test_4_x = {0, 2, 3, 4}; + vnx4i test_4_y = {4, 5, 7, 8}; + vnx4i test_4_except = {2, 3, 5, 7}; + vnx4i test_4_real; + test_4_real = test_4 (test_4_x, test_4_y); + for (int i = 0; i < 4; i++) + assert (test_4_real[i] == test_4_except[i]); + + vnx32ui test_5_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32}; + vnx32ui test_5_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64}; + vnx32ui test_5_except + = {3, 4, 6, 7, 9, 10, 14, 15, 17, 20, 21, 22, 24, 27, 29, 32, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49}; + vnx32ui test_5_real; + test_5_real = test_5 (test_5_x, test_5_y); + for (int i = 0; i < 32; i++) + assert (test_5_real[i] == test_5_except[i]); + + vnx16ui test_6_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16}; + vnx16ui test_6_y + = {16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; + vnx16ui test_6_except + = {0, 3, 5, 7, 10, 11, 15, 16, 16, 17, 19, 20, 21, 22, 23, 24}; + vnx16ui test_6_real; + test_6_real = test_6 (test_6_x, test_6_y); + for (int i = 0; i < 16; i++) + assert (test_6_real[i] == test_6_except[i]); + + vnx8ui test_7_x = {0, 2, 3, 4, 5, 6, 7, 8}; + vnx8ui test_7_y = {8, 9, 10, 12, 13, 14, 15, 16}; + vnx8ui test_7_except = {2, 3, 6, 8, 12, 13, 14, 15}; + vnx8ui test_7_real; + test_7_real = test_7 (test_7_x, test_7_y); + for (int i = 0; i < 8; i++) + assert (test_7_real[i] == test_7_except[i]); + + vnx4ui test_8_x = {0, 2, 3, 4}; + vnx4ui test_8_y = {5, 6, 7, 8}; + vnx4ui test_8_except = {2, 3, 6, 7}; + vnx4ui test_8_real; + test_8_real = test_8 (test_8_x, test_8_y); + for (int i = 0; i < 4; i++) + assert (test_8_real[i] == test_8_except[i]); + + vnx16f test_9_x = {0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + vnx16f test_9_y + = {16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; + vnx16f test_9_except + = {0, 3, 6, 8, 11, 12, 15, 16, 16, 17, 18, 20, 21, 22, 23, 24}; + vnx16f test_9_real; + test_9_real = test_9 (test_9_x, test_9_y); + for (int i = 0; i < 16; i++) + assert (test_9_real[i] == test_9_except[i]); + + vnx8f test_10_x = {0, 1, 2, 3, 4, 5, 6, 7}; + vnx8f test_10_y = {8, 9, 10, 12, 13, 14, 15, 16}; + vnx8f test_10_except = {1, 2, 5, 7, 12, 13, 14, 15}; + vnx8f test_10_real; + test_10_real = test_10 (test_10_x, test_10_y); + for (int i = 0; i < 8; i++) + assert (test_10_real[i] == test_10_except[i]); + + vnx4f test_11_x = {0, 2, 3, 4}; + vnx4f test_11_y = {4, 6, 7, 8}; + vnx4f test_11_except = {2, 3, 6, 7}; + vnx4f test_11_real; + test_11_real = test_11 (test_11_x, test_11_y); + for (int i = 0; i < 4; i++) + assert (test_11_real[i] == test_11_except[i]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-5.c new file mode 100644 index 0000000..8f15f45 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-5.c @@ -0,0 +1,149 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include +#include "compress-5.c" + +int +main (void) +{ + vnx64i test_1_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx64i test_1_y + = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + vnx64i test_1_except + = {1, 2, 3, 5, 7, 9, 10, 11, 12, 14, 15, 17, 19, 21, 22, 23, + 26, 28, 30, 31, 37, 38, 41, 46, 47, 53, 54, 55, 60, 61, 62, 63, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107}; + vnx64i test_1_real; + test_1_real = test_1 (test_1_x, test_1_y); + for (int i = 0; i < 64; i++) + assert (test_1_real[i] == test_1_except[i]); + + vnx32i test_2_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx32i test_2_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx32i test_2_except + = {4, 5, 6, 7, 9, 10, 12, 14, 18, 20, 22, 23, 25, 27, 28, 29, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50}; + vnx32i test_2_real; + test_2_real = test_2 (test_2_x, test_2_y); + for (int i = 0; i < 32; i++) + assert (test_2_real[i] == test_2_except[i]); + + vnx16i test_3_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16i test_3_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16i test_3_except + = {0, 2, 3, 8, 10, 11, 12, 14, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16i test_3_real; + test_3_real = test_3 (test_3_x, test_3_y); + for (int i = 0; i < 16; i++) + assert (test_3_real[i] == test_3_except[i]); + + vnx8i test_4_x = {0, 1, 2, 3, 4, 5, 6, 7}; + vnx8i test_4_y = {8, 9, 10, 11, 12, 13, 14, 15}; + vnx8i test_4_except = {0, 1, 5, 7, 11, 12, 13, 14}; + vnx8i test_4_real; + test_4_real = test_4 (test_4_x, test_4_y); + for (int i = 0; i < 8; i++) + assert (test_4_real[i] == test_4_except[i]); + + vnx64ui test_5_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx64ui test_5_y + = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + vnx64ui test_5_except + = {1, 2, 3, 5, 7, 9, 10, 11, 12, 14, 15, 17, 19, 21, 22, 23, + 26, 28, 30, 31, 37, 38, 41, 46, 47, 53, 54, 55, 60, 61, 62, 63, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107}; + vnx64ui test_5_real; + test_5_real = test_5 (test_5_x, test_5_y); + for (int i = 0; i < 64; i++) + assert (test_5_real[i] == test_5_except[i]); + + vnx32ui test_6_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx32ui test_6_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx32ui test_6_except + = {4, 5, 6, 7, 9, 10, 12, 14, 18, 20, 22, 23, 25, 27, 28, 29, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50}; + vnx32ui test_6_real; + test_6_real = test_6 (test_6_x, test_6_y); + for (int i = 0; i < 32; i++) + assert (test_6_real[i] == test_6_except[i]); + + vnx16ui test_7_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16ui test_7_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16ui test_7_except + = {0, 2, 3, 8, 10, 11, 12, 14, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16ui test_7_real; + test_7_real = test_7 (test_7_x, test_7_y); + for (int i = 0; i < 16; i++) + assert (test_7_real[i] == test_7_except[i]); + + vnx8ui test_8_x = {0, 1, 2, 3, 4, 5, 6, 7}; + vnx8ui test_8_y = {8, 9, 10, 11, 12, 13, 14, 15}; + vnx8ui test_8_except = {0, 1, 5, 7, 11, 12, 13, 14}; + vnx8ui test_8_real; + test_8_real = test_8 (test_8_x, test_8_y); + for (int i = 0; i < 8; i++) + assert (test_8_real[i] == test_8_except[i]); + + vnx32f test_9_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx32f test_9_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx32f test_9_except + = {4, 5, 6, 7, 9, 10, 12, 14, 18, 20, 22, 23, 25, 27, 28, 29, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50}; + vnx32f test_9_real; + test_9_real = test_9 (test_9_x, test_9_y); + for (int i = 0; i < 32; i++) + assert (test_9_real[i] == test_9_except[i]); + + vnx16f test_10_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16f test_10_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16f test_10_except + = {0, 2, 3, 8, 10, 11, 12, 14, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16f test_10_real; + test_10_real = test_10 (test_10_x, test_10_y); + for (int i = 0; i < 16; i++) + assert (test_10_real[i] == test_10_except[i]); + + vnx8f test_11_x = {0, 1, 2, 3, 4, 5, 6, 7}; + vnx8f test_11_y = {8, 9, 10, 11, 12, 13, 14, 15}; + vnx8f test_11_except = {0, 1, 5, 7, 11, 12, 13, 14}; + vnx8f test_11_real; + test_11_real = test_11 (test_11_x, test_11_y); + for (int i = 0; i < 8; i++) + assert (test_11_real[i] == test_11_except[i]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-6.c new file mode 100644 index 0000000..5139ea2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-6.c @@ -0,0 +1,222 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 --param riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ + +#include +#include "compress-6.c" + +int +main (void) +{ + vnx128i test_1_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + vnx128i test_1_y + = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + vnx128i test_1_except + = {1, 3, 4, 5, 6, 7, 8, 10, 12, 14, 15, 16, 17, + 18, 22, 25, 28, 29, 30, 31, 36, 37, 40, 41, 42, 43, + 44, 46, 52, 54, 55, 58, 61, 62, 64, 67, 68, 69, 70, + 71, 76, 77, 78, 80, 82, 83, 84, 86, 87, 88, 91, 94, + 95, 99, 102, 104, 106, 110, 112, 115, 116, 125, 126, 127, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207}; + vnx128i test_1_real; + test_1_real = test_1 (test_1_x, test_1_y); + for (int i = 0; i < 128; i++) + assert (test_1_real[i] == test_1_except[i]); + + vnx64i test_2_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx64i test_2_y + = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + vnx64i test_2_except + = {0, 2, 3, 4, 5, 7, 11, 13, 14, 16, 17, 19, 20, 22, 23, 24, + 27, 28, 30, 31, 35, 37, 39, 40, 44, 45, 46, 53, 54, 56, 61, 63, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; + vnx64i test_2_real; + test_2_real = test_2 (test_2_x, test_2_y); + for (int i = 0; i < 64; i++) + assert (test_2_real[i] == test_2_except[i]); + + vnx32i test_3_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx32i test_3_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx32i test_3_except + = {0, 1, 3, 4, 7, 8, 12, 13, 14, 19, 21, 22, 23, 27, 29, 31, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56}; + vnx32i test_3_real; + test_3_real = test_3 (test_3_x, test_3_y); + for (int i = 0; i < 32; i++) + assert (test_3_real[i] == test_3_except[i]); + + vnx16i test_4_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16i test_4_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16i test_4_except + = {2, 3, 4, 6, 7, 8, 9, 12, 20, 21, 22, 23, 24, 25, 26, 27}; + vnx16i test_4_real; + test_4_real = test_4 (test_4_x, test_4_y); + for (int i = 0; i < 16; i++) + assert (test_4_real[i] == test_4_except[i]); + + vnx128ui test_5_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + vnx128ui test_5_y + = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + vnx128ui test_5_except + = {1, 3, 4, 5, 6, 7, 8, 10, 12, 14, 15, 16, 17, + 18, 22, 25, 28, 29, 30, 31, 36, 37, 40, 41, 42, 43, + 44, 46, 52, 54, 55, 58, 61, 62, 64, 67, 68, 69, 70, + 71, 76, 77, 78, 80, 82, 83, 84, 86, 87, 88, 91, 94, + 95, 99, 102, 104, 106, 110, 112, 115, 116, 125, 126, 127, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207}; + vnx128ui test_5_real; + test_5_real = test_5 (test_5_x, test_5_y); + for (int i = 0; i < 128; i++) + assert (test_5_real[i] == test_5_except[i]); + + vnx64ui test_6_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx64ui test_6_y + = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + vnx64ui test_6_except + = {0, 2, 3, 4, 5, 7, 11, 13, 14, 16, 17, 19, 20, 22, 23, 24, + 27, 28, 30, 31, 35, 37, 39, 40, 44, 45, 46, 53, 54, 56, 61, 63, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; + vnx64ui test_6_real; + test_6_real = test_6 (test_6_x, test_6_y); + for (int i = 0; i < 64; i++) + assert (test_6_real[i] == test_6_except[i]); + + vnx32ui test_7_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx32ui test_7_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx32ui test_7_except + = {0, 1, 3, 4, 7, 8, 12, 13, 14, 19, 21, 22, 23, 27, 29, 31, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56}; + vnx32ui test_7_real; + test_7_real = test_7 (test_7_x, test_7_y); + for (int i = 0; i < 32; i++) + assert (test_7_real[i] == test_7_except[i]); + + vnx16ui test_8_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16ui test_8_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16ui test_8_except + = {2, 3, 4, 6, 7, 8, 9, 12, 20, 21, 22, 23, 24, 25, 26, 27}; + vnx16ui test_8_real; + test_8_real = test_8 (test_8_x, test_8_y); + for (int i = 0; i < 16; i++) + assert (test_8_real[i] == test_8_except[i]); + + vnx64f test_9_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx64f test_9_y + = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + vnx64f test_9_except + = {0, 2, 3, 4, 5, 7, 11, 13, 14, 16, 17, 19, 20, 22, 23, 24, + 27, 28, 30, 31, 35, 37, 39, 40, 44, 45, 46, 53, 54, 56, 61, 63, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; + vnx64f test_9_real; + test_9_real = test_9 (test_9_x, test_9_y); + for (int i = 0; i < 64; i++) + assert (test_9_real[i] == test_9_except[i]); + + vnx32f test_10_x + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx32f test_10_y + = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + vnx32f test_10_except + = {0, 1, 3, 4, 7, 8, 12, 13, 14, 19, 21, 22, 23, 27, 29, 31, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56}; + vnx32f test_10_real; + test_10_real = test_10 (test_10_x, test_10_y); + for (int i = 0; i < 32; i++) + assert (test_10_real[i] == test_10_except[i]); + + vnx16f test_11_x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + vnx16f test_11_y + = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + vnx16f test_11_except + = {2, 3, 4, 6, 7, 8, 9, 12, 20, 21, 22, 23, 24, 25, 26, 27}; + vnx16f test_11_real; + test_11_real = test_11 (test_11_x, test_11_y); + for (int i = 0; i < 16; i++) + assert (test_11_real[i] == test_11_except[i]); + + return 0; +} -- cgit v1.1 From af3d3ce31a259699f5ad26addcf1c88a2e4eea6d Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 12 Jul 2023 00:17:09 +0000 Subject: Daily bump. --- gcc/ChangeLog | 82 +++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 11 ++++++ gcc/cp/ChangeLog | 7 ++++ gcc/fortran/ChangeLog | 8 +++++ gcc/m2/ChangeLog | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 81 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 283 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cd7076b..111302e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,85 @@ +2023-07-11 Ju-Zhe Zhong + + * config/riscv/riscv-protos.h (enum insn_type): Add vcompress optimization. + * config/riscv/riscv-v.cc (emit_vlmax_compress_insn): Ditto. + (shuffle_compress_patterns): Ditto. + (expand_vec_perm_const_1): Ditto. + +2023-07-11 Uros Bizjak + + * cfghooks.cc (verify_flow_info): Change "err" variable to bool. + * cfghooks.h (struct cfg_hooks): Change return type of + verify_flow_info from integer to bool. + * cfgrtl.cc (can_delete_note_p): Change return type from int to bool. + (can_delete_label_p): Ditto. + (rtl_verify_flow_info): Change return type from int to bool + and adjust function body accordingly. Change "err" variable to bool. + (rtl_verify_flow_info_1): Ditto. + (free_bb_for_insn): Change return type to void. + (rtl_merge_blocks): Change "b_empty" variable to bool. + (try_redirect_by_replacing_jump): Change "fallthru" variable to bool. + (verify_hot_cold_block_grouping): Change return type from int to bool. + Change "err" variable to bool. + (rtl_verify_edges): Ditto. + (rtl_verify_bb_insns): Ditto. + (rtl_verify_bb_pointers): Ditto. + (rtl_verify_bb_insn_chain): Ditto. + (rtl_verify_fallthru): Ditto. + (rtl_verify_bb_layout): Ditto. + (purge_all_dead_edges): Change "purged" variable to bool. + * cfgrtl.h (free_bb_for_insn): Change return type from int to void. + * postreload-gcse.cc (expr_hasher::equal): Change "equiv_p" to bool. + (load_killed_in_block_p): Change return type from int to bool + and adjust function body accordingly. + (oprs_unchanged_p): Return true/false. + (rest_of_handle_gcse2): Change return type to void. + * tree-cfg.cc (gimple_verify_flow_info): Change return type from + int to bool. Change "err" variable to bool. + +2023-07-11 Gaius Mulley + + * doc/gm2.texi (-Wuninit-variable-checking=) New item. + +2023-07-11 Ju-Zhe Zhong + + * doc/md.texi: Add COND_LEN_* operations for loop control with length. + * internal-fn.cc (cond_len_unary_direct): Ditto. + (cond_len_binary_direct): Ditto. + (cond_len_ternary_direct): Ditto. + (expand_cond_len_unary_optab_fn): Ditto. + (expand_cond_len_binary_optab_fn): Ditto. + (expand_cond_len_ternary_optab_fn): Ditto. + (direct_cond_len_unary_optab_supported_p): Ditto. + (direct_cond_len_binary_optab_supported_p): Ditto. + (direct_cond_len_ternary_optab_supported_p): Ditto. + * internal-fn.def (COND_LEN_ADD): Ditto. + (COND_LEN_SUB): Ditto. + (COND_LEN_MUL): Ditto. + (COND_LEN_DIV): Ditto. + (COND_LEN_MOD): Ditto. + (COND_LEN_RDIV): Ditto. + (COND_LEN_MIN): Ditto. + (COND_LEN_MAX): Ditto. + (COND_LEN_FMIN): Ditto. + (COND_LEN_FMAX): Ditto. + (COND_LEN_AND): Ditto. + (COND_LEN_IOR): Ditto. + (COND_LEN_XOR): Ditto. + (COND_LEN_SHL): Ditto. + (COND_LEN_SHR): Ditto. + (COND_LEN_FMA): Ditto. + (COND_LEN_FMS): Ditto. + (COND_LEN_FNMA): Ditto. + (COND_LEN_FNMS): Ditto. + (COND_LEN_NEG): Ditto. + * optabs.def (OPTAB_D): Ditto. + +2023-07-11 Richard Biener + + PR tree-optimization/110614 + * tree-vect-data-refs.cc (vect_supportable_dr_alignment): + SLP splats are not suitable for re-align ops. + 2023-07-10 Peter Bergner * config/rs6000/predicates.md (quad_memory_operand): Remove redundant diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 2dbd21e..b130bea 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230711 +20230712 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 6890c5b..3820532 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,14 @@ +2023-07-11 Bob Duff + + * exp_ch3.adb (Expand_N_Object_Declaration): Avoid transforming to + a renaming in case of constrained array that comes from source. + +2023-07-11 Eric Botcazou + + * sem_ch13.adb (Replace_Type_References_Generic.Visible_Component): + In the case of private discriminated types, return a discriminant + only if it is listed in the discriminant part of the declaration. + 2023-07-10 Eric Botcazou * adaint.c [_WIN32]: Undefine 'abort' macro. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3db03db..19cf1da 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2023-07-11 Patrick Palka + + PR c++/110580 + * pt.cc (lookup_template_variable): Pass all levels of arguments + to coerce_template_parms, and use the parameters from the most + general template. + 2023-07-10 Patrick Palka PR c++/110523 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b6a902a..bc4ad57 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2023-07-11 Harald Anlauf + + PR fortran/110288 + * symbol.cc (gfc_copy_formal_args_intr): When deriving the formal + argument attributes from the actual ones for intrinsic procedure + calls, take special care of CHARACTER arguments that we do not + wrongly treat them formally as deferred-length. + 2023-07-08 Steve Kargl PR fortran/99139 diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 53cce9c..d5faf14 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,96 @@ +2023-07-11 Gaius Mulley + + * gm2-compiler/M2BasicBlock.def (InitBasicBlocksFromRange): New + parameter ScopeSym. + * gm2-compiler/M2BasicBlock.mod (ConvertQuads2BasicBlock): New + parameter ScopeSym. + (InitBasicBlocksFromRange): New parameter ScopeSym. Call + ConvertQuads2BasicBlock with ScopeSym. + (DisplayBasicBlocks): Uncomment. + * gm2-compiler/M2Code.mod: Replace VariableAnalysis with + ScopeBlockVariableAnalysis. + (InitialDeclareAndOptiomize): Add parameter scope. + (SecondDeclareAndOptimize): Add parameter scope. + * gm2-compiler/M2GCCDeclare.mod (DeclareConstructor): Add scope + parameter to DeclareTypesConstantsProceduresInRange. + (DeclareTypesConstantsProceduresInRange): New parameter scope. + Pass scope to DisplayQuadRange. Reformatted. + * gm2-compiler/M2GenGCC.def (ConvertQuadsToTree): New parameter + scope. + * gm2-compiler/M2GenGCC.mod (ConvertQuadsToTree): New parameter + scope. + * gm2-compiler/M2Optimize.mod (KnownReachable): New parameter + scope. + * gm2-compiler/M2Options.def (SetUninitVariableChecking): Add + arg parameter. + * gm2-compiler/M2Options.mod (SetUninitVariableChecking): Add + arg parameter and set boolean UninitVariableChecking and + UninitVariableConditionalChecking. + (UninitVariableConditionalChecking): New boolean set to FALSE. + * gm2-compiler/M2Quads.def (IsGoto): New procedure function. + (DisplayQuadRange): Add scope parameter. + (LoopAnalysis): Add scope parameter. + * gm2-compiler/M2Quads.mod: Import PutVarArrayRef. + (IsGoto): New procedure function. + (LoopAnalysis): Add scope parameter and use MetaErrorT1 instead + of WarnStringAt. + (BuildStaticArray): Call PutVarArrayRef. + (BuildDynamicArray): Call PutVarArrayRef. + (DisplayQuadRange): Add scope parameter. + (GetM2OperatorDesc): Add relational condition cases. + * gm2-compiler/M2Scope.def (ScopeProcedure): Add parameter. + * gm2-compiler/M2Scope.mod (DisplayScope): Pass scopeSym to + DisplayQuadRange. + (ForeachScopeBlockDo): Pass scopeSym to p. + * gm2-compiler/M2SymInit.def (VariableAnalysis): Rename to ... + (ScopeBlockVariableAnalysis): ... this. + * gm2-compiler/M2SymInit.mod (ScopeBlockVariableAnalysis): Add + scope parameter. + (bbEntry): New pointer to record. + (bbArray): New array. + (bbFreeList): New variable. + (errorList): New list. + (IssueConditional): New procedure. + (GenerateNoteFlow): New procedure. + (IssueWarning): New procedure. + (IsUniqueWarning): New procedure. + (CheckDeferredRecordAccess): Re-implement. + (CheckBinary): Add warning and lst parameters. + (CheckUnary): Add warning and lst parameters. + (CheckXIndr): Add warning and lst parameters. + (CheckIndrX): Add warning and lst parameters. + (CheckBecomes): Add warning and lst parameters. + (CheckComparison): Add warning and lst parameters. + (CheckReadBeforeInitQuad): Add warning and lst parameters to all + Check procedures. Add all case quadruple clauses. + (FilterCheckReadBeforeInitQuad): Add warning and lst parameters. + (CheckReadBeforeInitFirstBasicBlock): Add warning and lst parameters. + (bbArrayKill): New procedure. + (DumpBBEntry): New procedure. + (DumpBBArray): New procedure. + (DumpBBSequence): New procedure. + (TestBBSequence): New procedure. + (CreateBBPermultations): New procedure. + (ScopeBlockVariableAnalysis): New procedure. + (GetOp3): New procedure. + (GenerateCFG): New procedure. + (NewEntry): New procedure. + (AppendEntry): New procedure. + (init): Initialize bbFreeList and errorList. + * gm2-compiler/SymbolTable.def (PutVarArrayRef): New procedure. + (IsVarArrayRef): New procedure function. + * gm2-compiler/SymbolTable.mod (SymVar): ArrayRef new field. + (MakeVar): Set ArrayRef to FALSE. + (PutVarArrayRef): New procedure. + (IsVarArrayRef): New procedure function. + * gm2-gcc/init.cc (_M2_M2SymInit_init): New prototype. + (init_PerCompilationInit): Add call to _M2_M2SymInit_init. + * gm2-gcc/m2options.h (M2Options_SetUninitVariableChecking): + New definition. + * gm2-lang.cc (gm2_langhook_handle_option): Add new case + OPT_Wuninit_variable_checking_. + * lang.opt: Wuninit-variable-checking= new entry. + 2023-07-03 Gaius Mulley PR modula2/110125 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e710abd..5c0e05b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,84 @@ +2023-07-11 Ju-Zhe Zhong + + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-6.c: New test. + +2023-07-11 David Edelsohn + + * gcc.dg/analyzer/out-of-bounds-diagram-4.c: Skip on AIX. + * gcc.dg/analyzer/out-of-bounds-diagram-5-ascii.c: Same. + * gcc.dg/analyzer/out-of-bounds-diagram-5-unicode.c: Same. + * gcc.dg/analyzer/out-of-bounds-diagram-7.c: Same. + * gcc.dg/analyzer/out-of-bounds-diagram-13.c: Same. + * gcc.dg/analyzer/out-of-bounds-diagram-15.c: Same. + +2023-07-11 Harald Anlauf + + PR fortran/110288 + * gfortran.dg/findloc_10.f90: New test. + +2023-07-11 Carl Love + + * gcc.target/powerpc/vsx-vector-6-func-1op.h: New test file. + * gcc.target/powerpc/vsx-vector-6-func-1op-run.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-1op.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-2lop.h: New test file. + * gcc.target/powerpc/vsx-vector-6-func-2lop-run.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-2lop.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-2op.h: New test file. + * gcc.target/powerpc/vsx-vector-6-func-2op-run.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-2op.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-3op.h: New test file. + * gcc.target/powerpc/vsx-vector-6-func-3op-run.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-3op.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-cmp-all.h: New test file. + * gcc.target/powerpc/vsx-vector-6-func-cmp-all-run.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-cmp-all.c: New test + file. + * gcc.target/powerpc/vsx-vector-6-func-cmp.h: New test file. + * gcc.target/powerpc/vsx-vector-6-func-cmp-run.c: New test file. + * gcc.target/powerpc/vsx-vector-6-func-cmp.c: New test file. + * gcc.target/powerpc/vsx-vector-6.h: Remove test file. + * gcc.target/powerpc/vsx-vector-6.p7.c: Remove test file. + * gcc.target/powerpc/vsx-vector-6.p8.c: Remove test file. + * gcc.target/powerpc/vsx-vector-6.p9.c: Remove test file. + +2023-07-11 Maciej W. Rozycki + + * gcc.dg/vect/pr97428.c: Limit to `vect_double' targets. + +2023-07-11 Gaius Mulley + + * gm2/switches/uninit-variable-checking/cascade/fail/cascadedif.mod: New test. + * gm2/switches/uninit-variable-checking/cascade/fail/switches-uninit-variable-checking-cascade-fail.exp: + New test. + +2023-07-11 Patrick Palka + + PR c++/110580 + * g++.dg/cpp1y/var-templ83.C: New test. + +2023-07-11 liuhongt + + PR target/110170 + * g++.target/i386/pr110170.C: Fix typo. + +2023-07-11 Xi Ruoyao + + * g++.dg/vect/pr110557.cc: Use long long instead of long for + 64-bit type. + (test): Remove an unnecessary cast. + 2023-07-10 Patrick Palka PR c++/110523 -- cgit v1.1 From d9f9e53e3a0ce4280bf612cd6f59afa26fe81419 Mon Sep 17 00:00:00 2001 From: Haochen Jiang Date: Fri, 7 Jul 2023 15:53:42 +0800 Subject: i386: Guard 128 bit VAES builtins with AVX512VL Since commit 24a8acc, 128 bit intrin is enabled for VAES. However, AVX512VL is not checked until we reached into pattern, which reports an ICE. Added an AVX512VL guard at builtin to report error when checking ISA flags. gcc/ChangeLog: * config/i386/i386-builtins.cc (ix86_init_mmx_sse_builtins): Add OPTION_MASK_ISA_AVX512VL. * config/i386/i386-expand.cc (ix86_check_builtin_isa_match): Ditto. gcc/testsuite/ChangeLog: * gcc.target/i386/avx512vl-vaes-1.c: New test. --- gcc/config/i386/i386-builtins.cc | 12 ++++++++---- gcc/config/i386/i386-expand.cc | 4 +++- gcc/testsuite/gcc.target/i386/avx512vl-vaes-1.c | 12 ++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-vaes-1.c (limited to 'gcc') diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc index 28f404d..e436ca4 100644 --- a/gcc/config/i386/i386-builtins.cc +++ b/gcc/config/i386/i386-builtins.cc @@ -662,19 +662,23 @@ ix86_init_mmx_sse_builtins (void) VOID_FTYPE_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAIT); /* AES */ - def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2 + | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_VAES, "__builtin_ia32_aesenc128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENC128); - def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2 + | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_VAES, "__builtin_ia32_aesenclast128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENCLAST128); - def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2 + | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_VAES, "__builtin_ia32_aesdec128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDEC128); - def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2 + | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_VAES, "__builtin_ia32_aesdeclast128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDECLAST128); diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 92ffa4b..fd5d103 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -12654,6 +12654,7 @@ ix86_check_builtin_isa_match (unsigned int fcode, OPTION_MASK_ISA2_AVXIFMA (OPTION_MASK_ISA_AVX512VL | OPTION_MASK_ISA2_AVX512BF16) or OPTION_MASK_ISA2_AVXNECONVERT + OPTION_MASK_ISA_AES or (OPTION_MASK_ISA_AVX512VL | OPTION_MASK_ISA2_VAES) where for each such pair it is sufficient if either of the ISAs is enabled, plus if it is ored with other options also those others. OPTION_MASK_ISA_MMX in bisa is satisfied also if TARGET_MMX_WITH_SSE. */ @@ -12677,7 +12678,8 @@ ix86_check_builtin_isa_match (unsigned int fcode, OPTION_MASK_ISA2_AVXIFMA); SHARE_BUILTIN (OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVX512BF16, 0, OPTION_MASK_ISA2_AVXNECONVERT); - SHARE_BUILTIN (OPTION_MASK_ISA_AES, 0, 0, OPTION_MASK_ISA2_VAES); + SHARE_BUILTIN (OPTION_MASK_ISA_AES, 0, OPTION_MASK_ISA_AVX512VL, + OPTION_MASK_ISA2_VAES); isa = tmp_isa; isa2 = tmp_isa2; diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vaes-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vaes-1.c new file mode 100644 index 0000000..fabb170 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-vaes-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-mvaes -mno-avx512vl -mno-aes" } */ + +#include + +typedef long long v2di __attribute__((vector_size (16))); + +v2di +f1 (v2di x, v2di y) +{ + return __builtin_ia32_aesenc128 (x, y); /* { dg-error "needs isa option" } */ +} -- cgit v1.1 From a0cb65d34cc141571e870fb3b53b3ff47ae3338d Mon Sep 17 00:00:00 2001 From: "Mo, Zewei" Date: Mon, 3 Jul 2023 11:00:26 +0800 Subject: Initial Granite Rapids D Support gcc/ChangeLog: * common/config/i386/cpuinfo.h (get_intel_cpu): Handle Granite Rapids D. * common/config/i386/i386-common.cc: (processor_alias_table): Add graniterapids-d. * common/config/i386/i386-cpuinfo.h (enum processor_subtypes): Add INTEL_COREI7_GRANITERAPIDS_D. * config.gcc: Add -march=graniterapids-d. * config/i386/driver-i386.cc (host_detect_local_cpu): Handle graniterapids-d. * config/i386/i386.h: (PTA_GRANITERAPIDS_D): New. * doc/extend.texi: Add graniterapids-d. * doc/invoke.texi: Ditto. gcc/testsuite/ChangeLog: * g++.target/i386/mv16.C: Add graniterapids-d. * gcc.target/i386/funcspec-56.inc: Handle new march. --- gcc/common/config/i386/cpuinfo.h | 9 ++++++++- gcc/common/config/i386/i386-common.cc | 2 ++ gcc/common/config/i386/i386-cpuinfo.h | 1 + gcc/config.gcc | 2 +- gcc/config/i386/driver-i386.cc | 3 +++ gcc/config/i386/i386.h | 4 +++- gcc/doc/extend.texi | 3 +++ gcc/doc/invoke.texi | 11 +++++++++++ gcc/testsuite/g++.target/i386/mv16.C | 6 ++++++ gcc/testsuite/gcc.target/i386/funcspec-56.inc | 1 + 10 files changed, 39 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index ae48bc1..7c2565c 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -565,7 +565,6 @@ get_intel_cpu (struct __processor_model *cpu_model, cpu_model->__cpu_type = INTEL_SIERRAFOREST; break; case 0xad: - case 0xae: /* Granite Rapids. */ cpu = "graniterapids"; CHECK___builtin_cpu_is ("corei7"); @@ -573,6 +572,14 @@ get_intel_cpu (struct __processor_model *cpu_model, cpu_model->__cpu_type = INTEL_COREI7; cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS; break; + case 0xae: + /* Granite Rapids D. */ + cpu = "graniterapids-d"; + CHECK___builtin_cpu_is ("corei7"); + CHECK___builtin_cpu_is ("graniterapids-d"); + cpu_model->__cpu_type = INTEL_COREI7; + cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS_D; + break; case 0xb6: /* Grand Ridge. */ cpu = "grandridge"; diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index bf126f1..8cea366 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -2094,6 +2094,8 @@ const pta processor_alias_table[] = M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, {"graniterapids", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS, M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS), P_PROC_AVX512F}, + {"graniterapids-d", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS_D, + M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS_D), P_PROC_AVX512F}, {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index 2dafbb2..254dfec 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -98,6 +98,7 @@ enum processor_subtypes ZHAOXIN_FAM7H_LUJIAZUI, AMDFAM19H_ZNVER4, INTEL_COREI7_GRANITERAPIDS, + INTEL_COREI7_GRANITERAPIDS_D, CPU_SUBTYPE_MAX }; diff --git a/gcc/config.gcc b/gcc/config.gcc index d880717..1446eb2 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -682,7 +682,7 @@ silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \ skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \ sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 \ nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \ -sierraforest graniterapids grandridge native" +sierraforest graniterapids graniterapids-d grandridge native" # Additional x86 processors supported by --with-cpu=. Each processor # MUST be separated by exactly one space. diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc index 54c019a..4c362ff 100644 --- a/gcc/config/i386/driver-i386.cc +++ b/gcc/config/i386/driver-i386.cc @@ -594,6 +594,9 @@ const char *host_detect_local_cpu (int argc, const char **argv) /* Assume Grand Ridge. */ if (has_feature (FEATURE_RAOINT)) cpu = "grandridge"; + /* Assume Granite Rapids D. */ + else if (has_feature (FEATURE_AMX_COMPLEX)) + cpu = "graniterapids-d"; /* Assume Granite Rapids. */ else if (has_feature (FEATURE_AMX_FP16)) cpu = "graniterapids"; diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 84ebafd..aea3209 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2343,7 +2343,9 @@ constexpr wide_int_bitmask PTA_ALDERLAKE = PTA_TREMONT | PTA_ADX | PTA_AVX constexpr wide_int_bitmask PTA_SIERRAFOREST = PTA_ALDERLAKE | PTA_AVXIFMA | PTA_AVXVNNIINT8 | PTA_AVXNECONVERT | PTA_CMPCCXADD | PTA_ENQCMD | PTA_UINTR; constexpr wide_int_bitmask PTA_GRANITERAPIDS = PTA_SAPPHIRERAPIDS | PTA_AMX_FP16 - | PTA_PREFETCHI | PTA_AMX_COMPLEX; + | PTA_PREFETCHI; +constexpr wide_int_bitmask PTA_GRANITERAPIDS_D = PTA_GRANITERAPIDS + | PTA_AMX_COMPLEX; constexpr wide_int_bitmask PTA_GRANDRIDGE = PTA_SIERRAFOREST | PTA_RAOINT; constexpr wide_int_bitmask PTA_KNM = PTA_KNL | PTA_AVX5124VNNIW | PTA_AVX5124FMAPS | PTA_AVX512VPOPCNTDQ; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d88fd75..7e4c554 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -22218,6 +22218,9 @@ Intel Core i7 Rocketlake CPU. @item graniterapids Intel Core i7 graniterapids CPU. +@item graniterapids-d +Intel Core i7 graniterapids D CPU. + @item bonnell Intel Atom Bonnell CPU. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 3063e71..cbc1282 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -32684,6 +32684,17 @@ MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, AVX512BF16, AMX-FP16 and PREFETCHI instruction set support. +@item graniterapids-d +Intel graniterapids D CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, +SSSE3, SSE4.1, SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, +RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, +AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ, +AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2, +VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB, +MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, +SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, +AVX512BF16, AMX-FP16, PREFETCHI and AMX-COMPLEX instruction set support. + @item k6 AMD K6 CPU with MMX instruction set support. diff --git a/gcc/testsuite/g++.target/i386/mv16.C b/gcc/testsuite/g++.target/i386/mv16.C index 772791b..2158d58 100644 --- a/gcc/testsuite/g++.target/i386/mv16.C +++ b/gcc/testsuite/g++.target/i386/mv16.C @@ -104,6 +104,10 @@ int __attribute__ ((target("arch=grandridge"))) foo () { return 27; } +int __attribute__ ((target("arch=graniterapids-d"))) foo () { + return 28; +} + int main () { int val = foo (); @@ -148,6 +152,8 @@ int main () assert (val == 26); else if (__builtin_cpu_is ("grandridge")) assert (val == 27); + else if (__builtin_cpu_is ("graniterapids-d")) + assert (val == 28); else assert (val == 0); diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index cf2899f..f466962 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -203,6 +203,7 @@ extern void test_arch_sapphirerapids (void) __attribute__((__target__("arch=sapp extern void test_arch_alderlake (void) __attribute__((__target__("arch=alderlake"))); extern void test_arch_rocketlake (void) __attribute__((__target__("arch=rocketlake"))); extern void test_arch_graniterapids (void) __attribute__((__target__("arch=graniterapids"))); +extern void test_arch_graniterapids_d (void) __attribute__((__target__("arch=graniterapids-d"))); extern void test_arch_lujiazui (void) __attribute__((__target__("arch=lujiazui"))); extern void test_arch_k8 (void) __attribute__((__target__("arch=k8"))); extern void test_arch_k8_sse3 (void) __attribute__((__target__("arch=k8-sse3"))); -- cgit v1.1 From 13c556d6ae84be3ee2bc245a56eafa58221de86a Mon Sep 17 00:00:00 2001 From: liuhongt Date: Thu, 29 Jun 2023 14:25:28 +0800 Subject: Break false dependence for vpternlog by inserting vpxor or setting constraint of input operand to '0' False dependency happens when destination is only updated by pternlog. There is no false dependency when destination is also used in source. So either a pxor should be inserted, or input operand should be set with constraint '0'. gcc/ChangeLog: PR target/110438 PR target/110202 * config/i386/predicates.md (int_float_vector_all_ones_operand): New predicate. * config/i386/sse.md (*vmov_constm1_pternlog_false_dep): New define_insn. (*_cvtmask2_pternlog_false_dep): Ditto. (*_cvtmask2_pternlog_false_dep): Ditto. (*_cvtmask2): Adjust to define_insn_and_split to avoid false dependence. (*_cvtmask2): Ditto. (one_cmpl2): Adjust constraint of operands 1 to '0' to avoid false dependence. (*andnot3): Ditto. (iornot3): Ditto. (*3): Ditto. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110438.c: New test. * gcc.target/i386/pr100711-6.c: Adjust testcase. --- gcc/config/i386/predicates.md | 8 +- gcc/config/i386/sse.md | 145 ++++++++++++++++++++++++++--- gcc/testsuite/gcc.target/i386/pr100711-6.c | 2 +- gcc/testsuite/gcc.target/i386/pr110438.c | 30 ++++++ 4 files changed, 168 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110438.c (limited to 'gcc') diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 7ddbe01..37d20c6 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1192,12 +1192,18 @@ return false; }) -/* Return true if operand is a vector constant that is all ones. */ +/* Return true if operand is an integral vector constant that is all ones. */ (define_predicate "vector_all_ones_operand" (and (match_code "const_vector") (match_test "INTEGRAL_MODE_P (GET_MODE (op))") (match_test "op == CONSTM1_RTX (GET_MODE (op))"))) +/* Return true if operand is a vector constant that is all ones. */ +(define_predicate "int_float_vector_all_ones_operand" + (ior (match_operand 0 "vector_all_ones_operand") + (match_operand 0 "float_vector_all_ones_operand") + (match_test "op == constm1_rtx"))) + /* Return true if operand is an 128/256bit all ones vector that zero-extends to 256/512bit. */ (define_predicate "vector_all_ones_zero_extend_half_operand" diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index a209937..24359cd 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1382,6 +1382,29 @@ ] (symbol_ref "true")))]) +; False dependency happens on destination register which is not really +; used when moving all ones to vector register +(define_split + [(set (match_operand:VMOVE 0 "register_operand") + (match_operand:VMOVE 1 "int_float_vector_all_ones_operand"))] + "TARGET_AVX512F && reload_completed + && ( == 64 || EXT_REX_SSE_REG_P (operands[0])) + && optimize_insn_for_speed_p ()" + [(set (match_dup 0) (match_dup 2)) + (parallel + [(set (match_dup 0) (match_dup 1)) + (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] + "operands[2] = CONST0_RTX (mode);") + +(define_insn "*vmov_constm1_pternlog_false_dep" + [(set (match_operand:VMOVE 0 "register_operand" "=v") + (match_operand:VMOVE 1 "int_float_vector_all_ones_operand" "")) + (unspec [(match_operand:VMOVE 2 "register_operand" "0")] UNSPEC_INSN_FALSE_DEP)] + "TARGET_AVX512VL || == 64" + "vpternlogd\t{$0xFF, %0, %0, %0|%0, %0, %0, 0xFF}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "evex")]) + ;; If mem_addr points to a memory region with less than whole vector size bytes ;; of accessible memory and k is a mask that would prevent reading the inaccessible ;; bytes from mem_addr, add UNSPEC_MASKLOAD to prevent it to be transformed to vpblendd @@ -9336,7 +9359,7 @@ operands[3] = CONST0_RTX (mode); }") -(define_insn "*_cvtmask2" +(define_insn_and_split "*_cvtmask2" [(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v,v") (vec_merge:VI48_AVX512VL (match_operand:VI48_AVX512VL 2 "vector_all_ones_operand") @@ -9346,11 +9369,35 @@ "@ vpmovm2\t{%1, %0|%0, %1} vpternlog\t{$0x81, %0, %0, %0%{%1%}%{z%}|%0%{%1%}%{z%}, %0, %0, 0x81}" + "&& !TARGET_AVX512DQ && reload_completed + && optimize_function_for_speed_p (cfun)" + [(set (match_dup 0) (match_dup 4)) + (parallel + [(set (match_dup 0) + (vec_merge:VI48_AVX512VL + (match_dup 2) + (match_dup 3) + (match_dup 1))) + (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] + "operands[4] = CONST0_RTX (mode);" [(set_attr "isa" "avx512dq,*") (set_attr "length_immediate" "0,1") (set_attr "prefix" "evex") (set_attr "mode" "")]) +(define_insn "*_cvtmask2_pternlog_false_dep" + [(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v") + (vec_merge:VI48_AVX512VL + (match_operand:VI48_AVX512VL 2 "vector_all_ones_operand") + (match_operand:VI48_AVX512VL 3 "const0_operand") + (match_operand: 1 "register_operand" "Yk"))) + (unspec [(match_operand:VI48_AVX512VL 4 "register_operand" "0")] UNSPEC_INSN_FALSE_DEP)] + "TARGET_AVX512F && !TARGET_AVX512DQ" + "vpternlog\t{$0x81, %0, %0, %0%{%1%}%{z%}|%0%{%1%}%{z%}, %0, %0, 0x81}" + [(set_attr "length_immediate" "1") + (set_attr "prefix" "evex") + (set_attr "mode" "")]) + (define_expand "extendv2sfv2df2" [(set (match_operand:V2DF 0 "register_operand") (float_extend:V2DF @@ -17164,15 +17211,83 @@ operands[2] = force_reg (mode, operands[2]); }) -(define_insn "one_cmpl2" - [(set (match_operand:VI 0 "register_operand" "=v,v") - (xor:VI (match_operand:VI 1 "bcst_vector_operand" "vBr,m") - (match_operand:VI 2 "vector_all_ones_operand" "BC,BC")))] +(define_insn_and_split "one_cmpl2" + [(set (match_operand:VI 0 "register_operand" "=v,v,v") + (xor:VI (match_operand:VI 1 "bcst_vector_operand" " 0, m,Br") + (match_operand:VI 2 "vector_all_ones_operand" "BC,BC,BC")))] "TARGET_AVX512F && (! || mode == SImode || mode == DImode)" { + if (! && which_alternative + && optimize_insn_for_speed_p ()) + return "#"; + + if (TARGET_AVX512VL) + return "vpternlog\t{$0x55, %1, %0, %0|%0, %0, %1, 0x55}"; + else + return "vpternlog\t{$0x55, %g1, %g0, %g0|%g0, %g0, %g1, 0x55}"; +} + "&& reload_completed && !REG_P (operands[1]) && ! + && optimize_insn_for_speed_p ()" + [(set (match_dup 0) (match_dup 3)) + (parallel + [(set (match_dup 0) + (xor:VI (match_dup 1) (match_dup 2))) + (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] +{ + if (MEM_P (operands[1])) + { + operands[3] = operands[1]; + operands[1] = operands[0]; + } + else + { + if (GET_MODE_SIZE (mode) < 4) + { + if ( == 64 ? TARGET_AVX512BW + : (TARGET_AVX512BW && TARGET_AVX512VL) + || !EXT_REX_SSE_REG_P (operands[0])) + { + operands[3] = operands[1]; + operands[1] = operands[0]; + } + else + operands[3] = CONST0_RTX (mode); + } + else + { + if ( == 64 || TARGET_AVX512VL + || !EXT_REX_SSE_REG_P (operands[0])) + { + operands[3] = operands[1]; + operands[1] = operands[0]; + } + else + operands[3] = CONST0_RTX (mode); + } + } +} + [(set_attr "type" "sselog") + (set_attr "prefix" "evex") + (set (attr "mode") + (if_then_else (match_test "TARGET_AVX512VL") + (const_string "") + (const_string "XI"))) + (set (attr "enabled") + (if_then_else (eq_attr "alternative" "1") + (symbol_ref " == 64 || TARGET_AVX512VL") + (const_int 1)))]) + +(define_insn "*one_cmpl2_pternlog_false_dep" + [(set (match_operand:VI 0 "register_operand" "=v,v,v") + (xor:VI (match_operand:VI 1 "bcst_vector_operand" " 0, m,Br") + (match_operand:VI 2 "vector_all_ones_operand" "BC,BC,BC"))) + (unspec [(match_operand:VI 3 "register_operand" "0,0,0")] + UNSPEC_INSN_FALSE_DEP)] + "TARGET_AVX512F" +{ if (TARGET_AVX512VL) return "vpternlog\t{$0x55, %1, %0, %0|%0, %0, %1, 0x55}"; else @@ -17224,7 +17339,7 @@ [(set (match_operand:VI 0 "register_operand" "=x,x,v,v,v") (and:VI (not:VI (match_operand:VI 1 "bcst_vector_operand" "0,x,v,m,Br")) - (match_operand:VI 2 "bcst_vector_operand" "xBm,xm,vmBr,v,v")))] + (match_operand:VI 2 "bcst_vector_operand" "xBm,xm,vmBr,0,0")))] "TARGET_SSE && (register_operand (operands[1], mode) || register_operand (operands[2], mode))" @@ -17683,8 +17798,8 @@ [(set (match_operand:VI 0 "register_operand" "=v,v,v,v") (ior:VI (not:VI - (match_operand:VI 1 "bcst_vector_operand" "v,Br,v,m")) - (match_operand:VI 2 "bcst_vector_operand" "vBr,v,m,v")))] + (match_operand:VI 1 "bcst_vector_operand" "0,m, 0,vBr")) + (match_operand:VI 2 "bcst_vector_operand" "m,0,vBr, 0")))] "( == 64 || TARGET_AVX512VL || (TARGET_AVX512F && !TARGET_PREFER_AVX256)) && (register_operand (operands[1], mode) @@ -17708,7 +17823,7 @@ (const_string "") (const_string "XI"))) (set (attr "enabled") - (if_then_else (eq_attr "alternative" "2,3") + (if_then_else (eq_attr "alternative" "0,1") (symbol_ref " == 64 || TARGET_AVX512VL") (const_string "*")))]) @@ -17716,8 +17831,8 @@ [(set (match_operand:VI 0 "register_operand" "=v,v") (not:VI (xor:VI - (match_operand:VI 1 "bcst_vector_operand" "%v,v") - (match_operand:VI 2 "bcst_vector_operand" "vBr,m"))))] + (match_operand:VI 1 "bcst_vector_operand" "%0, 0") + (match_operand:VI 2 "bcst_vector_operand" " m,vBr"))))] "( == 64 || TARGET_AVX512VL || (TARGET_AVX512F && !TARGET_PREFER_AVX256)) && (register_operand (operands[1], mode) @@ -17736,7 +17851,7 @@ (const_string "") (const_string "XI"))) (set (attr "enabled") - (if_then_else (eq_attr "alternative" "1") + (if_then_else (eq_attr "alternative" "0") (symbol_ref " == 64 || TARGET_AVX512VL") (const_string "*")))]) @@ -17747,8 +17862,8 @@ (define_insn "*3" [(set (match_operand:VI 0 "register_operand" "=v,v") (andor:VI - (not:VI (match_operand:VI 1 "bcst_vector_operand" "%v,v")) - (not:VI (match_operand:VI 2 "bcst_vector_operand" "vBr,m"))))] + (not:VI (match_operand:VI 1 "bcst_vector_operand" "%0, 0")) + (not:VI (match_operand:VI 2 "bcst_vector_operand" "m,vBr"))))] "( == 64 || TARGET_AVX512VL || (TARGET_AVX512F && !TARGET_PREFER_AVX256)) && (register_operand (operands[1], mode) @@ -17767,7 +17882,7 @@ (const_string "") (const_string "XI"))) (set (attr "enabled") - (if_then_else (eq_attr "alternative" "1") + (if_then_else (eq_attr "alternative" "0") (symbol_ref " == 64 || TARGET_AVX512VL") (const_string "*")))]) diff --git a/gcc/testsuite/gcc.target/i386/pr100711-6.c b/gcc/testsuite/gcc.target/i386/pr100711-6.c index 7142a98..8085074 100644 --- a/gcc/testsuite/gcc.target/i386/pr100711-6.c +++ b/gcc/testsuite/gcc.target/i386/pr100711-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */ +/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -Os" } */ typedef int v16si __attribute__ ((vector_size (64))); typedef long long v8di __attribute__((vector_size (64))); diff --git a/gcc/testsuite/gcc.target/i386/pr110438.c b/gcc/testsuite/gcc.target/i386/pr110438.c new file mode 100644 index 0000000..11b8cc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110438.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx512f -O2 -ftree-vectorize -mno-avx512dq -dp -mprefer-vector-width=512" } */ +/* { dg-final { scan-assembler-times {cvtmask2.*_pternlog} "1" } } */ +/* { dg-final { scan-assembler-times {constm1_pternlog} "1" } } */ +/* { dg-final { scan-assembler-not {(?n)vpternlogd.*\(} } } */ + + +#include + +__m512i g(void) +{ + return (__m512i){ 0 } - 1; +} + +__m512i g1(__m512i* a) +{ + return ~(*a); +} + +void +foo (int* a, int* __restrict b) +{ + for (int i = 0; i != 16; i++) + { + if (b[i]) + a[i] = -1; + else + a[i] = 0; + } +} -- cgit v1.1 From d05c8b016fb96cdcc445406469867b757776894e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Wed, 15 Mar 2023 10:45:11 +0100 Subject: riscv: xtheadbb: Add sign/zero extension support for th.ext and th.extu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current support of the bitfield-extraction instructions th.ext and th.extu (XTheadBb extension) only covers sign_extract and zero_extract. This patch add support for sign_extend and zero_extend to avoid any shifts for sign or zero extensions. gcc/ChangeLog: * config/riscv/riscv.md: No base-ISA extension splitter for XThead*. * config/riscv/thead.md (*extend2_th_ext): New XThead extension INSN. (*zero_extendsidi2_th_extu): New XThead extension INSN. (*zero_extendhi2_th_extu): New XThead extension INSN. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadbb-ext-1.c: New test. * gcc.target/riscv/xtheadbb-extu-1.c: New test. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.md | 6 +-- gcc/config/riscv/thead.md | 31 +++++++++++ gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c | 67 ++++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c | 67 ++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index d63b584..7988026 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1594,7 +1594,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" " r,m")))] - "TARGET_64BIT && !TARGET_ZBA + "TARGET_64BIT && !TARGET_ZBA && !TARGET_XTHEADBB && !(register_operand (operands[1], SImode) && reg_or_subregno (operands[1]) == VL_REGNUM)" "@ @@ -1621,7 +1621,7 @@ [(set (match_operand:GPR 0 "register_operand" "=r,r") (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" " r,m")))] - "!TARGET_ZBB" + "!TARGET_ZBB && !TARGET_XTHEADBB" "@ # lhu\t%0,%1" @@ -1677,7 +1677,7 @@ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") (sign_extend:SUPERQI (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] - "!TARGET_ZBB" + "!TARGET_ZBB && !TARGET_XTHEADBB" "@ # l\t%0,%1" diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index ea37787..e8d3fcb 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -59,6 +59,17 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "")]) +(define_insn "*extend2_th_ext" + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") + (sign_extend:SUPERQI + (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))] + "TARGET_XTHEADBB" + "@ + th.ext\t%0,%1,15,0 + l\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "")]) + (define_insn "*th_extu4" [(set (match_operand:GPR 0 "register_operand" "=r") (zero_extract:GPR (match_operand:GPR 1 "register_operand" "r") @@ -72,6 +83,26 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "")]) +(define_insn "*zero_extendsidi2_th_extu" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))] + "TARGET_64BIT && TARGET_XTHEADBB" + "@ + th.extu\t%0,%1,31,0 + lwu\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "SI")]) + +(define_insn "*zero_extendhi2_th_extu" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))] + "TARGET_XTHEADBB" + "@ + th.extu\t%0,%1,15,0 + lhu\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "HI")]) + (define_insn "*th_clz2" [(set (match_operand:X 0 "register_operand" "=r") (clz:X (match_operand:X 1 "register_operand" "r")))] diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c new file mode 100644 index 0000000..02f6ec1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +long sext64_32(int s32) +{ + return s32; +} + +long sext64_16(short s16) +{ + return s16; +} + +long sext64_8(char s8) +{ + return s8; +} + +int sext32_64(long s64) +{ + return s64; +} + +int sext32_16(short s16) +{ + return s16; +} + +int sext32_8(char s8) +{ + return s8; +} + +short sext16_64(long s64) +{ + return s64; +} + +short sext16_32(int s32) +{ + return s32; +} + +short sext16_8(char s8) +{ + return s8; +} + +char sext8_64(long s64) +{ + return s64; +} + +char sext8_32(int s32) +{ + return s32; +} + +char sext8_16(short s16) +{ + return s16; +} + +/* { dg-final { scan-assembler-not "slli" } } */ +/* { dg-final { scan-assembler-not "srli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c new file mode 100644 index 0000000..01e3eda --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +unsigned long zext64_32(unsigned int u32) +{ + return u32; //th.extu a0, a0, 31, 0 +} + +unsigned long zext64_16(unsigned short u16) +{ + return u16; +} + +unsigned long zext64_8(unsigned char u8) +{ + return u8; +} + +unsigned int zext32_64(unsigned long u64) +{ + return u64; +} + +unsigned int zext32_16(unsigned short u16) +{ + return u16; +} + +unsigned int zext32_8(unsigned char u8) +{ + return u8; +} + +unsigned short zext16_64(unsigned long u64) +{ + return u64; +} + +unsigned short zext16_32(unsigned int u32) +{ + return u32; +} + +unsigned short zext16_8(unsigned char u8) +{ + return u8; +} + +unsigned char zext8_64(unsigned long u64) +{ + return u64; +} + +unsigned char zext8_32(unsigned int u32) +{ + return u32; +} + +unsigned char zext8_16(unsigned short u16) +{ + return u16; +} + +/* { dg-final { scan-assembler-not "slli" } } */ +/* { dg-final { scan-assembler-not "srli" } } */ -- cgit v1.1 From 93973e4c5d3bcde1f84cad3b42a8c36e23900d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Mon, 24 Apr 2023 23:09:06 +0200 Subject: riscv: xtheadmempair: Fix CFA reg notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation triggers an assertion in dwarf2out_frame_debug_cfa_offset() under certain circumstances. The standard code uses REG_FRAME_RELATED_EXPR notes instead of REG_CFA_OFFSET notes when saving registers on the stack. So let's do this as well. gcc/ChangeLog: * config/riscv/thead.cc (th_mempair_save_regs): Emit REG_FRAME_RELATED_EXPR notes in prologue. Signed-off-by: Christoph Müllner --- gcc/config/riscv/thead.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index 7520380..d7e3cf8 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -368,8 +368,12 @@ th_mempair_save_regs (rtx operands[4]) rtx set2 = gen_rtx_SET (operands[2], operands[3]); rtx insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set1, set2))); RTX_FRAME_RELATED_P (insn) = 1; - add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set1)); - add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set2)); + + REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, + copy_rtx (set1), REG_NOTES (insn)); + + REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, + copy_rtx (set2), REG_NOTES (insn)); } /* Similar like riscv_restore_reg, but restores two registers from memory -- cgit v1.1 From e15a82a1fea3a68f47d9a5a8634265eeec1562a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Mon, 24 Apr 2023 23:18:06 +0200 Subject: riscv: xtheadmempair: Fix doc for th_mempair_order_operands() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is an incorrect sentence in the documentation of the function th_mempair_order_operands(). Let's remove it. gcc/ChangeLog: * config/riscv/thead.cc (th_mempair_operands_p): Fix documentation of th_mempair_order_operands(). Signed-off-by: Christoph Müllner --- gcc/config/riscv/thead.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index d7e3cf8..507c912 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -336,8 +336,8 @@ th_mempair_operands_p (rtx operands[4], bool load_p, } /* Given OPERANDS of consecutive load/store that can be merged, - swap them if they are not in ascending order. - Return true if swap was performed. */ + swap them if they are not in ascending order. */ + void th_mempair_order_operands (rtx operands[4], bool load_p, machine_mode mode) { -- cgit v1.1 From 208e10bf8a90f49aa40152ab7fcebe8cd7c5d31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Tue, 25 Apr 2023 14:40:37 +0200 Subject: riscv: thead: Adjust constraints of th_addsl INSN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A recent change adjusted the constraints of ZBA's shNadd INSN. Let's mirror this change here as well. gcc/ChangeLog: * config/riscv/thead.md: Adjust constraints of th_addsl. Signed-off-by: Christoph Müllner --- gcc/config/riscv/thead.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index e8d3fcb..840a9ff 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -22,10 +22,9 @@ (define_insn "*th_addsl4" [(set (match_operand:X 0 "register_operand" "=r") (plus:X (ashift:X (match_operand:X 1 "register_operand" "r") - (match_operand 2 "const_int_operand" "n")) + (match_operand:QI 2 "imm123_operand" "Ds3")) (match_operand:X 3 "register_operand" "r")))] - "TARGET_XTHEADBA - && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)" + "TARGET_XTHEADBA" "th.addsl\t%0,%3,%1,%2" [(set_attr "type" "bitmanip") (set_attr "mode" "")]) -- cgit v1.1 From b621883620b127caf20e88e59fa73e666960013e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Thu, 27 Apr 2023 08:53:29 +0200 Subject: riscv: Simplify output of MEM addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have the following situation for MEM RTX objects: * TARGET_PRINT_OPERAND expands to riscv_print_operand() * This falls into the default case (unknown or on letter) of the outer switch-case-block and the MEM case of the inner switch-case-block and calls output_address() in final.cc with XEXP (op, 0) (the address) * This calls targetm.asm_out.print_operand_address() which is riscv_print_operand_address() * riscv_print_operand_address() is targeting the address of a MEM RTX * riscv_print_operand_address() calls riscv_print_operand() for the offset and directly prints the register if the address is classified as ADDRESS_REG * This falls into the default case (unknown or on letter) of the outer switch-case-block and the default case of the inner switch-case-block and calls output_addr_const(). However, since we know that offset must be a CONST_INT (which will be followed by a '()' string), there is no need to call riscv_print_operand() for the offset. Instead we can take the shortcut and use output_addr_const(). This change also brings the code in riscv_print_operand_address() in line with the other cases, where output_addr_const() is used to print offsets. Tested with GCC regression test suite and SPEC intrate. Signed-off-by: Christoph Müllner gcc/ChangeLog: * config/riscv/riscv.cc (riscv_print_operand_address): Use output_addr_const rather than riscv_print_operand. --- gcc/config/riscv/riscv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 38d8eb2..4d6e70b 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4801,7 +4801,7 @@ riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx switch (addr.type) { case ADDRESS_REG: - riscv_print_operand (file, addr.offset, 0); + output_addr_const (file, riscv_strip_unspec_address (addr.offset)); fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]); return; -- cgit v1.1 From a3480aacc4ab01651725a63e05829a43bc23d549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Tue, 25 Apr 2023 15:24:13 +0200 Subject: riscv: Define Xmode macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define a Xmode macro that specifies the registers size (XLEN) similar to Pmode. This allows the backend code to write generic RV32/RV64 C code (under certain circumstances). gcc/ChangeLog: * config/riscv/riscv.h (Xmode): New macro. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 83dcac1..7d548ac 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -800,6 +800,10 @@ typedef struct { #define Pmode word_mode +/* Specify the machine mode that registers have. */ + +#define Xmode (TARGET_64BIT ? DImode : SImode) + /* Give call MEMs SImode since it is the "most permissive" mode for both 32-bit and 64-bit targets. */ -- cgit v1.1 From 96ad6ab29b3d6d8646c97760cc87a17f405e09d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Mon, 24 Apr 2023 23:42:50 +0200 Subject: riscv: Move address classification info types to riscv-protos.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit enum riscv_address_type and struct riscv_address_info are used to store address classification information. Let's move this types into our common header file in order to share them with other compilation units. This is a non-functional change without any intendet side-effects. gcc/ChangeLog: * config/riscv/riscv-protos.h (enum riscv_address_type): New location of type definition. (struct riscv_address_info): Likewise. * config/riscv/riscv.cc (enum riscv_address_type): Old location of type definition. (struct riscv_address_info): Likewise. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv-protos.h | 43 +++++++++++++++++++++++++++++++++++++++++ gcc/config/riscv/riscv.cc | 43 ----------------------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 6cd5c66..8f5a5ab 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -37,6 +37,49 @@ enum riscv_symbol_type { }; #define NUM_SYMBOL_TYPES (SYMBOL_TLS_GD + 1) +/* Classifies an address. + + ADDRESS_REG + A natural register + offset address. The register satisfies + riscv_valid_base_register_p and the offset is a const_arith_operand. + + ADDRESS_LO_SUM + A LO_SUM rtx. The first operand is a valid base register and + the second operand is a symbolic address. + + ADDRESS_CONST_INT + A signed 16-bit constant address. + + ADDRESS_SYMBOLIC: + A constant symbolic address. */ +enum riscv_address_type { + ADDRESS_REG, + ADDRESS_LO_SUM, + ADDRESS_CONST_INT, + ADDRESS_SYMBOLIC +}; + +/* Information about an address described by riscv_address_type. + + ADDRESS_CONST_INT + No fields are used. + + ADDRESS_REG + REG is the base register and OFFSET is the constant offset. + + ADDRESS_LO_SUM + REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE + is the type of symbol it references. + + ADDRESS_SYMBOLIC + SYMBOL_TYPE is the type of symbol that the address references. */ +struct riscv_address_info { + enum riscv_address_type type; + rtx reg; + rtx offset; + enum riscv_symbol_type symbol_type; +}; + /* Routines implemented in riscv.cc. */ extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx); extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 4d6e70b..477b83c 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -90,28 +90,6 @@ along with GCC; see the file COPYING3. If not see /* True if bit BIT is set in VALUE. */ #define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0) -/* Classifies an address. - - ADDRESS_REG - A natural register + offset address. The register satisfies - riscv_valid_base_register_p and the offset is a const_arith_operand. - - ADDRESS_LO_SUM - A LO_SUM rtx. The first operand is a valid base register and - the second operand is a symbolic address. - - ADDRESS_CONST_INT - A signed 16-bit constant address. - - ADDRESS_SYMBOLIC: - A constant symbolic address. */ -enum riscv_address_type { - ADDRESS_REG, - ADDRESS_LO_SUM, - ADDRESS_CONST_INT, - ADDRESS_SYMBOLIC -}; - /* Information about a function's frame layout. */ struct GTY(()) riscv_frame_info { /* The size of the frame in bytes. */ @@ -191,27 +169,6 @@ struct riscv_arg_info { unsigned int fpr_offset; }; -/* Information about an address described by riscv_address_type. - - ADDRESS_CONST_INT - No fields are used. - - ADDRESS_REG - REG is the base register and OFFSET is the constant offset. - - ADDRESS_LO_SUM - REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE - is the type of symbol it references. - - ADDRESS_SYMBOLIC - SYMBOL_TYPE is the type of symbol that the address references. */ -struct riscv_address_info { - enum riscv_address_type type; - rtx reg; - rtx offset; - enum riscv_symbol_type symbol_type; -}; - /* One stage in a constant building sequence. These sequences have the form: -- cgit v1.1 From 423604278ed550f07f80c9687a441c58a6cd6e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Mon, 24 Apr 2023 23:54:16 +0200 Subject: riscv: Prepare backend for index registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RISC-V does currently not support index registers. However, there are some vendor extensions that specify them. Let's do the necessary changes in the backend so that we can add support for such a vendor extension in the future. This is a non-functional change without any intended side-effects. gcc/ChangeLog: * config/riscv/riscv-protos.h (riscv_regno_ok_for_index_p): New prototype. (riscv_index_reg_class): Likewise. * config/riscv/riscv.cc (riscv_regno_ok_for_index_p): New function. (riscv_index_reg_class): New function. * config/riscv/riscv.h (INDEX_REG_CLASS): Call new function riscv_index_reg_class(). (REGNO_OK_FOR_INDEX_P): Call new function riscv_regno_ok_for_index_p(). Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv-protos.h | 2 ++ gcc/config/riscv/riscv.cc | 20 ++++++++++++++++++++ gcc/config/riscv/riscv.h | 6 ++++-- 3 files changed, 26 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 8f5a5ab..5ce0d47 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -84,6 +84,8 @@ struct riscv_address_info { extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx); extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *); extern int riscv_regno_mode_ok_for_base_p (int, machine_mode, bool); +extern enum reg_class riscv_index_reg_class (); +extern int riscv_regno_ok_for_index_p (int); extern int riscv_address_insns (rtx, machine_mode, bool); extern int riscv_const_insns (rtx); extern int riscv_split_const_insns (rtx); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 477b83c..af18231 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -846,6 +846,26 @@ riscv_regno_mode_ok_for_base_p (int regno, return GP_REG_P (regno); } +/* Get valid index register class. + The RISC-V base instructions don't support index registers, + but extensions might support that. */ + +enum reg_class +riscv_index_reg_class () +{ + return NO_REGS; +} + +/* Return true if register REGNO is a valid index register. + The RISC-V base instructions don't support index registers, + but extensions might support that. */ + +int +riscv_regno_ok_for_index_p (int regno) +{ + return 0; +} + /* Return true if X is a valid base register for mode MODE. STRICT_P is true if REG_OK_STRICT is in effect. */ diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 7d548ac..1968315 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -542,7 +542,7 @@ enum reg_class factor or added to another register (as well as added to a displacement). */ -#define INDEX_REG_CLASS NO_REGS +#define INDEX_REG_CLASS riscv_index_reg_class() /* We generally want to put call-clobbered registers ahead of call-saved ones. (IRA expects this.) */ @@ -714,7 +714,9 @@ typedef struct { /* Addressing modes, and classification of registers for them. */ -#define REGNO_OK_FOR_INDEX_P(REGNO) 0 +#define REGNO_OK_FOR_INDEX_P(REGNO) \ + riscv_regno_ok_for_index_p (REGNO) + #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ riscv_regno_mode_ok_for_base_p (REGNO, MODE, 1) -- cgit v1.1 From 96d32c111e63b7cde38410f4e316512771c8ecff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Fri, 21 Apr 2023 03:46:26 +0200 Subject: riscv: thead: Factor out XThead*-specific peepholes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch moves the XThead*-specific peephole passes into thead-peephole.md with the intend to keep vendor-specific code separated from RISC-V standard code. This patch does not contain any functional changes. gcc/ChangeLog: * config/riscv/peephole.md: Remove XThead* peephole passes. * config/riscv/thead.md: Include thead-peephole.md. * config/riscv/thead-peephole.md: New file. Signed-off-by: Christoph Müllner --- gcc/config/riscv/peephole.md | 56 ----------------------------- gcc/config/riscv/thead-peephole.md | 74 ++++++++++++++++++++++++++++++++++++++ gcc/config/riscv/thead.md | 2 ++ 3 files changed, 76 insertions(+), 56 deletions(-) create mode 100644 gcc/config/riscv/thead-peephole.md (limited to 'gcc') diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md index 67e7046..0ef0c04 100644 --- a/gcc/config/riscv/peephole.md +++ b/gcc/config/riscv/peephole.md @@ -38,59 +38,3 @@ { operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5])); }) - -;; XTheadMemPair: merge two SI or DI loads -(define_peephole2 - [(set (match_operand:GPR 0 "register_operand" "") - (match_operand:GPR 1 "memory_operand" "")) - (set (match_operand:GPR 2 "register_operand" "") - (match_operand:GPR 3 "memory_operand" ""))] - "TARGET_XTHEADMEMPAIR - && th_mempair_operands_p (operands, true, mode)" - [(parallel [(set (match_dup 0) (match_dup 1)) - (set (match_dup 2) (match_dup 3))])] -{ - th_mempair_order_operands (operands, true, mode); -}) - -;; XTheadMemPair: merge two SI or DI stores -(define_peephole2 - [(set (match_operand:GPR 0 "memory_operand" "") - (match_operand:GPR 1 "register_operand" "")) - (set (match_operand:GPR 2 "memory_operand" "") - (match_operand:GPR 3 "register_operand" ""))] - "TARGET_XTHEADMEMPAIR - && th_mempair_operands_p (operands, false, mode)" - [(parallel [(set (match_dup 0) (match_dup 1)) - (set (match_dup 2) (match_dup 3))])] -{ - th_mempair_order_operands (operands, false, mode); -}) - -;; XTheadMemPair: merge two SI loads with sign-extension -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI (match_operand:SI 1 "memory_operand" ""))) - (set (match_operand:DI 2 "register_operand" "") - (sign_extend:DI (match_operand:SI 3 "memory_operand" "")))] - "TARGET_XTHEADMEMPAIR && TARGET_64BIT - && th_mempair_operands_p (operands, true, SImode)" - [(parallel [(set (match_dup 0) (sign_extend:DI (match_dup 1))) - (set (match_dup 2) (sign_extend:DI (match_dup 3)))])] -{ - th_mempair_order_operands (operands, true, SImode); -}) - -;; XTheadMemPair: merge two SI loads with zero-extension -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI (match_operand:SI 1 "memory_operand" ""))) - (set (match_operand:DI 2 "register_operand" "") - (zero_extend:DI (match_operand:SI 3 "memory_operand" "")))] - "TARGET_XTHEADMEMPAIR && TARGET_64BIT - && th_mempair_operands_p (operands, true, SImode)" - [(parallel [(set (match_dup 0) (zero_extend:DI (match_dup 1))) - (set (match_dup 2) (zero_extend:DI (match_dup 3)))])] -{ - th_mempair_order_operands (operands, true, SImode); -}) diff --git a/gcc/config/riscv/thead-peephole.md b/gcc/config/riscv/thead-peephole.md new file mode 100644 index 0000000..5b829b5 --- /dev/null +++ b/gcc/config/riscv/thead-peephole.md @@ -0,0 +1,74 @@ +;; Machine description for T-Head vendor extensions +;; Copyright (C) 2023 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; XTheadMemPair: merge two SI or DI loads +(define_peephole2 + [(set (match_operand:GPR 0 "register_operand" "") + (match_operand:GPR 1 "memory_operand" "")) + (set (match_operand:GPR 2 "register_operand" "") + (match_operand:GPR 3 "memory_operand" ""))] + "TARGET_XTHEADMEMPAIR + && th_mempair_operands_p (operands, true, mode)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])] +{ + th_mempair_order_operands (operands, true, mode); +}) + +;; XTheadMemPair: merge two SI or DI stores +(define_peephole2 + [(set (match_operand:GPR 0 "memory_operand" "") + (match_operand:GPR 1 "register_operand" "")) + (set (match_operand:GPR 2 "memory_operand" "") + (match_operand:GPR 3 "register_operand" ""))] + "TARGET_XTHEADMEMPAIR + && th_mempair_operands_p (operands, false, mode)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])] +{ + th_mempair_order_operands (operands, false, mode); +}) + +;; XTheadMemPair: merge two SI loads with sign-extension +(define_peephole2 + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:DI 2 "register_operand" "") + (sign_extend:DI (match_operand:SI 3 "memory_operand" "")))] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && th_mempair_operands_p (operands, true, SImode)" + [(parallel [(set (match_dup 0) (sign_extend:DI (match_dup 1))) + (set (match_dup 2) (sign_extend:DI (match_dup 3)))])] +{ + th_mempair_order_operands (operands, true, SImode); +}) + +;; XTheadMemPair: merge two SI loads with zero-extension +(define_peephole2 + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:DI 2 "register_operand" "") + (zero_extend:DI (match_operand:SI 3 "memory_operand" "")))] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && th_mempair_operands_p (operands, true, SImode)" + [(parallel [(set (match_dup 0) (zero_extend:DI (match_dup 1))) + (set (match_dup 2) (zero_extend:DI (match_dup 3)))])] +{ + th_mempair_order_operands (operands, true, SImode); +}) diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 840a9ff..29f98de 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -361,3 +361,5 @@ [(set_attr "move_type" "load") (set_attr "mode" "DI") (set_attr "length" "8")]) + +(include "thead-peephole.md") -- cgit v1.1 From 28cdba24a9b8405d9f4ec2591c53d23a8bb74051 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 12 Jul 2023 12:14:08 +0200 Subject: x86: make better use of VBROADCASTSS / VPBROADCASTD ... in vec_dupv4sf / *vec_dupv4si. The respective broadcast insns are never longer (yet sometimes shorter) than the corresponding VSHUFPS / VPSHUFD, due to the immediate operand of the shuffle insns balancing the (uniform) need for VEX3 in the broadcast ones. When EVEX encoding is respective the broadcast insns are always shorter. Add new alternatives to cover the AVX2 and AVX512 cases as appropriate. While touching this anyway, switch to consistently using "sseshuf1" in the "type" attributes for all shuffle forms. gcc/ * config/i386/sse.md (vec_dupv4sf): Make first alternative use vbroadcastss for AVX2. New AVX512F alternative. (*vec_dupv4si): New AVX2 and AVX512F alternatives using vpbroadcastd. Replace sselog1 by sseshuf1 in "type" attribute. gcc/testsuite/ * gcc.target/i386/avx2-dupv4sf.c: New test. * gcc.target/i386/avx2-dupv4si.c: Likewise. * gcc.target/i386/avx512f-dupv4sf.c: Likewise. * gcc.target/i386/avx512f-dupv4si.c: Likewise. --- gcc/config/i386/sse.md | 61 +++++++++++++++++-------- gcc/testsuite/gcc.target/i386/avx2-dupv4sf.c | 18 ++++++++ gcc/testsuite/gcc.target/i386/avx2-dupv4si.c | 18 ++++++++ gcc/testsuite/gcc.target/i386/avx512f-dupv4sf.c | 13 ++++++ gcc/testsuite/gcc.target/i386/avx512f-dupv4si.c | 13 ++++++ 5 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx2-dupv4sf.c create mode 100644 gcc/testsuite/gcc.target/i386/avx2-dupv4si.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-dupv4sf.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-dupv4si.c (limited to 'gcc') diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 24359cd..6bf9c99 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -26475,41 +26475,64 @@ (const_int 1)))]) (define_insn "vec_dupv4sf" - [(set (match_operand:V4SF 0 "register_operand" "=v,v,x") + [(set (match_operand:V4SF 0 "register_operand" "=v,v,v,x") (vec_duplicate:V4SF - (match_operand:SF 1 "nonimmediate_operand" "Yv,m,0")))] + (match_operand:SF 1 "nonimmediate_operand" "Yv,v,m,0")))] "TARGET_SSE" "@ - vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0} + * return TARGET_AVX2 ? \"vbroadcastss\t{%1, %0|%0, %1}\" : \"vshufps\t{$0, %d1, %0|%0, %d1, 0}\"; + vbroadcastss\t{%1, %g0|%g0, %1} vbroadcastss\t{%1, %0|%0, %1} shufps\t{$0, %0, %0|%0, %0, 0}" - [(set_attr "isa" "avx,avx,noavx") - (set_attr "type" "sseshuf1,ssemov,sseshuf1") - (set_attr "length_immediate" "1,0,1") - (set_attr "prefix_extra" "0,1,*") - (set_attr "prefix" "maybe_evex,maybe_evex,orig") - (set_attr "mode" "V4SF")]) + [(set_attr "isa" "avx,*,avx,noavx") + (set (attr "type") + (cond [(and (eq_attr "alternative" "0") + (match_test "!TARGET_AVX2")) + (const_string "sseshuf1") + (eq_attr "alternative" "3") + (const_string "sseshuf1") + ] + (const_string "ssemov"))) + (set (attr "length_immediate") + (if_then_else (eq_attr "type" "sseshuf1") + (const_string "1") + (const_string "0"))) + (set_attr "prefix_extra" "0,1,1,*") + (set_attr "prefix" "maybe_evex,evex,maybe_evex,orig") + (set_attr "mode" "V4SF,V16SF,V4SF,V4SF") + (set (attr "enabled") + (if_then_else (eq_attr "alternative" "1") + (symbol_ref "TARGET_AVX512F && !TARGET_AVX512VL + && !TARGET_PREFER_AVX256") + (const_string "*")))]) (define_insn "*vec_dupv4si" - [(set (match_operand:V4SI 0 "register_operand" "=v,v,x") + [(set (match_operand:V4SI 0 "register_operand" "=v,v,v,v,x") (vec_duplicate:V4SI - (match_operand:SI 1 "nonimmediate_operand" "Yv,m,0")))] + (match_operand:SI 1 "nonimmediate_operand" "Yvm,v,Yv,m,0")))] "TARGET_SSE" "@ + vpbroadcastd\t{%1, %0|%0, %1} + vpbroadcastd\t{%1, %g0|%g0, %1} %vpshufd\t{$0, %1, %0|%0, %1, 0} vbroadcastss\t{%1, %0|%0, %1} shufps\t{$0, %0, %0|%0, %0, 0}" - [(set_attr "isa" "sse2,avx,noavx") - (set_attr "type" "sselog1,ssemov,sselog1") - (set_attr "length_immediate" "1,0,1") - (set_attr "prefix_extra" "0,1,*") - (set_attr "prefix" "maybe_vex,maybe_evex,orig") - (set_attr "mode" "TI,V4SF,V4SF") + [(set_attr "isa" "avx2,*,sse2,avx,noavx") + (set_attr "type" "ssemov,ssemov,sseshuf1,ssemov,sseshuf1") + (set_attr "length_immediate" "0,0,1,0,1") + (set_attr "prefix_extra" "1,1,0,1,*") + (set_attr "prefix" "maybe_evex,evex,maybe_vex,maybe_evex,orig") + (set_attr "mode" "TI,XI,TI,V4SF,V4SF") (set (attr "preferred_for_speed") - (cond [(eq_attr "alternative" "1") + (cond [(eq_attr "alternative" "3") (symbol_ref "!TARGET_INTER_UNIT_MOVES_TO_VEC") ] - (symbol_ref "true")))]) + (symbol_ref "true"))) + (set (attr "enabled") + (if_then_else (eq_attr "alternative" "1") + (symbol_ref "TARGET_AVX512F && !TARGET_AVX512VL + && !TARGET_PREFER_AVX256") + (const_string "*")))]) (define_insn "*vec_dupv2di" [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,v,x") diff --git a/gcc/testsuite/gcc.target/i386/avx2-dupv4sf.c b/gcc/testsuite/gcc.target/i386/avx2-dupv4sf.c new file mode 100644 index 0000000..9b45ee5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-dupv4sf.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx2 -O2" } */ +/* { dg-final { scan-assembler-times "vbroadcastss" 2 } } */ + +typedef float __attribute__ ((vector_size (16))) v4sf; + +v4sf bcst_reg (float f) +{ + register float x asm ("xmm7") = f; + + asm ("" : "+v" (x)); + return (v4sf) {x, x, x, x}; +} + +v4sf bcst_mem (const float *f) +{ + return (v4sf) {*f, *f, *f, *f}; +} diff --git a/gcc/testsuite/gcc.target/i386/avx2-dupv4si.c b/gcc/testsuite/gcc.target/i386/avx2-dupv4si.c new file mode 100644 index 0000000..ffe6318 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-dupv4si.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx2 -O2" } */ +/* { dg-final { scan-assembler-times "vpbroadcastd" 2 } } */ + +typedef int __attribute__ ((vector_size (16))) v4si; + +v4si bcst_reg (int i) +{ + register int x asm ("xmm7") = i; + + asm ("" : "+v" (x)); + return (v4si) {x, x, x, x}; +} + +v4si bcst_mem (const int *i) +{ + return (v4si) {*i, *i, *i, *i}; +} diff --git a/gcc/testsuite/gcc.target/i386/avx512f-dupv4sf.c b/gcc/testsuite/gcc.target/i386/avx512f-dupv4sf.c new file mode 100644 index 0000000..2682fc6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512f-dupv4sf.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */ +/* { dg-final { scan-assembler "vbroadcastss\[^\n\]*%xmm17, *%zmm" } } */ + +typedef float __attribute__ ((vector_size (16))) v4sf; + +v4sf bcst (float f) +{ + register float x asm ("xmm17") = f; + + asm ("" : "+v" (x)); + return (v4sf) {x, x, x, x}; +} diff --git a/gcc/testsuite/gcc.target/i386/avx512f-dupv4si.c b/gcc/testsuite/gcc.target/i386/avx512f-dupv4si.c new file mode 100644 index 0000000..dbf00d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512f-dupv4si.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mavx512f -mno-avx512vl -mprefer-vector-width=512 -O2" } */ +/* { dg-final { scan-assembler "vpbroadcastd\[^\n\]*%xmm17, *%zmm" } } */ + +typedef int __attribute__ ((vector_size (16))) v4si; + +v4si bcst (int i) +{ + register int x asm ("xmm17") = i; + + asm ("" : "+v" (x)); + return (v4si) {x, x, x, x}; +} -- cgit v1.1 From 8a738ac71d6c7ff5fc6bd142de3852ccdca3e0ea Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 12 Jul 2023 12:16:08 +0200 Subject: x86: improve fast bfloat->float conversion There's nothing AVX512BW-ish in here, so no reason to use Yw as the constraints for the AVX alternative. Furthermore by using the 512-bit form of VPSSLD (in a new alternative) all 32 registers can be used directly by the insn without AVX512VL needing to be enabled. Also adjust the originally last alternative's "prefix" attribute to maybe_evex. gcc/ * config/i386/i386.md (extendbfsf2_1): Add new AVX512F alternative. Adjust original last alternative's "prefix" attribute to maybe_evex. --- gcc/config/i386/i386.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 844deea..ef96834 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -5247,21 +5247,27 @@ ;; Don't use float_extend since psrlld doesn't raise ;; exceptions and turn a sNaN into a qNaN. (define_insn "extendbfsf2_1" - [(set (match_operand:SF 0 "register_operand" "=x,Yw") + [(set (match_operand:SF 0 "register_operand" "=x,Yv,v") (unspec:SF - [(match_operand:BF 1 "register_operand" " 0,Yw")] + [(match_operand:BF 1 "register_operand" " 0,Yv,v")] UNSPEC_CVTBFSF))] "TARGET_SSE2" "@ pslld\t{$16, %0|%0, 16} - vpslld\t{$16, %1, %0|%0, %1, 16}" - [(set_attr "isa" "noavx,avx") + vpslld\t{$16, %1, %0|%0, %1, 16} + vpslld\t{$16, %g1, %g0|%g0, %g1, 16}" + [(set_attr "isa" "noavx,avx,*") (set_attr "type" "sseishft1") (set_attr "length_immediate" "1") - (set_attr "prefix_data16" "1,*") - (set_attr "prefix" "orig,vex") - (set_attr "mode" "TI") - (set_attr "memory" "none")]) + (set_attr "prefix_data16" "1,*,*") + (set_attr "prefix" "orig,maybe_evex,evex") + (set_attr "mode" "TI,TI,XI") + (set_attr "memory" "none") + (set (attr "enabled") + (if_then_else (eq_attr "alternative" "2") + (symbol_ref "TARGET_AVX512F && !TARGET_AVX512VL + && !TARGET_PREFER_AVX256") + (const_string "*")))]) (define_expand "extendxf2" [(set (match_operand:XF 0 "nonimmediate_operand") -- cgit v1.1 From c1b3b5a056b8940f845123a8e80ef8e646f40682 Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Wed, 12 Jul 2023 16:39:23 +0800 Subject: RISC-V: Support integer mult highpart auto-vectorization This patch is adding an obvious missing mult_high auto-vectorization pattern. Consider this following case: void __attribute__ ((noipa)) \ mod_##TYPE (TYPE *__restrict dst, TYPE *__restrict src, int count) \ { \ for (int i = 0; i < count; ++i) \ dst[i] = src[i] / 17; \ } T (int32_t) \ TEST_ALL (DEF_LOOP) Before this patch: mod_int32_t: ble a2,zero,.L5 li a5,17 vsetvli a3,zero,e32,m1,ta,ma vmv.v.x v2,a5 .L3: vsetvli a5,a2,e8,mf4,ta,ma vle32.v v1,0(a1) vsetvli a3,zero,e32,m1,ta,ma slli a4,a5,2 vdiv.vv v1,v1,v2 sub a2,a2,a5 vsetvli zero,a5,e32,m1,ta,ma vse32.v v1,0(a0) add a1,a1,a4 add a0,a0,a4 bne a2,zero,.L3 .L5: ret After this patch: mod_int32_t: ble a2,zero,.L5 li a5,2021163008 addiw a5,a5,-1927 vsetvli a3,zero,e32,m1,ta,ma vmv.v.x v3,a5 .L3: vsetvli a5,a2,e8,mf4,ta,ma vle32.v v2,0(a1) vsetvli a3,zero,e32,m1,ta,ma slli a4,a5,2 vmulh.vv v1,v2,v3 sub a2,a2,a5 vsra.vi v2,v2,31 vsra.vi v1,v1,3 vsub.vv v1,v1,v2 vsetvli zero,a5,e32,m1,ta,ma vse32.v v1,0(a0) add a1,a1,a4 add a0,a0,a4 bne a2,zero,.L3 .L5: ret Even though a single "vdiv" is lower into "1 vmulh + 2 vsra + 1 vsub", 4 more instructions are generated, we belive it's much better than before since division is very slow in the hardward. gcc/ChangeLog: * config/riscv/autovec.md (smul3_highpart): New pattern. (umul3_highpart): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/binop/mulh-1.c: New test. * gcc.target/riscv/rvv/autovec/binop/mulh-2.c: New test. * gcc.target/riscv/rvv/autovec/binop/mulh_run-1.c: New test. * gcc.target/riscv/rvv/autovec/binop/mulh_run-2.c: New test. --- gcc/config/riscv/autovec.md | 30 ++++++++++++++++++++++ .../gcc.target/riscv/rvv/autovec/binop/mulh-1.c | 26 +++++++++++++++++++ .../gcc.target/riscv/rvv/autovec/binop/mulh-2.c | 27 +++++++++++++++++++ .../riscv/rvv/autovec/binop/mulh_run-1.c | 29 +++++++++++++++++++++ .../riscv/rvv/autovec/binop/mulh_run-2.c | 29 +++++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-2.c (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 9e61b2e..d98a63c 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1178,3 +1178,33 @@ riscv_vector::RVV_BINOP, operands); DONE; }) + +;; ------------------------------------------------------------------------- +;; ---- [INT] Highpart multiplication +;; ------------------------------------------------------------------------- +;; Includes: +;; - vmulh.vv +;; - vmulhu.vv +;; ------------------------------------------------------------------------- + +(define_expand "smul3_highpart" + [(match_operand:VFULLI 0 "register_operand") + (match_operand:VFULLI 1 "register_operand") + (match_operand:VFULLI 2 "register_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred_mulh (UNSPEC_VMULHS, mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_BINOP, operands); + DONE; +}) + +(define_expand "umul3_highpart" + [(match_operand:VFULLI 0 "register_operand") + (match_operand:VFULLI 1 "register_operand") + (match_operand:VFULLI 2 "register_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred_mulh (UNSPEC_VMULHU, mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_BINOP, operands); + DONE; +}) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-1.c new file mode 100644 index 0000000..265a332 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define DEF_LOOP(TYPE) \ + void __attribute__ ((noipa)) mod_##TYPE (TYPE *dst, TYPE *src, int count) \ + { \ + for (int i = 0; i < count; ++i) \ + dst[i] = src[i] % 19; \ + } + +#define TEST_ALL(T) \ + T (int8_t) \ + T (uint8_t) \ + T (int16_t) \ + T (uint16_t) \ + T (int32_t) \ + T (uint32_t) \ + T (int64_t) \ + T (uint64_t) + +TEST_ALL (DEF_LOOP) + +/* { dg-final { scan-assembler-times {\tvmulh\.vv} 4 } } */ +/* { dg-final { scan-assembler-times {\tvmulhu\.vv} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-2.c new file mode 100644 index 0000000..18faaad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh-2.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define DEF_LOOP(TYPE) \ +void __attribute__ ((noipa)) \ +mod_##TYPE (TYPE *dst, TYPE *src, int count) \ +{ \ + for (int i = 0; i < count; ++i) \ + dst[i] = src[i] / 17; \ +} + +#define TEST_ALL(T) \ + T (int8_t) \ + T (uint8_t) \ + T (int16_t) \ + T (uint16_t) \ + T (int32_t) \ + T (uint32_t) \ + T (int64_t) \ + T (uint64_t) + +TEST_ALL (DEF_LOOP) + +/* { dg-final { scan-assembler-times {\tvmulh\.vv} 4 } } */ +/* { dg-final { scan-assembler-times {\tvmulhu\.vv} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-1.c new file mode 100644 index 0000000..7a47e11 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-1.c @@ -0,0 +1,29 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */ + +#include "mulh-1.c" + +#define N 79 + +#define TEST_LOOP(TYPE) \ + { \ + TYPE dst[N], src[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + src[i] = i * 7 + i % 3; \ + if (i % 11 > 7) \ + src[i] = -src[i]; \ + asm volatile ("" ::: "memory"); \ + } \ + mod_##TYPE (dst, src, N); \ + for (int i = 0; i < N; ++i) \ + if (dst[i] != src[i] % 19) \ + __builtin_abort (); \ + } + +int +main (void) +{ + TEST_ALL (TEST_LOOP); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-2.c new file mode 100644 index 0000000..72c72b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/mulh_run-2.c @@ -0,0 +1,29 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */ + +#include "mulh-2.c" + +#define N 79 + +#define TEST_LOOP(TYPE) \ + { \ + TYPE dst[N], src[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + src[i] = i * 7 + i % 3; \ + if (i % 11 > 7) \ + src[i] = -src[i]; \ + asm volatile ("" ::: "memory"); \ + } \ + mod_##TYPE (dst, src, N); \ + for (int i = 0; i < N; ++i) \ + if (dst[i] != src[i] / 17) \ + __builtin_abort (); \ + } + +int +main (void) +{ + TEST_ALL (TEST_LOOP); + return 0; +} -- cgit v1.1 From 25f831eab368d1bbec4dc67bf058cb7cf6b721ee Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 12 Jul 2023 11:19:58 +0200 Subject: tree-optimization/110630 - enhance SLP permute support The following enhances the existing lowpart extraction support for SLP VEC_PERM nodes to cover all vector aligned extractions. This allows the existing bb-slp-pr95839.c testcase to be vectorized with mips -mpaired-single and the new bb-slp-pr95839-3.c testcase with SSE2. PR tree-optimization/110630 * tree-vect-slp.cc (vect_add_slp_permutation): New offset parameter, honor that for the extract code generation. (vectorizable_slp_permutation_1): Handle offsetted identities. * gcc.dg/vect/bb-slp-pr95839.c: Make stricter. * gcc.dg/vect/bb-slp-pr95839-3.c: New variant testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-3.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c | 1 + gcc/tree-vect-slp.cc | 14 +++++++++----- 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-3.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-3.c new file mode 100644 index 0000000..aaee8fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-additional-options "-w -Wno-psabi" } */ + +typedef float __attribute__((vector_size(32))) v8f32; + +v8f32 f(v8f32 a, v8f32 b) +{ + /* Check that we vectorize this CTOR without any loads. */ + return (v8f32){a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3], + a[4] + b[4], a[5] + b[5], a[6] + b[6], a[7] + b[7]}; +} + +/* { dg-final { scan-tree-dump-not "from scalars" "slp2" } } */ +/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c index 931fd46..d87bbf1 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c @@ -10,4 +10,5 @@ v4f32 f(v4f32 a, v4f32 b) return (v4f32){a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]}; } +/* { dg-final { scan-tree-dump-not "from scalars" "slp2" } } */ /* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */ diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 355d078..693621c 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -8432,7 +8432,7 @@ vect_transform_slp_perm_load (vec_info *vinfo, static void vect_add_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi, slp_tree node, tree first_def, tree second_def, - tree mask_vec) + tree mask_vec, poly_uint64 identity_offset) { tree vectype = SLP_TREE_VECTYPE (node); @@ -8470,14 +8470,17 @@ vect_add_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi, else if (!types_compatible_p (TREE_TYPE (first_def), vectype)) { /* For identity permutes we still need to handle the case - of lowpart extracts or concats. */ + of offsetted extracts or concats. */ unsigned HOST_WIDE_INT c; auto first_def_nunits = TYPE_VECTOR_SUBPARTS (TREE_TYPE (first_def)); if (known_le (TYPE_VECTOR_SUBPARTS (vectype), first_def_nunits)) { + unsigned HOST_WIDE_INT elsz + = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (first_def)))); tree lowpart = build3 (BIT_FIELD_REF, vectype, first_def, - TYPE_SIZE (vectype), bitsize_zero_node); + TYPE_SIZE (vectype), + bitsize_int (identity_offset * elsz)); perm_stmt = gimple_build_assign (perm_dest, lowpart); } else if (constant_multiple_p (TYPE_VECTOR_SUBPARTS (vectype), @@ -8709,7 +8712,8 @@ vectorizable_slp_permutation_1 (vec_info *vinfo, gimple_stmt_iterator *gsi, { indices.new_vector (mask, second_vec.first == -1U ? 1 : 2, TYPE_VECTOR_SUBPARTS (op_vectype)); - bool identity_p = indices.series_p (0, 1, 0, 1); + bool identity_p = (indices.series_p (0, 1, mask[0], 1) + && constant_multiple_p (mask[0], nunits)); machine_mode vmode = TYPE_MODE (vectype); machine_mode op_vmode = TYPE_MODE (op_vectype); unsigned HOST_WIDE_INT c; @@ -8762,7 +8766,7 @@ vectorizable_slp_permutation_1 (vec_info *vinfo, gimple_stmt_iterator *gsi, = vect_get_slp_vect_def (second_node, second_vec.second + vi); vect_add_slp_permutation (vinfo, gsi, node, first_def, - second_def, mask_vec); + second_def, mask_vec, mask[0]); } } -- cgit v1.1 From f9182da3213aa57c16dd0b52862126de4a259f6a Mon Sep 17 00:00:00 2001 From: Andre Vehreschild Date: Wed, 12 Jul 2023 12:51:30 +0200 Subject: gfortran: Allow ref'ing PDT's len() in parameter-initializer. Fix declaring a parameter initialized using a pdt_len reference not simplifying the reference to a constant. 2023-07-12 Andre Vehreschild gcc/fortran/ChangeLog: PR fortran/102003 * expr.cc (find_inquiry_ref): Replace len of pdt_string by constant. (simplify_ref_chain): Ensure input to find_inquiry_ref is NULL. (gfc_match_init_expr): Prevent PDT analysis for function calls. (gfc_pdt_find_component_copy_initializer): Get the initializer value for given component. * gfortran.h (gfc_pdt_find_component_copy_initializer): New function. * simplify.cc (gfc_simplify_len): Replace len() of PDT with pdt component ref or constant. gcc/testsuite/ChangeLog: * gfortran.dg/pdt_33.f03: New test. --- gcc/fortran/expr.cc | 31 ++++++++++++++++++-- gcc/fortran/gfortran.h | 1 + gcc/fortran/simplify.cc | 57 ++++++++++++++++++++++++++++-------- gcc/testsuite/gfortran.dg/pdt_33.f03 | 21 +++++++++++++ 4 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pdt_33.f03 (limited to 'gcc') diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc index e418f1f..663fe63 100644 --- a/gcc/fortran/expr.cc +++ b/gcc/fortran/expr.cc @@ -1862,6 +1862,13 @@ find_inquiry_ref (gfc_expr *p, gfc_expr **newp) else if (tmp->expr_type == EXPR_CONSTANT) *newp = gfc_get_int_expr (gfc_default_integer_kind, NULL, tmp->value.character.length); + else if (gfc_init_expr_flag + && tmp->ts.u.cl->length->symtree->n.sym->attr.pdt_len) + *newp = gfc_pdt_find_component_copy_initializer (tmp->symtree->n + .sym, + tmp->ts.u.cl + ->length->symtree + ->n.sym->name); else goto cleanup; @@ -1902,7 +1909,9 @@ find_inquiry_ref (gfc_expr *p, gfc_expr **newp) mpc_imagref (tmp->value.complex), GFC_RND_MODE); break; } - tmp = gfc_copy_expr (*newp); + // TODO: Fix leaking expr tmp, when simplify is done twice. + if (inquiry->next) + gfc_replace_expr (tmp, *newp); } if (!(*newp)) @@ -2067,7 +2076,7 @@ static bool simplify_ref_chain (gfc_ref *ref, int type, gfc_expr **p) { int n; - gfc_expr *newp; + gfc_expr *newp = NULL; for (; ref; ref = ref->next) { @@ -3229,7 +3238,7 @@ gfc_match_init_expr (gfc_expr **result) return m; } - if (gfc_derived_parameter_expr (expr)) + if (expr->expr_type != EXPR_FUNCTION && gfc_derived_parameter_expr (expr)) { *result = expr; gfc_init_expr_flag = false; @@ -6556,3 +6565,19 @@ gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj, return true; } + +gfc_expr* +gfc_pdt_find_component_copy_initializer (gfc_symbol *sym, const char *name) +{ + /* The actual length of a pdt is in its components. In the + initializer of the current ref is only the default value. + Therefore traverse the chain of components and pick the correct + one's initializer expressions. */ + for (gfc_component *comp = sym->ts.u.derived->components; comp != NULL; + comp = comp->next) + { + if (!strcmp (comp->name, name)) + return gfc_copy_expr (comp->initializer); + } + return NULL; +} diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 30631ab..74466c7 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3727,6 +3727,7 @@ gfc_expr* gfc_find_stat_co (gfc_expr *); gfc_expr* gfc_build_intrinsic_call (gfc_namespace *, gfc_isym_id, const char*, locus, unsigned, ...); bool gfc_check_vardef_context (gfc_expr*, bool, bool, bool, const char*); +gfc_expr* gfc_pdt_find_component_copy_initializer (gfc_symbol *, const char *); /* st.cc */ diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc index 8168011..87fefe4 100644 --- a/gcc/fortran/simplify.cc +++ b/gcc/fortran/simplify.cc @@ -4580,19 +4580,50 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind) return range_check (result, "LEN"); } else if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER - && e->symtree->n.sym - && e->symtree->n.sym->ts.type != BT_DERIVED - && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target - && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED - && e->symtree->n.sym->assoc->target->symtree->n.sym - && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym)) - - /* The expression in assoc->target points to a ref to the _data component - of the unlimited polymorphic entity. To get the _len component the last - _data ref needs to be stripped and a ref to the _len component added. */ - return gfc_get_len_component (e->symtree->n.sym->assoc->target, k); - else - return NULL; + && e->symtree->n.sym) + { + if (e->symtree->n.sym->ts.type != BT_DERIVED + && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target + && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED + && e->symtree->n.sym->assoc->target->symtree->n.sym + && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym)) + /* The expression in assoc->target points to a ref to the _data + component of the unlimited polymorphic entity. To get the _len + component the last _data ref needs to be stripped and a ref to the + _len component added. */ + return gfc_get_len_component (e->symtree->n.sym->assoc->target, k); + else if (e->symtree->n.sym->ts.type == BT_DERIVED + && e->ref && e->ref->type == REF_COMPONENT + && e->ref->u.c.component->attr.pdt_string + && e->ref->u.c.component->ts.type == BT_CHARACTER + && e->ref->u.c.component->ts.u.cl->length) + { + if (gfc_init_expr_flag) + { + gfc_expr* tmp; + tmp = gfc_pdt_find_component_copy_initializer (e->symtree->n.sym, + e->ref->u.c + .component->ts.u.cl + ->length->symtree + ->name); + if (tmp) + return tmp; + } + else + { + gfc_expr *len_expr = gfc_copy_expr (e); + gfc_free_ref_list (len_expr->ref); + len_expr->ref = NULL; + gfc_find_component (len_expr->symtree->n.sym->ts.u.derived, e->ref + ->u.c.component->ts.u.cl->length->symtree + ->name, + false, true, &len_expr->ref); + len_expr->ts = len_expr->ref->u.c.component->ts; + return len_expr; + } + } + } + return NULL; } diff --git a/gcc/testsuite/gfortran.dg/pdt_33.f03 b/gcc/testsuite/gfortran.dg/pdt_33.f03 new file mode 100644 index 0000000..3b2fe72 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pdt_33.f03 @@ -0,0 +1,21 @@ +! { dg-do run } +! +! Test the fix for PR102003, where len parameters where not returned as constants. +! +! Contributed by Harald Anlauf +! +program pr102003 + type pdt(n) + integer, len :: n = 8 + character(len=n) :: c + end type pdt + type(pdt(42)) :: p + integer, parameter :: m = len (p% c) + integer, parameter :: lm = p% c% len + + if (m /= 42) stop 1 + if (len (p% c) /= 42) stop 2 + if (lm /= 42) stop 3 + if (p% c% len /= 42) stop 4 +end + -- cgit v1.1 From a454325bea77a0dd79415480d48233a7c296bc0a Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Mon, 10 Jul 2023 22:00:08 +0200 Subject: genopinit: Allow more than 256 modes. Upcoming changes for RISC-V will have us exceed 255 modes or 8 bits. This patch increases the limit to 10 bits and adjusts the hashing function for the gen* and optabs-query lookups accordingly. Consequently, the number of optabs is limited to 4095. gcc/ChangeLog: * genopinit.cc (main): Adjust maximal number of optabs and machine modes. * gensupport.cc (find_optab): Shift optab by 20 and mode by 10 bits. * optabs-query.h (optab_handler): Ditto. (convert_optab_handler): Ditto. --- gcc/genopinit.cc | 5 ++--- gcc/gensupport.cc | 2 +- gcc/optabs-query.h | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/genopinit.cc b/gcc/genopinit.cc index 6bd8858..2a84100 100644 --- a/gcc/genopinit.cc +++ b/gcc/genopinit.cc @@ -182,8 +182,7 @@ main (int argc, const char **argv) progname = "genopinit"; - if (NUM_OPTABS > 0xffff - || MAX_MACHINE_MODE >= ((1 << MACHINE_MODE_BITSIZE) - 1)) + if (NUM_OPTABS > 0xfff || NUM_MACHINE_MODES > 0x3ff) fatal ("genopinit range assumptions invalid"); if (!init_rtx_reader_args_cb (argc, argv, handle_arg)) @@ -439,7 +438,7 @@ main (int argc, const char **argv) "bool\n" "swap_optab_enable (optab op, machine_mode m, bool set)\n" "{\n" - " unsigned scode = (op << 16) | m;\n" + " unsigned scode = (op << 20) | m;\n" " int i = lookup_handler (scode);\n" " if (i >= 0)\n" " {\n" diff --git a/gcc/gensupport.cc b/gcc/gensupport.cc index e39e6da..959d1d9 100644 --- a/gcc/gensupport.cc +++ b/gcc/gensupport.cc @@ -3806,7 +3806,7 @@ find_optab (optab_pattern *p, const char *name) { p->name = name; p->op = optabs[pindex].op; - p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1; + p->sort_num = (p->op << 20) | (p->m2 << 10) | p->m1; return true; } } diff --git a/gcc/optabs-query.h b/gcc/optabs-query.h index 043e979..920eb6a 100644 --- a/gcc/optabs-query.h +++ b/gcc/optabs-query.h @@ -37,7 +37,7 @@ convert_optab_p (optab op) inline enum insn_code optab_handler (optab op, machine_mode mode) { - unsigned scode = (op << 16) | mode; + unsigned scode = (op << 20) | mode; gcc_assert (op > LAST_CONV_OPTAB); return raw_optab_handler (scode); } @@ -50,7 +50,7 @@ inline enum insn_code convert_optab_handler (convert_optab op, machine_mode to_mode, machine_mode from_mode) { - unsigned scode = (op << 16) | (from_mode << 8) | to_mode; + unsigned scode = (op << 20) | (from_mode << 10) | to_mode; gcc_assert (convert_optab_p (op)); return raw_optab_handler (scode); } -- cgit v1.1 From 46ade8c9cc860170ab4253cffd24169efa46ca70 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 12 Jul 2023 14:09:54 +0100 Subject: i386: Tweak ix86_expand_int_compare to use PTEST for vector equality. I've come up with an alternate/complementary/supplementary fix to the patch https://gcc.gnu.org/pipermail/gcc-patches/2023-June/622706.html for generating the PTEST during RTL expansion, rather than rely on this being caught/optimized later during STV. You'll notice in this patch, the tests for TARGET_SSE4_1 and TImode appear last. When I was writing this, I initially also added support for AVX VPTEST and OImode, before realizing that x86 doesn't (yet) support 256-bit OImode (which also explains why we don't have an OImode to V1OImode scalar-to-vector pass). Retaining this clause ordering should minimize the lines changed if things change in future. 2023-07-12 Roger Sayle gcc/ChangeLog * config/i386/i386-expand.cc (ix86_expand_int_compare): If testing a TImode SUBREG of a 128-bit vector register against zero, use a PTEST instruction instead of first moving it to a pair of scalar registers. --- gcc/config/i386/i386-expand.cc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index fd5d103..648d609 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -2987,9 +2987,26 @@ ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1) cmpmode = SELECT_CC_MODE (code, op0, op1); flags = gen_rtx_REG (cmpmode, FLAGS_REG); + /* Attempt to use PTEST, if available, when testing vector modes for + equality/inequality against zero. */ + if (op1 == const0_rtx + && SUBREG_P (op0) + && cmpmode == CCZmode + && SUBREG_BYTE (op0) == 0 + && REG_P (SUBREG_REG (op0)) + && VECTOR_MODE_P (GET_MODE (SUBREG_REG (op0))) + && TARGET_SSE4_1 + && GET_MODE (op0) == TImode + && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))) == 16) + { + tmp = SUBREG_REG (op0); + tmp = gen_rtx_UNSPEC (CCZmode, gen_rtvec (2, tmp, tmp), UNSPEC_PTEST); + } + else + tmp = gen_rtx_COMPARE (cmpmode, op0, op1); + /* This is very simple, but making the interface the same as in the FP case makes the rest of the code easier. */ - tmp = gen_rtx_COMPARE (cmpmode, op0, op1); emit_insn (gen_rtx_SET (flags, tmp)); /* Return the test that should be put into the flags user, i.e. -- cgit v1.1 From d2c18b4a16f9e1a6ed271ec1efaf94533d1c4a94 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 12 Jul 2023 14:12:34 +0100 Subject: PR target/110598: Fix rega = 0; rega ^= rega regression in i386.md This patch fixes the regression PR target/110598 caused by my recent addition of a peephole2. The intention of that optimization was to simplify zeroing a register, followed by an IOR, XOR or PLUS operation on it into a move, or as described in the comment: ;; Peephole2 rega = 0; rega op= regb into rega = regb. The issue is that I'd failed to consider the (rare and unusual) case, where regb is rega, where the transformation leads to the incorrect "rega = rega", when it should be "rega = 0". The minimal fix is to add a !reg_mentioned_p check to the recent peephole2. In addition to resolving the regression, I've added a second peephole2 to optimize the problematic case above, which contains a false dependency and is therefore tricky to optimize elsewhere. This is an improvement over GCC 13, for example, that generates the redundant: xorl %edx, %edx xorq %rdx, %rdx 2023-07-12 Roger Sayle gcc/ChangeLog PR target/110598 * config/i386/i386.md (peephole2): Check !reg_mentioned_p when optimizing rega = 0; rega op= regb for op in [XOR,IOR,PLUS]. (peephole2): Simplify rega = 0; rega op= rega cases. gcc/testsuite/ChangeLog PR target/110598 * gcc.target/i386/pr110598.c: New test case. --- gcc/config/i386/i386.md | 16 +++++++++-- gcc/testsuite/gcc.target/i386/pr110598.c | 46 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110598.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ef96834..d4a948d 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12325,9 +12325,21 @@ (any_or_plus:SWI (match_dup 0) (match_operand:SWI 1 ""))) (clobber (reg:CC FLAGS_REG))])] - "" + "!reg_mentioned_p (operands[0], operands[1])" [(set (match_dup 0) (match_dup 1))]) - + +;; Peephole2 dead instruction in rega = 0; rega op= rega. +(define_peephole2 + [(parallel [(set (match_operand:SWI 0 "general_reg_operand") + (const_int 0)) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 0) + (any_or_plus:SWI (match_dup 0) (match_dup 0))) + (clobber (reg:CC FLAGS_REG))])] + "" + [(parallel [(set (match_dup 0) (const_int 0)) + (clobber (reg:CC FLAGS_REG))])]) + ;; Split DST = (HI<<32)|LO early to minimize register usage. (define_insn_and_split "*concat3_1" [(set (match_operand: 0 "nonimmediate_operand" "=ro,r") diff --git a/gcc/testsuite/gcc.target/i386/pr110598.c b/gcc/testsuite/gcc.target/i386/pr110598.c new file mode 100644 index 0000000..1c88031 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110598.c @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +typedef unsigned long long u64; + +#define MAX_SUBTARGET_WORDS 4 + +int notequal(const void *a, const void *b) +{ + return __builtin_memcmp(a,b,MAX_SUBTARGET_WORDS*sizeof(u64)) != 0; +} +typedef struct FeatureBitset { + u64 Bits[MAX_SUBTARGET_WORDS]; +}FeatureBitset; + +__attribute__((noipa)) +_Bool is_eq_buggy (const FeatureBitset * lf, const FeatureBitset * rf) { + u64 Bits_l[MAX_SUBTARGET_WORDS]; + Bits_l[0] = lf->Bits[0]&1; + Bits_l[1] = 0; + Bits_l[2] = 0; + Bits_l[3] = 0; + u64 Bits_r[MAX_SUBTARGET_WORDS]; + Bits_r[0] = rf->Bits[0]&1; + Bits_r[1] = 0; + Bits_r[2] = 0; + Bits_r[3] = 0; + return !notequal(Bits_l, Bits_r); +} + +__attribute__((noipa)) +void bug(void) { + FeatureBitset lf, rf; + lf.Bits[0] = rf.Bits[0] = 1; + lf.Bits[1] = rf.Bits[1] = 1; + lf.Bits[2] = rf.Bits[2] = 1; + lf.Bits[3] = rf.Bits[3] = 1; + + _Bool r = is_eq_buggy (&lf, &rf); + if (!r) __builtin_trap(); +} + +__attribute__((noipa)) +int main(void) { + bug(); +} -- cgit v1.1 From 275a2124e4928c88bd5469096356ba393b6aadfb Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 12 Jul 2023 14:14:15 +0100 Subject: i386: Fix FAIL of gcc.target/i386/pr91681-1.c The recent change in TImode parameter passing on x86_64 results in the FAIL of pr91681-1.c. The issue is that with the extra flexibility, the combine pass is now spoilt for choice between using either the *add3_doubleword_concat or the *add3_doubleword_zext patterns, when one operand is a *concat and the other is a zero_extend. The solution proposed below is provide an *add3_doubleword_concat_zext define_insn_and_split, that can benefit both from the register allocation of *concat, and still avoid the xor normally required by zero extension. I'm investigating a follow-up refinement to improve register allocation further by avoiding the early clobber in the =&r, and handling (custom) reloads explicitly, but this piece resolves the testcase failure. 2023-07-12 Roger Sayle gcc/ChangeLog PR target/91681 * config/i386/i386.md (*add3_doubleword_concat_zext): New define_insn_and_split derived from *add3_doubleword_concat and *add3_doubleword_zext. --- gcc/config/i386/i386.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d4a948d..de274c8 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6294,6 +6294,39 @@ (clobber (reg:CC FLAGS_REG))])] "split_double_mode (mode, &operands[0], 2, &operands[0], &operands[5]);") +(define_insn_and_split "*add3_doubleword_concat_zext" + [(set (match_operand: 0 "register_operand" "=&r") + (plus: + (any_or_plus: + (ashift: + (zero_extend: + (match_operand:DWIH 2 "nonimmediate_operand" "rm")) + (match_operand:QI 3 "const_int_operand")) + (zero_extend: + (match_operand:DWIH 4 "nonimmediate_operand" "rm"))) + (zero_extend: + (match_operand:DWIH 1 "nonimmediate_operand" "rm"))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[3]) == * BITS_PER_UNIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 4)) + (set (match_dup 5) (match_dup 2)) + (parallel [(set (reg:CCC FLAGS_REG) + (compare:CCC + (plus:DWIH (match_dup 0) (match_dup 1)) + (match_dup 0))) + (set (match_dup 0) + (plus:DWIH (match_dup 0) (match_dup 1)))]) + (parallel [(set (match_dup 5) + (plus:DWIH + (plus:DWIH + (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) + (match_dup 5)) + (const_int 0))) + (clobber (reg:CC FLAGS_REG))])] + "split_double_mode (mode, &operands[0], 1, &operands[0], &operands[5]);") + (define_insn "*add_1" [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r") (plus:SWI48 -- cgit v1.1 From 30dbfcd86c364da8491634ed4f99def184e2d042 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 12 Jul 2023 14:43:37 +0100 Subject: i386: Fix FAIL of gcc.target/i386/pr91681-1.c I committed the wrong version of this patch (with a typo). Updating to the correct bootstrapped and regression tested version as obvious. 2023-07-12 Roger Sayle gcc/ChangeLog PR target/91681 * config/i386/i386.md (*add3_doubleword_concat_zext): Typo. --- gcc/config/i386/i386.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index de274c8..89a7fb0 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6305,7 +6305,7 @@ (zero_extend: (match_operand:DWIH 4 "nonimmediate_operand" "rm"))) (zero_extend: - (match_operand:DWIH 1 "nonimmediate_operand" "rm"))) + (match_operand:DWIH 1 "nonimmediate_operand" "rm")))) (clobber (reg:CC FLAGS_REG))] "INTVAL (operands[3]) == * BITS_PER_UNIT" "#" -- cgit v1.1 From 0d4dd7e07a879d6c07a33edb2799710faa95651e Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Wed, 12 Jul 2023 21:17:39 +0800 Subject: VECT: Apply COND_LEN_* into vectorizable_operation Hi, Richard and Richi. As we disscussed before, COND_LEN_* patterns were added for multiple situations. This patch apply CON_LEN_* for the following situation: Support for the situation that in "vectorizable_operation": /* If operating on inactive elements could generate spurious traps, we need to restrict the operation to active lanes. Note that this specifically doesn't apply to unhoisted invariants, since they operate on the same value for every lane. Similarly, if this operation is part of a reduction, a fully-masked loop should only change the active lanes of the reduction chain, keeping the inactive lanes as-is. */ bool mask_out_inactive = ((!is_invariant && gimple_could_trap_p (stmt)) || reduc_idx >= 0); For mask_out_inactive is true with length loop control. So, we can these 2 following cases: 1. Integer division: #define TEST_TYPE(TYPE) \ __attribute__((noipa)) \ void vrem_##TYPE (TYPE *dst, TYPE *a, TYPE *b, int n) \ { \ for (int i = 0; i < n; i++) \ dst[i] = a[i] % b[i]; \ } #define TEST_ALL() \ TEST_TYPE(int8_t) \ TEST_ALL() With this patch: _61 = .SELECT_VL (ivtmp_59, POLY_INT_CST [4, 4]); ivtmp_45 = _61 * 4; vect__4.8_48 = .LEN_MASK_LOAD (vectp_a.6_46, 32B, _61, 0, { -1, ... }); vect__6.11_52 = .LEN_MASK_LOAD (vectp_b.9_50, 32B, _61, 0, { -1, ... }); vect__8.12_53 = .COND_LEN_ADD ({ -1, ... }, vect__4.8_48, vect__6.11_52, vect__4.8_48, _61, 0); .LEN_MASK_STORE (vectp_dst.13_55, 32B, _61, 0, { -1, ... }, vect__8.12_53); 2. Floating-point arithmetic **WITHOUT** -ffast-math #define TEST_TYPE(TYPE) \ __attribute__((noipa)) \ void vadd_##TYPE (TYPE *dst, TYPE *a, TYPE *b, int n) \ { \ for (int i = 0; i < n; i++) \ dst[i] = a[i] + b[i]; \ } #define TEST_ALL() \ TEST_TYPE(float) \ TEST_ALL() With this patch: _61 = .SELECT_VL (ivtmp_59, POLY_INT_CST [4, 4]); ivtmp_45 = _61 * 4; vect__4.8_48 = .LEN_MASK_LOAD (vectp_a.6_46, 32B, _61, 0, { -1, ... }); vect__6.11_52 = .LEN_MASK_LOAD (vectp_b.9_50, 32B, _61, 0, { -1, ... }); vect__8.12_53 = .COND_LEN_ADD ({ -1, ... }, vect__4.8_48, vect__6.11_52, vect__4.8_48, _61, 0); .LEN_MASK_STORE (vectp_dst.13_55, 32B, _61, 0, { -1, ... }, vect__8.12_53); With this patch, we can make sure operations won't trap for elements that "mask_out_inactive". gcc/ChangeLog: * internal-fn.cc (FOR_EACH_CODE_MAPPING): Adapt for COND_LEN_* support. (CASE): Ditto. (get_conditional_len_internal_fn): New function. * internal-fn.h (get_conditional_len_internal_fn): Ditto. * tree-vect-stmts.cc (vectorizable_operation): Adapt for COND_LEN_* support. --- gcc/internal-fn.cc | 71 +++++++++++++++++++++++++++++++++++++------------- gcc/internal-fn.h | 1 + gcc/tree-vect-stmts.cc | 48 ++++++++++++++++++++++++++-------- 3 files changed, 91 insertions(+), 29 deletions(-) (limited to 'gcc') diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index f9aaf66..c11123a 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -4276,23 +4276,24 @@ static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = { 0 }; -/* Invoke T(CODE, IFN) for each conditional function IFN that maps to a - tree code CODE. */ +/* Invoke T(CODE, SUFFIX) for each conditional function IFN_COND_##SUFFIX + that maps to a tree code CODE. There is also an IFN_COND_LEN_##SUFFIX + for each such IFN_COND_##SUFFIX. */ #define FOR_EACH_CODE_MAPPING(T) \ - T (PLUS_EXPR, IFN_COND_ADD) \ - T (MINUS_EXPR, IFN_COND_SUB) \ - T (MULT_EXPR, IFN_COND_MUL) \ - T (TRUNC_DIV_EXPR, IFN_COND_DIV) \ - T (TRUNC_MOD_EXPR, IFN_COND_MOD) \ - T (RDIV_EXPR, IFN_COND_RDIV) \ - T (MIN_EXPR, IFN_COND_MIN) \ - T (MAX_EXPR, IFN_COND_MAX) \ - T (BIT_AND_EXPR, IFN_COND_AND) \ - T (BIT_IOR_EXPR, IFN_COND_IOR) \ - T (BIT_XOR_EXPR, IFN_COND_XOR) \ - T (LSHIFT_EXPR, IFN_COND_SHL) \ - T (RSHIFT_EXPR, IFN_COND_SHR) \ - T (NEGATE_EXPR, IFN_COND_NEG) + T (PLUS_EXPR, ADD) \ + T (MINUS_EXPR, SUB) \ + T (MULT_EXPR, MUL) \ + T (TRUNC_DIV_EXPR, DIV) \ + T (TRUNC_MOD_EXPR, MOD) \ + T (RDIV_EXPR, RDIV) \ + T (MIN_EXPR, MIN) \ + T (MAX_EXPR, MAX) \ + T (BIT_AND_EXPR, AND) \ + T (BIT_IOR_EXPR, IOR) \ + T (BIT_XOR_EXPR, XOR) \ + T (LSHIFT_EXPR, SHL) \ + T (RSHIFT_EXPR, SHR) \ + T (NEGATE_EXPR, NEG) /* Return a function that only performs CODE when a certain condition is met and that uses a given fallback value otherwise. For example, if CODE is @@ -4313,7 +4314,7 @@ get_conditional_internal_fn (tree_code code) { switch (code) { -#define CASE(CODE, IFN) case CODE: return IFN; +#define CASE(CODE, IFN) case CODE: return IFN_COND_##IFN; FOR_EACH_CODE_MAPPING(CASE) #undef CASE default: @@ -4329,7 +4330,7 @@ conditional_internal_fn_code (internal_fn ifn) { switch (ifn) { -#define CASE(CODE, IFN) case IFN: return CODE; +#define CASE(CODE, IFN) case IFN_COND_##IFN: return CODE; FOR_EACH_CODE_MAPPING(CASE) #undef CASE default: @@ -4337,6 +4338,40 @@ conditional_internal_fn_code (internal_fn ifn) } } +/* Like get_conditional_internal_fn, but return a function that + additionally restricts the operation to the leading elements + of a vector. The number of elements to process is given by a length + and bias pair, as for IFN_LOAD_LEN. The values of the remaining + elements are taken from the fallback ("else") argument. + + For example, if CODE is a binary operation associated with FN: + + LHS = FN (COND, A, B, ELSE, LEN, BIAS) + + is equivalent to the C code: + + for (int i = 0; i < NUNITS; i++) + { + if (i < LEN + BIAS && COND[i]) + LHS[i] = A[i] CODE B[i]; + else + LHS[i] = ELSE[i]; + } +*/ + +internal_fn +get_conditional_len_internal_fn (tree_code code) +{ + switch (code) + { +#define CASE(CODE, IFN) case CODE: return IFN_COND_LEN_##IFN; + FOR_EACH_CODE_MAPPING(CASE) +#undef CASE + default: + return IFN_LAST; + } +} + /* Invoke T(IFN) for each internal function IFN that also has an IFN_COND_* form. */ #define FOR_EACH_COND_FN_PAIR(T) \ diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h index 4234bbf..dd1bab0 100644 --- a/gcc/internal-fn.h +++ b/gcc/internal-fn.h @@ -224,6 +224,7 @@ extern bool set_edom_supported_p (void); extern internal_fn get_conditional_internal_fn (tree_code); extern internal_fn get_conditional_internal_fn (internal_fn); +extern internal_fn get_conditional_len_internal_fn (tree_code); extern tree_code conditional_internal_fn_code (internal_fn); extern internal_fn get_unconditional_internal_fn (internal_fn); extern bool can_interpret_as_conditional_op_p (gimple *, tree *, diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 10e7117..dd24f01 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -6711,7 +6711,9 @@ vectorizable_operation (vec_info *vinfo, int reduc_idx = STMT_VINFO_REDUC_IDX (stmt_info); vec_loop_masks *masks = (loop_vinfo ? &LOOP_VINFO_MASKS (loop_vinfo) : NULL); + vec_loop_lens *lens = (loop_vinfo ? &LOOP_VINFO_LENS (loop_vinfo) : NULL); internal_fn cond_fn = get_conditional_internal_fn (code); + internal_fn cond_len_fn = get_conditional_len_internal_fn (code); /* If operating on inactive elements could generate spurious traps, we need to restrict the operation to active lanes. Note that this @@ -6730,9 +6732,17 @@ vectorizable_operation (vec_info *vinfo, && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) && mask_out_inactive) { - if (cond_fn == IFN_LAST - || !direct_internal_fn_supported_p (cond_fn, vectype, - OPTIMIZE_FOR_SPEED)) + if (cond_fn != IFN_LAST + && direct_internal_fn_supported_p (cond_fn, vectype, + OPTIMIZE_FOR_SPEED)) + vect_record_loop_mask (loop_vinfo, masks, ncopies * vec_num, + vectype, NULL); + else if (cond_len_fn != IFN_LAST + && direct_internal_fn_supported_p (cond_len_fn, vectype, + OPTIMIZE_FOR_SPEED)) + vect_record_loop_len (loop_vinfo, lens, ncopies * vec_num, vectype, + 1); + else { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -6740,9 +6750,6 @@ vectorizable_operation (vec_info *vinfo, " conditional operation is available.\n"); LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; } - else - vect_record_loop_mask (loop_vinfo, masks, ncopies * vec_num, - vectype, NULL); } /* Put types on constant and invariant SLP children. */ @@ -6805,6 +6812,7 @@ vectorizable_operation (vec_info *vinfo, "transform binary/unary operation.\n"); bool masked_loop_p = loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo); + bool len_loop_p = loop_vinfo && LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo); /* POINTER_DIFF_EXPR has pointer arguments which are vectorized as vectors with unsigned elements, but the result is signed. So, we @@ -6971,11 +6979,16 @@ vectorizable_operation (vec_info *vinfo, gimple_assign_set_lhs (new_stmt, new_temp); vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); } - else if (masked_loop_p && mask_out_inactive) + else if ((masked_loop_p || len_loop_p) && mask_out_inactive) { - tree mask = vect_get_loop_mask (loop_vinfo, gsi, masks, - vec_num * ncopies, vectype, i); - auto_vec vops (5); + tree mask; + if (masked_loop_p) + mask = vect_get_loop_mask (loop_vinfo, gsi, masks, + vec_num * ncopies, vectype, i); + else + /* Dummy mask. */ + mask = build_minus_one_cst (truth_type_for (vectype)); + auto_vec vops (6); vops.quick_push (mask); vops.quick_push (vop0); if (vop1) @@ -6995,7 +7008,20 @@ vectorizable_operation (vec_info *vinfo, (cond_fn, vectype, vops.length () - 1, &vops[1]); vops.quick_push (else_value); } - gcall *call = gimple_build_call_internal_vec (cond_fn, vops); + if (len_loop_p) + { + tree len = vect_get_loop_len (loop_vinfo, gsi, lens, + vec_num * ncopies, vectype, i, 1); + signed char biasval + = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); + tree bias = build_int_cst (intQI_type_node, biasval); + vops.quick_push (len); + vops.quick_push (bias); + } + gcall *call + = gimple_build_call_internal_vec (masked_loop_p ? cond_fn + : cond_len_fn, + vops); new_temp = make_ssa_name (vec_dest, call); gimple_call_set_lhs (call, new_temp); gimple_call_set_nothrow (call, true); -- cgit v1.1 From 2eb8ee2b6a6922b1dd220de31ae1b48b83e51678 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 12 Jul 2023 16:29:53 +0200 Subject: ifcvt: Change return type of predicate functions from int to bool Also change some internal variables and function arguments from int to bool. gcc/ChangeLog: * ifcvt.cc (cond_exec_changed_p): Change variable to bool. (last_active_insn): Change "skip_use_p" function argument to bool. (noce_operand_ok): Change return type from int to bool. (find_cond_trap): Ditto. (block_jumps_and_fallthru_p): Change "fallthru_p" and "jump_p" variables to bool. (noce_find_if_block): Change return type from int to bool. (cond_exec_find_if_block): Ditto. (find_if_case_1): Ditto. (find_if_case_2): Ditto. (dead_or_predicable): Ditto. Change "reversep" function arg to bool. (block_jumps_and_fallthru): Rename from block_jumps_and_fallthru_p. (cond_exec_process_insns): Change return type from int to bool. Change "mod_ok" function arg to bool. (cond_exec_process_if_block): Change return type from int to bool. Change "do_multiple_p" function arg to bool. Change "then_mod_ok" variable to bool. (noce_emit_store_flag): Change return type from int to bool. Change "reversep" function arg to bool. Change "cond_complex" variable to bool. (noce_try_move): Change return type from int to bool. (noce_try_ifelse_collapse): Ditto. (noce_try_store_flag): Ditto. Change "reversep" variable to bool. (noce_try_addcc): Change return type from int to bool. Change "subtract" variable to bool. (noce_try_store_flag_constants): Change return type from int to bool. (noce_try_store_flag_mask): Ditto. Change "reversep" variable to bool. (noce_try_cmove): Change return type from int to bool. (noce_try_cmove_arith): Ditto. Change "is_mem" variable to bool. (noce_try_minmax): Change return type from int to bool. Change "unsignedp" variable to bool. (noce_try_abs): Change return type from int to bool. Change "negate" variable to bool. (noce_try_sign_mask): Change return type from int to bool. (noce_try_move): Ditto. (noce_try_store_flag_constants): Ditto. (noce_try_cmove): Ditto. (noce_try_cmove_arith): Ditto. (noce_try_minmax): Ditto. Change "unsignedp" variable to bool. (noce_try_bitop): Change return type from int to bool. (noce_operand_ok): Ditto. (noce_convert_multiple_sets): Ditto. (noce_convert_multiple_sets_1): Ditto. (noce_process_if_block): Ditto. (check_cond_move_block): Ditto. (cond_move_process_if_block): Ditto. Change "success_p" variable to bool. (rest_of_handle_if_conversion): Change return type to void. --- gcc/ifcvt.cc | 640 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 321 insertions(+), 319 deletions(-) (limited to 'gcc') diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 0b180b4..a0af553 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -73,29 +73,29 @@ static int num_updated_if_blocks; static int num_true_changes; /* Whether conditional execution changes were made. */ -static int cond_exec_changed_p; +static bool cond_exec_changed_p; /* Forward references. */ static int count_bb_insns (const_basic_block); static bool cheap_bb_rtx_cost_p (const_basic_block, profile_probability, int); static rtx_insn *first_active_insn (basic_block); -static rtx_insn *last_active_insn (basic_block, int); +static rtx_insn *last_active_insn (basic_block, bool); static rtx_insn *find_active_insn_before (basic_block, rtx_insn *); static rtx_insn *find_active_insn_after (basic_block, rtx_insn *); static basic_block block_fallthru (basic_block); static rtx cond_exec_get_condition (rtx_insn *, bool); static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool); -static int noce_operand_ok (const_rtx); +static bool noce_operand_ok (const_rtx); static void merge_if_block (ce_if_block *); -static int find_cond_trap (basic_block, edge, edge); +static bool find_cond_trap (basic_block, edge, edge); static basic_block find_if_header (basic_block, int); -static int block_jumps_and_fallthru_p (basic_block, basic_block); -static int noce_find_if_block (basic_block, edge, edge, int); -static int cond_exec_find_if_block (ce_if_block *); -static int find_if_case_1 (basic_block, edge, edge); -static int find_if_case_2 (basic_block, edge, edge); -static int dead_or_predicable (basic_block, basic_block, basic_block, - edge, int); +static int block_jumps_and_fallthru (basic_block, basic_block); +static bool noce_find_if_block (basic_block, edge, edge, int); +static bool cond_exec_find_if_block (ce_if_block *); +static bool find_if_case_1 (basic_block, edge, edge); +static bool find_if_case_2 (basic_block, edge, edge); +static bool dead_or_predicable (basic_block, basic_block, basic_block, + edge, bool); static void noce_emit_move_insn (rtx, rtx); static rtx_insn *block_has_only_trap (basic_block); static void need_cmov_or_rewire (basic_block, hash_set *, @@ -234,7 +234,7 @@ first_active_insn (basic_block bb) /* Return the last non-jump active (non-jump) insn in the basic block. */ static rtx_insn * -last_active_insn (basic_block bb, int skip_use_p) +last_active_insn (basic_block bb, bool skip_use_p) { rtx_insn *insn = BB_END (bb); rtx_insn *head = BB_HEAD (bb); @@ -335,28 +335,28 @@ rtx_interchangeable_p (const_rtx a, const_rtx b) execution format if possible. Return TRUE if all of the non-note insns were processed. */ -static int +static bool cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, /* if block information */rtx_insn *start, /* first insn to look at */rtx end, /* last insn to look at */rtx test, /* conditional execution test */profile_probability prob_val, - /* probability of branch taken. */int mod_ok) + /* probability of branch taken. */bool mod_ok) { - int must_be_last = FALSE; + bool must_be_last = false; rtx_insn *insn; rtx xtest; rtx pattern; if (!start || !end) - return FALSE; + return false; for (insn = start; ; insn = NEXT_INSN (insn)) { /* dwarf2out can't cope with conditional prologues. */ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END) - return FALSE; + return false; if (NOTE_P (insn) || DEBUG_INSN_P (insn)) goto insn_done; @@ -365,7 +365,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, /* dwarf2out can't cope with conditional unwind info. */ if (RTX_FRAME_RELATED_P (insn)) - return FALSE; + return false; /* Remove USE insns that get in the way. */ if (reload_completed && GET_CODE (PATTERN (insn)) == USE) @@ -378,13 +378,13 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, /* Last insn wasn't last? */ if (must_be_last) - return FALSE; + return false; if (modified_in_p (test, insn)) { if (!mod_ok) - return FALSE; - must_be_last = TRUE; + return false; + must_be_last = true; } /* Now build the conditional form of the instruction. */ @@ -396,7 +396,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, if (GET_CODE (pattern) == COND_EXEC) { if (GET_MODE (xtest) != GET_MODE (COND_EXEC_TEST (pattern))) - return FALSE; + return false; xtest = gen_rtx_AND (GET_MODE (xtest), xtest, COND_EXEC_TEST (pattern)); @@ -411,7 +411,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, #ifdef IFCVT_MODIFY_INSN IFCVT_MODIFY_INSN (ce_info, pattern, insn); if (! pattern) - return FALSE; + return false; #endif validate_change (insn, &PATTERN (insn), pattern, 1); @@ -427,7 +427,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, break; } - return TRUE; + return true; } /* Return the condition for a jump. Do not do any special processing. */ @@ -465,9 +465,9 @@ cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false) to conditional execution. Return TRUE if we were successful at converting the block. */ -static int +static bool cond_exec_process_if_block (ce_if_block * ce_info, - /* if block information */int do_multiple_p) + /* if block information */bool do_multiple_p) { basic_block test_bb = ce_info->test_bb; /* last test block */ basic_block then_bb = ce_info->then_bb; /* THEN */ @@ -478,7 +478,7 @@ cond_exec_process_if_block (ce_if_block * ce_info, rtx_insn *else_start = NULL; /* first insn in ELSE block or NULL */ rtx_insn *else_end = NULL; /* last insn + 1 in ELSE block */ int max; /* max # of insns to convert. */ - int then_mod_ok; /* whether conditional mods are ok in THEN */ + bool then_mod_ok; /* whether conditional mods are ok in THEN */ rtx true_expr; /* test for else block insns */ rtx false_expr; /* test for then block insns */ profile_probability true_prob_val;/* probability of else block */ @@ -497,7 +497,7 @@ cond_exec_process_if_block (ce_if_block * ce_info, if (!do_multiple_p && ce_info->num_multiple_test_blocks) { if (else_bb || ! ce_info->and_and_p) - return FALSE; + return false; ce_info->test_bb = test_bb = ce_info->last_test_bb; ce_info->num_multiple_test_blocks = 0; @@ -509,18 +509,18 @@ cond_exec_process_if_block (ce_if_block * ce_info, the test. */ test_expr = cond_exec_get_condition (BB_END (test_bb)); if (! test_expr) - return FALSE; + return false; /* If the conditional jump is more than just a conditional jump, then we cannot do conditional execution conversion on this block. */ if (! onlyjump_p (BB_END (test_bb))) - return FALSE; + return false; /* Collect the bounds of where we're to search, skipping any labels, jumps and notes at the beginning and end of the block. Then count the total number of insns and see if it is small enough to convert. */ then_start = first_active_insn (then_bb); - then_end = last_active_insn (then_bb, TRUE); + then_end = last_active_insn (then_bb, true); then_n_insns = ce_info->num_then_insns = count_bb_insns (then_bb); n_insns = then_n_insns; max = MAX_CONDITIONAL_EXECUTE; @@ -531,7 +531,7 @@ cond_exec_process_if_block (ce_if_block * ce_info, max *= 2; else_start = first_active_insn (else_bb); - else_end = last_active_insn (else_bb, TRUE); + else_end = last_active_insn (else_bb, true); else_n_insns = ce_info->num_else_insns = count_bb_insns (else_bb); n_insns += else_n_insns; @@ -580,7 +580,7 @@ cond_exec_process_if_block (ce_if_block * ce_info, if (!LABEL_P (insn) && !NOTE_P (insn) && !DEBUG_INSN_P (insn) && modified_in_p (test_expr, insn)) - return FALSE; + return false; } if (then_last_head == then_end) @@ -600,7 +600,7 @@ cond_exec_process_if_block (ce_if_block * ce_info, } if (n_insns > max) - return FALSE; + return false; /* Map test_expr/test_jump into the appropriate MD tests to use on the conditionally executed code. */ @@ -654,10 +654,10 @@ cond_exec_process_if_block (ce_if_block * ce_info, bb = block_fallthru (bb); start = first_active_insn (bb); - end = last_active_insn (bb, TRUE); + end = last_active_insn (bb, true); if (start && ! cond_exec_process_insns (ce_info, start, end, false_expr, - false_prob_val, FALSE)) + false_prob_val, false)) goto fail; /* If the conditional jump is more than just a conditional jump, then @@ -719,7 +719,7 @@ cond_exec_process_if_block (ce_if_block * ce_info, if (else_bb && else_end && ! cond_exec_process_insns (ce_info, else_start, else_end, - true_expr, true_prob_val, TRUE)) + true_expr, true_prob_val, true)) goto fail; /* If we cannot apply the changes, fail. Do not go through the normal fail @@ -730,7 +730,7 @@ cond_exec_process_if_block (ce_if_block * ce_info, /* Cancel any machine dependent changes. */ IFCVT_MODIFY_CANCEL (ce_info); #endif - return FALSE; + return false; } #ifdef IFCVT_MODIFY_FINAL @@ -759,8 +759,8 @@ cond_exec_process_if_block (ce_if_block * ce_info, delete_insn_chain (first_active_insn (else_bb), else_last_head, false); merge_if_block (ce_info); - cond_exec_changed_p = TRUE; - return TRUE; + cond_exec_changed_p = true; + return true; fail: #ifdef IFCVT_MODIFY_CANCEL @@ -769,24 +769,24 @@ cond_exec_process_if_block (ce_if_block * ce_info, #endif cancel_changes (0); - return FALSE; + return false; } -static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int); -static int noce_try_move (struct noce_if_info *); -static int noce_try_ifelse_collapse (struct noce_if_info *); -static int noce_try_store_flag (struct noce_if_info *); -static int noce_try_addcc (struct noce_if_info *); -static int noce_try_store_flag_constants (struct noce_if_info *); -static int noce_try_store_flag_mask (struct noce_if_info *); +static rtx noce_emit_store_flag (struct noce_if_info *, rtx, bool, int); +static bool noce_try_move (struct noce_if_info *); +static bool noce_try_ifelse_collapse (struct noce_if_info *); +static bool noce_try_store_flag (struct noce_if_info *); +static bool noce_try_addcc (struct noce_if_info *); +static bool noce_try_store_flag_constants (struct noce_if_info *); +static bool noce_try_store_flag_mask (struct noce_if_info *); static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx, rtx, rtx, rtx, rtx = NULL, rtx = NULL); -static int noce_try_cmove (struct noce_if_info *); -static int noce_try_cmove_arith (struct noce_if_info *); +static bool noce_try_cmove (struct noce_if_info *); +static bool noce_try_cmove_arith (struct noce_if_info *); static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **); -static int noce_try_minmax (struct noce_if_info *); -static int noce_try_abs (struct noce_if_info *); -static int noce_try_sign_mask (struct noce_if_info *); +static bool noce_try_minmax (struct noce_if_info *); +static bool noce_try_abs (struct noce_if_info *); +static bool noce_try_sign_mask (struct noce_if_info *); /* Return the comparison code for reversed condition for IF_INFO, or UNKNOWN if reversing the condition is not possible. */ @@ -824,11 +824,11 @@ default_noce_conversion_profitable_p (rtx_insn *seq, /* Helper function for noce_try_store_flag*. */ static rtx -noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep, +noce_emit_store_flag (struct noce_if_info *if_info, rtx x, bool reversep, int normalize) { rtx cond = if_info->cond; - int cond_complex; + bool cond_complex; enum rtx_code code; cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode) @@ -1127,7 +1127,7 @@ noce_simple_bbs (struct noce_if_info *if_info) /* Convert "if (a != b) x = a; else x = b" into "x = a" and "if (a == b) x = a; else x = b" into "x = b". */ -static int +static bool noce_try_move (struct noce_if_info *if_info) { rtx cond = if_info->cond; @@ -1136,16 +1136,16 @@ noce_try_move (struct noce_if_info *if_info) rtx_insn *seq; if (code != NE && code != EQ) - return FALSE; + return false; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; /* This optimization isn't valid if either A or B could be a NaN or a signed zero. */ if (HONOR_NANS (if_info->x) || HONOR_SIGNED_ZEROS (if_info->x)) - return FALSE; + return false; /* Check whether the operands of the comparison are A and in either order. */ @@ -1155,7 +1155,7 @@ noce_try_move (struct noce_if_info *if_info) && rtx_equal_p (if_info->b, XEXP (cond, 0)))) { if (!rtx_interchangeable_p (if_info->a, if_info->b)) - return FALSE; + return false; y = (code == EQ) ? if_info->a : if_info->b; @@ -1166,26 +1166,26 @@ noce_try_move (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, y); seq = end_ifcvt_sequence (if_info); if (!seq) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); } if_info->transform_name = "noce_try_move"; - return TRUE; + return true; } - return FALSE; + return false; } /* Try forming an IF_THEN_ELSE (cond, b, a) and collapsing that through simplify_rtx. Sometimes that can eliminate the IF_THEN_ELSE. If that is the case, emit the result into x. */ -static int +static bool noce_try_ifelse_collapse (struct noce_if_info * if_info) { if (!noce_simple_bbs (if_info)) - return FALSE; + return false; machine_mode mode = GET_MODE (if_info->x); rtx if_then_else = simplify_gen_ternary (IF_THEN_ELSE, mode, mode, @@ -1193,20 +1193,20 @@ noce_try_ifelse_collapse (struct noce_if_info * if_info) if_info->a); if (GET_CODE (if_then_else) == IF_THEN_ELSE) - return FALSE; + return false; rtx_insn *seq; start_sequence (); noce_emit_move_insn (if_info->x, if_then_else); seq = end_ifcvt_sequence (if_info); if (!seq) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_ifelse_collapse"; - return TRUE; + return true; } @@ -1216,27 +1216,27 @@ noce_try_ifelse_collapse (struct noce_if_info * if_info) tried in noce_try_store_flag_constants after noce_try_cmove has had a go at the conversion. */ -static int +static bool noce_try_store_flag (struct noce_if_info *if_info) { - int reversep; + bool reversep; rtx target; rtx_insn *seq; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; if (CONST_INT_P (if_info->b) && INTVAL (if_info->b) == STORE_FLAG_VALUE && if_info->a == const0_rtx) - reversep = 0; + reversep = false; else if (if_info->b == const0_rtx && CONST_INT_P (if_info->a) && INTVAL (if_info->a) == STORE_FLAG_VALUE && noce_reversed_cond_code (if_info) != UNKNOWN) - reversep = 1; + reversep = true; else - return FALSE; + return false; start_sequence (); @@ -1248,17 +1248,17 @@ noce_try_store_flag (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (! seq) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_store_flag"; - return TRUE; + return true; } else { end_sequence (); - return FALSE; + return false; } } @@ -1344,7 +1344,7 @@ noce_try_inverse_constants (struct noce_if_info *if_info) Also allow A = y + c1, B = y + c2, with a common y between A and B. */ -static int +static bool noce_try_store_flag_constants (struct noce_if_info *if_info) { rtx target; @@ -1377,7 +1377,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) } if (!noce_simple_bbs (if_info)) - return FALSE; + return false; if (CONST_INT_P (a) && CONST_INT_P (b)) @@ -1390,7 +1390,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) /* Make sure we can represent the difference between the two values. */ if ((diff > 0) != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue)) - return FALSE; + return false; diff = trunc_int_for_mode (diff, mode); @@ -1418,7 +1418,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) A and B then it is unlikely to be beneficial to play tricks here. */ if (subtract_flag_p && common) - return FALSE; + return false; } /* test ? 3 : 4 => can_reverse | 3 + (test == 0) @@ -1431,7 +1431,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) A and B then it is unlikely to be beneficial to play tricks here. */ if (subtract_flag_p && common) - return FALSE; + return false; } /* test ? 4 : 3 => 4 + (test != 0). */ @@ -1463,7 +1463,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) reversep = true; } else - return FALSE; + return false; if (reversep) { @@ -1485,7 +1485,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) if (! target) { end_sequence (); - return FALSE; + return false; } /* if (test) x = 3; else x = 4; @@ -1511,7 +1511,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) else if (common) { end_sequence (); - return FALSE; + return false; } /* if (test) x = 8; else x = 0; => x = (test != 0) << 3; */ @@ -1533,13 +1533,13 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) else { end_sequence (); - return FALSE; + return false; } if (! target) { end_sequence (); - return FALSE; + return false; } if (target != if_info->x) @@ -1547,30 +1547,31 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info)) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_store_flag_constants"; - return TRUE; + return true; } - return FALSE; + return false; } /* Convert "if (test) foo++" into "foo += (test != 0)", and similarly for "foo--". */ -static int +static bool noce_try_addcc (struct noce_if_info *if_info) { rtx target; rtx_insn *seq; - int subtract, normalize; + bool subtract; + int normalize; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; if (GET_CODE (if_info->a) == PLUS && rtx_equal_p (XEXP (if_info->a, 0), if_info->b) @@ -1608,13 +1609,13 @@ noce_try_addcc (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info)) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_addcc"; - return TRUE; + return true; } end_sequence (); } @@ -1627,16 +1628,16 @@ noce_try_addcc (struct noce_if_info *if_info) { start_sequence (); if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1))) - subtract = 0, normalize = 0; + subtract = false, normalize = 0; else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1))) - subtract = 1, normalize = 0; + subtract = true, normalize = 0; else - subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1)); + subtract = false, normalize = INTVAL (XEXP (if_info->a, 1)); target = noce_emit_store_flag (if_info, gen_reg_rtx (GET_MODE (if_info->x)), - 1, normalize); + true, normalize); if (target) target = expand_simple_binop (GET_MODE (if_info->x), @@ -1650,33 +1651,33 @@ noce_try_addcc (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info)) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_addcc"; - return TRUE; + return true; } end_sequence (); } } - return FALSE; + return false; } /* Convert "if (test) x = 0;" to "x &= -(test == 0);" */ -static int +static bool noce_try_store_flag_mask (struct noce_if_info *if_info) { rtx target; rtx_insn *seq; - int reversep; + bool reversep; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; - reversep = 0; + reversep = false; if ((if_info->a == const0_rtx && (REG_P (if_info->b) || rtx_equal_p (if_info->b, if_info->x))) @@ -1701,19 +1702,19 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info)) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_store_flag_mask"; - return TRUE; + return true; } end_sequence (); } - return FALSE; + return false; } /* Helper function for noce_try_cmove and noce_try_cmove_arith. */ @@ -1724,7 +1725,7 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, rtx rev_cc_cmp) { rtx target ATTRIBUTE_UNUSED; - int unsignedp ATTRIBUTE_UNUSED; + bool unsignedp ATTRIBUTE_UNUSED; /* If earliest == jump, try to build the cmove insn directly. This is helpful when combine has created some complex condition @@ -1834,7 +1835,7 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, are handled in noce_try_cmove_arith after noce_try_store_flag_arith has had a go at it. */ -static int +static bool noce_try_cmove (struct noce_if_info *if_info) { enum rtx_code code; @@ -1842,7 +1843,7 @@ noce_try_cmove (struct noce_if_info *if_info) rtx_insn *seq; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode)) && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode))) @@ -1862,13 +1863,13 @@ noce_try_cmove (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info)) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_cmove"; - return TRUE; + return true; } /* If both a and b are constants try a last-ditch transformation: if (test) x = a; else x = b; @@ -1887,7 +1888,7 @@ noce_try_cmove (struct noce_if_info *if_info) if (!target) { end_sequence (); - return FALSE; + return false; } HOST_WIDE_INT diff = (unsigned HOST_WIDE_INT) itrue - ifalse; @@ -1897,7 +1898,7 @@ noce_try_cmove (struct noce_if_info *if_info) != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue)) { end_sequence (); - return FALSE; + return false; } diff = trunc_int_for_mode (diff, mode); @@ -1915,24 +1916,24 @@ noce_try_cmove (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info)) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_cmove"; - return TRUE; + return true; } else { end_sequence (); - return FALSE; + return false; } } else end_sequence (); } - return FALSE; + return false; } /* Return true if X contains a conditional code mode rtx. */ @@ -2059,7 +2060,7 @@ bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b, rtx to_rename) static void noce_emit_all_but_last (basic_block bb) { - rtx_insn *last = last_active_insn (bb, FALSE); + rtx_insn *last = last_active_insn (bb, false); rtx_insn *insn; FOR_BB_INSNS (bb, insn) { @@ -2107,7 +2108,7 @@ noce_emit_bb (rtx last_insn, basic_block bb, bool simple) /* Try more complex cases involving conditional_move. */ -static int +static bool noce_try_cmove_arith (struct noce_if_info *if_info) { rtx a = if_info->a; @@ -2120,7 +2121,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) basic_block then_bb = if_info->then_bb; basic_block else_bb = if_info->else_bb; rtx target; - int is_mem = 0; + bool is_mem = false; enum rtx_code code; rtx cond = if_info->cond; rtx_insn *ifcvt_seq; @@ -2138,14 +2139,14 @@ noce_try_cmove_arith (struct noce_if_info *if_info) a = XEXP (a, 0); b = XEXP (b, 0); x = gen_reg_rtx (address_mode); - is_mem = 1; + is_mem = true; } /* ??? We could handle this if we knew that a load from A or B could not trap or fault. This is also true if we've already loaded from the address along the path from ENTRY. */ else if (may_trap_or_fault_p (a) || may_trap_or_fault_p (b)) - return FALSE; + return false; /* if (test) x = a + b; else x = c - d; => y = a + b; @@ -2161,16 +2162,16 @@ noce_try_cmove_arith (struct noce_if_info *if_info) machine_mode x_mode = GET_MODE (x); if (!can_conditionally_move_p (x_mode)) - return FALSE; + return false; /* Possibly rearrange operands to make things come out more natural. */ if (noce_reversed_cond_code (if_info) != UNKNOWN) { - int reversep = 0; + bool reversep = false; if (rtx_equal_p (b, x)) - reversep = 1; + reversep = true; else if (general_operand (b, GET_MODE (b))) - reversep = 1; + reversep = true; if (reversep) { @@ -2191,7 +2192,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) if (then_bb && else_bb && (!bbs_ok_for_cmove_arith (then_bb, else_bb, if_info->orig_x) || !bbs_ok_for_cmove_arith (else_bb, then_bb, if_info->orig_x))) - return FALSE; + return false; start_sequence (); @@ -2358,16 +2359,16 @@ noce_try_cmove_arith (struct noce_if_info *if_info) ifcvt_seq = end_ifcvt_sequence (if_info); if (!ifcvt_seq || !targetm.noce_conversion_profitable_p (ifcvt_seq, if_info)) - return FALSE; + return false; emit_insn_before_setloc (ifcvt_seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_cmove_arith"; - return TRUE; + return true; end_seq_and_fail: end_sequence (); - return FALSE; + return false; } /* For most cases, the simplified condition we found is the best @@ -2380,7 +2381,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target, { rtx cond, set; rtx_insn *insn; - int reverse; + bool reverse; /* If target is already mentioned in the known condition, return it. */ if (reg_mentioned_p (target, if_info->cond)) @@ -2528,27 +2529,27 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target, /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc. */ -static int +static bool noce_try_minmax (struct noce_if_info *if_info) { rtx cond, target; rtx_insn *earliest, *seq; enum rtx_code code, op; - int unsignedp; + bool unsignedp; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; /* ??? Reject modes with NaNs or signed zeros since we don't know how they will be resolved with an SMIN/SMAX. It wouldn't be too hard to get the target to tell us... */ if (HONOR_SIGNED_ZEROS (if_info->x) || HONOR_NANS (if_info->x)) - return FALSE; + return false; cond = noce_get_alt_condition (if_info, if_info->a, &earliest); if (!cond) - return FALSE; + return false; /* Verify the condition is of the form we expect, and canonicalize the comparison code. */ @@ -2556,16 +2557,16 @@ noce_try_minmax (struct noce_if_info *if_info) if (rtx_equal_p (XEXP (cond, 0), if_info->a)) { if (! rtx_equal_p (XEXP (cond, 1), if_info->b)) - return FALSE; + return false; } else if (rtx_equal_p (XEXP (cond, 1), if_info->a)) { if (! rtx_equal_p (XEXP (cond, 0), if_info->b)) - return FALSE; + return false; code = swap_condition (code); } else - return FALSE; + return false; /* Determine what sort of operation this is. Note that the code is for a taken branch, so the code->operation mapping appears backwards. */ @@ -2576,27 +2577,27 @@ noce_try_minmax (struct noce_if_info *if_info) case UNLT: case UNLE: op = SMAX; - unsignedp = 0; + unsignedp = false; break; case GT: case GE: case UNGT: case UNGE: op = SMIN; - unsignedp = 0; + unsignedp = false; break; case LTU: case LEU: op = UMAX; - unsignedp = 1; + unsignedp = true; break; case GTU: case GEU: op = UMIN; - unsignedp = 1; + unsignedp = true; break; default: - return FALSE; + return false; } start_sequence (); @@ -2607,14 +2608,14 @@ noce_try_minmax (struct noce_if_info *if_info) if (! target) { end_sequence (); - return FALSE; + return false; } if (target != if_info->x) noce_emit_move_insn (if_info->x, target); seq = end_ifcvt_sequence (if_info); if (!seq) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->cond = cond; @@ -2622,27 +2623,27 @@ noce_try_minmax (struct noce_if_info *if_info) if_info->rev_cond = NULL_RTX; if_info->transform_name = "noce_try_minmax"; - return TRUE; + return true; } /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);", etc. */ -static int +static bool noce_try_abs (struct noce_if_info *if_info) { rtx cond, target, a, b, c; rtx_insn *earliest, *seq; - int negate; + bool negate; bool one_cmpl = false; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; /* Reject modes with signed zeros. */ if (HONOR_SIGNED_ZEROS (if_info->x)) - return FALSE; + return false; /* Recognize A and B as constituting an ABS or NABS. The canonical form is a branch around the negation, taken when the object is the @@ -2650,29 +2651,29 @@ noce_try_abs (struct noce_if_info *if_info) a = if_info->a; b = if_info->b; if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b)) - negate = 0; + negate = false; else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a)) { std::swap (a, b); - negate = 1; + negate = true; } else if (GET_CODE (a) == NOT && rtx_equal_p (XEXP (a, 0), b)) { - negate = 0; + negate = false; one_cmpl = true; } else if (GET_CODE (b) == NOT && rtx_equal_p (XEXP (b, 0), a)) { std::swap (a, b); - negate = 1; + negate = true; one_cmpl = true; } else - return FALSE; + return false; cond = noce_get_alt_condition (if_info, b, &earliest); if (!cond) - return FALSE; + return false; /* Verify the condition is of the form we expect. */ if (rtx_equal_p (XEXP (cond, 0), b)) @@ -2683,7 +2684,7 @@ noce_try_abs (struct noce_if_info *if_info) negate = !negate; } else - return FALSE; + return false; /* Verify that C is zero. Search one step backward for a REG_EQUAL note or a simple source if necessary. */ @@ -2703,7 +2704,7 @@ noce_try_abs (struct noce_if_info *if_info) c = SET_SRC (set); } else - return FALSE; + return false; } if (MEM_P (c) && GET_CODE (XEXP (c, 0)) == SYMBOL_REF @@ -2722,17 +2723,17 @@ noce_try_abs (struct noce_if_info *if_info) else if (c == const1_rtx && GET_CODE (cond) == LT) { if (one_cmpl) - return FALSE; + return false; } else if (c == CONST0_RTX (GET_MODE (b))) { if (one_cmpl && GET_CODE (cond) != GE && GET_CODE (cond) != LT) - return FALSE; + return false; } else - return FALSE; + return false; /* Determine what sort of operation this is. */ switch (GET_CODE (cond)) @@ -2749,7 +2750,7 @@ noce_try_abs (struct noce_if_info *if_info) case UNGE: break; default: - return FALSE; + return false; } start_sequence (); @@ -2774,7 +2775,7 @@ noce_try_abs (struct noce_if_info *if_info) if (! target) { end_sequence (); - return FALSE; + return false; } if (target != if_info->x) @@ -2782,7 +2783,7 @@ noce_try_abs (struct noce_if_info *if_info) seq = end_ifcvt_sequence (if_info); if (!seq) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->cond = cond; @@ -2790,12 +2791,12 @@ noce_try_abs (struct noce_if_info *if_info) if_info->rev_cond = NULL_RTX; if_info->transform_name = "noce_try_abs"; - return TRUE; + return true; } /* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;". */ -static int +static bool noce_try_sign_mask (struct noce_if_info *if_info) { rtx cond, t, m, c; @@ -2805,7 +2806,7 @@ noce_try_sign_mask (struct noce_if_info *if_info) bool t_unconditional; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; cond = if_info->cond; code = GET_CODE (cond); @@ -2827,12 +2828,12 @@ noce_try_sign_mask (struct noce_if_info *if_info) } if (! t || side_effects_p (t)) - return FALSE; + return false; /* We currently don't handle different modes. */ mode = GET_MODE (t); if (GET_MODE (m) != mode) - return FALSE; + return false; /* This is only profitable if T is unconditionally executed/evaluated in the original insn sequence or T is cheap and can't trap or fault. The former @@ -2848,10 +2849,10 @@ noce_try_sign_mask (struct noce_if_info *if_info) || ((set_src_cost (t, mode, if_info->speed_p) < COSTS_N_INSNS (2)) && !may_trap_or_fault_p (t)))) - return FALSE; + return false; if (!noce_can_force_operand (t)) - return FALSE; + return false; start_sequence (); /* Use emit_store_flag to generate "m < 0 ? -1 : 0" instead of expanding @@ -2864,26 +2865,26 @@ noce_try_sign_mask (struct noce_if_info *if_info) if (!t) { end_sequence (); - return FALSE; + return false; } noce_emit_move_insn (if_info->x, t); seq = end_ifcvt_sequence (if_info); if (!seq) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); if_info->transform_name = "noce_try_sign_mask"; - return TRUE; + return true; } /* Optimize away "if (x & C) x |= C" and similar bit manipulation transformations. */ -static int +static bool noce_try_bitop (struct noce_if_info *if_info) { rtx cond, x, a, result; @@ -2898,20 +2899,20 @@ noce_try_bitop (struct noce_if_info *if_info) /* Check for an integer operation. */ if (!is_a (GET_MODE (x), &mode)) - return FALSE; + return false; if (!noce_simple_bbs (if_info)) - return FALSE; + return false; /* Check for no else condition. */ if (! rtx_equal_p (x, if_info->b)) - return FALSE; + return false; /* Check for a suitable condition. */ if (code != NE && code != EQ) - return FALSE; + return false; if (XEXP (cond, 1) != const0_rtx) - return FALSE; + return false; cond = XEXP (cond, 0); /* ??? We could also handle AND here. */ @@ -2920,15 +2921,15 @@ noce_try_bitop (struct noce_if_info *if_info) if (XEXP (cond, 1) != const1_rtx || !CONST_INT_P (XEXP (cond, 2)) || ! rtx_equal_p (x, XEXP (cond, 0))) - return FALSE; + return false; bitnum = INTVAL (XEXP (cond, 2)); if (BITS_BIG_ENDIAN) bitnum = GET_MODE_BITSIZE (mode) - 1 - bitnum; if (bitnum < 0 || bitnum >= HOST_BITS_PER_WIDE_INT) - return FALSE; + return false; } else - return FALSE; + return false; a = if_info->a; if (GET_CODE (a) == IOR || GET_CODE (a) == XOR) @@ -2938,7 +2939,7 @@ noce_try_bitop (struct noce_if_info *if_info) || !CONST_INT_P (XEXP (a, 1)) || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) != HOST_WIDE_INT_1U << bitnum) - return FALSE; + return false; /* if ((x & C) == 0) x |= C; is transformed to x |= C. */ /* if ((x & C) != 0) x |= C; is transformed to nothing. */ @@ -2964,14 +2965,14 @@ noce_try_bitop (struct noce_if_info *if_info) || !CONST_INT_P (XEXP (a, 1)) || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) != (~(HOST_WIDE_INT_1 << bitnum) & GET_MODE_MASK (mode))) - return FALSE; + return false; /* if ((x & C) == 0) x &= ~C; is transformed to nothing. */ /* if ((x & C) != 0) x &= ~C; is transformed to x &= ~C. */ result = (code == EQ) ? a : NULL_RTX; } else - return FALSE; + return false; if (result) { @@ -2979,13 +2980,13 @@ noce_try_bitop (struct noce_if_info *if_info) noce_emit_move_insn (x, result); seq = end_ifcvt_sequence (if_info); if (!seq) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a)); } if_info->transform_name = "noce_try_bitop"; - return TRUE; + return true; } @@ -2996,7 +2997,8 @@ noce_try_bitop (struct noce_if_info *if_info) THEN block of the caller, and we have to reverse the condition. */ static rtx -noce_get_condition (rtx_insn *jump, rtx_insn **earliest, bool then_else_reversed) +noce_get_condition (rtx_insn *jump, rtx_insn **earliest, + bool then_else_reversed) { rtx cond, set, tmp; bool reverse; @@ -3048,11 +3050,11 @@ noce_get_condition (rtx_insn *jump, rtx_insn **earliest, bool then_else_reversed /* Return true if OP is ok for if-then-else processing. */ -static int +static bool noce_operand_ok (const_rtx op) { if (side_effects_p (op)) - return FALSE; + return false; /* We special-case memories, so handle any of them with no address side effects. */ @@ -3079,7 +3081,7 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond, if (!test_bb) return false; - rtx_insn *last_insn = last_active_insn (test_bb, FALSE); + rtx_insn *last_insn = last_active_insn (test_bb, false); rtx last_set = NULL_RTX; rtx cc = cc_in_cond (cond); @@ -3251,7 +3253,7 @@ try_emit_cmove_seq (struct noce_if_info *if_info, rtx temp, IF_INFO contains the useful information about the block structure and jump instructions. */ -static int +static bool noce_convert_multiple_sets (struct noce_if_info *if_info) { basic_block test_bb = if_info->test_bb; @@ -3323,7 +3325,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) if (!targetm.noce_conversion_profitable_p (seq, if_info)) { end_sequence (); - return FALSE; + return false; } for (insn = seq; insn; insn = NEXT_INSN (insn)) @@ -3344,12 +3346,12 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) end_sequence (); if (!seq) - return FALSE; + return false; for (insn = seq; insn; insn = NEXT_INSN (insn)) if (JUMP_P (insn) || recog_memoized (insn) == -1) - return FALSE; + return false; emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (unmodified_insns.last ())); @@ -3370,7 +3372,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) num_updated_if_blocks++; if_info->transform_name = "noce_convert_multiple_sets"; - return TRUE; + return true; } /* Helper function for noce_convert_multiple_sets_1. If store to @@ -3511,7 +3513,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info, if (!partial_subreg_p (dst_mode, src_mode)) { end_sequence (); - return FALSE; + return false; } new_val = lowpart_subreg (dst_mode, new_val, src_mode); } @@ -3523,7 +3525,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info, if (!partial_subreg_p (dst_mode, src_mode)) { end_sequence (); - return FALSE; + return false; } old_val = lowpart_subreg (dst_mode, old_val, src_mode); } @@ -3604,7 +3606,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info, { /* Nothing worked, bail out. */ end_sequence (); - return FALSE; + return false; } if (cc_cmp) @@ -3725,7 +3727,7 @@ average_cost (unsigned then_cost, unsigned else_cost, edge e) it without using conditional execution. Return TRUE if we were successful at converting the block. */ -static int +static bool noce_process_if_block (struct noce_if_info *if_info) { basic_block test_bb = if_info->test_bb; /* test block */ @@ -3773,7 +3775,7 @@ noce_process_if_block (struct noce_if_info *if_info) if (dump_file && if_info->transform_name) fprintf (dump_file, "if-conversion succeeded through %s\n", if_info->transform_name); - return TRUE; + return true; } /* Restore the original costs. */ @@ -3797,7 +3799,7 @@ noce_process_if_block (struct noce_if_info *if_info) else if_info->original_cost += then_cost + else_cost; - insn_a = last_active_insn (then_bb, FALSE); + insn_a = last_active_insn (then_bb, false); set_a = single_set (insn_a); gcc_assert (set_a); @@ -3814,12 +3816,12 @@ noce_process_if_block (struct noce_if_info *if_info) set_b = NULL_RTX; if (else_bb) { - insn_b = last_active_insn (else_bb, FALSE); + insn_b = last_active_insn (else_bb, false); set_b = single_set (insn_b); gcc_assert (set_b); if (!rtx_interchangeable_p (x, SET_DEST (set_b))) - return FALSE; + return false; } else { @@ -3866,7 +3868,7 @@ noce_process_if_block (struct noce_if_info *if_info) noce_emit_move_insn expands to more than one insn, so disable the optimization entirely for now if there are side effects. */ if (side_effects_p (x)) - return FALSE; + return false; b = (set_b ? SET_SRC (set_b) : x); @@ -3879,12 +3881,12 @@ noce_process_if_block (struct noce_if_info *if_info) && targetm.small_register_classes_for_mode_p (GET_MODE (x)))) { if (GET_MODE (x) == BLKmode) - return FALSE; + return false; if (GET_CODE (x) == ZERO_EXTRACT && (!CONST_INT_P (XEXP (x, 1)) || !CONST_INT_P (XEXP (x, 2)))) - return FALSE; + return false; x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART ? XEXP (x, 0) : x)); @@ -3892,7 +3894,7 @@ noce_process_if_block (struct noce_if_info *if_info) /* Don't operate on sources that may trap or are volatile. */ if (! noce_operand_ok (a) || ! noce_operand_ok (b)) - return FALSE; + return false; retry: /* Set up the info block for our subroutines. */ @@ -3933,7 +3935,7 @@ noce_process_if_block (struct noce_if_info *if_info) /* If we have "x = b; if (...) x = a;", and x has side-effects, then x must be executed twice. */ else if (insn_b && side_effects_p (orig_x)) - return FALSE; + return false; x = orig_x; goto success; @@ -3945,7 +3947,7 @@ noce_process_if_block (struct noce_if_info *if_info) ++global_variable; Rather than go to much effort here, we rely on the SSA optimizers, which do a good enough job these days. */ - return FALSE; + return false; if (noce_try_move (if_info)) goto success; @@ -3988,7 +3990,7 @@ noce_process_if_block (struct noce_if_info *if_info) goto retry; } - return FALSE; + return false; success: if (dump_file && if_info->transform_name) @@ -4033,7 +4035,7 @@ noce_process_if_block (struct noce_if_info *if_info) } num_updated_if_blocks++; - return TRUE; + return true; } /* Check whether a block is suitable for conditional move conversion. @@ -4042,7 +4044,7 @@ noce_process_if_block (struct noce_if_info *if_info) VALS, keyed indexed by register pointer, then store the register pointer in REGS. COND is the condition we will test. */ -static int +static bool check_cond_move_block (basic_block bb, hash_map *vals, vec *regs, @@ -4055,7 +4057,7 @@ check_cond_move_block (basic_block bb, It is almost impossible to update the CFG otherwise. */ insn = BB_END (bb); if (JUMP_P (insn) && !onlyjump_p (insn)) - return FALSE; + return false; FOR_BB_INSNS (bb, insn) { @@ -4065,23 +4067,23 @@ check_cond_move_block (basic_block bb, continue; set = single_set (insn); if (!set) - return FALSE; + return false; dest = SET_DEST (set); src = SET_SRC (set); if (!REG_P (dest) || (HARD_REGISTER_P (dest) && targetm.small_register_classes_for_mode_p (GET_MODE (dest)))) - return FALSE; + return false; if (!CONSTANT_P (src) && !register_operand (src, VOIDmode)) - return FALSE; + return false; if (side_effects_p (src) || side_effects_p (dest)) - return FALSE; + return false; if (may_trap_p (src) || may_trap_p (dest)) - return FALSE; + return false; /* Don't try to handle this if the source register was modified earlier in the block. */ @@ -4089,34 +4091,34 @@ check_cond_move_block (basic_block bb, && vals->get (src)) || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)) && vals->get (SUBREG_REG (src)))) - return FALSE; + return false; /* Don't try to handle this if the destination register was modified earlier in the block. */ if (vals->get (dest)) - return FALSE; + return false; /* Don't try to handle this if the condition uses the destination register. */ if (reg_overlap_mentioned_p (dest, cond)) - return FALSE; + return false; /* Don't try to handle this if the source register is modified later in the block. */ if (!CONSTANT_P (src) && modified_between_p (src, insn, NEXT_INSN (BB_END (bb)))) - return FALSE; + return false; /* Skip it if the instruction to be moved might clobber CC. */ if (cc && set_of (cc, insn)) - return FALSE; + return false; vals->put (dest, src); regs->safe_push (dest); } - return TRUE; + return true; } /* Find local swap-style idioms in BB and mark the first insn (1) @@ -4276,7 +4278,7 @@ cond_move_convert_if_block (struct noce_if_info *if_infop, it using only conditional moves. Return TRUE if we were successful at converting the block. */ -static int +static bool cond_move_process_if_block (struct noce_if_info *if_info) { basic_block test_bb = if_info->test_bb; @@ -4289,7 +4291,7 @@ cond_move_process_if_block (struct noce_if_info *if_info) int c; vec then_regs = vNULL; vec else_regs = vNULL; - int success_p = FALSE; + bool success_p = false; int limit = param_max_rtl_if_conversion_insns; /* Build a mapping for each block to the value used for each @@ -4388,7 +4390,7 @@ cond_move_process_if_block (struct noce_if_info *if_info) } num_updated_if_blocks++; - success_p = TRUE; + success_p = true; done: then_regs.release (); @@ -4405,7 +4407,7 @@ done: Return TRUE if we were successful at converting the block. */ -static int +static bool noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, int pass) { @@ -4457,14 +4459,14 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, } else /* Not a form we can handle. */ - return FALSE; + return false; /* The edges of the THEN and ELSE blocks cannot have complex edges. */ if (single_succ_edge (then_bb)->flags & EDGE_COMPLEX) - return FALSE; + return false; if (else_bb && single_succ_edge (else_bb)->flags & EDGE_COMPLEX) - return FALSE; + return false; num_possible_if_blocks++; @@ -4485,7 +4487,7 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, jump, then we cannot do if-conversion on this block. */ jump = BB_END (test_bb); if (! onlyjump_p (jump)) - return FALSE; + return false; /* Initialize an IF_INFO struct to pass around. */ memset (&if_info, 0, sizeof if_info); @@ -4499,7 +4501,7 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, if_info.rev_cond = noce_get_condition (jump, &rev_cond_earliest, !then_else_reversed); if (!if_info.cond && !if_info.rev_cond) - return FALSE; + return false; if (!if_info.cond) { std::swap (if_info.cond, if_info.rev_cond); @@ -4508,7 +4510,7 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, } /* We must be comparing objects whose modes imply the size. */ if (GET_MODE (XEXP (if_info.cond, 0)) == BLKmode) - return FALSE; + return false; gcc_assert (if_info.rev_cond == NULL_RTX || rev_cond_earliest == cond_earliest); if_info.cond_earliest = cond_earliest; @@ -4530,13 +4532,13 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, /* ??? noce_process_if_block has not yet been updated to handle inverted conditions. */ if (!if_info.cond_inverted && noce_process_if_block (&if_info)) - return TRUE; + return true; if (HAVE_conditional_move && cond_move_process_if_block (&if_info)) - return TRUE; + return true; - return FALSE; + return false; } @@ -4762,7 +4764,7 @@ find_if_header (basic_block test_bb, int pass) if (dump_file) fprintf (dump_file, "Conversion succeeded on pass %d.\n", pass); /* Set this so we continue looking. */ - cond_exec_changed_p = TRUE; + cond_exec_changed_p = true; return ce_info.test_bb; } @@ -4772,11 +4774,11 @@ find_if_header (basic_block test_bb, int pass) of non-note, non-jump, non-USE/CLOBBER insns in the block. */ static int -block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb) +block_jumps_and_fallthru (basic_block cur_bb, basic_block target_bb) { edge cur_edge; - int fallthru_p = FALSE; - int jump_p = FALSE; + bool fallthru_p = false; + bool jump_p = false; rtx_insn *insn; rtx_insn *end; int n_insns = 0; @@ -4787,7 +4789,7 @@ block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb) /* If no edges, obviously it doesn't jump or fallthru. */ if (EDGE_COUNT (cur_bb->succs) == 0) - return FALSE; + return 0; FOR_EACH_EDGE (cur_edge, ei, cur_bb->succs) { @@ -4796,10 +4798,10 @@ block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb) return -1; else if (cur_edge->flags & EDGE_FALLTHRU) - fallthru_p = TRUE; + fallthru_p = true; else if (cur_edge->dest == target_bb) - jump_p = TRUE; + jump_p = true; else return -1; @@ -4840,7 +4842,7 @@ block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb) block. If so, we'll try to convert the insns to not require the branch. Return TRUE if we were successful at converting the block. */ -static int +static bool cond_exec_find_if_block (struct ce_if_block * ce_info) { basic_block test_bb = ce_info->test_bb; @@ -4869,14 +4871,14 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) int n_insns; /* Determine if the preceding block is an && or || block. */ - if ((n_insns = block_jumps_and_fallthru_p (bb, else_bb)) >= 0) + if ((n_insns = block_jumps_and_fallthru (bb, else_bb)) >= 0) { - ce_info->and_and_p = TRUE; + ce_info->and_and_p = true; target_bb = else_bb; } - else if ((n_insns = block_jumps_and_fallthru_p (bb, then_bb)) >= 0) + else if ((n_insns = block_jumps_and_fallthru (bb, then_bb)) >= 0) { - ce_info->and_and_p = FALSE; + ce_info->and_and_p = false; target_bb = then_bb; } else @@ -4900,7 +4902,7 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) break; bb = single_pred (bb); - n_insns = block_jumps_and_fallthru_p (bb, target_bb); + n_insns = block_jumps_and_fallthru (bb, target_bb); } while (n_insns >= 0 && (total_insns + n_insns) <= max_insns); @@ -4917,19 +4919,19 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) /* The THEN block of an IF-THEN combo must have exactly one predecessor, other than any || blocks which jump to the THEN block. */ if ((EDGE_COUNT (then_bb->preds) - ce_info->num_or_or_blocks) != 1) - return FALSE; + return false; /* The edges of the THEN and ELSE blocks cannot have complex edges. */ FOR_EACH_EDGE (cur_edge, ei, then_bb->preds) { if (cur_edge->flags & EDGE_COMPLEX) - return FALSE; + return false; } FOR_EACH_EDGE (cur_edge, ei, else_bb->preds) { if (cur_edge->flags & EDGE_COMPLEX) - return FALSE; + return false; } /* The THEN block of an IF-THEN combo must have zero or one successors. */ @@ -4938,7 +4940,7 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) || (single_succ_edge (then_bb)->flags & EDGE_COMPLEX) || (epilogue_completed && tablejump_p (BB_END (then_bb), NULL, NULL)))) - return FALSE; + return false; /* If the THEN block has no successors, conditional execution can still make a conditional call. Don't do this unless the ELSE block has @@ -4960,13 +4962,13 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) if (last_insn && JUMP_P (last_insn) && ! simplejump_p (last_insn)) - return FALSE; + return false; join_bb = else_bb; else_bb = NULL_BLOCK; } else - return FALSE; + return false; } /* If the THEN block's successor is the other edge out of the TEST block, @@ -4990,7 +4992,7 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */ else - return FALSE; + return false; num_possible_if_blocks++; @@ -5038,14 +5040,14 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) exist. Sticky enough I don't want to think about it now. */ next = then_bb; if (else_bb && (next = next->next_bb) != else_bb) - return FALSE; + return false; if ((next = next->next_bb) != join_bb && join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) { if (else_bb) join_bb = NULL; else - return FALSE; + return false; } /* Do the real work. */ @@ -5057,24 +5059,24 @@ cond_exec_find_if_block (struct ce_if_block * ce_info) tests into the conditional code, and if that fails, go back and handle it without the && and ||, which at present handles the && case if there was no ELSE block. */ - if (cond_exec_process_if_block (ce_info, TRUE)) - return TRUE; + if (cond_exec_process_if_block (ce_info, true)) + return true; if (ce_info->num_multiple_test_blocks) { cancel_changes (0); - if (cond_exec_process_if_block (ce_info, FALSE)) - return TRUE; + if (cond_exec_process_if_block (ce_info, false)) + return true; } - return FALSE; + return false; } /* Convert a branch over a trap, or a branch to a trap, into a conditional trap. */ -static int +static bool find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) { basic_block then_bb = then_edge->dest; @@ -5092,7 +5094,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) else if ((trap = block_has_only_trap (else_bb)) != NULL) trap_bb = else_bb, other_bb = then_bb; else - return FALSE; + return false; if (dump_file) { @@ -5104,7 +5106,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) jump = BB_END (test_bb); cond = noce_get_condition (jump, &cond_earliest, then_bb == trap_bb); if (! cond) - return FALSE; + return false; /* If the conditional jump is more than just a conditional jump, then we cannot do if-conversion on this block. Give up for returnjump_p, @@ -5112,25 +5114,25 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) conditional trap followed by unconditional return is likely not beneficial and harder to handle. */ if (! onlyjump_p (jump) || returnjump_p (jump)) - return FALSE; + return false; /* We must be comparing objects whose modes imply the size. */ if (GET_MODE (XEXP (cond, 0)) == BLKmode) - return FALSE; + return false; /* Attempt to generate the conditional trap. */ rtx_insn *seq = gen_cond_trap (GET_CODE (cond), copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)), TRAP_CODE (PATTERN (trap))); if (seq == NULL) - return FALSE; + return false; /* If that results in an invalid insn, back out. */ for (rtx_insn *x = seq; x; x = NEXT_INSN (x)) if (reload_completed ? !valid_insn_p (x) : recog_memoized (x) < 0) - return FALSE; + return false; /* Emit the new insns before cond_earliest. */ emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap)); @@ -5168,7 +5170,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) } num_updated_if_blocks++; - return TRUE; + return true; } /* Subroutine of find_cond_trap: if BB contains only a trap insn, @@ -5274,7 +5276,7 @@ block_has_only_trap (basic_block bb) /* Tests for case 1 above. */ -static int +static bool find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) { basic_block then_bb = then_edge->dest; @@ -5302,27 +5304,27 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) || (BB_END (else_bb) && JUMP_P (BB_END (else_bb)) && CROSSING_JUMP_P (BB_END (else_bb)))) - return FALSE; + return false; /* Verify test_bb ends in a conditional jump with no other side-effects. */ if (!onlyjump_p (BB_END (test_bb))) - return FALSE; + return false; /* THEN has one successor. */ if (!single_succ_p (then_bb)) - return FALSE; + return false; /* THEN does not fall through, but is not strange either. */ if (single_succ_edge (then_bb)->flags & (EDGE_COMPLEX | EDGE_FALLTHRU)) - return FALSE; + return false; /* THEN has one predecessor. */ if (!single_pred_p (then_bb)) - return FALSE; + return false; /* THEN must do something. */ if (forwarder_block_p (then_bb)) - return FALSE; + return false; num_possible_if_blocks++; if (dump_file) @@ -5337,7 +5339,7 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) if (! cheap_bb_rtx_cost_p (then_bb, then_prob, COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (then_edge->src), predictable_edge_p (then_edge))))) - return FALSE; + return false; if (else_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)) { @@ -5348,8 +5350,8 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) /* Registers set are dead, or are predicable. */ if (! dead_or_predicable (test_bb, then_bb, else_bb, - single_succ_edge (then_bb), 1)) - return FALSE; + single_succ_edge (then_bb), true)) + return false; /* Conversion went ok, including moving the insns and fixing up the jump. Adjust the CFG to match. */ @@ -5390,12 +5392,12 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) num_true_changes++; num_updated_if_blocks++; - return TRUE; + return true; } /* Test for case 2 above. */ -static int +static bool find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) { basic_block then_bb = then_edge->dest; @@ -5406,7 +5408,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) /* We do not want to speculate (empty) loop latches. */ if (current_loops && else_bb->loop_father->latch == else_bb) - return FALSE; + return false; /* If we are partitioning hot/cold basic blocks, we don't want to mess up unconditional or indirect jumps that cross between hot @@ -5426,29 +5428,29 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) || (BB_END (else_bb) && JUMP_P (BB_END (else_bb)) && CROSSING_JUMP_P (BB_END (else_bb)))) - return FALSE; + return false; /* Verify test_bb ends in a conditional jump with no other side-effects. */ if (!onlyjump_p (BB_END (test_bb))) - return FALSE; + return false; /* ELSE has one successor. */ if (!single_succ_p (else_bb)) - return FALSE; + return false; else else_succ = single_succ_edge (else_bb); /* ELSE outgoing edge is not complex. */ if (else_succ->flags & EDGE_COMPLEX) - return FALSE; + return false; /* ELSE has one predecessor. */ if (!single_pred_p (else_bb)) - return FALSE; + return false; /* THEN is not EXIT. */ if (then_bb->index < NUM_FIXED_BLOCKS) - return FALSE; + return false; else_prob = else_edge->probability; then_prob = else_prob.invert (); @@ -5461,7 +5463,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) else_succ->dest)) ; else - return FALSE; + return false; num_possible_if_blocks++; if (dump_file) @@ -5474,11 +5476,11 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) if (! cheap_bb_rtx_cost_p (else_bb, else_prob, COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge->src), predictable_edge_p (else_edge))))) - return FALSE; + return false; /* Registers set are dead, or are predicable. */ - if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, 0)) - return FALSE; + if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, false)) + return false; /* Conversion went ok, including moving the insns and fixing up the jump. Adjust the CFG to match. */ @@ -5493,7 +5495,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) /* ??? We may now fallthru from one of THEN's successors into a join block. Rerun cleanup_cfg? Examine things manually? Wait? */ - return TRUE; + return true; } /* Used by the code above to perform the actual rtl transformations. @@ -5505,9 +5507,9 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) TEST_BB should be branching to its destination. REVERSEP is true if the sense of the branch should be reversed. */ -static int +static bool dead_or_predicable (basic_block test_bb, basic_block merge_bb, - basic_block other_bb, edge dest_edge, int reversep) + basic_block other_bb, edge dest_edge, bool reversep) { basic_block new_dest = dest_edge->dest; rtx_insn *head, *end, *jump; @@ -5532,7 +5534,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, that follows merge_bb being removed along with merge_bb and then we get an unresolved reference to the jumptable. */ if (tablejump_p (end, NULL, NULL)) - return FALSE; + return false; if (LABEL_P (head)) head = NEXT_INSN (head); @@ -5553,7 +5555,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, if (JUMP_P (end)) { if (!onlyjump_p (end)) - return FALSE; + return false; if (head == end) { head = end = NULL; @@ -5572,7 +5574,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, while (1) { if (INSN_P (insn) && RTX_FRAME_RELATED_P (insn)) - return FALSE; + return false; if (insn == end) break; insn = NEXT_INSN (insn); @@ -5610,13 +5612,13 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, { enum rtx_code rev = reversed_comparison_code (cond, jump); if (rev == UNKNOWN) - return FALSE; + return false; cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0), XEXP (cond, 1)); prob_val = prob_val.invert (); } - if (cond_exec_process_insns (NULL, head, end, cond, prob_val, 0) + if (cond_exec_process_insns (NULL, head, end, cond, prob_val, false) && verify_changes (0)) n_validated_changes = num_validated_changes (); else @@ -5646,12 +5648,12 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, that any registers modified are dead at the branch site. */ if (!any_condjump_p (jump)) - return FALSE; + return false; /* Find the extent of the conditional. */ cond = noce_get_condition (jump, &earliest, false); if (!cond) - return FALSE; + return false; live = BITMAP_ALLOC (®_obstack); simulate_backwards_to_point (merge_bb, live, end); @@ -5660,7 +5662,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, df_get_live_in (other_bb), NULL); BITMAP_FREE (live); if (!success) - return FALSE; + return false; /* Collect the set of registers set in MERGE_BB. */ merge_set = BITMAP_ALLOC (®_obstack); @@ -5717,7 +5719,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, { BITMAP_FREE (return_regs); BITMAP_FREE (merge_set); - return FALSE; + return false; } } BITMAP_FREE (return_regs); @@ -5816,7 +5818,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, At minimum, the merge will get done just before bb-reorder. */ } - return TRUE; + return true; cancel: cancel_changes (0); @@ -5824,7 +5826,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, if (merge_set) BITMAP_FREE (merge_set); - return FALSE; + return false; } /* Main entry point for all if-conversion. AFTER_COMBINE is true if @@ -5869,7 +5871,7 @@ if_convert (bool after_combine) df_analyze (); /* Only need to do dce on the first pass. */ df_clear_flags (DF_LR_RUN_DCE); - cond_exec_changed_p = FALSE; + cond_exec_changed_p = false; pass++; #ifdef IFCVT_MULTIPLE_DUMPS @@ -5933,7 +5935,7 @@ if_convert (bool after_combine) } /* If-conversion and CFG cleanup. */ -static unsigned int +static void rest_of_handle_if_conversion (void) { int flags = 0; @@ -5953,7 +5955,6 @@ rest_of_handle_if_conversion (void) } cleanup_cfg (flags); - return 0; } namespace { @@ -5986,7 +5987,8 @@ public: unsigned int execute (function *) final override { - return rest_of_handle_if_conversion (); + rest_of_handle_if_conversion (); + return 0; } }; // class pass_rtl_ifcvt -- cgit v1.1 From 5a13caf2666bdf586272cc24a08ab90499771c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Thu, 6 Jul 2023 08:16:39 +0200 Subject: riscv: thead: Fix failing XTheadCondMov tests (indirect-rv[32|64]) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recently, two identical XTheadCondMov tests have been added, which both fail. Let's fix that by changing the following: * Merge both files into one (no need for separate tests for rv32 and rv64) * Drop unrelated attribute check test (we already test for `th.mveqz` and `th.mvnez` instructions, so there is little additional value) * Fix the pattern to allow matching Fixes: a1806f0918c0 ("RISC-V: Optimize TARGET_XTHEADCONDMOV") gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadcondmov-indirect-rv32.c: Moved to... * gcc.target/riscv/xtheadcondmov-indirect.c: ...here. * gcc.target/riscv/xtheadcondmov-indirect-rv64.c: Removed. Signed-off-by: Christoph Müllner --- .../gcc.target/riscv/xtheadcondmov-indirect-rv32.c | 104 ------------------ .../gcc.target/riscv/xtheadcondmov-indirect-rv64.c | 104 ------------------ .../gcc.target/riscv/xtheadcondmov-indirect.c | 118 +++++++++++++++++++++ 3 files changed, 118 insertions(+), 208 deletions(-) delete mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c delete mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c deleted file mode 100644 index d0df59c..0000000 --- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c +++ /dev/null @@ -1,104 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv32gc_xtheadcondmov -mabi=ilp32 -mriscv-attribute" } */ -/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */ -/* { dg-final { check-function-bodies "**" "" } } */ - -/* -**ConEmv_imm_imm_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** li\t\s*[a-x0-9]+,10+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_imm_imm_reg(int x, int y){ - if (x == 1000) return 10; - return y; -} - -/* -**ConEmv_imm_reg_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_imm_reg_reg(int x, int y, int z){ - if (x == 1000) return y; - return z; -} - -/* -**ConEmv_reg_imm_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** li\t\s*[a-x0-9]+,10+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_reg_imm_reg(int x, int y, int z){ - if (x == y) return 10; - return z; -} - -/* -**ConEmv_reg_reg_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_reg_reg_reg(int x, int y, int z, int n){ - if (x == y) return z; - return n; -} - -/* -**ConNmv_imm_imm_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** li\t\s*[a-x0-9]+,9998336+ -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,1664+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_imm_imm_reg(int x, int y){ - if (x != 1000) return 10000000; - return y; -} - -/* -**ConNmv_imm_reg_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_imm_reg_reg(int x, int y, int z){ - if (x != 1000) return y; - return z; -} - -/* -**ConNmv_reg_imm_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** li\t\s*[a-x0-9]+,10+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_reg_imm_reg(int x, int y, int z){ - if (x != y) return 10; - return z; -} - -/* -**ConNmv_reg_reg_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_reg_reg_reg(int x, int y, int z, int n){ - if (x != y) return z; - return n; -} - - -/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_xtheadcondmov1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c deleted file mode 100644 index cc971a7..0000000 --- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c +++ /dev/null @@ -1,104 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -march=rv64gc_xtheadcondmov -mabi=lp64d -mriscv-attribute" } */ -/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */ -/* { dg-final { check-function-bodies "**" "" } } */ - -/* -**ConEmv_imm_imm_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** li\t\s*[a-x0-9]+,10+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_imm_imm_reg(int x, int y){ - if (x == 1000) return 10; - return y; -} - -/* -**ConEmv_imm_reg_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_imm_reg_reg(int x, int y, int z){ - if (x == 1000) return y; - return z; -} - -/* -**ConEmv_reg_imm_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** li\t\s*[a-x0-9]+,10+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_reg_imm_reg(int x, int y, int z){ - if (x == y) return 10; - return z; -} - -/* -**ConEmv_reg_reg_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConEmv_reg_reg_reg(int x, int y, int z, int n){ - if (x == y) return z; - return n; -} - -/* -**ConNmv_imm_imm_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** li\t\s*[a-x0-9]+,9998336+ -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,1664+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_imm_imm_reg(int x, int y){ - if (x != 1000) return 10000000; - return y; -} - -/* -**ConNmv_imm_reg_reg: -** addi\t\s*[a-x0-9]+,\s*[a-x0-9]+,-1000+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_imm_reg_reg(int x, int y, int z){ - if (x != 1000) return y; - return z; -} - -/* -**ConNmv_reg_imm_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** li\t\s*[a-x0-9]+,10+ -** th.mveqz\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_reg_imm_reg(int x, int y, int z){ - if (x != y) return 10; - return z; -} - -/* -**ConNmv_reg_reg_reg: -** sub\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** th.mvnez\t\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+ -** mv\t\s*[a-x0-9]+,\s*[a-x0-9]+ -** ret -*/ -int ConNmv_reg_reg_reg(int x, int y, int z, int n){ - if (x != y) return z; - return n; -} - - -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_xtheadcondmov1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c new file mode 100644 index 0000000..8292999 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c @@ -0,0 +1,118 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os" "-Og" "-Oz" "-flto" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +/* +** ConEmv_imm_imm_reg: +** addi a[0-9]+,a[0-9]+,-1000 +** li a[0-9]+,10 +** th\.mvnez a[0-9]+,a[0-9]+,a[0-9]+ +** ret +*/ +int ConEmv_imm_imm_reg(int x, int y) +{ + if (x == 1000) + return 10; + return y; +} + +/* +** ConEmv_imm_reg_reg: +** addi a[0-9]+,a[0-9]+,-1000 +** th.mveqz a[0-9]+,a[0-9]+,a[0-9]+ +** mv a[0-9]+,a[0-9]+ +** ret +*/ +int ConEmv_imm_reg_reg(int x, int y, int z) +{ + if (x == 1000) + return y; + return z; +} + +/* +** ConEmv_reg_imm_reg: +** sub a[0-9]+,a[0-9]+,a[0-9]+ +** li a[0-9]+,10 +** th.mvnez a[0-9]+,a[0-9]+,a[0-9]+ +** ret +*/ +int ConEmv_reg_imm_reg(int x, int y, int z) +{ + if (x == y) + return 10; + return z; +} + +/* +** ConEmv_reg_reg_reg: +** sub a[0-9]+,a[0-9]+,a[0-9]+ +** th.mveqz a[0-9]+,a[0-9]+,a[0-9]+ +** mv a[0-9]+,a[0-9]+ +** ret +*/ +int ConEmv_reg_reg_reg(int x, int y, int z, int n) +{ + if (x == y) + return z; + return n; +} + +/* +** ConNmv_imm_imm_reg: +** addi a[0-9]+,a[0-9]+,-1000+ +** li a[0-9]+,9998336+ +** addi a[0-9]+,a[0-9]+,1664+ +** th.mveqz a[0-9]+,a[0-9]+,a[0-9]+ +** ret +*/ +int ConNmv_imm_imm_reg(int x, int y) +{ + if (x != 1000) + return 10000000; + return y; +} + +/* +**ConNmv_imm_reg_reg: +** addi a[0-9]+,a[0-9]+,-1000+ +** th.mvnez a[0-9]+,a[0-9]+,a[0-9]+ +** mv a[0-9]+,a[0-9]+ +** ret +*/ +int ConNmv_imm_reg_reg(int x, int y, int z) +{ + if (x != 1000) + return y; + return z; +} + +/* +**ConNmv_reg_imm_reg: +** sub a[0-9]+,a[0-9]+,a[0-9]+ +** li a[0-9]+,10+ +** th.mveqz a[0-9]+,a[0-9]+,a[0-9]+ +** ret +*/ +int ConNmv_reg_imm_reg(int x, int y, int z) +{ + if (x != y) + return 10; + return z; +} + +/* +**ConNmv_reg_reg_reg: +** sub a[0-9]+,a[0-9]+,a[0-9]+ +** th.mvnez a[0-9]+,a[0-9]+,a[0-9]+ +** mv a[0-9]+,a[0-9]+ +** ret +*/ +int ConNmv_reg_reg_reg(int x, int y, int z, int n) +{ + if (x != y) + return z; + return n; +} -- cgit v1.1 From 14b10ff30ad58265c5acd495c3b0e56563571b0c Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 12 Jul 2023 17:22:03 +0200 Subject: Improve profile update in loop-ch Improve profile update in loop-ch to handle situation where duplicated header has loop invariant test. In this case we konw that all count of the exit edge belongs to the duplicated loop header edge and can update probabilities accordingly. Since we also do all the work to track this information from analysis to duplicaiton I also added code to turn those conditionals to constants so we do not need later jump threading pass to clean up. This made me to work out that the propagation was buggy in few aspects 1) it handled every PHI as PHI in header and incorrectly assigned some PHIs to be IV-like when they are not 2) it did not check for novops calls that are not required to return same value on every invocation. 3) I also added check for asm statement since those are not necessarily reproducible either. I would like to do more changes, but tried to prevent this patch from snowballing. The analysis of what statements will remain after duplication can be improved. I think we should use ranger query for other than first basic block, too and possibly drop the IV heuristics then. Also it seems that a lot of this logic is pretty much same to analysis in peeling pass, so unifying this would be nice. I also think I should move the profile update out of gimple_duplicate_sese_region (it is now very specific to ch) and rename it, since those regions are singe entry multiple exit. Bootstrapped/regtsted x86_64-linux, OK? Honza gcc/ChangeLog: * tree-cfg.cc (gimple_duplicate_sese_region): Add ORIG_ELIMINATED_EDGES parameter and rewrite profile updating code to handle edges elimination. * tree-cfg.h (gimple_duplicate_sese_region): Update prototpe. * tree-ssa-loop-ch.cc (loop_invariant_op_p): New function. (loop_iv_derived_p): New function. (should_duplicate_loop_header_p): Track invariant exit edges; fix handling of PHIs and propagation of IV derived variables. (ch_base::copy_headers): Pass around the invariant edges hash set. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/loop-ch-profile-1.c: Remove xfail. --- gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c | 2 +- gcc/tree-cfg.cc | 131 ++++++++++++++-------- gcc/tree-cfg.h | 3 +- gcc/tree-ssa-loop-ch.cc | 118 ++++++++++++++----- 4 files changed, 174 insertions(+), 80 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c index 1634086..bfb0f17 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-ch-profile-1.c @@ -9,4 +9,4 @@ void test(int v, int q) /* { dg-final { scan-tree-dump-not "Invalid sum" "ch2"} } */ /* dom2 optimizes out the redundant test for loop invariant v/q which leads to inconsistent profile. */ -/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized" { xfail *-*-* }} } */ +/* { dg-final { scan-tree-dump-not "Invalid sum" "optimized" } } */ diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 938d063..7dad7b4 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -6663,14 +6663,16 @@ add_phi_args_after_copy (basic_block *region_copy, unsigned n_region, true otherwise. ELIMINATED_EDGE is an edge that is known to be removed in the dupicated - region. */ + region. ORIG_ELIMINATED_EDGES, if non-NULL is set of edges known to be + removed from the original region. */ bool gimple_duplicate_sese_region (edge entry, edge exit, basic_block *region, unsigned n_region, basic_block *region_copy, bool update_dominance, - edge eliminated_edge) + edge eliminated_edge, + hash_set *orig_eliminated_edges) { unsigned i; bool free_region_copy = false, copying_header = false; @@ -6749,7 +6751,8 @@ gimple_duplicate_sese_region (edge entry, edge exit, split_edge_bb_loc (entry), update_dominance); if (total_count.initialized_p () && entry_count.initialized_p ()) { - if (!eliminated_edge) + if (!eliminated_edge + && (!orig_eliminated_edges || orig_eliminated_edges->is_empty ())) { scale_bbs_frequencies_profile_count (region, n_region, total_count - entry_count, @@ -6767,7 +6770,7 @@ gimple_duplicate_sese_region (edge entry, edge exit, if (cond1) <- this condition will become false and we update probabilities goto loop_exit; - if (cond2) + if (cond2) <- this condition is loop invariant goto loop_exit; goto loop_header <- this will be redirected to loop. // region_copy_end @@ -6778,6 +6781,7 @@ gimple_duplicate_sese_region (edge entry, edge exit, if (cond1) <- we need to update probabbility here goto loop_exit; if (cond2) <- and determine scaling factor here. + moreover cond2 is now always true goto loop_exit; else goto loop; @@ -6787,53 +6791,84 @@ gimple_duplicate_sese_region (edge entry, edge exit, but only consumer so far is tree-ssa-loop-ch and it uses only this to handle the common case of peeling headers which have conditionals known to be always true upon entry. */ - gcc_assert (eliminated_edge->src == region[0] - && EDGE_COUNT (region[0]->succs) == 2 - && copying_header); - - edge e, e_copy, eliminated_edge_copy; - if (EDGE_SUCC (region[0], 0) == eliminated_edge) - { - e = EDGE_SUCC (region[0], 1); - e_copy = EDGE_SUCC (region_copy[0], 1); - eliminated_edge_copy = EDGE_SUCC (region_copy[0], 0); - } - else + gcc_checking_assert (copying_header); + for (unsigned int i = 0; i < n_region; i++) { - e = EDGE_SUCC (region[0], 0); - e_copy = EDGE_SUCC (region_copy[0], 0); - eliminated_edge_copy = EDGE_SUCC (region_copy[0], 1); - } - gcc_checking_assert (e != e_copy - && eliminated_edge_copy != eliminated_edge - && eliminated_edge_copy->dest - == eliminated_edge->dest); - + edge exit_e, exit_e_copy, e, e_copy; + if (EDGE_COUNT (region[i]->succs) == 1) + { + region_copy[i]->count = entry_count; + region[i]->count -= entry_count; + continue; + } - /* Handle first basic block in duplicated region as in the - non-eliminating case. */ - scale_bbs_frequencies_profile_count (region_copy, n_region, - entry_count, total_count); - /* Now update redirecting eliminated edge to the other edge. - Actual CFG update is done by caller. */ - e_copy->probability = profile_probability::always (); - eliminated_edge_copy->probability = profile_probability::never (); - /* Header copying is a special case of jump threading, so use - common code to update loop body exit condition. */ - update_bb_profile_for_threading (region[0], e_copy->count (), e); - /* If we duplicated more conditionals first scale the profile of - rest of the preheader. Then work out the probability of - entering the loop and scale rest of the loop. */ - if (n_region > 1) - { - scale_bbs_frequencies_profile_count (region_copy + 1, - n_region - 1, - e_copy->count (), - region_copy[1]->count); - scale_bbs_frequencies_profile_count (region + 1, n_region - 1, - e->count (), - region[1]->count); + gcc_checking_assert (EDGE_COUNT (region[i]->succs) == 2); + if (loop_exit_edge_p (region[0]->loop_father, + EDGE_SUCC (region[i], 0))) + { + exit_e = EDGE_SUCC (region[i], 0); + exit_e_copy = EDGE_SUCC (region_copy[i], 0); + e = EDGE_SUCC (region[i], 1); + e_copy = EDGE_SUCC (region_copy[i], 1); + } + else + { + exit_e = EDGE_SUCC (region[i], 1); + exit_e_copy = EDGE_SUCC (region_copy[i], 1); + e = EDGE_SUCC (region[i], 0); + e_copy = EDGE_SUCC (region_copy[i], 0); + } + gcc_assert (i == n_region - 1 + || (e->dest == region[i + 1] + && e_copy->dest == region_copy[i + 1])); + region_copy[i]->count = entry_count; + profile_count exit_e_count = exit_e->count (); + if (eliminated_edge == exit_e) + { + /* Update profile and the conditional. + CFG update is done by caller. */ + e_copy->probability = profile_probability::always (); + exit_e_copy->probability = profile_probability::never (); + gcond *cond_stmt + = as_a (*gsi_last_bb (region_copy[i])); + if (e_copy->flags & EDGE_TRUE_VALUE) + gimple_cond_make_true (cond_stmt); + else + gimple_cond_make_false (cond_stmt); + update_stmt (cond_stmt); + /* Header copying is a special case of jump threading, so use + common code to update loop body exit condition. */ + update_bb_profile_for_threading (region[i], entry_count, e); + eliminated_edge = NULL; + } + else + region[i]->count -= region_copy[i]->count; + if (orig_eliminated_edges->contains (exit_e)) + { + orig_eliminated_edges->remove (exit_e); + /* All exits will happen in exit_e_copy which is out of the + loop, so increase probability accordingly. + If the edge is eliminated_edge we already corrected + profile above. */ + if (entry_count.nonzero_p () && eliminated_edge != exit_e) + set_edge_probability_and_rescale_others + (exit_e_copy, exit_e_count.probability_in + (entry_count)); + /* Eliminate in-loop conditional. */ + e->probability = profile_probability::always (); + exit_e->probability = profile_probability::never (); + gcond *cond_stmt = as_a (*gsi_last_bb (region[i])); + if (e->flags & EDGE_TRUE_VALUE) + gimple_cond_make_true (cond_stmt); + else + gimple_cond_make_false (cond_stmt); + update_stmt (cond_stmt); + } + entry_count = e_copy->count (); } + /* Be sure that we seen all edges we are supposed to update. */ + gcc_checking_assert (!eliminated_edge + && orig_eliminated_edges->is_empty ()); } } diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h index b9ccd58..a7cc37f 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -70,7 +70,8 @@ extern void add_phi_args_after_copy_bb (basic_block); extern void add_phi_args_after_copy (basic_block *, unsigned, edge); extern basic_block split_edge_bb_loc (edge); extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned, - basic_block *, bool, edge); + basic_block *, bool, edge, + hash_set *); extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned, basic_block *); extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit, diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 72792ce..cae6266 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -97,13 +97,42 @@ static_loop_exit (class loop *l, gimple_ranger *ranger) return r == desired_static_range ? ret_e : NULL; } +/* Return true if OP is invariant. */ + +static bool +loop_invariant_op_p (class loop *loop, + tree op) +{ + if (is_gimple_min_invariant (op)) + return true; + if (SSA_NAME_IS_DEFAULT_DEF (op) + || !flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (op)))) + return true; + return gimple_uid (SSA_NAME_DEF_STMT (op)) & 2; +} + +/* Return true if OP looks like it is derived from IV. */ + +static bool +loop_iv_derived_p (class loop *loop, + tree op) +{ + /* Always check for invariant first. */ + gcc_checking_assert (!is_gimple_min_invariant (op) + && !SSA_NAME_IS_DEFAULT_DEF (op) + && flow_bb_inside_loop_p (loop, + gimple_bb (SSA_NAME_DEF_STMT (op)))); + return gimple_uid (SSA_NAME_DEF_STMT (op)) & 1; +} + /* Check whether we should duplicate HEADER of LOOP. At most *LIMIT instructions should be duplicated, limit is decreased by the actual amount. */ static bool should_duplicate_loop_header_p (basic_block header, class loop *loop, - int *limit) + int *limit, + hash_set *invariant_exits) { gimple_stmt_iterator bsi; @@ -152,15 +181,20 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, for (gphi_iterator psi = gsi_start_phis (header); !gsi_end_p (psi); gsi_next (&psi)) - { - gphi *phi = psi.phi (); - tree res = gimple_phi_result (phi); - if (INTEGRAL_TYPE_P (TREE_TYPE (res)) - || POINTER_TYPE_P (TREE_TYPE (res))) - gimple_set_uid (phi, 1 /* IV */); - else - gimple_set_uid (phi, 0); - } + /* If this is actual loop header PHIs indicate that the SSA_NAME + may be IV. Otherwise just give up. */ + if (header == loop->header) + { + gphi *phi = psi.phi (); + tree res = gimple_phi_result (phi); + if (INTEGRAL_TYPE_P (TREE_TYPE (res)) + || POINTER_TYPE_P (TREE_TYPE (res))) + gimple_set_uid (phi, 1 /* IV */); + else + gimple_set_uid (phi, 0); + } + else + gimple_set_uid (psi.phi (), 0); /* Count number of instructions and punt on calls. Populate stmts INV/IV flag to later apply heuristics to the @@ -201,21 +235,26 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, /* Classify the stmt based on whether its computation is based on a IV or whether it is invariant in the loop. */ gimple_set_uid (last, 0); - if (!gimple_vuse (last)) + if (!gimple_vuse (last) + && gimple_code (last) != GIMPLE_ASM + && (gimple_code (last) != GIMPLE_CALL + || gimple_call_flags (last) & ECF_CONST)) { bool inv = true; - bool iv = false; + bool iv = true; ssa_op_iter i; tree op; FOR_EACH_SSA_TREE_OPERAND (op, last, i, SSA_OP_USE) - if (!SSA_NAME_IS_DEFAULT_DEF (op) - && flow_bb_inside_loop_p (loop, - gimple_bb (SSA_NAME_DEF_STMT (op)))) + if (!loop_invariant_op_p (loop, op)) { - if (!(gimple_uid (SSA_NAME_DEF_STMT (op)) & 2 /* INV */)) + if (!loop_iv_derived_p (loop, op)) + { + inv = false; + iv = false; + break; + } + else inv = false; - if (gimple_uid (SSA_NAME_DEF_STMT (op)) & 1 /* IV */) - iv = true; } gimple_set_uid (last, (iv ? 1 : 0) | (inv ? 2 : 0)); } @@ -225,16 +264,32 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, the loop further. Unless this is the original loop header. */ tree lhs = gimple_cond_lhs (last); tree rhs = gimple_cond_rhs (last); + bool lhs_invariant = loop_invariant_op_p (loop, lhs); + bool rhs_invariant = loop_invariant_op_p (loop, rhs); + if (lhs_invariant && rhs_invariant) + { + if (invariant_exits) + { + edge e; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, header->succs) + if (loop_exit_edge_p (loop, e)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Will elliminate invariant exit %i->%i\n", + e->src->index, e->dest->index); + invariant_exits->add (e); + } + } + return true; + } + /* TODO: This is heuristics that claims that IV based ocnditionals will + likely be optimized out in duplicated header. We could use ranger + query instead to tell this more precisely. */ if (header != loop->header - && ((TREE_CODE (lhs) == SSA_NAME - && !SSA_NAME_IS_DEFAULT_DEF (lhs) - && flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (lhs))) - && gimple_uid (SSA_NAME_DEF_STMT (lhs)) == 0) - || (TREE_CODE (rhs) == SSA_NAME - && !SSA_NAME_IS_DEFAULT_DEF (rhs) - && flow_bb_inside_loop_p (loop, - gimple_bb (SSA_NAME_DEF_STMT (rhs))) - && gimple_uid (SSA_NAME_DEF_STMT (rhs)) == 0))) + && ((!lhs_invariant && !loop_iv_derived_p (loop, lhs)) + || (!rhs_invariant && !loop_iv_derived_p (loop, rhs)))) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, @@ -452,7 +507,7 @@ ch_base::copy_headers (function *fun) continue; } - if (should_duplicate_loop_header_p (header, loop, &remaining_limit)) + if (should_duplicate_loop_header_p (header, loop, &remaining_limit, NULL)) candidates.safe_push ({loop, static_exit}); } /* Do not use ranger after we change the IL and not have updated SSA. */ @@ -482,10 +537,12 @@ ch_base::copy_headers (function *fun) profile_count entry_count = profile_count::zero (); edge e; edge_iterator ei; + hash_set invariant_exits; FOR_EACH_EDGE (e, ei, loop->header->preds) if (e->src != loop->latch) entry_count += e->count (); - while (should_duplicate_loop_header_p (header, loop, &remaining_limit)) + while (should_duplicate_loop_header_p (header, loop, &remaining_limit, + &invariant_exits)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Will duplicate bb %i\n", header->index); @@ -537,7 +594,8 @@ ch_base::copy_headers (function *fun) propagate_threaded_block_debug_into (exit->dest, entry->dest); if (!gimple_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs, - true, candidate.static_exit)) + true, candidate.static_exit, + &invariant_exits)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Duplication failed.\n"); -- cgit v1.1 From 602e824eec30a7c6792b8b27d61c40f1c1a2714c Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 29 Jun 2023 11:27:49 +0200 Subject: [range-op] Enable value/mask propagation in range-op. Throw the switch in range-ops to make full use of the value/mask information instead of only the nonzero bits. This will cause most of the operators implemented in range-ops to use the value/mask information calculated by CCP's bit_value_binop() function which range-ops uses. This opens up more optimization opportunities. In follow-up patches I will change the global range setter (set_range_info) to be able to save the value/mask pair, and make both CCP and IPA be able to save the known ones bit info, instead of throwing it away. gcc/ChangeLog: * range-op.cc (irange_to_masked_value): Remove. (update_known_bitmask): Update irange value/mask pair instead of only updating nonzero bits. gcc/testsuite/ChangeLog: * gcc.dg/pr83073.c: Adjust testcase. --- gcc/range-op.cc | 53 ++++++++++++++++++------------------------ gcc/testsuite/gcc.dg/pr83073.c | 2 +- 2 files changed, 23 insertions(+), 32 deletions(-) (limited to 'gcc') diff --git a/gcc/range-op.cc b/gcc/range-op.cc index cb58431..56e80c9 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -367,23 +367,6 @@ range_op_handler::op1_op2_relation (const vrange &lhs) const } -// Convert irange bitmasks into a VALUE MASK pair suitable for calling CCP. - -static void -irange_to_masked_value (const irange &r, widest_int &value, widest_int &mask) -{ - if (r.singleton_p ()) - { - mask = 0; - value = widest_int::from (r.lower_bound (), TYPE_SIGN (r.type ())); - } - else - { - mask = widest_int::from (r.get_nonzero_bits (), TYPE_SIGN (r.type ())); - value = 0; - } -} - // Update the known bitmasks in R when applying the operation CODE to // LH and RH. @@ -391,25 +374,33 @@ void update_known_bitmask (irange &r, tree_code code, const irange &lh, const irange &rh) { - if (r.undefined_p () || lh.undefined_p () || rh.undefined_p ()) + if (r.undefined_p () || lh.undefined_p () || rh.undefined_p () + || r.singleton_p ()) return; - widest_int value, mask, lh_mask, rh_mask, lh_value, rh_value; + widest_int widest_value, widest_mask; tree type = r.type (); signop sign = TYPE_SIGN (type); int prec = TYPE_PRECISION (type); - signop lh_sign = TYPE_SIGN (lh.type ()); - signop rh_sign = TYPE_SIGN (rh.type ()); - int lh_prec = TYPE_PRECISION (lh.type ()); - int rh_prec = TYPE_PRECISION (rh.type ()); - - irange_to_masked_value (lh, lh_value, lh_mask); - irange_to_masked_value (rh, rh_value, rh_mask); - bit_value_binop (code, sign, prec, &value, &mask, - lh_sign, lh_prec, lh_value, lh_mask, - rh_sign, rh_prec, rh_value, rh_mask); - wide_int tmp = wide_int::from (value | mask, prec, sign); - r.set_nonzero_bits (tmp); + irange_bitmask lh_bits = lh.get_bitmask (); + irange_bitmask rh_bits = rh.get_bitmask (); + + bit_value_binop (code, sign, prec, &widest_value, &widest_mask, + TYPE_SIGN (lh.type ()), + TYPE_PRECISION (lh.type ()), + widest_int::from (lh_bits.value (), sign), + widest_int::from (lh_bits.mask (), sign), + TYPE_SIGN (rh.type ()), + TYPE_PRECISION (rh.type ()), + widest_int::from (rh_bits.value (), sign), + widest_int::from (rh_bits.mask (), sign)); + + wide_int mask = wide_int::from (widest_mask, prec, sign); + wide_int value = wide_int::from (widest_value, prec, sign); + // Bitmasks must have the unknown value bits cleared. + value &= ~mask; + irange_bitmask bm (value, mask); + r.update_bitmask (bm); } // Return the upper limit for a type. diff --git a/gcc/testsuite/gcc.dg/pr83073.c b/gcc/testsuite/gcc.dg/pr83073.c index 1168ae82..228e189 100644 --- a/gcc/testsuite/gcc.dg/pr83073.c +++ b/gcc/testsuite/gcc.dg/pr83073.c @@ -7,4 +7,4 @@ int f(int x) return x & 1; } -/* { dg-final { scan-tree-dump "gimple_simplified to.* = 1" "evrp" } } */ +/* { dg-final { scan-tree-dump "Folded into: return 1;" "evrp" } } */ -- cgit v1.1 From 519b29c9e53d110d165059faa8a300c74450235a Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 12 Jul 2023 21:09:05 +0200 Subject: IRA+LRA: Change return type of predicate functions from int to bool gcc/ChangeLog: * ira.cc (equiv_init_varies_p): Change return type from int to bool and adjust function body accordingly. (equiv_init_movable_p): Ditto. (memref_used_between_p): Ditto. * lra-constraints.cc (valid_address_p): Ditto. --- gcc/ira.cc | 42 +++++++++++++++++++++--------------------- gcc/lra-constraints.cc | 10 +++++----- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'gcc') diff --git a/gcc/ira.cc b/gcc/ira.cc index 02dea5d..a186010 100644 --- a/gcc/ira.cc +++ b/gcc/ira.cc @@ -3075,7 +3075,7 @@ validate_equiv_mem_from_store (rtx dest, const_rtx set ATTRIBUTE_UNUSED, info->equiv_mem_modified = true; } -static int equiv_init_varies_p (rtx x); +static bool equiv_init_varies_p (rtx x); enum valid_equiv { valid_none, valid_combine, valid_reload }; @@ -3145,8 +3145,8 @@ validate_equiv_mem (rtx_insn *start, rtx reg, rtx memref) return valid_none; } -/* Returns zero if X is known to be invariant. */ -static int +/* Returns false if X is known to be invariant. */ +static bool equiv_init_varies_p (rtx x) { RTX_CODE code = GET_CODE (x); @@ -3162,14 +3162,14 @@ equiv_init_varies_p (rtx x) CASE_CONST_ANY: case SYMBOL_REF: case LABEL_REF: - return 0; + return false; case REG: return reg_equiv[REGNO (x)].replace == 0 && rtx_varies_p (x, 0); case ASM_OPERANDS: if (MEM_VOLATILE_P (x)) - return 1; + return true; /* Fall through. */ @@ -3182,24 +3182,24 @@ equiv_init_varies_p (rtx x) if (fmt[i] == 'e') { if (equiv_init_varies_p (XEXP (x, i))) - return 1; + return true; } else if (fmt[i] == 'E') { int j; for (j = 0; j < XVECLEN (x, i); j++) if (equiv_init_varies_p (XVECEXP (x, i, j))) - return 1; + return true; } - return 0; + return false; } -/* Returns nonzero if X (used to initialize register REGNO) is movable. +/* Returns true if X (used to initialize register REGNO) is movable. X is only movable if the registers it uses have equivalent initializations which appear to be within the same loop (or in an inner loop) and movable or if they are not candidates for local_alloc and don't vary. */ -static int +static bool equiv_init_movable_p (rtx x, int regno) { int i, j; @@ -3212,7 +3212,7 @@ equiv_init_movable_p (rtx x, int regno) return equiv_init_movable_p (SET_SRC (x), regno); case CLOBBER: - return 0; + return false; case PRE_INC: case PRE_DEC: @@ -3220,7 +3220,7 @@ equiv_init_movable_p (rtx x, int regno) case POST_DEC: case PRE_MODIFY: case POST_MODIFY: - return 0; + return false; case REG: return ((reg_equiv[REGNO (x)].loop_depth >= reg_equiv[regno].loop_depth @@ -3229,11 +3229,11 @@ equiv_init_movable_p (rtx x, int regno) && ! rtx_varies_p (x, 0))); case UNSPEC_VOLATILE: - return 0; + return false; case ASM_OPERANDS: if (MEM_VOLATILE_P (x)) - return 0; + return false; /* Fall through. */ @@ -3247,16 +3247,16 @@ equiv_init_movable_p (rtx x, int regno) { case 'e': if (! equiv_init_movable_p (XEXP (x, i), regno)) - return 0; + return false; break; case 'E': for (j = XVECLEN (x, i) - 1; j >= 0; j--) if (! equiv_init_movable_p (XVECEXP (x, i, j), regno)) - return 0; + return false; break; } - return 1; + return true; } static bool memref_referenced_p (rtx memref, rtx x, bool read_p); @@ -3370,7 +3370,7 @@ memref_referenced_p (rtx memref, rtx x, bool read_p) Callers should not call this routine if START is after END in the RTL chain. */ -static int +static bool memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end) { rtx_insn *insn; @@ -3383,15 +3383,15 @@ memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end) continue; if (memref_referenced_p (memref, PATTERN (insn), false)) - return 1; + return true; /* Nonconst functions may access memory. */ if (CALL_P (insn) && (! RTL_CONST_CALL_P (insn))) - return 1; + return true; } gcc_assert (insn == NEXT_INSN (end)); - return 0; + return false; } /* Mark REG as having no known equivalence. diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 123ff66..9bfc881 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -329,20 +329,20 @@ in_mem_p (int regno) return get_reg_class (regno) == NO_REGS; } -/* Return 1 if ADDR is a valid memory address for mode MODE in address +/* Return true if ADDR is a valid memory address for mode MODE in address space AS, and check that each pseudo has the proper kind of hard reg. */ -static int +static bool valid_address_p (machine_mode mode ATTRIBUTE_UNUSED, rtx addr, addr_space_t as) { #ifdef GO_IF_LEGITIMATE_ADDRESS lra_assert (ADDR_SPACE_GENERIC_P (as)); GO_IF_LEGITIMATE_ADDRESS (mode, addr, win); - return 0; + return false; win: - return 1; + return true; #else return targetm.addr_space.legitimate_address_p (mode, addr, 0, as); #endif @@ -1624,7 +1624,7 @@ insert_move_for_subreg (rtx_insn **before, rtx_insn **after, rtx origreg, } } -static int valid_address_p (machine_mode mode, rtx addr, addr_space_t as); +static bool valid_address_p (machine_mode mode, rtx addr, addr_space_t as); static bool process_address (int, bool, rtx_insn **, rtx_insn **); /* Make reloads for subreg in operand NOP with internal subreg mode -- cgit v1.1 From 137fb7077f7711e2e09ee8f82650fe7d93de6a4d Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Fri, 30 Jun 2023 20:40:02 +0200 Subject: [range-op] Take known set bits into account in popcount [PR107053] This patch teaches popcount about known set bits which are now available in the irange. PR tree-optimization/107053 gcc/ChangeLog: * gimple-range-op.cc (cfn_popcount): Use known set bits. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107053.c: New test. --- gcc/gimple-range-op.cc | 11 +++++++---- gcc/testsuite/gcc.dg/tree-ssa/pr107053.c | 13 +++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107053.c (limited to 'gcc') diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index 72c7b86..67b3c3d 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -880,17 +880,20 @@ public: if (lh.undefined_p ()) return false; unsigned prec = TYPE_PRECISION (type); - wide_int nz = lh.get_nonzero_bits (); - wide_int pop = wi::shwi (wi::popcount (nz), prec); + irange_bitmask bm = lh.get_bitmask (); + wide_int nz = bm.get_nonzero_bits (); + wide_int high = wi::shwi (wi::popcount (nz), prec); // Calculating the popcount of a singleton is trivial. if (lh.singleton_p ()) { - r.set (type, pop, pop); + r.set (type, high, high); return true; } if (cfn_ffs::fold_range (r, type, lh, rh, rel)) { - int_range<2> tmp (type, wi::zero (prec), pop); + wide_int known_ones = ~bm.mask () & bm.value (); + wide_int low = wi::shwi (wi::popcount (known_ones), prec); + int_range<2> tmp (type, low, high); r.intersect (tmp); return true; } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107053.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107053.c new file mode 100644 index 0000000..8195d0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107053.c @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-evrp" } + +void link_failure(); +void f(int a) +{ + a |= 0x300; + int b = __builtin_popcount(a); + if (b < 2) + link_failure(); +} + +// { dg-final { scan-tree-dump-not "link_failure" "evrp" } } -- cgit v1.1 From 7a5e47658904de9dc90f1292f3f69769177706f9 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 6 Jul 2023 10:55:46 +0200 Subject: [range-op] Take known mask into account for bitwise ands [PR107043] PR tree-optimization/107043 gcc/ChangeLog: * range-op.cc (operator_bitwise_and::op1_range): Update bitmask. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107043.c: New test. --- gcc/range-op.cc | 8 ++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr107043.c | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107043.c (limited to 'gcc') diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 56e80c9..6b5d4f2 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -3463,6 +3463,14 @@ operator_bitwise_and::op1_range (irange &r, tree type, if (r.undefined_p ()) set_nonzero_range_from_mask (r, type, lhs); + // For MASK == op1 & MASK, all the bits in MASK must be set in op1. + wide_int mask; + if (lhs == op2 && lhs.singleton_p (mask)) + { + r.update_bitmask (irange_bitmask (mask, ~mask)); + return true; + } + // For 0 = op1 & MASK, op1 is ~MASK. if (lhs.zero_p () && op2.singleton_p ()) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107043.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107043.c new file mode 100644 index 0000000..af5df22 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107043.c @@ -0,0 +1,22 @@ +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-evrp" } + +int g0(int n) +{ + int n1 = n & 0x8000; + if (n1 == 0) + return 1; + // n1 will be 0x8000 here. + return (n1 >> 15) & 0x1; +} + +int g1(int n) +{ + int n1 = n & 0x8000; + if (n1 == 0) + return 1; + // n>>15 will be xxxxxx1 here. + return (n >> 15) & 0x1; +} + +// { dg-final { scan-tree-dump-times "return 1;" 2 "evrp" } } -- cgit v1.1 From 7df810d0d5745af756081824aaa347a2e69d2ead Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 13 Jul 2023 01:29:17 +0200 Subject: Break out profile updating code from gimple_duplicate_sese_region Move profile updating to tree-ssa-loop-ch.cc since it is now quite ch specific. There are no functional changes. Boostrapped/regtesed x86_64-linux, comitted. gcc/ChangeLog: * tree-cfg.cc (gimple_duplicate_sese_region): Rename to ... (gimple_duplicate_seme_region): ... this; break out profile updating code to ... * tree-ssa-loop-ch.cc (update_profile_after_ch): ... here. (ch_base::copy_headers): Update. * tree-cfg.h (gimple_duplicate_sese_region): Rename to ... (gimple_duplicate_seme_region): ... this. --- gcc/tree-cfg.cc | 148 ++---------------------------------------------- gcc/tree-cfg.h | 5 +- gcc/tree-ssa-loop-ch.cc | 131 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 150 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 7dad7b4..7ccc2a5 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -6662,25 +6662,19 @@ add_phi_args_after_copy (basic_block *region_copy, unsigned n_region, The function returns false if it is unable to copy the region, true otherwise. - ELIMINATED_EDGE is an edge that is known to be removed in the dupicated - region. ORIG_ELIMINATED_EDGES, if non-NULL is set of edges known to be - removed from the original region. */ + It is callers responsibility to update profile. */ bool -gimple_duplicate_sese_region (edge entry, edge exit, +gimple_duplicate_seme_region (edge entry, edge exit, basic_block *region, unsigned n_region, basic_block *region_copy, - bool update_dominance, - edge eliminated_edge, - hash_set *orig_eliminated_edges) + bool update_dominance) { unsigned i; bool free_region_copy = false, copying_header = false; class loop *loop = entry->dest->loop_father; edge exit_copy; edge redirected; - profile_count total_count = profile_count::uninitialized (); - profile_count entry_count = profile_count::uninitialized (); if (!can_copy_bbs_p (region, n_region)) return false; @@ -6733,144 +6727,10 @@ gimple_duplicate_sese_region (edge entry, edge exit, inside. */ auto_vec doms; if (update_dominance) - { - doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region); - } - - if (entry->dest->count.initialized_p ()) - { - total_count = entry->dest->count; - entry_count = entry->count (); - /* Fix up corner cases, to avoid division by zero or creation of negative - frequencies. */ - if (entry_count > total_count) - entry_count = total_count; - } + doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region); copy_bbs (region, n_region, region_copy, &exit, 1, &exit_copy, loop, split_edge_bb_loc (entry), update_dominance); - if (total_count.initialized_p () && entry_count.initialized_p ()) - { - if (!eliminated_edge - && (!orig_eliminated_edges || orig_eliminated_edges->is_empty ())) - { - scale_bbs_frequencies_profile_count (region, n_region, - total_count - entry_count, - total_count); - scale_bbs_frequencies_profile_count (region_copy, n_region, - entry_count, total_count); - } - else - { - /* We only support only case where eliminated_edge is one and it - exists first BB. We also assume that the duplicated region is - acyclic. So we expect the following: - - // region_copy_start entry will be scaled to entry_count - if (cond1) <- this condition will become false - and we update probabilities - goto loop_exit; - if (cond2) <- this condition is loop invariant - goto loop_exit; - goto loop_header <- this will be redirected to loop. - // region_copy_end - loop: - - // region start - loop_header: - if (cond1) <- we need to update probabbility here - goto loop_exit; - if (cond2) <- and determine scaling factor here. - moreover cond2 is now always true - goto loop_exit; - else - goto loop; - // region end - - Adding support for more exits can be done similarly, - but only consumer so far is tree-ssa-loop-ch and it uses only this - to handle the common case of peeling headers which have - conditionals known to be always true upon entry. */ - gcc_checking_assert (copying_header); - for (unsigned int i = 0; i < n_region; i++) - { - edge exit_e, exit_e_copy, e, e_copy; - if (EDGE_COUNT (region[i]->succs) == 1) - { - region_copy[i]->count = entry_count; - region[i]->count -= entry_count; - continue; - } - - gcc_checking_assert (EDGE_COUNT (region[i]->succs) == 2); - if (loop_exit_edge_p (region[0]->loop_father, - EDGE_SUCC (region[i], 0))) - { - exit_e = EDGE_SUCC (region[i], 0); - exit_e_copy = EDGE_SUCC (region_copy[i], 0); - e = EDGE_SUCC (region[i], 1); - e_copy = EDGE_SUCC (region_copy[i], 1); - } - else - { - exit_e = EDGE_SUCC (region[i], 1); - exit_e_copy = EDGE_SUCC (region_copy[i], 1); - e = EDGE_SUCC (region[i], 0); - e_copy = EDGE_SUCC (region_copy[i], 0); - } - gcc_assert (i == n_region - 1 - || (e->dest == region[i + 1] - && e_copy->dest == region_copy[i + 1])); - region_copy[i]->count = entry_count; - profile_count exit_e_count = exit_e->count (); - if (eliminated_edge == exit_e) - { - /* Update profile and the conditional. - CFG update is done by caller. */ - e_copy->probability = profile_probability::always (); - exit_e_copy->probability = profile_probability::never (); - gcond *cond_stmt - = as_a (*gsi_last_bb (region_copy[i])); - if (e_copy->flags & EDGE_TRUE_VALUE) - gimple_cond_make_true (cond_stmt); - else - gimple_cond_make_false (cond_stmt); - update_stmt (cond_stmt); - /* Header copying is a special case of jump threading, so use - common code to update loop body exit condition. */ - update_bb_profile_for_threading (region[i], entry_count, e); - eliminated_edge = NULL; - } - else - region[i]->count -= region_copy[i]->count; - if (orig_eliminated_edges->contains (exit_e)) - { - orig_eliminated_edges->remove (exit_e); - /* All exits will happen in exit_e_copy which is out of the - loop, so increase probability accordingly. - If the edge is eliminated_edge we already corrected - profile above. */ - if (entry_count.nonzero_p () && eliminated_edge != exit_e) - set_edge_probability_and_rescale_others - (exit_e_copy, exit_e_count.probability_in - (entry_count)); - /* Eliminate in-loop conditional. */ - e->probability = profile_probability::always (); - exit_e->probability = profile_probability::never (); - gcond *cond_stmt = as_a (*gsi_last_bb (region[i])); - if (e->flags & EDGE_TRUE_VALUE) - gimple_cond_make_true (cond_stmt); - else - gimple_cond_make_false (cond_stmt); - update_stmt (cond_stmt); - } - entry_count = e_copy->count (); - } - /* Be sure that we seen all edges we are supposed to update. */ - gcc_checking_assert (!eliminated_edge - && orig_eliminated_edges->is_empty ()); - } - } if (copying_header) { diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h index a7cc37f..89f0650 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -69,9 +69,8 @@ extern tree gimple_block_label (basic_block); extern void add_phi_args_after_copy_bb (basic_block); extern void add_phi_args_after_copy (basic_block *, unsigned, edge); extern basic_block split_edge_bb_loc (edge); -extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned, - basic_block *, bool, edge, - hash_set *); +extern bool gimple_duplicate_seme_region (edge, edge, basic_block *, unsigned, + basic_block *, bool); extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned, basic_block *); extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit, diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index cae6266..24e7fbc 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -347,6 +347,128 @@ do_while_loop_p (class loop *loop) return true; } +/* Update profile after header copying of LOOP. + REGION is the original (in loop) sequence, REGION_COPY is the + duplicated header (now outside of loop). N_REGION is number of + bbs duplicated. + ELIMINATED_EDGE is edge to be removed from duplicated sequence. + INVARIANT_EXITS are edges in the loop body to be elimianted + since they are loop invariants + + So We expect the following: + + // region_copy_start entry will be scaled to entry_count + if (cond1) <- this condition will become false + and we update probabilities + goto loop_exit; + if (cond2) <- this condition is loop invariant + goto loop_exit; + goto loop_header <- this will be redirected to loop. + // region_copy_end + loop: + + // region start + loop_header: + if (cond1) <- we need to update probabbility here + goto loop_exit; + if (cond2) <- and determine scaling factor here. + moreover cond2 is now always true + goto loop_exit; + else + goto loop; + // region end + + Adding support for more exits can be done similarly, + but only consumer so far is tree-ssa-loop-ch and it uses only this + to handle the common case of peeling headers which have + conditionals known to be always true upon entry. */ + +static void +update_profile_after_ch (class loop *loop, + basic_block *region, basic_block *region_copy, + unsigned n_region, edge eliminated_edge, + hash_set *invariant_exits, + profile_count entry_count) +{ + for (unsigned int i = 0; i < n_region; i++) + { + edge exit_e, exit_e_copy, e, e_copy; + if (EDGE_COUNT (region[i]->succs) == 1) + { + region_copy[i]->count = entry_count; + region[i]->count -= entry_count; + continue; + } + + gcc_checking_assert (EDGE_COUNT (region[i]->succs) == 2); + if (loop_exit_edge_p (loop, + EDGE_SUCC (region[i], 0))) + { + exit_e = EDGE_SUCC (region[i], 0); + exit_e_copy = EDGE_SUCC (region_copy[i], 0); + e = EDGE_SUCC (region[i], 1); + e_copy = EDGE_SUCC (region_copy[i], 1); + } + else + { + exit_e = EDGE_SUCC (region[i], 1); + exit_e_copy = EDGE_SUCC (region_copy[i], 1); + e = EDGE_SUCC (region[i], 0); + e_copy = EDGE_SUCC (region_copy[i], 0); + } + gcc_assert (i == n_region - 1 + || (e->dest == region[i + 1] + && e_copy->dest == region_copy[i + 1])); + region_copy[i]->count = entry_count; + profile_count exit_e_count = exit_e->count (); + if (eliminated_edge == exit_e) + { + /* Update profile and the conditional. + CFG update is done by caller. */ + e_copy->probability = profile_probability::always (); + exit_e_copy->probability = profile_probability::never (); + gcond *cond_stmt + = as_a (*gsi_last_bb (region_copy[i])); + if (e_copy->flags & EDGE_TRUE_VALUE) + gimple_cond_make_true (cond_stmt); + else + gimple_cond_make_false (cond_stmt); + update_stmt (cond_stmt); + /* Header copying is a special case of jump threading, so use + common code to update loop body exit condition. */ + update_bb_profile_for_threading (region[i], entry_count, e); + eliminated_edge = NULL; + } + else + region[i]->count -= region_copy[i]->count; + if (invariant_exits->contains (exit_e)) + { + invariant_exits->remove (exit_e); + /* All exits will happen in exit_e_copy which is out of the + loop, so increase probability accordingly. + If the edge is eliminated_edge we already corrected + profile above. */ + if (entry_count.nonzero_p () && eliminated_edge != exit_e) + set_edge_probability_and_rescale_others + (exit_e_copy, exit_e_count.probability_in + (entry_count)); + /* Eliminate in-loop conditional. */ + e->probability = profile_probability::always (); + exit_e->probability = profile_probability::never (); + gcond *cond_stmt = as_a (*gsi_last_bb (region[i])); + if (e->flags & EDGE_TRUE_VALUE) + gimple_cond_make_true (cond_stmt); + else + gimple_cond_make_false (cond_stmt); + update_stmt (cond_stmt); + } + entry_count = e_copy->count (); + } + /* Be sure that we seen all edges we are supposed to update. */ + gcc_checking_assert (!eliminated_edge + && invariant_exits->is_empty ()); +} + namespace { /* Common superclass for both header-copying phases. */ @@ -593,14 +715,17 @@ ch_base::copy_headers (function *fun) entry = loop_preheader_edge (loop); propagate_threaded_block_debug_into (exit->dest, entry->dest); - if (!gimple_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs, - true, candidate.static_exit, - &invariant_exits)) + if (!gimple_duplicate_seme_region (entry, exit, bbs, n_bbs, copied_bbs, + true)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Duplication failed.\n"); continue; } + if (loop->header->count.initialized_p ()) + update_profile_after_ch (loop, bbs, copied_bbs, n_bbs, + candidate.static_exit, &invariant_exits, + entry_count); copied.safe_push (std::make_pair (entry, loop)); /* If the loop has the form "for (i = j; i < j + 10; i++)" then -- cgit v1.1 From 44f244e4672578be6cc513104473981790a1c164 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Wed, 12 Jul 2023 23:24:38 +0800 Subject: RISC-V: Support COND_LEN_* patterns This middle-end has been merged: https://github.com/gcc-mirror/gcc/commit/0d4dd7e07a879d6c07a33edb2799710faa95651e With this patch, we can handle operations may trap on elements outside the loop. These 2 following cases will be addressed by this patch: 1. integer division: #define TEST_TYPE(TYPE) \ __attribute__((noipa)) \ void vrem_##TYPE (TYPE * __restrict dst, TYPE * __restrict a, TYPE * __restrict b, int n) \ { \ for (int i = 0; i < n; i++) \ dst[i] = a[i] % b[i]; \ } #define TEST_ALL() \ TEST_TYPE(int8_t) \ TEST_ALL() Before this patch: vrem_int8_t: ble a3,zero,.L14 csrr t4,vlenb addiw a5,a3,-1 addiw a4,t4,-1 sext.w t5,a3 bltu a5,a4,.L10 csrr t3,vlenb subw t3,t5,t3 li a5,0 vsetvli t6,zero,e8,m1,ta,ma .L4: add a6,a2,a5 add a7,a0,a5 add t1,a1,a5 mv a4,a5 add a5,a5,t4 vl1re8.v v2,0(a6) vl1re8.v v1,0(t1) sext.w a6,a5 vrem.vv v1,v1,v2 vs1r.v v1,0(a7) bleu a6,t3,.L4 csrr a5,vlenb addw a4,a4,a5 sext.w a5,a4 beq t5,a4,.L16 .L3: csrr a6,vlenb subw t5,t5,a4 srli a6,a6,1 addiw t1,t5,-1 addiw a7,a6,-1 bltu t1,a7,.L9 slli a4,a4,32 srli a4,a4,32 add t0,a1,a4 add t6,a2,a4 add a4,a0,a4 vsetvli a7,zero,e8,mf2,ta,ma sext.w t3,a6 vle8.v v1,0(t0) vle8.v v2,0(t6) subw t4,t5,a6 vrem.vv v1,v1,v2 vse8.v v1,0(a4) mv t1,t3 bltu t4,t3,.L7 csrr t1,vlenb add a4,a4,a6 add t0,t0,a6 add t6,t6,a6 sext.w t1,t1 vle8.v v1,0(t0) vle8.v v2,0(t6) vrem.vv v1,v1,v2 vse8.v v1,0(a4) .L7: addw a5,t1,a5 beq t5,t1,.L14 .L9: add a4,a1,a5 add a6,a2,a5 lb a6,0(a6) lb a4,0(a4) add a7,a0,a5 addi a5,a5,1 remw a4,a4,a6 sext.w a6,a5 sb a4,0(a7) bgt a3,a6,.L9 .L14: ret .L10: li a4,0 li a5,0 j .L3 .L16: ret After this patch: vrem_int8_t: ble a3,zero,.L5 .L3: vsetvli a5,a3,e8,m1,tu,ma vle8.v v1,0(a1) vle8.v v2,0(a2) sub a3,a3,a5 vrem.vv v1,v1,v2 vse8.v v1,0(a0) add a1,a1,a5 add a2,a2,a5 add a0,a0,a5 bne a3,zero,.L3 .L5: ret 2. Floating-point operation **WITHOUT** -ffast-math: #define TEST_TYPE(TYPE) \ __attribute__((noipa)) \ void vadd_##TYPE (TYPE * __restrict dst, TYPE *__restrict a, TYPE *__restrict b, int n) \ { \ for (int i = 0; i < n; i++) \ dst[i] = a[i] + b[i]; \ } #define TEST_ALL() \ TEST_TYPE(float) \ TEST_ALL() Before this patch: vadd_float: ble a3,zero,.L10 csrr a4,vlenb srli t3,a4,2 addiw a5,a3,-1 addiw a6,t3,-1 sext.w t6,a3 bltu a5,a6,.L7 subw t5,t6,t3 mv t1,a1 mv a7,a2 mv a6,a0 li a5,0 vsetvli t4,zero,e32,m1,ta,ma .L4: vl1re32.v v1,0(t1) vl1re32.v v2,0(a7) addw a5,a5,t3 vfadd.vv v1,v1,v2 vs1r.v v1,0(a6) add t1,t1,a4 add a7,a7,a4 add a6,a6,a4 bgeu t5,a5,.L4 beq t6,a5,.L10 sext.w a5,a5 .L3: slli a4,a5,2 .L6: add a6,a1,a4 add a7,a2,a4 flw fa4,0(a6) flw fa5,0(a7) add a6,a0,a4 addiw a5,a5,1 fadd.s fa5,fa5,fa4 addi a4,a4,4 fsw fa5,0(a6) bgt a3,a5,.L6 .L10: ret .L7: li a5,0 j .L3 After this patch: vadd_float: ble a3,zero,.L5 .L3: vsetvli a5,a3,e32,m1,tu,ma slli a4,a5,2 vle32.v v1,0(a1) vle32.v v2,0(a2) sub a3,a3,a5 vfadd.vv v1,v1,v2 vse32.v v1,0(a0) add a1,a1,a4 add a2,a2,a4 add a0,a0,a4 bne a3,zero,.L3 .L5: ret gcc/ChangeLog: * config/riscv/autovec.md (cond_len_): New pattern. * config/riscv/riscv-protos.h (enum insn_type): New enum. (expand_cond_len_binop): New function. * config/riscv/riscv-v.cc (emit_nonvlmax_tu_insn): Ditto. (emit_nonvlmax_fp_tu_insn): Ditto. (need_fp_rounding_p): Ditto. (expand_cond_len_binop): Ditto. * config/riscv/riscv.cc (riscv_preferred_else_value): Ditto. (TARGET_PREFERRED_ELSE_VALUE): New target hook. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c: Adapt testcase. * gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c: Ditto. * gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c: Ditto. * gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c: Ditto. * gcc.target/riscv/rvv/autovec/binop/vadd-run-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vdiv-run-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vmul-run-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vsub-run-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c: New test. * gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c: New test. --- gcc/config/riscv/autovec.md | 67 ++++++++++++++++++ gcc/config/riscv/riscv-protos.h | 2 + gcc/config/riscv/riscv-v.cc | 79 ++++++++++++++++++++++ gcc/config/riscv/riscv.cc | 21 ++++++ .../riscv/rvv/autovec/binop/vadd-run-nofm.c | 4 ++ .../riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c | 13 ++++ .../riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c | 13 ++++ .../riscv/rvv/autovec/binop/vdiv-run-nofm.c | 4 ++ .../riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c | 12 ++++ .../riscv/rvv/autovec/binop/vdiv-rv32gcv.c | 11 ++- .../riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c | 12 ++++ .../riscv/rvv/autovec/binop/vdiv-rv64gcv.c | 11 ++- .../riscv/rvv/autovec/binop/vmul-run-nofm.c | 4 ++ .../riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c | 8 +++ .../riscv/rvv/autovec/binop/vmul-rv64gcv-nofm.c | 8 +++ .../riscv/rvv/autovec/binop/vrem-rv32gcv.c | 10 ++- .../riscv/rvv/autovec/binop/vrem-rv64gcv.c | 10 ++- .../riscv/rvv/autovec/binop/vsub-run-nofm.c | 4 ++ .../riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c | 14 ++++ .../riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c | 14 ++++ 20 files changed, 297 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index d98a63c..883ac47 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1208,3 +1208,70 @@ riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_BINOP, operands); DONE; }) + +;; ------------------------------------------------------------------------- +;; ---- [INT] Conditional binary operations +;; ------------------------------------------------------------------------- +;; Includes: +;; - vadd.vv/vsub.vv/... +;; - vadd.vi/vsub.vi/... +;; ------------------------------------------------------------------------- + +(define_expand "cond_len_" + [(match_operand:VI 0 "register_operand") + (match_operand: 1 "vector_mask_operand") + (any_int_binop_no_shift:VI + (match_operand:VI 2 "") + (match_operand:VI 3 "")) + (match_operand:VI 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_cond_len_binop (, operands); + DONE; +}) + +;; ------------------------------------------------------------------------- +;; ---- [FP] Conditional binary operations +;; ------------------------------------------------------------------------- +;; Includes: +;; - vfadd.vv/vfsub.vv/... +;; - vfadd.vf/vfsub.vf/... +;; ------------------------------------------------------------------------- + +(define_expand "cond_len_" + [(match_operand:VF 0 "register_operand") + (match_operand: 1 "vector_mask_operand") + (any_float_binop:VF + (match_operand:VF 2 "register_operand") + (match_operand:VF 3 "register_operand")) + (match_operand:VF 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_cond_len_binop (, operands); + DONE; +}) + +;; ------------------------------------------------------------------------- +;; Includes: +;; - vfmin.vv/vfmax.vv +;; - vfmin.vf/vfmax.vf +;; ------------------------------------------------------------------------- + +(define_expand "cond_len_" + [(match_operand:VF 0 "register_operand") + (match_operand: 1 "vector_mask_operand") + (any_float_binop_nofrm:VF + (match_operand:VF 2 "register_operand") + (match_operand:VF 3 "register_operand")) + (match_operand:VF 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_cond_len_binop (, operands); + DONE; +}) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 5ce0d47..b7b5395 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -184,6 +184,7 @@ enum insn_type RVV_UNOP = 2, RVV_BINOP = 3, RVV_BINOP_MU = RVV_BINOP + 2, + RVV_BINOP_TU = RVV_BINOP + 2, RVV_MERGE_OP = 4, RVV_CMP_OP = 4, RVV_CMP_MU_OP = RVV_CMP_OP + 2, /* +2 means mask and maskoff operand. */ @@ -276,6 +277,7 @@ bool neg_simm5_p (rtx); bool has_vi_variant_p (rtx_code, rtx); void expand_vec_cmp (rtx, rtx_code, rtx, rtx); bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); +void expand_cond_len_binop (rtx_code, rtx *); #endif bool sew64_scalar_helper (rtx *, rtx *, rtx, machine_mode, bool, void (*)(rtx *, rtx)); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 1a61f9a..9d3f588 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -919,6 +919,45 @@ emit_vlmax_masked_mu_insn (unsigned icode, int op_num, rtx *ops) e.emit_insn ((enum insn_code) icode, ops); } +/* This function emits a TU instruction. */ +static void +emit_nonvlmax_tu_insn (unsigned icode, int op_num, rtx *ops, rtx avl) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (dest_mode).require (); + insn_expander e (/*OP_NUM*/ op_num, + /*HAS_DEST_P*/ true, + /*FULLY_UNMASKED_P*/ false, + /*USE_REAL_MERGE_P*/ true, + /*HAS_AVL_P*/ true, + /*VLMAX_P*/ false, dest_mode, + mask_mode); + e.set_policy (TAIL_UNDISTURBED); + e.set_policy (MASK_ANY); + e.set_vl (avl); + e.emit_insn ((enum insn_code) icode, ops); +} + +/* This function emits a TU instruction. */ +static void +emit_nonvlmax_fp_tu_insn (unsigned icode, int op_num, rtx *ops, rtx avl) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (dest_mode).require (); + insn_expander e (/*OP_NUM*/ op_num, + /*HAS_DEST_P*/ true, + /*FULLY_UNMASKED_P*/ false, + /*USE_REAL_MERGE_P*/ true, + /*HAS_AVL_P*/ true, + /*VLMAX_P*/ false, dest_mode, + mask_mode); + e.set_policy (TAIL_UNDISTURBED); + e.set_policy (MASK_ANY); + e.set_rounding_mode (FRM_DYN); + e.set_vl (avl); + e.emit_insn ((enum insn_code) icode, ops); +} + /* Emit vmv.s.x instruction. */ void @@ -2968,4 +3007,44 @@ expand_load_store (rtx *ops, bool is_load) } } +/* Return true if the operation is the floating-point operation need FRM. */ +static bool +needs_fp_rounding (rtx_code code, machine_mode mode) +{ + if (!FLOAT_MODE_P (mode)) + return false; + return code != SMIN && code != SMAX; +} + +/* Expand COND_LEN_*. */ +void +expand_cond_len_binop (rtx_code code, rtx *ops) +{ + rtx dest = ops[0]; + rtx mask = ops[1]; + rtx src1 = ops[2]; + rtx src2 = ops[3]; + rtx merge = ops[4]; + rtx len = ops[5]; + machine_mode mode = GET_MODE (dest); + machine_mode mask_mode = GET_MODE (mask); + + poly_uint64 value; + bool is_dummy_mask = rtx_equal_p (mask, CONSTM1_RTX (mask_mode)); + + if (is_dummy_mask) + { + /* Use TU, MASK ANY policy. */ + rtx ops[] = {dest, mask, merge, src1, src2}; + insn_code icode = code_for_pred (code, mode); + if (needs_fp_rounding (code, mode)) + emit_nonvlmax_fp_tu_insn (icode, RVV_BINOP_MU, ops, len); + else + emit_nonvlmax_tu_insn (icode, RVV_BINOP_MU, ops, len); + } + else + /* FIXME: Enable this case when we support it in the middle-end. */ + gcc_unreachable (); +} + } // namespace riscv_vector diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index af18231..398194f 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7832,6 +7832,24 @@ riscv_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode, return false; } +/* Implement TARGET_PREFERRED_ELSE_VALUE. For binary operations, + prefer to use the first arithmetic operand as the else value if + the else value doesn't matter, since that exactly matches the RVV + destructive merging form. For ternary operations we could either + pick the first operand and use VMADD-like instructions or the last + operand and use VMACC-like instructions; the latter seems more + natural. + + TODO: Currently, the return value is not ideal for RVV since it will + let VSETVL PASS use MU or TU. We will suport undefine value that allows + VSETVL PASS use TA/MA in the future. */ + +static tree +riscv_preferred_else_value (unsigned, tree, unsigned int nops, tree *ops) +{ + return nops == 3 ? ops[2] : ops[0]; +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -8133,6 +8151,9 @@ riscv_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode, #undef TARGET_VECTORIZE_VEC_PERM_CONST #define TARGET_VECTORIZE_VEC_PERM_CONST riscv_vectorize_vec_perm_const +#undef TARGET_PREFERRED_ELSE_VALUE +#define TARGET_PREFERRED_ELSE_VALUE riscv_preferred_else_value + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-riscv.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run-nofm.c new file mode 100644 index 0000000..66ae116 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run-nofm.c @@ -0,0 +1,4 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */ + +#include "vadd-run.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c new file mode 100644 index 0000000..069bc69 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vadd-template.h" + +/* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */ +/* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */ +/* { dg-final { scan-assembler-times {\tvfadd\.vv} 7 } } */ +/* There are 2 MINUS operations. */ +/* { dg-final { scan-assembler-times {\tvfsub\.vv} 2 } } */ + +/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 7 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c new file mode 100644 index 0000000..07fa548 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vadd-template.h" + +/* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */ +/* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */ +/* { dg-final { scan-assembler-times {\tvfadd\.vv} 7 } } */ +/* There are 2 MINUS operations. */ +/* { dg-final { scan-assembler-times {\tvfsub\.vv} 2 } } */ + +/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 7 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run-nofm.c new file mode 100644 index 0000000..ed340b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run-nofm.c @@ -0,0 +1,4 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */ + +#include "vdiv-run.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c new file mode 100644 index 0000000..5ce2e57 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vdiv-template.h" + +/* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ + +/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 6 } } */ + +/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 6 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c index 604d9ac..9b984dd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c @@ -1,15 +1,14 @@ /* { dg-do compile } */ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math -fdump-tree-optimized-details" } */ #include "vdiv-template.h" -/* Currently we use an epilogue loop which also contains vdivs. Therefore we - expect 14 vdiv[u]s instead of 8. */ - -/* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */ +/* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ /* Division by constant is done by calculating a reciprocal and then multiplying. Hence we do not expect 6 vfdivs. */ /* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */ /* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */ + +/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c new file mode 100644 index 0000000..7b1aa28 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vdiv-template.h" + +/* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ + +/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 6 } } */ + +/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 6 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c index 2688403..ca4d23bb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c @@ -1,15 +1,14 @@ /* { dg-do compile } */ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math -fdump-tree-optimized-details" } */ #include "vdiv-template.h" -/* Currently we use an epilogue loop which also contains vdivs. Therefore we - expect 14 vdiv[u]s instead of 8. */ - -/* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */ +/* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ /* Division by constant is done by calculating a reciprocal and then multiplying. Hence we do not expect 6 vfdivs. */ /* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */ /* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */ + +/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run-nofm.c new file mode 100644 index 0000000..225030e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run-nofm.c @@ -0,0 +1,4 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */ + +#include "vmul-run.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c new file mode 100644 index 0000000..3e0f061 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vmul-template.h" + +/* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */ +/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 6 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv-nofm.c new file mode 100644 index 0000000..ca245e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv-nofm.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vmul-template.h" + +/* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */ +/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 6 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c index 86607d0..6d0493b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c @@ -1,9 +1,7 @@ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -fdump-tree-optimized-details" } */ #include "vrem-template.h" -/* Currently we use an epilogue loop which also contains vrems. Therefore we - expect 14 vrem[u]s instead of 8. */ - -/* { dg-final { scan-assembler-times {\tvrem\.vv} 14 } } */ -/* { dg-final { scan-assembler-times {\tvremu\.vv} 14 } } */ +/* { dg-final { scan-assembler-times {\tvrem\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvremu\.vv} 8 } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_MOD" 16 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c index b7bc1cc..24b2bc8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c @@ -1,10 +1,8 @@ /* { dg-do compile } */ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -fdump-tree-optimized-details" } */ #include "vrem-template.h" -/* Currently we use an epilogue loop which also contains vrems. Therefore we - expect 14 vrem[u]s instead of 8. */ - -/* { dg-final { scan-assembler-times {\tvrem\.vv} 14 } } */ -/* { dg-final { scan-assembler-times {\tvremu\.vv} 14 } } */ +/* { dg-final { scan-assembler-times {\tvrem\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvremu\.vv} 8 } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_MOD" 16 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run-nofm.c new file mode 100644 index 0000000..36a1706 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run-nofm.c @@ -0,0 +1,4 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */ + +#include "vsub-run.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c new file mode 100644 index 0000000..c4ab934 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vsub-template.h" + +/* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */ +/* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */ + +/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 12 "optimized" } } */ + +/* Do not expect vfrsub for now, because we do not properly + handle vop.vx and vfop.vf yet. */ +/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c new file mode 100644 index 0000000..9e71911 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "vsub-template.h" + +/* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */ +/* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */ + +/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */ +/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 12 "optimized" } } */ + +/* Do not expect vfrsub for now, because we do not properly + handle vop.vx and vfop.vf yet. */ +/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */ -- cgit v1.1 From 15939bae358e9f79f91c51d72c6095facdcbe4e3 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 13 Jul 2023 00:17:12 +0000 Subject: Daily bump. --- gcc/ChangeLog | 278 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/fortran/ChangeLog | 15 +++ gcc/testsuite/ChangeLog | 91 ++++++++++++++++ 4 files changed, 385 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 111302e..dfeefd1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,281 @@ +2023-07-12 Juzhe-Zhong + + * config/riscv/autovec.md (cond_len_): New pattern. + * config/riscv/riscv-protos.h (enum insn_type): New enum. + (expand_cond_len_binop): New function. + * config/riscv/riscv-v.cc (emit_nonvlmax_tu_insn): Ditto. + (emit_nonvlmax_fp_tu_insn): Ditto. + (need_fp_rounding_p): Ditto. + (expand_cond_len_binop): Ditto. + * config/riscv/riscv.cc (riscv_preferred_else_value): Ditto. + (TARGET_PREFERRED_ELSE_VALUE): New target hook. + +2023-07-12 Jan Hubicka + + * tree-cfg.cc (gimple_duplicate_sese_region): Rename to ... + (gimple_duplicate_seme_region): ... this; break out profile updating + code to ... + * tree-ssa-loop-ch.cc (update_profile_after_ch): ... here. + (ch_base::copy_headers): Update. + * tree-cfg.h (gimple_duplicate_sese_region): Rename to ... + (gimple_duplicate_seme_region): ... this. + +2023-07-12 Aldy Hernandez + + PR tree-optimization/107043 + * range-op.cc (operator_bitwise_and::op1_range): Update bitmask. + +2023-07-12 Aldy Hernandez + + PR tree-optimization/107053 + * gimple-range-op.cc (cfn_popcount): Use known set bits. + +2023-07-12 Uros Bizjak + + * ira.cc (equiv_init_varies_p): Change return type from int to bool + and adjust function body accordingly. + (equiv_init_movable_p): Ditto. + (memref_used_between_p): Ditto. + * lra-constraints.cc (valid_address_p): Ditto. + +2023-07-12 Aldy Hernandez + + * range-op.cc (irange_to_masked_value): Remove. + (update_known_bitmask): Update irange value/mask pair instead of + only updating nonzero bits. + +2023-07-12 Jan Hubicka + + * tree-cfg.cc (gimple_duplicate_sese_region): Add ORIG_ELIMINATED_EDGES + parameter and rewrite profile updating code to handle edges elimination. + * tree-cfg.h (gimple_duplicate_sese_region): Update prototpe. + * tree-ssa-loop-ch.cc (loop_invariant_op_p): New function. + (loop_iv_derived_p): New function. + (should_duplicate_loop_header_p): Track invariant exit edges; fix handling + of PHIs and propagation of IV derived variables. + (ch_base::copy_headers): Pass around the invariant edges hash set. + +2023-07-12 Uros Bizjak + + * ifcvt.cc (cond_exec_changed_p): Change variable to bool. + (last_active_insn): Change "skip_use_p" function argument to bool. + (noce_operand_ok): Change return type from int to bool. + (find_cond_trap): Ditto. + (block_jumps_and_fallthru_p): Change "fallthru_p" and + "jump_p" variables to bool. + (noce_find_if_block): Change return type from int to bool. + (cond_exec_find_if_block): Ditto. + (find_if_case_1): Ditto. + (find_if_case_2): Ditto. + (dead_or_predicable): Ditto. Change "reversep" function arg to bool. + (block_jumps_and_fallthru): Rename from block_jumps_and_fallthru_p. + (cond_exec_process_insns): Change return type from int to bool. + Change "mod_ok" function arg to bool. + (cond_exec_process_if_block): Change return type from int to bool. + Change "do_multiple_p" function arg to bool. Change "then_mod_ok" + variable to bool. + (noce_emit_store_flag): Change return type from int to bool. + Change "reversep" function arg to bool. Change "cond_complex" + variable to bool. + (noce_try_move): Change return type from int to bool. + (noce_try_ifelse_collapse): Ditto. + (noce_try_store_flag): Ditto. Change "reversep" variable to bool. + (noce_try_addcc): Change return type from int to bool. Change + "subtract" variable to bool. + (noce_try_store_flag_constants): Change return type from int to bool. + (noce_try_store_flag_mask): Ditto. Change "reversep" variable to bool. + (noce_try_cmove): Change return type from int to bool. + (noce_try_cmove_arith): Ditto. Change "is_mem" variable to bool. + (noce_try_minmax): Change return type from int to bool. Change + "unsignedp" variable to bool. + (noce_try_abs): Change return type from int to bool. Change + "negate" variable to bool. + (noce_try_sign_mask): Change return type from int to bool. + (noce_try_move): Ditto. + (noce_try_store_flag_constants): Ditto. + (noce_try_cmove): Ditto. + (noce_try_cmove_arith): Ditto. + (noce_try_minmax): Ditto. Change "unsignedp" variable to bool. + (noce_try_bitop): Change return type from int to bool. + (noce_operand_ok): Ditto. + (noce_convert_multiple_sets): Ditto. + (noce_convert_multiple_sets_1): Ditto. + (noce_process_if_block): Ditto. + (check_cond_move_block): Ditto. + (cond_move_process_if_block): Ditto. Change "success_p" + variable to bool. + (rest_of_handle_if_conversion): Change return type to void. + +2023-07-12 Ju-Zhe Zhong + + * internal-fn.cc (FOR_EACH_CODE_MAPPING): Adapt for COND_LEN_* support. + (CASE): Ditto. + (get_conditional_len_internal_fn): New function. + * internal-fn.h (get_conditional_len_internal_fn): Ditto. + * tree-vect-stmts.cc (vectorizable_operation): Adapt for COND_LEN_* + support. + +2023-07-12 Roger Sayle + + PR target/91681 + * config/i386/i386.md (*add3_doubleword_concat_zext): Typo. + +2023-07-12 Roger Sayle + + PR target/91681 + * config/i386/i386.md (*add3_doubleword_concat_zext): New + define_insn_and_split derived from *add3_doubleword_concat + and *add3_doubleword_zext. + +2023-07-12 Roger Sayle + + PR target/110598 + * config/i386/i386.md (peephole2): Check !reg_mentioned_p when + optimizing rega = 0; rega op= regb for op in [XOR,IOR,PLUS]. + (peephole2): Simplify rega = 0; rega op= rega cases. + +2023-07-12 Roger Sayle + + * config/i386/i386-expand.cc (ix86_expand_int_compare): If + testing a TImode SUBREG of a 128-bit vector register against + zero, use a PTEST instruction instead of first moving it to + a pair of scalar registers. + +2023-07-12 Robin Dapp + + * genopinit.cc (main): Adjust maximal number of optabs and + machine modes. + * gensupport.cc (find_optab): Shift optab by 20 and mode by + 10 bits. + * optabs-query.h (optab_handler): Ditto. + (convert_optab_handler): Ditto. + +2023-07-12 Richard Biener + + PR tree-optimization/110630 + * tree-vect-slp.cc (vect_add_slp_permutation): New + offset parameter, honor that for the extract code generation. + (vectorizable_slp_permutation_1): Handle offsetted identities. + +2023-07-12 Ju-Zhe Zhong + + * config/riscv/autovec.md (smul3_highpart): New pattern. + (umul3_highpart): Ditto. + +2023-07-12 Jan Beulich + + * config/i386/i386.md (extendbfsf2_1): Add new AVX512F + alternative. Adjust original last alternative's "prefix" + attribute to maybe_evex. + +2023-07-12 Jan Beulich + + * config/i386/sse.md (vec_dupv4sf): Make first alternative use + vbroadcastss for AVX2. New AVX512F alternative. + (*vec_dupv4si): New AVX2 and AVX512F alternatives using + vpbroadcastd. Replace sselog1 by sseshuf1 in "type" attribute. + +2023-07-12 Christoph Müllner + + * config/riscv/peephole.md: Remove XThead* peephole passes. + * config/riscv/thead.md: Include thead-peephole.md. + * config/riscv/thead-peephole.md: New file. + +2023-07-12 Christoph Müllner + + * config/riscv/riscv-protos.h (riscv_regno_ok_for_index_p): + New prototype. + (riscv_index_reg_class): Likewise. + * config/riscv/riscv.cc (riscv_regno_ok_for_index_p): New function. + (riscv_index_reg_class): New function. + * config/riscv/riscv.h (INDEX_REG_CLASS): Call new function + riscv_index_reg_class(). + (REGNO_OK_FOR_INDEX_P): Call new function + riscv_regno_ok_for_index_p(). + +2023-07-12 Christoph Müllner + + * config/riscv/riscv-protos.h (enum riscv_address_type): + New location of type definition. + (struct riscv_address_info): Likewise. + * config/riscv/riscv.cc (enum riscv_address_type): + Old location of type definition. + (struct riscv_address_info): Likewise. + +2023-07-12 Christoph Müllner + + * config/riscv/riscv.h (Xmode): New macro. + +2023-07-12 Christoph Müllner + + * config/riscv/riscv.cc (riscv_print_operand_address): Use + output_addr_const rather than riscv_print_operand. + +2023-07-12 Christoph Müllner + + * config/riscv/thead.md: Adjust constraints of th_addsl. + +2023-07-12 Christoph Müllner + + * config/riscv/thead.cc (th_mempair_operands_p): + Fix documentation of th_mempair_order_operands(). + +2023-07-12 Christoph Müllner + + * config/riscv/thead.cc (th_mempair_save_regs): + Emit REG_FRAME_RELATED_EXPR notes in prologue. + +2023-07-12 Christoph Müllner + + * config/riscv/riscv.md: No base-ISA extension splitter for XThead*. + * config/riscv/thead.md (*extend2_th_ext): + New XThead extension INSN. + (*zero_extendsidi2_th_extu): New XThead extension INSN. + (*zero_extendhi2_th_extu): New XThead extension INSN. + +2023-07-12 liuhongt + + PR target/110438 + PR target/110202 + * config/i386/predicates.md + (int_float_vector_all_ones_operand): New predicate. + * config/i386/sse.md (*vmov_constm1_pternlog_false_dep): New + define_insn. + (*_cvtmask2_pternlog_false_dep): + Ditto. + (*_cvtmask2_pternlog_false_dep): + Ditto. + (*_cvtmask2): Adjust to + define_insn_and_split to avoid false dependence. + (*_cvtmask2): Ditto. + (one_cmpl2): Adjust constraint + of operands 1 to '0' to avoid false dependence. + (*andnot3): Ditto. + (iornot3): Ditto. + (*3): Ditto. + +2023-07-12 Mo, Zewei + + * common/config/i386/cpuinfo.h + (get_intel_cpu): Handle Granite Rapids D. + * common/config/i386/i386-common.cc: + (processor_alias_table): Add graniterapids-d. + * common/config/i386/i386-cpuinfo.h + (enum processor_subtypes): Add INTEL_COREI7_GRANITERAPIDS_D. + * config.gcc: Add -march=graniterapids-d. + * config/i386/driver-i386.cc (host_detect_local_cpu): + Handle graniterapids-d. + * config/i386/i386.h: (PTA_GRANITERAPIDS_D): New. + * doc/extend.texi: Add graniterapids-d. + * doc/invoke.texi: Ditto. + +2023-07-12 Haochen Jiang + + * config/i386/i386-builtins.cc (ix86_init_mmx_sse_builtins): + Add OPTION_MASK_ISA_AVX512VL. + * config/i386/i386-expand.cc (ix86_check_builtin_isa_match): + Ditto. + 2023-07-11 Ju-Zhe Zhong * config/riscv/riscv-protos.h (enum insn_type): Add vcompress optimization. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index b130bea..da7e217 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230712 +20230713 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index bc4ad57..82e5a96 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,18 @@ +2023-07-12 Andre Vehreschild + + PR fortran/102003 + * expr.cc (find_inquiry_ref): Replace len of pdt_string by + constant. + (simplify_ref_chain): Ensure input to find_inquiry_ref is + NULL. + (gfc_match_init_expr): Prevent PDT analysis for function calls. + (gfc_pdt_find_component_copy_initializer): Get the initializer + value for given component. + * gfortran.h (gfc_pdt_find_component_copy_initializer): New + function. + * simplify.cc (gfc_simplify_len): Replace len() of PDT with pdt + component ref or constant. + 2023-07-11 Harald Anlauf PR fortran/110288 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5c0e05b..b72c1f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,94 @@ +2023-07-12 Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c: Adapt testcase. + * gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c: Ditto. + * gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c: Ditto. + * gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c: Ditto. + * gcc.target/riscv/rvv/autovec/binop/vadd-run-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vdiv-run-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vmul-run-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vsub-run-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c: New test. + * gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c: New test. + +2023-07-12 Aldy Hernandez + + PR tree-optimization/107043 + * gcc.dg/tree-ssa/pr107043.c: New test. + +2023-07-12 Aldy Hernandez + + PR tree-optimization/107053 + * gcc.dg/tree-ssa/pr107053.c: New test. + +2023-07-12 Aldy Hernandez + + * gcc.dg/pr83073.c: Adjust testcase. + +2023-07-12 Jan Hubicka + + * gcc.dg/tree-ssa/loop-ch-profile-1.c: Remove xfail. + +2023-07-12 Christoph Müllner + + * gcc.target/riscv/xtheadcondmov-indirect-rv32.c: Moved to... + * gcc.target/riscv/xtheadcondmov-indirect.c: ...here. + * gcc.target/riscv/xtheadcondmov-indirect-rv64.c: Removed. + +2023-07-12 Roger Sayle + + PR target/110598 + * gcc.target/i386/pr110598.c: New test case. + +2023-07-12 Andre Vehreschild + + * gfortran.dg/pdt_33.f03: New test. + +2023-07-12 Richard Biener + + PR tree-optimization/110630 + * gcc.dg/vect/bb-slp-pr95839.c: Make stricter. + * gcc.dg/vect/bb-slp-pr95839-3.c: New variant testcase. + +2023-07-12 Ju-Zhe Zhong + + * gcc.target/riscv/rvv/autovec/binop/mulh-1.c: New test. + * gcc.target/riscv/rvv/autovec/binop/mulh-2.c: New test. + * gcc.target/riscv/rvv/autovec/binop/mulh_run-1.c: New test. + * gcc.target/riscv/rvv/autovec/binop/mulh_run-2.c: New test. + +2023-07-12 Jan Beulich + + * gcc.target/i386/avx2-dupv4sf.c: New test. + * gcc.target/i386/avx2-dupv4si.c: Likewise. + * gcc.target/i386/avx512f-dupv4sf.c: Likewise. + * gcc.target/i386/avx512f-dupv4si.c: Likewise. + +2023-07-12 Christoph Müllner + + * gcc.target/riscv/xtheadbb-ext-1.c: New test. + * gcc.target/riscv/xtheadbb-extu-1.c: New test. + +2023-07-12 liuhongt + + * gcc.target/i386/pr110438.c: New test. + * gcc.target/i386/pr100711-6.c: Adjust testcase. + +2023-07-12 Mo, Zewei + + * g++.target/i386/mv16.C: Add graniterapids-d. + * gcc.target/i386/funcspec-56.inc: Handle new march. + +2023-07-12 Haochen Jiang + + * gcc.target/i386/avx512vl-vaes-1.c: New test. + 2023-07-11 Ju-Zhe Zhong * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c: New test. -- cgit v1.1 From f048af2aa3dccec4d28c32056a1d5972f4049806 Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Wed, 12 Jul 2023 17:38:49 +0800 Subject: RISC-V: RISC-V: Support gather_load/scatter RVV auto-vectorization This patch fully support gather_load/scatter_store: 1. Support single-rgroup on both RV32/RV64. 2. Support indexed element width can be same as or smaller than Pmode. 3. Support VLA SLP with gather/scatter. 4. Fully tested all gather/scatter with LMUL = M1/M2/M4/M8 both VLA and VLS. 5. Fix bug of handling (subreg:SI (const_poly_int:DI)) 6. Fix bug on vec_perm which is used by gather/scatter SLP. All kinds of GATHER/SCATTER are normalized into LEN_MASK_*. We fully supported these 4 kinds of gather/scatter: 1. LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE with dummy length and dummy mask (Full vector). 2. LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE with dummy length and real mask. 3. LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE with real length and dummy mask. 4. LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE with real length and real mask. Base on the disscussions with Richards, we don't lower vlse/vsse in RISC-V backend for strided load/store. Instead, we leave it to the middle-end to handle that. Regression is pass ok for trunk ? gcc/ChangeLog: * config/riscv/autovec.md (len_mask_gather_load): New pattern. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. * config/riscv/predicates.md (const_1_operand): New predicate. (vector_gs_scale_operand_16): Ditto. (vector_gs_scale_operand_32): Ditto. (vector_gs_scale_operand_64): Ditto. (vector_gs_extension_operand): Ditto. (vector_gs_scale_operand_16_rv32): Ditto. (vector_gs_scale_operand_32_rv32): Ditto. * config/riscv/riscv-protos.h (enum insn_type): Add gather/scatter. (expand_gather_scatter): New function. * config/riscv/riscv-v.cc (gen_const_vector_dup): Add gather/scatter. (emit_vlmax_masked_store_insn): New function. (emit_nonvlmax_masked_store_insn): Ditto. (modulo_sel_indices): Ditto. (expand_vec_perm): Fix SLP for gather/scatter. (prepare_gather_scatter): New function. (expand_gather_scatter): Ditto. * config/riscv/riscv.cc (riscv_legitimize_move): Fix bug of (subreg:SI (DI CONST_POLY_INT)). * config/riscv/vector-iterators.md: Add gather/scatter. * config/riscv/vector.md (vec_duplicate): Use "@" instead. (@vec_duplicate): Ditto. (@pred_indexed_store): Fix name. (@pred_indexed_store): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/rvv.exp: Add gather/scatter tests. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-1.c: New test. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-2.c: New test. --- gcc/config/riscv/autovec.md | 256 ++++++++++++++++++ gcc/config/riscv/predicates.md | 33 ++- gcc/config/riscv/riscv-protos.h | 3 + gcc/config/riscv/riscv-v.cc | 286 ++++++++++++++++++--- gcc/config/riscv/riscv.cc | 11 +- gcc/config/riscv/vector-iterators.md | 118 +++++++-- gcc/config/riscv/vector.md | 30 ++- .../rvv/autovec/gather-scatter/gather_load-1.c | 38 +++ .../rvv/autovec/gather-scatter/gather_load-10.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load-11.c | 32 +++ .../rvv/autovec/gather-scatter/gather_load-12.c | 112 ++++++++ .../rvv/autovec/gather-scatter/gather_load-2.c | 38 +++ .../rvv/autovec/gather-scatter/gather_load-3.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load-4.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load-5.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load-6.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load-7.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load-8.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load-9.c | 35 +++ .../rvv/autovec/gather-scatter/gather_load_run-1.c | 41 +++ .../autovec/gather-scatter/gather_load_run-10.c | 41 +++ .../autovec/gather-scatter/gather_load_run-11.c | 39 +++ .../autovec/gather-scatter/gather_load_run-12.c | 124 +++++++++ .../rvv/autovec/gather-scatter/gather_load_run-2.c | 41 +++ .../rvv/autovec/gather-scatter/gather_load_run-3.c | 41 +++ .../rvv/autovec/gather-scatter/gather_load_run-4.c | 41 +++ .../rvv/autovec/gather-scatter/gather_load_run-5.c | 41 +++ .../rvv/autovec/gather-scatter/gather_load_run-6.c | 41 +++ .../rvv/autovec/gather-scatter/gather_load_run-7.c | 41 +++ .../rvv/autovec/gather-scatter/gather_load_run-8.c | 41 +++ .../rvv/autovec/gather-scatter/gather_load_run-9.c | 41 +++ .../autovec/gather-scatter/mask_gather_load-1.c | 39 +++ .../autovec/gather-scatter/mask_gather_load-10.c | 36 +++ .../autovec/gather-scatter/mask_gather_load-11.c | 116 +++++++++ .../autovec/gather-scatter/mask_gather_load-2.c | 39 +++ .../autovec/gather-scatter/mask_gather_load-3.c | 36 +++ .../autovec/gather-scatter/mask_gather_load-4.c | 36 +++ .../autovec/gather-scatter/mask_gather_load-5.c | 36 +++ .../autovec/gather-scatter/mask_gather_load-6.c | 36 +++ .../autovec/gather-scatter/mask_gather_load-7.c | 36 +++ .../autovec/gather-scatter/mask_gather_load-8.c | 36 +++ .../autovec/gather-scatter/mask_gather_load-9.c | 36 +++ .../gather-scatter/mask_gather_load_run-1.c | 48 ++++ .../gather-scatter/mask_gather_load_run-10.c | 48 ++++ .../gather-scatter/mask_gather_load_run-11.c | 140 ++++++++++ .../gather-scatter/mask_gather_load_run-2.c | 48 ++++ .../gather-scatter/mask_gather_load_run-3.c | 48 ++++ .../gather-scatter/mask_gather_load_run-4.c | 48 ++++ .../gather-scatter/mask_gather_load_run-5.c | 48 ++++ .../gather-scatter/mask_gather_load_run-6.c | 48 ++++ .../gather-scatter/mask_gather_load_run-7.c | 48 ++++ .../gather-scatter/mask_gather_load_run-8.c | 48 ++++ .../gather-scatter/mask_gather_load_run-9.c | 48 ++++ .../autovec/gather-scatter/mask_scatter_store-1.c | 39 +++ .../autovec/gather-scatter/mask_scatter_store-10.c | 36 +++ .../autovec/gather-scatter/mask_scatter_store-2.c | 39 +++ .../autovec/gather-scatter/mask_scatter_store-3.c | 36 +++ .../autovec/gather-scatter/mask_scatter_store-4.c | 36 +++ .../autovec/gather-scatter/mask_scatter_store-5.c | 36 +++ .../autovec/gather-scatter/mask_scatter_store-6.c | 36 +++ .../autovec/gather-scatter/mask_scatter_store-7.c | 36 +++ .../autovec/gather-scatter/mask_scatter_store-8.c | 36 +++ .../autovec/gather-scatter/mask_scatter_store-9.c | 36 +++ .../gather-scatter/mask_scatter_store_run-1.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-10.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-2.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-3.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-4.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-5.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-6.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-7.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-8.c | 48 ++++ .../gather-scatter/mask_scatter_store_run-9.c | 48 ++++ .../rvv/autovec/gather-scatter/scatter_store-1.c | 38 +++ .../rvv/autovec/gather-scatter/scatter_store-10.c | 35 +++ .../rvv/autovec/gather-scatter/scatter_store-2.c | 38 +++ .../rvv/autovec/gather-scatter/scatter_store-3.c | 35 +++ .../rvv/autovec/gather-scatter/scatter_store-4.c | 35 +++ .../rvv/autovec/gather-scatter/scatter_store-5.c | 35 +++ .../rvv/autovec/gather-scatter/scatter_store-6.c | 35 +++ .../rvv/autovec/gather-scatter/scatter_store-7.c | 35 +++ .../rvv/autovec/gather-scatter/scatter_store-8.c | 35 +++ .../rvv/autovec/gather-scatter/scatter_store-9.c | 35 +++ .../autovec/gather-scatter/scatter_store_run-1.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-10.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-2.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-3.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-4.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-5.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-6.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-7.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-8.c | 40 +++ .../autovec/gather-scatter/scatter_store_run-9.c | 40 +++ .../rvv/autovec/gather-scatter/strided_load-1.c | 45 ++++ .../rvv/autovec/gather-scatter/strided_load-2.c | 45 ++++ .../autovec/gather-scatter/strided_load_run-1.c | 84 ++++++ .../autovec/gather-scatter/strided_load_run-2.c | 84 ++++++ .../rvv/autovec/gather-scatter/strided_store-1.c | 45 ++++ .../rvv/autovec/gather-scatter/strided_store-2.c | 45 ++++ .../autovec/gather-scatter/strided_store_run-1.c | 82 ++++++ .../autovec/gather-scatter/strided_store_run-2.c | 82 ++++++ gcc/testsuite/gcc.target/riscv/rvv/rvv.exp | 23 ++ 102 files changed, 4987 insertions(+), 62 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-2.c (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 883ac47..0476b1d 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -58,6 +58,262 @@ ) ;; ========================================================================= +;; == Gather Load +;; ========================================================================= + +(define_expand "len_mask_gather_load" + [(match_operand:VNX1_QHSD 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX1_QHSDI 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +(define_expand "len_mask_gather_load" + [(match_operand:VNX2_QHSD 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX2_QHSDI 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +(define_expand "len_mask_gather_load" + [(match_operand:VNX4_QHSD 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX4_QHSDI 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +(define_expand "len_mask_gather_load" + [(match_operand:VNX8_QHSD 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX8_QHSDI 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +(define_expand "len_mask_gather_load" + [(match_operand:VNX16_QHSD 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX16_QHSDI 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +(define_expand "len_mask_gather_load" + [(match_operand:VNX32_QHS 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX32_QHSI 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +(define_expand "len_mask_gather_load" + [(match_operand:VNX64_QH 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX64_QHI 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +;; When SEW = 8 and LMUL = 8, we can't find any index mode with +;; larger SEW. Since RVV indexed load/store support zero extend +;; implicitly and not support scaling, we should only allow +;; operands[3] and operands[4] to be const_1_operand. +(define_expand "len_mask_gather_load" + [(match_operand:VNX128_Q 0 "register_operand") + (match_operand 1 "pmode_reg_or_0_operand") + (match_operand:VNX128_Q 2 "register_operand") + (match_operand 3 "const_1_operand") + (match_operand 4 "const_1_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, true); + DONE; +}) + +;; ========================================================================= +;; == Scatter Store +;; ========================================================================= + +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX1_QHSDI 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:VNX1_QHSD 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX2_QHSDI 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:VNX2_QHSD 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX4_QHSDI 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:VNX4_QHSD 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX8_QHSDI 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:VNX8_QHSD 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX16_QHSDI 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:VNX16_QHSD 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX32_QHSI 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:VNX32_QHS 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX64_QHI 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:VNX64_QH 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +;; When SEW = 8 and LMUL = 8, we can't find any index mode with +;; larger SEW. Since RVV indexed load/store support zero extend +;; implicitly and not support scaling, we should only allow +;; operands[3] and operands[4] to be const_1_operand. +(define_expand "len_mask_scatter_store" + [(match_operand 0 "pmode_reg_or_0_operand") + (match_operand:VNX128_Q 1 "register_operand") + (match_operand 2 "const_1_operand") + (match_operand 3 "const_1_operand") + (match_operand:VNX128_Q 4 "register_operand") + (match_operand 5 "autovec_length_operand") + (match_operand 6 "const_0_operand") + (match_operand: 7 "vector_mask_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_gather_scatter (operands, false); + DONE; +}) + +;; ========================================================================= ;; == Vector creation ;; ========================================================================= diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index eb975ea..5a22c77 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -61,6 +61,10 @@ (and (match_code "const_int,const_wide_int,const_vector") (match_test "op == CONST0_RTX (GET_MODE (op))"))) +(define_predicate "const_1_operand" + (and (match_code "const_int,const_wide_int,const_vector") + (match_test "op == CONST1_RTX (GET_MODE (op))"))) + (define_predicate "reg_or_0_operand" (ior (match_operand 0 "const_0_operand") (match_operand 0 "register_operand"))) @@ -341,6 +345,33 @@ (ior (match_operand 0 "register_operand") (match_code "const_vector"))) +(define_predicate "vector_gs_scale_operand_16" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 || INTVAL (op) == 2"))) + +(define_predicate "vector_gs_scale_operand_32" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 || INTVAL (op) == 4"))) + +(define_predicate "vector_gs_scale_operand_64" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 || (INTVAL (op) == 8 && Pmode == DImode)"))) + +(define_predicate "vector_gs_extension_operand" + (ior (match_operand 0 "const_1_operand") + (and (match_operand 0 "const_0_operand") + (match_test "Pmode == SImode")))) + +(define_predicate "vector_gs_scale_operand_16_rv32" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 + || (INTVAL (op) == 2 && Pmode == SImode)"))) + +(define_predicate "vector_gs_scale_operand_32_rv32" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 + || (INTVAL (op) == 4 && Pmode == SImode)"))) + (define_predicate "ltge_operator" (match_code "lt,ltu,ge,geu")) @@ -376,7 +407,7 @@ || rtx_equal_p (op, CONST0_RTX (GET_MODE (op)))) && maybe_gt (GET_MODE_BITSIZE (GET_MODE (op)), GET_MODE_BITSIZE (Pmode)))") (ior (match_test "rtx_equal_p (op, CONST0_RTX (GET_MODE (op)))") - (ior (match_operand 0 "const_int_operand") + (ior (match_code "const_int,const_poly_int") (ior (match_operand 0 "register_operand") (match_test "satisfies_constraint_Wdm (op)")))))) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index b7b5395..1a622c5 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -195,6 +195,8 @@ enum insn_type RVV_SCALAR_MOV_OP = 4, /* +1 for VUNDEF according to vector.md. */ RVV_SLIDE_OP = 4, /* Dest, VUNDEF, source and offset. */ RVV_COMPRESS_OP = 4, + RVV_GATHER_M_OP = 5, + RVV_SCATTER_M_OP = 4, }; enum vlmul_type { @@ -303,6 +305,7 @@ void expand_vec_init (rtx, rtx); void expand_vec_perm (rtx, rtx, rtx, rtx); void expand_select_vl (rtx *); void expand_load_store (rtx *, bool); +void expand_gather_scatter (rtx *, bool); /* Rounding mode bitfield for fixed point VXRM. */ enum fixed_point_rounding_mode diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 9d3f588..90da638 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -556,16 +556,23 @@ const_vec_all_in_range_p (rtx vec, poly_int64 minval, poly_int64 maxval) return true; } -/* Return a const_int vector of VAL. - - This function also exists in aarch64, we may unify it in middle-end in the - future. */ +/* Return a const vector of VAL. The VAL can be either const_int or + const_poly_int. */ static rtx gen_const_vector_dup (machine_mode mode, poly_int64 val) { - rtx c = gen_int_mode (val, GET_MODE_INNER (mode)); - return gen_const_vec_duplicate (mode, c); + scalar_mode smode = GET_MODE_INNER (mode); + rtx c = gen_int_mode (val, smode); + if (!val.is_constant () && GET_MODE_SIZE (smode) > GET_MODE_SIZE (Pmode)) + { + /* When VAL is const_poly_int value, we need to explicitly broadcast + it into a vector using RVV broadcast instruction. */ + rtx dup = gen_reg_rtx (mode); + emit_insn (gen_vec_duplicate (mode, dup, c)); + return dup; + } + return gen_const_vec_duplicate (mode, c); } /* Emit a vlmax vsetvl instruction. This should only be used when @@ -901,6 +908,39 @@ emit_nonvlmax_masked_insn (unsigned icode, int op_num, rtx *ops, rtx avl) e.emit_insn ((enum insn_code) icode, ops); } +/* This function emits a VLMAX masked store instruction. */ +static void +emit_vlmax_masked_store_insn (unsigned icode, int op_num, rtx *ops) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (dest_mode).require (); + insn_expander e (/*OP_NUM*/ op_num, + /*HAS_DEST_P*/ false, + /*FULLY_UNMASKED_P*/ false, + /*USE_REAL_MERGE_P*/ true, + /*HAS_AVL_P*/ true, + /*VLMAX_P*/ true, dest_mode, + mask_mode); + e.emit_insn ((enum insn_code) icode, ops); +} + +/* This function emits a non-VLMAX masked store instruction. */ +static void +emit_nonvlmax_masked_store_insn (unsigned icode, int op_num, rtx *ops, rtx avl) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (dest_mode).require (); + insn_expander e (/*OP_NUM*/ op_num, + /*HAS_DEST_P*/ false, + /*FULLY_UNMASKED_P*/ false, + /*USE_REAL_MERGE_P*/ true, + /*HAS_AVL_P*/ true, + /*VLMAX_P*/ false, dest_mode, + mask_mode); + e.set_vl (avl); + e.emit_insn ((enum insn_code) icode, ops); +} + /* This function emits a masked instruction. */ void emit_vlmax_masked_mu_insn (unsigned icode, int op_num, rtx *ops) @@ -1194,7 +1234,6 @@ static void expand_const_vector (rtx target, rtx src) { machine_mode mode = GET_MODE (target); - scalar_mode elt_mode = GET_MODE_INNER (mode); if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) { rtx elt; @@ -1219,7 +1258,6 @@ expand_const_vector (rtx target, rtx src) } else { - elt = force_reg (elt_mode, elt); rtx ops[] = {tmp, elt}; emit_vlmax_insn (code_for_pred_broadcast (mode), RVV_UNOP, ops); } @@ -2488,6 +2526,25 @@ expand_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1, return false; } +/* Modulo all SEL indices to ensure they are all in range if [0, MAX_SEL]. */ +static rtx +modulo_sel_indices (rtx sel, poly_uint64 max_sel) +{ + rtx sel_mod; + machine_mode sel_mode = GET_MODE (sel); + poly_uint64 nunits = GET_MODE_NUNITS (sel_mode); + /* If SEL is variable-length CONST_VECTOR, we don't need to modulo it. */ + if (!nunits.is_constant () && CONST_VECTOR_P (sel)) + sel_mod = sel; + else + { + rtx mod = gen_const_vector_dup (sel_mode, max_sel); + sel_mod + = expand_simple_binop (sel_mode, AND, sel, mod, NULL, 0, OPTAB_DIRECT); + } + return sel_mod; +} + /* Implement vec_perm. */ void @@ -2501,41 +2558,44 @@ expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel) index is in range of [0, nunits - 1]. A single vrgather instructions is enough. Since we will use vrgatherei16.vv for variable-length vector, it is never out of range and we don't need to modulo the index. */ - if (!nunits.is_constant () || const_vec_all_in_range_p (sel, 0, nunits - 1)) + if (nunits.is_constant () && const_vec_all_in_range_p (sel, 0, nunits - 1)) { emit_vlmax_gather_insn (target, op0, sel); return; } + /* Check if all the indices are same. */ + rtx elt; + if (const_vec_duplicate_p (sel, &elt)) + { + poly_uint64 value = rtx_to_poly_int64 (elt); + rtx op = op0; + if (maybe_gt (value, nunits - 1)) + { + sel = gen_const_vector_dup (sel_mode, value - nunits); + op = op1; + } + emit_vlmax_gather_insn (target, op, sel); + } + + /* Note: vec_perm indices are supposed to wrap when they go beyond the + size of the two value vectors, i.e. the upper bits of the indices + are effectively ignored. RVV vrgather instead produces 0 for any + out-of-range indices, so we need to modulo all the vec_perm indices + to ensure they are all in range of [0, nunits - 1] when op0 == op1 + or all in range of [0, 2 * nunits - 1] when op0 != op1. */ + rtx sel_mod + = modulo_sel_indices (sel, + rtx_equal_p (op0, op1) ? nunits - 1 : 2 * nunits - 1); + /* Check if the two values vectors are the same. */ - if (rtx_equal_p (op0, op1) || const_vec_duplicate_p (sel)) - { - /* Note: vec_perm indices are supposed to wrap when they go beyond the - size of the two value vectors, i.e. the upper bits of the indices - are effectively ignored. RVV vrgather instead produces 0 for any - out-of-range indices, so we need to modulo all the vec_perm indices - to ensure they are all in range of [0, nunits - 1]. */ - rtx max_sel = gen_const_vector_dup (sel_mode, nunits - 1); - rtx sel_mod = expand_simple_binop (sel_mode, AND, sel, max_sel, NULL, 0, - OPTAB_DIRECT); - emit_vlmax_gather_insn (target, op1, sel_mod); + if (rtx_equal_p (op0, op1)) + { + emit_vlmax_gather_insn (target, op0, sel_mod); return; } - rtx sel_mod = sel; rtx max_sel = gen_const_vector_dup (sel_mode, 2 * nunits - 1); - /* We don't need to modulo indices for VLA vector. - Since we should gurantee they aren't out of range before. */ - if (nunits.is_constant ()) - { - /* Note: vec_perm indices are supposed to wrap when they go beyond the - size of the two value vectors, i.e. the upper bits of the indices - are effectively ignored. RVV vrgather instead produces 0 for any - out-of-range indices, so we need to modulo all the vec_perm indices - to ensure they are all in range of [0, 2 * nunits - 1]. */ - sel_mod = expand_simple_binop (sel_mode, AND, sel, max_sel, NULL, 0, - OPTAB_DIRECT); - } /* This following sequence is handling the case that: __builtin_shufflevector (vec1, vec2, index...), the index can be any @@ -3007,6 +3067,7 @@ expand_load_store (rtx *ops, bool is_load) } } + /* Return true if the operation is the floating-point operation need FRM. */ static bool needs_fp_rounding (rtx_code code, machine_mode mode) @@ -3047,4 +3108,163 @@ expand_cond_len_binop (rtx_code code, rtx *ops) gcc_unreachable (); } +/* Prepare insn_code for gather_load/scatter_store according to + the vector mode and index mode. */ +static insn_code +prepare_gather_scatter (machine_mode vec_mode, machine_mode idx_mode, + bool is_load) +{ + if (!is_load) + return code_for_pred_indexed_store (UNSPEC_UNORDERED, vec_mode, idx_mode); + else + { + unsigned src_eew_bitsize = GET_MODE_BITSIZE (GET_MODE_INNER (idx_mode)); + unsigned dst_eew_bitsize = GET_MODE_BITSIZE (GET_MODE_INNER (vec_mode)); + if (dst_eew_bitsize == src_eew_bitsize) + return code_for_pred_indexed_load_same_eew (UNSPEC_UNORDERED, vec_mode); + else if (dst_eew_bitsize > src_eew_bitsize) + { + unsigned factor = dst_eew_bitsize / src_eew_bitsize; + switch (factor) + { + case 2: + return code_for_pred_indexed_load_x2_greater_eew ( + UNSPEC_UNORDERED, vec_mode); + case 4: + return code_for_pred_indexed_load_x4_greater_eew ( + UNSPEC_UNORDERED, vec_mode); + case 8: + return code_for_pred_indexed_load_x8_greater_eew ( + UNSPEC_UNORDERED, vec_mode); + default: + gcc_unreachable (); + } + } + else + { + unsigned factor = src_eew_bitsize / dst_eew_bitsize; + switch (factor) + { + case 2: + return code_for_pred_indexed_load_x2_smaller_eew ( + UNSPEC_UNORDERED, vec_mode); + case 4: + return code_for_pred_indexed_load_x4_smaller_eew ( + UNSPEC_UNORDERED, vec_mode); + case 8: + return code_for_pred_indexed_load_x8_smaller_eew ( + UNSPEC_UNORDERED, vec_mode); + default: + gcc_unreachable (); + } + } + } +} + +/* Expand LEN_MASK_{GATHER_LOAD,SCATTER_STORE}. */ +void +expand_gather_scatter (rtx *ops, bool is_load) +{ + rtx ptr, vec_offset, vec_reg, len, mask; + bool zero_extend_p; + int scale_log2; + if (is_load) + { + vec_reg = ops[0]; + ptr = ops[1]; + vec_offset = ops[2]; + zero_extend_p = INTVAL (ops[3]); + scale_log2 = exact_log2 (INTVAL (ops[4])); + len = ops[5]; + mask = ops[7]; + } + else + { + vec_reg = ops[4]; + ptr = ops[0]; + vec_offset = ops[1]; + zero_extend_p = INTVAL (ops[2]); + scale_log2 = exact_log2 (INTVAL (ops[3])); + len = ops[5]; + mask = ops[7]; + } + + machine_mode vec_mode = GET_MODE (vec_reg); + machine_mode idx_mode = GET_MODE (vec_offset); + scalar_mode inner_vec_mode = GET_MODE_INNER (vec_mode); + scalar_mode inner_idx_mode = GET_MODE_INNER (idx_mode); + unsigned inner_vsize = GET_MODE_BITSIZE (inner_vec_mode); + unsigned inner_offsize = GET_MODE_BITSIZE (inner_idx_mode); + poly_int64 nunits = GET_MODE_NUNITS (vec_mode); + poly_int64 value; + bool is_vlmax = poly_int_rtx_p (len, &value) && known_eq (value, nunits); + + if (inner_offsize < inner_vsize) + { + /* 7.2. Vector Load/Store Addressing Modes. + If the vector offset elements are narrower than XLEN, they are + zero-extended to XLEN before adding to the ptr effective address. If + the vector offset elements are wider than XLEN, the least-significant + XLEN bits are used in the address calculation. An implementation must + raise an illegal instruction exception if the EEW is not supported for + offset elements. + + RVV spec only refers to the scale_log == 0 case. */ + if (!zero_extend_p || (zero_extend_p && scale_log2 != 0)) + { + if (zero_extend_p) + inner_idx_mode + = int_mode_for_size (inner_offsize * 2, 0).require (); + else + inner_idx_mode = int_mode_for_size (BITS_PER_WORD, 0).require (); + machine_mode new_idx_mode + = get_vector_mode (inner_idx_mode, nunits).require (); + rtx tmp = gen_reg_rtx (new_idx_mode); + emit_insn (gen_extend_insn (tmp, vec_offset, new_idx_mode, idx_mode, + zero_extend_p ? true : false)); + vec_offset = tmp; + idx_mode = new_idx_mode; + } + } + + if (scale_log2 != 0) + { + rtx tmp = expand_binop (idx_mode, ashl_optab, vec_offset, + gen_int_mode (scale_log2, Pmode), NULL_RTX, 0, + OPTAB_DIRECT); + vec_offset = tmp; + } + + insn_code icode = prepare_gather_scatter (vec_mode, idx_mode, is_load); + if (is_vlmax) + { + if (is_load) + { + rtx load_ops[] + = {vec_reg, mask, RVV_VUNDEF (vec_mode), ptr, vec_offset}; + emit_vlmax_masked_insn (icode, RVV_GATHER_M_OP, load_ops); + } + else + { + rtx store_ops[] = {mask, ptr, vec_offset, vec_reg}; + emit_vlmax_masked_store_insn (icode, RVV_SCATTER_M_OP, store_ops); + } + } + else + { + if (is_load) + { + rtx load_ops[] + = {vec_reg, mask, RVV_VUNDEF (vec_mode), ptr, vec_offset}; + emit_nonvlmax_masked_insn (icode, RVV_GATHER_M_OP, load_ops, len); + } + else + { + rtx store_ops[] = {mask, ptr, vec_offset, vec_reg}; + emit_nonvlmax_masked_store_insn (icode, RVV_SCATTER_M_OP, store_ops, + len); + } + } +} + } // namespace riscv_vector diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 398194f..706c184 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2037,7 +2037,14 @@ riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src) (m, n) = base * magn + constant. This calculation doesn't need div operation. */ - emit_move_insn (tmp, gen_int_mode (BYTES_PER_RISCV_VECTOR, mode)); + if (known_le (GET_MODE_SIZE (mode), GET_MODE_SIZE (Pmode))) + emit_move_insn (tmp, gen_int_mode (BYTES_PER_RISCV_VECTOR, mode)); + else + { + emit_move_insn (gen_highpart (Pmode, tmp), CONST0_RTX (Pmode)); + emit_move_insn (gen_lowpart (Pmode, tmp), + gen_int_mode (BYTES_PER_RISCV_VECTOR, Pmode)); + } if (BYTES_PER_RISCV_VECTOR.is_constant ()) { @@ -2144,7 +2151,7 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src) return false; } - if (satisfies_constraint_vp (src)) + if (satisfies_constraint_vp (src) && GET_MODE (src) == Pmode) return false; if (GET_MODE_SIZE (mode).to_constant () < GET_MODE_SIZE (Pmode)) diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 8afd3dc..ec49544 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -115,6 +115,9 @@ (define_mode_iterator VEEWEXT2 [ (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") + (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") (VNx2HF "TARGET_VECTOR_ELEN_FP_16") (VNx4HF "TARGET_VECTOR_ELEN_FP_16") + (VNx8HF "TARGET_VECTOR_ELEN_FP_16") (VNx16HF "TARGET_VECTOR_ELEN_FP_16") (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") @@ -161,6 +164,8 @@ (define_mode_iterator VEEWTRUNC2 [ (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN >= 128") (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN >= 128") + (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") (VNx2HF "TARGET_VECTOR_ELEN_FP_16") (VNx4HF "TARGET_VECTOR_ELEN_FP_16") + (VNx8HF "TARGET_VECTOR_ELEN_FP_16") (VNx16HF "TARGET_VECTOR_ELEN_FP_16") (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN >= 128") (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") (VNx2SF "TARGET_VECTOR_ELEN_FP_32") @@ -172,6 +177,8 @@ (define_mode_iterator VEEWTRUNC4 [ (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI (VNx32QI "TARGET_MIN_VLEN >= 128") (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI (VNx16HI "TARGET_MIN_VLEN >= 128") + (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") (VNx2HF "TARGET_VECTOR_ELEN_FP_16") (VNx4HF "TARGET_VECTOR_ELEN_FP_16") + (VNx8HF "TARGET_VECTOR_ELEN_FP_16") (VNx16HF "TARGET_VECTOR_ELEN_FP_16") ]) (define_mode_iterator VEEWTRUNC8 [ @@ -362,46 +369,67 @@ ]) (define_mode_iterator VNX1_QHSD [ - (VNx1QI "TARGET_MIN_VLEN < 128") (VNx1HI "TARGET_MIN_VLEN < 128") (VNx1SI "TARGET_MIN_VLEN < 128") + (VNx1QI "TARGET_MIN_VLEN < 128") + (VNx1HI "TARGET_MIN_VLEN < 128") + (VNx1SI "TARGET_MIN_VLEN < 128") (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") + (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") ]) (define_mode_iterator VNX2_QHSD [ - VNx2QI VNx2HI VNx2SI + VNx2QI + VNx2HI + VNx2SI (VNx2DI "TARGET_VECTOR_ELEN_64") + (VNx2HF "TARGET_VECTOR_ELEN_FP_16") (VNx2SF "TARGET_VECTOR_ELEN_FP_32") (VNx2DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VNX4_QHSD [ - VNx4QI VNx4HI VNx4SI + VNx4QI + VNx4HI + VNx4SI (VNx4DI "TARGET_VECTOR_ELEN_64") + (VNx4HF "TARGET_VECTOR_ELEN_FP_16") (VNx4SF "TARGET_VECTOR_ELEN_FP_32") (VNx4DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VNX8_QHSD [ - VNx8QI VNx8HI VNx8SI + VNx8QI + VNx8HI + VNx8SI (VNx8DI "TARGET_VECTOR_ELEN_64") + (VNx8HF "TARGET_VECTOR_ELEN_FP_16") (VNx8SF "TARGET_VECTOR_ELEN_FP_32") (VNx8DF "TARGET_VECTOR_ELEN_FP_64") ]) -(define_mode_iterator VNX16_QHS [ - VNx16QI VNx16HI (VNx16SI "TARGET_MIN_VLEN > 32") +(define_mode_iterator VNX16_QHSD [ + VNx16QI + VNx16HI + (VNx16SI "TARGET_MIN_VLEN > 32") + (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (VNx16HF "TARGET_VECTOR_ELEN_FP_16") (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") ]) (define_mode_iterator VNX32_QHS [ - VNx32QI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + VNx32QI + (VNx32HI "TARGET_MIN_VLEN > 32") + (VNx32SI "TARGET_MIN_VLEN >= 128") + (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") ]) (define_mode_iterator VNX64_QH [ (VNx64QI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") + (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") ]) (define_mode_iterator VNX128_Q [ @@ -409,35 +437,49 @@ ]) (define_mode_iterator VNX1_QHSDI [ - (VNx1QI "TARGET_MIN_VLEN < 128") (VNx1HI "TARGET_MIN_VLEN < 128") (VNx1SI "TARGET_MIN_VLEN < 128") - (VNx1DI "TARGET_64BIT && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") + (VNx1QI "TARGET_MIN_VLEN < 128") + (VNx1HI "TARGET_MIN_VLEN < 128") + (VNx1SI "TARGET_MIN_VLEN < 128") + (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128 && TARGET_64BIT") ]) (define_mode_iterator VNX2_QHSDI [ - VNx2QI VNx2HI VNx2SI - (VNx2DI "TARGET_64BIT && TARGET_VECTOR_ELEN_64") + VNx2QI + VNx2HI + VNx2SI + (VNx2DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT") ]) (define_mode_iterator VNX4_QHSDI [ - VNx4QI VNx4HI VNx4SI - (VNx4DI "TARGET_64BIT && TARGET_VECTOR_ELEN_64") + VNx4QI + VNx4HI + VNx4SI + (VNx4DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT") ]) (define_mode_iterator VNX8_QHSDI [ - VNx8QI VNx8HI VNx8SI - (VNx8DI "TARGET_64BIT && TARGET_VECTOR_ELEN_64") + VNx8QI + VNx8HI + VNx8SI + (VNx8DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT") ]) (define_mode_iterator VNX16_QHSDI [ - VNx16QI VNx16HI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx16DI "TARGET_64BIT && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + VNx16QI + VNx16HI + (VNx16SI "TARGET_MIN_VLEN > 32") + (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128 && TARGET_64BIT") ]) (define_mode_iterator VNX32_QHSI [ - VNx32QI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") + VNx32QI + (VNx32HI "TARGET_MIN_VLEN > 32") + (VNx32SI "TARGET_MIN_VLEN >= 128") ]) (define_mode_iterator VNX64_QHI [ - VNx64QI (VNx64HI "TARGET_MIN_VLEN >= 128") + (VNx64QI "TARGET_MIN_VLEN > 32") + (VNx64HI "TARGET_MIN_VLEN >= 128") ]) (define_mode_iterator V_WHOLE [ @@ -1393,6 +1435,8 @@ (define_mode_attr VINDEX_DOUBLE_TRUNC [ (VNx1HI "VNx1QI") (VNx2HI "VNx2QI") (VNx4HI "VNx4QI") (VNx8HI "VNx8QI") (VNx16HI "VNx16QI") (VNx32HI "VNx32QI") (VNx64HI "VNx64QI") + (VNx1HF "VNx1QI") (VNx2HF "VNx2QI") (VNx4HF "VNx4QI") (VNx8HF "VNx8QI") + (VNx16HF "VNx16QI") (VNx32HF "VNx32QI") (VNx64HF "VNx64QI") (VNx1SI "VNx1HI") (VNx2SI "VNx2HI") (VNx4SI "VNx4HI") (VNx8SI "VNx8HI") (VNx16SI "VNx16HI") (VNx32SI "VNx32HI") (VNx1SF "VNx1HI") (VNx2SF "VNx2HI") (VNx4SF "VNx4HI") (VNx8SF "VNx8HI") @@ -1420,6 +1464,7 @@ (define_mode_attr VINDEX_DOUBLE_EXT [ (VNx1QI "VNx1HI") (VNx2QI "VNx2HI") (VNx4QI "VNx4HI") (VNx8QI "VNx8HI") (VNx16QI "VNx16HI") (VNx32QI "VNx32HI") (VNx64QI "VNx64HI") (VNx1HI "VNx1SI") (VNx2HI "VNx2SI") (VNx4HI "VNx4SI") (VNx8HI "VNx8SI") (VNx16HI "VNx16SI") (VNx32HI "VNx32SI") + (VNx1HF "VNx1SI") (VNx2HF "VNx2SI") (VNx4HF "VNx4SI") (VNx8HF "VNx8SI") (VNx16HF "VNx16SI") (VNx32HF "VNx32SI") (VNx1SI "VNx1DI") (VNx2SI "VNx2DI") (VNx4SI "VNx4DI") (VNx8SI "VNx8DI") (VNx16SI "VNx16DI") (VNx1SF "VNx1DI") (VNx2SF "VNx2DI") (VNx4SF "VNx4DI") (VNx8SF "VNx8DI") (VNx16SF "VNx16DI") ]) @@ -1427,6 +1472,7 @@ (define_mode_attr VINDEX_QUAD_EXT [ (VNx1QI "VNx1SI") (VNx2QI "VNx2SI") (VNx4QI "VNx4SI") (VNx8QI "VNx8SI") (VNx16QI "VNx16SI") (VNx32QI "VNx32SI") (VNx1HI "VNx1DI") (VNx2HI "VNx2DI") (VNx4HI "VNx4DI") (VNx8HI "VNx8DI") (VNx16HI "VNx16DI") + (VNx1HF "VNx1DI") (VNx2HF "VNx2DI") (VNx4HF "VNx4DI") (VNx8HF "VNx8DI") (VNx16HF "VNx16DI") ]) (define_mode_attr VINDEX_OCT_EXT [ @@ -1471,6 +1517,40 @@ (VNx4DI "VNx8BI") (VNx8DI "VNx16BI") (VNx16DI "VNx32BI") ]) +(define_mode_attr gs_extension [ + (VNx1QI "immediate_operand") (VNx2QI "immediate_operand") (VNx4QI "immediate_operand") (VNx8QI "immediate_operand") (VNx16QI "immediate_operand") + (VNx32QI "vector_gs_extension_operand") (VNx64QI "const_1_operand") + (VNx1HI "immediate_operand") (VNx2HI "immediate_operand") (VNx4HI "immediate_operand") (VNx8HI "immediate_operand") (VNx16HI "immediate_operand") + (VNx32HI "vector_gs_extension_operand") (VNx64HI "const_1_operand") + (VNx1SI "immediate_operand") (VNx2SI "immediate_operand") (VNx4SI "immediate_operand") (VNx8SI "immediate_operand") (VNx16SI "immediate_operand") + (VNx32SI "vector_gs_extension_operand") + (VNx1DI "immediate_operand") (VNx2DI "immediate_operand") (VNx4DI "immediate_operand") (VNx8DI "immediate_operand") (VNx16DI "immediate_operand") + + (VNx1HF "immediate_operand") (VNx2HF "immediate_operand") (VNx4HF "immediate_operand") (VNx8HF "immediate_operand") (VNx16HF "immediate_operand") + (VNx32HF "vector_gs_extension_operand") (VNx64HF "const_1_operand") + (VNx1SF "immediate_operand") (VNx2SF "immediate_operand") (VNx4SF "immediate_operand") (VNx8SF "immediate_operand") (VNx16SF "immediate_operand") + (VNx32SF "vector_gs_extension_operand") + (VNx1DF "immediate_operand") (VNx2DF "immediate_operand") (VNx4DF "immediate_operand") (VNx8DF "immediate_operand") (VNx16DF "immediate_operand") +]) + +(define_mode_attr gs_scale [ + (VNx1QI "const_1_operand") (VNx2QI "const_1_operand") (VNx4QI "const_1_operand") (VNx8QI "const_1_operand") + (VNx16QI "const_1_operand") (VNx32QI "const_1_operand") (VNx64QI "const_1_operand") + (VNx1HI "vector_gs_scale_operand_16") (VNx2HI "vector_gs_scale_operand_16") (VNx4HI "vector_gs_scale_operand_16") (VNx8HI "vector_gs_scale_operand_16") + (VNx16HI "vector_gs_scale_operand_16") (VNx32HI "vector_gs_scale_operand_16_rv32") (VNx64HI "const_1_operand") + (VNx1SI "vector_gs_scale_operand_32") (VNx2SI "vector_gs_scale_operand_32") (VNx4SI "vector_gs_scale_operand_32") (VNx8SI "vector_gs_scale_operand_32") + (VNx16SI "vector_gs_scale_operand_32") (VNx32SI "vector_gs_scale_operand_32_rv32") + (VNx1DI "vector_gs_scale_operand_64") (VNx2DI "vector_gs_scale_operand_64") (VNx4DI "vector_gs_scale_operand_64") (VNx8DI "vector_gs_scale_operand_64") + (VNx16DI "vector_gs_scale_operand_64") + + (VNx1HF "vector_gs_scale_operand_16") (VNx2HF "vector_gs_scale_operand_16") (VNx4HF "vector_gs_scale_operand_16") (VNx8HF "vector_gs_scale_operand_16") + (VNx16HF "vector_gs_scale_operand_16") (VNx32HF "vector_gs_scale_operand_16_rv32") (VNx64HF "const_1_operand") + (VNx1SF "vector_gs_scale_operand_32") (VNx2SF "vector_gs_scale_operand_32") (VNx4SF "vector_gs_scale_operand_32") (VNx8SF "vector_gs_scale_operand_32") + (VNx16SF "vector_gs_scale_operand_32") (VNx32SF "vector_gs_scale_operand_32_rv32") + (VNx1DF "vector_gs_scale_operand_64") (VNx2DF "vector_gs_scale_operand_64") (VNx4DF "vector_gs_scale_operand_64") (VNx8DF "vector_gs_scale_operand_64") + (VNx16DF "vector_gs_scale_operand_64") +]) + (define_int_iterator WREDUC [UNSPEC_WREDUC_SUM UNSPEC_WREDUC_USUM]) (define_int_iterator ORDER [UNSPEC_ORDERED UNSPEC_UNORDERED]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 5b7a17b..de94463 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -818,7 +818,7 @@ ;; This pattern only handles duplicates of non-constant inputs. ;; Constant vectors go through the movm pattern instead. ;; So "direct_broadcast_operand" can only be mem or reg, no CONSTANT. -(define_expand "vec_duplicate" +(define_expand "@vec_duplicate" [(set (match_operand:V 0 "register_operand") (vec_duplicate:V (match_operand: 1 "direct_broadcast_operand")))] @@ -1357,8 +1357,16 @@ } } else if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (Pmode) - && immediate_operand (operands[3], Pmode)) - operands[3] = gen_rtx_SIGN_EXTEND (mode, force_reg (Pmode, operands[3])); + && (immediate_operand (operands[3], Pmode) + || (CONST_POLY_INT_P (operands[3]) + && known_ge (rtx_to_poly_int64 (operands[3]), 0U) + && known_le (rtx_to_poly_int64 (operands[3]), GET_MODE_SIZE (mode))))) + { + rtx tmp = gen_reg_rtx (Pmode); + poly_int64 value = rtx_to_poly_int64 (operands[3]); + emit_move_insn (tmp, gen_int_mode (value, Pmode)); + operands[3] = gen_rtx_SIGN_EXTEND (mode, tmp); + } else operands[3] = force_reg (mode, operands[3]); }) @@ -1387,7 +1395,8 @@ vlse.v\t%0,%3,zero vmv.s.x\t%0,%3 vmv.s.x\t%0,%3" - "register_operand (operands[3], mode) + "(register_operand (operands[3], mode) + || CONST_POLY_INT_P (operands[3])) && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (Pmode)" [(set (match_dup 0) (if_then_else:VI (unspec: [(match_dup 1) (match_dup 4) @@ -1397,6 +1406,12 @@ (match_dup 2)))] { gcc_assert (can_create_pseudo_p ()); + if (CONST_POLY_INT_P (operands[3])) + { + rtx tmp = gen_reg_rtx (mode); + emit_move_insn (tmp, operands[3]); + operands[3] = tmp; + } rtx m = assign_stack_local (mode, GET_MODE_SIZE (mode), GET_MODE_ALIGNMENT (mode)); m = validize_mem (m); @@ -1483,6 +1498,7 @@ (match_operand 5 "vector_length_operand" " rK, rK, rK") (match_operand 6 "const_int_operand" " i, i, i") (match_operand 7 "const_int_operand" " i, i, i") + (match_operand 8 "const_int_operand" " i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (unspec:V @@ -1738,7 +1754,7 @@ [(set_attr "type" "vstx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1749,11 +1765,11 @@ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") (match_operand:VNX16_QHSDI 2 "register_operand" " vr") - (match_operand:VNX16_QHS 3 "register_operand" " vr")] ORDER))] + (match_operand:VNX16_QHSD 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) (define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c new file mode 100644 index 0000000..dffe13f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t +#define INDEX16 uint16_t +#define INDEX32 uint32_t +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c new file mode 100644 index 0000000..a622e51 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c new file mode 100644 index 0000000..4692380 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define TEST_LOOP(DATA_TYPE) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict *src) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += *src[i]; \ + } + +#define TEST_ALL(T) \ + T (int8_t) \ + T (uint8_t) \ + T (int16_t) \ + T (uint16_t) \ + T (_Float16) \ + T (int32_t) \ + T (uint32_t) \ + T (float) \ + T (int64_t) \ + T (uint64_t) \ + T (double) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c new file mode 100644 index 0000000..71a3dd4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c @@ -0,0 +1,112 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-vect-cost-model -fdump-tree-vect-details" } */ + +#include + +#define TEST_LOOP(DATA_TYPE, INDEX_TYPE) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE##_##INDEX_TYPE (DATA_TYPE *restrict y, DATA_TYPE *restrict x, \ + INDEX_TYPE *restrict index) \ + { \ + for (int i = 0; i < 100; ++i) \ + { \ + y[i * 2] = x[index[i * 2]] + 1; \ + y[i * 2 + 1] = x[index[i * 2 + 1]] + 2; \ + } \ + } + +TEST_LOOP (int8_t, int8_t) +TEST_LOOP (uint8_t, int8_t) +TEST_LOOP (int16_t, int8_t) +TEST_LOOP (uint16_t, int8_t) +TEST_LOOP (int32_t, int8_t) +TEST_LOOP (uint32_t, int8_t) +TEST_LOOP (int64_t, int8_t) +TEST_LOOP (uint64_t, int8_t) +TEST_LOOP (_Float16, int8_t) +TEST_LOOP (float, int8_t) +TEST_LOOP (double, int8_t) +TEST_LOOP (int8_t, int16_t) +TEST_LOOP (uint8_t, int16_t) +TEST_LOOP (int16_t, int16_t) +TEST_LOOP (uint16_t, int16_t) +TEST_LOOP (int32_t, int16_t) +TEST_LOOP (uint32_t, int16_t) +TEST_LOOP (int64_t, int16_t) +TEST_LOOP (uint64_t, int16_t) +TEST_LOOP (_Float16, int16_t) +TEST_LOOP (float, int16_t) +TEST_LOOP (double, int16_t) +TEST_LOOP (int8_t, int32_t) +TEST_LOOP (uint8_t, int32_t) +TEST_LOOP (int16_t, int32_t) +TEST_LOOP (uint16_t, int32_t) +TEST_LOOP (int32_t, int32_t) +TEST_LOOP (uint32_t, int32_t) +TEST_LOOP (int64_t, int32_t) +TEST_LOOP (uint64_t, int32_t) +TEST_LOOP (_Float16, int32_t) +TEST_LOOP (float, int32_t) +TEST_LOOP (double, int32_t) +TEST_LOOP (int8_t, int64_t) +TEST_LOOP (uint8_t, int64_t) +TEST_LOOP (int16_t, int64_t) +TEST_LOOP (uint16_t, int64_t) +TEST_LOOP (int32_t, int64_t) +TEST_LOOP (uint32_t, int64_t) +TEST_LOOP (int64_t, int64_t) +TEST_LOOP (uint64_t, int64_t) +TEST_LOOP (_Float16, int64_t) +TEST_LOOP (float, int64_t) +TEST_LOOP (double, int64_t) +TEST_LOOP (int8_t, uint8_t) +TEST_LOOP (uint8_t, uint8_t) +TEST_LOOP (int16_t, uint8_t) +TEST_LOOP (uint16_t, uint8_t) +TEST_LOOP (int32_t, uint8_t) +TEST_LOOP (uint32_t, uint8_t) +TEST_LOOP (int64_t, uint8_t) +TEST_LOOP (uint64_t, uint8_t) +TEST_LOOP (_Float16, uint8_t) +TEST_LOOP (float, uint8_t) +TEST_LOOP (double, uint8_t) +TEST_LOOP (int8_t, uint16_t) +TEST_LOOP (uint8_t, uint16_t) +TEST_LOOP (int16_t, uint16_t) +TEST_LOOP (uint16_t, uint16_t) +TEST_LOOP (int32_t, uint16_t) +TEST_LOOP (uint32_t, uint16_t) +TEST_LOOP (int64_t, uint16_t) +TEST_LOOP (uint64_t, uint16_t) +TEST_LOOP (_Float16, uint16_t) +TEST_LOOP (float, uint16_t) +TEST_LOOP (double, uint16_t) +TEST_LOOP (int8_t, uint32_t) +TEST_LOOP (uint8_t, uint32_t) +TEST_LOOP (int16_t, uint32_t) +TEST_LOOP (uint16_t, uint32_t) +TEST_LOOP (int32_t, uint32_t) +TEST_LOOP (uint32_t, uint32_t) +TEST_LOOP (int64_t, uint32_t) +TEST_LOOP (uint64_t, uint32_t) +TEST_LOOP (_Float16, uint32_t) +TEST_LOOP (float, uint32_t) +TEST_LOOP (double, uint32_t) +TEST_LOOP (int8_t, uint64_t) +TEST_LOOP (uint8_t, uint64_t) +TEST_LOOP (int16_t, uint64_t) +TEST_LOOP (uint16_t, uint64_t) +TEST_LOOP (int32_t, uint64_t) +TEST_LOOP (uint32_t, uint64_t) +TEST_LOOP (int64_t, uint64_t) +TEST_LOOP (uint64_t, uint64_t) +TEST_LOOP (_Float16, uint64_t) +TEST_LOOP (float, uint64_t) +TEST_LOOP (double, uint64_t) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 88 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-assembler-not "vluxei64\.v" } } */ +/* { dg-final { scan-assembler-not "vsuxei64\.v" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c new file mode 100644 index 0000000..785550c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c new file mode 100644 index 0000000..22aeb88 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c new file mode 100644 index 0000000..d74a834 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c new file mode 100644 index 0000000..2b6c0a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 uint16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c new file mode 100644 index 0000000..407cc8a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 int16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c new file mode 100644 index 0000000..81b31ef --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 uint32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c new file mode 100644 index 0000000..0bfdb8f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 int32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c new file mode 100644 index 0000000..46f7911 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c new file mode 100644 index 0000000..0d3c5b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-1.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c new file mode 100644 index 0000000..145df1e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-10.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c new file mode 100644 index 0000000..d36b6f0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c @@ -0,0 +1,39 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-11.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE *src_##DATA_TYPE[128]; \ + DATA_TYPE src2_##DATA_TYPE[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + src_##DATA_TYPE[i] = src2_##DATA_TYPE + i; \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] + src_##DATA_TYPE[i][0])); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c new file mode 100644 index 0000000..b4e2ead --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c @@ -0,0 +1,124 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-12.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, INDEX_TYPE) \ + DATA_TYPE dest_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + DATA_TYPE src_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + INDEX_TYPE index_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + for (int i = 0; i < 202; i++) \ + { \ + src_##DATA_TYPE##_##INDEX_TYPE[i] \ + = (DATA_TYPE) ((i * 19 + 735) & (sizeof (DATA_TYPE) * 7 - 1)); \ + index_##DATA_TYPE##_##INDEX_TYPE[i] = (i * 7) % (55); \ + } \ + f_##DATA_TYPE##_##INDEX_TYPE (dest_##DATA_TYPE##_##INDEX_TYPE, \ + src_##DATA_TYPE##_##INDEX_TYPE, \ + index_##DATA_TYPE##_##INDEX_TYPE); \ + for (int i = 0; i < 100; i++) \ + { \ + assert (dest_##DATA_TYPE##_##INDEX_TYPE[i * 2] \ + == (src_##DATA_TYPE##_##INDEX_TYPE \ + [index_##DATA_TYPE##_##INDEX_TYPE[i * 2]] \ + + 1)); \ + assert (dest_##DATA_TYPE##_##INDEX_TYPE[i * 2 + 1] \ + == (src_##DATA_TYPE##_##INDEX_TYPE \ + [index_##DATA_TYPE##_##INDEX_TYPE[i * 2 + 1]] \ + + 2)); \ + } + + RUN_LOOP (int8_t, int8_t) + RUN_LOOP (uint8_t, int8_t) + RUN_LOOP (int16_t, int8_t) + RUN_LOOP (uint16_t, int8_t) + RUN_LOOP (int32_t, int8_t) + RUN_LOOP (uint32_t, int8_t) + RUN_LOOP (int64_t, int8_t) + RUN_LOOP (uint64_t, int8_t) + RUN_LOOP (_Float16, int8_t) + RUN_LOOP (float, int8_t) + RUN_LOOP (double, int8_t) + RUN_LOOP (int8_t, int16_t) + RUN_LOOP (uint8_t, int16_t) + RUN_LOOP (int16_t, int16_t) + RUN_LOOP (uint16_t, int16_t) + RUN_LOOP (int32_t, int16_t) + RUN_LOOP (uint32_t, int16_t) + RUN_LOOP (int64_t, int16_t) + RUN_LOOP (uint64_t, int16_t) + RUN_LOOP (_Float16, int16_t) + RUN_LOOP (float, int16_t) + RUN_LOOP (double, int16_t) + RUN_LOOP (int8_t, int32_t) + RUN_LOOP (uint8_t, int32_t) + RUN_LOOP (int16_t, int32_t) + RUN_LOOP (uint16_t, int32_t) + RUN_LOOP (int32_t, int32_t) + RUN_LOOP (uint32_t, int32_t) + RUN_LOOP (int64_t, int32_t) + RUN_LOOP (uint64_t, int32_t) + RUN_LOOP (_Float16, int32_t) + RUN_LOOP (float, int32_t) + RUN_LOOP (double, int32_t) + RUN_LOOP (int8_t, int64_t) + RUN_LOOP (uint8_t, int64_t) + RUN_LOOP (int16_t, int64_t) + RUN_LOOP (uint16_t, int64_t) + RUN_LOOP (int32_t, int64_t) + RUN_LOOP (uint32_t, int64_t) + RUN_LOOP (int64_t, int64_t) + RUN_LOOP (uint64_t, int64_t) + RUN_LOOP (_Float16, int64_t) + RUN_LOOP (float, int64_t) + RUN_LOOP (double, int64_t) + RUN_LOOP (int8_t, uint8_t) + RUN_LOOP (uint8_t, uint8_t) + RUN_LOOP (int16_t, uint8_t) + RUN_LOOP (uint16_t, uint8_t) + RUN_LOOP (int32_t, uint8_t) + RUN_LOOP (uint32_t, uint8_t) + RUN_LOOP (int64_t, uint8_t) + RUN_LOOP (uint64_t, uint8_t) + RUN_LOOP (_Float16, uint8_t) + RUN_LOOP (float, uint8_t) + RUN_LOOP (double, uint8_t) + RUN_LOOP (int8_t, uint16_t) + RUN_LOOP (uint8_t, uint16_t) + RUN_LOOP (int16_t, uint16_t) + RUN_LOOP (uint16_t, uint16_t) + RUN_LOOP (int32_t, uint16_t) + RUN_LOOP (uint32_t, uint16_t) + RUN_LOOP (int64_t, uint16_t) + RUN_LOOP (uint64_t, uint16_t) + RUN_LOOP (_Float16, uint16_t) + RUN_LOOP (float, uint16_t) + RUN_LOOP (double, uint16_t) + RUN_LOOP (int8_t, uint32_t) + RUN_LOOP (uint8_t, uint32_t) + RUN_LOOP (int16_t, uint32_t) + RUN_LOOP (uint16_t, uint32_t) + RUN_LOOP (int32_t, uint32_t) + RUN_LOOP (uint32_t, uint32_t) + RUN_LOOP (int64_t, uint32_t) + RUN_LOOP (uint64_t, uint32_t) + RUN_LOOP (_Float16, uint32_t) + RUN_LOOP (float, uint32_t) + RUN_LOOP (double, uint32_t) + RUN_LOOP (int8_t, uint64_t) + RUN_LOOP (uint8_t, uint64_t) + RUN_LOOP (int16_t, uint64_t) + RUN_LOOP (uint16_t, uint64_t) + RUN_LOOP (int32_t, uint64_t) + RUN_LOOP (uint32_t, uint64_t) + RUN_LOOP (int64_t, uint64_t) + RUN_LOOP (uint64_t, uint64_t) + RUN_LOOP (_Float16, uint64_t) + RUN_LOOP (float, uint64_t) + RUN_LOOP (double, uint64_t) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c new file mode 100644 index 0000000..76c6df3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-2.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c new file mode 100644 index 0000000..0fd6426 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-3.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c new file mode 100644 index 0000000..069d232 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-4.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c new file mode 100644 index 0000000..499e555 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-5.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c new file mode 100644 index 0000000..ec6587a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-6.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c new file mode 100644 index 0000000..c162879 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-7.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c new file mode 100644 index 0000000..e1744f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-8.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c new file mode 100644 index 0000000..3ad6d33 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "gather_load-9.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c new file mode 100644 index 0000000..a5de0de --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t +#define INDEX16 uint16_t +#define INDEX32 uint32_t +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c new file mode 100644 index 0000000..74a0d05 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c new file mode 100644 index 0000000..98c5b46 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c @@ -0,0 +1,116 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-vect-cost-model -fdump-tree-vect-details" } */ + +#include + +#define TEST_LOOP(DATA_TYPE, INDEX_TYPE) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE##_##INDEX_TYPE (DATA_TYPE *restrict y, DATA_TYPE *restrict x, \ + INDEX_TYPE *restrict index, \ + INDEX_TYPE *restrict cond) \ + { \ + for (int i = 0; i < 100; ++i) \ + { \ + if (cond[i * 2]) \ + y[i * 2] = x[index[i * 2]] + 1; \ + if (cond[i * 2 + 1]) \ + y[i * 2 + 1] = x[index[i * 2 + 1]] + 2; \ + } \ + } + +TEST_LOOP (int8_t, int8_t) +TEST_LOOP (uint8_t, int8_t) +TEST_LOOP (int16_t, int8_t) +TEST_LOOP (uint16_t, int8_t) +TEST_LOOP (int32_t, int8_t) +TEST_LOOP (uint32_t, int8_t) +TEST_LOOP (int64_t, int8_t) +TEST_LOOP (uint64_t, int8_t) +TEST_LOOP (_Float16, int8_t) +TEST_LOOP (float, int8_t) +TEST_LOOP (double, int8_t) +TEST_LOOP (int8_t, int16_t) +TEST_LOOP (uint8_t, int16_t) +TEST_LOOP (int16_t, int16_t) +TEST_LOOP (uint16_t, int16_t) +TEST_LOOP (int32_t, int16_t) +TEST_LOOP (uint32_t, int16_t) +TEST_LOOP (int64_t, int16_t) +TEST_LOOP (uint64_t, int16_t) +TEST_LOOP (_Float16, int16_t) +TEST_LOOP (float, int16_t) +TEST_LOOP (double, int16_t) +TEST_LOOP (int8_t, int32_t) +TEST_LOOP (uint8_t, int32_t) +TEST_LOOP (int16_t, int32_t) +TEST_LOOP (uint16_t, int32_t) +TEST_LOOP (int32_t, int32_t) +TEST_LOOP (uint32_t, int32_t) +TEST_LOOP (int64_t, int32_t) +TEST_LOOP (uint64_t, int32_t) +TEST_LOOP (_Float16, int32_t) +TEST_LOOP (float, int32_t) +TEST_LOOP (double, int32_t) +TEST_LOOP (int8_t, int64_t) +TEST_LOOP (uint8_t, int64_t) +TEST_LOOP (int16_t, int64_t) +TEST_LOOP (uint16_t, int64_t) +TEST_LOOP (int32_t, int64_t) +TEST_LOOP (uint32_t, int64_t) +TEST_LOOP (int64_t, int64_t) +TEST_LOOP (uint64_t, int64_t) +TEST_LOOP (_Float16, int64_t) +TEST_LOOP (float, int64_t) +TEST_LOOP (double, int64_t) +TEST_LOOP (int8_t, uint8_t) +TEST_LOOP (uint8_t, uint8_t) +TEST_LOOP (int16_t, uint8_t) +TEST_LOOP (uint16_t, uint8_t) +TEST_LOOP (int32_t, uint8_t) +TEST_LOOP (uint32_t, uint8_t) +TEST_LOOP (int64_t, uint8_t) +TEST_LOOP (uint64_t, uint8_t) +TEST_LOOP (_Float16, uint8_t) +TEST_LOOP (float, uint8_t) +TEST_LOOP (double, uint8_t) +TEST_LOOP (int8_t, uint16_t) +TEST_LOOP (uint8_t, uint16_t) +TEST_LOOP (int16_t, uint16_t) +TEST_LOOP (uint16_t, uint16_t) +TEST_LOOP (int32_t, uint16_t) +TEST_LOOP (uint32_t, uint16_t) +TEST_LOOP (int64_t, uint16_t) +TEST_LOOP (uint64_t, uint16_t) +TEST_LOOP (_Float16, uint16_t) +TEST_LOOP (float, uint16_t) +TEST_LOOP (double, uint16_t) +TEST_LOOP (int8_t, uint32_t) +TEST_LOOP (uint8_t, uint32_t) +TEST_LOOP (int16_t, uint32_t) +TEST_LOOP (uint16_t, uint32_t) +TEST_LOOP (int32_t, uint32_t) +TEST_LOOP (uint32_t, uint32_t) +TEST_LOOP (int64_t, uint32_t) +TEST_LOOP (uint64_t, uint32_t) +TEST_LOOP (_Float16, uint32_t) +TEST_LOOP (float, uint32_t) +TEST_LOOP (double, uint32_t) +TEST_LOOP (int8_t, uint64_t) +TEST_LOOP (uint8_t, uint64_t) +TEST_LOOP (int16_t, uint64_t) +TEST_LOOP (uint16_t, uint64_t) +TEST_LOOP (int32_t, uint64_t) +TEST_LOOP (uint32_t, uint64_t) +TEST_LOOP (int64_t, uint64_t) +TEST_LOOP (uint64_t, uint64_t) +TEST_LOOP (_Float16, uint64_t) +TEST_LOOP (float, uint64_t) +TEST_LOOP (double, uint64_t) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 88 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-assembler-not "vluxei64\.v" } } */ +/* { dg-final { scan-assembler-not "vsuxei64\.v" } } */ +/* { dg-final { scan-assembler-not {vlse64\.v\s+v[0-9]+,\s*0\([a-x0-9]+\),\s*zero} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c new file mode 100644 index 0000000..03f84ce --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c new file mode 100644 index 0000000..8578001 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c new file mode 100644 index 0000000..b273caa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c new file mode 100644 index 0000000..5055d88 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 uint16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c new file mode 100644 index 0000000..2a4ae585 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 int16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c new file mode 100644 index 0000000..31d9414 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 uint32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c new file mode 100644 index 0000000..73ed230 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 int32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c new file mode 100644 index 0000000..2f64e80 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fno-schedule-insns -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[i] += src[indices[i]]; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c new file mode 100644 index 0000000..41f60bd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-1.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c new file mode 100644 index 0000000..9840434 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-10.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c new file mode 100644 index 0000000..105c706 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c @@ -0,0 +1,140 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-mcmodel=medany" } */ + +#include "mask_gather_load-11.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, INDEX_TYPE) \ + DATA_TYPE dest_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + DATA_TYPE src_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + INDEX_TYPE index_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + INDEX_TYPE cond_##DATA_TYPE##_##INDEX_TYPE[202] = {0}; \ + for (int i = 0; i < 202; i++) \ + { \ + src_##DATA_TYPE##_##INDEX_TYPE[i] \ + = (DATA_TYPE) ((i * 19 + 735) & (sizeof (DATA_TYPE) * 7 - 1)); \ + dest_##DATA_TYPE##_##INDEX_TYPE[i] \ + = (DATA_TYPE) ((i * 7 + 666) & (sizeof (DATA_TYPE) * 5 - 1)); \ + dest2_##DATA_TYPE##_##INDEX_TYPE[i] \ + = (DATA_TYPE) ((i * 7 + 666) & (sizeof (DATA_TYPE) * 5 - 1)); \ + index_##DATA_TYPE##_##INDEX_TYPE[i] = (i * 7) % (55); \ + cond_##DATA_TYPE##_##INDEX_TYPE[i] = (INDEX_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE##_##INDEX_TYPE (dest_##DATA_TYPE##_##INDEX_TYPE, \ + src_##DATA_TYPE##_##INDEX_TYPE, \ + index_##DATA_TYPE##_##INDEX_TYPE, \ + cond_##DATA_TYPE##_##INDEX_TYPE); \ + for (int i = 0; i < 100; i++) \ + { \ + if (cond_##DATA_TYPE##_##INDEX_TYPE[i * 2]) \ + assert (dest_##DATA_TYPE##_##INDEX_TYPE[i * 2] \ + == (src_##DATA_TYPE##_##INDEX_TYPE \ + [index_##DATA_TYPE##_##INDEX_TYPE[i * 2]] \ + + 1)); \ + else \ + assert (dest_##DATA_TYPE##_##INDEX_TYPE[i * 2] \ + == dest2_##DATA_TYPE##_##INDEX_TYPE[i * 2]); \ + if (cond_##DATA_TYPE##_##INDEX_TYPE[i * 2 + 1]) \ + assert (dest_##DATA_TYPE##_##INDEX_TYPE[i * 2 + 1] \ + == (src_##DATA_TYPE##_##INDEX_TYPE \ + [index_##DATA_TYPE##_##INDEX_TYPE[i * 2 + 1]] \ + + 2)); \ + else \ + assert (dest_##DATA_TYPE##_##INDEX_TYPE[i * 2 + 1] \ + == dest2_##DATA_TYPE##_##INDEX_TYPE[i * 2 + 1]); \ + } + + RUN_LOOP (int8_t, int8_t) + RUN_LOOP (uint8_t, int8_t) + RUN_LOOP (int16_t, int8_t) + RUN_LOOP (uint16_t, int8_t) + RUN_LOOP (int32_t, int8_t) + RUN_LOOP (uint32_t, int8_t) + RUN_LOOP (int64_t, int8_t) + RUN_LOOP (uint64_t, int8_t) + RUN_LOOP (_Float16, int8_t) + RUN_LOOP (float, int8_t) + RUN_LOOP (double, int8_t) + RUN_LOOP (int8_t, int16_t) + RUN_LOOP (uint8_t, int16_t) + RUN_LOOP (int16_t, int16_t) + RUN_LOOP (uint16_t, int16_t) + RUN_LOOP (int32_t, int16_t) + RUN_LOOP (uint32_t, int16_t) + RUN_LOOP (int64_t, int16_t) + RUN_LOOP (uint64_t, int16_t) + RUN_LOOP (_Float16, int16_t) + RUN_LOOP (float, int16_t) + RUN_LOOP (double, int16_t) + RUN_LOOP (int8_t, int32_t) + RUN_LOOP (uint8_t, int32_t) + RUN_LOOP (int16_t, int32_t) + RUN_LOOP (uint16_t, int32_t) + RUN_LOOP (int32_t, int32_t) + RUN_LOOP (uint32_t, int32_t) + RUN_LOOP (int64_t, int32_t) + RUN_LOOP (uint64_t, int32_t) + RUN_LOOP (_Float16, int32_t) + RUN_LOOP (float, int32_t) + RUN_LOOP (double, int32_t) + RUN_LOOP (int8_t, int64_t) + RUN_LOOP (uint8_t, int64_t) + RUN_LOOP (int16_t, int64_t) + RUN_LOOP (uint16_t, int64_t) + RUN_LOOP (int32_t, int64_t) + RUN_LOOP (uint32_t, int64_t) + RUN_LOOP (int64_t, int64_t) + RUN_LOOP (uint64_t, int64_t) + RUN_LOOP (_Float16, int64_t) + RUN_LOOP (float, int64_t) + RUN_LOOP (double, int64_t) + RUN_LOOP (int8_t, uint8_t) + RUN_LOOP (uint8_t, uint8_t) + RUN_LOOP (int16_t, uint8_t) + RUN_LOOP (uint16_t, uint8_t) + RUN_LOOP (int32_t, uint8_t) + RUN_LOOP (uint32_t, uint8_t) + RUN_LOOP (int64_t, uint8_t) + RUN_LOOP (uint64_t, uint8_t) + RUN_LOOP (_Float16, uint8_t) + RUN_LOOP (float, uint8_t) + RUN_LOOP (double, uint8_t) + RUN_LOOP (int8_t, uint16_t) + RUN_LOOP (uint8_t, uint16_t) + RUN_LOOP (int16_t, uint16_t) + RUN_LOOP (uint16_t, uint16_t) + RUN_LOOP (int32_t, uint16_t) + RUN_LOOP (uint32_t, uint16_t) + RUN_LOOP (int64_t, uint16_t) + RUN_LOOP (uint64_t, uint16_t) + RUN_LOOP (_Float16, uint16_t) + RUN_LOOP (float, uint16_t) + RUN_LOOP (double, uint16_t) + RUN_LOOP (int8_t, uint32_t) + RUN_LOOP (uint8_t, uint32_t) + RUN_LOOP (int16_t, uint32_t) + RUN_LOOP (uint16_t, uint32_t) + RUN_LOOP (int32_t, uint32_t) + RUN_LOOP (uint32_t, uint32_t) + RUN_LOOP (int64_t, uint32_t) + RUN_LOOP (uint64_t, uint32_t) + RUN_LOOP (_Float16, uint32_t) + RUN_LOOP (float, uint32_t) + RUN_LOOP (double, uint32_t) + RUN_LOOP (int8_t, uint64_t) + RUN_LOOP (uint8_t, uint64_t) + RUN_LOOP (int16_t, uint64_t) + RUN_LOOP (uint16_t, uint64_t) + RUN_LOOP (int32_t, uint64_t) + RUN_LOOP (uint32_t, uint64_t) + RUN_LOOP (int64_t, uint64_t) + RUN_LOOP (uint64_t, uint64_t) + RUN_LOOP (_Float16, uint64_t) + RUN_LOOP (float, uint64_t) + RUN_LOOP (double, uint64_t) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c new file mode 100644 index 0000000..33ddb5d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-2.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c new file mode 100644 index 0000000..9f06fbe --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-3.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c new file mode 100644 index 0000000..ae578f0c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-4.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c new file mode 100644 index 0000000..741abd1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-5.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c new file mode 100644 index 0000000..a14a5c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-6.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c new file mode 100644 index 0000000..5f6ec81 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-mcmodel=medany" } */ + +#include "mask_gather_load-7.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c new file mode 100644 index 0000000..a34688f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-mcmodel=medany" } */ + +#include "mask_gather_load-8.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c new file mode 100644 index 0000000..1cfdede --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_gather_load-9.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128] = {0}; \ + DATA_TYPE dest2_##DATA_TYPE[128] = {0}; \ + DATA_TYPE src_##DATA_TYPE[128] = {0}; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128] = {0}; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[i] \ + == (dest2_##DATA_TYPE[i] \ + + src_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]])); \ + else \ + assert (dest_##DATA_TYPE[i] == dest2_##DATA_TYPE[i]); \ + } + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c new file mode 100644 index 0000000..623de41 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t +#define INDEX16 uint16_t +#define INDEX32 uint32_t +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c new file mode 100644 index 0000000..55112b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c new file mode 100644 index 0000000..32a572d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c new file mode 100644 index 0000000..fbaaa9d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c new file mode 100644 index 0000000..9b08661 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c new file mode 100644 index 0000000..dd26635 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 uint16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c new file mode 100644 index 0000000..fa0206a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 int16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c new file mode 100644 index 0000000..325e86c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 uint32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c new file mode 100644 index 0000000..b4b84e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 int32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c new file mode 100644 index 0000000..77a9af9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices, INDEX##BITS *restrict cond) \ + { \ + for (int i = 0; i < 128; ++i) \ + if (cond[i]) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c new file mode 100644 index 0000000..e0d52bf62 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-1.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c new file mode 100644 index 0000000..c1af0d3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-10.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c new file mode 100644 index 0000000..6b1b02ea --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-2.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c new file mode 100644 index 0000000..cef0bde --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-3.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c new file mode 100644 index 0000000..88a74d5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-4.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c new file mode 100644 index 0000000..06804ab --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-5.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c new file mode 100644 index 0000000..c6c9a67 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-6.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c new file mode 100644 index 0000000..06a37f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-mcmodel=medany" } */ + +#include "mask_scatter_store-7.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c new file mode 100644 index 0000000..8ee35d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-8.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c new file mode 100644 index 0000000..c27a673 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "mask_scatter_store-9.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + INDEX##BITS cond_##DATA_TYPE##_##BITS[128] = {0}; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + cond_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i & 0x3) == 3); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS, cond_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + { \ + if (cond_##DATA_TYPE##_##BITS[i]) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); \ + else \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == dest2_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]]); \ + } + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c new file mode 100644 index 0000000..6a39026 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t +#define INDEX16 uint16_t +#define INDEX32 uint32_t +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c new file mode 100644 index 0000000..feb58d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c new file mode 100644 index 0000000..e4c587f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c new file mode 100644 index 0000000..33ad256 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 uint8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c new file mode 100644 index 0000000..48d3056 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX8 int8_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 8) \ + T (uint8_t, 8) \ + T (int16_t, 8) \ + T (uint16_t, 8) \ + T (_Float16, 8) \ + T (int32_t, 8) \ + T (uint32_t, 8) \ + T (float, 8) \ + T (int64_t, 8) \ + T (uint64_t, 8) \ + T (double, 8) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c new file mode 100644 index 0000000..83ddc44 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 uint16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c new file mode 100644 index 0000000..11eb68b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX16 int16_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 16) \ + T (uint8_t, 16) \ + T (int16_t, 16) \ + T (uint16_t, 16) \ + T (_Float16, 16) \ + T (int32_t, 16) \ + T (uint32_t, 16) \ + T (float, 16) \ + T (int64_t, 16) \ + T (uint64_t, 16) \ + T (double, 16) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c new file mode 100644 index 0000000..2e32347 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 uint32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c new file mode 100644 index 0000000..e6732fe --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX32 int32_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 32) \ + T (uint8_t, 32) \ + T (int16_t, 32) \ + T (uint16_t, 32) \ + T (_Float16, 32) \ + T (int32_t, 32) \ + T (uint32_t, 32) \ + T (float, 32) \ + T (int64_t, 32) \ + T (uint64_t, 32) \ + T (double, 32) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c new file mode 100644 index 0000000..766a52b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ + +#include + +#define INDEX64 uint64_t + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS *restrict indices) \ + { \ + for (int i = 0; i < 128; ++i) \ + dest[indices[i]] = src[i] + 1; \ + } + +#define TEST_ALL(T) \ + T (int8_t, 64) \ + T (uint8_t, 64) \ + T (int16_t, 64) \ + T (uint16_t, 64) \ + T (_Float16, 64) \ + T (int32_t, 64) \ + T (uint32_t, 64) \ + T (float, 64) \ + T (int64_t, 64) \ + T (uint64_t, 64) \ + T (double, 64) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ +/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c new file mode 100644 index 0000000..cafa64f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-1.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c new file mode 100644 index 0000000..79f6885 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-10.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c new file mode 100644 index 0000000..376db08 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-mcmodel=medany" } */ + +#include "scatter_store-2.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c new file mode 100644 index 0000000..103b864 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-3.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c new file mode 100644 index 0000000..f5f89c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-4.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c new file mode 100644 index 0000000..049251e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-5.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c new file mode 100644 index 0000000..59c8e70 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-6.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c new file mode 100644 index 0000000..a244011 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-7.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c new file mode 100644 index 0000000..080c9b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ + + +#include "scatter_store-8.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c new file mode 100644 index 0000000..cc9f20f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-mcmodel=medany" } */ + +#include "scatter_store-9.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE[128]; \ + DATA_TYPE dest2_##DATA_TYPE[128]; \ + DATA_TYPE src_##DATA_TYPE[128]; \ + INDEX##BITS indices_##DATA_TYPE##_##BITS[128]; \ + for (int i = 0; i < 128; i++) \ + { \ + dest_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE[i] = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE[i] = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + indices_##DATA_TYPE##_##BITS[i] = (DATA_TYPE) ((i * 3 + 67) % 128); \ + } \ + f_##DATA_TYPE (dest_##DATA_TYPE, src_##DATA_TYPE, \ + indices_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < 128; i++) \ + assert (dest_##DATA_TYPE[indices_##DATA_TYPE##_##BITS[i]] \ + == (src_##DATA_TYPE[i] + 1)); + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c new file mode 100644 index 0000000..0c64f3e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */ + +#include + +#ifndef INDEX8 +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t +#endif + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE##_##BITS (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS stride, INDEX##BITS n) \ + { \ + for (INDEX##BITS i = 0; i < n; ++i) \ + dest[i] += src[i * stride]; \ + } + +#define TEST_TYPE(T, DATA_TYPE) \ + T (DATA_TYPE, 8) \ + T (DATA_TYPE, 16) \ + T (DATA_TYPE, 32) \ + T (DATA_TYPE, 64) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int8_t) \ + TEST_TYPE (T, uint8_t) \ + TEST_TYPE (T, int16_t) \ + TEST_TYPE (T, uint16_t) \ + TEST_TYPE (T, _Float16) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, float) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) \ + TEST_TYPE (T, double) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times " \.LEN_MASK_GATHER_LOAD" 66 "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c new file mode 100644 index 0000000..0f23420 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */ + +#include + +#ifndef INDEX8 +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t +#endif + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE##_##BITS (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS stride, INDEX##BITS n) \ + { \ + for (INDEX##BITS i = 0; i < (BITS + 13); ++i) \ + dest[i] += src[i * (BITS - 3)]; \ + } + +#define TEST_TYPE(T, DATA_TYPE) \ + T (DATA_TYPE, 8) \ + T (DATA_TYPE, 16) \ + T (DATA_TYPE, 32) \ + T (DATA_TYPE, 64) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int8_t) \ + TEST_TYPE (T, uint8_t) \ + TEST_TYPE (T, int16_t) \ + TEST_TYPE (T, uint16_t) \ + TEST_TYPE (T, _Float16) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, float) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) \ + TEST_TYPE (T, double) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times " \.LEN_MASK_GATHER_LOAD" 46 "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-1.c new file mode 100644 index 0000000..4b03c25 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-1.c @@ -0,0 +1,84 @@ +/* { dg-do run { target { riscv_vector } } } */ + +#include "strided_load-1.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE dest2_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE src_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + INDEX##BITS stride_##DATA_TYPE##_##BITS = (BITS - 3); \ + INDEX##BITS n_##DATA_TYPE##_##BITS = (BITS + 13); \ + for (INDEX##BITS i = 0; \ + i < stride_##DATA_TYPE##_##BITS * n_##DATA_TYPE##_##BITS; i++) \ + { \ + dest_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + } \ + f_##DATA_TYPE##_##BITS (dest_##DATA_TYPE##_##BITS, src_##DATA_TYPE##_##BITS, \ + stride_##DATA_TYPE##_##BITS, \ + n_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < n_##DATA_TYPE##_##BITS; i++) \ + { \ + assert ( \ + dest_##DATA_TYPE##_##BITS[i] \ + == (dest2_##DATA_TYPE##_##BITS[i] \ + + src_##DATA_TYPE##_##BITS[i * stride_##DATA_TYPE##_##BITS])); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-2.c new file mode 100644 index 0000000..8499e4c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-2.c @@ -0,0 +1,84 @@ +/* { dg-do run { target { riscv_vector } } } */ + +#include "strided_load-2.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE dest2_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE src_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + INDEX##BITS stride_##DATA_TYPE##_##BITS = (BITS - 3); \ + INDEX##BITS n_##DATA_TYPE##_##BITS = (BITS + 13); \ + for (INDEX##BITS i = 0; \ + i < stride_##DATA_TYPE##_##BITS * n_##DATA_TYPE##_##BITS; i++) \ + { \ + dest_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + } \ + f_##DATA_TYPE##_##BITS (dest_##DATA_TYPE##_##BITS, src_##DATA_TYPE##_##BITS, \ + stride_##DATA_TYPE##_##BITS, \ + n_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < n_##DATA_TYPE##_##BITS; i++) \ + { \ + assert ( \ + dest_##DATA_TYPE##_##BITS[i] \ + == (dest2_##DATA_TYPE##_##BITS[i] \ + + src_##DATA_TYPE##_##BITS[i * stride_##DATA_TYPE##_##BITS])); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c new file mode 100644 index 0000000..2418a0d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */ + +#include + +#ifndef INDEX8 +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t +#endif + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE##_##BITS (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS stride, INDEX##BITS n) \ + { \ + for (INDEX##BITS i = 0; i < n; ++i) \ + dest[i * stride] = src[i] + BITS; \ + } + +#define TEST_TYPE(T, DATA_TYPE) \ + T (DATA_TYPE, 8) \ + T (DATA_TYPE, 16) \ + T (DATA_TYPE, 32) \ + T (DATA_TYPE, 64) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int8_t) \ + TEST_TYPE (T, uint8_t) \ + TEST_TYPE (T, int16_t) \ + TEST_TYPE (T, uint16_t) \ + TEST_TYPE (T, _Float16) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, float) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) \ + TEST_TYPE (T, double) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times " \.LEN_MASK_SCATTER_STORE" 66 "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c new file mode 100644 index 0000000..83e101d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O3 --param riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */ + +#include + +#ifndef INDEX8 +#define INDEX8 int8_t +#define INDEX16 int16_t +#define INDEX32 int32_t +#define INDEX64 int64_t +#endif + +#define TEST_LOOP(DATA_TYPE, BITS) \ + void __attribute__ ((noinline, noclone)) \ + f_##DATA_TYPE##_##BITS (DATA_TYPE *restrict dest, DATA_TYPE *restrict src, \ + INDEX##BITS stride, INDEX##BITS n) \ + { \ + for (INDEX##BITS i = 0; i < n; ++i) \ + dest[i * (BITS - 3)] = src[i] + BITS; \ + } + +#define TEST_TYPE(T, DATA_TYPE) \ + T (DATA_TYPE, 8) \ + T (DATA_TYPE, 16) \ + T (DATA_TYPE, 32) \ + T (DATA_TYPE, 64) + +#define TEST_ALL(T) \ + TEST_TYPE (T, int8_t) \ + TEST_TYPE (T, uint8_t) \ + TEST_TYPE (T, int16_t) \ + TEST_TYPE (T, uint16_t) \ + TEST_TYPE (T, _Float16) \ + TEST_TYPE (T, int32_t) \ + TEST_TYPE (T, uint32_t) \ + TEST_TYPE (T, float) \ + TEST_TYPE (T, int64_t) \ + TEST_TYPE (T, uint64_t) \ + TEST_TYPE (T, double) + +TEST_ALL (TEST_LOOP) + +/* { dg-final { scan-tree-dump-times " \.LEN_MASK_SCATTER_STORE" 44 "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-1.c new file mode 100644 index 0000000..e9dca46 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-1.c @@ -0,0 +1,82 @@ +/* { dg-do run { target { riscv_vector } } } */ + +#include "strided_store-1.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE dest2_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE src_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + INDEX##BITS stride_##DATA_TYPE##_##BITS = (BITS - 3); \ + INDEX##BITS n_##DATA_TYPE##_##BITS = (BITS + 13); \ + for (INDEX##BITS i = 0; \ + i < stride_##DATA_TYPE##_##BITS * n_##DATA_TYPE##_##BITS; i++) \ + { \ + dest_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + } \ + f_##DATA_TYPE##_##BITS (dest_##DATA_TYPE##_##BITS, src_##DATA_TYPE##_##BITS, \ + stride_##DATA_TYPE##_##BITS, \ + n_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < n_##DATA_TYPE##_##BITS; i++) \ + { \ + assert (dest_##DATA_TYPE##_##BITS[i * stride_##DATA_TYPE##_##BITS] \ + == (src_##DATA_TYPE##_##BITS[i] + BITS)); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-2.c new file mode 100644 index 0000000..509def7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-2.c @@ -0,0 +1,82 @@ +/* { dg-do run { target { riscv_vector } } } */ + +#include "strided_store-2.c" +#include + +int +main (void) +{ +#define RUN_LOOP(DATA_TYPE, BITS) \ + DATA_TYPE dest_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE dest2_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + DATA_TYPE src_##DATA_TYPE##_##BITS[(BITS - 3) * (BITS + 13)]; \ + INDEX##BITS stride_##DATA_TYPE##_##BITS = (BITS - 3); \ + INDEX##BITS n_##DATA_TYPE##_##BITS = (BITS + 13); \ + for (INDEX##BITS i = 0; \ + i < stride_##DATA_TYPE##_##BITS * n_##DATA_TYPE##_##BITS; i++) \ + { \ + dest_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + dest2_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 81 + 735) & (BITS - 1)); \ + src_##DATA_TYPE##_##BITS[i] \ + = (DATA_TYPE) ((i * 13 + 9107) & (BITS - 1)); \ + } \ + f_##DATA_TYPE##_##BITS (dest_##DATA_TYPE##_##BITS, src_##DATA_TYPE##_##BITS, \ + stride_##DATA_TYPE##_##BITS, \ + n_##DATA_TYPE##_##BITS); \ + for (int i = 0; i < n_##DATA_TYPE##_##BITS; i++) \ + { \ + assert (dest_##DATA_TYPE##_##BITS[i * stride_##DATA_TYPE##_##BITS] \ + == (src_##DATA_TYPE##_##BITS[i] + BITS)); \ + } + + RUN_LOOP (int8_t, 8) + RUN_LOOP (uint8_t, 8) + RUN_LOOP (int16_t, 8) + RUN_LOOP (uint16_t, 8) + RUN_LOOP (_Float16, 8) + RUN_LOOP (int32_t, 8) + RUN_LOOP (uint32_t, 8) + RUN_LOOP (float, 8) + RUN_LOOP (int64_t, 8) + RUN_LOOP (uint64_t, 8) + RUN_LOOP (double, 8) + + RUN_LOOP (int8_t, 16) + RUN_LOOP (uint8_t, 16) + RUN_LOOP (int16_t, 16) + RUN_LOOP (uint16_t, 16) + RUN_LOOP (_Float16, 16) + RUN_LOOP (int32_t, 16) + RUN_LOOP (uint32_t, 16) + RUN_LOOP (float, 16) + RUN_LOOP (int64_t, 16) + RUN_LOOP (uint64_t, 16) + RUN_LOOP (double, 16) + + RUN_LOOP (int8_t, 32) + RUN_LOOP (uint8_t, 32) + RUN_LOOP (int16_t, 32) + RUN_LOOP (uint16_t, 32) + RUN_LOOP (_Float16, 32) + RUN_LOOP (int32_t, 32) + RUN_LOOP (uint32_t, 32) + RUN_LOOP (float, 32) + RUN_LOOP (int64_t, 32) + RUN_LOOP (uint64_t, 32) + RUN_LOOP (double, 32) + + RUN_LOOP (int8_t, 64) + RUN_LOOP (uint8_t, 64) + RUN_LOOP (int16_t, 64) + RUN_LOOP (uint16_t, 64) + RUN_LOOP (_Float16, 64) + RUN_LOOP (int32_t, 64) + RUN_LOOP (uint32_t, 64) + RUN_LOOP (float, 64) + RUN_LOOP (int64_t, 64) + RUN_LOOP (uint64_t, 64) + RUN_LOOP (double, 64) + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp index 5e69235..19589fa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp +++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp @@ -90,5 +90,28 @@ foreach op $AUTOVEC_TEST_OPTS { dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/vls-vlmax/*.\[cS\]]] \ "-std=c99 -O3 -ftree-vectorize --param riscv-autovec-preference=fixed-vlmax" $CFLAGS +# gather-scatter tests +set AUTOVEC_TEST_OPTS [list \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m1 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m2 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m1 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m2 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m1 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m2 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m4 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O3 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m8 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m1 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m2 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m4 -fno-vect-cost-model -ffast-math} \ + {-ftree-vectorize -O2 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m8 -fno-vect-cost-model -ffast-math} ] +foreach op $AUTOVEC_TEST_OPTS { + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/gather-scatter/*.\[cS\]]] \ + "" "$op" +} + # All done. dg-finish -- cgit v1.1 From a7f6e6c483bcb9888d680e47e29c4a7859a61d4f Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:22:26 -0500 Subject: tree: Hide wi::from_mpz from GENERATOR_FILE Similar to r0-85707-g34917a102a4e0c for PR35051, the uses of mpz_t should be guarded with "#ifndef GENERATOR_FILE". This patch is to fix it and avoid some possible build errors. gcc/ChangeLog: * tree.h (wi::from_mpz): Hide from GENERATOR_FILE. --- gcc/tree.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/tree.h b/gcc/tree.h index fa02e29..4c04245 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -6467,7 +6467,9 @@ namespace wi wide_int min_value (const_tree); wide_int max_value (const_tree); +#ifndef GENERATOR_FILE wide_int from_mpz (const_tree, mpz_t, bool); +#endif } template -- cgit v1.1 From 574a1ea4406dd1dbf14e149a9b5d142f6cbdf32a Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:21 -0500 Subject: vect: Move vect_model_load_cost next to the transform in vectorizable_load This patch is an initial patch to move costing next to the transform, it still adopts vect_model_load_cost for costing but moves and duplicates it down according to the handlings of different vect_memory_access_types, hope it can make the subsequent patches easy to review. This patch should not have any functional changes. gcc/ChangeLog: * tree-vect-stmts.cc (vectorizable_load): Move and duplicate the call to vect_model_load_cost down to some different transform paths according to the handlings of different vect_memory_access_types. --- gcc/tree-vect-stmts.cc | 86 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 29 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index dd24f01..894c2b3 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -9680,7 +9680,9 @@ vectorizable_load (vec_info *vinfo, } } - if (!vec_stmt) /* transformation not required. */ + bool costing_p = !vec_stmt; + + if (costing_p) /* transformation not required. */ { if (slp_node && mask @@ -9714,17 +9716,13 @@ vectorizable_load (vec_info *vinfo, vinfo->any_known_not_updated_vssa = true; STMT_VINFO_TYPE (stmt_info) = load_vec_info_type; - vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, - alignment_support_scheme, misalignment, - &gs_info, slp_node, cost_vec); - return true; } if (!slp) gcc_assert (memory_access_type == STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info)); - if (dump_enabled_p ()) + if (dump_enabled_p () && !costing_p) dump_printf_loc (MSG_NOTE, vect_location, "transform load. ncopies = %d\n", ncopies); @@ -9735,13 +9733,26 @@ vectorizable_load (vec_info *vinfo, if (memory_access_type == VMAT_GATHER_SCATTER && gs_info.decl) { - vect_build_gather_load_calls (vinfo, - stmt_info, gsi, vec_stmt, &gs_info, mask); + if (costing_p) + vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, + alignment_support_scheme, misalignment, &gs_info, + slp_node, cost_vec); + else + vect_build_gather_load_calls (vinfo, stmt_info, gsi, vec_stmt, &gs_info, + mask); return true; } if (memory_access_type == VMAT_INVARIANT) { + if (costing_p) + { + vect_model_load_cost (vinfo, stmt_info, ncopies, vf, + memory_access_type, alignment_support_scheme, + misalignment, &gs_info, slp_node, cost_vec); + return true; + } + gcc_assert (!grouped_load && !mask && !bb_vinfo); /* If we have versioned for aliasing or the loop doesn't have any data dependencies that would preclude this, @@ -9797,6 +9808,14 @@ vectorizable_load (vec_info *vinfo, if (memory_access_type == VMAT_ELEMENTWISE || memory_access_type == VMAT_STRIDED_SLP) { + if (costing_p) + { + vect_model_load_cost (vinfo, stmt_info, ncopies, vf, + memory_access_type, alignment_support_scheme, + misalignment, &gs_info, slp_node, cost_vec); + return true; + } + gimple_stmt_iterator incr_gsi; bool insert_after; tree offvar; @@ -10247,17 +10266,20 @@ vectorizable_load (vec_info *vinfo, here, since we can't guarantee first_stmt_info DR has been initialized yet, use first_stmt_info_for_drptr DR by bumping the distance from first_stmt_info DR instead as below. */ - if (!diff_first_stmt_info) - msq = vect_setup_realignment (vinfo, - first_stmt_info, gsi, &realignment_token, - alignment_support_scheme, NULL_TREE, - &at_loop); - if (alignment_support_scheme == dr_explicit_realign_optimized) - { - phi = as_a (SSA_NAME_DEF_STMT (msq)); - offset = size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (vectype), - size_one_node); - gcc_assert (!first_stmt_info_for_drptr); + if (!costing_p) + { + if (!diff_first_stmt_info) + msq = vect_setup_realignment (vinfo, first_stmt_info, gsi, + &realignment_token, + alignment_support_scheme, NULL_TREE, + &at_loop); + if (alignment_support_scheme == dr_explicit_realign_optimized) + { + phi = as_a (SSA_NAME_DEF_STMT (msq)); + offset = size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (vectype), + size_one_node); + gcc_assert (!first_stmt_info_for_drptr); + } } } else @@ -10278,8 +10300,9 @@ vectorizable_load (vec_info *vinfo, else if (memory_access_type == VMAT_GATHER_SCATTER) { aggr_type = elem_type; - vect_get_strided_load_store_ops (stmt_info, loop_vinfo, gsi, &gs_info, - &bump, &vec_offset, loop_lens); + if (!costing_p) + vect_get_strided_load_store_ops (stmt_info, loop_vinfo, gsi, &gs_info, + &bump, &vec_offset, loop_lens); } else { @@ -10293,7 +10316,7 @@ vectorizable_load (vec_info *vinfo, auto_vec vec_offsets; auto_vec vec_masks; - if (mask) + if (mask && !costing_p) { if (slp_node) vect_get_slp_defs (SLP_TREE_CHILDREN (slp_node)[mask_index], @@ -10307,7 +10330,7 @@ vectorizable_load (vec_info *vinfo, for (j = 0; j < ncopies; j++) { /* 1. Create the vector or array pointer update chain. */ - if (j == 0) + if (j == 0 && !costing_p) { bool simd_lane_access_p = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) != 0; @@ -10366,7 +10389,7 @@ vectorizable_load (vec_info *vinfo, if (mask) vec_mask = vec_masks[0]; } - else + else if (!costing_p) { gcc_assert (!LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo)); if (dataref_offset) @@ -10383,7 +10406,7 @@ vectorizable_load (vec_info *vinfo, dr_chain.create (vec_num); gimple *new_stmt = NULL; - if (memory_access_type == VMAT_LOAD_STORE_LANES) + if (memory_access_type == VMAT_LOAD_STORE_LANES && !costing_p) { tree vec_array; @@ -10435,7 +10458,7 @@ vectorizable_load (vec_info *vinfo, /* Record that VEC_ARRAY is now dead. */ vect_clobber_variable (vinfo, stmt_info, gsi, vec_array); } - else + else if (!costing_p) { for (i = 0; i < vec_num; i++) { @@ -10959,7 +10982,7 @@ vectorizable_load (vec_info *vinfo, if (slp && !slp_perm) continue; - if (slp_perm) + if (slp_perm && !costing_p) { unsigned n_perms; /* For SLP we know we've seen all possible uses of dr_chain so @@ -10971,7 +10994,7 @@ vectorizable_load (vec_info *vinfo, nullptr, true); gcc_assert (ok); } - else + else if (!costing_p) { if (grouped_load) { @@ -10987,9 +11010,14 @@ vectorizable_load (vec_info *vinfo, } dr_chain.release (); } - if (!slp) + if (!slp && !costing_p) *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; + if (costing_p) + vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, + alignment_support_scheme, misalignment, &gs_info, + slp_node, cost_vec); + return true; } -- cgit v1.1 From 2115c22617c88fea0470cb87de284de904ed786e Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:21 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_GATHER_SCATTER && gs_info.decl This patch adds one extra argument cost_vec to function vect_build_gather_load_calls, so that we can do costing next to the tranform in vect_build_gather_load_calls. For now, the implementation just follows the handlings in vect_model_load_cost, it isn't so good, so placing one FIXME for any further improvement. This patch should not cause any functional changes. gcc/ChangeLog: * tree-vect-stmts.cc (vect_build_gather_load_calls): Add the handlings on costing with one extra argument cost_vec. (vectorizable_load): Adjust the call to vect_build_gather_load_calls. (vect_model_load_cost): Assert it won't get VMAT_GATHER_SCATTER with gs_info.decl set any more. --- gcc/tree-vect-stmts.cc | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 894c2b3..0975f66 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1151,6 +1151,8 @@ vect_model_load_cost (vec_info *vinfo, slp_tree slp_node, stmt_vector_for_cost *cost_vec) { + gcc_assert (memory_access_type != VMAT_GATHER_SCATTER || !gs_info->decl); + unsigned int inside_cost = 0, prologue_cost = 0; bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info); @@ -2873,7 +2875,8 @@ vect_build_gather_load_calls (vec_info *vinfo, stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, gimple **vec_stmt, gather_scatter_info *gs_info, - tree mask) + tree mask, + stmt_vector_for_cost *cost_vec) { loop_vec_info loop_vinfo = dyn_cast (vinfo); class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); @@ -2885,6 +2888,23 @@ vect_build_gather_load_calls (vec_info *vinfo, stmt_vec_info stmt_info, poly_uint64 gather_off_nunits = TYPE_VECTOR_SUBPARTS (gs_info->offset_vectype); + /* FIXME: Keep the previous costing way in vect_model_load_cost by costing + N scalar loads, but it should be tweaked to use target specific costs + on related gather load calls. */ + if (cost_vec) + { + unsigned int assumed_nunits = vect_nunits_for_cost (vectype); + unsigned int inside_cost; + inside_cost = record_stmt_cost (cost_vec, ncopies * assumed_nunits, + scalar_load, stmt_info, 0, vect_body); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: inside_cost = %d, " + "prologue_cost = 0 .\n", + inside_cost); + return; + } + tree arglist = TYPE_ARG_TYPES (TREE_TYPE (gs_info->decl)); tree rettype = TREE_TYPE (TREE_TYPE (gs_info->decl)); tree srctype = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist); @@ -9733,13 +9753,8 @@ vectorizable_load (vec_info *vinfo, if (memory_access_type == VMAT_GATHER_SCATTER && gs_info.decl) { - if (costing_p) - vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, - alignment_support_scheme, misalignment, &gs_info, - slp_node, cost_vec); - else - vect_build_gather_load_calls (vinfo, stmt_info, gsi, vec_stmt, &gs_info, - mask); + vect_build_gather_load_calls (vinfo, stmt_info, gsi, vec_stmt, &gs_info, + mask, cost_vec); return true; } -- cgit v1.1 From bbee29e82881c30c4f23e29db3e40de71cf49789 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:21 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_INVARIANT This patch adjusts the cost handling on VMAT_INVARIANT in function vectorizable_load. We don't call function vect_model_load_cost for it any more. To make the costing on VMAT_INVARIANT better, this patch is to query hoist_defs_of_uses for hoisting decision, and add costs for different "where" based on it. Currently function hoist_defs_of_uses would always hoist the defs of all SSA uses, adding one argument HOIST_P aims to avoid the actual hoisting during costing phase. gcc/ChangeLog: * tree-vect-stmts.cc (hoist_defs_of_uses): Add one argument HOIST_P. (vectorizable_load): Adjust the handling on VMAT_INVARIANT to respect hoisting decision and without calling vect_model_load_cost. (vect_model_load_cost): Assert it won't get VMAT_INVARIANT any more and remove VMAT_INVARIANT related handlings. --- gcc/tree-vect-stmts.cc | 53 ++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 0975f66..616c529 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1151,7 +1151,8 @@ vect_model_load_cost (vec_info *vinfo, slp_tree slp_node, stmt_vector_for_cost *cost_vec) { - gcc_assert (memory_access_type != VMAT_GATHER_SCATTER || !gs_info->decl); + gcc_assert ((memory_access_type != VMAT_GATHER_SCATTER || !gs_info->decl) + && memory_access_type != VMAT_INVARIANT); unsigned int inside_cost = 0, prologue_cost = 0; bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info); @@ -1256,16 +1257,6 @@ vect_model_load_cost (vec_info *vinfo, ncopies * assumed_nunits, scalar_load, stmt_info, 0, vect_body); } - else if (memory_access_type == VMAT_INVARIANT) - { - /* Invariant loads will ideally be hoisted and splat to a vector. */ - prologue_cost += record_stmt_cost (cost_vec, 1, - scalar_load, stmt_info, 0, - vect_prologue); - prologue_cost += record_stmt_cost (cost_vec, 1, - scalar_to_vec, stmt_info, 0, - vect_prologue); - } else vect_get_load_cost (vinfo, stmt_info, ncopies, alignment_support_scheme, misalignment, first_stmt_p, @@ -9371,10 +9362,11 @@ permute_vec_elements (vec_info *vinfo, /* Hoist the definitions of all SSA uses on STMT_INFO out of the loop LOOP, inserting them on the loops preheader edge. Returns true if we were successful in doing so (and thus STMT_INFO can be moved then), - otherwise returns false. */ + otherwise returns false. HOIST_P indicates if we want to hoist the + definitions of all SSA uses, it would be false when we are costing. */ static bool -hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop) +hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p) { ssa_op_iter i; tree op; @@ -9408,6 +9400,9 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop) if (!any) return true; + if (!hoist_p) + return true; + FOR_EACH_SSA_TREE_OPERAND (op, stmt_info->stmt, i, SSA_OP_USE) { gimple *def_stmt = SSA_NAME_DEF_STMT (op); @@ -9760,22 +9755,34 @@ vectorizable_load (vec_info *vinfo, if (memory_access_type == VMAT_INVARIANT) { - if (costing_p) - { - vect_model_load_cost (vinfo, stmt_info, ncopies, vf, - memory_access_type, alignment_support_scheme, - misalignment, &gs_info, slp_node, cost_vec); - return true; - } - gcc_assert (!grouped_load && !mask && !bb_vinfo); /* If we have versioned for aliasing or the loop doesn't have any data dependencies that would preclude this, then we are sure this is a loop invariant load and - thus we can insert it on the preheader edge. */ + thus we can insert it on the preheader edge. + TODO: hoist_defs_of_uses should ideally be computed + once at analysis time, remembered and used in the + transform time. */ bool hoist_p = (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) && !nested_in_vect_loop - && hoist_defs_of_uses (stmt_info, loop)); + && hoist_defs_of_uses (stmt_info, loop, !costing_p)); + if (costing_p) + { + enum vect_cost_model_location cost_loc + = hoist_p ? vect_prologue : vect_body; + unsigned int cost = record_stmt_cost (cost_vec, 1, scalar_load, + stmt_info, 0, cost_loc); + cost += record_stmt_cost (cost_vec, 1, scalar_to_vec, stmt_info, 0, + cost_loc); + unsigned int prologue_cost = hoist_p ? cost : 0; + unsigned int inside_cost = hoist_p ? 0 : cost; + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: inside_cost = %d, " + "prologue_cost = %d .\n", + inside_cost, prologue_cost); + return true; + } if (hoist_p) { gassign *stmt = as_a (stmt_info->stmt); -- cgit v1.1 From 090d83c25508c108756a534c765d2fa8c07eb261 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:21 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_ELEMENTWISE and VMAT_STRIDED_SLP This patch adjusts the cost handling on VMAT_ELEMENTWISE and VMAT_STRIDED_SLP in function vectorizable_load. We don't call function vect_model_load_cost for them any more. As PR82255 shows, we don't always need a vector construction there, moving costing next to the transform can make us only cost for vector construction when it's actually needed. Besides, it can count the number of loads consistently for some cases. PR tree-optimization/82255 gcc/ChangeLog: * tree-vect-stmts.cc (vectorizable_load): Adjust the cost handling on VMAT_ELEMENTWISE and VMAT_STRIDED_SLP without calling vect_model_load_cost. (vect_model_load_cost): Assert it won't get VMAT_ELEMENTWISE and VMAT_STRIDED_SLP any more, and remove their related handlings. gcc/testsuite/ChangeLog: * gcc.dg/vect/costmodel/ppc/costmodel-pr82255.c: New test. 2023-06-13 Bill Schmidt Kewen Lin --- .../gcc.dg/vect/costmodel/ppc/costmodel-pr82255.c | 31 ++++ gcc/tree-vect-stmts.cc | 170 +++++++++++++-------- 2 files changed, 134 insertions(+), 67 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-pr82255.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-pr82255.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-pr82255.c new file mode 100644 index 0000000..9317ee2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-pr82255.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +/* PR82255: Ensure we don't require a vec_construct cost when we aren't + going to generate a strided load. */ + +extern int abs (int __x) __attribute__ ((__nothrow__, __leaf__)) +__attribute__ ((__const__)); + +static int +foo (unsigned char *w, int i, unsigned char *x, int j) +{ + int tot = 0; + for (int a = 0; a < 16; a++) + { +#pragma GCC unroll 16 + for (int b = 0; b < 16; b++) + tot += abs (w[b] - x[b]); + w += i; + x += j; + } + return tot; +} + +void +bar (unsigned char *w, unsigned char *x, int i, int *result) +{ + *result = foo (w, 16, x, i); +} + +/* { dg-final { scan-tree-dump-times "vec_construct" 0 "vect" } } */ diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 616c529..4622d6a 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1152,7 +1152,9 @@ vect_model_load_cost (vec_info *vinfo, stmt_vector_for_cost *cost_vec) { gcc_assert ((memory_access_type != VMAT_GATHER_SCATTER || !gs_info->decl) - && memory_access_type != VMAT_INVARIANT); + && memory_access_type != VMAT_INVARIANT + && memory_access_type != VMAT_ELEMENTWISE + && memory_access_type != VMAT_STRIDED_SLP); unsigned int inside_cost = 0, prologue_cost = 0; bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info); @@ -1239,8 +1241,7 @@ vect_model_load_cost (vec_info *vinfo, } /* The loads themselves. */ - if (memory_access_type == VMAT_ELEMENTWISE - || memory_access_type == VMAT_GATHER_SCATTER) + if (memory_access_type == VMAT_GATHER_SCATTER) { tree vectype = STMT_VINFO_VECTYPE (stmt_info); unsigned int assumed_nunits = vect_nunits_for_cost (vectype); @@ -1262,10 +1263,10 @@ vect_model_load_cost (vec_info *vinfo, alignment_support_scheme, misalignment, first_stmt_p, &inside_cost, &prologue_cost, cost_vec, cost_vec, true); - if (memory_access_type == VMAT_ELEMENTWISE - || memory_access_type == VMAT_STRIDED_SLP - || (memory_access_type == VMAT_GATHER_SCATTER - && gs_info->ifn == IFN_LAST && !gs_info->decl)) + + if (memory_access_type == VMAT_GATHER_SCATTER + && gs_info->ifn == IFN_LAST + && !gs_info->decl) inside_cost += record_stmt_cost (cost_vec, ncopies, vec_construct, stmt_info, 0, vect_body); @@ -9830,14 +9831,6 @@ vectorizable_load (vec_info *vinfo, if (memory_access_type == VMAT_ELEMENTWISE || memory_access_type == VMAT_STRIDED_SLP) { - if (costing_p) - { - vect_model_load_cost (vinfo, stmt_info, ncopies, vf, - memory_access_type, alignment_support_scheme, - misalignment, &gs_info, slp_node, cost_vec); - return true; - } - gimple_stmt_iterator incr_gsi; bool insert_after; tree offvar; @@ -9849,6 +9842,7 @@ vectorizable_load (vec_info *vinfo, unsigned int const_nunits = nunits.to_constant (); unsigned HOST_WIDE_INT cst_offset = 0; tree dr_offset; + unsigned int inside_cost = 0; gcc_assert (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)); gcc_assert (!nested_in_vect_loop); @@ -9863,6 +9857,7 @@ vectorizable_load (vec_info *vinfo, first_stmt_info = stmt_info; first_dr_info = dr_info; } + if (slp && grouped_load) { group_size = DR_GROUP_SIZE (first_stmt_info); @@ -9879,43 +9874,44 @@ vectorizable_load (vec_info *vinfo, ref_type = reference_alias_ptr_type (DR_REF (dr_info->dr)); } - dr_offset = get_dr_vinfo_offset (vinfo, first_dr_info); - stride_base - = fold_build_pointer_plus - (DR_BASE_ADDRESS (first_dr_info->dr), - size_binop (PLUS_EXPR, - convert_to_ptrofftype (dr_offset), - convert_to_ptrofftype (DR_INIT (first_dr_info->dr)))); - stride_step = fold_convert (sizetype, DR_STEP (first_dr_info->dr)); + if (!costing_p) + { + dr_offset = get_dr_vinfo_offset (vinfo, first_dr_info); + stride_base = fold_build_pointer_plus ( + DR_BASE_ADDRESS (first_dr_info->dr), + size_binop (PLUS_EXPR, convert_to_ptrofftype (dr_offset), + convert_to_ptrofftype (DR_INIT (first_dr_info->dr)))); + stride_step = fold_convert (sizetype, DR_STEP (first_dr_info->dr)); - /* For a load with loop-invariant (but other than power-of-2) - stride (i.e. not a grouped access) like so: + /* For a load with loop-invariant (but other than power-of-2) + stride (i.e. not a grouped access) like so: - for (i = 0; i < n; i += stride) - ... = array[i]; + for (i = 0; i < n; i += stride) + ... = array[i]; - we generate a new induction variable and new accesses to - form a new vector (or vectors, depending on ncopies): + we generate a new induction variable and new accesses to + form a new vector (or vectors, depending on ncopies): - for (j = 0; ; j += VF*stride) - tmp1 = array[j]; - tmp2 = array[j + stride]; - ... - vectemp = {tmp1, tmp2, ...} - */ + for (j = 0; ; j += VF*stride) + tmp1 = array[j]; + tmp2 = array[j + stride]; + ... + vectemp = {tmp1, tmp2, ...} + */ - ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (stride_step), stride_step, - build_int_cst (TREE_TYPE (stride_step), vf)); + ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (stride_step), stride_step, + build_int_cst (TREE_TYPE (stride_step), vf)); - standard_iv_increment_position (loop, &incr_gsi, &insert_after); + standard_iv_increment_position (loop, &incr_gsi, &insert_after); - stride_base = cse_and_gimplify_to_preheader (loop_vinfo, stride_base); - ivstep = cse_and_gimplify_to_preheader (loop_vinfo, ivstep); - create_iv (stride_base, PLUS_EXPR, ivstep, NULL, - loop, &incr_gsi, insert_after, - &offvar, NULL); + stride_base = cse_and_gimplify_to_preheader (loop_vinfo, stride_base); + ivstep = cse_and_gimplify_to_preheader (loop_vinfo, ivstep); + create_iv (stride_base, PLUS_EXPR, ivstep, NULL, + loop, &incr_gsi, insert_after, + &offvar, NULL); - stride_step = cse_and_gimplify_to_preheader (loop_vinfo, stride_step); + stride_step = cse_and_gimplify_to_preheader (loop_vinfo, stride_step); + } running_off = offvar; alias_off = build_int_cst (ref_type, 0); @@ -9982,11 +9978,23 @@ vectorizable_load (vec_info *vinfo, unsigned int n_groups = 0; for (j = 0; j < ncopies; j++) { - if (nloads > 1) + if (nloads > 1 && !costing_p) vec_alloc (v, nloads); gimple *new_stmt = NULL; for (i = 0; i < nloads; i++) { + if (costing_p) + { + if (VECTOR_TYPE_P (ltype)) + vect_get_load_cost (vinfo, stmt_info, 1, + alignment_support_scheme, misalignment, + false, &inside_cost, nullptr, cost_vec, + cost_vec, true); + else + inside_cost += record_stmt_cost (cost_vec, 1, scalar_load, + stmt_info, 0, vect_body); + continue; + } tree this_off = build_int_cst (TREE_TYPE (alias_off), group_el * elsz + cst_offset); tree data_ref = build2 (MEM_REF, ltype, running_off, this_off); @@ -10017,42 +10025,70 @@ vectorizable_load (vec_info *vinfo, group_el = 0; } } + if (nloads > 1) { - tree vec_inv = build_constructor (lvectype, v); - new_temp = vect_init_vector (vinfo, stmt_info, - vec_inv, lvectype, gsi); - new_stmt = SSA_NAME_DEF_STMT (new_temp); - if (lvectype != vectype) + if (costing_p) + inside_cost += record_stmt_cost (cost_vec, 1, vec_construct, + stmt_info, 0, vect_body); + else { - new_stmt = gimple_build_assign (make_ssa_name (vectype), - VIEW_CONVERT_EXPR, - build1 (VIEW_CONVERT_EXPR, - vectype, new_temp)); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + tree vec_inv = build_constructor (lvectype, v); + new_temp = vect_init_vector (vinfo, stmt_info, vec_inv, + lvectype, gsi); + new_stmt = SSA_NAME_DEF_STMT (new_temp); + if (lvectype != vectype) + { + new_stmt + = gimple_build_assign (make_ssa_name (vectype), + VIEW_CONVERT_EXPR, + build1 (VIEW_CONVERT_EXPR, + vectype, new_temp)); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, + gsi); + } } } - if (slp) + if (!costing_p) { - if (slp_perm) - dr_chain.quick_push (gimple_assign_lhs (new_stmt)); + if (slp) + { + if (slp_perm) + dr_chain.quick_push (gimple_assign_lhs (new_stmt)); + else + SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + } else - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); - } - else - { - if (j == 0) - *vec_stmt = new_stmt; - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + { + if (j == 0) + *vec_stmt = new_stmt; + STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + } } } if (slp_perm) { unsigned n_perms; - vect_transform_slp_perm_load (vinfo, slp_node, dr_chain, gsi, vf, - false, &n_perms); + if (costing_p) + { + unsigned n_loads; + vect_transform_slp_perm_load (vinfo, slp_node, vNULL, NULL, vf, + true, &n_perms, &n_loads); + inside_cost += record_stmt_cost (cost_vec, n_perms, vec_perm, + first_stmt_info, 0, vect_body); + } + else + vect_transform_slp_perm_load (vinfo, slp_node, dr_chain, gsi, vf, + false, &n_perms); } + + if (costing_p && dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: inside_cost = %u, " + "prologue_cost = 0 .\n", + inside_cost); + return true; } -- cgit v1.1 From 131943ca22e012d6ab953b1406e1fd51eac4d418 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:21 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_GATHER_SCATTER This patch adjusts the cost handling on VMAT_GATHER_SCATTER in function vectorizable_load. We don't call function vect_model_load_cost for it any more. It's mainly for gather loads with IFN or emulated gather loads, it follows the handlings in function vect_model_load_cost. This patch shouldn't have any functional changes. gcc/ChangeLog: * tree-vect-stmts.cc (vectorizable_load): Adjust the cost handling on VMAT_GATHER_SCATTER without calling vect_model_load_cost. (vect_model_load_cost): Adjut the assertion on VMAT_GATHER_SCATTER, remove VMAT_GATHER_SCATTER related handlings and the related parameter gs_info. --- gcc/tree-vect-stmts.cc | 124 ++++++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 48 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 4622d6a..cbf9e28 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1147,11 +1147,10 @@ vect_model_load_cost (vec_info *vinfo, vect_memory_access_type memory_access_type, dr_alignment_support alignment_support_scheme, int misalignment, - gather_scatter_info *gs_info, slp_tree slp_node, stmt_vector_for_cost *cost_vec) { - gcc_assert ((memory_access_type != VMAT_GATHER_SCATTER || !gs_info->decl) + gcc_assert (memory_access_type != VMAT_GATHER_SCATTER && memory_access_type != VMAT_INVARIANT && memory_access_type != VMAT_ELEMENTWISE && memory_access_type != VMAT_STRIDED_SLP); @@ -1240,35 +1239,9 @@ vect_model_load_cost (vec_info *vinfo, group_size); } - /* The loads themselves. */ - if (memory_access_type == VMAT_GATHER_SCATTER) - { - tree vectype = STMT_VINFO_VECTYPE (stmt_info); - unsigned int assumed_nunits = vect_nunits_for_cost (vectype); - if (memory_access_type == VMAT_GATHER_SCATTER - && gs_info->ifn == IFN_LAST && !gs_info->decl) - /* For emulated gathers N offset vector element extracts - (we assume the scalar scaling and ptr + offset add is consumed by - the load). */ - inside_cost += record_stmt_cost (cost_vec, ncopies * assumed_nunits, - vec_to_scalar, stmt_info, 0, - vect_body); - /* N scalar loads plus gathering them into a vector. */ - inside_cost += record_stmt_cost (cost_vec, - ncopies * assumed_nunits, - scalar_load, stmt_info, 0, vect_body); - } - else - vect_get_load_cost (vinfo, stmt_info, ncopies, - alignment_support_scheme, misalignment, first_stmt_p, - &inside_cost, &prologue_cost, - cost_vec, cost_vec, true); - - if (memory_access_type == VMAT_GATHER_SCATTER - && gs_info->ifn == IFN_LAST - && !gs_info->decl) - inside_cost += record_stmt_cost (cost_vec, ncopies, vec_construct, - stmt_info, 0, vect_body); + vect_get_load_cost (vinfo, stmt_info, ncopies, alignment_support_scheme, + misalignment, first_stmt_p, &inside_cost, &prologue_cost, + cost_vec, cost_vec, true); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, @@ -10385,6 +10358,7 @@ vectorizable_load (vec_info *vinfo, } tree vec_mask = NULL_TREE; poly_uint64 group_elt = 0; + unsigned int inside_cost = 0; for (j = 0; j < ncopies; j++) { /* 1. Create the vector or array pointer update chain. */ @@ -10516,25 +10490,28 @@ vectorizable_load (vec_info *vinfo, /* Record that VEC_ARRAY is now dead. */ vect_clobber_variable (vinfo, stmt_info, gsi, vec_array); } - else if (!costing_p) + else { for (i = 0; i < vec_num; i++) { tree final_mask = NULL_TREE; tree final_len = NULL_TREE; tree bias = NULL_TREE; - if (loop_masks - && memory_access_type != VMAT_INVARIANT) - final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, - vec_num * ncopies, - vectype, vec_num * j + i); - if (vec_mask) - final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, - final_mask, vec_mask, gsi); - - if (i > 0 && !STMT_VINFO_GATHER_SCATTER_P (stmt_info)) - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, - gsi, stmt_info, bump); + if (!costing_p) + { + if (loop_masks && memory_access_type != VMAT_INVARIANT) + final_mask + = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, + vec_num * ncopies, vectype, + vec_num * j + i); + if (vec_mask) + final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, + final_mask, vec_mask, gsi); + + if (i > 0 && !STMT_VINFO_GATHER_SCATTER_P (stmt_info)) + dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, + gsi, stmt_info, bump); + } /* 2. Create the vector-load in the loop. */ switch (alignment_support_scheme) @@ -10548,6 +10525,16 @@ vectorizable_load (vec_info *vinfo, if (memory_access_type == VMAT_GATHER_SCATTER && gs_info.ifn != IFN_LAST) { + if (costing_p) + { + unsigned int cnunits + = vect_nunits_for_cost (vectype); + inside_cost + = record_stmt_cost (cost_vec, cnunits, + scalar_load, stmt_info, 0, + vect_body); + goto vec_num_loop_costing_end; + } if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) vec_offset = vec_offsets[vec_num * j + i]; tree zero = build_zero_cst (vectype); @@ -10599,6 +10586,25 @@ vectorizable_load (vec_info *vinfo, gcc_assert (!final_mask); unsigned HOST_WIDE_INT const_nunits = nunits.to_constant (); + if (costing_p) + { + /* For emulated gathers N offset vector element + offset add is consumed by the load). */ + inside_cost + = record_stmt_cost (cost_vec, const_nunits, + vec_to_scalar, stmt_info, 0, + vect_body); + /* N scalar loads plus gathering them into a + vector. */ + inside_cost + = record_stmt_cost (cost_vec, const_nunits, + scalar_load, stmt_info, 0, + vect_body); + inside_cost + = record_stmt_cost (cost_vec, 1, vec_construct, + stmt_info, 0, vect_body); + goto vec_num_loop_costing_end; + } unsigned HOST_WIDE_INT const_offset_nunits = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype) .to_constant (); @@ -10651,6 +10657,9 @@ vectorizable_load (vec_info *vinfo, break; } + if (costing_p) + goto vec_num_loop_costing_end; + align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); if (alignment_support_scheme == dr_aligned) @@ -10862,6 +10871,8 @@ vectorizable_load (vec_info *vinfo, } case dr_explicit_realign: { + if (costing_p) + goto vec_num_loop_costing_end; tree ptr, bump; tree vs = size_int (TYPE_VECTOR_SUBPARTS (vectype)); @@ -10924,6 +10935,8 @@ vectorizable_load (vec_info *vinfo, } case dr_explicit_realign_optimized: { + if (costing_p) + goto vec_num_loop_costing_end; if (TREE_CODE (dataref_ptr) == SSA_NAME) new_temp = copy_ssa_name (dataref_ptr); else @@ -11020,10 +11033,14 @@ vectorizable_load (vec_info *vinfo, gsi, stmt_info, bump); group_elt = 0; } +vec_num_loop_costing_end: + ; } /* Bump the vector pointer to account for a gap or for excess elements loaded for a permuted SLP load. */ - if (maybe_ne (group_gap_adj, 0U) && slp_perm) + if (!costing_p + && maybe_ne (group_gap_adj, 0U) + && slp_perm) { poly_wide_int bump_val = (wi::to_wide (TYPE_SIZE_UNIT (elem_type)) @@ -11072,9 +11089,20 @@ vectorizable_load (vec_info *vinfo, *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; if (costing_p) - vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, - alignment_support_scheme, misalignment, &gs_info, - slp_node, cost_vec); + { + if (memory_access_type == VMAT_GATHER_SCATTER) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: inside_cost = %u, " + "prologue_cost = 0 .\n", + inside_cost); + } + else + vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, + alignment_support_scheme, misalignment, slp_node, + cost_vec); + } return true; } -- cgit v1.1 From c4a8f4414215be6bf381398fdb391afd1440c8f9 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:21 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_LOAD_STORE_LANES This patch adjusts the cost handling on VMAT_LOAD_STORE_LANES in function vectorizable_load. We don't call function vect_model_load_cost for it any more. It follows what we do in the function vect_model_load_cost, and shouldn't have any functional changes. gcc/ChangeLog: * tree-vect-stmts.cc (vectorizable_load): Adjust the cost handling on VMAT_LOAD_STORE_LANES without calling vect_model_load_cost. (vectorizable_load): Remove VMAT_LOAD_STORE_LANES related handling and assert it will never get VMAT_LOAD_STORE_LANES. --- gcc/tree-vect-stmts.cc | 73 +++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 31 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index cbf9e28..0339469 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1153,7 +1153,8 @@ vect_model_load_cost (vec_info *vinfo, gcc_assert (memory_access_type != VMAT_GATHER_SCATTER && memory_access_type != VMAT_INVARIANT && memory_access_type != VMAT_ELEMENTWISE - && memory_access_type != VMAT_STRIDED_SLP); + && memory_access_type != VMAT_STRIDED_SLP + && memory_access_type != VMAT_LOAD_STORE_LANES); unsigned int inside_cost = 0, prologue_cost = 0; bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info); @@ -1194,31 +1195,6 @@ vect_model_load_cost (vec_info *vinfo, once per group anyhow. */ bool first_stmt_p = (first_stmt_info == stmt_info); - /* An IFN_LOAD_LANES will load all its vector results, regardless of which - ones we actually need. Account for the cost of unused results. */ - if (first_stmt_p && !slp_node && memory_access_type == VMAT_LOAD_STORE_LANES) - { - unsigned int gaps = DR_GROUP_SIZE (first_stmt_info); - stmt_vec_info next_stmt_info = first_stmt_info; - do - { - gaps -= 1; - next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); - } - while (next_stmt_info); - if (gaps) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: %d unused vectors.\n", - gaps); - vect_get_load_cost (vinfo, stmt_info, ncopies * gaps, - alignment_support_scheme, misalignment, false, - &inside_cost, &prologue_cost, - cost_vec, cost_vec, true); - } - } - /* We assume that the cost of a single load-lanes instruction is equivalent to the cost of DR_GROUP_SIZE separate loads. If a grouped access is instead being provided by a load-and-permute operation, @@ -10358,7 +10334,7 @@ vectorizable_load (vec_info *vinfo, } tree vec_mask = NULL_TREE; poly_uint64 group_elt = 0; - unsigned int inside_cost = 0; + unsigned int inside_cost = 0, prologue_cost = 0; for (j = 0; j < ncopies; j++) { /* 1. Create the vector or array pointer update chain. */ @@ -10438,8 +10414,42 @@ vectorizable_load (vec_info *vinfo, dr_chain.create (vec_num); gimple *new_stmt = NULL; - if (memory_access_type == VMAT_LOAD_STORE_LANES && !costing_p) + if (memory_access_type == VMAT_LOAD_STORE_LANES) { + if (costing_p) + { + /* An IFN_LOAD_LANES will load all its vector results, + regardless of which ones we actually need. Account + for the cost of unused results. */ + if (grouped_load && first_stmt_info == stmt_info) + { + unsigned int gaps = DR_GROUP_SIZE (first_stmt_info); + stmt_vec_info next_stmt_info = first_stmt_info; + do + { + gaps -= 1; + next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); + } + while (next_stmt_info); + if (gaps) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: %d " + "unused vectors.\n", + gaps); + vect_get_load_cost (vinfo, stmt_info, gaps, + alignment_support_scheme, + misalignment, false, &inside_cost, + &prologue_cost, cost_vec, cost_vec, + true); + } + } + vect_get_load_cost (vinfo, stmt_info, 1, alignment_support_scheme, + misalignment, false, &inside_cost, + &prologue_cost, cost_vec, cost_vec, true); + continue; + } tree vec_array; vec_array = create_vector_array (vectype, vec_num); @@ -11090,13 +11100,14 @@ vec_num_loop_costing_end: if (costing_p) { - if (memory_access_type == VMAT_GATHER_SCATTER) + if (memory_access_type == VMAT_GATHER_SCATTER + || memory_access_type == VMAT_LOAD_STORE_LANES) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_load_cost: inside_cost = %u, " - "prologue_cost = 0 .\n", - inside_cost); + "prologue_cost = %u .\n", + inside_cost, prologue_cost); } else vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, -- cgit v1.1 From 5f03844b32f45224c33dcea08a20b5a2089082f7 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:22 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_CONTIGUOUS_REVERSE This patch adjusts the cost handling on VMAT_CONTIGUOUS_REVERSE in function vectorizable_load. We don't call function vect_model_load_cost for it any more. This change makes us not miscount some required vector permutation as the associated test case shows. gcc/ChangeLog: * tree-vect-stmts.cc (vect_model_load_cost): Assert it won't get VMAT_CONTIGUOUS_REVERSE any more. (vectorizable_load): Adjust the costing handling on VMAT_CONTIGUOUS_REVERSE without calling vect_model_load_cost. gcc/testsuite/ChangeLog: * gcc.dg/vect/costmodel/ppc/costmodel-vect-reversed.c: New test. --- .../vect/costmodel/ppc/costmodel-vect-reversed.c | 22 +++++ gcc/tree-vect-stmts.cc | 109 ++++++++++++++------- 2 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-reversed.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-reversed.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-reversed.c new file mode 100644 index 0000000..651274b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-reversed.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-additional-options "-mvsx" } */ + +/* Verify we do cost the required vec_perm. */ + +int x[1024], y[1024]; + +void +foo () +{ + for (int i = 0; i < 512; ++i) + { + x[2 * i] = y[1023 - (2 * i)]; + x[2 * i + 1] = y[1023 - (2 * i + 1)]; + } +} +/* The reason why it doesn't check the exact count is that + retrying for the epilogue with partial vector capability + like Power10 can result in more than 1 vec_perm. */ +/* { dg-final { scan-tree-dump {\mvec_perm\M} "vect" } } */ diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 0339469..b2ffdfd 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1150,11 +1150,8 @@ vect_model_load_cost (vec_info *vinfo, slp_tree slp_node, stmt_vector_for_cost *cost_vec) { - gcc_assert (memory_access_type != VMAT_GATHER_SCATTER - && memory_access_type != VMAT_INVARIANT - && memory_access_type != VMAT_ELEMENTWISE - && memory_access_type != VMAT_STRIDED_SLP - && memory_access_type != VMAT_LOAD_STORE_LANES); + gcc_assert (memory_access_type == VMAT_CONTIGUOUS + || memory_access_type == VMAT_CONTIGUOUS_PERMUTE); unsigned int inside_cost = 0, prologue_cost = 0; bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info); @@ -10543,7 +10540,7 @@ vectorizable_load (vec_info *vinfo, = record_stmt_cost (cost_vec, cnunits, scalar_load, stmt_info, 0, vect_body); - goto vec_num_loop_costing_end; + break; } if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) vec_offset = vec_offsets[vec_num * j + i]; @@ -10613,7 +10610,7 @@ vectorizable_load (vec_info *vinfo, inside_cost = record_stmt_cost (cost_vec, 1, vec_construct, stmt_info, 0, vect_body); - goto vec_num_loop_costing_end; + break; } unsigned HOST_WIDE_INT const_offset_nunits = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype) @@ -10668,7 +10665,7 @@ vectorizable_load (vec_info *vinfo, } if (costing_p) - goto vec_num_loop_costing_end; + break; align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); @@ -10882,7 +10879,7 @@ vectorizable_load (vec_info *vinfo, case dr_explicit_realign: { if (costing_p) - goto vec_num_loop_costing_end; + break; tree ptr, bump; tree vs = size_int (TYPE_VECTOR_SUBPARTS (vectype)); @@ -10946,7 +10943,7 @@ vectorizable_load (vec_info *vinfo, case dr_explicit_realign_optimized: { if (costing_p) - goto vec_num_loop_costing_end; + break; if (TREE_CODE (dataref_ptr) == SSA_NAME) new_temp = copy_ssa_name (dataref_ptr); else @@ -10969,22 +10966,37 @@ vectorizable_load (vec_info *vinfo, default: gcc_unreachable (); } - vec_dest = vect_create_destination_var (scalar_dest, vectype); - /* DATA_REF is null if we've already built the statement. */ - if (data_ref) + + /* One common place to cost the above vect load for different + alignment support schemes. */ + if (costing_p) { - vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); - new_stmt = gimple_build_assign (vec_dest, data_ref); + if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) + vect_get_load_cost (vinfo, stmt_info, 1, + alignment_support_scheme, misalignment, + false, &inside_cost, &prologue_cost, + cost_vec, cost_vec, true); + } + else + { + vec_dest = vect_create_destination_var (scalar_dest, vectype); + /* DATA_REF is null if we've already built the statement. */ + if (data_ref) + { + vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); + new_stmt = gimple_build_assign (vec_dest, data_ref); + } + new_temp = make_ssa_name (vec_dest, new_stmt); + gimple_set_lhs (new_stmt, new_temp); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); } - new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_set_lhs (new_stmt, new_temp); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); /* 3. Handle explicit realignment if necessary/supported. Create in loop: vec_dest = realign_load (msq, lsq, realignment_token) */ - if (alignment_support_scheme == dr_explicit_realign_optimized - || alignment_support_scheme == dr_explicit_realign) + if (!costing_p + && (alignment_support_scheme == dr_explicit_realign_optimized + || alignment_support_scheme == dr_explicit_realign)) { lsq = gimple_assign_lhs (new_stmt); if (!realignment_token) @@ -11009,26 +11021,34 @@ vectorizable_load (vec_info *vinfo, if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) { - tree perm_mask = perm_mask_for_reverse (vectype); - new_temp = permute_vec_elements (vinfo, new_temp, new_temp, - perm_mask, stmt_info, gsi); - new_stmt = SSA_NAME_DEF_STMT (new_temp); + if (costing_p) + inside_cost = record_stmt_cost (cost_vec, 1, vec_perm, + stmt_info, 0, vect_body); + else + { + tree perm_mask = perm_mask_for_reverse (vectype); + new_temp + = permute_vec_elements (vinfo, new_temp, new_temp, + perm_mask, stmt_info, gsi); + new_stmt = SSA_NAME_DEF_STMT (new_temp); + } } /* Collect vector loads and later create their permutation in vect_transform_grouped_load (). */ - if (grouped_load || slp_perm) + if (!costing_p && (grouped_load || slp_perm)) dr_chain.quick_push (new_temp); /* Store vector loads in the corresponding SLP_NODE. */ - if (slp && !slp_perm) + if (!costing_p && slp && !slp_perm) SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); /* With SLP permutation we load the gaps as well, without we need to skip the gaps after we manage to fully load all elements. group_gap_adj is DR_GROUP_SIZE here. */ group_elt += nunits; - if (maybe_ne (group_gap_adj, 0U) + if (!costing_p + && maybe_ne (group_gap_adj, 0U) && !slp_perm && known_eq (group_elt, group_size - group_gap_adj)) { @@ -11043,8 +11063,6 @@ vectorizable_load (vec_info *vinfo, gsi, stmt_info, bump); group_elt = 0; } -vec_num_loop_costing_end: - ; } /* Bump the vector pointer to account for a gap or for excess elements loaded for a permuted SLP load. */ @@ -11067,18 +11085,30 @@ vec_num_loop_costing_end: if (slp && !slp_perm) continue; - if (slp_perm && !costing_p) - { + if (slp_perm) + { unsigned n_perms; /* For SLP we know we've seen all possible uses of dr_chain so direct vect_transform_slp_perm_load to DCE the unused parts. ??? This is a hack to prevent compile-time issues as seen in PR101120 and friends. */ - bool ok = vect_transform_slp_perm_load (vinfo, slp_node, dr_chain, - gsi, vf, false, &n_perms, - nullptr, true); - gcc_assert (ok); - } + if (costing_p + && memory_access_type != VMAT_CONTIGUOUS + && memory_access_type != VMAT_CONTIGUOUS_PERMUTE) + { + vect_transform_slp_perm_load (vinfo, slp_node, vNULL, nullptr, vf, + true, &n_perms, nullptr); + inside_cost = record_stmt_cost (cost_vec, n_perms, vec_perm, + stmt_info, 0, vect_body); + } + else if (!costing_p) + { + bool ok = vect_transform_slp_perm_load (vinfo, slp_node, dr_chain, + gsi, vf, false, &n_perms, + nullptr, true); + gcc_assert (ok); + } + } else if (!costing_p) { if (grouped_load) @@ -11100,8 +11130,11 @@ vec_num_loop_costing_end: if (costing_p) { - if (memory_access_type == VMAT_GATHER_SCATTER - || memory_access_type == VMAT_LOAD_STORE_LANES) + gcc_assert (memory_access_type != VMAT_INVARIANT + && memory_access_type != VMAT_ELEMENTWISE + && memory_access_type != VMAT_STRIDED_SLP); + if (memory_access_type != VMAT_CONTIGUOUS + && memory_access_type != VMAT_CONTIGUOUS_PERMUTE) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, -- cgit v1.1 From a3118d7c153dc9c0af9d892903dc4ebc69f654b0 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:22 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_CONTIGUOUS_PERMUTE This patch adjusts the cost handling on VMAT_CONTIGUOUS_PERMUTE in function vectorizable_load. We don't call function vect_model_load_cost for it any more. As the affected test case gcc.target/i386/pr70021.c shows, the previous costing can under-cost the total generated vector loads as for VMAT_CONTIGUOUS_PERMUTE function vect_model_load_cost doesn't consider the group size which is considered as vec_num during the transformation. This patch makes the count of vector load in costing become consistent with what we generates during the transformation. To be more specific, for the given test case, for memory access b[i_20], it costed for 2 vector loads before, with this patch it costs 8 instead, it matches the final count of generated vector loads basing from b. This costing change makes cost model analysis feel it's not profitable to vectorize the first loop, so this patch adjusts the test case without vect cost model any more. But note that this test case also exposes something we can improve further is that although the number of vector permutation what we costed and generated are consistent, but DCE can further optimize some unused permutation out, it would be good if we can predict that and generate only those necessary permutations. gcc/ChangeLog: * tree-vect-stmts.cc (vect_model_load_cost): Assert this function only handle memory_access_type VMAT_CONTIGUOUS, remove some VMAT_CONTIGUOUS_PERMUTE related handlings. (vectorizable_load): Adjust the cost handling on VMAT_CONTIGUOUS_PERMUTE without calling vect_model_load_cost. gcc/testsuite/ChangeLog: * gcc.target/i386/pr70021.c: Adjust with -fno-vect-cost-model. --- gcc/testsuite/gcc.target/i386/pr70021.c | 2 +- gcc/tree-vect-stmts.cc | 88 +++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 39 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/i386/pr70021.c b/gcc/testsuite/gcc.target/i386/pr70021.c index 6562c0f..d509583 100644 --- a/gcc/testsuite/gcc.target/i386/pr70021.c +++ b/gcc/testsuite/gcc.target/i386/pr70021.c @@ -1,7 +1,7 @@ /* PR target/70021 */ /* { dg-do run } */ /* { dg-require-effective-target avx2 } */ -/* { dg-options "-O2 -ftree-vectorize -mavx2 -fdump-tree-vect-details -mtune=skylake" } */ +/* { dg-options "-O2 -ftree-vectorize -mavx2 -fdump-tree-vect-details -mtune=skylake -fno-vect-cost-model" } */ #include "avx2-check.h" diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index b2ffdfd..3a14aee 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1150,8 +1150,7 @@ vect_model_load_cost (vec_info *vinfo, slp_tree slp_node, stmt_vector_for_cost *cost_vec) { - gcc_assert (memory_access_type == VMAT_CONTIGUOUS - || memory_access_type == VMAT_CONTIGUOUS_PERMUTE); + gcc_assert (memory_access_type == VMAT_CONTIGUOUS); unsigned int inside_cost = 0, prologue_cost = 0; bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info); @@ -1192,26 +1191,6 @@ vect_model_load_cost (vec_info *vinfo, once per group anyhow. */ bool first_stmt_p = (first_stmt_info == stmt_info); - /* We assume that the cost of a single load-lanes instruction is - equivalent to the cost of DR_GROUP_SIZE separate loads. If a grouped - access is instead being provided by a load-and-permute operation, - include the cost of the permutes. */ - if (first_stmt_p - && memory_access_type == VMAT_CONTIGUOUS_PERMUTE) - { - /* Uses an even and odd extract operations or shuffle operations - for each needed permute. */ - int group_size = DR_GROUP_SIZE (first_stmt_info); - int nstmts = ncopies * ceil_log2 (group_size) * group_size; - inside_cost += record_stmt_cost (cost_vec, nstmts, vec_perm, - stmt_info, 0, vect_body); - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: strided group_size = %d .\n", - group_size); - } - vect_get_load_cost (vinfo, stmt_info, ncopies, alignment_support_scheme, misalignment, first_stmt_p, &inside_cost, &prologue_cost, cost_vec, cost_vec, true); @@ -10971,11 +10950,22 @@ vectorizable_load (vec_info *vinfo, alignment support schemes. */ if (costing_p) { - if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) + /* For VMAT_CONTIGUOUS_PERMUTE if it's grouped load, we + only need to take care of the first stmt, whose + stmt_info is first_stmt_info, vec_num iterating on it + will cover the cost for the remaining, it's consistent + with transforming. For the prologue cost for realign, + we only need to count it once for the whole group. */ + bool first_stmt_info_p = first_stmt_info == stmt_info; + bool add_realign_cost = first_stmt_info_p && i == 0; + if (memory_access_type == VMAT_CONTIGUOUS_REVERSE + || (memory_access_type == VMAT_CONTIGUOUS_PERMUTE + && (!grouped_load || first_stmt_info_p))) vect_get_load_cost (vinfo, stmt_info, 1, alignment_support_scheme, misalignment, - false, &inside_cost, &prologue_cost, - cost_vec, cost_vec, true); + add_realign_cost, &inside_cost, + &prologue_cost, cost_vec, cost_vec, + true); } else { @@ -11093,8 +11083,7 @@ vectorizable_load (vec_info *vinfo, ??? This is a hack to prevent compile-time issues as seen in PR101120 and friends. */ if (costing_p - && memory_access_type != VMAT_CONTIGUOUS - && memory_access_type != VMAT_CONTIGUOUS_PERMUTE) + && memory_access_type != VMAT_CONTIGUOUS) { vect_transform_slp_perm_load (vinfo, slp_node, vNULL, nullptr, vf, true, &n_perms, nullptr); @@ -11109,20 +11098,44 @@ vectorizable_load (vec_info *vinfo, gcc_assert (ok); } } - else if (!costing_p) + else { if (grouped_load) { if (memory_access_type != VMAT_LOAD_STORE_LANES) - vect_transform_grouped_load (vinfo, stmt_info, dr_chain, - group_size, gsi); - *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; - } - else - { - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + { + gcc_assert (memory_access_type == VMAT_CONTIGUOUS_PERMUTE); + /* We assume that the cost of a single load-lanes instruction + is equivalent to the cost of DR_GROUP_SIZE separate loads. + If a grouped access is instead being provided by a + load-and-permute operation, include the cost of the + permutes. */ + if (costing_p && first_stmt_info == stmt_info) + { + /* Uses an even and odd extract operations or shuffle + operations for each needed permute. */ + int group_size = DR_GROUP_SIZE (first_stmt_info); + int nstmts = ceil_log2 (group_size) * group_size; + inside_cost + += record_stmt_cost (cost_vec, nstmts, vec_perm, + stmt_info, 0, vect_body); + + if (dump_enabled_p ()) + dump_printf_loc ( + MSG_NOTE, vect_location, + "vect_model_load_cost: strided group_size = %d .\n", + group_size); + } + else if (!costing_p) + vect_transform_grouped_load (vinfo, stmt_info, dr_chain, + group_size, gsi); + } + if (!costing_p) + *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; } - } + else if (!costing_p) + STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + } dr_chain.release (); } if (!slp && !costing_p) @@ -11133,8 +11146,7 @@ vectorizable_load (vec_info *vinfo, gcc_assert (memory_access_type != VMAT_INVARIANT && memory_access_type != VMAT_ELEMENTWISE && memory_access_type != VMAT_STRIDED_SLP); - if (memory_access_type != VMAT_CONTIGUOUS - && memory_access_type != VMAT_CONTIGUOUS_PERMUTE) + if (memory_access_type != VMAT_CONTIGUOUS) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, -- cgit v1.1 From 43ed05a08963a5c3ccc4cc6143d2b322851edd10 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 12 Jul 2023 21:23:22 -0500 Subject: vect: Adjust vectorizable_load costing on VMAT_CONTIGUOUS This patch adjusts the cost handling on VMAT_CONTIGUOUS in function vectorizable_load. We don't call function vect_model_load_cost for it any more. It removes function vect_model_load_cost which becomes useless and unreachable now. gcc/ChangeLog: * tree-vect-stmts.cc (vect_model_load_cost): Remove. (vectorizable_load): Adjust the cost handling on VMAT_CONTIGUOUS without calling vect_model_load_cost. --- gcc/tree-vect-stmts.cc | 94 +++++--------------------------------------------- 1 file changed, 9 insertions(+), 85 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 3a14aee..c08d0ef 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1133,75 +1133,6 @@ vect_get_store_cost (vec_info *, stmt_vec_info stmt_info, int ncopies, } } - -/* Function vect_model_load_cost - - Models cost for loads. In the case of grouped accesses, one access has - the overhead of the grouped access attributed to it. Since unaligned - accesses are supported for loads, we also account for the costs of the - access scheme chosen. */ - -static void -vect_model_load_cost (vec_info *vinfo, - stmt_vec_info stmt_info, unsigned ncopies, poly_uint64 vf, - vect_memory_access_type memory_access_type, - dr_alignment_support alignment_support_scheme, - int misalignment, - slp_tree slp_node, - stmt_vector_for_cost *cost_vec) -{ - gcc_assert (memory_access_type == VMAT_CONTIGUOUS); - - unsigned int inside_cost = 0, prologue_cost = 0; - bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info); - - gcc_assert (cost_vec); - - /* ??? Somehow we need to fix this at the callers. */ - if (slp_node) - ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - - if (slp_node && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) - { - /* If the load is permuted then the alignment is determined by - the first group element not by the first scalar stmt DR. */ - stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); - if (!first_stmt_info) - first_stmt_info = stmt_info; - /* Record the cost for the permutation. */ - unsigned n_perms, n_loads; - vect_transform_slp_perm_load (vinfo, slp_node, vNULL, NULL, - vf, true, &n_perms, &n_loads); - inside_cost += record_stmt_cost (cost_vec, n_perms, vec_perm, - first_stmt_info, 0, vect_body); - - /* And adjust the number of loads performed. This handles - redundancies as well as loads that are later dead. */ - ncopies = n_loads; - } - - /* Grouped loads read all elements in the group at once, - so we want the DR for the first statement. */ - stmt_vec_info first_stmt_info = stmt_info; - if (!slp_node && grouped_access_p) - first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); - - /* True if we should include any once-per-group costs as well as - the cost of the statement itself. For SLP we only get called - once per group anyhow. */ - bool first_stmt_p = (first_stmt_info == stmt_info); - - vect_get_load_cost (vinfo, stmt_info, ncopies, alignment_support_scheme, - misalignment, first_stmt_p, &inside_cost, &prologue_cost, - cost_vec, cost_vec, true); - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: inside_cost = %d, " - "prologue_cost = %d .\n", inside_cost, prologue_cost); -} - - /* Calculate cost of DR's memory access. */ void vect_get_load_cost (vec_info *, stmt_vec_info stmt_info, int ncopies, @@ -10958,7 +10889,8 @@ vectorizable_load (vec_info *vinfo, we only need to count it once for the whole group. */ bool first_stmt_info_p = first_stmt_info == stmt_info; bool add_realign_cost = first_stmt_info_p && i == 0; - if (memory_access_type == VMAT_CONTIGUOUS_REVERSE + if (memory_access_type == VMAT_CONTIGUOUS + || memory_access_type == VMAT_CONTIGUOUS_REVERSE || (memory_access_type == VMAT_CONTIGUOUS_PERMUTE && (!grouped_load || first_stmt_info_p))) vect_get_load_cost (vinfo, stmt_info, 1, @@ -11082,15 +11014,14 @@ vectorizable_load (vec_info *vinfo, direct vect_transform_slp_perm_load to DCE the unused parts. ??? This is a hack to prevent compile-time issues as seen in PR101120 and friends. */ - if (costing_p - && memory_access_type != VMAT_CONTIGUOUS) + if (costing_p) { vect_transform_slp_perm_load (vinfo, slp_node, vNULL, nullptr, vf, true, &n_perms, nullptr); inside_cost = record_stmt_cost (cost_vec, n_perms, vec_perm, stmt_info, 0, vect_body); } - else if (!costing_p) + else { bool ok = vect_transform_slp_perm_load (vinfo, slp_node, dr_chain, gsi, vf, false, &n_perms, @@ -11146,18 +11077,11 @@ vectorizable_load (vec_info *vinfo, gcc_assert (memory_access_type != VMAT_INVARIANT && memory_access_type != VMAT_ELEMENTWISE && memory_access_type != VMAT_STRIDED_SLP); - if (memory_access_type != VMAT_CONTIGUOUS) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: inside_cost = %u, " - "prologue_cost = %u .\n", - inside_cost, prologue_cost); - } - else - vect_model_load_cost (vinfo, stmt_info, ncopies, vf, memory_access_type, - alignment_support_scheme, misalignment, slp_node, - cost_vec); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: inside_cost = %u, " + "prologue_cost = %u .\n", + inside_cost, prologue_cost); } return true; -- cgit v1.1 From 43fefc1f832a80370ea142273ebc1a76005c68a0 Mon Sep 17 00:00:00 2001 From: Pan Li Date: Wed, 12 Jul 2023 23:01:39 +0800 Subject: RISC-V: Add more tests for RVV floating-point FRM. Add more test cases include both the asm check and run for RVV FRM. Signed-off-by: Pan Li gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-insert-10.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-insert-7.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-insert-8.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-insert-9.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-run-1.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-run-2.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-run-3.c: New test. --- .../riscv/rvv/base/float-point-frm-insert-10.c | 23 +++++++ .../riscv/rvv/base/float-point-frm-insert-7.c | 29 ++++++++ .../riscv/rvv/base/float-point-frm-insert-8.c | 27 ++++++++ .../riscv/rvv/base/float-point-frm-insert-9.c | 24 +++++++ .../riscv/rvv/base/float-point-frm-run-1.c | 79 ++++++++++++++++++++++ .../riscv/rvv/base/float-point-frm-run-2.c | 70 +++++++++++++++++++ .../riscv/rvv/base/float-point-frm-run-3.c | 71 +++++++++++++++++++ 7 files changed, 323 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c new file mode 100644 index 0000000..c46910b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, + size_t vl) +{ + asm volatile ( + "addi %0, %0, 0x12" + :"+r"(vl) + : + : + ); + + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (op1, op2, 2, vl); + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl); + *(vfloat32m1_t *)out = result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c new file mode 100644 index 0000000..7b1602f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +size_t __attribute__ ((noinline)) +normalize_vl (size_t vl) +{ + if (vl % 4 == 0) + return vl; + + return ((vl / 4) + 1) * 4; +} + +void +test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, + size_t vl) +{ + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (op1, op2, 2, vl); + + vl = normalize_vl (vl); + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl); + + *(vfloat32m1_t *)out = result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c new file mode 100644 index 0000000..37481dd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +size_t __attribute__ ((noinline)) +normalize_vl (size_t vl) +{ + if (vl % 4 == 0) + return vl; + + return ((vl / 4) + 1) * 4; +} + +void +test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, + size_t vl) +{ + vl = normalize_vl (vl); + + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (op1, op2, 2, vl); + + *(vfloat32m1_t *)out = result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c new file mode 100644 index 0000000..7ae834a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, + size_t vl) +{ + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (op1, op2, 2, vl); + + asm volatile ( + "fsrmi 4" + : + : + :"frm" + ); + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl); + *(vfloat32m1_t *)out = result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c new file mode 100644 index 0000000..210c49c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c @@ -0,0 +1,79 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 -Wno-psabi" } */ + +#include "riscv_vector.h" +#include +#include + +static int +get_frm () +{ + int frm = -1; + + __asm__ volatile ( + "frrm %0" + :"=r"(frm) + : + : + ); + + return frm; +} + +static void +set_frm (int frm) +{ + __asm__ volatile ( + "fsrm %0" + : + :"r"(frm) + : + ); +} + +static inline void +assert_equal (int a, int b, char *message) +{ + if (a != b) + { + printf (message); + __builtin_abort (); + } +} + +vfloat32m1_t __attribute__ ((noinline)) +test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + set_frm (0); + + vfloat32m1_t result; + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl); + assert_equal (1, get_frm (), "The value of frm register should be 1."); + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl); + assert_equal (2, get_frm (), "The value of frm register should be 2."); + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl); + assert_equal (3, get_frm (), "The value of frm register should be 3."); + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + assert_equal (4, get_frm (), "The value of frm register should be 4."); + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 0, vl); + assert_equal (0, get_frm (), "The value of frm register should be 0."); + + return result; +} + +int +main () +{ + size_t vl = 8; + vfloat32m1_t op1; + vfloat32m1_t op2; + + test_float_point_frm_run (op1, op2, vl); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c new file mode 100644 index 0000000..a703652 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c @@ -0,0 +1,70 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 -Wno-psabi" } */ + +#include "riscv_vector.h" +#include +#include + +static int +get_frm () +{ + int frm = -1; + + __asm__ volatile ( + "frrm %0" + :"=r"(frm) + : + : + ); + + return frm; +} + +static void +set_frm (int frm) +{ + __asm__ volatile ( + "fsrm %0" + : + :"r"(frm) + : + ); +} + +static inline void +assert_equal (int a, int b, char *message) +{ + if (a != b) + { + fprintf (stdout, "%s, but get %d != %d\n", message, a, b); + __builtin_abort (); + } +} + +vfloat32m1_t __attribute__ ((noinline)) +test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + set_frm (0); + + vfloat32m1_t result = {}; + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl); + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + + assert_equal (4, get_frm (), "The value of frm register should be 4."); + + return result; +} + +int +main () +{ + size_t vl = 8; + vfloat32m1_t op1 = {}; + vfloat32m1_t op2 = {}; + + test_float_point_frm_run (op1, op2, vl); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c new file mode 100644 index 0000000..6924bdf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c @@ -0,0 +1,71 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 -Wno-psabi" } */ + +#include "riscv_vector.h" +#include +#include + +static int +get_frm () +{ + int frm = -1; + + __asm__ volatile ( + "frrm %0" + :"=r"(frm) + : + : + ); + + return frm; +} + +static void +set_frm (int frm) +{ + __asm__ volatile ( + "fsrm %0" + : + :"r"(frm) + : + ); +} + +static inline void +assert_equal (int a, int b, char *message) +{ + if (a != b) + { + fprintf (stdout, "%s, but get %d != %d\n", message, a, b); + __builtin_abort (); + } +} + +vfloat32m1_t __attribute__ ((noinline)) +test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + set_frm (0); + + vfloat32m1_t result = {}; + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + assert_equal (4, get_frm (), "The value of frm register should be 4."); + + return result; +} + +int +main () +{ + size_t vl = 8; + vfloat32m1_t op1 = {}; + vfloat32m1_t op2 = {}; + + test_float_point_frm_run (op1, op2, vl); + + return 0; +} -- cgit v1.1 From 880676d603979852f30b76b1e2a3532b95f08048 Mon Sep 17 00:00:00 2001 From: Pan Li Date: Wed, 12 Jul 2023 13:38:42 +0800 Subject: RISC-V: Refactor riscv mode after for VXRM and FRM When investigate the FRM dynmaic rounding mode, we find the global unknown status is quite different between the fixed-point and floating-point. Thus, we separate the unknown function with extracting some inner common functions. We will also prepare more test cases in another PATCH. Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/riscv.cc (vxrm_rtx): New static var. (frm_rtx): Ditto. (global_state_unknown_p): Removed. (riscv_entity_mode_after): Removed. (asm_insn_p): New function. (vxrm_unknown_p): New function for fixed-point. (riscv_vxrm_mode_after): Ditto. (frm_unknown_dynamic_p): New function for floating-point. (riscv_frm_mode_after): Ditto. (riscv_mode_after): Leverage new functions. --- gcc/config/riscv/riscv.cc | 85 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 23 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 706c184..6ed735d 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7701,17 +7701,24 @@ riscv_mode_needed (int entity, rtx_insn *insn) } } -/* Return true if the VXRM/FRM status of the INSN is unknown. */ +/* Return TRUE that an insn is asm. */ + static bool -global_state_unknown_p (rtx_insn *insn, unsigned int regno) +asm_insn_p (rtx_insn *insn) { - struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref ref; + extract_insn (insn); + + return recog_data.is_asm; +} + +/* Return TRUE that an insn is unknown for VXRM. */ +static bool +vxrm_unknown_p (rtx_insn *insn) +{ /* Return true if there is a definition of VXRM. */ - for (ref = DF_INSN_INFO_DEFS (insn_info); ref; ref = DF_REF_NEXT_LOC (ref)) - if (DF_REF_REGNO (ref) == regno) - return true; + if (reg_set_p (gen_rtx_REG (SImode, VXRM_REGNUM), insn)) + return true; /* A CALL function may contain an instruction that modifies the VXRM, return true in this situation. */ @@ -7720,25 +7727,61 @@ global_state_unknown_p (rtx_insn *insn, unsigned int regno) /* Return true for all assembly since users may hardcode a assembly like this: asm volatile ("csrwi vxrm, 0"). */ - extract_insn (insn); - if (recog_data.is_asm) + if (asm_insn_p (insn)) + return true; + + return false; +} + +/* Return TRUE that an insn is unknown dynamic for FRM. */ + +static bool +frm_unknown_dynamic_p (rtx_insn *insn) +{ + /* Return true if there is a definition of FRM. */ + if (reg_set_p (gen_rtx_REG (SImode, FRM_REGNUM), insn)) return true; + + /* A CALL function may contain an instruction that modifies the FRM, + return true in this situation. */ + if (CALL_P (insn)) + return true; + return false; } +/* Return the mode that an insn results in for VXRM. */ + static int -riscv_entity_mode_after (int regnum, rtx_insn *insn, int mode, - int (*get_attr_mode) (rtx_insn *), int default_mode) +riscv_vxrm_mode_after (rtx_insn *insn, int mode) { - if (global_state_unknown_p (insn, regnum)) - return default_mode; - else if (recog_memoized (insn) < 0) + if (vxrm_unknown_p (insn)) + return VXRM_MODE_NONE; + + if (recog_memoized (insn) < 0) + return mode; + + if (reg_mentioned_p (gen_rtx_REG (SImode, VXRM_REGNUM), PATTERN (insn))) + return get_attr_vxrm_mode (insn); + else return mode; +} + +/* Return the mode that an insn results in for FRM. */ - rtx reg = gen_rtx_REG (SImode, regnum); - bool mentioned_p = reg_mentioned_p (reg, PATTERN (insn)); +static int +riscv_frm_mode_after (rtx_insn *insn, int mode) +{ + if (frm_unknown_dynamic_p (insn)) + return FRM_MODE_DYN; - return mentioned_p ? get_attr_mode (insn): mode; + if (recog_memoized (insn) < 0) + return mode; + + if (reg_mentioned_p (gen_rtx_REG (SImode, FRM_REGNUM), PATTERN (insn))) + return get_attr_frm_mode (insn); + else + return mode; } /* Return the mode that an insn results in. */ @@ -7749,13 +7792,9 @@ riscv_mode_after (int entity, int mode, rtx_insn *insn) switch (entity) { case RISCV_VXRM: - return riscv_entity_mode_after (VXRM_REGNUM, insn, mode, - (int (*)(rtx_insn *)) get_attr_vxrm_mode, - VXRM_MODE_NONE); + return riscv_vxrm_mode_after (insn, mode); case RISCV_FRM: - return riscv_entity_mode_after (FRM_REGNUM, insn, mode, - (int (*)(rtx_insn *)) get_attr_frm_mode, - FRM_MODE_DYN); + return riscv_frm_mode_after (insn, mode); default: gcc_unreachable (); } -- cgit v1.1 From 834f34947b20b18696487fc5d2bccab5ea720351 Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Thu, 13 Jul 2023 16:54:34 +0800 Subject: SSA MATH: Support COND_LEN_FMA for floating-point math optimization Hi, Richard and Richi. Previous patch we support COND_LEN_* binary operations. However, we didn't support COND_LEN_* ternary. Now, this patch support COND_LEN_* ternary. Consider this following case: __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dst, \ TYPE *__restrict a, \ TYPE *__restrict b,\ TYPE *__restrict c, int n) \ { \ for (int i = 0; i < n; i++) \ dst[i] += a[i] * b[i]; \ } TEST_ALL () Before this patch: ... COND_LEN_MUL COND_LEN_ADD Afther this patch: ... COND_LEN_FMA gcc/ChangeLog: * genmatch.cc (commutative_op): Add COND_LEN_* * internal-fn.cc (first_commutative_argument): Ditto. (CASE): Ditto. (get_unconditional_internal_fn): Ditto. (can_interpret_as_conditional_op_p): Ditto. (internal_fn_len_index): Ditto. * internal-fn.h (can_interpret_as_conditional_op_p): Ditt. * tree-ssa-math-opts.cc (convert_mult_to_fma_1): Ditto. (convert_mult_to_fma): Ditto. (math_opts_dom_walker::after_dom_children): Ditto. --- gcc/genmatch.cc | 13 +++++++ gcc/internal-fn.cc | 87 +++++++++++++++++++++++++++++++++++++++++------ gcc/internal-fn.h | 2 +- gcc/tree-ssa-math-opts.cc | 80 ++++++++++++++++++++++++++++++++++++------- 4 files changed, 159 insertions(+), 23 deletions(-) (limited to 'gcc') diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc index 5fceeec..2302f2a 100644 --- a/gcc/genmatch.cc +++ b/gcc/genmatch.cc @@ -559,6 +559,19 @@ commutative_op (id_base *id) case CFN_COND_FMS: case CFN_COND_FNMA: case CFN_COND_FNMS: + case CFN_COND_LEN_ADD: + case CFN_COND_LEN_MUL: + case CFN_COND_LEN_MIN: + case CFN_COND_LEN_MAX: + case CFN_COND_LEN_FMIN: + case CFN_COND_LEN_FMAX: + case CFN_COND_LEN_AND: + case CFN_COND_LEN_IOR: + case CFN_COND_LEN_XOR: + case CFN_COND_LEN_FMA: + case CFN_COND_LEN_FMS: + case CFN_COND_LEN_FNMA: + case CFN_COND_LEN_FNMS: return 1; default: diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index c11123a..e698f0b 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -4191,6 +4191,19 @@ first_commutative_argument (internal_fn fn) case IFN_COND_FMS: case IFN_COND_FNMA: case IFN_COND_FNMS: + case IFN_COND_LEN_ADD: + case IFN_COND_LEN_MUL: + case IFN_COND_LEN_MIN: + case IFN_COND_LEN_MAX: + case IFN_COND_LEN_FMIN: + case IFN_COND_LEN_FMAX: + case IFN_COND_LEN_AND: + case IFN_COND_LEN_IOR: + case IFN_COND_LEN_XOR: + case IFN_COND_LEN_FMA: + case IFN_COND_LEN_FMS: + case IFN_COND_LEN_FNMA: + case IFN_COND_LEN_FNMS: return 1; default: @@ -4330,11 +4343,14 @@ conditional_internal_fn_code (internal_fn ifn) { switch (ifn) { -#define CASE(CODE, IFN) case IFN_COND_##IFN: return CODE; - FOR_EACH_CODE_MAPPING(CASE) +#define CASE(CODE, IFN) \ + case IFN_COND_##IFN: \ + case IFN_COND_LEN_##IFN: \ + return CODE; + FOR_EACH_CODE_MAPPING (CASE) #undef CASE - default: - return ERROR_MARK; + default: + return ERROR_MARK; } } @@ -4433,6 +4449,18 @@ get_unconditional_internal_fn (internal_fn ifn) operating elementwise if the operands are vectors. This includes the case of an all-true COND, so that the operation always happens. + There is an alternative approach to interpret the STMT when the operands + are vectors which is the operation predicated by both conditional mask + and loop control length, the equivalent C code: + + for (int i = 0; i < NUNTIS; i++) + { + if (i < LEN + BIAS && COND[i]) + LHS[i] = A[i] CODE B[i]; + else + LHS[i] = ELSE[i]; + } + When returning true, set: - *COND_OUT to the condition COND, or to NULL_TREE if the condition @@ -4440,13 +4468,18 @@ get_unconditional_internal_fn (internal_fn ifn) - *CODE_OUT to the tree code - OPS[I] to operand I of *CODE_OUT - *ELSE_OUT to the fallback value ELSE, or to NULL_TREE if the - condition is known to be all true. */ + condition is known to be all true. + - *LEN to the len argument if it COND_LEN_* operations or to NULL_TREE. + - *BIAS to the bias argument if it COND_LEN_* operations or to NULL_TREE. */ bool can_interpret_as_conditional_op_p (gimple *stmt, tree *cond_out, tree_code *code_out, - tree (&ops)[3], tree *else_out) + tree (&ops)[3], tree *else_out, + tree *len, tree *bias) { + *len = NULL_TREE; + *bias = NULL_TREE; if (gassign *assign = dyn_cast (stmt)) { *cond_out = NULL_TREE; @@ -4462,18 +4495,28 @@ can_interpret_as_conditional_op_p (gimple *stmt, tree *cond_out, { internal_fn ifn = gimple_call_internal_fn (call); tree_code code = conditional_internal_fn_code (ifn); + int len_index = internal_fn_len_index (ifn); + int cond_nargs = len_index >= 0 ? 4 : 2; if (code != ERROR_MARK) { *cond_out = gimple_call_arg (call, 0); *code_out = code; - unsigned int nops = gimple_call_num_args (call) - 2; + unsigned int nops = gimple_call_num_args (call) - cond_nargs; for (unsigned int i = 0; i < 3; ++i) ops[i] = i < nops ? gimple_call_arg (call, i + 1) : NULL_TREE; *else_out = gimple_call_arg (call, nops + 1); - if (integer_truep (*cond_out)) + if (len_index < 0) + { + if (integer_truep (*cond_out)) + { + *cond_out = NULL_TREE; + *else_out = NULL_TREE; + } + } + else { - *cond_out = NULL_TREE; - *else_out = NULL_TREE; + *len = gimple_call_arg (call, len_index); + *bias = gimple_call_arg (call, len_index + 1); } return true; } @@ -4561,8 +4604,32 @@ internal_fn_len_index (internal_fn fn) case IFN_LEN_MASK_GATHER_LOAD: case IFN_LEN_MASK_SCATTER_STORE: + case IFN_COND_LEN_FMA: + case IFN_COND_LEN_FMS: + case IFN_COND_LEN_FNMA: + case IFN_COND_LEN_FNMS: return 5; + case IFN_COND_LEN_ADD: + case IFN_COND_LEN_SUB: + case IFN_COND_LEN_MUL: + case IFN_COND_LEN_DIV: + case IFN_COND_LEN_MOD: + case IFN_COND_LEN_RDIV: + case IFN_COND_LEN_MIN: + case IFN_COND_LEN_MAX: + case IFN_COND_LEN_FMIN: + case IFN_COND_LEN_FMAX: + case IFN_COND_LEN_AND: + case IFN_COND_LEN_IOR: + case IFN_COND_LEN_XOR: + case IFN_COND_LEN_SHL: + case IFN_COND_LEN_SHR: + return 4; + + case IFN_COND_LEN_NEG: + return 3; + default: return -1; } diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h index dd1bab0..a5c3f47 100644 --- a/gcc/internal-fn.h +++ b/gcc/internal-fn.h @@ -229,7 +229,7 @@ extern tree_code conditional_internal_fn_code (internal_fn); extern internal_fn get_unconditional_internal_fn (internal_fn); extern bool can_interpret_as_conditional_op_p (gimple *, tree *, tree_code *, tree (&)[3], - tree *); + tree *, tree *, tree *); extern bool internal_load_fn_p (internal_fn); extern bool internal_store_fn_p (internal_fn); diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index 68fc518..712097a 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -3099,10 +3099,11 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) negate_p = true; } - tree cond, else_value, ops[3]; + tree cond, else_value, ops[3], len, bias; tree_code code; if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, - ops, &else_value)) + ops, &else_value, + &len, &bias)) gcc_unreachable (); addop = ops[0] == result ? ops[1] : ops[0]; @@ -3122,7 +3123,11 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) if (seq) gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); - if (cond) + if (len) + fma_stmt + = gimple_build_call_internal (IFN_COND_LEN_FMA, 7, cond, mulop1, op2, + addop, else_value, len, bias); + else if (cond) fma_stmt = gimple_build_call_internal (IFN_COND_FMA, 5, cond, mulop1, op2, addop, else_value); else @@ -3307,7 +3312,8 @@ last_fma_candidate_feeds_initial_phi (fma_deferring_state *state, static bool convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, - fma_deferring_state *state, tree mul_cond = NULL_TREE) + fma_deferring_state *state, tree mul_cond = NULL_TREE, + tree mul_len = NULL_TREE, tree mul_bias = NULL_TREE) { tree mul_result = gimple_get_lhs (mul_stmt); /* If there isn't a LHS then this can't be an FMA. There can be no LHS @@ -3420,10 +3426,10 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, negate_p = seen_negate_p = true; } - tree cond, else_value, ops[3]; + tree cond, else_value, ops[3], len, bias; tree_code code; if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops, - &else_value)) + &else_value, &len, &bias)) return false; switch (code) @@ -3439,15 +3445,49 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, return false; } - if (mul_cond && cond != mul_cond) - return false; - - if (cond) + if (len) { - if (cond == result || else_value == result) + /* For COND_LEN_* operations, we may have dummpy mask which is + the all true mask. Such TREE type may be mul_cond != cond + but we still consider they are equal. */ + if (mul_cond && cond != mul_cond + && !(integer_truep (mul_cond) && integer_truep (cond))) return false; - if (!direct_internal_fn_supported_p (IFN_COND_FMA, type, opt_type)) + + if (else_value == result) + return false; + + if (!direct_internal_fn_supported_p (IFN_COND_LEN_FMA, type, + opt_type)) return false; + + if (mul_len) + { + poly_int64 mul_value, value; + if (poly_int_tree_p (mul_len, &mul_value) + && poly_int_tree_p (len, &value) + && maybe_ne (mul_value, value)) + return false; + else if (mul_len != len) + return false; + + if (wi::to_widest (mul_bias) != wi::to_widest (bias)) + return false; + } + } + else + { + if (mul_cond && cond != mul_cond) + return false; + + if (cond) + { + if (cond == result || else_value == result) + return false; + if (!direct_internal_fn_supported_p (IFN_COND_FMA, type, + opt_type)) + return false; + } } /* If the subtrahend (OPS[1]) is computed by a MULT_EXPR that @@ -5632,6 +5672,22 @@ math_opts_dom_walker::after_dom_children (basic_block bb) } break; + case CFN_COND_LEN_MUL: + if (convert_mult_to_fma (stmt, + gimple_call_arg (stmt, 1), + gimple_call_arg (stmt, 2), + &fma_state, + gimple_call_arg (stmt, 0), + gimple_call_arg (stmt, 4), + gimple_call_arg (stmt, 5))) + + { + gsi_remove (&gsi, true); + release_defs (stmt); + continue; + } + break; + case CFN_LAST: cancel_fma_deferring (&fma_state); break; -- cgit v1.1 From b175b4887f928118af997f6d4d75097a64dcec5d Mon Sep 17 00:00:00 2001 From: "Vladimir N. Makarov" Date: Thu, 13 Jul 2023 10:42:17 -0400 Subject: [RA][PR109520]: Catch error when there are no enough registers for asm insn Asm insn unlike other insns can have so many operands whose constraints can not be satisfied. It results in LRA cycling for such test case. The following patch catches such situation and reports the problem. PR middle-end/109520 gcc/ChangeLog: * lra-int.h (lra_insn_recog_data): Add member asm_reloads_num. (lra_asm_insn_error): New prototype. * lra.cc: Include rtl_error.h. (lra_set_insn_recog_data): Initialize asm_reloads_num. (lra_asm_insn_error): New func whose code is taken from ... * lra-assigns.cc (lra_split_hard_reg_for): ... here. Use lra_asm_insn_error. * lra-constraints.cc (curr_insn_transform): Check reloads nummber for asm. gcc/testsuite/ChangeLog: * gcc.target/i386/pr109520.c: New test. --- gcc/lra-assigns.cc | 16 ++--------- gcc/lra-constraints.cc | 4 +++ gcc/lra-int.h | 4 +++ gcc/lra.cc | 23 +++++++++++++++ gcc/testsuite/gcc.target/i386/pr109520.c | 48 ++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr109520.c (limited to 'gcc') diff --git a/gcc/lra-assigns.cc b/gcc/lra-assigns.cc index 2f95121..3555926 100644 --- a/gcc/lra-assigns.cc +++ b/gcc/lra-assigns.cc @@ -1851,20 +1851,8 @@ lra_split_hard_reg_for (void) insn = lra_insn_recog_data[u]->insn; if (asm_noperands (PATTERN (insn)) >= 0) { - lra_asm_error_p = asm_p = true; - error_for_asm (insn, - "% operand has impossible constraints"); - /* Avoid further trouble with this insn. */ - if (JUMP_P (insn)) - { - ira_nullify_asm_goto (insn); - lra_update_insn_regno_info (insn); - } - else - { - PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); - lra_set_insn_deleted (insn); - } + asm_p = true; + lra_asm_insn_error (insn); } else if (!asm_p) { diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 9bfc881..0c6912d 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -4813,6 +4813,10 @@ curr_insn_transform (bool check_only_p) lra_update_operator_dups (curr_id); /* Something changes -- process the insn. */ lra_update_insn_regno_info (curr_insn); + if (asm_noperands (PATTERN (curr_insn)) >= 0 + && ++curr_id->asm_reloads_num >= FIRST_PSEUDO_REGISTER) + /* Most probably there are no enough registers to satisfy asm insn: */ + lra_asm_insn_error (curr_insn); } lra_process_new_insns (curr_insn, before, after, "Inserting insn reload"); return change_p; diff --git a/gcc/lra-int.h b/gcc/lra-int.h index 4dbe667..a32359e5 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -209,6 +209,9 @@ public: debug insn. LRA_NON_CLOBBERED_ALT means ignoring any earlier clobbers for the insn. */ int used_insn_alternative; + /* Defined for asm insn and it is how many times we already generated reloads + for the asm insn. */ + int asm_reloads_num; /* SP offset before the insn relative to one at the func start. */ poly_int64 sp_offset; /* The insn itself. */ @@ -307,6 +310,7 @@ extern void lra_delete_dead_insn (rtx_insn *); extern void lra_emit_add (rtx, rtx, rtx); extern void lra_emit_move (rtx, rtx); extern void lra_update_dups (lra_insn_recog_data_t, signed char *); +extern void lra_asm_insn_error (rtx_insn *insn); extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *, const char *); diff --git a/gcc/lra.cc b/gcc/lra.cc index c8b3f13..563aff1 100644 --- a/gcc/lra.cc +++ b/gcc/lra.cc @@ -106,6 +106,7 @@ along with GCC; see the file COPYING3. If not see #include "backend.h" #include "target.h" #include "rtl.h" +#include "rtl-error.h" #include "tree.h" #include "predict.h" #include "df.h" @@ -536,6 +537,27 @@ lra_update_dups (lra_insn_recog_data_t id, signed char *nops) *id->dup_loc[i] = *id->operand_loc[nop]; } +/* Report asm insn error and modify the asm insn. */ +void +lra_asm_insn_error (rtx_insn *insn) +{ + lra_asm_error_p = true; + error_for_asm (insn, + "% operand has impossible constraints" + " or there are not enough registers"); + /* Avoid further trouble with this insn. */ + if (JUMP_P (insn)) + { + ira_nullify_asm_goto (insn); + lra_update_insn_regno_info (insn); + } + else + { + PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); + lra_set_insn_deleted (insn); + } +} + /* This page contains code dealing with info about registers in the @@ -973,6 +995,7 @@ lra_set_insn_recog_data (rtx_insn *insn) lra_insn_recog_data[uid] = data; data->insn = insn; data->used_insn_alternative = LRA_UNKNOWN_ALT; + data->asm_reloads_num = 0; data->icode = icode; data->regs = NULL; if (DEBUG_INSN_P (insn)) diff --git a/gcc/testsuite/gcc.target/i386/pr109520.c b/gcc/testsuite/gcc.target/i386/pr109520.c new file mode 100644 index 0000000..d81b255 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr109520.c @@ -0,0 +1,48 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O0" } */ + +int +foo (int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, + int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16) +{ + register int v0 asm ("rax") = a3; + register int v1 asm ("rbx") = a4; + register int v2 asm ("rcx") = a5; + register int v3 asm ("rdx") = a6; + register int v4 asm ("rsi") = a7; + register int v5 asm ("rdi") = a8; + register int v6 asm ("r8") = a9; + register int v7 asm ("r9") = a10; + register int v8 asm ("r10") = a11; + register int v9 asm ("r11") = a12; + register int v10 asm ("r12") = a13; + register int v11 asm ("r13") = a14; + register int v12 asm ("r14") = a15; + register int v13 asm ("r15") = a16; + int x; + + v0 += a0; + v1 += a1; + v2 += a2; + v0 |= a0; + v1 |= a1; + v2 |= a2; + v0 ^= a0; + v1 ^= a1; + v2 ^= a2; + v0 &= a0; + v1 &= a1; + v2 &= a2; + asm goto ("": "=r" (x) : : : lab); /* { dg-error "operand has impossible constraints" } */ + a1 ^= a0; + a2 = a1; + a0 |= a2; + a0 |= x; + lab: + v0 += x + a0 + a1 + a2; + v1 -= a0 - a1 - a2; + v2 |= a0 | a1 | a2; + v3 |= a0 & a1 & a2; + v4 ^= a0 ^ a1 ^ a2; + return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 + v11 + v12 + v13 + a0 + a1 + a2; +} -- cgit v1.1 From 285c9d042e90a7425b37697edc9ec93a1b03b486 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Wed, 12 Jul 2023 00:33:14 -0700 Subject: Fix part of PR 110293: `A NEEQ (A NEEQ CST)` part This fixes part of PR 110293, for the outer comparison case being `!=` or `==`. In turn PR 110539 is able to be optimized again as the if statement for `(a&1) == ((a & 1) != 0)` gets optimized to `false` early enough to allow FRE/DOM to do a CSE for memory store/load. OK? Bootstrapped and tested on x86_64-linux with no regressions. gcc/ChangeLog: PR tree-optimization/110293 PR tree-optimization/110539 * match.pd: Expand the `x != (typeof x)(x == 0)` pattern to handle where the inner and outer comparsions are either `!=` or `==` and handle other constants than 0. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr110293-1.c: New test. * gcc.dg/tree-ssa/pr110539-1.c: New test. * gcc.dg/tree-ssa/pr110539-2.c: New test. * gcc.dg/tree-ssa/pr110539-3.c: New test. * gcc.dg/tree-ssa/pr110539-4.c: New test. --- gcc/match.pd | 39 ++++++++++++-- gcc/testsuite/gcc.dg/tree-ssa/pr110293-1.c | 58 +++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr110539-1.c | 12 +++++ gcc/testsuite/gcc.dg/tree-ssa/pr110539-2.c | 12 +++++ gcc/testsuite/gcc.dg/tree-ssa/pr110539-3.c | 75 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr110539-4.c | 82 ++++++++++++++++++++++++++++++ 6 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110293-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110539-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110539-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110539-3.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110539-4.c (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index 8543f77..351d928 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6429,10 +6429,41 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (TYPE_UNSIGNED (TREE_TYPE (@0))) { constant_boolean_node (false, type); })) -/* x != (typeof x)(x == 0) is always true. */ -(simplify - (ne:c @0 (convert (eq @0 integer_zerop))) - { constant_boolean_node (true, type); }) +/* x != (typeof x)(x == CST) -> CST == 0 ? 1 : (CST == 1 ? (x!=0&&x!=1) : x != 0) */ +/* x != (typeof x)(x != CST) -> CST == 1 ? 1 : (CST == 0 ? (x!=0&&x!=1) : x != 1) */ +/* x == (typeof x)(x == CST) -> CST == 0 ? 0 : (CST == 1 ? (x==0||x==1) : x != 0) */ +/* x == (typeof x)(x != CST) -> CST == 1 ? 0 : (CST == 0 ? (x==0||x==1) : x != 1) */ +(for outer (ne eq) + (for inner (ne eq) + (simplify + (outer:c @0 (convert (inner @0 INTEGER_CST@1))) + (with { + bool cst1 = integer_onep (@1); + bool cst0 = integer_zerop (@1); + bool innereq = inner == EQ_EXPR; + bool outereq = outer == EQ_EXPR; + } + (switch + (if (innereq ? cst0 : cst1) + { constant_boolean_node (!outereq, type); }) + (if (innereq ? cst1 : cst0) + (with { + tree utype = unsigned_type_for (TREE_TYPE (@0)); + tree ucst1 = build_one_cst (utype); + } + (if (!outereq) + (gt (convert:utype @0) { ucst1; }) + (le (convert:utype @0) { ucst1; }) + ) + ) + ) + (if (innereq) + (ne @0 { build_zero_cst (TREE_TYPE (@0)); })) + (ne @0 { build_one_cst (TREE_TYPE (@0)); })) + ) + ) + ) +) (for cmp (unordered ordered unlt unle ungt unge uneq ltgt) /* If the second operand is NaN, the result is constant. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110293-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110293-1.c new file mode 100644 index 0000000..24aea1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110293-1.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized-raw" } */ + +_Bool eqeq0(unsigned x) +{ + return x == (x == 0); +} +_Bool eqeq1(unsigned x) +{ + return x == (x == 1); +} +_Bool eqeq2(unsigned x) +{ + return x == (x == 2); +} + +_Bool neeq0(unsigned x) +{ + return x != (x == 0); +} +_Bool neeq1(unsigned x) +{ + return x != (x == 1); +} +_Bool neeq2(unsigned x) +{ + return x != (x == 2); +} + +_Bool eqne0(unsigned x) +{ + return x == (x != 0); +} +_Bool eqne1(unsigned x) +{ + return x == (x != 1); +} +_Bool eqne2(unsigned x) +{ + return x == (x != 2); +} + +_Bool nene0(unsigned x) +{ + return x != (x != 0); +} +_Bool nene1(unsigned x) +{ + return x != (x != 1); +} +_Bool nene2(unsigned x) +{ + return x != (x != 2); +} + +/* All of these functions should have removed the inner most comparison which + means all of the conversions from bool to unsigned should have been removed too. */ +/* { dg-final { scan-tree-dump-not "nop_expr," "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110539-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-1.c new file mode 100644 index 0000000..6ba864c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ +int f(int a) +{ + int b = a & 1; + int c = b != 0; + return c == b; +} + +/* This should be optimized to just return 1; */ +/* { dg-final { scan-tree-dump-not " == " "optimized"} } */ +/* { dg-final { scan-tree-dump "return 1;" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110539-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-2.c new file mode 100644 index 0000000..17874d3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ +int f(int a) +{ + int b = a & 1; + int c = b == 0; + return c == b; +} + +/* This should be optimized to just return 0; */ +/* { dg-final { scan-tree-dump-not " == " "optimized"} } */ +/* { dg-final { scan-tree-dump "return 0;" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110539-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-3.c new file mode 100644 index 0000000..e2bd4df --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-3.c @@ -0,0 +1,75 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +void foo(void); +static int a, c = 1; +static short b; +static int *d = &c, *e = &a; +static int **f = &d; +void __assert_fail() __attribute__((__noreturn__)); +static void g(short h) { + if (*d) + ; + else { + if (e) __assert_fail(); + if (a) { + __builtin_unreachable(); + } else + __assert_fail(); + } + if ((((0, 0) || h) == h) + b) *f = 0; +} +int main() { + int i = 0 != 10 & a; + g(i); + *e = 9; + e = 0; + if (d == 0) + ; + else + foo(); + ; +} +/* The call to foo should be optimized away. */ +/* The missed optimization at -O2 here was: + int b = a & 1; + int c = b != 0; + int d = c == b; + not being optimized to 1 early enough, it is done in vrp2 but + that is too late. + In phiopt2 we got: + _17 = i_7 != 0; + _12 = (int) _17; + if (i_7 == _12) + goto ; [50.00%] + else + goto ; [50.00%] + + [local count: 268435456]: + d = 0B; + + [local count: 536870913]: + e.1_3 = e; + *e.1_3 = 9; + e = 0B; + d.2_4 = d; + if (d.2_4 == 0B) + + The first if is not optimized before, until vrp2 which is + too late as there are no passes which will then find the + load of d in `d.2_4 = d;` was `0B` after vrp2. + + Now in forwprop3 (after phiopt2), we optimize: + _17 = i_7 != 0; + _12 = (int) _17; + if (i_7 == _12) + into just: + _t = (unsigned)i_7; + if (_t <= 1) + + And then during ccp3, that is optimized away and that is optimized + early enough now that the load `d.2_4 = d;` is optimizd to just + `d.2_4 = 0B;` + */ + +/* { dg-final { scan-tree-dump-not "foo \\(\\)" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110539-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-4.c new file mode 100644 index 0000000..2c03dcc --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110539-4.c @@ -0,0 +1,82 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fstrict-aliasing -fdump-tree-optimized" } */ + +/* This is a small variant of pr110539-3.c using -O1 -fstrict-aliasing + rather than -O2. Just to show VRP and PRE is not needed to optimize + the call to foo away. */ + + +void foo(void); +static int a, c = 1; +static short b; +static int *d = &c, *e = &a; +static int **f = &d; +void __assert_fail() __attribute__((__noreturn__)); +static void g(int h) { + if (*d) + ; + else { + if (e) __assert_fail(); + if (a) { + __builtin_unreachable(); + } else + __assert_fail(); + } + if (((h!=0) == h) + b) *f = 0; +} + +int main() { + int i = 0 != 10 & a; + g(i); + *e = 9; + e = 0; + if (d == 0) + ; + else + foo(); + ; +} + +/* The call to foo should be optimized away. */ +/* The missed optimization at -O1 here was: + int b = a & 1; + int c = b != 0; + int d = c == b; + not being optimized to 1 early enough, it is done in vrp2 but + that is too late. + In phiopt2 we got: + _17 = i_7 != 0; + _12 = (int) _17; + if (i_7 == _12) + goto ; [50.00%] + else + goto ; [50.00%] + + [local count: 268435456]: + d = 0B; + + [local count: 536870913]: + e.1_3 = e; + *e.1_3 = 9; + e = 0B; + d.2_4 = d; + if (d.2_4 == 0B) + + The first if is not optimized before, until vrp2 which is + too late as there are no passes which will then find the + load of d in `d.2_4 = d;` was `0B` after vrp2. + + Now in forwprop3 (after phiopt2), we optimize: + _17 = i_7 != 0; + _12 = (int) _17; + if (i_7 == _12) + into just: + _t = (unsigned)i_7; + if (_t <= 1) + + And then during ccp3, that is optimized away and that is optimized + early enough now that the load `d.2_4 = d;` is optimizd to just + `d.2_4 = 0B;` + */ + +/* { dg-final { scan-tree-dump-not "foo \\(\\)" "optimized"} } */ -- cgit v1.1 From ad71cd89d327d5bf05d17bfa8f92cdaf71dbf751 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 13 Jul 2023 17:47:49 +0200 Subject: RA+sched: Change TRUE/FALSE to true/false gcc/ChangeLog: * haifa-sched.cc: Change TRUE/FALSE to true/false. * ira.cc: Ditto. * lra-assigns.cc: Ditto. * lra-constraints.cc: Ditto. * sel-sched.cc: Ditto. --- gcc/haifa-sched.cc | 4 ++-- gcc/ira.cc | 2 +- gcc/lra-assigns.cc | 2 +- gcc/lra-constraints.cc | 16 ++++++++-------- gcc/sel-sched.cc | 12 ++++++------ 5 files changed, 18 insertions(+), 18 deletions(-) (limited to 'gcc') diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc index 01a2a80..8e8add7 100644 --- a/gcc/haifa-sched.cc +++ b/gcc/haifa-sched.cc @@ -6624,7 +6624,7 @@ schedule_block (basic_block *target_bb, state_t init_state) advance = 0; gcc_assert (scheduled_insns.length () == 0); - sort_p = TRUE; + sort_p = true; must_backtrack = false; modulo_insns_scheduled = 0; @@ -6844,7 +6844,7 @@ schedule_block (basic_block *target_bb, state_t init_state) break; } - sort_p = TRUE; + sort_p = true; if (current_sched_info->can_schedule_ready_p && ! (*current_sched_info->can_schedule_ready_p) (insn)) diff --git a/gcc/ira.cc b/gcc/ira.cc index a186010..4a6fb35 100644 --- a/gcc/ira.cc +++ b/gcc/ira.cc @@ -5795,7 +5795,7 @@ ira (FILE *f) there is setjmp call because a variable not modified between setjmp and longjmp the compiler is required to preserve its value and sharing slots does not guarantee it. */ - flag_ira_share_spill_slots = FALSE; + flag_ira_share_spill_slots = false; ira_color (); diff --git a/gcc/lra-assigns.cc b/gcc/lra-assigns.cc index 3555926..b8582dc 100644 --- a/gcc/lra-assigns.cc +++ b/gcc/lra-assigns.cc @@ -948,7 +948,7 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p) } best_hard_regno = -1; best_cost = INT_MAX; - best_static_p = TRUE; + best_static_p = true; best_insn_pseudos_num = INT_MAX; smallest_bad_spills_num = INT_MAX; rclass_size = ira_class_hard_regs_num[rclass]; diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 0c6912d..76a155e 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -1723,7 +1723,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS); if (get_reload_reg (curr_static_id->operand[nop].type, innermode, reg, rclass, NULL, - TRUE, "slow/invalid mem", &new_reg)) + true, "slow/invalid mem", &new_reg)) { bool insert_before, insert_after; bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); @@ -1743,7 +1743,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS); if (get_reload_reg (curr_static_id->operand[nop].type, mode, reg, rclass, NULL, - TRUE, "slow/invalid mem", &new_reg)) + true, "slow/invalid mem", &new_reg)) { bool insert_before, insert_after; bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); @@ -1828,7 +1828,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) if (get_reload_reg (curr_static_id->operand[nop].type, reg_mode, reg, rclass, NULL, - TRUE, "subreg reg", &new_reg)) + true, "subreg reg", &new_reg)) { bool insert_before, insert_after; bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); @@ -1902,7 +1902,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) if (get_reload_reg (curr_static_id->operand[nop].type, mode, reg, rclass, NULL, - TRUE, "paradoxical subreg", &new_reg)) + true, "paradoxical subreg", &new_reg)) { rtx subreg; bool insert_before, insert_after; @@ -4578,7 +4578,7 @@ curr_insn_transform (bool check_only_p) lra-lives.cc. */ match_reload (i, goal_alt_matched[i], outputs, goal_alt[i], &goal_alt_exclude_start_hard_regs[i], &before, - &after, TRUE); + &after, true); } continue; } @@ -4623,7 +4623,7 @@ curr_insn_transform (bool check_only_p) /* This value does not matter for MODIFY. */ GET_MODE_SIZE (GET_MODE (op))); else if (get_reload_reg (OP_IN, Pmode, *loc, rclass, - NULL, FALSE, + NULL, false, "offsetable address", &new_reg)) { rtx addr = *loc; @@ -6188,7 +6188,7 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn, { lra_assert (next_usage_insns == NULL); usage_insn = to; - after_p = TRUE; + after_p = true; } else { @@ -6299,7 +6299,7 @@ spill_hard_reg_in_range (int regno, enum reg_class rclass, rtx_insn *from, rtx_i } if (insn != NEXT_INSN (to)) continue; - if (split_reg (TRUE, hard_regno, from, NULL, to)) + if (split_reg (true, hard_regno, from, NULL, to)) return true; } return false; diff --git a/gcc/sel-sched.cc b/gcc/sel-sched.cc index cb1cf75..1925f4a 100644 --- a/gcc/sel-sched.cc +++ b/gcc/sel-sched.cc @@ -2023,7 +2023,7 @@ moving_insn_creates_bookkeeping_block_p (insn_t insn, { if (sched_verbose >= 9) sel_print ("no bookkeeping required: "); - return FALSE; + return false; } bbi = BLOCK_FOR_INSN (insn); @@ -2032,7 +2032,7 @@ moving_insn_creates_bookkeeping_block_p (insn_t insn, { if (sched_verbose >= 9) sel_print ("only one pred edge: "); - return TRUE; + return true; } bbt = BLOCK_FOR_INSN (through_insn); @@ -2041,11 +2041,11 @@ moving_insn_creates_bookkeeping_block_p (insn_t insn, { FOR_EACH_EDGE (e2, ei2, bbi->preds) { - if (find_block_for_bookkeeping (e1, e2, TRUE)) + if (find_block_for_bookkeeping (e1, e2, true)) { if (sched_verbose >= 9) sel_print ("found existing block: "); - return FALSE; + return false; } } } @@ -2053,7 +2053,7 @@ moving_insn_creates_bookkeeping_block_p (insn_t insn, if (sched_verbose >= 9) sel_print ("would create bookkeeping block: "); - return TRUE; + return true; } /* Return true when the conflict with newly created implicit clobbers @@ -4658,7 +4658,7 @@ find_place_for_bookkeeping (edge e1, edge e2, fence_t *fence_to_rewind) insn_t place_to_insert; /* Find a basic block that can hold bookkeeping. If it can be found, do not create new basic block, but insert bookkeeping there. */ - basic_block book_block = find_block_for_bookkeeping (e1, e2, FALSE); + basic_block book_block = find_block_for_bookkeeping (e1, e2, false); if (book_block) { -- cgit v1.1 From 337649c1660211db733c1ba34ae260b8c66a3578 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 13 Jul 2023 18:32:15 +0200 Subject: alpha: Fix computation mode in alpha_emit_set_long_cost [PR106966] PR target/106966 gcc/ChangeLog: * config/alpha/alpha.cc (alpha_emit_set_long_const): Always use DImode when constructing long const. gcc/testsuite/ChangeLog: * gcc.target/alpha/pr106966.c: New test. --- gcc/config/alpha/alpha.cc | 7 ++++++- gcc/testsuite/gcc.target/alpha/pr106966.c | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/alpha/pr106966.c (limited to 'gcc') diff --git a/gcc/config/alpha/alpha.cc b/gcc/config/alpha/alpha.cc index 360b50e..beeab06 100644 --- a/gcc/config/alpha/alpha.cc +++ b/gcc/config/alpha/alpha.cc @@ -2070,6 +2070,8 @@ static rtx alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1) { HOST_WIDE_INT d1, d2, d3, d4; + machine_mode mode = GET_MODE (target); + rtx orig_target = target; /* Decompose the entire word */ @@ -2082,6 +2084,9 @@ alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1) d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; gcc_assert (c1 == d4); + if (mode != DImode) + target = gen_lowpart (DImode, target); + /* Construct the high word */ if (d4) { @@ -2101,7 +2106,7 @@ alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1) if (d1) emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1))); - return target; + return orig_target; } /* Given an integral CONST_INT or CONST_VECTOR, return the low 64 bits. */ diff --git a/gcc/testsuite/gcc.target/alpha/pr106966.c b/gcc/testsuite/gcc.target/alpha/pr106966.c new file mode 100644 index 0000000..7145c20 --- /dev/null +++ b/gcc/testsuite/gcc.target/alpha/pr106966.c @@ -0,0 +1,13 @@ +/* PR target/106906 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbuild-constants" } */ + +void +do_console (unsigned short *vga) +{ + vga[0] = 'H'; + vga[1] = 'e'; + vga[2] = 'l'; + vga[3] = 'l'; + vga[4] = 'o'; +} -- cgit v1.1 From ef3bbc69d15707e4db6e2f198c621effb636cc26 Mon Sep 17 00:00:00 2001 From: Carl Love Date: Thu, 13 Jul 2023 13:44:43 -0400 Subject: rs6000, Add return value to __builtin_set_fpscr_rn Change the return value from void to double for __builtin_set_fpscr_rn. The return value consists of the FPSCR fields DRN, VE, OE, UE, ZE, XE, NI, RN bit positions. A new test file, test powerpc/test_fpscr_rn_builtin_2.c, is added to test the new return value for the built-in. The value __SET_FPSCR_RN_RETURNS_FPSCR__ is defined if __builtin_set_fpscr_rn returns a double. gcc/ChangeLog: * config/rs6000/rs6000-builtins.def (__builtin_set_fpscr_rn): Update built-in definition return type. * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Add check, define __SET_FPSCR_RN_RETURNS_FPSCR__ macro. * config/rs6000/rs6000.md (rs6000_set_fpscr_rn): Add return argument to return FPSCR fields. * doc/extend.texi (__builtin_set_fpscr_rn): Update description for the return value. Add description for __SET_FPSCR_RN_RETURNS_FPSCR__ macro. gcc/testsuite/ChangeLog: * gcc.target/powerpc/test_fpscr_rn_builtin.c: Rename to test_fpscr_rn_builtin_1.c. Add comment. * gcc.target/powerpc/test_fpscr_rn_builtin_2.c: New test for the return value of __builtin_set_fpscr_rn builtin. --- gcc/config/rs6000/rs6000-builtins.def | 2 +- gcc/config/rs6000/rs6000-c.cc | 5 + gcc/config/rs6000/rs6000.md | 56 +++--- gcc/doc/extend.texi | 23 ++- .../gcc.target/powerpc/test_fpscr_rn_builtin.c | 193 -------------------- .../gcc.target/powerpc/test_fpscr_rn_builtin_1.c | 199 +++++++++++++++++++++ .../gcc.target/powerpc/test_fpscr_rn_builtin_2.c | 148 +++++++++++++++ 7 files changed, 404 insertions(+), 222 deletions(-) delete mode 100644 gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin.c create mode 100644 gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_2.c (limited to 'gcc') diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def index 1062cd4..c0ef717 100644 --- a/gcc/config/rs6000/rs6000-builtins.def +++ b/gcc/config/rs6000/rs6000-builtins.def @@ -237,7 +237,7 @@ const __ibm128 __builtin_pack_ibm128 (double, double); PACK_IF packif {ibm128} - void __builtin_set_fpscr_rn (const int[0,3]); + double __builtin_set_fpscr_rn (const int[0,3]); SET_FPSCR_RN rs6000_set_fpscr_rn {nosoft} const double __builtin_unpack_ibm128 (__ibm128, const int<1>); diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index 11060f6..a353bca 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -604,6 +604,11 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags) /* Tell the user -mrop-protect is in play. */ if (rs6000_rop_protect) rs6000_define_or_undefine_macro (define_p, "__ROP_PROTECT__"); + /* Tell the user __builtin_set_fpscr_rn now returns the FPSCR fields + in a double. Originally the built-in returned void. */ + if ((flags & OPTION_MASK_SOFT_FLOAT) == 0) + rs6000_define_or_undefine_macro (define_p, + "__SET_FPSCR_RN_RETURNS_FPSCR__"); } void diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index cdab49f..783f9ff 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6442,7 +6442,8 @@ [(set_attr "type" "fp")]) (define_expand "rs6000_set_fpscr_rn" - [(match_operand:SI 0 "reg_or_cint_operand")] + [(use (match_operand:DF 0 "gpc_reg_operand")) + (use (match_operand:SI 1 "reg_or_cint_operand"))] "TARGET_HARD_FLOAT" { rtx tmp_df = gen_reg_rtx (DFmode); @@ -6451,49 +6452,64 @@ new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */ if (TARGET_P9_MISC) { - if (const_0_to_3_operand (operands[0], VOIDmode)) - emit_insn (gen_rs6000_mffscrni (tmp_df, operands[0])); + if (const_0_to_3_operand (operands[1], VOIDmode)) + emit_insn (gen_rs6000_mffscrni (tmp_df, operands[1])); else { - rtx op0 = convert_to_mode (DImode, operands[0], false); - rtx src_df = simplify_gen_subreg (DFmode, op0, DImode, 0); + rtx op1 = convert_to_mode (DImode, operands[1], false); + rtx src_df = simplify_gen_subreg (DFmode, op1, DImode, 0); emit_insn (gen_rs6000_mffscrn (tmp_df, src_df)); } - DONE; + emit_move_insn (operands[0], tmp_df); + DONE; } - if (CONST_INT_P (operands[0])) + /* Emulate the behavior of the mffscrni, mffscrn instructions for earlier + ISAs. Return bits 29:31 (DRN) and bits 56:63 (VE, OE, UE, ZE, XE, NI, + RN) from the FPSCR. Set the RN field based on the value in operands[1]. + */ + + /* Get the current FPSCR fields, bits 29:31 (DRN) and bits 56:63 (VE, OE, UE, + ZE, XE, NI, RN) from the FPSCR and return them. */ + + emit_insn (gen_rs6000_mffs (tmp_df)); + rtx orig_df_in_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); + rtx tmp_di1 = gen_reg_rtx (DImode); + emit_insn (gen_anddi3 (tmp_di1, orig_df_in_di, + GEN_INT (0x00000007000000FFULL))); + rtx tmp_rtn = simplify_gen_subreg (DFmode, tmp_di1, DImode, 0); + emit_move_insn (operands[0], tmp_rtn); + + if (CONST_INT_P (operands[1])) { - if ((INTVAL (operands[0]) & 0x1) == 0x1) + if ((INTVAL (operands[1]) & 0x1) == 0x1) emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31))); else emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31))); - if ((INTVAL (operands[0]) & 0x2) == 0x2) + if ((INTVAL (operands[1]) & 0x2) == 0x2) emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30))); else emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30))); } else { - rtx tmp_rn = gen_reg_rtx (DImode); - rtx tmp_di = gen_reg_rtx (DImode); - /* Extract new RN mode from operand. */ - rtx op0 = convert_to_mode (DImode, operands[0], false); - emit_insn (gen_anddi3 (tmp_rn, op0, GEN_INT (3))); + rtx op1 = convert_to_mode (DImode, operands[1], false); + rtx tmp_rn = gen_reg_rtx (DImode); + emit_insn (gen_anddi3 (tmp_rn, op1, GEN_INT (3))); - /* Insert new RN mode into FSCPR. */ - emit_insn (gen_rs6000_mffs (tmp_df)); - tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); - emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4))); - emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); + /* Insert the new RN value from tmp_rn into FPSCR bit [62:63]. */ + rtx tmp_di1 = gen_reg_rtx (DImode); + emit_insn (gen_anddi3 (tmp_di1, orig_df_in_di, GEN_INT (-4))); + rtx tmp_di2 = gen_reg_rtx (DImode); + emit_insn (gen_iordi3 (tmp_di2, tmp_di1, tmp_rn)); /* Need to write to field k=15. The fields are [0:15]. Hence with L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an 8-bit field[0:7]. Need to set the bit that corresponds to the value of i that you want [0:7]. */ - tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); + tmp_df = simplify_gen_subreg (DFmode, tmp_di2, DImode, 0); emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df)); } DONE; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 7e4c554..dda3535 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -18392,7 +18392,7 @@ double __builtin_mffs (void); void __builtin_mtfsf (const int, double); void __builtin_mtfsb0 (const int); void __builtin_mtfsb1 (const int); -void __builtin_set_fpscr_rn (int); +double __builtin_set_fpscr_rn (int); @end smallexample The @code{__builtin_ppc_get_timebase} and @code{__builtin_ppc_mftb} @@ -18413,13 +18413,20 @@ values to selected fields of the FPSCR. The as an argument. The valid bit range is between 0 and 31. The builtins map to the @code{mtfsb0} and @code{mtfsb1} instructions which take the argument and add 32. Hence these instructions only modify the FPSCR[32:63] bits by -changing the specified bit to a zero or one respectively. The -@code{__builtin_set_fpscr_rn} builtin allows changing both of the floating -point rounding mode bits. The argument is a 2-bit value. The argument can -either be a @code{const int} or stored in a variable. The builtin uses -the ISA 3.0 -instruction @code{mffscrn} if available, otherwise it reads the FPSCR, masks -the current rounding mode bits out and OR's in the new value. +changing the specified bit to a zero or one respectively. + +The @code{__builtin_set_fpscr_rn} built-in allows changing both of the floating +point rounding mode bits and returning the various FPSCR fields before the RN +field is updated. The built-in returns a double consisting of the initial +value of the FPSCR fields DRN, VE, OE, UE, ZE, XE, NI, and RN bit positions +with all other bits set to zero. The built-in argument is a 2-bit value for the +new RN field value. The argument can either be an @code{const int} or stored +in a variable. Earlier versions of @code{__builtin_set_fpscr_rn} returned +void. A @code{__SET_FPSCR_RN_RETURNS_FPSCR__} macro has been added. If +defined, then the @code{__builtin_set_fpscr_rn} built-in returns the FPSCR +fields. If not defined, the @code{__builtin_set_fpscr_rn} does not return a +value. If the @option{-msoft-float} option is used, the +@code{__builtin_set_fpscr_rn} built-in will not return a value. @node Basic PowerPC Built-in Functions Available on ISA 2.05 @subsubsection Basic PowerPC Built-in Functions Available on ISA 2.05 diff --git a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin.c b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin.c deleted file mode 100644 index 04707ad..0000000 --- a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin.c +++ /dev/null @@ -1,193 +0,0 @@ -/* { dg-do run { target { powerpc*-*-* } } } */ -/* { dg-options "-O2 -std=c99" } */ - -#ifdef DEBUG -#include -#endif - -#define RN_MASK 0x3LL /* RN field mask */ - -void abort (void); -void __attribute__ ((noipa)) wrap_set_fpscr_rn (int val) -{ - __builtin_set_fpscr_rn (val); -} - -int main () -{ - int i; - int val, bit; - double fpscr_val; - union blah { - double d; - unsigned long long ll; - } conv_val; - - unsigned long long ll_value; - register double f14; - - /* __builtin_set_fpscr_rn() builtin can take a const or a variable - value between 0 and 3 as the argument. - __builtin_mtfsb0 and __builtin_mtfsb1 argument must be a constant - 30 or 31. - */ - - /* Test reading the FPSCR register */ - __asm __volatile ("mffs %0" : "=f"(f14)); - conv_val.d = f14; - - if (conv_val.d != __builtin_mffs()) - { -#ifdef DEBUG - printf("ERROR, __builtin_mffs() returned 0x%llx, not the expecected value 0x%llx\n", - __builtin_mffs(), conv_val.d); -#else - abort(); -#endif - } - - /* Test float rounding mode builtin with const value argument. */ - val = 3; - __builtin_set_fpscr_rn (val); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & RN_MASK; - - if (ll_value != 3) - { -#ifdef DEBUG - printf("ERROR, __builtin_set_fpscr_rn(3) returned 0x%llx, not the expecected value 0x%x\n", - ll_value, 3); -#else - abort(); -#endif - } - - val = 2; - __builtin_set_fpscr_rn (val); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & RN_MASK; - - if (ll_value != val) - { -#ifdef DEBUG - printf("ERROR, __builtin_set_fpscr_rn(val=%d) returned 0x%llx, not the expecected value 0x%x\n", - val, ll_value, val); -#else - abort(); -#endif - } - - /* Reset to 0 for testing */ - val = 0; - __builtin_set_fpscr_rn (val); - - __builtin_mtfsb1(31); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & 0x1LL; - - if (ll_value != 1) - { -#ifdef DEBUG - printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 1.\n"); -#else - abort(); -#endif - } - - __builtin_mtfsb0(31); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & 0x1LL; - - if (ll_value != 0) - { -#ifdef DEBUG - printf("ERROR, __builtin_mtfsb0(31) did not set the bit to a 0.\n"); -#else - abort(); -#endif - } - - __builtin_mtfsb1(30); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & 0x2LL; - - if (ll_value != 2) - { -#ifdef DEBUG - printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 1.\n"); -#else - abort(); -#endif - } - - __builtin_mtfsb0(30); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & 0x2LL; - - if (ll_value != 0) - { -#ifdef DEBUG - printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 0.\n"); -#else - abort(); -#endif - } - - __builtin_mtfsb1(0); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & (0x1LL << (31-0)); - - if (ll_value != (0x1LL << (31-0))) - { -#ifdef DEBUG - printf("ERROR, __builtin_mtfsb1(0) did not set the bit to a 1.\n"); -#else - abort(); -#endif - } - - __builtin_mtfsb0(0); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & (0x1LL << (31-0)); - - if (ll_value != 0) - { -#ifdef DEBUG - printf("ERROR, __builtin_mtfsb0(0) did not set the bit to a 0.\n"); -#else - abort(); -#endif - } - - - /* Test builtin float rounding mode with variable as argument. */ - val = 0; - wrap_set_fpscr_rn (val); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & RN_MASK; - - if (ll_value != val) - { -#ifdef DEBUG - printf("ERROR, __builtin_set_fpscr_rn(val=%d) did not set rounding mode to %x.\n", - val, val); -#else - abort(); -#endif - } - - val = 3; - wrap_set_fpscr_rn (val); - conv_val.d = __builtin_mffs(); - ll_value = conv_val.ll & RN_MASK; - - if (ll_value != val) - { -#ifdef DEBUG - printf("ERROR, __builtin_set_fpscr_rn(val=%d) did not set rounding mode to %x.\n", - val, val); -#else - abort(); -#endif - } -} diff --git a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_1.c b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_1.c new file mode 100644 index 0000000..e09dd64 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_1.c @@ -0,0 +1,199 @@ +/* { dg-do run { target powerpc_fprs } } */ +/* { dg-options "-O2" } */ + +/* Originally __builtin_set_fpscr_rn was defined to return void. It was + later extended to return a double with the various FPSCR bits. The + extended built-in is intended to be a drop in replacement for the original + version. This test is for the original version of the built-in and should + work exactly as before. */ + +#ifdef DEBUG +#include +#endif + +#define RN_MASK 0x3LL /* RN field mask */ + +void abort (void); +void __attribute__ ((noipa)) wrap_set_fpscr_rn (int val) +{ + __builtin_set_fpscr_rn (val); +} + +int main () +{ + int i; + int val, bit; + double fpscr_val; + union blah { + double d; + unsigned long long ll; + } conv_val; + + unsigned long long ll_value; + register double f14; + + /* __builtin_set_fpscr_rn() built-in can take a const or a variable + value between 0 and 3 as the argument. + __builtin_mtfsb0 and __builtin_mtfsb1 argument must be a constant + 30 or 31. + */ + + /* Test reading the FPSCR register */ + __asm __volatile ("mffs %0" : "=f"(f14)); + conv_val.d = f14; + + if (conv_val.d != __builtin_mffs()) + { +#ifdef DEBUG + printf("ERROR, __builtin_mffs() returned 0x%llx, not the expecected value 0x%llx\n", + __builtin_mffs(), conv_val.d); +#else + abort(); +#endif + } + + /* Test float rounding mode builtin with const value argument. */ + val = 3; + __builtin_set_fpscr_rn (val); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & RN_MASK; + + if (ll_value != 3) + { +#ifdef DEBUG + printf("ERROR, __builtin_set_fpscr_rn(3) returned 0x%llx, not the expecected value 0x%x\n", + ll_value, 3); +#else + abort(); +#endif + } + + val = 2; + __builtin_set_fpscr_rn (val); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & RN_MASK; + + if (ll_value != val) + { +#ifdef DEBUG + printf("ERROR, __builtin_set_fpscr_rn(val=%d) returned 0x%llx, not the expecected value 0x%x\n", + val, ll_value, val); +#else + abort(); +#endif + } + + /* Reset to 0 for testing */ + val = 0; + __builtin_set_fpscr_rn (val); + + __builtin_mtfsb1(31); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & 0x1LL; + + if (ll_value != 1) + { +#ifdef DEBUG + printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 1.\n"); +#else + abort(); +#endif + } + + __builtin_mtfsb0(31); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & 0x1LL; + + if (ll_value != 0) + { +#ifdef DEBUG + printf("ERROR, __builtin_mtfsb0(31) did not set the bit to a 0.\n"); +#else + abort(); +#endif + } + + __builtin_mtfsb1(30); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & 0x2LL; + + if (ll_value != 2) + { +#ifdef DEBUG + printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 1.\n"); +#else + abort(); +#endif + } + + __builtin_mtfsb0(30); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & 0x2LL; + + if (ll_value != 0) + { +#ifdef DEBUG + printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 0.\n"); +#else + abort(); +#endif + } + + __builtin_mtfsb1(0); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & (0x1LL << (31-0)); + + if (ll_value != (0x1LL << (31-0))) + { +#ifdef DEBUG + printf("ERROR, __builtin_mtfsb1(0) did not set the bit to a 1.\n"); +#else + abort(); +#endif + } + + __builtin_mtfsb0(0); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & (0x1LL << (31-0)); + + if (ll_value != 0) + { +#ifdef DEBUG + printf("ERROR, __builtin_mtfsb0(0) did not set the bit to a 0.\n"); +#else + abort(); +#endif + } + + + /* Test builtin float rounding mode with variable as argument. */ + val = 0; + wrap_set_fpscr_rn (val); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & RN_MASK; + + if (ll_value != val) + { +#ifdef DEBUG + printf("ERROR, __builtin_set_fpscr_rn(val=%d) did not set rounding mode to %x.\n", + val, val); +#else + abort(); +#endif + } + + val = 3; + wrap_set_fpscr_rn (val); + conv_val.d = __builtin_mffs(); + ll_value = conv_val.ll & RN_MASK; + + if (ll_value != val) + { +#ifdef DEBUG + printf("ERROR, __builtin_set_fpscr_rn(val=%d) did not set rounding mode to %x.\n", + val, val); +#else + abort(); +#endif + } +} diff --git a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_2.c b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_2.c new file mode 100644 index 0000000..be4f65d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_2.c @@ -0,0 +1,148 @@ +/* { dg-do run { target powerpc_fprs } } */ +/* { dg-options "-O2" } */ + +/* The __builtin_set_fpscr_rn built-in was originally defined to return + void. The built-in now returns a double containing the various FPSCR bits. + This test verifies the new return value. */ + +#ifdef DEBUG +#include +#endif + +#define RN_MASK 0x3LL /* RN field mask */ +#define FIELD_MASK 0x00000007000000FFULL + +union blah { + double d; + unsigned long long ll; +} conv_val; + +void abort (void); + +double __attribute__ ((noipa)) wrap_set_fpscr_rn (int val) +{ + return __builtin_set_fpscr_rn (val); +} + +double __attribute__ ((noipa)) wrap_const_fpscr_rn (int val) +{ + switch (val) + { + case 0: return __builtin_set_fpscr_rn (0x0); + case 1: return __builtin_set_fpscr_rn (0x1); + case 2: return __builtin_set_fpscr_rn (0x2); + case 3: return __builtin_set_fpscr_rn (0x3); + } +} + +void check_builtin_set_fpscr_rn (unsigned long long initial_fpscr, + int new_RN, double result) +{ + register double f14; + unsigned long long masked_fpscr = initial_fpscr & FIELD_MASK; + + conv_val.d = result; + + /* Check the result. */ + if (conv_val.ll != masked_fpscr) + { +#ifdef DEBUG + printf("ERROR, __builtin_set_fpscr_rn(%d) did not return expected value %llx.\n", + new_RN, masked_fpscr); + printf("fpscr_val_initial = 0x%llx\n", initial_fpscr); + printf("result = 0x%llx\n", conv_val.ll); +#else + abort(); +#endif + } + + /* Check to see if the RN field was updated. */ + __asm __volatile ("mffs %0" : "=f"(f14)); + conv_val.d = f14; + + if ((conv_val.ll & RN_MASK) != new_RN) +#ifdef DEBUG + { + printf("ERROR, __builtin_set_fpscr_rn(%d) did not update RN to %llx.\n", + new_RN, new_RN); + printf(" conv_val.ll = 0x%llx\n", conv_val.ll); + } +#else + abort(); +#endif +} + +int +main () +{ + int i; + int val, bit; + double fpscr_val; + unsigned long long fpscr_val_initial; + + unsigned long long ll_value; + union blah src_double; + register double f14; + + /* If __SET_FPSCR_RN_RETURNS_FPSCR__ is defined, the __builtin_set_fpscr_rn() + builtin returns the FPSCR fields.*/ + + /* __builtin_set_fpscr_rn() builtin can take a constant or a variable + value between 0 and 3 as the argument. + __builtin_mtfsb0 and __builtin_mtfsb1 argument must be a constant + 30 or 31. + */ + + /* Test reading the FPSCR register */ + __asm __volatile ("mffs %0" : "=f"(f14)); + conv_val.d = f14; + + if (conv_val.d != __builtin_mffs()) + { +#ifdef DEBUG + printf("ERROR, __builtin_mffs() returned 0x%llx, not the expected value 0x%llx\n", + __builtin_mffs(), conv_val.d); +#else + abort(); +#endif + } + + /* Test return value from __builtin_set_fpscr_rn. The FPSCR fields (DRN, VE, + OE, UE, ZE, XE, NI, RN) are returned and the RN field of FPSCR is updated + with the specified argument for the built-in. */ + + /* Check immediate argument cases */ + __asm __volatile ("mffs %0" : "=f"(f14)); + conv_val.d = f14; + fpscr_val_initial = conv_val.ll; + + val = 0x0; + fpscr_val = wrap_const_fpscr_rn (val); + check_builtin_set_fpscr_rn (fpscr_val_initial, val, fpscr_val); + + __asm __volatile ("mffs %0" : "=f"(f14)); + conv_val.d = f14; + fpscr_val_initial = conv_val.ll; + + val = 0x3; + fpscr_val = wrap_const_fpscr_rn (val); + check_builtin_set_fpscr_rn (fpscr_val_initial, val, fpscr_val); + + /* Check int argument cases */ + __asm __volatile ("mffs %0" : "=f"(f14)); + conv_val.d = f14; + fpscr_val_initial = conv_val.ll; + + val = 0x1; + fpscr_val = wrap_set_fpscr_rn (val); + check_builtin_set_fpscr_rn (fpscr_val_initial, val, fpscr_val); + + __asm __volatile ("mffs %0" : "=f"(f14)); + conv_val.d = f14; + fpscr_val_initial = conv_val.ll; + + val = 0x2; + fpscr_val = wrap_set_fpscr_rn (val); + check_builtin_set_fpscr_rn (fpscr_val_initial, val, fpscr_val); + return 0; +} -- cgit v1.1 From 032b5da1fc781bd3c23d9caa72fb09439e7f6f3a Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Thu, 13 Jul 2023 07:36:51 +0100 Subject: Darwin: Use -platform_version when available [PR110624]. Later versions of the static linker support a more flexible flag to describe the OS, OS version and SDK used to build the code. This replaces the functionality of '-mmacosx_version_min' (which is now deprecated, leading to the diagnostic described in the PR). We now use the platform_version flag when available which avoids the diagnostic. Signed-off-by: Iain Sandoe PR target/110624 gcc/ChangeLog: * config/darwin.h (DARWIN_PLATFORM_ID): New. (LINK_COMMAND_A): Use DARWIN_PLATFORM_ID to pass OS, OS version and SDK data to the static linker. --- gcc/config/darwin.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index 714d3d5..1b538c7 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -276,6 +276,14 @@ extern GTY(()) int darwin_ms_struct; #define DARWIN_RDYNAMIC "%{rdynamic:%nrdynamic is not supported}" #endif +#if LD64_HAS_PLATFORM_VERSION +#define DARWIN_PLATFORM_ID \ + "%{mmacosx-version-min=*: -platform_version macos %* 0.0} " +#else +#define DARWIN_PLATFORM_ID \ + "%{mmacosx-version-min=*:-macosx_version_min %*} " +#endif + /* Code built with mdynamic-no-pic does not support PIE/PIC, so we disallow these combinations; we also ensure that the no_pie option is passed to ld64 on system versions that default to PIE when mdynamic-no-pic is given. @@ -351,7 +359,9 @@ extern GTY(()) int darwin_ms_struct; LINK_PLUGIN_SPEC \ "%{flto*:% Date: Thu, 13 Jul 2023 21:23:44 +0200 Subject: fortran: Release symbols in reversed order [PR106050] Release symbols in reversed order wrt the order they were allocated. This fixes an error recovery ICE in the case of a misplaced derived type declaration. Such a declaration creates nested symbols, one for the derived type and one for each type parameter, which should be immediately released as the declaration is rejected. This breaks if the derived type is released first. As the type parameter symbols are in the namespace of the derived type, releasing the derived type releases the type parameters, so one can't access them after that, even to release them. Hence, the type parameters should be released first. PR fortran/106050 gcc/fortran/ChangeLog: * symbol.cc (gfc_restore_last_undo_checkpoint): Release symbols in reverse order. gcc/testsuite/ChangeLog: * gfortran.dg/pdt_33.f90: New test. --- gcc/fortran/symbol.cc | 2 +- gcc/testsuite/gfortran.dg/pdt_33.f90 | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/pdt_33.f90 (limited to 'gcc') diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc index 90023f0..aa3cdc9 100644 --- a/gcc/fortran/symbol.cc +++ b/gcc/fortran/symbol.cc @@ -3661,7 +3661,7 @@ gfc_restore_last_undo_checkpoint (void) gfc_symbol *p; unsigned i; - FOR_EACH_VEC_ELT (latest_undo_chgset->syms, i, p) + FOR_EACH_VEC_ELT_REVERSE (latest_undo_chgset->syms, i, p) { /* Symbol in a common block was new. Or was old and just put in common */ if (p->common_block diff --git a/gcc/testsuite/gfortran.dg/pdt_33.f90 b/gcc/testsuite/gfortran.dg/pdt_33.f90 new file mode 100644 index 0000000..0521513 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pdt_33.f90 @@ -0,0 +1,15 @@ +! { dg-do compile } +! +! PR fortran/106050 +! The following used to trigger an error recovery ICE by releasing +! the symbol T before the symbol K which was leading to releasing +! K twice as it's in T's namespace. +! +! Contributed by G. Steinmetz + +program p + a = 1 + type t(k) ! { dg-error "Unexpected derived type declaration" } + integer, kind :: k = 4 ! { dg-error "not allowed outside a TYPE definition" } + end type ! { dg-error "Expecting END PROGRAM" } +end -- cgit v1.1 From ae862e0e47cb2d62d7c624ab999a3bd8bd2914ef Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Thu, 13 Jul 2023 21:44:52 +0200 Subject: m2, build: Use LDLFAGS for mklink When trying to bootstrap current trunk on macOS 14.0 beta 3 with Xcode 15 beta 4, the build failed running mklink in stage 2: unset CC ; m2/boot-bin/mklink -s --langc++ --exit --name m2/mc-boot/main.cc /vol/gcc/src/hg/master/darwin/gcc/m2/init/mcinit dyld[55825]: Library not loaded: /vol/gcc/lib/libstdc++.6.dylib While it's unclear to me why this only happens on macOS 14, the problem is clear: unlike other C++ executables, mklink isn't linked with -static-libstdc++ which is passed in from toplevel in LDFLAGS. This patch fixes that and allows the build to continue. Bootstrapped on x86_64-apple-darwin23.0.0, i386-pc-solaris2.11, and sparc-sun-solaris2.11. 2023-07-11 Rainer Orth gcc/m2: * Make-lang.in (m2/boot-bin/mklink$(exeext)): Add $(LDFLAGS). --- gcc/m2/Make-lang.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in index 6fb551f..0fe671e 100644 --- a/gcc/m2/Make-lang.in +++ b/gcc/m2/Make-lang.in @@ -1653,7 +1653,7 @@ m2/gm2-compiler-boot/gm2.a: m2/boot-bin/mc$(exeext) m2/boot-bin/mklink$(exeext): $(srcdir)/m2/tools-src/mklink.c -test -d $(@D) || $(mkinstalldirs) $(@D) - $(CXX) $(CFLAGS) -I$(srcdir)/m2 -Im2/gm2-libs-boot -Im2/gm2-compiler-boot -I$(srcdir)/m2/mc-boot-ch $(INCLUDES) $< -o $@ + $(CXX) $(CFLAGS) $(LDFLAGS) -I$(srcdir)/m2 -Im2/gm2-libs-boot -Im2/gm2-compiler-boot -I$(srcdir)/m2/mc-boot-ch $(INCLUDES) $< -o $@ m2/gm2-compiler-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-compiler-boot/%.def $(MCDEPS) -test -d $(@D) || $(mkinstalldirs) $(@D) -- cgit v1.1 From 8f1a26ee259f72e42405b9c5f2b161042ec4014b Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Thu, 13 Jul 2023 16:06:39 -0400 Subject: pdp11: Fix epilogue generation [PR107841] gcc/ PR target/107841 * config/pdp11/pdp11.cc (pdp11_expand_epilogue): Also deallocate alloca-only frame. gcc/testsuite/ PR target/107841 * gcc.target/pdp11/pr107841.c: New test. --- gcc/config/pdp11/pdp11.cc | 2 +- gcc/testsuite/gcc.target/pdp11/pr107841.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/pdp11/pr107841.c (limited to 'gcc') diff --git a/gcc/config/pdp11/pdp11.cc b/gcc/config/pdp11/pdp11.cc index f6dd841..311a1d2 100644 --- a/gcc/config/pdp11/pdp11.cc +++ b/gcc/config/pdp11/pdp11.cc @@ -393,7 +393,7 @@ pdp11_expand_epilogue (void) rtx x, reg, via_ac = NULL; /* Deallocate the local variables. */ - if (fsize) + if (fsize || cfun->calls_alloca) { if (frame_pointer_needed) { diff --git a/gcc/testsuite/gcc.target/pdp11/pr107841.c b/gcc/testsuite/gcc.target/pdp11/pr107841.c new file mode 100644 index 0000000..a363c46 --- /dev/null +++ b/gcc/testsuite/gcc.target/pdp11/pr107841.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* Verify that the stack frame is deallocated using the frame pointer. */ + +void qq (int a) +{ + char *s = __builtin_alloca (128); + __builtin_sprintf (s, "qq %d", 3); +} + +/* { dg-final { scan-assembler "mov\tr5,sp" } } */ -- cgit v1.1 From 3d0ca8b55b9a882b9cc9b02b1d7db6a449be10c4 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 14 Jul 2023 00:16:43 +0000 Subject: Daily bump. --- gcc/ChangeLog | 199 +++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/fortran/ChangeLog | 6 ++ gcc/m2/ChangeLog | 4 + gcc/testsuite/ChangeLog | 242 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 452 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dfeefd1..5401ea6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,202 @@ +2023-07-13 Mikael Pettersson + + PR target/107841 + * config/pdp11/pdp11.cc (pdp11_expand_epilogue): Also + deallocate alloca-only frame. + +2023-07-13 Iain Sandoe + + PR target/110624 + * config/darwin.h (DARWIN_PLATFORM_ID): New. + (LINK_COMMAND_A): Use DARWIN_PLATFORM_ID to pass OS, OS version + and SDK data to the static linker. + +2023-07-13 Carl Love + + * config/rs6000/rs6000-builtins.def (__builtin_set_fpscr_rn): Update + built-in definition return type. + * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Add check, + define __SET_FPSCR_RN_RETURNS_FPSCR__ macro. + * config/rs6000/rs6000.md (rs6000_set_fpscr_rn): Add return + argument to return FPSCR fields. + * doc/extend.texi (__builtin_set_fpscr_rn): Update description for + the return value. Add description for + __SET_FPSCR_RN_RETURNS_FPSCR__ macro. + +2023-07-13 Uros Bizjak + + PR target/106966 + * config/alpha/alpha.cc (alpha_emit_set_long_const): + Always use DImode when constructing long const. + +2023-07-13 Uros Bizjak + + * haifa-sched.cc: Change TRUE/FALSE to true/false. + * ira.cc: Ditto. + * lra-assigns.cc: Ditto. + * lra-constraints.cc: Ditto. + * sel-sched.cc: Ditto. + +2023-07-13 Andrew Pinski + + PR tree-optimization/110293 + PR tree-optimization/110539 + * match.pd: Expand the `x != (typeof x)(x == 0)` + pattern to handle where the inner and outer comparsions + are either `!=` or `==` and handle other constants + than 0. + +2023-07-13 Vladimir N. Makarov + + PR middle-end/109520 + * lra-int.h (lra_insn_recog_data): Add member asm_reloads_num. + (lra_asm_insn_error): New prototype. + * lra.cc: Include rtl_error.h. + (lra_set_insn_recog_data): Initialize asm_reloads_num. + (lra_asm_insn_error): New func whose code is taken from ... + * lra-assigns.cc (lra_split_hard_reg_for): ... here. Use lra_asm_insn_error. + * lra-constraints.cc (curr_insn_transform): Check reloads nummber for asm. + +2023-07-13 Ju-Zhe Zhong + + * genmatch.cc (commutative_op): Add COND_LEN_* + * internal-fn.cc (first_commutative_argument): Ditto. + (CASE): Ditto. + (get_unconditional_internal_fn): Ditto. + (can_interpret_as_conditional_op_p): Ditto. + (internal_fn_len_index): Ditto. + * internal-fn.h (can_interpret_as_conditional_op_p): Ditt. + * tree-ssa-math-opts.cc (convert_mult_to_fma_1): Ditto. + (convert_mult_to_fma): Ditto. + (math_opts_dom_walker::after_dom_children): Ditto. + +2023-07-13 Pan Li + + * config/riscv/riscv.cc (vxrm_rtx): New static var. + (frm_rtx): Ditto. + (global_state_unknown_p): Removed. + (riscv_entity_mode_after): Removed. + (asm_insn_p): New function. + (vxrm_unknown_p): New function for fixed-point. + (riscv_vxrm_mode_after): Ditto. + (frm_unknown_dynamic_p): New function for floating-point. + (riscv_frm_mode_after): Ditto. + (riscv_mode_after): Leverage new functions. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vect_model_load_cost): Remove. + (vectorizable_load): Adjust the cost handling on VMAT_CONTIGUOUS without + calling vect_model_load_cost. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vect_model_load_cost): Assert this function only + handle memory_access_type VMAT_CONTIGUOUS, remove some + VMAT_CONTIGUOUS_PERMUTE related handlings. + (vectorizable_load): Adjust the cost handling on VMAT_CONTIGUOUS_PERMUTE + without calling vect_model_load_cost. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vect_model_load_cost): Assert it won't get + VMAT_CONTIGUOUS_REVERSE any more. + (vectorizable_load): Adjust the costing handling on + VMAT_CONTIGUOUS_REVERSE without calling vect_model_load_cost. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vectorizable_load): Adjust the cost handling on + VMAT_LOAD_STORE_LANES without calling vect_model_load_cost. + (vectorizable_load): Remove VMAT_LOAD_STORE_LANES related handling and + assert it will never get VMAT_LOAD_STORE_LANES. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vectorizable_load): Adjust the cost handling on + VMAT_GATHER_SCATTER without calling vect_model_load_cost. + (vect_model_load_cost): Adjut the assertion on VMAT_GATHER_SCATTER, + remove VMAT_GATHER_SCATTER related handlings and the related parameter + gs_info. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vectorizable_load): Adjust the cost handling + on VMAT_ELEMENTWISE and VMAT_STRIDED_SLP without calling + vect_model_load_cost. + (vect_model_load_cost): Assert it won't get VMAT_ELEMENTWISE and + VMAT_STRIDED_SLP any more, and remove their related handlings. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (hoist_defs_of_uses): Add one argument HOIST_P. + (vectorizable_load): Adjust the handling on VMAT_INVARIANT to respect + hoisting decision and without calling vect_model_load_cost. + (vect_model_load_cost): Assert it won't get VMAT_INVARIANT any more + and remove VMAT_INVARIANT related handlings. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vect_build_gather_load_calls): Add the handlings + on costing with one extra argument cost_vec. + (vectorizable_load): Adjust the call to vect_build_gather_load_calls. + (vect_model_load_cost): Assert it won't get VMAT_GATHER_SCATTER with + gs_info.decl set any more. + +2023-07-13 Kewen Lin + + * tree-vect-stmts.cc (vectorizable_load): Move and duplicate the call + to vect_model_load_cost down to some different transform paths + according to the handlings of different vect_memory_access_types. + +2023-07-13 Kewen Lin + + * tree.h (wi::from_mpz): Hide from GENERATOR_FILE. + +2023-07-13 Ju-Zhe Zhong + + * config/riscv/autovec.md + (len_mask_gather_load): New pattern. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + * config/riscv/predicates.md (const_1_operand): New predicate. + (vector_gs_scale_operand_16): Ditto. + (vector_gs_scale_operand_32): Ditto. + (vector_gs_scale_operand_64): Ditto. + (vector_gs_extension_operand): Ditto. + (vector_gs_scale_operand_16_rv32): Ditto. + (vector_gs_scale_operand_32_rv32): Ditto. + * config/riscv/riscv-protos.h (enum insn_type): Add gather/scatter. + (expand_gather_scatter): New function. + * config/riscv/riscv-v.cc (gen_const_vector_dup): Add gather/scatter. + (emit_vlmax_masked_store_insn): New function. + (emit_nonvlmax_masked_store_insn): Ditto. + (modulo_sel_indices): Ditto. + (expand_vec_perm): Fix SLP for gather/scatter. + (prepare_gather_scatter): New function. + (expand_gather_scatter): Ditto. + * config/riscv/riscv.cc (riscv_legitimize_move): Fix bug of + (subreg:SI (DI CONST_POLY_INT)). + * config/riscv/vector-iterators.md: Add gather/scatter. + * config/riscv/vector.md (vec_duplicate): Use "@" instead. + (@vec_duplicate): Ditto. + (@pred_indexed_store): + Fix name. + (@pred_indexed_store): Ditto. + 2023-07-12 Juzhe-Zhong * config/riscv/autovec.md (cond_len_): New pattern. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index da7e217..f1d3077 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230713 +20230714 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 82e5a96..7f8d96f 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2023-07-13 Mikael Morin + + PR fortran/106050 + * symbol.cc (gfc_restore_last_undo_checkpoint): Release symbols + in reverse order. + 2023-07-12 Andre Vehreschild PR fortran/102003 diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index d5faf14..774090e 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,7 @@ +2023-07-13 Rainer Orth + + * Make-lang.in (m2/boot-bin/mklink$(exeext)): Add $(LDFLAGS). + 2023-07-11 Gaius Mulley * gm2-compiler/M2BasicBlock.def (InitBasicBlocksFromRange): New diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b72c1f6..58d58c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,245 @@ +2023-07-13 Mikael Pettersson + + PR target/107841 + * gcc.target/pdp11/pr107841.c: New test. + +2023-07-13 Mikael Morin + + PR fortran/106050 + * gfortran.dg/pdt_33.f90: New test. + +2023-07-13 Carl Love + + * gcc.target/powerpc/test_fpscr_rn_builtin.c: Rename to + test_fpscr_rn_builtin_1.c. Add comment. + * gcc.target/powerpc/test_fpscr_rn_builtin_2.c: New test for the + return value of __builtin_set_fpscr_rn builtin. + * gcc.target/powerpc/test_fpscr_rn_builtin_1.c: New file. + +2023-07-13 Uros Bizjak + + PR target/106966 + * gcc.target/alpha/pr106966.c: New test. + +2023-07-13 Andrew Pinski + + * gcc.dg/tree-ssa/pr110293-1.c: New test. + * gcc.dg/tree-ssa/pr110539-1.c: New test. + * gcc.dg/tree-ssa/pr110539-2.c: New test. + * gcc.dg/tree-ssa/pr110539-3.c: New test. + * gcc.dg/tree-ssa/pr110539-4.c: New test. + +2023-07-13 Vladimir N. Makarov + + PR middle-end/109520 + * gcc.target/i386/pr109520.c: New test. + +2023-07-13 Pan Li + + * gcc.target/riscv/rvv/base/float-point-frm-insert-10.c: New test. + * gcc.target/riscv/rvv/base/float-point-frm-insert-7.c: New test. + * gcc.target/riscv/rvv/base/float-point-frm-insert-8.c: New test. + * gcc.target/riscv/rvv/base/float-point-frm-insert-9.c: New test. + * gcc.target/riscv/rvv/base/float-point-frm-run-1.c: New test. + * gcc.target/riscv/rvv/base/float-point-frm-run-2.c: New test. + * gcc.target/riscv/rvv/base/float-point-frm-run-3.c: New test. + +2023-07-13 Kewen Lin + + * gcc.target/i386/pr70021.c: Adjust with -fno-vect-cost-model. + +2023-07-13 Kewen Lin + + * gcc.dg/vect/costmodel/ppc/costmodel-vect-reversed.c: New test. + +2023-07-13 Bill Schmidt + Kewen Lin + + * gcc.dg/vect/costmodel/ppc/costmodel-pr82255.c: New test. + +2023-07-13 Ju-Zhe Zhong + + * gcc.target/riscv/rvv/rvv.exp: Add gather/scatter tests. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c: New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-11.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-12.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-3.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-4.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-5.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-6.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-9.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-11.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-3.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-4.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-5.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-6.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-7.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-8.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load_run-9.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-3.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-4.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-5.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-6.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-7.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-9.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-10.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-3.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-4.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-5.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-6.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-9.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load_run-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-1.c: + New test. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store_run-2.c: + New test. + 2023-07-12 Juzhe-Zhong * gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c: Adapt testcase. -- cgit v1.1 From 4dbb3af1efe55174a714d15c2994cf2842ef8c28 Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Fri, 14 Jul 2023 09:54:20 +0900 Subject: SH: Fix PR101496 peephole bug gcc/ChangeLog: PR target/101469 * config/sh/sh.md (peephole2): Handle case where eliminated reg is also used by the address of the following memory operand. --- gcc/config/sh/sh.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'gcc') diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 5cb1795..484a34f 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -10680,6 +10680,45 @@ && peep2_reg_dead_p (2, operands[1]) && peep2_reg_dead_p (3, operands[0])" [(const_int 0)] { + if (MEM_P (operands[3]) && reg_overlap_mentioned_p (operands[0], operands[3])) + { + // Take care when the eliminated operand[0] register is part of + // the destination memory address. + rtx addr = XEXP (operands[3], 0); + + if (REG_P (addr)) + operands[3] = replace_equiv_address (operands[3], operands[1]); + + else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) + && CONST_INT_P (XEXP (addr, 1)) + && REGNO (operands[0]) == REGNO (XEXP (addr, 0))) + operands[3] = replace_equiv_address (operands[3], + gen_rtx_PLUS (SImode, operands[1], XEXP (addr, 1))); + + else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) + && REG_P (XEXP (addr, 1))) + { + // register + register address @(R0, Rn) + // can change only the Rn in the address, not R0. + if (REGNO (operands[0]) == REGNO (XEXP (addr, 0)) + && REGNO (XEXP (addr, 0)) != 0) + { + operands[3] = replace_equiv_address (operands[3], + gen_rtx_PLUS (SImode, operands[1], XEXP (addr, 1))); + } + else if (REGNO (operands[0]) == REGNO (XEXP (addr, 1)) + && REGNO (XEXP (addr, 1)) != 0) + { + operands[3] = replace_equiv_address (operands[3], + gen_rtx_PLUS (SImode, XEXP (addr, 0), operands[1])); + } + else + FAIL; + } + else + FAIL; + } + emit_insn (gen_addsi3 (operands[1], operands[1], operands[2])); sh_peephole_emit_move_insn (operands[3], operands[1]); }) -- cgit v1.1 From 601a412ef0fe59ce48fb8635ebdaa58b58512a5a Mon Sep 17 00:00:00 2001 From: Die Li Date: Fri, 14 Jul 2023 02:02:05 +0000 Subject: RISC-V: Remove the redundant expressions in the and3. When generating the gen_and3 function based on the and3 template, it produces the expression emit_insn (gen_rtx_SET (operand0, gen_rtx_AND (, operand1, operand2)));, which is identical to the portion I removed in this patch. Therefore, the redundant portion can be deleted. Signed-off-by: Die Li gcc/ChangeLog: * config/riscv/riscv.md: Remove redundant portion in and3. --- gcc/config/riscv/riscv.md | 5 ----- 1 file changed, 5 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 7988026..c4f8eb9 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1491,11 +1491,6 @@ DONE; } } - else - { - emit_move_insn (operands[0], gen_rtx_AND (mode, operands[1], operands[2])); - DONE; - } }) (define_insn "*and3" -- cgit v1.1 From ad0518d97cfc857183e524fabc104ebeec9e8ccd Mon Sep 17 00:00:00 2001 From: Monk Chiang Date: Thu, 13 Jul 2023 13:38:55 +0800 Subject: RISC-V: Recognized zihintntl extensions gcc/ChangeLog: * common/config/riscv/riscv-common.cc: (riscv_implied_info): Add zihintntl item. (riscv_ext_version_table): Ditto. (riscv_ext_flag_table): Ditto. * config/riscv/riscv-opts.h (MASK_ZIHINTNTL): New macro. (TARGET_ZIHINTNTL): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/arch-22.c: New test. * gcc.target/riscv/predef-28.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 4 +++ gcc/config/riscv/riscv-opts.h | 2 ++ gcc/testsuite/gcc.target/riscv/arch-22.c | 5 ++++ gcc/testsuite/gcc.target/riscv/predef-28.c | 47 ++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/arch-22.c create mode 100644 gcc/testsuite/gcc.target/riscv/predef-28.c (limited to 'gcc') diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 6091d8f..28c8f0c 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -206,6 +206,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zksh", ISA_SPEC_CLASS_NONE, 1, 0}, {"zkt", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zihintntl", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zicboz",ISA_SPEC_CLASS_NONE, 1, 0}, {"zicbom",ISA_SPEC_CLASS_NONE, 1, 0}, {"zicbop",ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1267,6 +1269,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zksh", &gcc_options::x_riscv_zk_subext, MASK_ZKSH}, {"zkt", &gcc_options::x_riscv_zk_subext, MASK_ZKT}, + {"zihintntl", &gcc_options::x_riscv_zi_subext, MASK_ZIHINTNTL}, + {"zicboz", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOZ}, {"zicbom", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOM}, {"zicbop", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOP}, diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index cfcf608..beee241 100644 --- a/gcc/config/riscv/riscv-opts.h +++ b/gcc/config/riscv/riscv-opts.h @@ -101,9 +101,11 @@ enum riscv_entity #define MASK_ZICSR (1 << 0) #define MASK_ZIFENCEI (1 << 1) +#define MASK_ZIHINTNTL (1 << 2) #define TARGET_ZICSR ((riscv_zi_subext & MASK_ZICSR) != 0) #define TARGET_ZIFENCEI ((riscv_zi_subext & MASK_ZIFENCEI) != 0) +#define TARGET_ZIHINTNTL ((riscv_zi_subext & MASK_ZIHINTNTL) != 0) #define MASK_ZAWRS (1 << 0) #define TARGET_ZAWRS ((riscv_za_subext & MASK_ZAWRS) != 0) diff --git a/gcc/testsuite/gcc.target/riscv/arch-22.c b/gcc/testsuite/gcc.target/riscv/arch-22.c new file mode 100644 index 0000000..cdc18e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-22.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc_zihintntl -mabi=lp64 -mcmodel=medlow" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/predef-28.c b/gcc/testsuite/gcc.target/riscv/predef-28.c new file mode 100644 index 0000000..81fdad5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/predef-28.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zihintntl -mabi=lp64 -mcmodel=medlow" } */ + +int main () { + +#ifndef __riscv_arch_test +#error "__riscv_arch_test" +#endif + +#if __riscv_xlen != 64 +#error "__riscv_xlen" +#endif + +#if !defined(__riscv_i) +#error "__riscv_i" +#endif + +#if !defined(__riscv_c) +#error "__riscv_c" +#endif + +#if defined(__riscv_e) +#error "__riscv_e" +#endif + +#if !defined(__riscv_a) +#error "__riscv_a" +#endif + +#if !defined(__riscv_m) +#error "__riscv_m" +#endif + +#if !defined(__riscv_f) +#error "__riscv_f" +#endif + +#if !defined(__riscv_d) +#error "__riscv_d" +#endif + +#if !defined(__riscv_zihintntl) +#error "__riscv_zihintntl" +#endif + + return 0; +} -- cgit v1.1 From b77161e60bce7b4416319defe5f141f14fd375c4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 14 Jul 2023 10:01:39 +0200 Subject: Provide extra checking for phi argument access from edge The following adds checking that the edge we query an associated PHI arg for is related to the PHI node. Triggered by questionable code in one of my reviews. * gimple.h (gimple_phi_arg): New const overload. (gimple_phi_arg_def): Make gimple arg const. (gimple_phi_arg_def_from_edge): New inline function. * tree-phinodes.h (gimple_phi_arg_imm_use_ptr_from_edge): Likewise. * tree-ssa-operands.h (PHI_ARG_DEF_FROM_EDGE): Direct to new inline function. (PHI_ARG_DEF_PTR_FROM_EDGE): Likewise. --- gcc/gimple.h | 25 ++++++++++++++++++++++++- gcc/tree-phinodes.h | 7 +++++++ gcc/tree-ssa-operands.h | 4 ++-- 3 files changed, 33 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple.h b/gcc/gimple.h index daf5524..d3750f9 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -4633,6 +4633,13 @@ gimple_phi_arg (const gphi *gs, unsigned index) return &(gs->args[index]); } +inline const phi_arg_d * +gimple_phi_arg (const gimple *gs, unsigned index) +{ + const gphi *phi_stmt = as_a (gs); + return gimple_phi_arg (phi_stmt, index); +} + inline struct phi_arg_d * gimple_phi_arg (gimple *gs, unsigned index) { @@ -4678,11 +4685,27 @@ gimple_phi_arg_def (const gphi *gs, size_t index) } inline tree -gimple_phi_arg_def (gimple *gs, size_t index) +gimple_phi_arg_def (const gimple *gs, size_t index) { return gimple_phi_arg (gs, index)->def; } +/* Return the tree operand for the argument associated with + edge E of PHI node GS. */ + +inline tree +gimple_phi_arg_def_from_edge (const gphi *gs, const_edge e) +{ + gcc_checking_assert (e->dest == gimple_bb (gs)); + return gimple_phi_arg (gs, e->dest_idx)->def; +} + +inline tree +gimple_phi_arg_def_from_edge (const gimple *gs, const_edge e) +{ + gcc_checking_assert (e->dest == gimple_bb (gs)); + return gimple_phi_arg (gs, e->dest_idx)->def; +} /* Return a pointer to the tree operand for argument I of phi node PHI. */ diff --git a/gcc/tree-phinodes.h b/gcc/tree-phinodes.h index 932a461..be114e3 100644 --- a/gcc/tree-phinodes.h +++ b/gcc/tree-phinodes.h @@ -37,6 +37,13 @@ gimple_phi_arg_imm_use_ptr (gimple *gs, int i) return &gimple_phi_arg (gs, i)->imm_use; } +inline use_operand_p +gimple_phi_arg_imm_use_ptr_from_edge (gimple *gs, const_edge e) +{ + gcc_checking_assert (e->dest == gimple_bb (gs)); + return &gimple_phi_arg (gs, e->dest_idx)->imm_use; +} + /* Return the phi argument which contains the specified use. */ inline int diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h index ae36bcd..c7b74e0 100644 --- a/gcc/tree-ssa-operands.h +++ b/gcc/tree-ssa-operands.h @@ -83,9 +83,9 @@ struct GTY(()) ssa_operands { #define SET_PHI_ARG_DEF(PHI, I, V) \ SET_USE (PHI_ARG_DEF_PTR ((PHI), (I)), (V)) #define PHI_ARG_DEF_FROM_EDGE(PHI, E) \ - PHI_ARG_DEF ((PHI), (E)->dest_idx) + gimple_phi_arg_def_from_edge ((PHI), (E)) #define PHI_ARG_DEF_PTR_FROM_EDGE(PHI, E) \ - PHI_ARG_DEF_PTR ((PHI), (E)->dest_idx) + gimple_phi_arg_imm_use_ptr_from_edge ((PHI), (E)) #define PHI_ARG_INDEX_FROM_USE(USE) phi_arg_index_from_use (USE) -- cgit v1.1 From d8f5e349772b6652bddb0620bb178290905998b9 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Fri, 14 Jul 2023 11:21:12 +0100 Subject: ifcvt: Reduce comparisons on conditionals by tracking truths [PR109154] Following on from Jakub's patch in g:de0ee9d14165eebb3d31c84e98260c05c3b33acb these two patches finishes the work fixing the regression and improves codegen. As explained in that commit, ifconvert sorts PHI args in increasing number of occurrences in order to reduce the number of comparisons done while traversing the tree. The remaining task that this patch fixes is dealing with the long chain of comparisons that can be created from phi nodes, particularly when they share any common successor (classical example is a diamond node). on a PHI-node the true and else branches carry a condition, true will carry `a` and false `~a`. The issue is that at the moment GCC tests both `a` and `~a` when the phi node has more than 2 arguments. Clearly this isn't needed. The deeper the nesting of phi nodes the larger the repetition. As an example, for foo (int *f, int d, int e) { for (int i = 0; i < 1024; i++) { int a = f[i]; int t; if (a < 0) t = 1; else if (a < e) t = 1 - a * d; else t = 0; f[i] = t; } } after Jakub's patch we generate: _7 = a_10 < 0; _21 = a_10 >= 0; _22 = a_10 < e_11(D); _23 = _21 & _22; _ifc__42 = _23 ? t_13 : 0; t_6 = _7 ? 1 : _ifc__42 but while better than before it is still inefficient, since in the false branch, where we know ~_7 is true, we still test _21. This leads to superfluous tests for every diamond node. After this patch we generate _7 = a_10 < 0; _22 = a_10 < e_11(D); _ifc__42 = _22 ? t_13 : 0; t_6 = _7 ? 1 : _ifc__42; Which correctly elides the test of _21. This is done by borrowing the vectorizer's helper functions to limit predicate mask usages. Ifcvt will chain conditionals on the false edge (unless specifically inverted) so this patch on creating cond a ? b : c, will register ~a when traversing c. If c is a conditional then c will be simplified to the smaller possible predicate given the assumptions we already know to be true. gcc/ChangeLog: PR tree-optimization/109154 * tree-if-conv.cc (gen_simplified_condition, gen_phi_nest_statement): New. (gen_phi_arg_condition, predicate_scalar_phi): Use it. gcc/testsuite/ChangeLog: PR tree-optimization/109154 * gcc.dg/vect/vect-ifcvt-19.c: New test. --- gcc/testsuite/gcc.dg/vect/vect-ifcvt-19.c | 63 ++++++++++++++ gcc/tree-if-conv.cc | 137 ++++++++++++++++++++++++------ 2 files changed, 174 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-ifcvt-19.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-19.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-19.c new file mode 100644 index 0000000..e34bfa9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-19.c @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple -Ofast -fdump-tree-ifcvt-raw" } */ + +void __GIMPLE (ssa,guessed_local(10737414), startwith ("fix_loops")) +foo (int * f, int d, int e) +{ + int t; + int a; + int i; + long unsigned int _1; + long unsigned int _2; + int * _3; + int _4; + + __BB(2,guessed_local(10737414)): + goto __BB3(guessed(134217728)); + + __BB(3,loop_header(1),guessed_local(1063004408)): + i_18 = __PHI (__BB8: i_15, __BB2: 0); + _1 = (long unsigned int) i_18; + _2 = _1 * 4ul; + _3 = f_9(D) + _2; + a_10 = __MEM (_3); + if (a_10 < 0) + goto __BB9(guessed(55029268)); + else + goto __BB4(guessed(79188460)); + + __BB(9,guessed_local(435831803)): + goto __BB6(precise(134217728)); + + __BB(4,guessed_local(627172605)): + if (a_10 < e_11(D)) + goto __BB5(guessed(67108864)); + else + goto __BB10(guessed(67108864)); + + __BB(10,guessed_local(313586303)): + goto __BB6(precise(134217728)); + + __BB(5,guessed_local(313586302)): + _4 = a_10 * d_12(D); + t_13 = 1 - _4; + goto __BB6(precise(134217728)); + + __BB(6,guessed_local(1063004410)): + t_6 = __PHI (__BB9: 1, __BB5: t_13, __BB10: 0); + __MEM (_3) = t_6; + i_15 = i_18 + 1; + if (i_15 != 1024) + goto __BB8(guessed(132875551)); + else + goto __BB7(guessed(1342177)); + + __BB(8,guessed_local(1052374368)): + goto __BB3(precise(134217728)); + + __BB(7,guessed_local(10737416)): + return; + +} + +/* { dg-final { scan-tree-dump-times { (stmt)) + && gimple_assign_rhs_code (assign) == BIT_AND_EXPR) + { + tree arg1 = gimple_assign_rhs1 (assign); + tree arg2 = gimple_assign_rhs2 (assign); + if (cond_set.contains ({ arg1, 1 })) + arg1 = boolean_true_node; + else + arg1 = gen_simplified_condition (arg1, cond_set); + + if (cond_set.contains ({ arg2, 1 })) + arg2 = boolean_true_node; + else + arg2 = gen_simplified_condition (arg2, cond_set); + + cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, arg1, arg2); + } + } + return cond; +} + /* Produce condition for all occurrences of ARG in PHI node. Set *INVERT as to whether the condition is inverted. */ static tree -gen_phi_arg_condition (gphi *phi, vec *occur, - gimple_stmt_iterator *gsi, bool *invert) +gen_phi_arg_condition (gphi *phi, vec *occur, gimple_stmt_iterator *gsi, + scalar_cond_masked_set_type &cond_set, bool *invert) { int len; int i; @@ -1902,6 +1934,8 @@ gen_phi_arg_condition (gphi *phi, vec *occur, c = TREE_OPERAND (c, 0); *invert = true; } + + c = gen_simplified_condition (c, cond_set); c = force_gimple_operand_gsi (gsi, unshare_expr (c), true, NULL_TREE, true, GSI_SAME_STMT); if (cond != NULL_TREE) @@ -1913,11 +1947,79 @@ gen_phi_arg_condition (gphi *phi, vec *occur, } else cond = c; + + /* Register the new possibly simplified conditional. When more than 2 + entries in a phi node we chain entries in the false branch, so the + inverted condition is active. */ + scalar_cond_masked_key pred_cond ({ cond, 1 }); + if (!*invert) + pred_cond.inverted_p = !pred_cond.inverted_p; + cond_set.add (pred_cond); } gcc_assert (cond != NULL_TREE); return cond; } +/* Create the smallest nested conditional possible. On pre-order we record + which conditionals are live, and on post-order rewrite the chain by removing + already active conditions. + + As an example we simplify: + + _7 = a_10 < 0; + _21 = a_10 >= 0; + _22 = a_10 < e_11(D); + _23 = _21 & _22; + _ifc__42 = _23 ? t_13 : 0; + t_6 = _7 ? 1 : _ifc__42 + + into + + _7 = a_10 < 0; + _22 = a_10 < e_11(D); + _ifc__42 = _22 ? t_13 : 0; + t_6 = _7 ? 1 : _ifc__42; + + which produces better code. */ + +static tree +gen_phi_nest_statement (gphi *phi, gimple_stmt_iterator *gsi, + scalar_cond_masked_set_type &cond_set, tree type, + hash_map> &phi_arg_map, + gimple **res_stmt, tree lhs0, vec &args, + unsigned idx) +{ + if (idx == args.length ()) + return args[idx - 1]; + + vec *indexes = phi_arg_map.get (args[idx - 1]); + bool invert; + tree cond = gen_phi_arg_condition (phi, indexes, gsi, cond_set, &invert); + tree arg1 = gen_phi_nest_statement (phi, gsi, cond_set, type, phi_arg_map, + res_stmt, lhs0, args, idx + 1); + + unsigned prev = idx; + unsigned curr = prev - 1; + tree arg0 = args[curr]; + tree rhs, lhs; + if (idx > 1) + lhs = make_temp_ssa_name (type, NULL, "_ifc_"); + else + lhs = lhs0; + + if (invert) + rhs = fold_build_cond_expr (type, unshare_expr (cond), + arg1, arg0); + else + rhs = fold_build_cond_expr (type, unshare_expr (cond), + arg0, arg1); + gassign *new_stmt = gimple_build_assign (lhs, rhs); + gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); + update_stmt (new_stmt); + *res_stmt = new_stmt; + return lhs; +} + /* Replace a scalar PHI node with a COND_EXPR using COND as condition. This routine can handle PHI nodes with more than two arguments. @@ -1968,6 +2070,8 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) } bb = gimple_bb (phi); + /* Keep track of conditionals already seen. */ + scalar_cond_masked_set_type cond_set; if (EDGE_COUNT (bb->preds) == 2) { /* Predicate ordinary PHI node with 2 arguments. */ @@ -1976,6 +2080,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) first_edge = EDGE_PRED (bb, 0); second_edge = EDGE_PRED (bb, 1); cond = bb_predicate (first_edge->src); + cond_set.add ({ cond, 1 }); if (TREE_CODE (cond) == TRUTH_NOT_EXPR) std::swap (first_edge, second_edge); if (EDGE_COUNT (first_edge->src->succs) > 1) @@ -1988,7 +2093,9 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) } else cond = bb_predicate (first_edge->src); + /* Gimplify the condition to a valid cond-expr conditonal operand. */ + cond = gen_simplified_condition (cond, cond_set); cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true, NULL_TREE, true, GSI_SAME_STMT); true_bb = first_edge->src; @@ -2110,31 +2217,9 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) else { /* Common case. */ - vec *indexes; tree type = TREE_TYPE (gimple_phi_result (phi)); - tree lhs; - arg1 = args[args_len - 1]; - for (i = args_len - 1; i > 0; i--) - { - arg0 = args[i - 1]; - indexes = phi_arg_map.get (args[i - 1]); - if (i != 1) - lhs = make_temp_ssa_name (type, NULL, "_ifc_"); - else - lhs = res; - bool invert; - cond = gen_phi_arg_condition (phi, indexes, gsi, &invert); - if (invert) - rhs = fold_build_cond_expr (type, unshare_expr (cond), - arg1, arg0); - else - rhs = fold_build_cond_expr (type, unshare_expr (cond), - arg0, arg1); - new_stmt = gimple_build_assign (lhs, rhs); - gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); - update_stmt (new_stmt); - arg1 = lhs; - } + gen_phi_nest_statement (phi, gsi, cond_set, type, phi_arg_map, + &new_stmt, res, args, 1); } if (dump_file && (dump_flags & TDF_DETAILS)) -- cgit v1.1 From 9ed4fcfe47f28b36c73d74109898514ef4da00fb Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Fri, 14 Jul 2023 11:21:46 +0100 Subject: ifcvt: Sort PHI arguments not only occurrences but also complexity [PR109154] This patch builds on the previous patch by fixing another issue with the way ifcvt currently picks which branches to test. The issue with the current implementation is while it sorts for occurrences of the argument, it doesn't check for complexity of the arguments. As an example: [local count: 528603100]: ... if (distbb_75 >= 0.0) goto ; [59.00%] else goto ; [41.00%] [local count: 216727269]: ... goto ; [100.00%] [local count: 311875831]: ... if (distbb_75 < iftmp.0_98) goto ; [20.00%] else goto ; [80.00%] [local count: 62375167]: ... [local count: 528603100]: # prephitmp_175 = PHI <_173(18), 0.0(17), _174(16)> All tree arguments to the PHI have the same number of occurrences, namely 1, however it makes a big difference which comparison we test first. Sorting only on occurrences we'll pick the compares coming from BB 18 and BB 17, This means we end up generating 4 comparisons, while 2 would have been enough. By keeping track of the "complexity" of the COND in each BB, (i.e. the number of comparisons needed to traverse from the start [BB 15] to end [BB 19]) and using a key tuple of we end up selecting the compare from BB 16 and BB 18 first. BB 16 only requires 1 compare, and BB 18, after we test BB 16 also only requires one additional compare. This change paired with the one previous above results in the optimal 2 compares. For deep nesting, i.e. for ... _79 = vr_15 > 20; _80 = _68 & _79; _82 = vr_15 <= 20; _83 = _68 & _82; _84 = vr_15 < -20; _85 = _73 & _84; _87 = vr_15 >= -20; _88 = _73 & _87; _ifc__111 = _55 ? 10 : 12; _ifc__112 = _70 ? 7 : _ifc__111; _ifc__113 = _85 ? 8 : _ifc__112; _ifc__114 = _88 ? 9 : _ifc__113; _ifc__115 = _45 ? 1 : _ifc__114; _ifc__116 = _63 ? 3 : _ifc__115; _ifc__117 = _65 ? 4 : _ifc__116; _ifc__118 = _83 ? 6 : _ifc__117; _ifc__119 = _60 ? 2 : _ifc__118; _ifc__120 = _43 ? 13 : _ifc__119; _ifc__121 = _75 ? 11 : _ifc__120; vw_1 = _80 ? 5 : _ifc__121; Most of the comparisons are still needed because the chain of occurrences to not negate eachother. i.e. _80 is _73 & vr_15 >= -20 and _85 is _73 & vr_15 < -20. clearly given _73 needs to be true in both branches, the only additional test needed is on vr_15, where the one test is the negation of the other. So we don't need to do the comparison of _73 twice. The changes in the patch reduces the overall number of compares by one, but has a bigger effect on the dependency chain. Previously we would generate 5 instructions chain: cmple p7.s, p4/z, z29.s, z30.s cmpne p7.s, p7/z, z29.s, #0 cmple p6.s, p7/z, z31.s, z30.s cmpge p6.s, p6/z, z27.s, z25.s cmplt p15.s, p6/z, z28.s, z21.s as the longest chain. With this patch we generate 3: cmple p7.s, p3/z, z27.s, z30.s cmpne p7.s, p7/z, z27.s, #0 cmpgt p7.s, p7/z, z31.s, z30.s and I don't think (x <= y) && (x != 0) && (z > y) can be reduced further. gcc/ChangeLog: PR tree-optimization/109154 * tree-if-conv.cc (INCLUDE_ALGORITHM): Include. (struct bb_predicate): Add no_predicate_stmts. (set_bb_predicate): Increase predicate count. (set_bb_predicate_gimplified_stmts): Conditionally initialize no_predicate_stmts. (get_bb_num_predicate_stmts): New. (init_bb_predicate): Initialzie no_predicate_stmts. (release_bb_predicate): Cleanup no_predicate_stmts. (insert_gimplified_predicates): Preserve no_predicate_stmts. gcc/testsuite/ChangeLog: PR tree-optimization/109154 * gcc.dg/vect/vect-ifcvt-20.c: New test. --- gcc/testsuite/gcc.dg/vect/vect-ifcvt-20.c | 62 +++++++++++++++++++++++++ gcc/tree-if-conv.cc | 75 ++++++++++++++++++++++--------- 2 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-ifcvt-20.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-20.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-20.c new file mode 100644 index 0000000..96c5f5a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-20.c @@ -0,0 +1,62 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple -fopenmp-simd -Ofast -fdump-tree-ifcvt-raw" } */ + +void foo (int * restrict p, int * restrict q, int * restrict r, int * restrict s, int * restrict t, int * restrict u) +{ +#pragma omp simd + for (int i = 0; i < 1024; i++) + { + int vp = p[i]; + int vq = q[i]; + int vr = r[i]; + int vs = s[i]; + int vt = t[i]; + int vu = u[i]; + int vw; + if (vp != 0) + { + if (vp > 100) + { + if (vq < 200) + vw = 1; + else if (vr) + vw = 2; + else + vw = 3; + } + else if (vs > 100) + { + if (vq < 180) + vw = 4; + else if (vr > 20) + vw = 5; + else + vw = 6; + } + else + { + if (vq < -100) + vw = 7; + else if (vr < -20) + vw = 8; + else + vw = 9; + } + } + else if (vt > 10) + { + if (vu > 100) + vw = 10; + else if (vu < -100) + vw = 11; + else + vw = 12; + } + else + vw = 13; + u[i] = vw; + } +} + +/* { dg-final { scan-tree-dump-times {:; */ +#define INCLUDE_ALGORITHM #include "config.h" #include "system.h" #include "coretypes.h" @@ -231,6 +232,10 @@ struct bb_predicate { recorded here, in order to avoid the duplication of computations that occur in previous conditions. See PR44483. */ gimple_seq predicate_gimplified_stmts; + + /* Records the number of statements recorded into + PREDICATE_GIMPLIFIED_STMTS. */ + unsigned no_predicate_stmts; }; /* Returns true when the basic block BB has a predicate. */ @@ -254,10 +259,16 @@ bb_predicate (basic_block bb) static inline void set_bb_predicate (basic_block bb, tree cond) { + auto aux = (struct bb_predicate *) bb->aux; gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR && is_gimple_val (TREE_OPERAND (cond, 0))) || is_gimple_val (cond)); - ((struct bb_predicate *) bb->aux)->predicate = cond; + aux->predicate = cond; + aux->no_predicate_stmts++; + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Recording block %d value %d\n", bb->index, + aux->no_predicate_stmts); } /* Returns the sequence of statements of the gimplification of the @@ -270,12 +281,16 @@ bb_predicate_gimplified_stmts (basic_block bb) } /* Sets the sequence of statements STMTS of the gimplification of the - predicate for basic block BB. */ + predicate for basic block BB. If PRESERVE_COUNTS then don't clear the predicate + counts. */ static inline void -set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts) +set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts, + bool preserve_counts) { ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts = stmts; + if (stmts == NULL && !preserve_counts) + ((struct bb_predicate *) bb->aux)->no_predicate_stmts = 0; } /* Adds the sequence of statements STMTS to the sequence of statements @@ -296,18 +311,28 @@ add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts) gimple *stmt = gsi_stmt (gsi); delink_stmt_imm_use (stmt); gimple_set_modified (stmt, true); + ((struct bb_predicate *) bb->aux)->no_predicate_stmts++; } gimple_seq_add_seq_without_update (&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts); } +/* Return the number of statements the predicate of the basic block consists + of. */ + +static inline unsigned +get_bb_num_predicate_stmts (basic_block bb) +{ + return ((struct bb_predicate *) bb->aux)->no_predicate_stmts; +} + /* Initializes to TRUE the predicate of basic block BB. */ static inline void init_bb_predicate (basic_block bb) { bb->aux = XNEW (struct bb_predicate); - set_bb_predicate_gimplified_stmts (bb, NULL); + set_bb_predicate_gimplified_stmts (bb, NULL, false); set_bb_predicate (bb, boolean_true_node); } @@ -327,7 +352,7 @@ release_bb_predicate (basic_block bb) /* Discard them. */ gimple_seq_discard (stmts); - set_bb_predicate_gimplified_stmts (bb, NULL); + set_bb_predicate_gimplified_stmts (bb, NULL, false); } } @@ -2041,7 +2066,6 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) tree rhs, res, arg0, arg1, op0, op1, scev; tree cond; unsigned int index0; - unsigned int max, args_len; edge e; basic_block bb; unsigned int i; @@ -2145,7 +2169,6 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) bool swap = false; hash_map > phi_arg_map; unsigned int num_args = gimple_phi_num_args (phi); - int max_ind = -1; /* Vector of different PHI argument values. */ auto_vec args (num_args); @@ -2160,28 +2183,38 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) phi_arg_map.get_or_insert (arg).safe_push (i); } - /* Determine element with max number of occurrences. */ - max_ind = -1; - max = 1; - args_len = args.length (); - for (i = 0; i < args_len; i++) + /* Determine element with max number of occurrences and complexity. Looking at only + number of occurrences as a measure for complexity isn't enough as all usages can + be unique but the comparisons to reach the PHI node differ per branch. */ + typedef std::pair > ArgEntry; + auto_vec argsKV; + for (i = 0; i < args.length (); i++) { - unsigned int len; - if ((len = phi_arg_map.get (args[i])->length ()) > max) + unsigned int len = 0; + for (int index : phi_arg_map.get (args[i])) { - max_ind = (int) i; - max = len; + edge e = gimple_phi_arg_edge (phi, index); + len += get_bb_num_predicate_stmts (e->src); } + + unsigned occur = phi_arg_map.get (args[i])->length (); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Ranking %d as len=%d, idx=%d\n", i, len, occur); + argsKV.safe_push ({ args[i], { len, occur }}); } - /* Put element with max number of occurences to the end of ARGS. */ - if (max_ind != -1 && max_ind + 1 != (int) args_len) - std::swap (args[args_len - 1], args[max_ind]); + /* Sort elements based on rankings ARGS. */ + std::sort(argsKV.begin(), argsKV.end(), [](ArgEntry &left, ArgEntry &right) { + return left.second < right.second; + }); + + for (i = 0; i < args.length (); i++) + args[i] = argsKV[i].first; /* Handle one special case when number of arguments with different values is equal 2 and one argument has the only occurrence. Such PHI can be handled as if would have only 2 arguments. */ - if (args_len == 2 && phi_arg_map.get (args[0])->length () == 1) + if (args.length () == 2 && phi_arg_map.get (args[0])->length () == 1) { vec *indexes; indexes = phi_arg_map.get (args[0]); @@ -2317,7 +2350,7 @@ insert_gimplified_predicates (loop_p loop) } /* Once the sequence is code generated, set it to NULL. */ - set_bb_predicate_gimplified_stmts (bb, NULL); + set_bb_predicate_gimplified_stmts (bb, NULL, true); } } } -- cgit v1.1 From e93452a5712e87ba624562ba7164b1e1394d18fb Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Fri, 14 Jul 2023 14:15:07 +0200 Subject: fortran: defer class wrapper initialization after deallocation [PR92178] If an actual argument is associated with an INTENT(OUT) dummy, and code to deallocate it is generated, generate the class wrapper initialization after the actual argument deallocation. This is achieved by passing a cleaned up expression to gfc_conv_class_to_class, so that the class wrapper initialization code can be isolated and moved independently after the deallocation. PR fortran/92178 gcc/fortran/ChangeLog: * trans-expr.cc (gfc_conv_procedure_call): Use a separate gfc_se struct, initalized from parmse, to generate the class wrapper. After the class wrapper code has been generated, copy it back depending on whether parameter deallocation code has been generated. gcc/testsuite/ChangeLog: * gfortran.dg/intent_out_19.f90: New test. --- gcc/fortran/trans-expr.cc | 18 +++++++++++++++++- gcc/testsuite/gfortran.dg/intent_out_19.f90 | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/intent_out_19.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 7017b65..b7e95e6 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6500,6 +6500,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else { + bool defer_to_dealloc_blk = false; if (e->ts.type == BT_CLASS && fsym && fsym->ts.type == BT_CLASS && (!CLASS_DATA (fsym)->as @@ -6661,6 +6662,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, stmtblock_t block; tree ptr; + defer_to_dealloc_blk = true; + gfc_init_block (&block); ptr = parmse.expr; if (e->ts.type == BT_CLASS) @@ -6717,7 +6720,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && ((CLASS_DATA (fsym)->as && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK) || CLASS_DATA (e)->attr.dimension)) - gfc_conv_class_to_class (&parmse, e, fsym->ts, false, + { + gfc_se class_se = parmse; + gfc_init_block (&class_se.pre); + gfc_init_block (&class_se.post); + + gfc_conv_class_to_class (&class_se, e, fsym->ts, false, fsym->attr.intent != INTENT_IN && (CLASS_DATA (fsym)->attr.class_pointer || CLASS_DATA (fsym)->attr.allocatable), @@ -6727,6 +6735,14 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, CLASS_DATA (fsym)->attr.class_pointer || CLASS_DATA (fsym)->attr.allocatable); + parmse.expr = class_se.expr; + stmtblock_t *class_pre_block = defer_to_dealloc_blk + ? &dealloc_blk + : &parmse.pre; + gfc_add_block_to_block (class_pre_block, &class_se.pre); + gfc_add_block_to_block (&parmse.post, &class_se.post); + } + if (fsym && (fsym->ts.type == BT_DERIVED || fsym->ts.type == BT_ASSUMED) && e->ts.type == BT_CLASS diff --git a/gcc/testsuite/gfortran.dg/intent_out_19.f90 b/gcc/testsuite/gfortran.dg/intent_out_19.f90 new file mode 100644 index 0000000..03036ed --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intent_out_19.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +! +! PR fortran/92178 +! Check that if a data reference passed is as actual argument whose dummy +! has INTENT(OUT) attribute, any other argument depending on the +! same data reference is evaluated before the data reference deallocation. + +program p + implicit none + class(*), allocatable :: c + c = 3 + call bar (allocated(c), c, allocated (c)) + if (allocated (c)) stop 14 +contains + subroutine bar (alloc, x, alloc2) + logical :: alloc, alloc2 + class(*), allocatable, intent(out) :: x(..) + if (allocated (x)) stop 5 + if (.not. alloc) stop 6 + if (.not. alloc2) stop 16 + end subroutine bar +end -- cgit v1.1 From 71e4d568b1264bca46d30c5fc4933f137d05ca24 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Fri, 14 Jul 2023 14:15:21 +0200 Subject: fortran: Factor data references for scalar class argument wrapping [PR92178] In the case of a scalar actual arg passed to a polymorphic assumed-rank dummy with INTENT(OUT) attribute, avoid repeatedly evaluating the actual argument reference by saving a pointer to it. This is non-optimal, but may also be invalid, because the data reference may depend on its own content. In that case the expression can't be evaluated after the data has been deallocated. There are two ways redundant expressions are generated: - parmse.expr, which contains the actual argument expression, is reused to get or set subfields in gfc_conv_class_to_class. - gfc_conv_class_to_class, to get the virtual table pointer associated with the argument, generates a new expression from scratch starting with the frontend expression. The first part is fixed by saving parmse.expr to a pointer and using the pointer instead of the original expression. The second part is fixed by adding a separate field to gfc_se that is set to the class container expression when the expression to evaluate is polymorphic. This needs the same field in gfc_ss_info so that its value can be propagated to gfc_conv_class_to_class which is modified to use that value. Finally gfc_conv_procedure saves the expression in that field to a pointer in between to avoid the same problem as for the first part. PR fortran/92178 gcc/fortran/ChangeLog: * trans.h (struct gfc_se): New field class_container. (struct gfc_ss_info): Ditto. (gfc_evaluate_data_ref_now): New prototype. * trans.cc (gfc_evaluate_data_ref_now): Implement it. * trans-array.cc (gfc_conv_ss_descriptor): Copy class_container field from gfc_se struct to gfc_ss_info struct. (gfc_conv_expr_descriptor): Copy class_container field from gfc_ss_info struct to gfc_se struct. * trans-expr.cc (gfc_conv_class_to_class): Use class container set in class_container field if available. (gfc_conv_variable): Set class_container field on encountering class variables or components, clear it on encountering non-class components. (gfc_conv_procedure_call): Evaluate data ref to a pointer now, and replace later references by usage of the pointer. gcc/testsuite/ChangeLog: * gfortran.dg/intent_out_20.f90: New test. --- gcc/fortran/trans-array.cc | 3 +++ gcc/fortran/trans-expr.cc | 26 +++++++++++++++++++++++ gcc/fortran/trans.cc | 28 ++++++++++++++++++++++++ gcc/fortran/trans.h | 6 ++++++ gcc/testsuite/gfortran.dg/intent_out_20.f90 | 33 +++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/intent_out_20.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index e7c51ba..1c2af55 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -3271,6 +3271,7 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base) gfc_add_block_to_block (block, &se.pre); info->descriptor = se.expr; ss_info->string_length = se.string_length; + ss_info->class_container = se.class_container; if (base) { @@ -7687,6 +7688,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) else if (deferred_array_component) se->string_length = ss_info->string_length; + se->class_container = ss_info->class_container; + gfc_free_ss_chain (ss); return; } diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index b7e95e6..5169fbc 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -1266,6 +1266,10 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, slen = build_zero_cst (size_type_node); } + else if (parmse->class_container != NULL_TREE) + /* Don't redundantly evaluate the expression if the required information + is already available. */ + tmp = parmse->class_container; else { /* Remove everything after the last class reference, convert the @@ -3078,6 +3082,11 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr) return; } + if (sym->ts.type == BT_CLASS + && sym->attr.class_ok + && sym->ts.u.derived->attr.is_class) + se->class_container = se->expr; + /* Dereference the expression, where needed. */ se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only, is_classarray); @@ -3135,6 +3144,15 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr) conv_parent_component_references (se, ref); gfc_conv_component_ref (se, ref); + + if (ref->u.c.component->ts.type == BT_CLASS + && ref->u.c.component->attr.class_ok + && ref->u.c.component->ts.u.derived->attr.is_class) + se->class_container = se->expr; + else if (!(ref->u.c.sym->attr.flavor == FL_DERIVED + && ref->u.c.sym->attr.is_class)) + se->class_container = NULL_TREE; + if (!ref->next && ref->u.c.sym->attr.codimension && se->want_pointer && se->descriptor_only) return; @@ -6664,6 +6682,14 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, defer_to_dealloc_blk = true; + parmse.expr = gfc_evaluate_data_ref_now (parmse.expr, + &parmse.pre); + + if (parmse.class_container != NULL_TREE) + parmse.class_container + = gfc_evaluate_data_ref_now (parmse.class_container, + &parmse.pre); + gfc_init_block (&block); ptr = parmse.expr; if (e->ts.type == BT_CLASS) diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 7ad85ae..f1a3aac 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -174,6 +174,34 @@ gfc_evaluate_now (tree expr, stmtblock_t * pblock) return gfc_evaluate_now_loc (input_location, expr, pblock); } + +/* Returns a fresh pointer variable pointing to the same data as EXPR, adding + in BLOCK the initialization code that makes it point to EXPR. */ + +tree +gfc_evaluate_data_ref_now (tree expr, stmtblock_t *block) +{ + tree t = expr; + + STRIP_NOPS (t); + + /* If EXPR can be used as lhs of an assignment, we have to take the address + of EXPR. Otherwise, reassigning the pointer would retarget it to some + other data without EXPR being retargetted as well. */ + bool lvalue_p = DECL_P (t) || REFERENCE_CLASS_P (t) || INDIRECT_REF_P (t); + + tree value; + if (lvalue_p) + { + value = gfc_build_addr_expr (NULL_TREE, expr); + value = gfc_evaluate_now (value, block); + return build_fold_indirect_ref_loc (input_location, value); + } + else + return gfc_evaluate_now (expr, block); +} + + /* Like gfc_evaluate_now, but add the created variable to the function scope. */ diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 0c8d004..82cdd69 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -57,6 +57,10 @@ typedef struct gfc_se here. */ tree class_vptr; + /* When expr is a reference to a direct subobject of a class, store + the reference to the class object here. */ + tree class_container; + /* Whether expr is a reference to an unlimited polymorphic object. */ unsigned unlimited_polymorphic:1; @@ -263,6 +267,7 @@ typedef struct gfc_ss_info gfc_ss_type type; gfc_expr *expr; tree string_length; + tree class_container; union { @@ -525,6 +530,7 @@ void gfc_conv_label_variable (gfc_se * se, gfc_expr * expr); /* If the value is not constant, Create a temporary and copy the value. */ tree gfc_evaluate_now_loc (location_t, tree, stmtblock_t *); tree gfc_evaluate_now (tree, stmtblock_t *); +tree gfc_evaluate_data_ref_now (tree, stmtblock_t *); tree gfc_evaluate_now_function_scope (tree, stmtblock_t *); /* Find the appropriate variant of a math intrinsic. */ diff --git a/gcc/testsuite/gfortran.dg/intent_out_20.f90 b/gcc/testsuite/gfortran.dg/intent_out_20.f90 new file mode 100644 index 0000000..8e5d8c6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intent_out_20.f90 @@ -0,0 +1,33 @@ +! { dg-do run } +! +! PR fortran/92178 +! Check that if a data reference passed is as actual argument whose dummy +! has INTENT(OUT) attribute, any other argument depending on the +! same data reference is evaluated before the data reference deallocation. + +program p + implicit none + type t + integer :: i + end type t + type u + class(t), allocatable :: ta + end type u + type(u), allocatable :: c(:) + allocate(c, source = [u(t(1)), u(t(4))]) + call bar ( & + allocated (c(c(1)%ta%i)%ta), & + c(c(1)%ta%i)%ta, & + allocated (c(c(1)%ta%i)%ta) & + ) + if (allocated (c(1)%ta)) stop 11 + if (.not. allocated (c(2)%ta)) stop 12 +contains + subroutine bar (alloc, x, alloc2) + logical :: alloc, alloc2 + class(t), allocatable, intent(out) :: x(..) + if (allocated (x)) stop 1 + if (.not. alloc) stop 2 + if (.not. alloc2) stop 3 + end subroutine bar +end -- cgit v1.1 From 9206641d0899e4bae3ad6765129661ff3bcc423a Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Fri, 14 Jul 2023 14:15:51 +0200 Subject: fortran: Reorder array argument evaluation parts [PR92178] In the case of an array actual arg passed to a polymorphic array dummy with INTENT(OUT) attribute, reorder the argument evaluation code to the following: - first evaluate arguments' values, and data references, - deallocate data references associated with an allocatable, intent(out) dummy, - create a class container using the freed data references. The ordering used to be incorrect between the first two items, when one argument was deallocated before a later argument evaluated its expression depending on the former argument. r14-2395-gb1079fc88f082d3c5b583c8822c08c5647810259 fixed it by treating arguments associated with an allocatable, intent(out) dummy in a separate, later block. This, however, wasn't working either if the data reference of such an argument was depending on its own content, as the class container initialization was trying to use deallocated content. This change generates class container initialization code in a separate block, so that it is moved after the deallocation block without moving the rest of the argument evaluation code. This alone is not sufficient to fix the problem, because the class container generation code repeatedly uses the full expression of the argument at a place where deallocation might have happened already. This is non-optimal, but may also be invalid, because the data reference may depend on its own content. In that case the expression can't be evaluated after the data has been deallocated. As in the scalar case previously treated, this is fixed by saving the data reference to a pointer before any deallocation happens, and then only refering to the pointer. gfc_reset_vptr is updated to take into account the already evaluated class container if it's available. Contrary to the scalar case, one hunk is needed to wrap the parameter evaluation in a conditional, to avoid regressing in optional_class_2.f90. This used to be handled by the class wrapper construction which wrapped the whole code in a conditional. With this change the class wrapper construction can't see the parameter evaluation code, so the latter is updated with an additional handling for optional arguments. PR fortran/92178 gcc/fortran/ChangeLog: * trans.h (gfc_reset_vptr): Add class_container argument. * trans-expr.cc (gfc_reset_vptr): Ditto. If a valid vptr can be obtained through class_container argument, bypass evaluation of e. (gfc_conv_procedure_call): Wrap the argument evaluation code in a conditional if the associated dummy is optional. Evaluate the data reference to a pointer now, and replace later references with usage of the pointer. gcc/testsuite/ChangeLog: * gfortran.dg/intent_out_21.f90: New test. --- gcc/fortran/trans-expr.cc | 86 ++++++++++++++++++++++------- gcc/fortran/trans.h | 2 +- gcc/testsuite/gfortran.dg/intent_out_21.f90 | 33 +++++++++++ 3 files changed, 101 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/intent_out_21.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 5169fbc..dbb04f8 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -529,24 +529,32 @@ gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold, } -/* Reset the vptr to the declared type, e.g. after deallocation. */ +/* Reset the vptr to the declared type, e.g. after deallocation. + Use the variable in CLASS_CONTAINER if available. Otherwise, recreate + one with E. The generated assignment code is added at the end of BLOCK. */ void -gfc_reset_vptr (stmtblock_t *block, gfc_expr *e) +gfc_reset_vptr (stmtblock_t *block, gfc_expr *e, tree class_container) { - gfc_symbol *vtab; - tree vptr; - tree vtable; - gfc_se se; + tree vptr = NULL_TREE; - /* Evaluate the expression and obtain the vptr from it. */ - gfc_init_se (&se, NULL); - if (e->rank) - gfc_conv_expr_descriptor (&se, e); - else - gfc_conv_expr (&se, e); - gfc_add_block_to_block (block, &se.pre); - vptr = gfc_get_vptr_from_expr (se.expr); + if (class_container != NULL_TREE) + vptr = gfc_get_vptr_from_expr (class_container); + + if (vptr == NULL_TREE) + { + gfc_se se; + + /* Evaluate the expression and obtain the vptr from it. */ + gfc_init_se (&se, NULL); + if (e->rank) + gfc_conv_expr_descriptor (&se, e); + else + gfc_conv_expr (&se, e); + gfc_add_block_to_block (block, &se.pre); + + vptr = gfc_get_vptr_from_expr (se.expr); + } /* If a vptr is not found, we can do nothing more. */ if (vptr == NULL_TREE) @@ -556,6 +564,9 @@ gfc_reset_vptr (stmtblock_t *block, gfc_expr *e) gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0)); else { + gfc_symbol *vtab; + tree vtable; + /* Return the vptr to the address of the declared type. */ vtab = gfc_find_derived_vtab (e->ts.u.derived); vtable = vtab->backend_decl; @@ -6847,6 +6858,24 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, gfc_conv_expr_descriptor (&parmse, e); bool defer_to_dealloc_blk = false; + if (fsym->attr.optional + && e->expr_type == EXPR_VARIABLE + && e->symtree->n.sym->attr.optional) + { + stmtblock_t block; + + gfc_init_block (&block); + gfc_add_block_to_block (&block, &parmse.pre); + + tree t = fold_build3_loc (input_location, COND_EXPR, + void_type_node, + gfc_conv_expr_present (e->symtree->n.sym), + gfc_finish_block (&block), + build_empty_stmt (input_location)); + + gfc_add_expr_to_block (&parmse.pre, t); + } + /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is allocated on entry, it must be deallocated. */ if (fsym->attr.intent == INTENT_OUT @@ -6855,6 +6884,18 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, stmtblock_t block; tree ptr; + /* In case the data reference to deallocate is dependent on + its own content, save the resulting pointer to a variable + and only use that variable from now on, before the + expression becomes invalid. */ + parmse.expr = gfc_evaluate_data_ref_now (parmse.expr, + &parmse.pre); + + if (parmse.class_container != NULL_TREE) + parmse.class_container + = gfc_evaluate_data_ref_now (parmse.class_container, + &parmse.pre); + gfc_init_block (&block); ptr = parmse.expr; ptr = gfc_class_data_get (ptr); @@ -6868,7 +6909,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, void_type_node, ptr, null_pointer_node); gfc_add_expr_to_block (&block, tmp); - gfc_reset_vptr (&block, e); + gfc_reset_vptr (&block, e, parmse.class_container); if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE @@ -6890,9 +6931,13 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, defer_to_dealloc_blk = true; } + gfc_se class_se = parmse; + gfc_init_block (&class_se.pre); + gfc_init_block (&class_se.post); + /* The conversion does not repackage the reference to a class array - _data descriptor. */ - gfc_conv_class_to_class (&parmse, e, fsym->ts, false, + gfc_conv_class_to_class (&class_se, e, fsym->ts, false, fsym->attr.intent != INTENT_IN && (CLASS_DATA (fsym)->attr.class_pointer || CLASS_DATA (fsym)->attr.allocatable), @@ -6902,9 +6947,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, CLASS_DATA (fsym)->attr.class_pointer || CLASS_DATA (fsym)->attr.allocatable); - /* Defer repackaging after deallocation. */ - if (defer_to_dealloc_blk) - gfc_add_block_to_block (&dealloc_blk, &parmse.pre); + parmse.expr = class_se.expr; + stmtblock_t *class_pre_block = defer_to_dealloc_blk + ? &dealloc_blk + : &parmse.pre; + gfc_add_block_to_block (class_pre_block, &class_se.pre); + gfc_add_block_to_block (&parmse.post, &class_se.post); } else { diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 82cdd69..7b41e89 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -451,7 +451,7 @@ tree gfc_vptr_def_init_get (tree); tree gfc_vptr_copy_get (tree); tree gfc_vptr_final_get (tree); tree gfc_vptr_deallocate_get (tree); -void gfc_reset_vptr (stmtblock_t *, gfc_expr *); +void gfc_reset_vptr (stmtblock_t *, gfc_expr *, tree = NULL_TREE); void gfc_reset_len (stmtblock_t *, gfc_expr *); tree gfc_get_class_from_gfc_expr (gfc_expr *); tree gfc_get_class_from_expr (tree); diff --git a/gcc/testsuite/gfortran.dg/intent_out_21.f90 b/gcc/testsuite/gfortran.dg/intent_out_21.f90 new file mode 100644 index 0000000..5f61a54 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intent_out_21.f90 @@ -0,0 +1,33 @@ +! { dg-do run } +! +! PR fortran/92178 +! Check that in the case of a data reference depending on its own content +! passed as actual argument to an INTENT(OUT) dummy, no reference to the +! content happens after the deallocation. + +program p + implicit none + type t + integer :: i + end type t + type u + class(t), allocatable :: ta(:) + end type u + type(u), allocatable :: c(:) + c = [u([t(1), t(3)]), u([t(4), t(9)])] + call bar ( & + allocated (c(c(1)%ta(1)%i)%ta), & + c(c(1)%ta(1)%i)%ta, & + allocated (c(c(1)%ta(1)%i)%ta) & + ) + if (allocated(c(1)%ta)) stop 11 + if (.not. allocated(c(2)%ta)) stop 12 +contains + subroutine bar (alloc, x, alloc2) + logical :: alloc, alloc2 + class(t), allocatable, intent(out) :: x(:) + if (allocated (x)) stop 1 + if (.not. alloc) stop 2 + if (.not. alloc2) stop 3 + end subroutine bar +end -- cgit v1.1 From 53d12ecd624ec901d8449cfa1917f6f90e910927 Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Fri, 14 Jul 2023 13:54:06 +0200 Subject: bpf: enable instruction scheduling This patch adds a dummy FSM to bpf.md in order to get INSN_SCHEDULING defined. If the later is not defined, the `combine' pass generates paradoxical subregs of mems, which seems to then be mishandled by LRA, resulting in invalid code. Tested in bpf-unknown-none. gcc/ChangeLog: 2023-07-14 Jose E. Marchesi PR target/110657 * config/bpf/bpf.md: Enable instruction scheduling. --- gcc/config/bpf/bpf.md | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gcc') diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index f6be0a2..329f62f 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -20,6 +20,17 @@ (include "predicates.md") (include "constraints.md") +;;;; Instruction Scheduler FSM + +;; This is just to get INSN_SCHEDULING defined, so that combine does +;; not make paradoxical subregs of memory. These subregs seems to +;; confuse LRA that ends generating wrong instructions. + +(define_automaton "frob") +(define_cpu_unit "frob_unit" "frob") +(define_insn_reservation "frobnicator" 814 + (const_int 0) "frob_unit") + ;;;; Unspecs (define_c_enum "unspec" [ -- cgit v1.1 From 0d2673e995f0dd69f406a34d2e87d2a25cf3c285 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Fri, 14 Jul 2023 06:17:09 +0800 Subject: RISC-V: Enable COND_LEN_FMA auto-vectorization Add comments as Robin's suggestion in scatter_store_run-7.c Enable COND_LEN_FMA auto-vectorization for floating-point FMA auto-vectorization **NO** ffast-math. Since the middle-end support has been approved and I will merge it after I finished bootstrap && regression on X86. https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624395.html Now, it's time to send this patch. Consider this following case: __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dst, \ TYPE *__restrict a, \ TYPE *__restrict b, int n) \ { \ for (int i = 0; i < n; i++) \ dst[i] += a[i] * b[i]; \ } TEST_ALL () Before this patch: ternop_double: ble a3,zero,.L5 mv a6,a0 .L3: vsetvli a5,a3,e64,m1,tu,ma slli a4,a5,3 vle64.v v1,0(a0) vle64.v v2,0(a1) vle64.v v3,0(a2) sub a3,a3,a5 vfmul.vv v2,v2,v3 vfadd.vv v1,v1,v2 vse64.v v1,0(a6) add a0,a0,a4 add a1,a1,a4 add a2,a2,a4 add a6,a6,a4 bne a3,zero,.L3 .L5: ret After this patch: ternop_double: ble a3,zero,.L5 mv a6,a0 .L3: vsetvli a5,a3,e64,m1,tu,ma slli a4,a5,3 vle64.v v1,0(a0) vle64.v v2,0(a1) vle64.v v3,0(a2) sub a3,a3,a5 vfmacc.vv v1,v3,v2 vse64.v v1,0(a6) add a0,a0,a4 add a1,a1,a4 add a2,a2,a4 add a6,a6,a4 bne a3,zero,.L3 .L5: ret Notice: This patch only supports COND_LEN_FMA, **NO** COND_LEN_FNMA, ... etc since I didn't support them in the middle-end yet. Will support them in the following patches soon. gcc/ChangeLog: * config/riscv/autovec.md (cond_len_fma): New pattern. * config/riscv/riscv-protos.h (enum insn_type): New enum. (expand_cond_len_ternop): New function. * config/riscv/riscv-v.cc (emit_nonvlmax_fp_ternary_tu_insn): Ditto. (expand_cond_len_ternop): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c: Adapt testcase for link fail. * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-1.c: New test. * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c: New test. * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-3.c: New test. * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-1.c: New test. * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-2.c: New test. * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-3.c: New test. --- gcc/config/riscv/autovec.md | 23 ++++++++++ gcc/config/riscv/riscv-protos.h | 2 + gcc/config/riscv/riscv-v.cc | 49 ++++++++++++++++++++++ .../autovec/gather-scatter/scatter_store_run-7.c | 6 ++- .../riscv/rvv/autovec/ternop/ternop_nofm-1.c | 7 ++++ .../riscv/rvv/autovec/ternop/ternop_nofm-2.c | 11 +++++ .../riscv/rvv/autovec/ternop/ternop_nofm-3.c | 9 ++++ .../riscv/rvv/autovec/ternop/ternop_nofm_run-1.c | 4 ++ .../riscv/rvv/autovec/ternop/ternop_nofm_run-2.c | 4 ++ .../riscv/rvv/autovec/ternop/ternop_nofm_run-3.c | 4 ++ 10 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-3.c (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 0476b1d..64a41bd 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1531,3 +1531,26 @@ riscv_vector::expand_cond_len_binop (, operands); DONE; }) + +;; ------------------------------------------------------------------------- +;; ---- [FP] Conditional ternary operations +;; ------------------------------------------------------------------------- +;; Includes: +;; - vfmacc/... +;; ------------------------------------------------------------------------- + +(define_expand "cond_len_fma" + [(match_operand:VF 0 "register_operand") + (match_operand: 1 "vector_mask_operand") + (match_operand:VF 2 "register_operand") + (match_operand:VF 3 "register_operand") + (match_operand:VF 4 "register_operand") + (match_operand:VF 5 "register_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred_mul (PLUS, mode); + riscv_vector::expand_cond_len_ternop (icode, operands); + DONE; +}) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 1a622c5..f91c2d5 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -191,6 +191,7 @@ enum insn_type RVV_UNOP_MU = RVV_UNOP + 2, /* Likewise. */ RVV_UNOP_M = RVV_UNOP + 2, /* Likewise. */ RVV_TERNOP = 5, + RVV_TERNOP_TU = RVV_TERNOP + 1, RVV_WIDEN_TERNOP = 4, RVV_SCALAR_MOV_OP = 4, /* +1 for VUNDEF according to vector.md. */ RVV_SLIDE_OP = 4, /* Dest, VUNDEF, source and offset. */ @@ -306,6 +307,7 @@ void expand_vec_perm (rtx, rtx, rtx, rtx); void expand_select_vl (rtx *); void expand_load_store (rtx *, bool); void expand_gather_scatter (rtx *, bool); +void expand_cond_len_ternop (unsigned, rtx *); /* Rounding mode bitfield for fixed point VXRM. */ enum fixed_point_rounding_mode diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 90da638..c3fd4a1 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -748,6 +748,28 @@ emit_vlmax_fp_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx vl) e.emit_insn ((enum insn_code) icode, ops); } +/* This function emits a {NONVLMAX, TAIL_UNDISTURBED, MASK_ANY} vsetvli followed + * by the ternary operation which always has a real merge operand. */ +static void +emit_nonvlmax_fp_ternary_tu_insn (unsigned icode, int op_num, rtx *ops, rtx vl) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (dest_mode).require (); + insn_expander e (/*OP_NUM*/ op_num, + /*HAS_DEST_P*/ true, + /*FULLY_UNMASKED_P*/ false, + /*USE_REAL_MERGE_P*/ true, + /*HAS_AVL_P*/ true, + /*VLMAX_P*/ false, + /*DEST_MODE*/ dest_mode, + /*MASK_MODE*/ mask_mode); + e.set_policy (TAIL_UNDISTURBED); + e.set_policy (MASK_ANY); + e.set_rounding_mode (FRM_DYN); + e.set_vl (vl); + e.emit_insn ((enum insn_code) icode, ops); +} + /* This function emits a {NONVLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the * actual operation. */ void @@ -3267,4 +3289,31 @@ expand_gather_scatter (rtx *ops, bool is_load) } } +/* Expand COND_LEN_*. */ +void +expand_cond_len_ternop (unsigned icode, rtx *ops) +{ + rtx dest = ops[0]; + rtx mask = ops[1]; + rtx len = ops[6]; + machine_mode mode = GET_MODE (dest); + machine_mode mask_mode = GET_MODE (mask); + + poly_uint64 value; + bool is_dummy_mask = rtx_equal_p (mask, CONSTM1_RTX (mask_mode)); + + if (is_dummy_mask) + { + /* Use TU, MASK ANY policy. */ + if (FLOAT_MODE_P (mode)) + emit_nonvlmax_fp_ternary_tu_insn (icode, RVV_TERNOP_TU, ops, len); + else + /* FIXME: Enable this case when we support it in the middle-end. */ + gcc_unreachable (); + } + else + /* FIXME: Enable this case when we support it in the middle-end. */ + gcc_unreachable (); +} + } // namespace riscv_vector diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c index a244011..6f7316e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c @@ -1,5 +1,9 @@ /* { dg-do run { target { riscv_vector } } } */ - +/* For some reason we exceed + the default code model's +-2 GiB limits. We should investigate why and + add a proper description here. For now just make sure the test case + compiles properly. */ +/* { dg-additional-options "-mcmodel=medany" } */ #include "scatter_store-7.c" #include diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-1.c new file mode 100644 index 0000000..d608504 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "ternop-1.c" + +/* { dg-final { scan-assembler-not {\tvmv} } } */ +/* { dg-final { scan-tree-dump-times "COND_LEN_FMA" 3 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c new file mode 100644 index 0000000..cb60540 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ + +#include "ternop-2.c" + +/* { dg-final { scan-assembler-times {\tvmacc\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvfmacc\.vv} 9 } } */ +/* TODO: we don't have undefine IR for COND_LEN_* operations, + which will produce redundant move instructions here. + Will add assembler-not check of 'vmv' instructions in the future. */ +/* { dg-final { scan-tree-dump-times "COND_LEN_FMA" 9 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-3.c new file mode 100644 index 0000000..63cd4ae --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-3.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns" } */ + +#include "ternop-3.c" + +/* { dg-final { scan-assembler-times {\tvmacc\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {\tvfmacc\.vv} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmv} 11 } } */ +/* { dg-final { scan-tree-dump-times "COND_LEN_FMA" 6 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-1.c new file mode 100644 index 0000000..446d216 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-1.c @@ -0,0 +1,4 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */ + +#include "ternop_run-1.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-2.c new file mode 100644 index 0000000..55ee829 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-2.c @@ -0,0 +1,4 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */ + +#include "ternop_run-2.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-3.c new file mode 100644 index 0000000..31aab4c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-3.c @@ -0,0 +1,4 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */ + +#include "ternop_run-3.c" -- cgit v1.1 From aa6741ef2e0c312af51825f6411380fe160a8222 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 14 Jul 2023 17:14:15 +0200 Subject: Turn TODO_rebuild_frequencies to a pass Currently we rebiuild profile_counts from profile_probability after inlining, because there is a chance that producing large loop nests may get unrealistically large profile_count values. This is much less of concern when we switched to new profile_count representation while back. This propagation can also compensate for profile inconsistencies caused by optimization passes. Since inliner is followed by basic cleanup passes that does not use profile, we get more realistic profile by delaying the recomputation after basic optimizations exposed by inlininig are finished. This does not fit into TODO machinery, so I turn rebuilding into stand alone pass and schedule it before first consumer of profile in the optimization queue. I also added logic that avoids repropagating when CFG is good and not too close to overflow. Propagating visits very basic block loop_depth times, so it is not linear and avoiding it may help a bit. On tramp3d we get 14 functions repropagated and 916 are OK. The repropagated functions are RB tree ones where we produce crazy loop nests by recurisve inlining. This is something to fix independently. gcc/ChangeLog: * passes.cc (execute_function_todo): Remove TODO_rebuild_frequencies * passes.def: Add rebuild_frequencies pass. * predict.cc (estimate_bb_frequencies): Drop force parameter. (tree_estimate_probability): Update call of estimate_bb_frequencies. (rebuild_frequencies): Turn into a pass; verify CFG profile consistency first and do not rebuild if not necessary. (class pass_rebuild_frequencies): New. (make_pass_rebuild_frequencies): New. * profile-count.h: Add profile_count::very_large_p. * tree-inline.cc (optimize_inline_calls): Do not return TODO_rebuild_frequencies * tree-pass.h (TODO_rebuild_frequencies): Remove. (make_pass_rebuild_frequencies): Declare. --- gcc/passes.cc | 3 - gcc/passes.def | 8 ++ gcc/predict.cc | 337 +++++++++++++++++++++++++++++++++++----------------- gcc/profile-count.h | 10 ++ gcc/tree-inline.cc | 4 +- gcc/tree-pass.h | 2 +- 6 files changed, 248 insertions(+), 116 deletions(-) (limited to 'gcc') diff --git a/gcc/passes.cc b/gcc/passes.cc index 2f0e378..d7b0ad2 100644 --- a/gcc/passes.cc +++ b/gcc/passes.cc @@ -2075,9 +2075,6 @@ execute_function_todo (function *fn, void *data) if (flags & TODO_remove_unused_locals) remove_unused_locals (); - if (flags & TODO_rebuild_frequencies) - rebuild_frequencies (); - if (flags & TODO_rebuild_cgraph_edges) cgraph_edge::rebuild_edges (); diff --git a/gcc/passes.def b/gcc/passes.def index faa5208..f2893ae 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -206,6 +206,10 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_post_ipa_warn); /* Must run before loop unrolling. */ NEXT_PASS (pass_warn_access, /*early=*/true); + /* Profile count may overflow as a result of inlinining very large + loop nests. This pass should run before any late pass that makes + use of profile. */ + NEXT_PASS (pass_rebuild_frequencies); NEXT_PASS (pass_complete_unrolli); NEXT_PASS (pass_backprop); NEXT_PASS (pass_phiprop); @@ -395,6 +399,10 @@ along with GCC; see the file COPYING3. If not see to forward object-size and builtin folding results properly. */ NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_dce); + /* Profile count may overflow as a result of inlinining very large + loop nests. This pass should run before any late pass that makes + use of profile. */ + NEXT_PASS (pass_rebuild_frequencies); NEXT_PASS (pass_sancov); NEXT_PASS (pass_asan); NEXT_PASS (pass_tsan); diff --git a/gcc/predict.cc b/gcc/predict.cc index 1aa4c25..26f9f3f 100644 --- a/gcc/predict.cc +++ b/gcc/predict.cc @@ -89,7 +89,7 @@ static void predict_paths_leading_to_edge (edge, enum br_predictor, static bool can_predict_insn_p (const rtx_insn *); static HOST_WIDE_INT get_predictor_value (br_predictor, HOST_WIDE_INT); static void determine_unlikely_bbs (); -static void estimate_bb_frequencies (bool force); +static void estimate_bb_frequencies (); /* Information we hold about each branch predictor. Filled using information from predict.def. */ @@ -3169,8 +3169,9 @@ tree_estimate_probability (bool dry_run) delete bb_predictions; bb_predictions = NULL; - if (!dry_run) - estimate_bb_frequencies (false); + if (!dry_run + && profile_status_for_fn (cfun) != PROFILE_READ) + estimate_bb_frequencies (); free_dominance_info (CDI_POST_DOMINATORS); remove_fake_exit_edges (); } @@ -3923,103 +3924,97 @@ determine_unlikely_bbs () } /* Estimate and propagate basic block frequencies using the given branch - probabilities. If FORCE is true, the frequencies are used to estimate - the counts even when there are already non-zero profile counts. */ + probabilities. */ static void -estimate_bb_frequencies (bool force) +estimate_bb_frequencies () { basic_block bb; sreal freq_max; determine_unlikely_bbs (); - if (force || profile_status_for_fn (cfun) != PROFILE_READ - || !update_max_bb_count ()) - { + mark_dfs_back_edges (); - mark_dfs_back_edges (); + single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->probability = + profile_probability::always (); - single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->probability = - profile_probability::always (); + /* Set up block info for each basic block. */ + alloc_aux_for_blocks (sizeof (block_info)); + alloc_aux_for_edges (sizeof (edge_prob_info)); + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb) + { + edge e; + edge_iterator ei; - /* Set up block info for each basic block. */ - alloc_aux_for_blocks (sizeof (block_info)); - alloc_aux_for_edges (sizeof (edge_prob_info)); - FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb) + FOR_EACH_EDGE (e, ei, bb->succs) { - edge e; - edge_iterator ei; - - FOR_EACH_EDGE (e, ei, bb->succs) - { - /* FIXME: Graphite is producing edges with no profile. Once - this is fixed, drop this. */ - if (e->probability.initialized_p ()) - EDGE_INFO (e)->back_edge_prob - = e->probability.to_sreal (); - else - /* back_edge_prob = 0.5 */ - EDGE_INFO (e)->back_edge_prob = sreal (1, -1); - } + /* FIXME: Graphite is producing edges with no profile. Once + this is fixed, drop this. */ + if (e->probability.initialized_p ()) + EDGE_INFO (e)->back_edge_prob + = e->probability.to_sreal (); + else + /* back_edge_prob = 0.5 */ + EDGE_INFO (e)->back_edge_prob = sreal (1, -1); } + } - /* First compute frequencies locally for each loop from innermost - to outermost to examine frequencies for back edges. */ - estimate_loops (); - - freq_max = 0; - FOR_EACH_BB_FN (bb, cfun) - if (freq_max < BLOCK_INFO (bb)->frequency) - freq_max = BLOCK_INFO (bb)->frequency; - - /* Scaling frequencies up to maximal profile count may result in - frequent overflows especially when inlining loops. - Small scalling results in unnecesary precision loss. Stay in - the half of the (exponential) range. */ - freq_max = (sreal (1) << (profile_count::n_bits / 2)) / freq_max; - if (freq_max < 16) - freq_max = 16; - profile_count ipa_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa (); - cfun->cfg->count_max = profile_count::uninitialized (); - FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb) + /* First compute frequencies locally for each loop from innermost + to outermost to examine frequencies for back edges. */ + estimate_loops (); + + freq_max = 0; + FOR_EACH_BB_FN (bb, cfun) + if (freq_max < BLOCK_INFO (bb)->frequency) + freq_max = BLOCK_INFO (bb)->frequency; + + /* Scaling frequencies up to maximal profile count may result in + frequent overflows especially when inlining loops. + Small scalling results in unnecesary precision loss. Stay in + the half of the (exponential) range. */ + freq_max = (sreal (1) << (profile_count::n_bits / 2)) / freq_max; + if (freq_max < 16) + freq_max = 16; + profile_count ipa_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa (); + cfun->cfg->count_max = profile_count::uninitialized (); + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb) + { + sreal tmp = BLOCK_INFO (bb)->frequency; + if (tmp >= 1) { - sreal tmp = BLOCK_INFO (bb)->frequency; - if (tmp >= 1) - { - gimple_stmt_iterator gsi; - tree decl; - - /* Self recursive calls can not have frequency greater than 1 - or program will never terminate. This will result in an - inconsistent bb profile but it is better than greatly confusing - IPA cost metrics. */ - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - if (is_gimple_call (gsi_stmt (gsi)) - && (decl = gimple_call_fndecl (gsi_stmt (gsi))) != NULL - && recursive_call_p (current_function_decl, decl)) - { - if (dump_file) - fprintf (dump_file, "Dropping frequency of recursive call" - " in bb %i from %f\n", bb->index, - tmp.to_double ()); - tmp = (sreal)9 / (sreal)10; - break; - } - } - tmp = tmp * freq_max + sreal (1, -1); - profile_count count = profile_count::from_gcov_type (tmp.to_int ()); - - /* If we have profile feedback in which this function was never - executed, then preserve this info. */ - if (!(bb->count == profile_count::zero ())) - bb->count = count.guessed_local ().combine_with_ipa_count (ipa_count); - cfun->cfg->count_max = cfun->cfg->count_max.max (bb->count); + gimple_stmt_iterator gsi; + tree decl; + + /* Self recursive calls can not have frequency greater than 1 + or program will never terminate. This will result in an + inconsistent bb profile but it is better than greatly confusing + IPA cost metrics. */ + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + if (is_gimple_call (gsi_stmt (gsi)) + && (decl = gimple_call_fndecl (gsi_stmt (gsi))) != NULL + && recursive_call_p (current_function_decl, decl)) + { + if (dump_file) + fprintf (dump_file, "Dropping frequency of recursive call" + " in bb %i from %f\n", bb->index, + tmp.to_double ()); + tmp = (sreal)9 / (sreal)10; + break; + } } + tmp = tmp * freq_max + sreal (1, -1); + profile_count count = profile_count::from_gcov_type (tmp.to_int ()); - free_aux_for_blocks (); - free_aux_for_edges (); + /* If we have profile feedback in which this function was never + executed, then preserve this info. */ + if (!(bb->count == profile_count::zero ())) + bb->count = count.guessed_local ().combine_with_ipa_count (ipa_count); + cfun->cfg->count_max = cfun->cfg->count_max.max (bb->count); } + + free_aux_for_blocks (); + free_aux_for_edges (); compute_function_frequency (); } @@ -4307,38 +4302,162 @@ make_pass_strip_predict_hints (gcc::context *ctxt) void rebuild_frequencies (void) { - timevar_push (TV_REBUILD_FREQUENCIES); - - /* When the max bb count in the function is small, there is a higher - chance that there were truncation errors in the integer scaling - of counts by inlining and other optimizations. This could lead - to incorrect classification of code as being cold when it isn't. - In that case, force the estimation of bb counts/frequencies from the - branch probabilities, rather than computing frequencies from counts, - which may also lead to frequencies incorrectly reduced to 0. There - is less precision in the probabilities, so we only do this for small - max counts. */ - cfun->cfg->count_max = profile_count::uninitialized (); + /* If we have no profile, do nothing. Note that after inlining + profile_status_for_fn may not represent the actual presence/absence of + profile. */ + if (profile_status_for_fn (cfun) == PROFILE_ABSENT + && !ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.initialized_p ()) + return; + + + /* See if everything is OK and update count_max. */ basic_block bb; + bool inconsistency_found = false; + bool uninitialized_probablity_found = false; + bool uninitialized_count_found = false; + + cfun->cfg->count_max = profile_count::uninitialized (); FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb) - cfun->cfg->count_max = cfun->cfg->count_max.max (bb->count); + { + cfun->cfg->count_max = cfun->cfg->count_max.max (bb->count); + /* Uninitialized count may be result of inlining or an omision in an + optimization pass. */ + if (!bb->count.initialized_p ()) + { + uninitialized_count_found = true; + if (dump_file) + fprintf (dump_file, "BB %i has uninitialized count\n", + bb->index); + } + if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) + && (!uninitialized_probablity_found || !inconsistency_found)) + { + profile_count sum = profile_count::zero (); + edge e; + edge_iterator ei; - if (profile_status_for_fn (cfun) == PROFILE_GUESSED) + FOR_EACH_EDGE (e, ei, bb->preds) + { + sum += e->count (); + /* Uninitialized probability may be result of inlining or an + omision in an optimization pass. */ + if (!e->probability.initialized_p ()) + { + if (dump_file) + fprintf (dump_file, + "Edge %i->%i has uninitialized probability\n", + e->src->index, e->dest->index); + } + } + if (sum.differs_from_p (bb->count)) + { + if (dump_file) + fprintf (dump_file, + "BB %i has invalid sum of incomming counts\n", + bb->index); + inconsistency_found = true; + } + } + } + + /* If everything is OK, do not re-propagate frequencies. */ + if (!inconsistency_found + && (!uninitialized_count_found || uninitialized_probablity_found) + && !cfun->cfg->count_max.very_large_p ()) { - loop_optimizer_init (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS); - connect_infinite_loops_to_exit (); - estimate_bb_frequencies (true); - remove_fake_exit_edges (); - loop_optimizer_finalize (); + if (dump_file) + fprintf (dump_file, "Profile is consistent\n"); + return; } - else if (profile_status_for_fn (cfun) == PROFILE_READ) - update_max_bb_count (); - else if (profile_status_for_fn (cfun) == PROFILE_ABSENT - && !flag_guess_branch_prob) - ; - else - gcc_unreachable (); - timevar_pop (TV_REBUILD_FREQUENCIES); + /* Do not re-propagate if we have profile feedback. Even if the profile is + inconsistent from previous transofrmations, it is probably more realistic + for hot part of the program than result of repropagating. + + Consider example where we previously has + + if (test) + then [large probability for true] + + and we later proved that test is always 0. In this case, if profile was + read correctly, we must have duplicated the conditional (for example by + inlining) in to a context where test is false. From profile feedback + we know that most executions if the conditionals were true, so the + important copy is not the one we look on. + + Propagating from probabilities would make profile look consistent, but + because probablities after code duplication may not be representative + for a given run, we would only propagate the error further. */ + if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa ().nonzero_p () + && !uninitialized_count_found) + { + if (dump_file) + fprintf (dump_file, + "Profile is inconsistent but read from profile feedback;" + " not rebuilding\n"); + return; + } + + loop_optimizer_init (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS); + connect_infinite_loops_to_exit (); + estimate_bb_frequencies (); + remove_fake_exit_edges (); + loop_optimizer_finalize (); + if (dump_file) + fprintf (dump_file, "Rebuilt basic block counts\n"); + + return; +} + +namespace { + +const pass_data pass_data_rebuild_frequencies = +{ + GIMPLE_PASS, /* type */ + "rebuild_frequencies", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_REBUILD_FREQUENCIES, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_rebuild_frequencies : public gimple_opt_pass +{ +public: + pass_rebuild_frequencies (gcc::context *ctxt) + : gimple_opt_pass (pass_data_rebuild_frequencies, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () final override + { + return new pass_rebuild_frequencies (m_ctxt); + } + void set_pass_param (unsigned int n, bool param) final override + { + gcc_assert (n == 0); + early_p = param; + } + + unsigned int execute (function *) final override + { + rebuild_frequencies (); + return 0; + } + +private: + bool early_p; + +}; // class pass_rebuild_frequencies + +} // anon namespace + +gimple_opt_pass * +make_pass_rebuild_frequencies (gcc::context *ctxt) +{ + return new pass_rebuild_frequencies (ctxt); } /* Perform a dry run of the branch prediction pass and report comparsion of diff --git a/gcc/profile-count.h b/gcc/profile-count.h index 99416d9..bf11367 100644 --- a/gcc/profile-count.h +++ b/gcc/profile-count.h @@ -1276,6 +1276,16 @@ public: return ret; } + /* Return true if profile count is very large, so we risk overflows + with loop transformations. */ + bool + very_large_p () + { + if (!initialized_p ()) + return false; + return m_val > max_count / 65536; + } + int to_frequency (struct function *fun) const; int to_cgraph_frequency (profile_count entry_bb_count) const; sreal to_sreal_scale (profile_count in, bool *known = NULL) const; diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index 99efddc..954b39a 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -5526,9 +5526,7 @@ optimize_inline_calls (tree fn) return (TODO_update_ssa | TODO_cleanup_cfg | (gimple_in_ssa_p (cfun) ? TODO_remove_unused_locals : 0) - | (gimple_in_ssa_p (cfun) ? TODO_update_address_taken : 0) - | (profile_status_for_fn (cfun) != PROFILE_ABSENT - ? TODO_rebuild_frequencies : 0)); + | (gimple_in_ssa_p (cfun) ? TODO_update_address_taken : 0)); } /* Passed to walk_tree. Copies the node pointed to, if appropriate. */ diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 6cdaed7..57865cd 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -239,7 +239,6 @@ protected: #define TODO_verify_il (1 << 6) #define TODO_dump_symtab (1 << 7) #define TODO_remove_functions (1 << 8) -#define TODO_rebuild_frequencies (1 << 9) /* To-do flags for calls to update_ssa. */ @@ -418,6 +417,7 @@ extern gimple_opt_pass *make_pass_pre (gcc::context *ctxt); extern unsigned int tail_merge_optimize (bool); extern gimple_opt_pass *make_pass_profile (gcc::context *ctxt); extern gimple_opt_pass *make_pass_strip_predict_hints (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_rebuild_frequencies (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_complex_O0 (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_complex (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_switch (gcc::context *ctxt); -- cgit v1.1 From 1815e313a8fb519a77c94a908eb6dafc4ce51ffe Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Fri, 14 Jul 2023 11:46:22 +0200 Subject: cprop: Do not set REG_EQUAL note when simplifying paradoxical subreg [PR110206] cprop1 pass does not consider paradoxical subreg and for (insn 22) claims that it equals 8 elements of HImodeby setting REG_EQUAL note: (insn 21 19 22 4 (set (reg:V4QI 98) (mem/u/c:V4QI (symbol_ref/u:DI ("*.LC1") [flags 0x2]) [0 S4 A32])) "pr110206.c":12:42 1530 {*movv4qi_internal} (expr_list:REG_EQUAL (const_vector:V4QI [ (const_int -52 [0xffffffffffffffcc]) repeated x4 ]) (nil))) (insn 22 21 23 4 (set (reg:V8HI 100) (zero_extend:V8HI (vec_select:V8QI (subreg:V16QI (reg:V4QI 98) 0) (parallel [ (const_int 0 [0]) (const_int 1 [0x1]) (const_int 2 [0x2]) (const_int 3 [0x3]) (const_int 4 [0x4]) (const_int 5 [0x5]) (const_int 6 [0x6]) (const_int 7 [0x7]) ])))) "pr110206.c":12:42 7471 {sse4_1_zero_extendv8qiv8hi2} (expr_list:REG_EQUAL (const_vector:V8HI [ (const_int 204 [0xcc]) repeated x8 ]) (expr_list:REG_DEAD (reg:V4QI 98) (nil)))) We rely on the "undefined" vals to have a specific value (from the earlier REG_EQUAL note) but actual code generation doesn't ensure this (it doesn't need to). That said, the issue isn't the constant folding per-se but that we do not actually constant fold but register an equality that doesn't hold. PR target/110206 gcc/ChangeLog: * fwprop.cc (contains_paradoxical_subreg_p): Move to ... * rtlanal.cc (contains_paradoxical_subreg_p): ... here. * rtlanal.h (contains_paradoxical_subreg_p): Add prototype. * cprop.cc (try_replace_reg): Do not set REG_EQUAL note when the original source contains a paradoxical subreg. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110206.c: New test. --- gcc/cprop.cc | 4 +++- gcc/fwprop.cc | 16 +------------ gcc/rtlanal.cc | 15 ++++++++++++ gcc/rtlanal.h | 2 ++ gcc/testsuite/gcc.target/i386/pr110206.c | 39 ++++++++++++++++++++++++++++++++ 5 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110206.c (limited to 'gcc') diff --git a/gcc/cprop.cc b/gcc/cprop.cc index b7400c9..cf6faca 100644 --- a/gcc/cprop.cc +++ b/gcc/cprop.cc @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "backend.h" #include "rtl.h" +#include "rtlanal.h" #include "cfghooks.h" #include "df.h" #include "insn-config.h" @@ -795,7 +796,8 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn) /* If we've failed perform the replacement, have a single SET to a REG destination and don't yet have a note, add a REG_EQUAL note to not lose information. */ - if (!success && note == 0 && set != 0 && REG_P (SET_DEST (set))) + if (!success && note == 0 && set != 0 && REG_P (SET_DEST (set)) + && !contains_paradoxical_subreg_p (SET_SRC (set))) note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src)); } diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc index ae342f5..0707a23 100644 --- a/gcc/fwprop.cc +++ b/gcc/fwprop.cc @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "backend.h" #include "rtl.h" +#include "rtlanal.h" #include "df.h" #include "rtl-ssa.h" @@ -353,21 +354,6 @@ reg_single_def_p (rtx x) return REG_P (x) && crtl->ssa->single_dominating_def (REGNO (x)); } -/* Return true if X contains a paradoxical subreg. */ - -static bool -contains_paradoxical_subreg_p (rtx x) -{ - subrtx_var_iterator::array_type array; - FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST) - { - x = *iter; - if (SUBREG_P (x) && paradoxical_subreg_p (x)) - return true; - } - return false; -} - /* Try to substitute (set DEST SRC), which defines DEF, into note NOTE of USE_INSN. Return the number of substitutions on success, otherwise return -1 and leave USE_INSN unchanged. diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc index 31707f3..8b48fc2 100644 --- a/gcc/rtlanal.cc +++ b/gcc/rtlanal.cc @@ -6970,3 +6970,18 @@ vec_series_lowpart_p (machine_mode result_mode, machine_mode op_mode, rtx sel) } return false; } + +/* Return true if X contains a paradoxical subreg. */ + +bool +contains_paradoxical_subreg_p (rtx x) +{ + subrtx_var_iterator::array_type array; + FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST) + { + x = *iter; + if (SUBREG_P (x) && paradoxical_subreg_p (x)) + return true; + } + return false; +} diff --git a/gcc/rtlanal.h b/gcc/rtlanal.h index 9013e75..4f0dea8 100644 --- a/gcc/rtlanal.h +++ b/gcc/rtlanal.h @@ -338,4 +338,6 @@ vec_series_highpart_p (machine_mode result_mode, machine_mode op_mode, bool vec_series_lowpart_p (machine_mode result_mode, machine_mode op_mode, rtx sel); +bool +contains_paradoxical_subreg_p (rtx x); #endif diff --git a/gcc/testsuite/gcc.target/i386/pr110206.c b/gcc/testsuite/gcc.target/i386/pr110206.c new file mode 100644 index 0000000..af1455c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110206.c @@ -0,0 +1,39 @@ +/* PR target/110206 */ +/* { dg-do run } */ +/* { dg-options "-Os -mavx512bw -mavx512vl" } */ +/* { dg-require-effective-target avx512bw } */ +/* { dg-require-effective-target avx512vl } */ + +#define AVX512BW +#define AVX512VL + +#include "avx512f-check.h" + +typedef unsigned char __attribute__((__vector_size__ (4))) U; +typedef unsigned char __attribute__((__vector_size__ (8))) V; +typedef unsigned short u16; + +V g; + +void +__attribute__((noinline)) +foo (U u, u16 c, V *r) +{ + if (!c) + abort (); + V x = __builtin_shufflevector (u, (204 >> u), 7, 0, 5, 1, 3, 5, 0, 2); + V y = __builtin_shufflevector (g, (V) { }, 7, 6, 6, 7, 2, 6, 3, 5); + V z = __builtin_shufflevector (y, 204 * x, 3, 9, 8, 1, 4, 6, 14, 5); + *r = z; +} + +static void test_256 (void) { }; + +static void +test_128 (void) +{ + V r; + foo ((U){4}, 5, &r); + if (r[6] != 0x30) + abort(); +} -- cgit v1.1 From 8911879415d6c2a7baad88235554a912887a1c5c Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Fri, 14 Jul 2023 18:10:05 +0100 Subject: i386: Improved insv of DImode/DFmode {high,low}parts into TImode. This is the next piece towards a fix for (the x86_64 ABI issues affecting) PR 88873. This patch generalizes the recent tweak to ix86_expand_move for setting the highpart of a TImode reg from a DImode source using *insvti_highpart_1, to handle both DImode and DFmode sources, and also use the recently added *insvti_lowpart_1 for setting the lowpart. Although this is another intermediate step (not yet a fix), towards enabling *insvti and *concat* patterns to be candidates for TImode STV (by using V2DI/V2DF instructions), it already improves things a little. For the test case from PR 88873 typedef struct { double x, y; } s_t; typedef double v2df __attribute__ ((vector_size (2 * sizeof(double)))); s_t foo (s_t a, s_t b, s_t c) { return (s_t) { fma(a.x, b.x, c.x), fma (a.y, b.y, c.y) }; } With -O2 -march=cascadelake, GCC currently generates: Before (29 instructions): vmovq %xmm2, -56(%rsp) movq -56(%rsp), %rdx vmovq %xmm4, -40(%rsp) movq $0, -48(%rsp) movq %rdx, -56(%rsp) movq -40(%rsp), %rdx vmovq %xmm0, -24(%rsp) movq %rdx, -40(%rsp) movq -24(%rsp), %rsi movq -56(%rsp), %rax movq $0, -32(%rsp) vmovq %xmm3, -48(%rsp) movq -48(%rsp), %rcx vmovq %xmm5, -32(%rsp) vmovq %rax, %xmm6 movq -40(%rsp), %rax movq $0, -16(%rsp) movq %rsi, -24(%rsp) movq -32(%rsp), %rsi vpinsrq $1, %rcx, %xmm6, %xmm6 vmovq %rax, %xmm7 vmovq %xmm1, -16(%rsp) vmovapd %xmm6, %xmm3 vpinsrq $1, %rsi, %xmm7, %xmm7 vfmadd132pd -24(%rsp), %xmm7, %xmm3 vmovapd %xmm3, -56(%rsp) vmovsd -48(%rsp), %xmm1 vmovsd -56(%rsp), %xmm0 ret After (20 instructions): vmovq %xmm2, -56(%rsp) movq -56(%rsp), %rax vmovq %xmm3, -48(%rsp) vmovq %xmm4, -40(%rsp) movq -48(%rsp), %rcx vmovq %xmm5, -32(%rsp) vmovq %rax, %xmm6 movq -40(%rsp), %rax movq -32(%rsp), %rsi vpinsrq $1, %rcx, %xmm6, %xmm6 vmovq %xmm0, -24(%rsp) vmovq %rax, %xmm7 vmovq %xmm1, -16(%rsp) vmovapd %xmm6, %xmm2 vpinsrq $1, %rsi, %xmm7, %xmm7 vfmadd132pd -24(%rsp), %xmm7, %xmm2 vmovapd %xmm2, -56(%rsp) vmovsd -48(%rsp), %xmm1 vmovsd -56(%rsp), %xmm0 ret 2023-07-14 Roger Sayle gcc/ChangeLog * config/i386/i386-expand.cc (ix86_expand_move): Generalize special case inserting of 64-bit values into a TImode register, to handle both DImode and DFmode using either *insvti_lowpart_1 or *isnvti_highpart_1. --- gcc/config/i386/i386-expand.cc | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 648d609..f9b0dc6 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -542,22 +542,39 @@ ix86_expand_move (machine_mode mode, rtx operands[]) } } - /* Use *insvti_highpart_1 to set highpart of TImode register. */ + /* Special case inserting 64-bit values into a TImode register. */ if (TARGET_64BIT - && mode == DImode + && (mode == DImode || mode == DFmode) && SUBREG_P (op0) - && SUBREG_BYTE (op0) == 8 && GET_MODE (SUBREG_REG (op0)) == TImode && REG_P (SUBREG_REG (op0)) && REG_P (op1)) { - wide_int mask = wi::mask (64, false, 128); - rtx tmp = immed_wide_int_const (mask, TImode); - op0 = SUBREG_REG (op0); - tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp); - op1 = gen_rtx_ZERO_EXTEND (TImode, op1); - op1 = gen_rtx_ASHIFT (TImode, op1, GEN_INT (64)); - op1 = gen_rtx_IOR (TImode, tmp, op1); + /* Use *insvti_lowpart_1 to set lowpart. */ + if (SUBREG_BYTE (op0) == 0) + { + wide_int mask = wi::mask (64, true, 128); + rtx tmp = immed_wide_int_const (mask, TImode); + op0 = SUBREG_REG (op0); + tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp); + if (mode == DFmode) + op1 = force_reg (DImode, gen_lowpart (DImode, op1)); + op1 = gen_rtx_ZERO_EXTEND (TImode, op1); + op1 = gen_rtx_IOR (TImode, tmp, op1); + } + /* Use *insvti_highpart_1 to set highpart. */ + else if (SUBREG_BYTE (op0) == 8) + { + wide_int mask = wi::mask (64, false, 128); + rtx tmp = immed_wide_int_const (mask, TImode); + op0 = SUBREG_REG (op0); + tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp); + if (mode == DFmode) + op1 = force_reg (DImode, gen_lowpart (DImode, op1)); + op1 = gen_rtx_ZERO_EXTEND (TImode, op1); + op1 = gen_rtx_ASHIFT (TImode, op1, GEN_INT (64)); + op1 = gen_rtx_IOR (TImode, tmp, op1); + } } emit_insn (gen_rtx_SET (op0, op1)); -- cgit v1.1 From b5138df96a93d3b5070c88b8617eabd38cb24ab6 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 25 May 2023 18:54:18 -0400 Subject: c++: wrong error with static constexpr var in tmpl [PR109876] Since r8-509, we'll no longer create a static temporary var for the initializer '{ 1, 2 }' for num in the attached test because the code in finish_compound_literal is now guarded by '&& fcl_context == fcl_c99' but it's fcl_functional here. This causes us to reject num as non-constant when evaluating it in a template. Jason's idea was to treat num as value-dependent even though it actually isn't. This patch implements that suggestion. We weren't marking objects whose type is an empty class type constant. This patch changes that so that v_d_e_p doesn't need to check is_really_empty_class. Co-authored-by: Jason Merrill PR c++/109876 gcc/cp/ChangeLog: * decl.cc (cp_finish_decl): Set TREE_CONSTANT when initializing an object of empty class type. * pt.cc (value_dependent_expression_p) : Treat a constexpr-declared non-constant variable as value-dependent. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-template12.C: New test. * g++.dg/cpp1z/constexpr-template1.C: New test. * g++.dg/cpp1z/constexpr-template2.C: New test. --- gcc/cp/decl.cc | 13 ++++++-- gcc/cp/pt.cc | 7 +++++ gcc/testsuite/g++.dg/cpp0x/constexpr-template12.C | 38 +++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/constexpr-template1.C | 25 +++++++++++++++ gcc/testsuite/g++.dg/cpp1z/constexpr-template2.C | 25 +++++++++++++++ 5 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-template12.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-template1.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-template2.C (limited to 'gcc') diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 60f107d..792ab33 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8200,7 +8200,6 @@ void cp_finish_decl (tree decl, tree init, bool init_const_expr_p, tree asmspec_tree, int flags) { - tree type; vec *cleanups = NULL; const char *asmspec = NULL; int was_readonly = 0; @@ -8220,7 +8219,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, /* Parameters are handled by store_parm_decls, not cp_finish_decl. */ gcc_assert (TREE_CODE (decl) != PARM_DECL); - type = TREE_TYPE (decl); + tree type = TREE_TYPE (decl); if (type == error_mark_node) return; @@ -8410,7 +8409,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (decl_maybe_constant_var_p (decl) /* FIXME setting TREE_CONSTANT on refs breaks the back end. */ && !TYPE_REF_P (type)) - TREE_CONSTANT (decl) = 1; + TREE_CONSTANT (decl) = true; } /* This is handled mostly by gimplify.cc, but we have to deal with not warning about int x = x; as it is a GCC extension to turn off @@ -8421,6 +8420,14 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self)) suppress_warning (decl, OPT_Winit_self); } + else if (VAR_P (decl) + && COMPLETE_TYPE_P (type) + && !TYPE_REF_P (type) + && !dependent_type_p (type) + && is_really_empty_class (type, /*ignore_vptr*/false)) + /* We have no initializer but there's nothing to initialize anyway. + Treat DECL as constant due to c++/109876. */ + TREE_CONSTANT (decl) = true; if (flag_openmp && TREE_CODE (decl) == FUNCTION_DECL diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index fa15b75..255d18b 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -27983,6 +27983,13 @@ value_dependent_expression_p (tree expression) else if (TYPE_REF_P (TREE_TYPE (expression))) /* FIXME cp_finish_decl doesn't fold reference initializers. */ return true; + /* We have a constexpr variable and we're processing a template. When + there's lifetime extension involved (for which finish_compound_literal + used to create a temporary), we'll not be able to evaluate the + variable until instantiating, so pretend it's value-dependent. */ + else if (DECL_DECLARED_CONSTEXPR_P (expression) + && !TREE_CONSTANT (expression)) + return true; return false; case DYNAMIC_CAST_EXPR: diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-template12.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-template12.C new file mode 100644 index 0000000..a9e0653 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-template12.C @@ -0,0 +1,38 @@ +// PR c++/109876 +// { dg-do compile { target c++11 } } + +using size_t = decltype(sizeof 0); + +namespace std { +template struct initializer_list { + const int *_M_array; + size_t _M_len; + constexpr size_t size() const { return _M_len; } +}; +} // namespace std + +constexpr std::initializer_list gnum{2}; + +template struct Array {}; +template void g() +{ + static constexpr std::initializer_list num{2}; + static_assert(num.size(), ""); + Array ctx; + + constexpr Array<1> num1{}; +} + +template +struct Foo +{ + static constexpr std::initializer_list num = { 1, 2 }; + static_assert(num.size(), ""); + Array ctx; +}; + +void +f (Foo<5>) +{ + g<0>(); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-template1.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-template1.C new file mode 100644 index 0000000..58be046 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-template1.C @@ -0,0 +1,25 @@ +// PR c++/109876 +// { dg-do compile { target c++17 } } + +struct Foo {}; +template struct X {}; + +void g() +{ + static constexpr Foo foo; + X x; +} + +template +void f() +{ + static constexpr Foo foo; + X x; +} + +void +h () +{ + f<0>(); + f<1>(); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-template2.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-template2.C new file mode 100644 index 0000000..5a9a96b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-template2.C @@ -0,0 +1,25 @@ +// PR c++/109876 +// { dg-do compile { target c++17 } } + +struct Foo {}; +template struct X {}; + +void g() +{ + static constexpr Foo foo{}; + X x; +} + +template +void f() +{ + static constexpr Foo foo{}; + X x; +} + +void +h () +{ + f<0>(); + f<1>(); +} -- cgit v1.1 From 43a0a5cd57eefd5a5bbead606ec4f6959af31802 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Fri, 14 Jul 2023 18:21:56 +0100 Subject: PR target/110588: Add *bt_setncqi_2 to generate btl on x86. This patch resolves PR target/110588 to catch another case in combine where the i386 backend should be generating a btl instruction. This adds another define_insn_and_split to recognize the RTL representation for this case. I also noticed that two related define_insn_and_split weren't using the preferred string style for single statement preparation-statements, so I've reformatted these to be consistent in style with the new one. 2023-07-14 Roger Sayle gcc/ChangeLog PR target/110588 * config/i386/i386.md (*bt_setcqi): Prefer string form preparation statement over braces for a single statement. (*bt_setncqi): Likewise. (*bt_setncqi_2): New define_insn_and_split. gcc/testsuite/ChangeLog PR target/110588 * gcc.target/i386/pr110588.c: New test case. --- gcc/config/i386/i386.md | 29 +++++++++++++++++++++++------ gcc/testsuite/gcc.target/i386/pr110588.c | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110588.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 89a7fb0..47ea050 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -16287,9 +16287,7 @@ (const_int 0))) (set (match_dup 0) (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] -{ - operands[2] = lowpart_subreg (SImode, operands[2], QImode); -}) + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") ;; Help combine recognize bt followed by setnc (define_insn_and_split "*bt_setncqi" @@ -16310,9 +16308,7 @@ (const_int 0))) (set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] -{ - operands[2] = lowpart_subreg (SImode, operands[2], QImode); -}) + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") (define_insn_and_split "*bt_setnc" [(set (match_operand:SWI48 0 "register_operand") @@ -16336,6 +16332,27 @@ operands[2] = lowpart_subreg (SImode, operands[2], QImode); operands[3] = gen_reg_rtx (QImode); }) + +;; Help combine recognize bt followed by setnc (PR target/110588) +(define_insn_and_split "*bt_setncqi_2" + [(set (match_operand:QI 0 "register_operand") + (eq:QI + (zero_extract:SWI48 + (match_operand:SWI48 1 "register_operand") + (const_int 1) + (zero_extend:SI (match_operand:QI 2 "register_operand"))) + (const_int 0))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_USE_BT && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) + (const_int 0))) + (set (match_dup 0) + (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") ;; Store-flag instructions. diff --git a/gcc/testsuite/gcc.target/i386/pr110588.c b/gcc/testsuite/gcc.target/i386/pr110588.c new file mode 100644 index 0000000..4505c87 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110588.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=core2" } */ + +unsigned char foo (unsigned char x, int y) +{ + int _1 = (int) x; + int _2 = _1 >> y; + int _3 = _2 & 1; + unsigned char _8 = (unsigned char) _3; + unsigned char _6 = _8 ^ 1; + return _6; +} + +/* { dg-final { scan-assembler "btl" } } */ +/* { dg-final { scan-assembler "setnc" } } */ +/* { dg-final { scan-assembler-not "sarl" } } */ +/* { dg-final { scan-assembler-not "andl" } } */ +/* { dg-final { scan-assembler-not "xorl" } } */ -- cgit v1.1 From b22e70e8e97176561357f0ddcd84af889eb6b317 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 28 Jun 2023 14:29:15 +0000 Subject: arm: [MVE intrinsics] Factorize vcaddq vhcaddq Factorize vcaddq, vhcaddq so that they use the same parameterized names. To be able to use the same patterns, we add a suffix to vcaddq. Note that vcadd uses UNSPEC_VCADDxx for builtins without predication, and VCADDQ_ROTxx_M_x (that is, not starting with "UNSPEC_"). The UNPEC_* names are also used by neon.md 2023-07-13 Christophe Lyon gcc/ * config/arm/arm_mve_builtins.def (vcaddq_rot90_, vcaddq_rot270_) (vcaddq_rot90_f, vcaddq_rot90_f): Add "_" or "_f" suffix. * config/arm/iterators.md (mve_insn): Add vcadd, vhcadd. (isu): Add UNSPEC_VCADD90, UNSPEC_VCADD270, VCADDQ_ROT270_M_U, VCADDQ_ROT270_M_S, VCADDQ_ROT90_M_U, VCADDQ_ROT90_M_S, VHCADDQ_ROT90_M_S, VHCADDQ_ROT270_M_S, VHCADDQ_ROT90_S, VHCADDQ_ROT270_S. (rot): Add VCADDQ_ROT90_M_F, VCADDQ_ROT90_M_S, VCADDQ_ROT90_M_U, VCADDQ_ROT270_M_F, VCADDQ_ROT270_M_S, VCADDQ_ROT270_M_U, VHCADDQ_ROT90_S, VHCADDQ_ROT270_S, VHCADDQ_ROT90_M_S, VHCADDQ_ROT270_M_S. (mve_rot): Add VCADDQ_ROT90_M_F, VCADDQ_ROT90_M_S, VCADDQ_ROT90_M_U, VCADDQ_ROT270_M_F, VCADDQ_ROT270_M_S, VCADDQ_ROT270_M_U, VHCADDQ_ROT90_S, VHCADDQ_ROT270_S, VHCADDQ_ROT90_M_S, VHCADDQ_ROT270_M_S. (supf): Add VHCADDQ_ROT90_M_S, VHCADDQ_ROT270_M_S, VHCADDQ_ROT90_S, VHCADDQ_ROT270_S, UNSPEC_VCADD90, UNSPEC_VCADD270. (VCADDQ_ROT270_M): Delete. (VCADDQ_M_F VxCADDQ VxCADDQ_M): New. (VCADDQ_ROT90_M): Delete. * config/arm/mve.md (mve_vcaddq) (mve_vhcaddq_rot270_s, mve_vhcaddq_rot90_s): Merge into ... (@mve_q_): ... this. (mve_vcaddq): Rename into ... (@mve_q_f): ... this (mve_vcaddq_rot270_m_) (mve_vcaddq_rot90_m_, mve_vhcaddq_rot270_m_s) (mve_vhcaddq_rot90_m_s): Merge into ... (@mve_q_m_): ... this. (mve_vcaddq_rot270_m_f, mve_vcaddq_rot90_m_f): Merge into ... (@mve_q_m_f): ... this. --- gcc/config/arm/arm_mve_builtins.def | 6 +- gcc/config/arm/iterators.md | 38 +++++++++- gcc/config/arm/mve.md | 135 ++++++------------------------------ 3 files changed, 62 insertions(+), 117 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arm/arm_mve_builtins.def b/gcc/config/arm/arm_mve_builtins.def index 8de765d..63ad184 100644 --- a/gcc/config/arm/arm_mve_builtins.def +++ b/gcc/config/arm/arm_mve_builtins.def @@ -187,6 +187,10 @@ VAR3 (BINOP_NONE_NONE_NONE, vmaxvq_s, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vmaxq_s, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vhsubq_s, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vhsubq_n_s, v16qi, v8hi, v4si) +VAR3 (BINOP_NONE_NONE_NONE, vcaddq_rot90_, v16qi, v8hi, v4si) +VAR3 (BINOP_NONE_NONE_NONE, vcaddq_rot270_, v16qi, v8hi, v4si) +VAR2 (BINOP_NONE_NONE_NONE, vcaddq_rot90_f, v8hf, v4sf) +VAR2 (BINOP_NONE_NONE_NONE, vcaddq_rot270_f, v8hf, v4sf) VAR3 (BINOP_NONE_NONE_NONE, vhcaddq_rot90_s, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vhcaddq_rot270_s, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vhaddq_s, v16qi, v8hi, v4si) @@ -870,8 +874,6 @@ VAR3 (QUADOP_UNONE_UNONE_UNONE_IMM_PRED, vshlcq_m_vec_u, v16qi, v8hi, v4si) VAR3 (QUADOP_UNONE_UNONE_UNONE_IMM_PRED, vshlcq_m_carry_u, v16qi, v8hi, v4si) /* optabs without any suffixes. */ -VAR5 (BINOP_NONE_NONE_NONE, vcaddq_rot90, v16qi, v8hi, v4si, v8hf, v4sf) -VAR5 (BINOP_NONE_NONE_NONE, vcaddq_rot270, v16qi, v8hi, v4si, v8hf, v4sf) VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot90, v8hf, v4sf) VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot270, v8hf, v4sf) VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot180, v8hf, v4sf) diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 9e77af5..da1ead3 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -902,6 +902,7 @@ ]) (define_int_attr mve_insn [ + (UNSPEC_VCADD90 "vcadd") (UNSPEC_VCADD270 "vcadd") (VABAVQ_P_S "vabav") (VABAVQ_P_U "vabav") (VABAVQ_S "vabav") (VABAVQ_U "vabav") (VABDQ_M_S "vabd") (VABDQ_M_U "vabd") (VABDQ_M_F "vabd") @@ -925,6 +926,8 @@ (VBICQ_N_S "vbic") (VBICQ_N_U "vbic") (VBRSRQ_M_N_S "vbrsr") (VBRSRQ_M_N_U "vbrsr") (VBRSRQ_M_N_F "vbrsr") (VBRSRQ_N_S "vbrsr") (VBRSRQ_N_U "vbrsr") (VBRSRQ_N_F "vbrsr") + (VCADDQ_ROT270_M_U "vcadd") (VCADDQ_ROT270_M_S "vcadd") (VCADDQ_ROT270_M_F "vcadd") + (VCADDQ_ROT90_M_U "vcadd") (VCADDQ_ROT90_M_S "vcadd") (VCADDQ_ROT90_M_F "vcadd") (VCLSQ_M_S "vcls") (VCLSQ_S "vcls") (VCLZQ_M_S "vclz") (VCLZQ_M_U "vclz") @@ -944,6 +947,8 @@ (VHADDQ_M_S "vhadd") (VHADDQ_M_U "vhadd") (VHADDQ_N_S "vhadd") (VHADDQ_N_U "vhadd") (VHADDQ_S "vhadd") (VHADDQ_U "vhadd") + (VHCADDQ_ROT90_M_S "vhcadd") (VHCADDQ_ROT270_M_S "vhcadd") + (VHCADDQ_ROT90_S "vhcadd") (VHCADDQ_ROT270_S "vhcadd") (VHSUBQ_M_N_S "vhsub") (VHSUBQ_M_N_U "vhsub") (VHSUBQ_M_S "vhsub") (VHSUBQ_M_U "vhsub") (VHSUBQ_N_S "vhsub") (VHSUBQ_N_U "vhsub") @@ -1190,7 +1195,10 @@ ]) (define_int_attr isu [ + (UNSPEC_VCADD90 "i") (UNSPEC_VCADD270 "i") (VABSQ_M_S "s") + (VCADDQ_ROT270_M_U "i") (VCADDQ_ROT270_M_S "i") + (VCADDQ_ROT90_M_U "i") (VCADDQ_ROT90_M_S "i") (VCLSQ_M_S "s") (VCLZQ_M_S "i") (VCLZQ_M_U "i") @@ -1214,6 +1222,8 @@ (VCMPNEQ_M_N_U "i") (VCMPNEQ_M_S "i") (VCMPNEQ_M_U "i") + (VHCADDQ_ROT90_M_S "s") (VHCADDQ_ROT270_M_S "s") + (VHCADDQ_ROT90_S "s") (VHCADDQ_ROT270_S "s") (VMOVNBQ_M_S "i") (VMOVNBQ_M_U "i") (VMOVNBQ_S "i") (VMOVNBQ_U "i") (VMOVNTQ_M_S "i") (VMOVNTQ_M_U "i") @@ -2155,6 +2165,16 @@ (define_int_attr rot [(UNSPEC_VCADD90 "90") (UNSPEC_VCADD270 "270") + (VCADDQ_ROT90_M_F "90") + (VCADDQ_ROT90_M_S "90") + (VCADDQ_ROT90_M_U "90") + (VCADDQ_ROT270_M_F "270") + (VCADDQ_ROT270_M_S "270") + (VCADDQ_ROT270_M_U "270") + (VHCADDQ_ROT90_S "90") + (VHCADDQ_ROT270_S "270") + (VHCADDQ_ROT90_M_S "90") + (VHCADDQ_ROT270_M_S "270") (UNSPEC_VCMUL "0") (UNSPEC_VCMUL90 "90") (UNSPEC_VCMUL180 "180") @@ -2193,6 +2213,16 @@ (define_int_attr mve_rot [(UNSPEC_VCADD90 "_rot90") (UNSPEC_VCADD270 "_rot270") + (VCADDQ_ROT90_M_F "_rot90") + (VCADDQ_ROT90_M_S "_rot90") + (VCADDQ_ROT90_M_U "_rot90") + (VCADDQ_ROT270_M_F "_rot270") + (VCADDQ_ROT270_M_S "_rot270") + (VCADDQ_ROT270_M_U "_rot270") + (VHCADDQ_ROT90_S "_rot90") + (VHCADDQ_ROT270_S "_rot270") + (VHCADDQ_ROT90_M_S "_rot90") + (VHCADDQ_ROT270_M_S "_rot270") (UNSPEC_VCMLA "") (UNSPEC_VCMLA90 "_rot90") (UNSPEC_VCMLA180 "_rot180") @@ -2535,6 +2565,9 @@ (VRMLALDAVHAQ_P_S "s") (VRMLALDAVHAQ_P_U "u") (VQSHLUQ_M_N_S "s") (VQSHLUQ_N_S "s") + (VHCADDQ_ROT90_M_S "s") (VHCADDQ_ROT270_M_S "s") + (VHCADDQ_ROT90_S "s") (VHCADDQ_ROT270_S "s") + (UNSPEC_VCADD90 "") (UNSPEC_VCADD270 "") ]) ;; Both kinds of return insn. @@ -2767,7 +2800,9 @@ (define_int_iterator VANDQ_M [VANDQ_M_U VANDQ_M_S]) (define_int_iterator VBICQ_M [VBICQ_M_U VBICQ_M_S]) (define_int_iterator VSHLQ_M_N [VSHLQ_M_N_S VSHLQ_M_N_U]) -(define_int_iterator VCADDQ_ROT270_M [VCADDQ_ROT270_M_U VCADDQ_ROT270_M_S]) +(define_int_iterator VCADDQ_M_F [VCADDQ_ROT90_M_F VCADDQ_ROT270_M_F]) +(define_int_iterator VxCADDQ [UNSPEC_VCADD90 UNSPEC_VCADD270 VHCADDQ_ROT90_S VHCADDQ_ROT270_S]) +(define_int_iterator VxCADDQ_M [VHCADDQ_ROT90_M_S VHCADDQ_ROT270_M_S VCADDQ_ROT90_M_U VCADDQ_ROT90_M_S VCADDQ_ROT270_M_U VCADDQ_ROT270_M_S]) (define_int_iterator VQRSHLQ_M [VQRSHLQ_M_U VQRSHLQ_M_S]) (define_int_iterator VQADDQ_M_N [VQADDQ_M_N_U VQADDQ_M_N_S]) (define_int_iterator VADDQ_M_N [VADDQ_M_N_S VADDQ_M_N_U]) @@ -2777,7 +2812,6 @@ (define_int_iterator VMLADAVAQ_P [VMLADAVAQ_P_U VMLADAVAQ_P_S]) (define_int_iterator VBRSRQ_M_N [VBRSRQ_M_N_U VBRSRQ_M_N_S]) (define_int_iterator VMULQ_M_N [VMULQ_M_N_U VMULQ_M_N_S]) -(define_int_iterator VCADDQ_ROT90_M [VCADDQ_ROT90_M_U VCADDQ_ROT90_M_S]) (define_int_iterator VMULLTQ_INT_M [VMULLTQ_INT_M_S VMULLTQ_INT_M_U]) (define_int_iterator VEORQ_M [VEORQ_M_S VEORQ_M_U]) (define_int_iterator VSHRQ_M_N [VSHRQ_M_N_S VSHRQ_M_N_U]) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 74909ce..a6db6d1 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -839,17 +839,20 @@ ]) ;; -;; [vcaddq, vcaddq_rot90, vcadd_rot180, vcadd_rot270]) +;; [vcaddq_rot90_s, vcadd_rot90_u] +;; [vcaddq_rot270_s, vcadd_rot270_u] +;; [vhcaddq_rot90_s] +;; [vhcaddq_rot270_s] ;; -(define_insn "mve_vcaddq" +(define_insn "@mve_q_" [ (set (match_operand:MVE_2 0 "s_register_operand" "") (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "w") (match_operand:MVE_2 2 "s_register_operand" "w")] - VCADD)) + VxCADDQ)) ] "TARGET_HAVE_MVE" - "vcadd.i%# %q0, %q1, %q2, #" + ".%#\t%q0, %q1, %q2, #" [(set_attr "type" "mve_move") ]) @@ -905,36 +908,6 @@ ]) ;; -;; [vhcaddq_rot270_s]) -;; -(define_insn "mve_vhcaddq_rot270_s" - [ - (set (match_operand:MVE_2 0 "s_register_operand" "") - (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "w") - (match_operand:MVE_2 2 "s_register_operand" "w")] - VHCADDQ_ROT270_S)) - ] - "TARGET_HAVE_MVE" - "vhcadd.s%#\t%q0, %q1, %q2, #270" - [(set_attr "type" "mve_move") -]) - -;; -;; [vhcaddq_rot90_s]) -;; -(define_insn "mve_vhcaddq_rot90_s" - [ - (set (match_operand:MVE_2 0 "s_register_operand" "") - (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "w") - (match_operand:MVE_2 2 "s_register_operand" "w")] - VHCADDQ_ROT90_S)) - ] - "TARGET_HAVE_MVE" - "vhcadd.s%#\t%q0, %q1, %q2, #90" - [(set_attr "type" "mve_move") -]) - -;; ;; [vmaxaq_s] ;; [vminaq_s] ;; @@ -1238,9 +1211,9 @@ ]) ;; -;; [vcaddq, vcaddq_rot90, vcadd_rot180, vcadd_rot270]) +;; [vcaddq_rot90_f, vcaddq_rot270_f] ;; -(define_insn "mve_vcaddq" +(define_insn "@mve_q_f" [ (set (match_operand:MVE_0 0 "s_register_operand" "") (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w") @@ -1248,7 +1221,7 @@ VCADD)) ] "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vcadd.f%# %q0, %q1, %q2, #" + ".f%#\t%q0, %q1, %q2, #" [(set_attr "type" "mve_move") ]) @@ -2788,36 +2761,22 @@ (set_attr "length""8")]) ;; -;; [vcaddq_rot270_m_u, vcaddq_rot270_m_s]) +;; [vcaddq_rot90_m_u, vcaddq_rot90_m_s] +;; [vcaddq_rot270_m_u, vcaddq_rot270_m_s] +;; [vhcaddq_rot90_m_s] +;; [vhcaddq_rot270_m_s] ;; -(define_insn "mve_vcaddq_rot270_m_" +(define_insn "@mve_q_m_" [ (set (match_operand:MVE_2 0 "s_register_operand" "") (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "0") (match_operand:MVE_2 2 "s_register_operand" "w") (match_operand:MVE_2 3 "s_register_operand" "w") (match_operand: 4 "vpr_register_operand" "Up")] - VCADDQ_ROT270_M)) + VxCADDQ_M)) ] "TARGET_HAVE_MVE" - "vpst\;vcaddt.i%# %q0, %q2, %q3, #270" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcaddq_rot90_m_u, vcaddq_rot90_m_s]) -;; -(define_insn "mve_vcaddq_rot90_m_" - [ - (set (match_operand:MVE_2 0 "s_register_operand" "") - (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "0") - (match_operand:MVE_2 2 "s_register_operand" "w") - (match_operand:MVE_2 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCADDQ_ROT90_M)) - ] - "TARGET_HAVE_MVE" - "vpst\;vcaddt.i%# %q0, %q2, %q3, #90" + "vpst\;t.%#\t%q0, %q2, %q3, #" [(set_attr "type" "mve_move") (set_attr "length""8")]) @@ -2975,40 +2934,6 @@ (set_attr "length""8")]) ;; -;; [vhcaddq_rot270_m_s]) -;; -(define_insn "mve_vhcaddq_rot270_m_s" - [ - (set (match_operand:MVE_2 0 "s_register_operand" "") - (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "0") - (match_operand:MVE_2 2 "s_register_operand" "w") - (match_operand:MVE_2 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VHCADDQ_ROT270_M_S)) - ] - "TARGET_HAVE_MVE" - "vpst\;vhcaddt.s%#\t%q0, %q2, %q3, #270" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vhcaddq_rot90_m_s]) -;; -(define_insn "mve_vhcaddq_rot90_m_s" - [ - (set (match_operand:MVE_2 0 "s_register_operand" "") - (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "0") - (match_operand:MVE_2 2 "s_register_operand" "w") - (match_operand:MVE_2 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VHCADDQ_ROT90_M_S)) - ] - "TARGET_HAVE_MVE" - "vpst\;vhcaddt.s%#\t%q0, %q2, %q3, #90" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; ;; [vmlaldavaq_p_u, vmlaldavaq_p_s] ;; [vmlaldavaxq_p_s] ;; [vmlsldavaq_p_s] @@ -3247,36 +3172,20 @@ (set_attr "length""8")]) ;; -;; [vcaddq_rot270_m_f]) -;; -(define_insn "mve_vcaddq_rot270_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCADDQ_ROT270_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcaddt.f%# %q0, %q2, %q3, #270" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcaddq_rot90_m_f]) +;; [vcaddq_rot90_m_f] +;; [vcaddq_rot270_m_f] ;; -(define_insn "mve_vcaddq_rot90_m_f" +(define_insn "@mve_q_m_f" [ (set (match_operand:MVE_0 0 "s_register_operand" "") (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") (match_operand:MVE_0 2 "s_register_operand" "w") (match_operand:MVE_0 3 "s_register_operand" "w") (match_operand: 4 "vpr_register_operand" "Up")] - VCADDQ_ROT90_M_F)) + VCADDQ_M_F)) ] "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcaddt.f%# %q0, %q2, %q3, #90" + "vpst\;t.f%#\t%q0, %q2, %q3, #" [(set_attr "type" "mve_move") (set_attr "length""8")]) -- cgit v1.1 From 446b5be4d591709004c1018ecf153afd2644bef3 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 11 Jul 2023 16:13:30 +0000 Subject: arm: [MVE intrinsics] rework vcaddq vhcaddq Implement vcaddq, vhcaddq using the new MVE builtins framework. 2023-07-13 Christophe Lyon gcc/ * config/arm/arm-mve-builtins-base.cc (vcaddq_rot90) (vcaddq_rot270, vhcaddq_rot90, vhcaddq_rot270): New. * config/arm/arm-mve-builtins-base.def (vcaddq_rot90) (vcaddq_rot270, vhcaddq_rot90, vhcaddq_rot270): New. * config/arm/arm-mve-builtins-base.h: (vcaddq_rot90) (vcaddq_rot270, vhcaddq_rot90, vhcaddq_rot270): New. * config/arm/arm-mve-builtins-functions.h (class unspec_mve_function_exact_insn_rot): New. * config/arm/arm_mve.h (vcaddq_rot90): Delete. (vcaddq_rot270): Delete. (vhcaddq_rot90): Delete. (vhcaddq_rot270): Delete. (vcaddq_rot270_m): Delete. (vcaddq_rot90_m): Delete. (vhcaddq_rot270_m): Delete. (vhcaddq_rot90_m): Delete. (vcaddq_rot90_x): Delete. (vcaddq_rot270_x): Delete. (vhcaddq_rot90_x): Delete. (vhcaddq_rot270_x): Delete. (vcaddq_rot90_u8): Delete. (vcaddq_rot270_u8): Delete. (vhcaddq_rot90_s8): Delete. (vhcaddq_rot270_s8): Delete. (vcaddq_rot90_s8): Delete. (vcaddq_rot270_s8): Delete. (vcaddq_rot90_u16): Delete. (vcaddq_rot270_u16): Delete. (vhcaddq_rot90_s16): Delete. (vhcaddq_rot270_s16): Delete. (vcaddq_rot90_s16): Delete. (vcaddq_rot270_s16): Delete. (vcaddq_rot90_u32): Delete. (vcaddq_rot270_u32): Delete. (vhcaddq_rot90_s32): Delete. (vhcaddq_rot270_s32): Delete. (vcaddq_rot90_s32): Delete. (vcaddq_rot270_s32): Delete. (vcaddq_rot90_f16): Delete. (vcaddq_rot270_f16): Delete. (vcaddq_rot90_f32): Delete. (vcaddq_rot270_f32): Delete. (vcaddq_rot270_m_s8): Delete. (vcaddq_rot270_m_s32): Delete. (vcaddq_rot270_m_s16): Delete. (vcaddq_rot270_m_u8): Delete. (vcaddq_rot270_m_u32): Delete. (vcaddq_rot270_m_u16): Delete. (vcaddq_rot90_m_s8): Delete. (vcaddq_rot90_m_s32): Delete. (vcaddq_rot90_m_s16): Delete. (vcaddq_rot90_m_u8): Delete. (vcaddq_rot90_m_u32): Delete. (vcaddq_rot90_m_u16): Delete. (vhcaddq_rot270_m_s8): Delete. (vhcaddq_rot270_m_s32): Delete. (vhcaddq_rot270_m_s16): Delete. (vhcaddq_rot90_m_s8): Delete. (vhcaddq_rot90_m_s32): Delete. (vhcaddq_rot90_m_s16): Delete. (vcaddq_rot270_m_f32): Delete. (vcaddq_rot270_m_f16): Delete. (vcaddq_rot90_m_f32): Delete. (vcaddq_rot90_m_f16): Delete. (vcaddq_rot90_x_s8): Delete. (vcaddq_rot90_x_s16): Delete. (vcaddq_rot90_x_s32): Delete. (vcaddq_rot90_x_u8): Delete. (vcaddq_rot90_x_u16): Delete. (vcaddq_rot90_x_u32): Delete. (vcaddq_rot270_x_s8): Delete. (vcaddq_rot270_x_s16): Delete. (vcaddq_rot270_x_s32): Delete. (vcaddq_rot270_x_u8): Delete. (vcaddq_rot270_x_u16): Delete. (vcaddq_rot270_x_u32): Delete. (vhcaddq_rot90_x_s8): Delete. (vhcaddq_rot90_x_s16): Delete. (vhcaddq_rot90_x_s32): Delete. (vhcaddq_rot270_x_s8): Delete. (vhcaddq_rot270_x_s16): Delete. (vhcaddq_rot270_x_s32): Delete. (vcaddq_rot90_x_f16): Delete. (vcaddq_rot90_x_f32): Delete. (vcaddq_rot270_x_f16): Delete. (vcaddq_rot270_x_f32): Delete. (__arm_vcaddq_rot90_u8): Delete. (__arm_vcaddq_rot270_u8): Delete. (__arm_vhcaddq_rot90_s8): Delete. (__arm_vhcaddq_rot270_s8): Delete. (__arm_vcaddq_rot90_s8): Delete. (__arm_vcaddq_rot270_s8): Delete. (__arm_vcaddq_rot90_u16): Delete. (__arm_vcaddq_rot270_u16): Delete. (__arm_vhcaddq_rot90_s16): Delete. (__arm_vhcaddq_rot270_s16): Delete. (__arm_vcaddq_rot90_s16): Delete. (__arm_vcaddq_rot270_s16): Delete. (__arm_vcaddq_rot90_u32): Delete. (__arm_vcaddq_rot270_u32): Delete. (__arm_vhcaddq_rot90_s32): Delete. (__arm_vhcaddq_rot270_s32): Delete. (__arm_vcaddq_rot90_s32): Delete. (__arm_vcaddq_rot270_s32): Delete. (__arm_vcaddq_rot270_m_s8): Delete. (__arm_vcaddq_rot270_m_s32): Delete. (__arm_vcaddq_rot270_m_s16): Delete. (__arm_vcaddq_rot270_m_u8): Delete. (__arm_vcaddq_rot270_m_u32): Delete. (__arm_vcaddq_rot270_m_u16): Delete. (__arm_vcaddq_rot90_m_s8): Delete. (__arm_vcaddq_rot90_m_s32): Delete. (__arm_vcaddq_rot90_m_s16): Delete. (__arm_vcaddq_rot90_m_u8): Delete. (__arm_vcaddq_rot90_m_u32): Delete. (__arm_vcaddq_rot90_m_u16): Delete. (__arm_vhcaddq_rot270_m_s8): Delete. (__arm_vhcaddq_rot270_m_s32): Delete. (__arm_vhcaddq_rot270_m_s16): Delete. (__arm_vhcaddq_rot90_m_s8): Delete. (__arm_vhcaddq_rot90_m_s32): Delete. (__arm_vhcaddq_rot90_m_s16): Delete. (__arm_vcaddq_rot90_x_s8): Delete. (__arm_vcaddq_rot90_x_s16): Delete. (__arm_vcaddq_rot90_x_s32): Delete. (__arm_vcaddq_rot90_x_u8): Delete. (__arm_vcaddq_rot90_x_u16): Delete. (__arm_vcaddq_rot90_x_u32): Delete. (__arm_vcaddq_rot270_x_s8): Delete. (__arm_vcaddq_rot270_x_s16): Delete. (__arm_vcaddq_rot270_x_s32): Delete. (__arm_vcaddq_rot270_x_u8): Delete. (__arm_vcaddq_rot270_x_u16): Delete. (__arm_vcaddq_rot270_x_u32): Delete. (__arm_vhcaddq_rot90_x_s8): Delete. (__arm_vhcaddq_rot90_x_s16): Delete. (__arm_vhcaddq_rot90_x_s32): Delete. (__arm_vhcaddq_rot270_x_s8): Delete. (__arm_vhcaddq_rot270_x_s16): Delete. (__arm_vhcaddq_rot270_x_s32): Delete. (__arm_vcaddq_rot90_f16): Delete. (__arm_vcaddq_rot270_f16): Delete. (__arm_vcaddq_rot90_f32): Delete. (__arm_vcaddq_rot270_f32): Delete. (__arm_vcaddq_rot270_m_f32): Delete. (__arm_vcaddq_rot270_m_f16): Delete. (__arm_vcaddq_rot90_m_f32): Delete. (__arm_vcaddq_rot90_m_f16): Delete. (__arm_vcaddq_rot90_x_f16): Delete. (__arm_vcaddq_rot90_x_f32): Delete. (__arm_vcaddq_rot270_x_f16): Delete. (__arm_vcaddq_rot270_x_f32): Delete. (__arm_vcaddq_rot90): Delete. (__arm_vcaddq_rot270): Delete. (__arm_vhcaddq_rot90): Delete. (__arm_vhcaddq_rot270): Delete. (__arm_vcaddq_rot270_m): Delete. (__arm_vcaddq_rot90_m): Delete. (__arm_vhcaddq_rot270_m): Delete. (__arm_vhcaddq_rot90_m): Delete. (__arm_vcaddq_rot90_x): Delete. (__arm_vcaddq_rot270_x): Delete. (__arm_vhcaddq_rot90_x): Delete. (__arm_vhcaddq_rot270_x): Delete. --- gcc/config/arm/arm-mve-builtins-base.cc | 4 + gcc/config/arm/arm-mve-builtins-base.def | 6 + gcc/config/arm/arm-mve-builtins-base.h | 4 + gcc/config/arm/arm-mve-builtins-functions.h | 103 ++ gcc/config/arm/arm_mve.h | 1398 ++------------------------- 5 files changed, 215 insertions(+), 1300 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm-mve-builtins-base.cc index af02397..f15bb92 100644 --- a/gcc/config/arm/arm-mve-builtins-base.cc +++ b/gcc/config/arm/arm-mve-builtins-base.cc @@ -260,6 +260,10 @@ FUNCTION_PRED_P_S_U (vaddvq, VADDVQ) FUNCTION_PRED_P_S_U (vaddvaq, VADDVAQ) FUNCTION_WITH_RTX_M (vandq, AND, VANDQ) FUNCTION_ONLY_N (vbrsrq, VBRSRQ) +FUNCTION (vcaddq_rot90, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD90, UNSPEC_VCADD90, UNSPEC_VCADD90, VCADDQ_ROT90_M_S, VCADDQ_ROT90_M_U, VCADDQ_ROT90_M_F)) +FUNCTION (vcaddq_rot270, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD270, UNSPEC_VCADD270, UNSPEC_VCADD270, VCADDQ_ROT270_M_S, VCADDQ_ROT270_M_U, VCADDQ_ROT270_M_F)) +FUNCTION (vhcaddq_rot90, unspec_mve_function_exact_insn_rot, (VHCADDQ_ROT90_S, -1, -1, VHCADDQ_ROT90_M_S, -1, -1)) +FUNCTION (vhcaddq_rot270, unspec_mve_function_exact_insn_rot, (VHCADDQ_ROT270_S, -1, -1, VHCADDQ_ROT270_M_S, -1, -1)) FUNCTION_WITHOUT_N_NO_U_F (vclsq, VCLSQ) FUNCTION (vclzq, unspec_based_mve_function_exact_insn, (CLZ, CLZ, CLZ, -1, -1, -1, VCLZQ_M_S, VCLZQ_M_U, -1, -1, -1 ,-1)) FUNCTION (vcmpeqq, unspec_based_mve_function_exact_insn_vcmp, (EQ, EQ, EQ, VCMPEQQ_M_S, VCMPEQQ_M_U, VCMPEQQ_M_F, VCMPEQQ_M_N_S, VCMPEQQ_M_N_U, VCMPEQQ_M_N_F)) diff --git a/gcc/config/arm/arm-mve-builtins-base.def b/gcc/config/arm/arm-mve-builtins-base.def index ee08d06..9a79314 100644 --- a/gcc/config/arm/arm-mve-builtins-base.def +++ b/gcc/config/arm/arm-mve-builtins-base.def @@ -28,6 +28,8 @@ DEF_MVE_FUNCTION (vaddvaq, unary_int32_acc, all_integer, p_or_none) DEF_MVE_FUNCTION (vaddvq, unary_int32, all_integer, p_or_none) DEF_MVE_FUNCTION (vandq, binary, all_integer, mx_or_none) DEF_MVE_FUNCTION (vbrsrq, binary_imm32, all_integer, mx_or_none) +DEF_MVE_FUNCTION (vcaddq_rot90, binary, all_integer, mx_or_none) +DEF_MVE_FUNCTION (vcaddq_rot270, binary, all_integer, mx_or_none) DEF_MVE_FUNCTION (vclsq, unary, all_signed, mx_or_none) DEF_MVE_FUNCTION (vclzq, unary, all_integer, mx_or_none) DEF_MVE_FUNCTION (vcmpcsq, cmp, all_unsigned, m_or_none) @@ -42,6 +44,8 @@ DEF_MVE_FUNCTION (vcreateq, create, all_integer_with_64, none) DEF_MVE_FUNCTION (vdupq, unary_n, all_integer, mx_or_none) DEF_MVE_FUNCTION (veorq, binary, all_integer, mx_or_none) DEF_MVE_FUNCTION (vhaddq, binary_opt_n, all_integer, mx_or_none) +DEF_MVE_FUNCTION (vhcaddq_rot90, binary, all_signed, mx_or_none) +DEF_MVE_FUNCTION (vhcaddq_rot270, binary, all_signed, mx_or_none) DEF_MVE_FUNCTION (vhsubq, binary_opt_n, all_integer, mx_or_none) DEF_MVE_FUNCTION (vmaxaq, binary_maxamina, all_signed, m_or_none) DEF_MVE_FUNCTION (vmaxavq, binary_maxavminav, all_signed, p_or_none) @@ -152,6 +156,8 @@ DEF_MVE_FUNCTION (vabsq, unary, all_float, mx_or_none) DEF_MVE_FUNCTION (vaddq, binary_opt_n, all_float, mx_or_none) DEF_MVE_FUNCTION (vandq, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vbrsrq, binary_imm32, all_float, mx_or_none) +DEF_MVE_FUNCTION (vcaddq_rot90, binary, all_float, mx_or_none) +DEF_MVE_FUNCTION (vcaddq_rot270, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vcmpeqq, cmp, all_float, m_or_none) DEF_MVE_FUNCTION (vcmpgeq, cmp, all_float, m_or_none) DEF_MVE_FUNCTION (vcmpgtq, cmp, all_float, m_or_none) diff --git a/gcc/config/arm/arm-mve-builtins-base.h b/gcc/config/arm/arm-mve-builtins-base.h index 942c858..8dac729 100644 --- a/gcc/config/arm/arm-mve-builtins-base.h +++ b/gcc/config/arm/arm-mve-builtins-base.h @@ -33,6 +33,8 @@ extern const function_base *const vaddvaq; extern const function_base *const vaddvq; extern const function_base *const vandq; extern const function_base *const vbrsrq; +extern const function_base *const vcaddq_rot90; +extern const function_base *const vcaddq_rot270; extern const function_base *const vclsq; extern const function_base *const vclzq; extern const function_base *const vcmpcsq; @@ -50,6 +52,8 @@ extern const function_base *const vfmaq; extern const function_base *const vfmasq; extern const function_base *const vfmsq; extern const function_base *const vhaddq; +extern const function_base *const vhcaddq_rot90; +extern const function_base *const vhcaddq_rot270; extern const function_base *const vhsubq; extern const function_base *const vmaxaq; extern const function_base *const vmaxavq; diff --git a/gcc/config/arm/arm-mve-builtins-functions.h b/gcc/config/arm/arm-mve-builtins-functions.h index 8f3bae4..a657384 100644 --- a/gcc/config/arm/arm-mve-builtins-functions.h +++ b/gcc/config/arm/arm-mve-builtins-functions.h @@ -735,6 +735,109 @@ public: } }; +/* Map the function directly to CODE (UNSPEC, UNSPEC, UNSPEC, M) where + M is the vector mode associated with type suffix 0. USed for the + operations where there is a "rot90" or "rot270" suffix, depending + on the UNSPEC. */ +class unspec_mve_function_exact_insn_rot : public function_base +{ +public: + CONSTEXPR unspec_mve_function_exact_insn_rot (int unspec_for_sint, + int unspec_for_uint, + int unspec_for_fp, + int unspec_for_m_sint, + int unspec_for_m_uint, + int unspec_for_m_fp) + : m_unspec_for_sint (unspec_for_sint), + m_unspec_for_uint (unspec_for_uint), + m_unspec_for_fp (unspec_for_fp), + m_unspec_for_m_sint (unspec_for_m_sint), + m_unspec_for_m_uint (unspec_for_m_uint), + m_unspec_for_m_fp (unspec_for_m_fp) + {} + + /* The unspec code associated with signed-integer, unsigned-integer + and floating-point operations respectively. It covers the cases + with and without the _m predicate. */ + int m_unspec_for_sint; + int m_unspec_for_uint; + int m_unspec_for_fp; + int m_unspec_for_m_sint; + int m_unspec_for_m_uint; + int m_unspec_for_m_fp; + + rtx + expand (function_expander &e) const override + { + insn_code code; + + switch (e.pred) + { + case PRED_none: + switch (e.mode_suffix_id) + { + case MODE_none: + /* No predicate, no suffix. */ + if (e.type_suffix (0).integer_p) + if (e.type_suffix (0).unsigned_p) + code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, m_unspec_for_uint, e.vector_mode (0)); + else + code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, m_unspec_for_sint, e.vector_mode (0)); + else + code = code_for_mve_q_f (m_unspec_for_fp, m_unspec_for_fp, e.vector_mode (0)); + break; + + default: + gcc_unreachable (); + } + return e.use_exact_insn (code); + + case PRED_m: + switch (e.mode_suffix_id) + { + case MODE_none: + /* No suffix, "m" predicate. */ + if (e.type_suffix (0).integer_p) + if (e.type_suffix (0).unsigned_p) + code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0)); + else + code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0)); + else + code = code_for_mve_q_m_f (m_unspec_for_m_fp, m_unspec_for_m_fp, e.vector_mode (0)); + break; + + default: + gcc_unreachable (); + } + return e.use_cond_insn (code, 0); + + case PRED_x: + switch (e.mode_suffix_id) + { + case MODE_none: + /* No suffix, "x" predicate. */ + if (e.type_suffix (0).integer_p) + if (e.type_suffix (0).unsigned_p) + code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0)); + else + code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0)); + else + code = code_for_mve_q_m_f (m_unspec_for_m_fp, m_unspec_for_m_fp, e.vector_mode (0)); + break; + + default: + gcc_unreachable (); + } + return e.use_pred_x_insn (code); + + default: + gcc_unreachable (); + } + + gcc_unreachable (); + } +}; + } /* end namespace arm_mve */ /* Declare the global function base NAME, creating it from an instance diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h index 30485e7..9297ad7 100644 --- a/gcc/config/arm/arm_mve.h +++ b/gcc/config/arm/arm_mve.h @@ -45,20 +45,12 @@ #define vornq(__a, __b) __arm_vornq(__a, __b) #define vmulltq_int(__a, __b) __arm_vmulltq_int(__a, __b) #define vmullbq_int(__a, __b) __arm_vmullbq_int(__a, __b) -#define vcaddq_rot90(__a, __b) __arm_vcaddq_rot90(__a, __b) -#define vcaddq_rot270(__a, __b) __arm_vcaddq_rot270(__a, __b) #define vbicq(__a, __b) __arm_vbicq(__a, __b) -#define vhcaddq_rot90(__a, __b) __arm_vhcaddq_rot90(__a, __b) -#define vhcaddq_rot270(__a, __b) __arm_vhcaddq_rot270(__a, __b) #define vmulltq_poly(__a, __b) __arm_vmulltq_poly(__a, __b) #define vmullbq_poly(__a, __b) __arm_vmullbq_poly(__a, __b) #define vbicq_m_n(__a, __imm, __p) __arm_vbicq_m_n(__a, __imm, __p) #define vshlcq(__a, __b, __imm) __arm_vshlcq(__a, __b, __imm) #define vbicq_m(__inactive, __a, __b, __p) __arm_vbicq_m(__inactive, __a, __b, __p) -#define vcaddq_rot270_m(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m(__inactive, __a, __b, __p) -#define vcaddq_rot90_m(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m(__inactive, __a, __b, __p) -#define vhcaddq_rot270_m(__inactive, __a, __b, __p) __arm_vhcaddq_rot270_m(__inactive, __a, __b, __p) -#define vhcaddq_rot90_m(__inactive, __a, __b, __p) __arm_vhcaddq_rot90_m(__inactive, __a, __b, __p) #define vmullbq_int_m(__inactive, __a, __b, __p) __arm_vmullbq_int_m(__inactive, __a, __b, __p) #define vmulltq_int_m(__inactive, __a, __b, __p) __arm_vmulltq_int_m(__inactive, __a, __b, __p) #define vornq_m(__inactive, __a, __b, __p) __arm_vornq_m(__inactive, __a, __b, __p) @@ -141,10 +133,6 @@ #define vmullbq_int_x(__a, __b, __p) __arm_vmullbq_int_x(__a, __b, __p) #define vmulltq_poly_x(__a, __b, __p) __arm_vmulltq_poly_x(__a, __b, __p) #define vmulltq_int_x(__a, __b, __p) __arm_vmulltq_int_x(__a, __b, __p) -#define vcaddq_rot90_x(__a, __b, __p) __arm_vcaddq_rot90_x(__a, __b, __p) -#define vcaddq_rot270_x(__a, __b, __p) __arm_vcaddq_rot270_x(__a, __b, __p) -#define vhcaddq_rot90_x(__a, __b, __p) __arm_vhcaddq_rot90_x(__a, __b, __p) -#define vhcaddq_rot270_x(__a, __b, __p) __arm_vhcaddq_rot270_x(__a, __b, __p) #define vbicq_x(__a, __b, __p) __arm_vbicq_x(__a, __b, __p) #define vornq_x(__a, __b, __p) __arm_vornq_x(__a, __b, __p) #define vadciq(__a, __b, __carry_out) __arm_vadciq(__a, __b, __carry_out) @@ -249,44 +237,26 @@ #define vornq_u8(__a, __b) __arm_vornq_u8(__a, __b) #define vmulltq_int_u8(__a, __b) __arm_vmulltq_int_u8(__a, __b) #define vmullbq_int_u8(__a, __b) __arm_vmullbq_int_u8(__a, __b) -#define vcaddq_rot90_u8(__a, __b) __arm_vcaddq_rot90_u8(__a, __b) -#define vcaddq_rot270_u8(__a, __b) __arm_vcaddq_rot270_u8(__a, __b) #define vbicq_u8(__a, __b) __arm_vbicq_u8(__a, __b) #define vornq_s8(__a, __b) __arm_vornq_s8(__a, __b) #define vmulltq_int_s8(__a, __b) __arm_vmulltq_int_s8(__a, __b) #define vmullbq_int_s8(__a, __b) __arm_vmullbq_int_s8(__a, __b) -#define vhcaddq_rot90_s8(__a, __b) __arm_vhcaddq_rot90_s8(__a, __b) -#define vhcaddq_rot270_s8(__a, __b) __arm_vhcaddq_rot270_s8(__a, __b) -#define vcaddq_rot90_s8(__a, __b) __arm_vcaddq_rot90_s8(__a, __b) -#define vcaddq_rot270_s8(__a, __b) __arm_vcaddq_rot270_s8(__a, __b) #define vbicq_s8(__a, __b) __arm_vbicq_s8(__a, __b) #define vornq_u16(__a, __b) __arm_vornq_u16(__a, __b) #define vmulltq_int_u16(__a, __b) __arm_vmulltq_int_u16(__a, __b) #define vmullbq_int_u16(__a, __b) __arm_vmullbq_int_u16(__a, __b) -#define vcaddq_rot90_u16(__a, __b) __arm_vcaddq_rot90_u16(__a, __b) -#define vcaddq_rot270_u16(__a, __b) __arm_vcaddq_rot270_u16(__a, __b) #define vbicq_u16(__a, __b) __arm_vbicq_u16(__a, __b) #define vornq_s16(__a, __b) __arm_vornq_s16(__a, __b) #define vmulltq_int_s16(__a, __b) __arm_vmulltq_int_s16(__a, __b) #define vmullbq_int_s16(__a, __b) __arm_vmullbq_int_s16(__a, __b) -#define vhcaddq_rot90_s16(__a, __b) __arm_vhcaddq_rot90_s16(__a, __b) -#define vhcaddq_rot270_s16(__a, __b) __arm_vhcaddq_rot270_s16(__a, __b) -#define vcaddq_rot90_s16(__a, __b) __arm_vcaddq_rot90_s16(__a, __b) -#define vcaddq_rot270_s16(__a, __b) __arm_vcaddq_rot270_s16(__a, __b) #define vbicq_s16(__a, __b) __arm_vbicq_s16(__a, __b) #define vornq_u32(__a, __b) __arm_vornq_u32(__a, __b) #define vmulltq_int_u32(__a, __b) __arm_vmulltq_int_u32(__a, __b) #define vmullbq_int_u32(__a, __b) __arm_vmullbq_int_u32(__a, __b) -#define vcaddq_rot90_u32(__a, __b) __arm_vcaddq_rot90_u32(__a, __b) -#define vcaddq_rot270_u32(__a, __b) __arm_vcaddq_rot270_u32(__a, __b) #define vbicq_u32(__a, __b) __arm_vbicq_u32(__a, __b) #define vornq_s32(__a, __b) __arm_vornq_s32(__a, __b) #define vmulltq_int_s32(__a, __b) __arm_vmulltq_int_s32(__a, __b) #define vmullbq_int_s32(__a, __b) __arm_vmullbq_int_s32(__a, __b) -#define vhcaddq_rot90_s32(__a, __b) __arm_vhcaddq_rot90_s32(__a, __b) -#define vhcaddq_rot270_s32(__a, __b) __arm_vhcaddq_rot270_s32(__a, __b) -#define vcaddq_rot90_s32(__a, __b) __arm_vcaddq_rot90_s32(__a, __b) -#define vcaddq_rot270_s32(__a, __b) __arm_vcaddq_rot270_s32(__a, __b) #define vbicq_s32(__a, __b) __arm_vbicq_s32(__a, __b) #define vmulltq_poly_p8(__a, __b) __arm_vmulltq_poly_p8(__a, __b) #define vmullbq_poly_p8(__a, __b) __arm_vmullbq_poly_p8(__a, __b) @@ -296,8 +266,6 @@ #define vcmulq_rot270_f16(__a, __b) __arm_vcmulq_rot270_f16(__a, __b) #define vcmulq_rot180_f16(__a, __b) __arm_vcmulq_rot180_f16(__a, __b) #define vcmulq_f16(__a, __b) __arm_vcmulq_f16(__a, __b) -#define vcaddq_rot90_f16(__a, __b) __arm_vcaddq_rot90_f16(__a, __b) -#define vcaddq_rot270_f16(__a, __b) __arm_vcaddq_rot270_f16(__a, __b) #define vbicq_f16(__a, __b) __arm_vbicq_f16(__a, __b) #define vbicq_n_s16(__a, __imm) __arm_vbicq_n_s16(__a, __imm) #define vmulltq_poly_p16(__a, __b) __arm_vmulltq_poly_p16(__a, __b) @@ -308,8 +276,6 @@ #define vcmulq_rot270_f32(__a, __b) __arm_vcmulq_rot270_f32(__a, __b) #define vcmulq_rot180_f32(__a, __b) __arm_vcmulq_rot180_f32(__a, __b) #define vcmulq_f32(__a, __b) __arm_vcmulq_f32(__a, __b) -#define vcaddq_rot90_f32(__a, __b) __arm_vcaddq_rot90_f32(__a, __b) -#define vcaddq_rot270_f32(__a, __b) __arm_vcaddq_rot270_f32(__a, __b) #define vbicq_f32(__a, __b) __arm_vbicq_f32(__a, __b) #define vbicq_n_s32(__a, __imm) __arm_vbicq_n_s32(__a, __imm) #define vctp8q_m(__a, __p) __arm_vctp8q_m(__a, __p) @@ -374,24 +340,6 @@ #define vbicq_m_u8(__inactive, __a, __b, __p) __arm_vbicq_m_u8(__inactive, __a, __b, __p) #define vbicq_m_u32(__inactive, __a, __b, __p) __arm_vbicq_m_u32(__inactive, __a, __b, __p) #define vbicq_m_u16(__inactive, __a, __b, __p) __arm_vbicq_m_u16(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_s8(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_s8(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_s32(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_s32(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_s16(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_s16(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_u8(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_u8(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_u32(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_u32(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_u16(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_u16(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_s8(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_s8(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_s32(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_s32(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_s16(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_s16(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_u8(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_u8(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_u32(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_u32(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_u16(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_u16(__inactive, __a, __b, __p) -#define vhcaddq_rot270_m_s8(__inactive, __a, __b, __p) __arm_vhcaddq_rot270_m_s8(__inactive, __a, __b, __p) -#define vhcaddq_rot270_m_s32(__inactive, __a, __b, __p) __arm_vhcaddq_rot270_m_s32(__inactive, __a, __b, __p) -#define vhcaddq_rot270_m_s16(__inactive, __a, __b, __p) __arm_vhcaddq_rot270_m_s16(__inactive, __a, __b, __p) -#define vhcaddq_rot90_m_s8(__inactive, __a, __b, __p) __arm_vhcaddq_rot90_m_s8(__inactive, __a, __b, __p) -#define vhcaddq_rot90_m_s32(__inactive, __a, __b, __p) __arm_vhcaddq_rot90_m_s32(__inactive, __a, __b, __p) -#define vhcaddq_rot90_m_s16(__inactive, __a, __b, __p) __arm_vhcaddq_rot90_m_s16(__inactive, __a, __b, __p) #define vmullbq_int_m_s8(__inactive, __a, __b, __p) __arm_vmullbq_int_m_s8(__inactive, __a, __b, __p) #define vmullbq_int_m_s32(__inactive, __a, __b, __p) __arm_vmullbq_int_m_s32(__inactive, __a, __b, __p) #define vmullbq_int_m_s16(__inactive, __a, __b, __p) __arm_vmullbq_int_m_s16(__inactive, __a, __b, __p) @@ -416,10 +364,6 @@ #define vmulltq_poly_m_p16(__inactive, __a, __b, __p) __arm_vmulltq_poly_m_p16(__inactive, __a, __b, __p) #define vbicq_m_f32(__inactive, __a, __b, __p) __arm_vbicq_m_f32(__inactive, __a, __b, __p) #define vbicq_m_f16(__inactive, __a, __b, __p) __arm_vbicq_m_f16(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_f32(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_f32(__inactive, __a, __b, __p) -#define vcaddq_rot270_m_f16(__inactive, __a, __b, __p) __arm_vcaddq_rot270_m_f16(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_f32(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_f32(__inactive, __a, __b, __p) -#define vcaddq_rot90_m_f16(__inactive, __a, __b, __p) __arm_vcaddq_rot90_m_f16(__inactive, __a, __b, __p) #define vcmlaq_m_f32(__a, __b, __c, __p) __arm_vcmlaq_m_f32(__a, __b, __c, __p) #define vcmlaq_m_f16(__a, __b, __c, __p) __arm_vcmlaq_m_f16(__a, __b, __c, __p) #define vcmlaq_rot180_m_f32(__a, __b, __c, __p) __arm_vcmlaq_rot180_m_f32(__a, __b, __c, __p) @@ -756,24 +700,6 @@ #define vmulltq_int_x_u8(__a, __b, __p) __arm_vmulltq_int_x_u8(__a, __b, __p) #define vmulltq_int_x_u16(__a, __b, __p) __arm_vmulltq_int_x_u16(__a, __b, __p) #define vmulltq_int_x_u32(__a, __b, __p) __arm_vmulltq_int_x_u32(__a, __b, __p) -#define vcaddq_rot90_x_s8(__a, __b, __p) __arm_vcaddq_rot90_x_s8(__a, __b, __p) -#define vcaddq_rot90_x_s16(__a, __b, __p) __arm_vcaddq_rot90_x_s16(__a, __b, __p) -#define vcaddq_rot90_x_s32(__a, __b, __p) __arm_vcaddq_rot90_x_s32(__a, __b, __p) -#define vcaddq_rot90_x_u8(__a, __b, __p) __arm_vcaddq_rot90_x_u8(__a, __b, __p) -#define vcaddq_rot90_x_u16(__a, __b, __p) __arm_vcaddq_rot90_x_u16(__a, __b, __p) -#define vcaddq_rot90_x_u32(__a, __b, __p) __arm_vcaddq_rot90_x_u32(__a, __b, __p) -#define vcaddq_rot270_x_s8(__a, __b, __p) __arm_vcaddq_rot270_x_s8(__a, __b, __p) -#define vcaddq_rot270_x_s16(__a, __b, __p) __arm_vcaddq_rot270_x_s16(__a, __b, __p) -#define vcaddq_rot270_x_s32(__a, __b, __p) __arm_vcaddq_rot270_x_s32(__a, __b, __p) -#define vcaddq_rot270_x_u8(__a, __b, __p) __arm_vcaddq_rot270_x_u8(__a, __b, __p) -#define vcaddq_rot270_x_u16(__a, __b, __p) __arm_vcaddq_rot270_x_u16(__a, __b, __p) -#define vcaddq_rot270_x_u32(__a, __b, __p) __arm_vcaddq_rot270_x_u32(__a, __b, __p) -#define vhcaddq_rot90_x_s8(__a, __b, __p) __arm_vhcaddq_rot90_x_s8(__a, __b, __p) -#define vhcaddq_rot90_x_s16(__a, __b, __p) __arm_vhcaddq_rot90_x_s16(__a, __b, __p) -#define vhcaddq_rot90_x_s32(__a, __b, __p) __arm_vhcaddq_rot90_x_s32(__a, __b, __p) -#define vhcaddq_rot270_x_s8(__a, __b, __p) __arm_vhcaddq_rot270_x_s8(__a, __b, __p) -#define vhcaddq_rot270_x_s16(__a, __b, __p) __arm_vhcaddq_rot270_x_s16(__a, __b, __p) -#define vhcaddq_rot270_x_s32(__a, __b, __p) __arm_vhcaddq_rot270_x_s32(__a, __b, __p) #define vbicq_x_s8(__a, __b, __p) __arm_vbicq_x_s8(__a, __b, __p) #define vbicq_x_s16(__a, __b, __p) __arm_vbicq_x_s16(__a, __b, __p) #define vbicq_x_s32(__a, __b, __p) __arm_vbicq_x_s32(__a, __b, __p) @@ -786,10 +712,6 @@ #define vornq_x_u8(__a, __b, __p) __arm_vornq_x_u8(__a, __b, __p) #define vornq_x_u16(__a, __b, __p) __arm_vornq_x_u16(__a, __b, __p) #define vornq_x_u32(__a, __b, __p) __arm_vornq_x_u32(__a, __b, __p) -#define vcaddq_rot90_x_f16(__a, __b, __p) __arm_vcaddq_rot90_x_f16(__a, __b, __p) -#define vcaddq_rot90_x_f32(__a, __b, __p) __arm_vcaddq_rot90_x_f32(__a, __b, __p) -#define vcaddq_rot270_x_f16(__a, __b, __p) __arm_vcaddq_rot270_x_f16(__a, __b, __p) -#define vcaddq_rot270_x_f32(__a, __b, __p) __arm_vcaddq_rot270_x_f32(__a, __b, __p) #define vcmulq_x_f16(__a, __b, __p) __arm_vcmulq_x_f16(__a, __b, __p) #define vcmulq_x_f32(__a, __b, __p) __arm_vcmulq_x_f32(__a, __b, __p) #define vcmulq_rot90_x_f16(__a, __b, __p) __arm_vcmulq_rot90_x_f16(__a, __b, __p) @@ -1060,22 +982,6 @@ __arm_vmullbq_int_u8 (uint8x16_t __a, uint8x16_t __b) __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_u8 (uint8x16_t __a, uint8x16_t __b) -{ - return (uint8x16_t) - __builtin_mve_vcaddq_rot90v16qi ((int8x16_t)__a, (int8x16_t)__b); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_u8 (uint8x16_t __a, uint8x16_t __b) -{ - return (uint8x16_t) - __builtin_mve_vcaddq_rot270v16qi ((int8x16_t)__a, (int8x16_t)__b); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_u8 (uint8x16_t __a, uint8x16_t __b) { return __builtin_mve_vbicq_uv16qi (__a, __b); @@ -1104,34 +1010,6 @@ __arm_vmullbq_int_s8 (int8x16_t __a, int8x16_t __b) __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_s8 (int8x16_t __a, int8x16_t __b) -{ - return __builtin_mve_vhcaddq_rot90_sv16qi (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_s8 (int8x16_t __a, int8x16_t __b) -{ - return __builtin_mve_vhcaddq_rot270_sv16qi (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_s8 (int8x16_t __a, int8x16_t __b) -{ - return __builtin_mve_vcaddq_rot90v16qi (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_s8 (int8x16_t __a, int8x16_t __b) -{ - return __builtin_mve_vcaddq_rot270v16qi (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_s8 (int8x16_t __a, int8x16_t __b) { return __builtin_mve_vbicq_sv16qi (__a, __b); @@ -1160,22 +1038,6 @@ __arm_vmullbq_int_u16 (uint16x8_t __a, uint16x8_t __b) __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_u16 (uint16x8_t __a, uint16x8_t __b) -{ - return (uint16x8_t) - __builtin_mve_vcaddq_rot90v8hi ((int16x8_t)__a, (int16x8_t)__b); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_u16 (uint16x8_t __a, uint16x8_t __b) -{ - return (uint16x8_t) - __builtin_mve_vcaddq_rot270v8hi ((int16x8_t)__a, (int16x8_t)__b); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_u16 (uint16x8_t __a, uint16x8_t __b) { return __builtin_mve_vbicq_uv8hi (__a, __b); @@ -1204,34 +1066,6 @@ __arm_vmullbq_int_s16 (int16x8_t __a, int16x8_t __b) __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_s16 (int16x8_t __a, int16x8_t __b) -{ - return __builtin_mve_vhcaddq_rot90_sv8hi (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_s16 (int16x8_t __a, int16x8_t __b) -{ - return __builtin_mve_vhcaddq_rot270_sv8hi (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_s16 (int16x8_t __a, int16x8_t __b) -{ - return __builtin_mve_vcaddq_rot90v8hi (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_s16 (int16x8_t __a, int16x8_t __b) -{ - return __builtin_mve_vcaddq_rot270v8hi (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_s16 (int16x8_t __a, int16x8_t __b) { return __builtin_mve_vbicq_sv8hi (__a, __b); @@ -1260,22 +1094,6 @@ __arm_vmullbq_int_u32 (uint32x4_t __a, uint32x4_t __b) __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_u32 (uint32x4_t __a, uint32x4_t __b) -{ - return (uint32x4_t) - __builtin_mve_vcaddq_rot90v4si ((int32x4_t)__a, (int32x4_t)__b); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_u32 (uint32x4_t __a, uint32x4_t __b) -{ - return (uint32x4_t) - __builtin_mve_vcaddq_rot270v4si ((int32x4_t)__a, (int32x4_t)__b); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_u32 (uint32x4_t __a, uint32x4_t __b) { return __builtin_mve_vbicq_uv4si (__a, __b); @@ -1304,34 +1122,6 @@ __arm_vmullbq_int_s32 (int32x4_t __a, int32x4_t __b) __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_s32 (int32x4_t __a, int32x4_t __b) -{ - return __builtin_mve_vhcaddq_rot90_sv4si (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_s32 (int32x4_t __a, int32x4_t __b) -{ - return __builtin_mve_vhcaddq_rot270_sv4si (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_s32 (int32x4_t __a, int32x4_t __b) -{ - return __builtin_mve_vcaddq_rot90v4si (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_s32 (int32x4_t __a, int32x4_t __b) -{ - return __builtin_mve_vcaddq_rot270v4si (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_s32 (int32x4_t __a, int32x4_t __b) { return __builtin_mve_vbicq_sv4si (__a, __b); @@ -1545,132 +1335,6 @@ __arm_vbicq_m_u16 (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pr return __builtin_mve_vbicq_m_uv8hi (__inactive, __a, __b, __p); } -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_s8 (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_sv16qi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_sv4si (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_s16 (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_sv8hi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_u8 (uint8x16_t __inactive, uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_uv16qi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_u32 (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_uv4si (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_u16 (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_uv8hi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_s8 (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_sv16qi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_sv4si (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_s16 (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_sv8hi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_u8 (uint8x16_t __inactive, uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_uv16qi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_u32 (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_uv4si (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_u16 (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_uv8hi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_m_s8 (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vhcaddq_rot270_m_sv16qi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vhcaddq_rot270_m_sv4si (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_m_s16 (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vhcaddq_rot270_m_sv8hi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_m_s8 (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vhcaddq_rot90_m_sv16qi (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vhcaddq_rot90_m_sv4si (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_m_s16 (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vhcaddq_rot90_m_sv8hi (__inactive, __a, __b, __p); -} - __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vmullbq_int_m_s8 (int16x8_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) @@ -3850,281 +3514,155 @@ __arm_vmulltq_int_x_u32 (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vbicq_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot90_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); + return __builtin_mve_vbicq_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); } __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vbicq_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot90_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); + return __builtin_mve_vbicq_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) +__arm_vbicq_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot90_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); + return __builtin_mve_vbicq_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_u8 (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) +__arm_vbicq_x_u8 (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot90_m_uv16qi (__arm_vuninitializedq_u8 (), __a, __b, __p); + return __builtin_mve_vbicq_m_uv16qi (__arm_vuninitializedq_u8 (), __a, __b, __p); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_u16 (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) +__arm_vbicq_x_u16 (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot90_m_uv8hi (__arm_vuninitializedq_u16 (), __a, __b, __p); + return __builtin_mve_vbicq_m_uv8hi (__arm_vuninitializedq_u16 (), __a, __b, __p); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_u32 (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) +__arm_vbicq_x_u32 (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot90_m_uv4si (__arm_vuninitializedq_u32 (), __a, __b, __p); + return __builtin_mve_vbicq_m_uv4si (__arm_vuninitializedq_u32 (), __a, __b, __p); } __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vornq_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot270_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); + return __builtin_mve_vornq_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); } __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vornq_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot270_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); + return __builtin_mve_vornq_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) +__arm_vornq_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot270_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); + return __builtin_mve_vornq_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_u8 (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) +__arm_vornq_x_u8 (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot270_m_uv16qi (__arm_vuninitializedq_u8 (), __a, __b, __p); + return __builtin_mve_vornq_m_uv16qi (__arm_vuninitializedq_u8 (), __a, __b, __p); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_u16 (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) +__arm_vornq_x_u16 (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot270_m_uv8hi (__arm_vuninitializedq_u16 (), __a, __b, __p); + return __builtin_mve_vornq_m_uv8hi (__arm_vuninitializedq_u16 (), __a, __b, __p); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_u32 (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) +__arm_vornq_x_u32 (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) { - return __builtin_mve_vcaddq_rot270_m_uv4si (__arm_vuninitializedq_u32 (), __a, __b, __p); + return __builtin_mve_vornq_m_uv4si (__arm_vuninitializedq_u32 (), __a, __b, __p); } -__extension__ extern __inline int8x16_t +__extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vadciq_s32 (int32x4_t __a, int32x4_t __b, unsigned * __carry_out) { - return __builtin_mve_vhcaddq_rot90_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); + int32x4_t __res = __builtin_mve_vadciq_sv4si (__a, __b); + *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; + return __res; } -__extension__ extern __inline int16x8_t +__extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vadciq_u32 (uint32x4_t __a, uint32x4_t __b, unsigned * __carry_out) { - return __builtin_mve_vhcaddq_rot90_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); + uint32x4_t __res = __builtin_mve_vadciq_uv4si (__a, __b); + *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; + return __res; } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vhcaddq_rot90_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vadciq_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, unsigned * __carry_out, mve_pred16_t __p) { - return __builtin_mve_vhcaddq_rot270_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); + int32x4_t __res = __builtin_mve_vadciq_m_sv4si (__inactive, __a, __b, __p); + *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; + return __res; } -__extension__ extern __inline int16x8_t +__extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vadciq_m_u32 (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, unsigned * __carry_out, mve_pred16_t __p) { - return __builtin_mve_vhcaddq_rot270_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); + uint32x4_t __res = __builtin_mve_vadciq_m_uv4si (__inactive, __a, __b, __p); + *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; + return __res; } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) +__arm_vadcq_s32 (int32x4_t __a, int32x4_t __b, unsigned * __carry) { - return __builtin_mve_vhcaddq_rot270_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); + __builtin_arm_set_fpscr_nzcvqc((__builtin_arm_get_fpscr_nzcvqc () & ~0x20000000u) | ((*__carry & 0x1u) << 29)); + int32x4_t __res = __builtin_mve_vadcq_sv4si (__a, __b); + *__carry = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; + return __res; } -__extension__ extern __inline int8x16_t +__extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vadcq_u32 (uint32x4_t __a, uint32x4_t __b, unsigned * __carry) { - return __builtin_mve_vbicq_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); + __builtin_arm_set_fpscr_nzcvqc((__builtin_arm_get_fpscr_nzcvqc () & ~0x20000000u) | ((*__carry & 0x1u) << 29)); + uint32x4_t __res = __builtin_mve_vadcq_uv4si (__a, __b); + *__carry = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; + return __res; } -__extension__ extern __inline int16x8_t +__extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vadcq_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, unsigned * __carry, mve_pred16_t __p) { - return __builtin_mve_vbicq_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); + __builtin_arm_set_fpscr_nzcvqc((__builtin_arm_get_fpscr_nzcvqc () & ~0x20000000u) | ((*__carry & 0x1u) << 29)); + int32x4_t __res = __builtin_mve_vadcq_m_sv4si (__inactive, __a, __b, __p); + *__carry = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; + return __res; } -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vbicq_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_x_u8 (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vbicq_m_uv16qi (__arm_vuninitializedq_u8 (), __a, __b, __p); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_x_u16 (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vbicq_m_uv8hi (__arm_vuninitializedq_u16 (), __a, __b, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_x_u32 (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vbicq_m_uv4si (__arm_vuninitializedq_u32 (), __a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vornq_x_s8 (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vornq_m_sv16qi (__arm_vuninitializedq_s8 (), __a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vornq_x_s16 (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vornq_m_sv8hi (__arm_vuninitializedq_s16 (), __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vornq_x_s32 (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vornq_m_sv4si (__arm_vuninitializedq_s32 (), __a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vornq_x_u8 (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vornq_m_uv16qi (__arm_vuninitializedq_u8 (), __a, __b, __p); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vornq_x_u16 (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vornq_m_uv8hi (__arm_vuninitializedq_u16 (), __a, __b, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vornq_x_u32 (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vornq_m_uv4si (__arm_vuninitializedq_u32 (), __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vadciq_s32 (int32x4_t __a, int32x4_t __b, unsigned * __carry_out) -{ - int32x4_t __res = __builtin_mve_vadciq_sv4si (__a, __b); - *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; - return __res; -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vadciq_u32 (uint32x4_t __a, uint32x4_t __b, unsigned * __carry_out) -{ - uint32x4_t __res = __builtin_mve_vadciq_uv4si (__a, __b); - *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; - return __res; -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vadciq_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, unsigned * __carry_out, mve_pred16_t __p) -{ - int32x4_t __res = __builtin_mve_vadciq_m_sv4si (__inactive, __a, __b, __p); - *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; - return __res; -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vadciq_m_u32 (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, unsigned * __carry_out, mve_pred16_t __p) -{ - uint32x4_t __res = __builtin_mve_vadciq_m_uv4si (__inactive, __a, __b, __p); - *__carry_out = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; - return __res; -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vadcq_s32 (int32x4_t __a, int32x4_t __b, unsigned * __carry) -{ - __builtin_arm_set_fpscr_nzcvqc((__builtin_arm_get_fpscr_nzcvqc () & ~0x20000000u) | ((*__carry & 0x1u) << 29)); - int32x4_t __res = __builtin_mve_vadcq_sv4si (__a, __b); - *__carry = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; - return __res; -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vadcq_u32 (uint32x4_t __a, uint32x4_t __b, unsigned * __carry) -{ - __builtin_arm_set_fpscr_nzcvqc((__builtin_arm_get_fpscr_nzcvqc () & ~0x20000000u) | ((*__carry & 0x1u) << 29)); - uint32x4_t __res = __builtin_mve_vadcq_uv4si (__a, __b); - *__carry = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; - return __res; -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vadcq_m_s32 (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, unsigned * __carry, mve_pred16_t __p) -{ - __builtin_arm_set_fpscr_nzcvqc((__builtin_arm_get_fpscr_nzcvqc () & ~0x20000000u) | ((*__carry & 0x1u) << 29)); - int32x4_t __res = __builtin_mve_vadcq_m_sv4si (__inactive, __a, __b, __p); - *__carry = (__builtin_arm_get_fpscr_nzcvqc () >> 29) & 0x1u; - return __res; -} - -__extension__ extern __inline uint32x4_t +__extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vadcq_m_u32 (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, unsigned * __carry, mve_pred16_t __p) { @@ -5053,20 +4591,6 @@ __arm_vcmulq_f16 (float16x8_t __a, float16x8_t __b) __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_f16 (float16x8_t __a, float16x8_t __b) -{ - return __builtin_mve_vcaddq_rot90v8hf (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_f16 (float16x8_t __a, float16x8_t __b) -{ - return __builtin_mve_vcaddq_rot270v8hf (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_f16 (float16x8_t __a, float16x8_t __b) { return __builtin_mve_vbicq_fv8hf (__a, __b); @@ -5109,20 +4633,6 @@ __arm_vcmulq_f32 (float32x4_t __a, float32x4_t __b) __extension__ extern __inline float32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_f32 (float32x4_t __a, float32x4_t __b) -{ - return __builtin_mve_vcaddq_rot90v4sf (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_f32 (float32x4_t __a, float32x4_t __b) -{ - return __builtin_mve_vcaddq_rot270v4sf (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_f32 (float32x4_t __a, float32x4_t __b) { return __builtin_mve_vbicq_fv4sf (__a, __b); @@ -5439,34 +4949,6 @@ __arm_vbicq_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve __extension__ extern __inline float32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_f32 (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_fv4sf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_fv8hf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_f32 (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_fv4sf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_fv8hf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcmlaq_m_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) { return __builtin_mve_vcmlaq_m_fv4sf (__a, __b, __c, __p); @@ -5879,34 +5361,6 @@ __arm_vstrwq_scatter_base_wb_p_f32 (uint32x4_t * __addr, const int __offset, flo __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_f16 (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_fv8hf (__arm_vuninitializedq_f16 (), __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x_f32 (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot90_m_fv4sf (__arm_vuninitializedq_f32 (), __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_f16 (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_fv8hf (__arm_vuninitializedq_f16 (), __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x_f32 (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcaddq_rot270_m_fv4sf (__arm_vuninitializedq_f32 (), __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcmulq_x_f16 (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) { return __builtin_mve_vcmulq_m_fv8hf (__arm_vuninitializedq_f16 (), __a, __b, __p); @@ -6410,20 +5864,6 @@ __arm_vmullbq_int (uint8x16_t __a, uint8x16_t __b) __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (uint8x16_t __a, uint8x16_t __b) -{ - return __arm_vcaddq_rot90_u8 (__a, __b); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (uint8x16_t __a, uint8x16_t __b) -{ - return __arm_vcaddq_rot270_u8 (__a, __b); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (uint8x16_t __a, uint8x16_t __b) { return __arm_vbicq_u8 (__a, __b); @@ -6452,34 +5892,6 @@ __arm_vmullbq_int (int8x16_t __a, int8x16_t __b) __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90 (int8x16_t __a, int8x16_t __b) -{ - return __arm_vhcaddq_rot90_s8 (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270 (int8x16_t __a, int8x16_t __b) -{ - return __arm_vhcaddq_rot270_s8 (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (int8x16_t __a, int8x16_t __b) -{ - return __arm_vcaddq_rot90_s8 (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (int8x16_t __a, int8x16_t __b) -{ - return __arm_vcaddq_rot270_s8 (__a, __b); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (int8x16_t __a, int8x16_t __b) { return __arm_vbicq_s8 (__a, __b); @@ -6508,20 +5920,6 @@ __arm_vmullbq_int (uint16x8_t __a, uint16x8_t __b) __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (uint16x8_t __a, uint16x8_t __b) -{ - return __arm_vcaddq_rot90_u16 (__a, __b); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (uint16x8_t __a, uint16x8_t __b) -{ - return __arm_vcaddq_rot270_u16 (__a, __b); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (uint16x8_t __a, uint16x8_t __b) { return __arm_vbicq_u16 (__a, __b); @@ -6550,34 +5948,6 @@ __arm_vmullbq_int (int16x8_t __a, int16x8_t __b) __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90 (int16x8_t __a, int16x8_t __b) -{ - return __arm_vhcaddq_rot90_s16 (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270 (int16x8_t __a, int16x8_t __b) -{ - return __arm_vhcaddq_rot270_s16 (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (int16x8_t __a, int16x8_t __b) -{ - return __arm_vcaddq_rot90_s16 (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (int16x8_t __a, int16x8_t __b) -{ - return __arm_vcaddq_rot270_s16 (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (int16x8_t __a, int16x8_t __b) { return __arm_vbicq_s16 (__a, __b); @@ -6606,20 +5976,6 @@ __arm_vmullbq_int (uint32x4_t __a, uint32x4_t __b) __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (uint32x4_t __a, uint32x4_t __b) -{ - return __arm_vcaddq_rot90_u32 (__a, __b); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (uint32x4_t __a, uint32x4_t __b) -{ - return __arm_vcaddq_rot270_u32 (__a, __b); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (uint32x4_t __a, uint32x4_t __b) { return __arm_vbicq_u32 (__a, __b); @@ -6648,34 +6004,6 @@ __arm_vmullbq_int (int32x4_t __a, int32x4_t __b) __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90 (int32x4_t __a, int32x4_t __b) -{ - return __arm_vhcaddq_rot90_s32 (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270 (int32x4_t __a, int32x4_t __b) -{ - return __arm_vhcaddq_rot270_s32 (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (int32x4_t __a, int32x4_t __b) -{ - return __arm_vcaddq_rot90_s32 (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (int32x4_t __a, int32x4_t __b) -{ - return __arm_vcaddq_rot270_s32 (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (int32x4_t __a, int32x4_t __b) { return __arm_vbicq_s32 (__a, __b); @@ -6751,228 +6079,102 @@ __arm_vbicq_m_n (int32x4_t __a, const int __imm, mve_pred16_t __p) return __arm_vbicq_m_n_s32 (__a, __imm, __p); } -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m_n (uint16x8_t __a, const int __imm, mve_pred16_t __p) -{ - return __arm_vbicq_m_n_u16 (__a, __imm, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m_n (uint32x4_t __a, const int __imm, mve_pred16_t __p) -{ - return __arm_vbicq_m_n_u32 (__a, __imm, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vshlcq (int8x16_t __a, uint32_t * __b, const int __imm) -{ - return __arm_vshlcq_s8 (__a, __b, __imm); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vshlcq (uint8x16_t __a, uint32_t * __b, const int __imm) -{ - return __arm_vshlcq_u8 (__a, __b, __imm); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vshlcq (int16x8_t __a, uint32_t * __b, const int __imm) -{ - return __arm_vshlcq_s16 (__a, __b, __imm); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vshlcq (uint16x8_t __a, uint32_t * __b, const int __imm) -{ - return __arm_vshlcq_u16 (__a, __b, __imm); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vshlcq (int32x4_t __a, uint32_t * __b, const int __imm) -{ - return __arm_vshlcq_s32 (__a, __b, __imm); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vshlcq (uint32x4_t __a, uint32_t * __b, const int __imm) -{ - return __arm_vshlcq_u32 (__a, __b, __imm); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __arm_vbicq_m_s8 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __arm_vbicq_m_s32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __arm_vbicq_m_s16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m (uint8x16_t __inactive, uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __arm_vbicq_m_u8 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) -{ - return __arm_vbicq_m_u32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vbicq_m (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) -{ - return __arm_vbicq_m_u16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_m_s8 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_m_s32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_m_s16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (uint8x16_t __inactive, uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_m_u8 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline uint32x4_t +__extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) +__arm_vbicq_m_n (uint16x8_t __a, const int __imm, mve_pred16_t __p) { - return __arm_vcaddq_rot270_m_u32 (__inactive, __a, __b, __p); + return __arm_vbicq_m_n_u16 (__a, __imm, __p); } -__extension__ extern __inline uint16x8_t +__extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) +__arm_vbicq_m_n (uint32x4_t __a, const int __imm, mve_pred16_t __p) { - return __arm_vcaddq_rot270_m_u16 (__inactive, __a, __b, __p); + return __arm_vbicq_m_n_u32 (__a, __imm, __p); } __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vshlcq (int8x16_t __a, uint32_t * __b, const int __imm) { - return __arm_vcaddq_rot90_m_s8 (__inactive, __a, __b, __p); + return __arm_vshlcq_s8 (__a, __b, __imm); } -__extension__ extern __inline int32x4_t +__extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) +__arm_vshlcq (uint8x16_t __a, uint32_t * __b, const int __imm) { - return __arm_vcaddq_rot90_m_s32 (__inactive, __a, __b, __p); + return __arm_vshlcq_u8 (__a, __b, __imm); } __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vshlcq (int16x8_t __a, uint32_t * __b, const int __imm) { - return __arm_vcaddq_rot90_m_s16 (__inactive, __a, __b, __p); + return __arm_vshlcq_s16 (__a, __b, __imm); } -__extension__ extern __inline uint8x16_t +__extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (uint8x16_t __inactive, uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) +__arm_vshlcq (uint16x8_t __a, uint32_t * __b, const int __imm) { - return __arm_vcaddq_rot90_m_u8 (__inactive, __a, __b, __p); + return __arm_vshlcq_u16 (__a, __b, __imm); } -__extension__ extern __inline uint32x4_t +__extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) +__arm_vshlcq (int32x4_t __a, uint32_t * __b, const int __imm) { - return __arm_vcaddq_rot90_m_u32 (__inactive, __a, __b, __p); + return __arm_vshlcq_s32 (__a, __b, __imm); } -__extension__ extern __inline uint16x8_t +__extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) +__arm_vshlcq (uint32x4_t __a, uint32_t * __b, const int __imm) { - return __arm_vcaddq_rot90_m_u16 (__inactive, __a, __b, __p); + return __arm_vshlcq_u32 (__a, __b, __imm); } __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_m (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vbicq_m (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) { - return __arm_vhcaddq_rot270_m_s8 (__inactive, __a, __b, __p); + return __arm_vbicq_m_s8 (__inactive, __a, __b, __p); } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_m (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) +__arm_vbicq_m (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) { - return __arm_vhcaddq_rot270_m_s32 (__inactive, __a, __b, __p); + return __arm_vbicq_m_s32 (__inactive, __a, __b, __p); } __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_m (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vbicq_m (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) { - return __arm_vhcaddq_rot270_m_s16 (__inactive, __a, __b, __p); + return __arm_vbicq_m_s16 (__inactive, __a, __b, __p); } -__extension__ extern __inline int8x16_t +__extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_m (int8x16_t __inactive, int8x16_t __a, int8x16_t __b, mve_pred16_t __p) +__arm_vbicq_m (uint8x16_t __inactive, uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) { - return __arm_vhcaddq_rot90_m_s8 (__inactive, __a, __b, __p); + return __arm_vbicq_m_u8 (__inactive, __a, __b, __p); } -__extension__ extern __inline int32x4_t +__extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_m (int32x4_t __inactive, int32x4_t __a, int32x4_t __b, mve_pred16_t __p) +__arm_vbicq_m (uint32x4_t __inactive, uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) { - return __arm_vhcaddq_rot90_m_s32 (__inactive, __a, __b, __p); + return __arm_vbicq_m_u32 (__inactive, __a, __b, __p); } -__extension__ extern __inline int16x8_t +__extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_m (int16x8_t __inactive, int16x8_t __a, int16x8_t __b, mve_pred16_t __p) +__arm_vbicq_m (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) { - return __arm_vhcaddq_rot90_m_s16 (__inactive, __a, __b, __p); + return __arm_vbicq_m_u16 (__inactive, __a, __b, __p); } __extension__ extern __inline int16x8_t @@ -8727,132 +7929,6 @@ __arm_vmulltq_int_x (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_s8 (__a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_s16 (__a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_s32 (__a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_u8 (__a, __b, __p); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_u16 (__a, __b, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_u32 (__a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_s8 (__a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_s16 (__a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_s32 (__a, __b, __p); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (uint8x16_t __a, uint8x16_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_u8 (__a, __b, __p); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (uint16x8_t __a, uint16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_u16 (__a, __b, __p); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (uint32x4_t __a, uint32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_u32 (__a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_x (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __arm_vhcaddq_rot90_x_s8 (__a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_x (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __arm_vhcaddq_rot90_x_s16 (__a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot90_x (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __arm_vhcaddq_rot90_x_s32 (__a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_x (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) -{ - return __arm_vhcaddq_rot270_x_s8 (__a, __b, __p); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_x (int16x8_t __a, int16x8_t __b, mve_pred16_t __p) -{ - return __arm_vhcaddq_rot270_x_s16 (__a, __b, __p); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vhcaddq_rot270_x (int32x4_t __a, int32x4_t __b, mve_pred16_t __p) -{ - return __arm_vhcaddq_rot270_x_s32 (__a, __b, __p); -} - -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_x (int8x16_t __a, int8x16_t __b, mve_pred16_t __p) { return __arm_vbicq_x_s8 (__a, __b, __p); @@ -9534,20 +8610,6 @@ __arm_vcmulq (float16x8_t __a, float16x8_t __b) __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (float16x8_t __a, float16x8_t __b) -{ - return __arm_vcaddq_rot90_f16 (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (float16x8_t __a, float16x8_t __b) -{ - return __arm_vcaddq_rot270_f16 (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (float16x8_t __a, float16x8_t __b) { return __arm_vbicq_f16 (__a, __b); @@ -9590,20 +8652,6 @@ __arm_vcmulq (float32x4_t __a, float32x4_t __b) __extension__ extern __inline float32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90 (float32x4_t __a, float32x4_t __b) -{ - return __arm_vcaddq_rot90_f32 (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270 (float32x4_t __a, float32x4_t __b) -{ - return __arm_vcaddq_rot270_f32 (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (float32x4_t __a, float32x4_t __b) { return __arm_vbicq_f32 (__a, __b); @@ -9905,34 +8953,6 @@ __arm_vbicq_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pre __extension__ extern __inline float32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_m_f32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_m_f16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_m_f32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_m_f16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcmlaq_m (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) { return __arm_vcmlaq_m_f32 (__a, __b, __c, __p); @@ -10283,34 +9303,6 @@ __arm_vstrwq_scatter_base_wb_p (uint32x4_t * __addr, const int __offset, float32 __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_f16 (__a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot90_x (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot90_x_f32 (__a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_f16 (__a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcaddq_rot270_x (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcaddq_rot270_x_f32 (__a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcmulq_x (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) { return __arm_vcmulq_x_f16 (__a, __b, __p); @@ -10920,30 +9912,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vornq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vornq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) -#define __arm_vcaddq_rot270(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot270_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot270_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot270_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot270_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot270_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot270_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcaddq_rot270_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcaddq_rot270_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) - -#define __arm_vcaddq_rot90(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot90_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot90_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot90_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot90_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot90_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot90_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcaddq_rot90_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcaddq_rot90_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) - #define __arm_vcmulq(p0,p1) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ @@ -10990,20 +9958,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmulltq_int_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmulltq_int_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)));}) -#define __arm_vhcaddq_rot270(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot270_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot270_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot270_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));}) - -#define __arm_vhcaddq_rot90(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot90_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot90_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot90_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));}) - #define __arm_vmullbq_int(p0,p1) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ @@ -11139,32 +10093,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vbicq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vbicq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) -#define __arm_vcaddq_rot270_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot270_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot270_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot270_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot270_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot270_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot270_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcaddq_rot270_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcaddq_rot270_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcaddq_rot90_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot90_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot90_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot90_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot90_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot90_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot90_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcaddq_rot90_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcaddq_rot90_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - #define __arm_vcmlaq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ __typeof(p2) __p2 = (p2); \ @@ -11558,30 +10486,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vbicq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vbicq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) -#define __arm_vcaddq_rot270_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot270_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot270_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot270_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot270_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot270_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot270_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcaddq_rot270_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcaddq_rot270_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcaddq_rot90_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot90_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot90_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot90_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot90_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot90_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot90_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcaddq_rot90_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcaddq_rot90_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - #define __arm_vcmulq_rot180_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ __typeof(p2) __p2 = (p2); \ _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ @@ -11710,40 +10614,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmullbq_int_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmullbq_int_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)));}) -#define __arm_vhcaddq_rot90(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot90_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot90_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot90_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));}) - -#define __arm_vhcaddq_rot270(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot270_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot270_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot270_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));}) - -#define __arm_vcaddq_rot90(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot90_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot90_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot90_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot90_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot90_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot90_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)));}) - -#define __arm_vcaddq_rot270(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot270_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot270_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot270_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot270_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot270_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot270_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)));}) - #define __arm_vbicq(p0,p1) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ @@ -11797,28 +10667,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vbicq_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vbicq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));}) -#define __arm_vcaddq_rot270_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot270_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot270_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot270_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot270_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot270_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot270_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));}) - -#define __arm_vcaddq_rot90_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot90_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot90_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot90_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot90_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot90_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot90_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));}) - #define __arm_vornq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ __typeof(p2) __p2 = (p2); \ @@ -12067,26 +10915,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_uint32x4_t]: __arm_vuninitializedq_u32 (), \ int (*)[__ARM_mve_type_uint64x2_t]: __arm_vuninitializedq_u64 ());}) -#define __arm_vcaddq_rot270_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot270_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot270_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot270_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot270_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot270_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot270_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));}) - -#define __arm_vcaddq_rot90_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcaddq_rot90_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcaddq_rot90_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcaddq_rot90_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \ - int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcaddq_rot90_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \ - int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcaddq_rot90_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \ - int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcaddq_rot90_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));}) - #define __arm_vmullbq_int_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ __typeof(p2) __p2 = (p2); \ _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ @@ -12251,20 +11079,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_int_n]: __arm_vddupq_x_n_u32 ((uint32_t) __p1, p2, p3), \ int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vddupq_x_wb_u32 (__ARM_mve_coerce_u32_ptr(__p1, uint32_t *), p2, p3));}) -#define __arm_vhcaddq_rot270_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot270_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot270_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot270_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));}) - -#define __arm_vhcaddq_rot90_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot90_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot90_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot90_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));}) - #define __arm_vadciq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ @@ -12358,22 +11172,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_z_u16 (__ARM_mve_coerce_u8_ptr(p0, uint8_t *), __ARM_mve_coerce(__p1, uint16x8_t), p2), \ int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_z_u32 (__ARM_mve_coerce_u8_ptr(p0, uint8_t *), __ARM_mve_coerce(__p1, uint32x4_t), p2));}) -#define __arm_vhcaddq_rot270_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot270_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot270_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot270_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));}) - -#define __arm_vhcaddq_rot90_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhcaddq_rot90_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \ - int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhcaddq_rot90_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \ - int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhcaddq_rot90_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));}) - #define __arm_vmullbq_int_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ __typeof(p2) __p2 = (p2); \ -- cgit v1.1 From 0c5ba73aeb4fab4f1957e2e498848d9b78d33cab Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 12 Jul 2023 13:55:26 +0000 Subject: arm: [MVE intrinsics factorize vcmulq Factorize vcmulq builtins so that they use parameterized names. We can merged them with vcadd. 2023-07-13 Christophe Lyon gcc/: * config/arm/arm_mve_builtins.def (vcmulq_rot90_f) (vcmulq_rot270_f, vcmulq_rot180_f, vcmulq_f): Add "_f" suffix. * config/arm/iterators.md (MVE_VCADDQ_VCMULQ) (MVE_VCADDQ_VCMULQ_M): New. (mve_insn): Add vcmul. (rot): Add VCMULQ_M_F, VCMULQ_ROT90_M_F, VCMULQ_ROT180_M_F, VCMULQ_ROT270_M_F. (VCMUL): Delete. (mve_rot): Add VCMULQ_M_F, VCMULQ_ROT90_M_F, VCMULQ_ROT180_M_F, VCMULQ_ROT270_M_F. * config/arm/mve.md (mve_vcmulq): Merge into @mve_q_f. (mve_vcmulq_m_f, mve_vcmulq_rot180_m_f) (mve_vcmulq_rot270_m_f, mve_vcmulq_rot90_m_f): Merge into @mve_q_m_f. --- gcc/config/arm/arm_mve_builtins.def | 8 ++-- gcc/config/arm/iterators.md | 27 +++++++++-- gcc/config/arm/mve.md | 92 +++---------------------------------- 3 files changed, 33 insertions(+), 94 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arm/arm_mve_builtins.def b/gcc/config/arm/arm_mve_builtins.def index 63ad184..56358c0 100644 --- a/gcc/config/arm/arm_mve_builtins.def +++ b/gcc/config/arm/arm_mve_builtins.def @@ -191,6 +191,10 @@ VAR3 (BINOP_NONE_NONE_NONE, vcaddq_rot90_, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vcaddq_rot270_, v16qi, v8hi, v4si) VAR2 (BINOP_NONE_NONE_NONE, vcaddq_rot90_f, v8hf, v4sf) VAR2 (BINOP_NONE_NONE_NONE, vcaddq_rot270_f, v8hf, v4sf) +VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot90_f, v8hf, v4sf) +VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot270_f, v8hf, v4sf) +VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot180_f, v8hf, v4sf) +VAR2 (BINOP_NONE_NONE_NONE, vcmulq_f, v8hf, v4sf) VAR3 (BINOP_NONE_NONE_NONE, vhcaddq_rot90_s, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vhcaddq_rot270_s, v16qi, v8hi, v4si) VAR3 (BINOP_NONE_NONE_NONE, vhaddq_s, v16qi, v8hi, v4si) @@ -874,10 +878,6 @@ VAR3 (QUADOP_UNONE_UNONE_UNONE_IMM_PRED, vshlcq_m_vec_u, v16qi, v8hi, v4si) VAR3 (QUADOP_UNONE_UNONE_UNONE_IMM_PRED, vshlcq_m_carry_u, v16qi, v8hi, v4si) /* optabs without any suffixes. */ -VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot90, v8hf, v4sf) -VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot270, v8hf, v4sf) -VAR2 (BINOP_NONE_NONE_NONE, vcmulq_rot180, v8hf, v4sf) -VAR2 (BINOP_NONE_NONE_NONE, vcmulq, v8hf, v4sf) VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot90, v8hf, v4sf) VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot270, v8hf, v4sf) VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot180, v8hf, v4sf) diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index da1ead3..9f71404 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -901,8 +901,19 @@ VPSELQ_F ]) +(define_int_iterator MVE_VCADDQ_VCMULQ [ + UNSPEC_VCADD90 UNSPEC_VCADD270 + UNSPEC_VCMUL UNSPEC_VCMUL90 UNSPEC_VCMUL180 UNSPEC_VCMUL270 + ]) + +(define_int_iterator MVE_VCADDQ_VCMULQ_M [ + VCADDQ_ROT90_M_F VCADDQ_ROT270_M_F + VCMULQ_M_F VCMULQ_ROT90_M_F VCMULQ_ROT180_M_F VCMULQ_ROT270_M_F + ]) + (define_int_attr mve_insn [ (UNSPEC_VCADD90 "vcadd") (UNSPEC_VCADD270 "vcadd") + (UNSPEC_VCMUL "vcmul") (UNSPEC_VCMUL90 "vcmul") (UNSPEC_VCMUL180 "vcmul") (UNSPEC_VCMUL270 "vcmul") (VABAVQ_P_S "vabav") (VABAVQ_P_U "vabav") (VABAVQ_S "vabav") (VABAVQ_U "vabav") (VABDQ_M_S "vabd") (VABDQ_M_U "vabd") (VABDQ_M_F "vabd") @@ -931,6 +942,7 @@ (VCLSQ_M_S "vcls") (VCLSQ_S "vcls") (VCLZQ_M_S "vclz") (VCLZQ_M_U "vclz") + (VCMULQ_M_F "vcmul") (VCMULQ_ROT90_M_F "vcmul") (VCMULQ_ROT180_M_F "vcmul") (VCMULQ_ROT270_M_F "vcmul") (VCREATEQ_S "vcreate") (VCREATEQ_U "vcreate") (VCREATEQ_F "vcreate") (VDUPQ_M_N_S "vdup") (VDUPQ_M_N_U "vdup") (VDUPQ_M_N_F "vdup") (VDUPQ_N_S "vdup") (VDUPQ_N_U "vdup") (VDUPQ_N_F "vdup") @@ -2182,7 +2194,11 @@ (UNSPEC_VCMLA "0") (UNSPEC_VCMLA90 "90") (UNSPEC_VCMLA180 "180") - (UNSPEC_VCMLA270 "270")]) + (UNSPEC_VCMLA270 "270") + (VCMULQ_M_F "0") + (VCMULQ_ROT90_M_F "90") + (VCMULQ_ROT180_M_F "180") + (VCMULQ_ROT270_M_F "270")]) ;; The complex operations when performed on a real complex number require two ;; instructions to perform the operation. e.g. complex multiplication requires @@ -2230,10 +2246,11 @@ (UNSPEC_VCMUL "") (UNSPEC_VCMUL90 "_rot90") (UNSPEC_VCMUL180 "_rot180") - (UNSPEC_VCMUL270 "_rot270")]) - -(define_int_iterator VCMUL [UNSPEC_VCMUL UNSPEC_VCMUL90 - UNSPEC_VCMUL180 UNSPEC_VCMUL270]) + (UNSPEC_VCMUL270 "_rot270") + (VCMULQ_M_F "") + (VCMULQ_ROT90_M_F "_rot90") + (VCMULQ_ROT180_M_F "_rot180") + (VCMULQ_ROT270_M_F "_rot270")]) (define_int_attr fcmac1 [(UNSPEC_VCMLA "a") (UNSPEC_VCMLA_CONJ "a") (UNSPEC_VCMLA180 "s") (UNSPEC_VCMLA180_CONJ "s")]) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index a6db6d1..0b99bf0 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -1212,13 +1212,14 @@ ;; ;; [vcaddq_rot90_f, vcaddq_rot270_f] +;; [vcmulq, vcmulq_rot90, vcmulq_rot180, vcmulq_rot270] ;; (define_insn "@mve_q_f" [ (set (match_operand:MVE_0 0 "s_register_operand" "") (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w") (match_operand:MVE_0 2 "s_register_operand" "w")] - VCADD)) + MVE_VCADDQ_VCMULQ)) ] "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" ".f%#\t%q0, %q1, %q2, #" @@ -1255,21 +1256,6 @@ ]) ;; -;; [vcmulq, vcmulq_rot90, vcmulq_rot180, vcmulq_rot270]) -;; -(define_insn "mve_vcmulq" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w") - (match_operand:MVE_0 2 "s_register_operand" "w")] - VCMUL)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vcmul.f%# %q0, %q1, %q2, #" - [(set_attr "type" "mve_move") -]) - -;; ;; [vctp8q_m vctp16q_m vctp32q_m vctp64q_m]) ;; (define_insn "mve_vctpq_m" @@ -3174,6 +3160,10 @@ ;; ;; [vcaddq_rot90_m_f] ;; [vcaddq_rot270_m_f] +;; [vcmulq_m_f] +;; [vcmulq_rot90_m_f] +;; [vcmulq_rot180_m_f] +;; [vcmulq_rot270_m_f] ;; (define_insn "@mve_q_m_f" [ @@ -3182,7 +3172,7 @@ (match_operand:MVE_0 2 "s_register_operand" "w") (match_operand:MVE_0 3 "s_register_operand" "w") (match_operand: 4 "vpr_register_operand" "Up")] - VCADDQ_M_F)) + MVE_VCADDQ_VCMULQ_M)) ] "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" "vpst\;t.f%#\t%q0, %q2, %q3, #" @@ -3258,74 +3248,6 @@ (set_attr "length""8")]) ;; -;; [vcmulq_m_f]) -;; -(define_insn "mve_vcmulq_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCMULQ_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmult.f%# %q0, %q2, %q3, #0" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcmulq_rot180_m_f]) -;; -(define_insn "mve_vcmulq_rot180_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCMULQ_ROT180_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmult.f%# %q0, %q2, %q3, #180" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcmulq_rot270_m_f]) -;; -(define_insn "mve_vcmulq_rot270_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCMULQ_ROT270_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmult.f%# %q0, %q2, %q3, #270" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcmulq_rot90_m_f]) -;; -(define_insn "mve_vcmulq_rot90_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCMULQ_ROT90_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmult.f%# %q0, %q2, %q3, #90" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; ;; [vornq_m_f]) ;; (define_insn "mve_vornq_m_f" -- cgit v1.1 From a96e2dd12ce13ffeabd8b46adda7903557217c47 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 12 Jul 2023 14:35:29 +0000 Subject: arm: [MVE intrinsics] rework vcmulq Implement vcmulq using the new MVE builtins framework. 2023-07-13 Christophe Lyon gcc/ * config/arm/arm-mve-builtins-base.cc (vcmulq, vcmulq_rot90) (vcmulq_rot180, vcmulq_rot270): New. * config/arm/arm-mve-builtins-base.def (vcmulq, vcmulq_rot90) (vcmulq_rot180, vcmulq_rot270): New. * config/arm/arm-mve-builtins-base.h: (vcmulq, vcmulq_rot90) (vcmulq_rot180, vcmulq_rot270): New. * config/arm/arm_mve.h (vcmulq_rot90): Delete. (vcmulq_rot270): Delete. (vcmulq_rot180): Delete. (vcmulq): Delete. (vcmulq_m): Delete. (vcmulq_rot180_m): Delete. (vcmulq_rot270_m): Delete. (vcmulq_rot90_m): Delete. (vcmulq_x): Delete. (vcmulq_rot90_x): Delete. (vcmulq_rot180_x): Delete. (vcmulq_rot270_x): Delete. (vcmulq_rot90_f16): Delete. (vcmulq_rot270_f16): Delete. (vcmulq_rot180_f16): Delete. (vcmulq_f16): Delete. (vcmulq_rot90_f32): Delete. (vcmulq_rot270_f32): Delete. (vcmulq_rot180_f32): Delete. (vcmulq_f32): Delete. (vcmulq_m_f32): Delete. (vcmulq_m_f16): Delete. (vcmulq_rot180_m_f32): Delete. (vcmulq_rot180_m_f16): Delete. (vcmulq_rot270_m_f32): Delete. (vcmulq_rot270_m_f16): Delete. (vcmulq_rot90_m_f32): Delete. (vcmulq_rot90_m_f16): Delete. (vcmulq_x_f16): Delete. (vcmulq_x_f32): Delete. (vcmulq_rot90_x_f16): Delete. (vcmulq_rot90_x_f32): Delete. (vcmulq_rot180_x_f16): Delete. (vcmulq_rot180_x_f32): Delete. (vcmulq_rot270_x_f16): Delete. (vcmulq_rot270_x_f32): Delete. (__arm_vcmulq_rot90_f16): Delete. (__arm_vcmulq_rot270_f16): Delete. (__arm_vcmulq_rot180_f16): Delete. (__arm_vcmulq_f16): Delete. (__arm_vcmulq_rot90_f32): Delete. (__arm_vcmulq_rot270_f32): Delete. (__arm_vcmulq_rot180_f32): Delete. (__arm_vcmulq_f32): Delete. (__arm_vcmulq_m_f32): Delete. (__arm_vcmulq_m_f16): Delete. (__arm_vcmulq_rot180_m_f32): Delete. (__arm_vcmulq_rot180_m_f16): Delete. (__arm_vcmulq_rot270_m_f32): Delete. (__arm_vcmulq_rot270_m_f16): Delete. (__arm_vcmulq_rot90_m_f32): Delete. (__arm_vcmulq_rot90_m_f16): Delete. (__arm_vcmulq_x_f16): Delete. (__arm_vcmulq_x_f32): Delete. (__arm_vcmulq_rot90_x_f16): Delete. (__arm_vcmulq_rot90_x_f32): Delete. (__arm_vcmulq_rot180_x_f16): Delete. (__arm_vcmulq_rot180_x_f32): Delete. (__arm_vcmulq_rot270_x_f16): Delete. (__arm_vcmulq_rot270_x_f32): Delete. (__arm_vcmulq_rot90): Delete. (__arm_vcmulq_rot270): Delete. (__arm_vcmulq_rot180): Delete. (__arm_vcmulq): Delete. (__arm_vcmulq_m): Delete. (__arm_vcmulq_rot180_m): Delete. (__arm_vcmulq_rot270_m): Delete. (__arm_vcmulq_rot90_m): Delete. (__arm_vcmulq_x): Delete. (__arm_vcmulq_rot90_x): Delete. (__arm_vcmulq_rot180_x): Delete. (__arm_vcmulq_rot270_x): Delete. --- gcc/config/arm/arm-mve-builtins-base.cc | 4 + gcc/config/arm/arm-mve-builtins-base.def | 4 + gcc/config/arm/arm-mve-builtins-base.h | 4 + gcc/config/arm/arm_mve.h | 448 ------------------------------- 4 files changed, 12 insertions(+), 448 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm-mve-builtins-base.cc index f15bb92..3ad8df3 100644 --- a/gcc/config/arm/arm-mve-builtins-base.cc +++ b/gcc/config/arm/arm-mve-builtins-base.cc @@ -262,6 +262,10 @@ FUNCTION_WITH_RTX_M (vandq, AND, VANDQ) FUNCTION_ONLY_N (vbrsrq, VBRSRQ) FUNCTION (vcaddq_rot90, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD90, UNSPEC_VCADD90, UNSPEC_VCADD90, VCADDQ_ROT90_M_S, VCADDQ_ROT90_M_U, VCADDQ_ROT90_M_F)) FUNCTION (vcaddq_rot270, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD270, UNSPEC_VCADD270, UNSPEC_VCADD270, VCADDQ_ROT270_M_S, VCADDQ_ROT270_M_U, VCADDQ_ROT270_M_F)) +FUNCTION (vcmulq, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL, -1, -1, VCMULQ_M_F)) +FUNCTION (vcmulq_rot90, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL90, -1, -1, VCMULQ_ROT90_M_F)) +FUNCTION (vcmulq_rot180, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL180, -1, -1, VCMULQ_ROT180_M_F)) +FUNCTION (vcmulq_rot270, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL270, -1, -1, VCMULQ_ROT270_M_F)) FUNCTION (vhcaddq_rot90, unspec_mve_function_exact_insn_rot, (VHCADDQ_ROT90_S, -1, -1, VHCADDQ_ROT90_M_S, -1, -1)) FUNCTION (vhcaddq_rot270, unspec_mve_function_exact_insn_rot, (VHCADDQ_ROT270_S, -1, -1, VHCADDQ_ROT270_M_S, -1, -1)) FUNCTION_WITHOUT_N_NO_U_F (vclsq, VCLSQ) diff --git a/gcc/config/arm/arm-mve-builtins-base.def b/gcc/config/arm/arm-mve-builtins-base.def index 9a79314..cbcf0d2 100644 --- a/gcc/config/arm/arm-mve-builtins-base.def +++ b/gcc/config/arm/arm-mve-builtins-base.def @@ -158,6 +158,10 @@ DEF_MVE_FUNCTION (vandq, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vbrsrq, binary_imm32, all_float, mx_or_none) DEF_MVE_FUNCTION (vcaddq_rot90, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vcaddq_rot270, binary, all_float, mx_or_none) +DEF_MVE_FUNCTION (vcmulq, binary, all_float, mx_or_none) +DEF_MVE_FUNCTION (vcmulq_rot90, binary, all_float, mx_or_none) +DEF_MVE_FUNCTION (vcmulq_rot180, binary, all_float, mx_or_none) +DEF_MVE_FUNCTION (vcmulq_rot270, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vcmpeqq, cmp, all_float, m_or_none) DEF_MVE_FUNCTION (vcmpgeq, cmp, all_float, m_or_none) DEF_MVE_FUNCTION (vcmpgtq, cmp, all_float, m_or_none) diff --git a/gcc/config/arm/arm-mve-builtins-base.h b/gcc/config/arm/arm-mve-builtins-base.h index 8dac729..875b333 100644 --- a/gcc/config/arm/arm-mve-builtins-base.h +++ b/gcc/config/arm/arm-mve-builtins-base.h @@ -35,6 +35,10 @@ extern const function_base *const vandq; extern const function_base *const vbrsrq; extern const function_base *const vcaddq_rot90; extern const function_base *const vcaddq_rot270; +extern const function_base *const vcmulq; +extern const function_base *const vcmulq_rot90; +extern const function_base *const vcmulq_rot180; +extern const function_base *const vcmulq_rot270; extern const function_base *const vclsq; extern const function_base *const vclzq; extern const function_base *const vcmpcsq; diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h index 9297ad7..b9d3a87 100644 --- a/gcc/config/arm/arm_mve.h +++ b/gcc/config/arm/arm_mve.h @@ -155,10 +155,6 @@ #define vcvtbq_f32(__a) __arm_vcvtbq_f32(__a) #define vcvtq(__a) __arm_vcvtq(__a) #define vcvtq_n(__a, __imm6) __arm_vcvtq_n(__a, __imm6) -#define vcmulq_rot90(__a, __b) __arm_vcmulq_rot90(__a, __b) -#define vcmulq_rot270(__a, __b) __arm_vcmulq_rot270(__a, __b) -#define vcmulq_rot180(__a, __b) __arm_vcmulq_rot180(__a, __b) -#define vcmulq(__a, __b) __arm_vcmulq(__a, __b) #define vcvtaq_m(__inactive, __a, __p) __arm_vcvtaq_m(__inactive, __a, __p) #define vcvtq_m(__inactive, __a, __p) __arm_vcvtq_m(__inactive, __a, __p) #define vcvtbq_m(__a, __b, __p) __arm_vcvtbq_m(__a, __b, __p) @@ -175,14 +171,6 @@ #define vcmlaq_rot180_m(__a, __b, __c, __p) __arm_vcmlaq_rot180_m(__a, __b, __c, __p) #define vcmlaq_rot270_m(__a, __b, __c, __p) __arm_vcmlaq_rot270_m(__a, __b, __c, __p) #define vcmlaq_rot90_m(__a, __b, __c, __p) __arm_vcmlaq_rot90_m(__a, __b, __c, __p) -#define vcmulq_m(__inactive, __a, __b, __p) __arm_vcmulq_m(__inactive, __a, __b, __p) -#define vcmulq_rot180_m(__inactive, __a, __b, __p) __arm_vcmulq_rot180_m(__inactive, __a, __b, __p) -#define vcmulq_rot270_m(__inactive, __a, __b, __p) __arm_vcmulq_rot270_m(__inactive, __a, __b, __p) -#define vcmulq_rot90_m(__inactive, __a, __b, __p) __arm_vcmulq_rot90_m(__inactive, __a, __b, __p) -#define vcmulq_x(__a, __b, __p) __arm_vcmulq_x(__a, __b, __p) -#define vcmulq_rot90_x(__a, __b, __p) __arm_vcmulq_rot90_x(__a, __b, __p) -#define vcmulq_rot180_x(__a, __b, __p) __arm_vcmulq_rot180_x(__a, __b, __p) -#define vcmulq_rot270_x(__a, __b, __p) __arm_vcmulq_rot270_x(__a, __b, __p) #define vcvtq_x(__a, __p) __arm_vcvtq_x(__a, __p) #define vcvtq_x_n(__a, __imm6, __p) __arm_vcvtq_x_n(__a, __imm6, __p) @@ -262,20 +250,12 @@ #define vmullbq_poly_p8(__a, __b) __arm_vmullbq_poly_p8(__a, __b) #define vbicq_n_u16(__a, __imm) __arm_vbicq_n_u16(__a, __imm) #define vornq_f16(__a, __b) __arm_vornq_f16(__a, __b) -#define vcmulq_rot90_f16(__a, __b) __arm_vcmulq_rot90_f16(__a, __b) -#define vcmulq_rot270_f16(__a, __b) __arm_vcmulq_rot270_f16(__a, __b) -#define vcmulq_rot180_f16(__a, __b) __arm_vcmulq_rot180_f16(__a, __b) -#define vcmulq_f16(__a, __b) __arm_vcmulq_f16(__a, __b) #define vbicq_f16(__a, __b) __arm_vbicq_f16(__a, __b) #define vbicq_n_s16(__a, __imm) __arm_vbicq_n_s16(__a, __imm) #define vmulltq_poly_p16(__a, __b) __arm_vmulltq_poly_p16(__a, __b) #define vmullbq_poly_p16(__a, __b) __arm_vmullbq_poly_p16(__a, __b) #define vbicq_n_u32(__a, __imm) __arm_vbicq_n_u32(__a, __imm) #define vornq_f32(__a, __b) __arm_vornq_f32(__a, __b) -#define vcmulq_rot90_f32(__a, __b) __arm_vcmulq_rot90_f32(__a, __b) -#define vcmulq_rot270_f32(__a, __b) __arm_vcmulq_rot270_f32(__a, __b) -#define vcmulq_rot180_f32(__a, __b) __arm_vcmulq_rot180_f32(__a, __b) -#define vcmulq_f32(__a, __b) __arm_vcmulq_f32(__a, __b) #define vbicq_f32(__a, __b) __arm_vbicq_f32(__a, __b) #define vbicq_n_s32(__a, __imm) __arm_vbicq_n_s32(__a, __imm) #define vctp8q_m(__a, __p) __arm_vctp8q_m(__a, __p) @@ -372,14 +352,6 @@ #define vcmlaq_rot270_m_f16(__a, __b, __c, __p) __arm_vcmlaq_rot270_m_f16(__a, __b, __c, __p) #define vcmlaq_rot90_m_f32(__a, __b, __c, __p) __arm_vcmlaq_rot90_m_f32(__a, __b, __c, __p) #define vcmlaq_rot90_m_f16(__a, __b, __c, __p) __arm_vcmlaq_rot90_m_f16(__a, __b, __c, __p) -#define vcmulq_m_f32(__inactive, __a, __b, __p) __arm_vcmulq_m_f32(__inactive, __a, __b, __p) -#define vcmulq_m_f16(__inactive, __a, __b, __p) __arm_vcmulq_m_f16(__inactive, __a, __b, __p) -#define vcmulq_rot180_m_f32(__inactive, __a, __b, __p) __arm_vcmulq_rot180_m_f32(__inactive, __a, __b, __p) -#define vcmulq_rot180_m_f16(__inactive, __a, __b, __p) __arm_vcmulq_rot180_m_f16(__inactive, __a, __b, __p) -#define vcmulq_rot270_m_f32(__inactive, __a, __b, __p) __arm_vcmulq_rot270_m_f32(__inactive, __a, __b, __p) -#define vcmulq_rot270_m_f16(__inactive, __a, __b, __p) __arm_vcmulq_rot270_m_f16(__inactive, __a, __b, __p) -#define vcmulq_rot90_m_f32(__inactive, __a, __b, __p) __arm_vcmulq_rot90_m_f32(__inactive, __a, __b, __p) -#define vcmulq_rot90_m_f16(__inactive, __a, __b, __p) __arm_vcmulq_rot90_m_f16(__inactive, __a, __b, __p) #define vcvtq_m_n_s32_f32(__inactive, __a, __imm6, __p) __arm_vcvtq_m_n_s32_f32(__inactive, __a, __imm6, __p) #define vcvtq_m_n_s16_f16(__inactive, __a, __imm6, __p) __arm_vcvtq_m_n_s16_f16(__inactive, __a, __imm6, __p) #define vcvtq_m_n_u32_f32(__inactive, __a, __imm6, __p) __arm_vcvtq_m_n_u32_f32(__inactive, __a, __imm6, __p) @@ -712,14 +684,6 @@ #define vornq_x_u8(__a, __b, __p) __arm_vornq_x_u8(__a, __b, __p) #define vornq_x_u16(__a, __b, __p) __arm_vornq_x_u16(__a, __b, __p) #define vornq_x_u32(__a, __b, __p) __arm_vornq_x_u32(__a, __b, __p) -#define vcmulq_x_f16(__a, __b, __p) __arm_vcmulq_x_f16(__a, __b, __p) -#define vcmulq_x_f32(__a, __b, __p) __arm_vcmulq_x_f32(__a, __b, __p) -#define vcmulq_rot90_x_f16(__a, __b, __p) __arm_vcmulq_rot90_x_f16(__a, __b, __p) -#define vcmulq_rot90_x_f32(__a, __b, __p) __arm_vcmulq_rot90_x_f32(__a, __b, __p) -#define vcmulq_rot180_x_f16(__a, __b, __p) __arm_vcmulq_rot180_x_f16(__a, __b, __p) -#define vcmulq_rot180_x_f32(__a, __b, __p) __arm_vcmulq_rot180_x_f32(__a, __b, __p) -#define vcmulq_rot270_x_f16(__a, __b, __p) __arm_vcmulq_rot270_x_f16(__a, __b, __p) -#define vcmulq_rot270_x_f32(__a, __b, __p) __arm_vcmulq_rot270_x_f32(__a, __b, __p) #define vcvtaq_x_s16_f16(__a, __p) __arm_vcvtaq_x_s16_f16(__a, __p) #define vcvtaq_x_s32_f32(__a, __p) __arm_vcvtaq_x_s32_f32(__a, __p) #define vcvtaq_x_u16_f16(__a, __p) __arm_vcvtaq_x_u16_f16(__a, __p) @@ -4563,34 +4527,6 @@ __arm_vornq_f16 (float16x8_t __a, float16x8_t __b) __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_f16 (float16x8_t __a, float16x8_t __b) -{ - return __builtin_mve_vcmulq_rot90v8hf (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_f16 (float16x8_t __a, float16x8_t __b) -{ - return __builtin_mve_vcmulq_rot270v8hf (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_f16 (float16x8_t __a, float16x8_t __b) -{ - return __builtin_mve_vcmulq_rot180v8hf (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_f16 (float16x8_t __a, float16x8_t __b) -{ - return __builtin_mve_vcmulqv8hf (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_f16 (float16x8_t __a, float16x8_t __b) { return __builtin_mve_vbicq_fv8hf (__a, __b); @@ -4605,34 +4541,6 @@ __arm_vornq_f32 (float32x4_t __a, float32x4_t __b) __extension__ extern __inline float32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_f32 (float32x4_t __a, float32x4_t __b) -{ - return __builtin_mve_vcmulq_rot90v4sf (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_f32 (float32x4_t __a, float32x4_t __b) -{ - return __builtin_mve_vcmulq_rot270v4sf (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_f32 (float32x4_t __a, float32x4_t __b) -{ - return __builtin_mve_vcmulq_rot180v4sf (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_f32 (float32x4_t __a, float32x4_t __b) -{ - return __builtin_mve_vcmulqv4sf (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq_f32 (float32x4_t __a, float32x4_t __b) { return __builtin_mve_vbicq_fv4sf (__a, __b); @@ -5003,62 +4911,6 @@ __arm_vcmlaq_rot90_m_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve return __builtin_mve_vcmlaq_rot90_m_fv8hf (__a, __b, __c, __p); } -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_m_f32 (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_m_fv4sf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_m_fv8hf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_m_f32 (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot180_m_fv4sf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot180_m_fv8hf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_m_f32 (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot270_m_fv4sf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot270_m_fv8hf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_m_f32 (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot90_m_fv4sf (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot90_m_fv8hf (__inactive, __a, __b, __p); -} - __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtq_m_n_s32_f32 (int32x4_t __inactive, float32x4_t __a, const int __imm6, mve_pred16_t __p) @@ -5359,62 +5211,6 @@ __arm_vstrwq_scatter_base_wb_p_f32 (uint32x4_t * __addr, const int __offset, flo *__addr = __builtin_mve_vstrwq_scatter_base_wb_p_fv4sf (*__addr, __offset, __value, __p); } -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_x_f16 (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_m_fv8hf (__arm_vuninitializedq_f16 (), __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_x_f32 (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_m_fv4sf (__arm_vuninitializedq_f32 (), __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_x_f16 (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot90_m_fv8hf (__arm_vuninitializedq_f16 (), __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_x_f32 (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot90_m_fv4sf (__arm_vuninitializedq_f32 (), __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_x_f16 (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot180_m_fv8hf (__arm_vuninitializedq_f16 (), __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_x_f32 (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot180_m_fv4sf (__arm_vuninitializedq_f32 (), __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_x_f16 (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot270_m_fv8hf (__arm_vuninitializedq_f16 (), __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_x_f32 (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __builtin_mve_vcmulq_rot270_m_fv4sf (__arm_vuninitializedq_f32 (), __a, __b, __p); -} - __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtaq_x_s16_f16 (float16x8_t __a, mve_pred16_t __p) @@ -8582,34 +8378,6 @@ __arm_vornq (float16x8_t __a, float16x8_t __b) __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90 (float16x8_t __a, float16x8_t __b) -{ - return __arm_vcmulq_rot90_f16 (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270 (float16x8_t __a, float16x8_t __b) -{ - return __arm_vcmulq_rot270_f16 (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180 (float16x8_t __a, float16x8_t __b) -{ - return __arm_vcmulq_rot180_f16 (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq (float16x8_t __a, float16x8_t __b) -{ - return __arm_vcmulq_f16 (__a, __b); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (float16x8_t __a, float16x8_t __b) { return __arm_vbicq_f16 (__a, __b); @@ -8624,34 +8392,6 @@ __arm_vornq (float32x4_t __a, float32x4_t __b) __extension__ extern __inline float32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90 (float32x4_t __a, float32x4_t __b) -{ - return __arm_vcmulq_rot90_f32 (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270 (float32x4_t __a, float32x4_t __b) -{ - return __arm_vcmulq_rot270_f32 (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180 (float32x4_t __a, float32x4_t __b) -{ - return __arm_vcmulq_rot180_f32 (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq (float32x4_t __a, float32x4_t __b) -{ - return __arm_vcmulq_f32 (__a, __b); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vbicq (float32x4_t __a, float32x4_t __b) { return __arm_vbicq_f32 (__a, __b); @@ -9007,62 +8747,6 @@ __arm_vcmlaq_rot90_m (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pre return __arm_vcmlaq_rot90_m_f16 (__a, __b, __c, __p); } -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_m (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_m_f32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_m_f16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_m (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot180_m_f32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot180_m_f16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_m (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot270_m_f32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot270_m_f16 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_m (float32x4_t __inactive, float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot90_m_f32 (__inactive, __a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot90_m_f16 (__inactive, __a, __b, __p); -} - __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtq_m_n (int32x4_t __inactive, float32x4_t __a, const int __imm6, mve_pred16_t __p) @@ -9303,62 +8987,6 @@ __arm_vstrwq_scatter_base_wb_p (uint32x4_t * __addr, const int __offset, float32 __extension__ extern __inline float16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_x (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_x_f16 (__a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_x (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_x_f32 (__a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_x (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot90_x_f16 (__a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot90_x (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot90_x_f32 (__a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_x (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot180_x_f16 (__a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot180_x (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot180_x_f32 (__a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_x (float16x8_t __a, float16x8_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot270_x_f16 (__a, __b, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmulq_rot270_x (float32x4_t __a, float32x4_t __b, mve_pred16_t __p) -{ - return __arm_vcmulq_rot270_x_f32 (__a, __b, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtq_x (uint16x8_t __a, mve_pred16_t __p) { return __arm_vcvtq_x_f16_u16 (__a, __p); @@ -9912,30 +9540,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vornq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vornq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) -#define __arm_vcmulq(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) - -#define __arm_vcmulq_rot180(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot180_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot180_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) - -#define __arm_vcmulq_rot270(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot270_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot270_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) - -#define __arm_vcmulq_rot90(p0,p1) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot90_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot90_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)));}) - #define __arm_vmulltq_poly(p0,p1) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ @@ -10121,34 +9725,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_rot90_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_rot90_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) -#define __arm_vcmulq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmulq_rot180_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot180_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot180_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmulq_rot270_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot270_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot270_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmulq_rot90_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)] [__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot90_m_f16(__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot90_m_f32(__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - #define __arm_vornq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ __typeof(p2) __p2 = (p2); \ @@ -10486,24 +10062,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vbicq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vbicq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) -#define __arm_vcmulq_rot180_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot180_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot180_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmulq_rot270_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot270_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot270_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmulq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - #define __arm_vcvtq_x(p1,p2) ({ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(__p1)])0, \ int (*)[__ARM_mve_type_int16x8_t]: __arm_vcvtq_x_f16_s16 (__ARM_mve_coerce(__p1, int16x8_t), p2), \ @@ -10530,12 +10088,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vornq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vornq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) -#define __arm_vcmulq_rot90_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmulq_rot90_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmulq_rot90_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - #define __arm_vgetq_lane(p0,p1) ({ __typeof(p0) __p0 = (p0); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \ int (*)[__ARM_mve_type_int8x16_t]: __arm_vgetq_lane_s8 (__ARM_mve_coerce(__p0, int8x16_t), p1), \ -- cgit v1.1 From 6ae2fba5602fe473c0f7584e0f29ca918fd863e6 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 12 Jul 2023 16:02:59 +0000 Subject: arm: [MVE intrinsics] factorize vcmlaq Factorize vcmlaq builtins so that they use parameterized names. 2023-17-13 Christophe Lyon gcc/ * config/arm/arm_mve_builtins.def (vcmlaq_rot90_f) (vcmlaq_rot270_f, vcmlaq_rot180_f, vcmlaq_f): Add "_f" suffix. * config/arm/iterators.md (MVE_VCMLAQ_M): New. (mve_insn): Add vcmla. (rot): Add VCMLAQ_M_F, VCMLAQ_ROT90_M_F, VCMLAQ_ROT180_M_F, VCMLAQ_ROT270_M_F. (mve_rot): Add VCMLAQ_M_F, VCMLAQ_ROT90_M_F, VCMLAQ_ROT180_M_F, VCMLAQ_ROT270_M_F. * config/arm/mve.md (mve_vcmlaq): Rename into ... (@mve_q_f): ... this. (mve_vcmlaq_m_f, mve_vcmlaq_rot180_m_f) (mve_vcmlaq_rot270_m_f, mve_vcmlaq_rot90_m_f): Merge into ... (@mve_q_m_f): ... this. --- gcc/config/arm/arm_mve_builtins.def | 10 +++--- gcc/config/arm/iterators.md | 19 +++++++++-- gcc/config/arm/mve.md | 64 +++++-------------------------------- 3 files changed, 29 insertions(+), 64 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arm/arm_mve_builtins.def b/gcc/config/arm/arm_mve_builtins.def index 56358c0..43dacc3 100644 --- a/gcc/config/arm/arm_mve_builtins.def +++ b/gcc/config/arm/arm_mve_builtins.def @@ -378,6 +378,10 @@ VAR3 (TERNOP_NONE_NONE_NONE_NONE, vmlasq_n_s, v16qi, v8hi, v4si) VAR3 (TERNOP_NONE_NONE_NONE_NONE, vmlaq_n_s, v16qi, v8hi, v4si) VAR3 (TERNOP_NONE_NONE_NONE_NONE, vmladavaxq_s, v16qi, v8hi, v4si) VAR3 (TERNOP_NONE_NONE_NONE_NONE, vmladavaq_s, v16qi, v8hi, v4si) +VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot90_f, v8hf, v4sf) +VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot270_f, v8hf, v4sf) +VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot180_f, v8hf, v4sf) +VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_f, v8hf, v4sf) VAR3 (TERNOP_NONE_NONE_NONE_IMM, vsriq_n_s, v16qi, v8hi, v4si) VAR3 (TERNOP_NONE_NONE_NONE_IMM, vsliq_n_s, v16qi, v8hi, v4si) VAR2 (TERNOP_UNONE_UNONE_UNONE_PRED, vrev32q_m_u, v16qi, v8hi) @@ -876,9 +880,3 @@ VAR3 (QUADOP_NONE_NONE_UNONE_IMM_PRED, vshlcq_m_vec_s, v16qi, v8hi, v4si) VAR3 (QUADOP_NONE_NONE_UNONE_IMM_PRED, vshlcq_m_carry_s, v16qi, v8hi, v4si) VAR3 (QUADOP_UNONE_UNONE_UNONE_IMM_PRED, vshlcq_m_vec_u, v16qi, v8hi, v4si) VAR3 (QUADOP_UNONE_UNONE_UNONE_IMM_PRED, vshlcq_m_carry_u, v16qi, v8hi, v4si) - -/* optabs without any suffixes. */ -VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot90, v8hf, v4sf) -VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot270, v8hf, v4sf) -VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq_rot180, v8hf, v4sf) -VAR2 (TERNOP_NONE_NONE_NONE_NONE, vcmlaq, v8hf, v4sf) diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 9f71404..b13ff53 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -911,6 +911,10 @@ VCMULQ_M_F VCMULQ_ROT90_M_F VCMULQ_ROT180_M_F VCMULQ_ROT270_M_F ]) +(define_int_iterator MVE_VCMLAQ_M [ + VCMLAQ_M_F VCMLAQ_ROT90_M_F VCMLAQ_ROT180_M_F VCMLAQ_ROT270_M_F + ]) + (define_int_attr mve_insn [ (UNSPEC_VCADD90 "vcadd") (UNSPEC_VCADD270 "vcadd") (UNSPEC_VCMUL "vcmul") (UNSPEC_VCMUL90 "vcmul") (UNSPEC_VCMUL180 "vcmul") (UNSPEC_VCMUL270 "vcmul") @@ -942,6 +946,7 @@ (VCLSQ_M_S "vcls") (VCLSQ_S "vcls") (VCLZQ_M_S "vclz") (VCLZQ_M_U "vclz") + (VCMLAQ_M_F "vcmla") (VCMLAQ_ROT90_M_F "vcmla") (VCMLAQ_ROT180_M_F "vcmla") (VCMLAQ_ROT270_M_F "vcmla") (VCMULQ_M_F "vcmul") (VCMULQ_ROT90_M_F "vcmul") (VCMULQ_ROT180_M_F "vcmul") (VCMULQ_ROT270_M_F "vcmul") (VCREATEQ_S "vcreate") (VCREATEQ_U "vcreate") (VCREATEQ_F "vcreate") (VDUPQ_M_N_S "vdup") (VDUPQ_M_N_U "vdup") (VDUPQ_M_N_F "vdup") @@ -1204,6 +1209,7 @@ (VSUBQ_M_N_S "vsub") (VSUBQ_M_N_U "vsub") (VSUBQ_M_N_F "vsub") (VSUBQ_M_S "vsub") (VSUBQ_M_U "vsub") (VSUBQ_M_F "vsub") (VSUBQ_N_S "vsub") (VSUBQ_N_U "vsub") (VSUBQ_N_F "vsub") + (UNSPEC_VCMLA "vcmla") (UNSPEC_VCMLA90 "vcmla") (UNSPEC_VCMLA180 "vcmla") (UNSPEC_VCMLA270 "vcmla") ]) (define_int_attr isu [ @@ -2198,7 +2204,12 @@ (VCMULQ_M_F "0") (VCMULQ_ROT90_M_F "90") (VCMULQ_ROT180_M_F "180") - (VCMULQ_ROT270_M_F "270")]) + (VCMULQ_ROT270_M_F "270") + (VCMLAQ_M_F "0") + (VCMLAQ_ROT90_M_F "90") + (VCMLAQ_ROT180_M_F "180") + (VCMLAQ_ROT270_M_F "270") + ]) ;; The complex operations when performed on a real complex number require two ;; instructions to perform the operation. e.g. complex multiplication requires @@ -2250,7 +2261,11 @@ (VCMULQ_M_F "") (VCMULQ_ROT90_M_F "_rot90") (VCMULQ_ROT180_M_F "_rot180") - (VCMULQ_ROT270_M_F "_rot270")]) + (VCMULQ_ROT270_M_F "_rot270") + (VCMLAQ_M_F "") + (VCMLAQ_ROT90_M_F "_rot90") + (VCMLAQ_ROT180_M_F "_rot180") + (VCMLAQ_ROT270_M_F "_rot270")]) (define_int_attr fcmac1 [(UNSPEC_VCMLA "a") (UNSPEC_VCMLA_CONJ "a") (UNSPEC_VCMLA180 "s") (UNSPEC_VCMLA180_CONJ "s")]) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 0b99bf0..a2cbcff 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -2087,7 +2087,7 @@ ;; ;; [vcmlaq, vcmlaq_rot90, vcmlaq_rot180, vcmlaq_rot270]) ;; -(define_insn "mve_vcmlaq" +(define_insn "@mve_q_f" [ (set (match_operand:MVE_0 0 "s_register_operand" "=w,w") (plus:MVE_0 (match_operand:MVE_0 1 "reg_or_zero_operand" "Dz,0") @@ -3180,70 +3180,22 @@ (set_attr "length""8")]) ;; -;; [vcmlaq_m_f]) -;; -(define_insn "mve_vcmlaq_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "=w") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCMLAQ_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmlat.f%# %q0, %q2, %q3, #0" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcmlaq_rot180_m_f]) -;; -(define_insn "mve_vcmlaq_rot180_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "=w") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCMLAQ_ROT180_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmlat.f%# %q0, %q2, %q3, #180" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcmlaq_rot270_m_f]) +;; [vcmlaq_m_f] +;; [vcmlaq_rot90_m_f] +;; [vcmlaq_rot180_m_f] +;; [vcmlaq_rot270_m_f] ;; -(define_insn "mve_vcmlaq_rot270_m_f" - [ - (set (match_operand:MVE_0 0 "s_register_operand" "=w") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") - (match_operand:MVE_0 2 "s_register_operand" "w") - (match_operand:MVE_0 3 "s_register_operand" "w") - (match_operand: 4 "vpr_register_operand" "Up")] - VCMLAQ_ROT270_M_F)) - ] - "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmlat.f%# %q0, %q2, %q3, #270" - [(set_attr "type" "mve_move") - (set_attr "length""8")]) - -;; -;; [vcmlaq_rot90_m_f]) -;; -(define_insn "mve_vcmlaq_rot90_m_f" +(define_insn "@mve_q_m_f" [ (set (match_operand:MVE_0 0 "s_register_operand" "=w") (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") (match_operand:MVE_0 2 "s_register_operand" "w") (match_operand:MVE_0 3 "s_register_operand" "w") (match_operand: 4 "vpr_register_operand" "Up")] - VCMLAQ_ROT90_M_F)) + MVE_VCMLAQ_M)) ] "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" - "vpst\;vcmlat.f%# %q0, %q2, %q3, #90" + "vpst\;t.f%#\t%q0, %q2, %q3, #" [(set_attr "type" "mve_move") (set_attr "length""8")]) -- cgit v1.1 From 49a2a63e6518cfa294d903f5f62ab1f922df438e Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 12 Jul 2023 17:27:23 +0000 Subject: arm: [MVE intrinsics] rework vcmlaq Implement vcmlaq using the new MVE builtins framework. 2023-07-13 Christophe Lyon gcc/ * config/arm/arm-mve-builtins-base.cc (vcmlaq, vcmlaq_rot90) (vcmlaq_rot180, vcmlaq_rot270): New. * config/arm/arm-mve-builtins-base.def (vcmlaq, vcmlaq_rot90) (vcmlaq_rot180, vcmlaq_rot270): New. * config/arm/arm-mve-builtins-base.h: (vcmlaq, vcmlaq_rot90) (vcmlaq_rot180, vcmlaq_rot270): New. * config/arm/arm-mve-builtins.cc (function_instance::has_inactive_argument): Handle vcmlaq, vcmlaq_rot90, vcmlaq_rot180, vcmlaq_rot270. * config/arm/arm_mve.h (vcmlaq): Delete. (vcmlaq_rot180): Delete. (vcmlaq_rot270): Delete. (vcmlaq_rot90): Delete. (vcmlaq_m): Delete. (vcmlaq_rot180_m): Delete. (vcmlaq_rot270_m): Delete. (vcmlaq_rot90_m): Delete. (vcmlaq_f16): Delete. (vcmlaq_rot180_f16): Delete. (vcmlaq_rot270_f16): Delete. (vcmlaq_rot90_f16): Delete. (vcmlaq_f32): Delete. (vcmlaq_rot180_f32): Delete. (vcmlaq_rot270_f32): Delete. (vcmlaq_rot90_f32): Delete. (vcmlaq_m_f32): Delete. (vcmlaq_m_f16): Delete. (vcmlaq_rot180_m_f32): Delete. (vcmlaq_rot180_m_f16): Delete. (vcmlaq_rot270_m_f32): Delete. (vcmlaq_rot270_m_f16): Delete. (vcmlaq_rot90_m_f32): Delete. (vcmlaq_rot90_m_f16): Delete. (__arm_vcmlaq_f16): Delete. (__arm_vcmlaq_rot180_f16): Delete. (__arm_vcmlaq_rot270_f16): Delete. (__arm_vcmlaq_rot90_f16): Delete. (__arm_vcmlaq_f32): Delete. (__arm_vcmlaq_rot180_f32): Delete. (__arm_vcmlaq_rot270_f32): Delete. (__arm_vcmlaq_rot90_f32): Delete. (__arm_vcmlaq_m_f32): Delete. (__arm_vcmlaq_m_f16): Delete. (__arm_vcmlaq_rot180_m_f32): Delete. (__arm_vcmlaq_rot180_m_f16): Delete. (__arm_vcmlaq_rot270_m_f32): Delete. (__arm_vcmlaq_rot270_m_f16): Delete. (__arm_vcmlaq_rot90_m_f32): Delete. (__arm_vcmlaq_rot90_m_f16): Delete. (__arm_vcmlaq): Delete. (__arm_vcmlaq_rot180): Delete. (__arm_vcmlaq_rot270): Delete. (__arm_vcmlaq_rot90): Delete. (__arm_vcmlaq_m): Delete. (__arm_vcmlaq_rot180_m): Delete. (__arm_vcmlaq_rot270_m): Delete. (__arm_vcmlaq_rot90_m): Delete. --- gcc/config/arm/arm-mve-builtins-base.cc | 4 + gcc/config/arm/arm-mve-builtins-base.def | 4 + gcc/config/arm/arm-mve-builtins-base.h | 16 +- gcc/config/arm/arm-mve-builtins.cc | 4 + gcc/config/arm/arm_mve.h | 304 ------------------------------- 5 files changed, 22 insertions(+), 310 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm-mve-builtins-base.cc index 3ad8df3..e31095a 100644 --- a/gcc/config/arm/arm-mve-builtins-base.cc +++ b/gcc/config/arm/arm-mve-builtins-base.cc @@ -262,6 +262,10 @@ FUNCTION_WITH_RTX_M (vandq, AND, VANDQ) FUNCTION_ONLY_N (vbrsrq, VBRSRQ) FUNCTION (vcaddq_rot90, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD90, UNSPEC_VCADD90, UNSPEC_VCADD90, VCADDQ_ROT90_M_S, VCADDQ_ROT90_M_U, VCADDQ_ROT90_M_F)) FUNCTION (vcaddq_rot270, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD270, UNSPEC_VCADD270, UNSPEC_VCADD270, VCADDQ_ROT270_M_S, VCADDQ_ROT270_M_U, VCADDQ_ROT270_M_F)) +FUNCTION (vcmlaq, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA, -1, -1, VCMLAQ_M_F)) +FUNCTION (vcmlaq_rot90, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA90, -1, -1, VCMLAQ_ROT90_M_F)) +FUNCTION (vcmlaq_rot180, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA180, -1, -1, VCMLAQ_ROT180_M_F)) +FUNCTION (vcmlaq_rot270, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA270, -1, -1, VCMLAQ_ROT270_M_F)) FUNCTION (vcmulq, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL, -1, -1, VCMULQ_M_F)) FUNCTION (vcmulq_rot90, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL90, -1, -1, VCMULQ_ROT90_M_F)) FUNCTION (vcmulq_rot180, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL180, -1, -1, VCMULQ_ROT180_M_F)) diff --git a/gcc/config/arm/arm-mve-builtins-base.def b/gcc/config/arm/arm-mve-builtins-base.def index cbcf0d2..e7d466f 100644 --- a/gcc/config/arm/arm-mve-builtins-base.def +++ b/gcc/config/arm/arm-mve-builtins-base.def @@ -158,6 +158,10 @@ DEF_MVE_FUNCTION (vandq, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vbrsrq, binary_imm32, all_float, mx_or_none) DEF_MVE_FUNCTION (vcaddq_rot90, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vcaddq_rot270, binary, all_float, mx_or_none) +DEF_MVE_FUNCTION (vcmlaq, ternary, all_float, m_or_none) +DEF_MVE_FUNCTION (vcmlaq_rot90, ternary, all_float, m_or_none) +DEF_MVE_FUNCTION (vcmlaq_rot180, ternary, all_float, m_or_none) +DEF_MVE_FUNCTION (vcmlaq_rot270, ternary, all_float, m_or_none) DEF_MVE_FUNCTION (vcmulq, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vcmulq_rot90, binary, all_float, mx_or_none) DEF_MVE_FUNCTION (vcmulq_rot180, binary, all_float, mx_or_none) diff --git a/gcc/config/arm/arm-mve-builtins-base.h b/gcc/config/arm/arm-mve-builtins-base.h index 875b333..be3698b 100644 --- a/gcc/config/arm/arm-mve-builtins-base.h +++ b/gcc/config/arm/arm-mve-builtins-base.h @@ -33,14 +33,14 @@ extern const function_base *const vaddvaq; extern const function_base *const vaddvq; extern const function_base *const vandq; extern const function_base *const vbrsrq; -extern const function_base *const vcaddq_rot90; extern const function_base *const vcaddq_rot270; -extern const function_base *const vcmulq; -extern const function_base *const vcmulq_rot90; -extern const function_base *const vcmulq_rot180; -extern const function_base *const vcmulq_rot270; +extern const function_base *const vcaddq_rot90; extern const function_base *const vclsq; extern const function_base *const vclzq; +extern const function_base *const vcmlaq; +extern const function_base *const vcmlaq_rot180; +extern const function_base *const vcmlaq_rot270; +extern const function_base *const vcmlaq_rot90; extern const function_base *const vcmpcsq; extern const function_base *const vcmpeqq; extern const function_base *const vcmpgeq; @@ -49,6 +49,10 @@ extern const function_base *const vcmphiq; extern const function_base *const vcmpleq; extern const function_base *const vcmpltq; extern const function_base *const vcmpneq; +extern const function_base *const vcmulq; +extern const function_base *const vcmulq_rot180; +extern const function_base *const vcmulq_rot270; +extern const function_base *const vcmulq_rot90; extern const function_base *const vcreateq; extern const function_base *const vdupq; extern const function_base *const veorq; @@ -56,8 +60,8 @@ extern const function_base *const vfmaq; extern const function_base *const vfmasq; extern const function_base *const vfmsq; extern const function_base *const vhaddq; -extern const function_base *const vhcaddq_rot90; extern const function_base *const vhcaddq_rot270; +extern const function_base *const vhcaddq_rot90; extern const function_base *const vhsubq; extern const function_base *const vmaxaq; extern const function_base *const vmaxavq; diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc index 413d810..7eec9d2 100644 --- a/gcc/config/arm/arm-mve-builtins.cc +++ b/gcc/config/arm/arm-mve-builtins.cc @@ -680,6 +680,10 @@ function_instance::has_inactive_argument () const return false; if (mode_suffix_id == MODE_r + || base == functions::vcmlaq + || base == functions::vcmlaq_rot90 + || base == functions::vcmlaq_rot180 + || base == functions::vcmlaq_rot270 || base == functions::vcmpeqq || base == functions::vcmpneq || base == functions::vcmpgeq diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h index b9d3a87..88b2e77 100644 --- a/gcc/config/arm/arm_mve.h +++ b/gcc/config/arm/arm_mve.h @@ -159,18 +159,10 @@ #define vcvtq_m(__inactive, __a, __p) __arm_vcvtq_m(__inactive, __a, __p) #define vcvtbq_m(__a, __b, __p) __arm_vcvtbq_m(__a, __b, __p) #define vcvttq_m(__a, __b, __p) __arm_vcvttq_m(__a, __b, __p) -#define vcmlaq(__a, __b, __c) __arm_vcmlaq(__a, __b, __c) -#define vcmlaq_rot180(__a, __b, __c) __arm_vcmlaq_rot180(__a, __b, __c) -#define vcmlaq_rot270(__a, __b, __c) __arm_vcmlaq_rot270(__a, __b, __c) -#define vcmlaq_rot90(__a, __b, __c) __arm_vcmlaq_rot90(__a, __b, __c) #define vcvtmq_m(__inactive, __a, __p) __arm_vcvtmq_m(__inactive, __a, __p) #define vcvtnq_m(__inactive, __a, __p) __arm_vcvtnq_m(__inactive, __a, __p) #define vcvtpq_m(__inactive, __a, __p) __arm_vcvtpq_m(__inactive, __a, __p) #define vcvtq_m_n(__inactive, __a, __imm6, __p) __arm_vcvtq_m_n(__inactive, __a, __imm6, __p) -#define vcmlaq_m(__a, __b, __c, __p) __arm_vcmlaq_m(__a, __b, __c, __p) -#define vcmlaq_rot180_m(__a, __b, __c, __p) __arm_vcmlaq_rot180_m(__a, __b, __c, __p) -#define vcmlaq_rot270_m(__a, __b, __c, __p) __arm_vcmlaq_rot270_m(__a, __b, __c, __p) -#define vcmlaq_rot90_m(__a, __b, __c, __p) __arm_vcmlaq_rot90_m(__a, __b, __c, __p) #define vcvtq_x(__a, __p) __arm_vcvtq_x(__a, __p) #define vcvtq_x_n(__a, __imm6, __p) __arm_vcvtq_x_n(__a, __imm6, __p) @@ -286,10 +278,6 @@ #define vcvtbq_m_f32_f16(__inactive, __a, __p) __arm_vcvtbq_m_f32_f16(__inactive, __a, __p) #define vcvttq_m_f16_f32(__a, __b, __p) __arm_vcvttq_m_f16_f32(__a, __b, __p) #define vcvttq_m_f32_f16(__inactive, __a, __p) __arm_vcvttq_m_f32_f16(__inactive, __a, __p) -#define vcmlaq_f16(__a, __b, __c) __arm_vcmlaq_f16(__a, __b, __c) -#define vcmlaq_rot180_f16(__a, __b, __c) __arm_vcmlaq_rot180_f16(__a, __b, __c) -#define vcmlaq_rot270_f16(__a, __b, __c) __arm_vcmlaq_rot270_f16(__a, __b, __c) -#define vcmlaq_rot90_f16(__a, __b, __c) __arm_vcmlaq_rot90_f16(__a, __b, __c) #define vcvtmq_m_s16_f16(__inactive, __a, __p) __arm_vcvtmq_m_s16_f16(__inactive, __a, __p) #define vcvtnq_m_s16_f16(__inactive, __a, __p) __arm_vcvtnq_m_s16_f16(__inactive, __a, __p) #define vcvtpq_m_s16_f16(__inactive, __a, __p) __arm_vcvtpq_m_s16_f16(__inactive, __a, __p) @@ -298,10 +286,6 @@ #define vcvtnq_m_u16_f16(__inactive, __a, __p) __arm_vcvtnq_m_u16_f16(__inactive, __a, __p) #define vcvtpq_m_u16_f16(__inactive, __a, __p) __arm_vcvtpq_m_u16_f16(__inactive, __a, __p) #define vcvtq_m_u16_f16(__inactive, __a, __p) __arm_vcvtq_m_u16_f16(__inactive, __a, __p) -#define vcmlaq_f32(__a, __b, __c) __arm_vcmlaq_f32(__a, __b, __c) -#define vcmlaq_rot180_f32(__a, __b, __c) __arm_vcmlaq_rot180_f32(__a, __b, __c) -#define vcmlaq_rot270_f32(__a, __b, __c) __arm_vcmlaq_rot270_f32(__a, __b, __c) -#define vcmlaq_rot90_f32(__a, __b, __c) __arm_vcmlaq_rot90_f32(__a, __b, __c) #define vcvtmq_m_s32_f32(__inactive, __a, __p) __arm_vcvtmq_m_s32_f32(__inactive, __a, __p) #define vcvtnq_m_s32_f32(__inactive, __a, __p) __arm_vcvtnq_m_s32_f32(__inactive, __a, __p) #define vcvtpq_m_s32_f32(__inactive, __a, __p) __arm_vcvtpq_m_s32_f32(__inactive, __a, __p) @@ -344,14 +328,6 @@ #define vmulltq_poly_m_p16(__inactive, __a, __b, __p) __arm_vmulltq_poly_m_p16(__inactive, __a, __b, __p) #define vbicq_m_f32(__inactive, __a, __b, __p) __arm_vbicq_m_f32(__inactive, __a, __b, __p) #define vbicq_m_f16(__inactive, __a, __b, __p) __arm_vbicq_m_f16(__inactive, __a, __b, __p) -#define vcmlaq_m_f32(__a, __b, __c, __p) __arm_vcmlaq_m_f32(__a, __b, __c, __p) -#define vcmlaq_m_f16(__a, __b, __c, __p) __arm_vcmlaq_m_f16(__a, __b, __c, __p) -#define vcmlaq_rot180_m_f32(__a, __b, __c, __p) __arm_vcmlaq_rot180_m_f32(__a, __b, __c, __p) -#define vcmlaq_rot180_m_f16(__a, __b, __c, __p) __arm_vcmlaq_rot180_m_f16(__a, __b, __c, __p) -#define vcmlaq_rot270_m_f32(__a, __b, __c, __p) __arm_vcmlaq_rot270_m_f32(__a, __b, __c, __p) -#define vcmlaq_rot270_m_f16(__a, __b, __c, __p) __arm_vcmlaq_rot270_m_f16(__a, __b, __c, __p) -#define vcmlaq_rot90_m_f32(__a, __b, __c, __p) __arm_vcmlaq_rot90_m_f32(__a, __b, __c, __p) -#define vcmlaq_rot90_m_f16(__a, __b, __c, __p) __arm_vcmlaq_rot90_m_f16(__a, __b, __c, __p) #define vcvtq_m_n_s32_f32(__inactive, __a, __imm6, __p) __arm_vcvtq_m_n_s32_f32(__inactive, __a, __imm6, __p) #define vcvtq_m_n_s16_f16(__inactive, __a, __imm6, __p) __arm_vcvtq_m_n_s16_f16(__inactive, __a, __imm6, __p) #define vcvtq_m_n_u32_f32(__inactive, __a, __imm6, __p) __arm_vcvtq_m_n_u32_f32(__inactive, __a, __imm6, __p) @@ -4645,34 +4621,6 @@ __arm_vcvttq_m_f32_f16 (float32x4_t __inactive, float16x8_t __a, mve_pred16_t __ return __builtin_mve_vcvttq_m_f32_f16v4sf (__inactive, __a, __p); } -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __builtin_mve_vcmlaqv8hf (__a, __b, __c); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __builtin_mve_vcmlaq_rot180v8hf (__a, __b, __c); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __builtin_mve_vcmlaq_rot270v8hf (__a, __b, __c); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __builtin_mve_vcmlaq_rot90v8hf (__a, __b, __c); -} - __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtmq_m_s16_f16 (int16x8_t __inactive, float16x8_t __a, mve_pred16_t __p) @@ -4729,34 +4677,6 @@ __arm_vcvtq_m_u16_f16 (uint16x8_t __inactive, float16x8_t __a, mve_pred16_t __p) return __builtin_mve_vcvtq_m_from_f_uv8hi (__inactive, __a, __p); } -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __builtin_mve_vcmlaqv4sf (__a, __b, __c); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __builtin_mve_vcmlaq_rot180v4sf (__a, __b, __c); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __builtin_mve_vcmlaq_rot270v4sf (__a, __b, __c); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __builtin_mve_vcmlaq_rot90v4sf (__a, __b, __c); -} - __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtmq_m_s32_f32 (int32x4_t __inactive, float32x4_t __a, mve_pred16_t __p) @@ -4855,62 +4775,6 @@ __arm_vbicq_m_f16 (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve return __builtin_mve_vbicq_m_fv8hf (__inactive, __a, __b, __p); } -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_m_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_m_fv4sf (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_m_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_m_fv8hf (__a, __b, __c, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180_m_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_rot180_m_fv4sf (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180_m_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_rot180_m_fv8hf (__a, __b, __c, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270_m_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_rot270_m_fv4sf (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270_m_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_rot270_m_fv8hf (__a, __b, __c, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90_m_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_rot90_m_fv4sf (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90_m_f16 (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __builtin_mve_vcmlaq_rot90_m_fv8hf (__a, __b, __c, __p); -} - __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtq_m_n_s32_f32 (int32x4_t __inactive, float32x4_t __a, const int __imm6, mve_pred16_t __p) @@ -8481,34 +8345,6 @@ __arm_vcvttq_m (float32x4_t __inactive, float16x8_t __a, mve_pred16_t __p) return __arm_vcvttq_m_f32_f16 (__inactive, __a, __p); } -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __arm_vcmlaq_f16 (__a, __b, __c); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180 (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __arm_vcmlaq_rot180_f16 (__a, __b, __c); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270 (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __arm_vcmlaq_rot270_f16 (__a, __b, __c); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90 (float16x8_t __a, float16x8_t __b, float16x8_t __c) -{ - return __arm_vcmlaq_rot90_f16 (__a, __b, __c); -} - __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtmq_m (int16x8_t __inactive, float16x8_t __a, mve_pred16_t __p) @@ -8565,34 +8401,6 @@ __arm_vcvtq_m (uint16x8_t __inactive, float16x8_t __a, mve_pred16_t __p) return __arm_vcvtq_m_u16_f16 (__inactive, __a, __p); } -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __arm_vcmlaq_f32 (__a, __b, __c); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180 (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __arm_vcmlaq_rot180_f32 (__a, __b, __c); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270 (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __arm_vcmlaq_rot270_f32 (__a, __b, __c); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90 (float32x4_t __a, float32x4_t __b, float32x4_t __c) -{ - return __arm_vcmlaq_rot90_f32 (__a, __b, __c); -} - __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtmq_m (int32x4_t __inactive, float32x4_t __a, mve_pred16_t __p) @@ -8691,62 +8499,6 @@ __arm_vbicq_m (float16x8_t __inactive, float16x8_t __a, float16x8_t __b, mve_pre return __arm_vbicq_m_f16 (__inactive, __a, __b, __p); } -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_m (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_m_f32 (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_m (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_m_f16 (__a, __b, __c, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180_m (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_rot180_m_f32 (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot180_m (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_rot180_m_f16 (__a, __b, __c, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270_m (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_rot270_m_f32 (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot270_m (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_rot270_m_f16 (__a, __b, __c, __p); -} - -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90_m (float32x4_t __a, float32x4_t __b, float32x4_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_rot90_m_f32 (__a, __b, __c, __p); -} - -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_vcmlaq_rot90_m (float16x8_t __a, float16x8_t __b, float16x8_t __c, mve_pred16_t __p) -{ - return __arm_vcmlaq_rot90_m_f16 (__a, __b, __c, __p); -} - __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_vcvtq_m_n (int32x4_t __inactive, float32x4_t __a, const int __imm6, mve_pred16_t __p) @@ -9620,34 +9372,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcvtq_m_n_f16_u16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), p2, p3), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcvtq_m_n_f32_u32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), p2, p3));}) -#define __arm_vcmlaq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t)));}) - -#define __arm_vcmlaq_rot180(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_rot180_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_rot180_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t)));}) - -#define __arm_vcmlaq_rot270(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_rot270_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_rot270_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t)));}) - -#define __arm_vcmlaq_rot90(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_rot90_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t)), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_rot90_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t)));}) - #define __arm_vcvtbq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \ @@ -9697,34 +9421,6 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vbicq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vbicq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) -#define __arm_vcmlaq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmlaq_rot180_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_rot180_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_rot180_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmlaq_rot270_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_rot270_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_rot270_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - -#define __arm_vcmlaq_rot90_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ - __typeof(p1) __p1 = (p1); \ - __typeof(p2) __p2 = (p2); \ - _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \ - int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmlaq_rot90_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \ - int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmlaq_rot90_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3));}) - #define __arm_vornq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ __typeof(p2) __p2 = (p2); \ -- cgit v1.1 From 8d344146727da02eb5c62fbf6cee97a4e96d63db Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 14 Jul 2023 09:37:21 -0400 Subject: c++: c++26 regression fixes Apparently I wasn't actually running the testsuite in C++26 mode like I thought I was, so there were some failures I wasn't seeing. The constexpr hunk fixes regressions with the P2738 implementation; we still need to use the old handling for casting from void pointers to heap variables. PR c++/110344 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Move P2738 handling after heap handling. * name-lookup.cc (get_cxx_dialect_name): Add C++26. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-cast2.C: Adjust for P2738. * g++.dg/ipa/devirt-45.C: Handle -fimplicit-constexpr. --- gcc/cp/constexpr.cc | 21 ++++++++++----------- gcc/cp/name-lookup.cc | 2 ++ gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C | 6 +++--- gcc/testsuite/g++.dg/ipa/devirt-45.C | 2 +- 4 files changed, 16 insertions(+), 15 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index cca0435..9f96a6c 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -7681,17 +7681,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, && !is_std_construct_at (ctx->call) && !is_std_allocator_allocate (ctx->call)) { - /* P2738 (C++26): a conversion from a prvalue P of type "pointer to - cv void" to a pointer-to-object type T unless P points to an - object whose type is similar to T. */ - if (cxx_dialect > cxx23) - if (tree ob - = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), op)) - { - r = build1 (ADDR_EXPR, type, ob); - break; - } - /* Likewise, don't error when casting from void* when OP is &heap uninit and similar. */ tree sop = tree_strip_nop_conversions (op); @@ -7699,6 +7688,16 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, && VAR_P (TREE_OPERAND (sop, 0)) && DECL_ARTIFICIAL (TREE_OPERAND (sop, 0))) /* OK */; + /* P2738 (C++26): a conversion from a prvalue P of type "pointer to + cv void" to a pointer-to-object type T unless P points to an + object whose type is similar to T. */ + else if (cxx_dialect > cxx23 + && (sop = cxx_fold_indirect_ref (ctx, loc, + TREE_TYPE (type), sop))) + { + r = build1 (ADDR_EXPR, type, sop); + break; + } else { if (!ctx->quiet) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 7456518..2d74756 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -6731,6 +6731,8 @@ get_cxx_dialect_name (enum cxx_dialect dialect) return "C++20"; case cxx23: return "C++23"; + case cxx26: + return "C++26"; } } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C index b79e8a9..3efbd92 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C @@ -6,11 +6,11 @@ static int i; constexpr void *vp0 = nullptr; constexpr void *vpi = &i; constexpr int *p1 = (int *) vp0; // { dg-error "cast from .void\\*. is not allowed" } -constexpr int *p2 = (int *) vpi; // { dg-error "cast from .void\\*. is not allowed" } +constexpr int *p2 = (int *) vpi; // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } constexpr int *p3 = static_cast(vp0); // { dg-error "cast from .void\\*. is not allowed" } -constexpr int *p4 = static_cast(vpi); // { dg-error "cast from .void\\*. is not allowed" } +constexpr int *p4 = static_cast(vpi); // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } constexpr void *p5 = vp0; constexpr void *p6 = vpi; constexpr int *pi = &i; -constexpr bool b = ((int *)(void *) pi == pi); // { dg-error "cast from .void\\*. is not allowed" } +constexpr bool b = ((int *)(void *) pi == pi); // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } diff --git a/gcc/testsuite/g++.dg/ipa/devirt-45.C b/gcc/testsuite/g++.dg/ipa/devirt-45.C index c26be21..019b454 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-45.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-45.C @@ -37,5 +37,5 @@ int main() } /* One invocation is A::foo () other is B::foo () even though the type is destroyed and rebuilt in test() */ -/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target\[^\\n\]*A::foo" 2 "inline" } } */ +/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target\[^\\n\]*A::foo" 2 "inline" { target { ! implicit_constexpr } } } }*/ /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target\[^\\n\]*B::foo" 1 "inline" } } */ -- cgit v1.1 From 12a1162072eef9b6cdf07a3e3889def18a836221 Mon Sep 17 00:00:00 2001 From: Nathaniel Shead Date: Thu, 13 Jul 2023 17:40:10 -0400 Subject: c++: style tweak At this point r == t, but it makes more sense to refer to t like all the other cases do. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Pass t to get_value. Signed-off-by: Nathaniel Shead --- gcc/cp/constexpr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 9f96a6c..c6f323e 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -7085,7 +7085,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case PARM_DECL: if (lval && !TYPE_REF_P (TREE_TYPE (t))) /* glvalue use. */; - else if (tree v = ctx->global->get_value (r)) + else if (tree v = ctx->global->get_value (t)) r = v; else if (lval) /* Defer in case this is only used for its type. */; -- cgit v1.1 From 18dac101678b8c0aed4bd995351e47f26cd54dec Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 15 Jul 2023 00:17:26 +0000 Subject: Daily bump. --- gcc/ChangeLog | 486 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 20 ++ gcc/fortran/ChangeLog | 40 ++++ gcc/testsuite/ChangeLog | 65 +++++++ 5 files changed, 612 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5401ea6..165f9f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,489 @@ +2023-07-14 Christophe Lyon + + * config/arm/arm-mve-builtins-base.cc (vcmlaq, vcmlaq_rot90) + (vcmlaq_rot180, vcmlaq_rot270): New. + * config/arm/arm-mve-builtins-base.def (vcmlaq, vcmlaq_rot90) + (vcmlaq_rot180, vcmlaq_rot270): New. + * config/arm/arm-mve-builtins-base.h: (vcmlaq, vcmlaq_rot90) + (vcmlaq_rot180, vcmlaq_rot270): New. + * config/arm/arm-mve-builtins.cc + (function_instance::has_inactive_argument): Handle vcmlaq, + vcmlaq_rot90, vcmlaq_rot180, vcmlaq_rot270. + * config/arm/arm_mve.h (vcmlaq): Delete. + (vcmlaq_rot180): Delete. + (vcmlaq_rot270): Delete. + (vcmlaq_rot90): Delete. + (vcmlaq_m): Delete. + (vcmlaq_rot180_m): Delete. + (vcmlaq_rot270_m): Delete. + (vcmlaq_rot90_m): Delete. + (vcmlaq_f16): Delete. + (vcmlaq_rot180_f16): Delete. + (vcmlaq_rot270_f16): Delete. + (vcmlaq_rot90_f16): Delete. + (vcmlaq_f32): Delete. + (vcmlaq_rot180_f32): Delete. + (vcmlaq_rot270_f32): Delete. + (vcmlaq_rot90_f32): Delete. + (vcmlaq_m_f32): Delete. + (vcmlaq_m_f16): Delete. + (vcmlaq_rot180_m_f32): Delete. + (vcmlaq_rot180_m_f16): Delete. + (vcmlaq_rot270_m_f32): Delete. + (vcmlaq_rot270_m_f16): Delete. + (vcmlaq_rot90_m_f32): Delete. + (vcmlaq_rot90_m_f16): Delete. + (__arm_vcmlaq_f16): Delete. + (__arm_vcmlaq_rot180_f16): Delete. + (__arm_vcmlaq_rot270_f16): Delete. + (__arm_vcmlaq_rot90_f16): Delete. + (__arm_vcmlaq_f32): Delete. + (__arm_vcmlaq_rot180_f32): Delete. + (__arm_vcmlaq_rot270_f32): Delete. + (__arm_vcmlaq_rot90_f32): Delete. + (__arm_vcmlaq_m_f32): Delete. + (__arm_vcmlaq_m_f16): Delete. + (__arm_vcmlaq_rot180_m_f32): Delete. + (__arm_vcmlaq_rot180_m_f16): Delete. + (__arm_vcmlaq_rot270_m_f32): Delete. + (__arm_vcmlaq_rot270_m_f16): Delete. + (__arm_vcmlaq_rot90_m_f32): Delete. + (__arm_vcmlaq_rot90_m_f16): Delete. + (__arm_vcmlaq): Delete. + (__arm_vcmlaq_rot180): Delete. + (__arm_vcmlaq_rot270): Delete. + (__arm_vcmlaq_rot90): Delete. + (__arm_vcmlaq_m): Delete. + (__arm_vcmlaq_rot180_m): Delete. + (__arm_vcmlaq_rot270_m): Delete. + (__arm_vcmlaq_rot90_m): Delete. + +2023-07-14 Christophe Lyon + + * config/arm/arm_mve_builtins.def (vcmlaq_rot90_f) + (vcmlaq_rot270_f, vcmlaq_rot180_f, vcmlaq_f): Add "_f" suffix. + * config/arm/iterators.md (MVE_VCMLAQ_M): New. + (mve_insn): Add vcmla. + (rot): Add VCMLAQ_M_F, VCMLAQ_ROT90_M_F, VCMLAQ_ROT180_M_F, + VCMLAQ_ROT270_M_F. + (mve_rot): Add VCMLAQ_M_F, VCMLAQ_ROT90_M_F, VCMLAQ_ROT180_M_F, + VCMLAQ_ROT270_M_F. + * config/arm/mve.md (mve_vcmlaq): Rename into ... + (@mve_q_f): ... this. + (mve_vcmlaq_m_f, mve_vcmlaq_rot180_m_f) + (mve_vcmlaq_rot270_m_f, mve_vcmlaq_rot90_m_f): Merge + into ... + (@mve_q_m_f): ... this. + +2023-07-14 Christophe Lyon + + * config/arm/arm-mve-builtins-base.cc (vcmulq, vcmulq_rot90) + (vcmulq_rot180, vcmulq_rot270): New. + * config/arm/arm-mve-builtins-base.def (vcmulq, vcmulq_rot90) + (vcmulq_rot180, vcmulq_rot270): New. + * config/arm/arm-mve-builtins-base.h: (vcmulq, vcmulq_rot90) + (vcmulq_rot180, vcmulq_rot270): New. + * config/arm/arm_mve.h (vcmulq_rot90): Delete. + (vcmulq_rot270): Delete. + (vcmulq_rot180): Delete. + (vcmulq): Delete. + (vcmulq_m): Delete. + (vcmulq_rot180_m): Delete. + (vcmulq_rot270_m): Delete. + (vcmulq_rot90_m): Delete. + (vcmulq_x): Delete. + (vcmulq_rot90_x): Delete. + (vcmulq_rot180_x): Delete. + (vcmulq_rot270_x): Delete. + (vcmulq_rot90_f16): Delete. + (vcmulq_rot270_f16): Delete. + (vcmulq_rot180_f16): Delete. + (vcmulq_f16): Delete. + (vcmulq_rot90_f32): Delete. + (vcmulq_rot270_f32): Delete. + (vcmulq_rot180_f32): Delete. + (vcmulq_f32): Delete. + (vcmulq_m_f32): Delete. + (vcmulq_m_f16): Delete. + (vcmulq_rot180_m_f32): Delete. + (vcmulq_rot180_m_f16): Delete. + (vcmulq_rot270_m_f32): Delete. + (vcmulq_rot270_m_f16): Delete. + (vcmulq_rot90_m_f32): Delete. + (vcmulq_rot90_m_f16): Delete. + (vcmulq_x_f16): Delete. + (vcmulq_x_f32): Delete. + (vcmulq_rot90_x_f16): Delete. + (vcmulq_rot90_x_f32): Delete. + (vcmulq_rot180_x_f16): Delete. + (vcmulq_rot180_x_f32): Delete. + (vcmulq_rot270_x_f16): Delete. + (vcmulq_rot270_x_f32): Delete. + (__arm_vcmulq_rot90_f16): Delete. + (__arm_vcmulq_rot270_f16): Delete. + (__arm_vcmulq_rot180_f16): Delete. + (__arm_vcmulq_f16): Delete. + (__arm_vcmulq_rot90_f32): Delete. + (__arm_vcmulq_rot270_f32): Delete. + (__arm_vcmulq_rot180_f32): Delete. + (__arm_vcmulq_f32): Delete. + (__arm_vcmulq_m_f32): Delete. + (__arm_vcmulq_m_f16): Delete. + (__arm_vcmulq_rot180_m_f32): Delete. + (__arm_vcmulq_rot180_m_f16): Delete. + (__arm_vcmulq_rot270_m_f32): Delete. + (__arm_vcmulq_rot270_m_f16): Delete. + (__arm_vcmulq_rot90_m_f32): Delete. + (__arm_vcmulq_rot90_m_f16): Delete. + (__arm_vcmulq_x_f16): Delete. + (__arm_vcmulq_x_f32): Delete. + (__arm_vcmulq_rot90_x_f16): Delete. + (__arm_vcmulq_rot90_x_f32): Delete. + (__arm_vcmulq_rot180_x_f16): Delete. + (__arm_vcmulq_rot180_x_f32): Delete. + (__arm_vcmulq_rot270_x_f16): Delete. + (__arm_vcmulq_rot270_x_f32): Delete. + (__arm_vcmulq_rot90): Delete. + (__arm_vcmulq_rot270): Delete. + (__arm_vcmulq_rot180): Delete. + (__arm_vcmulq): Delete. + (__arm_vcmulq_m): Delete. + (__arm_vcmulq_rot180_m): Delete. + (__arm_vcmulq_rot270_m): Delete. + (__arm_vcmulq_rot90_m): Delete. + (__arm_vcmulq_x): Delete. + (__arm_vcmulq_rot90_x): Delete. + (__arm_vcmulq_rot180_x): Delete. + (__arm_vcmulq_rot270_x): Delete. + +2023-07-14 Christophe Lyon + + * config/arm/arm_mve_builtins.def (vcmulq_rot90_f) + (vcmulq_rot270_f, vcmulq_rot180_f, vcmulq_f): Add "_f" suffix. + * config/arm/iterators.md (MVE_VCADDQ_VCMULQ) + (MVE_VCADDQ_VCMULQ_M): New. + (mve_insn): Add vcmul. + (rot): Add VCMULQ_M_F, VCMULQ_ROT90_M_F, VCMULQ_ROT180_M_F, + VCMULQ_ROT270_M_F. + (VCMUL): Delete. + (mve_rot): Add VCMULQ_M_F, VCMULQ_ROT90_M_F, VCMULQ_ROT180_M_F, + VCMULQ_ROT270_M_F. + * config/arm/mve.md (mve_vcmulq): Merge into + @mve_q_f. + (mve_vcmulq_m_f, mve_vcmulq_rot180_m_f) + (mve_vcmulq_rot270_m_f, mve_vcmulq_rot90_m_f): Merge + into @mve_q_m_f. + +2023-07-14 Christophe Lyon + + * config/arm/arm-mve-builtins-base.cc (vcaddq_rot90) + (vcaddq_rot270, vhcaddq_rot90, vhcaddq_rot270): New. + * config/arm/arm-mve-builtins-base.def (vcaddq_rot90) + (vcaddq_rot270, vhcaddq_rot90, vhcaddq_rot270): New. + * config/arm/arm-mve-builtins-base.h: (vcaddq_rot90) + (vcaddq_rot270, vhcaddq_rot90, vhcaddq_rot270): New. + * config/arm/arm-mve-builtins-functions.h (class + unspec_mve_function_exact_insn_rot): New. + * config/arm/arm_mve.h (vcaddq_rot90): Delete. + (vcaddq_rot270): Delete. + (vhcaddq_rot90): Delete. + (vhcaddq_rot270): Delete. + (vcaddq_rot270_m): Delete. + (vcaddq_rot90_m): Delete. + (vhcaddq_rot270_m): Delete. + (vhcaddq_rot90_m): Delete. + (vcaddq_rot90_x): Delete. + (vcaddq_rot270_x): Delete. + (vhcaddq_rot90_x): Delete. + (vhcaddq_rot270_x): Delete. + (vcaddq_rot90_u8): Delete. + (vcaddq_rot270_u8): Delete. + (vhcaddq_rot90_s8): Delete. + (vhcaddq_rot270_s8): Delete. + (vcaddq_rot90_s8): Delete. + (vcaddq_rot270_s8): Delete. + (vcaddq_rot90_u16): Delete. + (vcaddq_rot270_u16): Delete. + (vhcaddq_rot90_s16): Delete. + (vhcaddq_rot270_s16): Delete. + (vcaddq_rot90_s16): Delete. + (vcaddq_rot270_s16): Delete. + (vcaddq_rot90_u32): Delete. + (vcaddq_rot270_u32): Delete. + (vhcaddq_rot90_s32): Delete. + (vhcaddq_rot270_s32): Delete. + (vcaddq_rot90_s32): Delete. + (vcaddq_rot270_s32): Delete. + (vcaddq_rot90_f16): Delete. + (vcaddq_rot270_f16): Delete. + (vcaddq_rot90_f32): Delete. + (vcaddq_rot270_f32): Delete. + (vcaddq_rot270_m_s8): Delete. + (vcaddq_rot270_m_s32): Delete. + (vcaddq_rot270_m_s16): Delete. + (vcaddq_rot270_m_u8): Delete. + (vcaddq_rot270_m_u32): Delete. + (vcaddq_rot270_m_u16): Delete. + (vcaddq_rot90_m_s8): Delete. + (vcaddq_rot90_m_s32): Delete. + (vcaddq_rot90_m_s16): Delete. + (vcaddq_rot90_m_u8): Delete. + (vcaddq_rot90_m_u32): Delete. + (vcaddq_rot90_m_u16): Delete. + (vhcaddq_rot270_m_s8): Delete. + (vhcaddq_rot270_m_s32): Delete. + (vhcaddq_rot270_m_s16): Delete. + (vhcaddq_rot90_m_s8): Delete. + (vhcaddq_rot90_m_s32): Delete. + (vhcaddq_rot90_m_s16): Delete. + (vcaddq_rot270_m_f32): Delete. + (vcaddq_rot270_m_f16): Delete. + (vcaddq_rot90_m_f32): Delete. + (vcaddq_rot90_m_f16): Delete. + (vcaddq_rot90_x_s8): Delete. + (vcaddq_rot90_x_s16): Delete. + (vcaddq_rot90_x_s32): Delete. + (vcaddq_rot90_x_u8): Delete. + (vcaddq_rot90_x_u16): Delete. + (vcaddq_rot90_x_u32): Delete. + (vcaddq_rot270_x_s8): Delete. + (vcaddq_rot270_x_s16): Delete. + (vcaddq_rot270_x_s32): Delete. + (vcaddq_rot270_x_u8): Delete. + (vcaddq_rot270_x_u16): Delete. + (vcaddq_rot270_x_u32): Delete. + (vhcaddq_rot90_x_s8): Delete. + (vhcaddq_rot90_x_s16): Delete. + (vhcaddq_rot90_x_s32): Delete. + (vhcaddq_rot270_x_s8): Delete. + (vhcaddq_rot270_x_s16): Delete. + (vhcaddq_rot270_x_s32): Delete. + (vcaddq_rot90_x_f16): Delete. + (vcaddq_rot90_x_f32): Delete. + (vcaddq_rot270_x_f16): Delete. + (vcaddq_rot270_x_f32): Delete. + (__arm_vcaddq_rot90_u8): Delete. + (__arm_vcaddq_rot270_u8): Delete. + (__arm_vhcaddq_rot90_s8): Delete. + (__arm_vhcaddq_rot270_s8): Delete. + (__arm_vcaddq_rot90_s8): Delete. + (__arm_vcaddq_rot270_s8): Delete. + (__arm_vcaddq_rot90_u16): Delete. + (__arm_vcaddq_rot270_u16): Delete. + (__arm_vhcaddq_rot90_s16): Delete. + (__arm_vhcaddq_rot270_s16): Delete. + (__arm_vcaddq_rot90_s16): Delete. + (__arm_vcaddq_rot270_s16): Delete. + (__arm_vcaddq_rot90_u32): Delete. + (__arm_vcaddq_rot270_u32): Delete. + (__arm_vhcaddq_rot90_s32): Delete. + (__arm_vhcaddq_rot270_s32): Delete. + (__arm_vcaddq_rot90_s32): Delete. + (__arm_vcaddq_rot270_s32): Delete. + (__arm_vcaddq_rot270_m_s8): Delete. + (__arm_vcaddq_rot270_m_s32): Delete. + (__arm_vcaddq_rot270_m_s16): Delete. + (__arm_vcaddq_rot270_m_u8): Delete. + (__arm_vcaddq_rot270_m_u32): Delete. + (__arm_vcaddq_rot270_m_u16): Delete. + (__arm_vcaddq_rot90_m_s8): Delete. + (__arm_vcaddq_rot90_m_s32): Delete. + (__arm_vcaddq_rot90_m_s16): Delete. + (__arm_vcaddq_rot90_m_u8): Delete. + (__arm_vcaddq_rot90_m_u32): Delete. + (__arm_vcaddq_rot90_m_u16): Delete. + (__arm_vhcaddq_rot270_m_s8): Delete. + (__arm_vhcaddq_rot270_m_s32): Delete. + (__arm_vhcaddq_rot270_m_s16): Delete. + (__arm_vhcaddq_rot90_m_s8): Delete. + (__arm_vhcaddq_rot90_m_s32): Delete. + (__arm_vhcaddq_rot90_m_s16): Delete. + (__arm_vcaddq_rot90_x_s8): Delete. + (__arm_vcaddq_rot90_x_s16): Delete. + (__arm_vcaddq_rot90_x_s32): Delete. + (__arm_vcaddq_rot90_x_u8): Delete. + (__arm_vcaddq_rot90_x_u16): Delete. + (__arm_vcaddq_rot90_x_u32): Delete. + (__arm_vcaddq_rot270_x_s8): Delete. + (__arm_vcaddq_rot270_x_s16): Delete. + (__arm_vcaddq_rot270_x_s32): Delete. + (__arm_vcaddq_rot270_x_u8): Delete. + (__arm_vcaddq_rot270_x_u16): Delete. + (__arm_vcaddq_rot270_x_u32): Delete. + (__arm_vhcaddq_rot90_x_s8): Delete. + (__arm_vhcaddq_rot90_x_s16): Delete. + (__arm_vhcaddq_rot90_x_s32): Delete. + (__arm_vhcaddq_rot270_x_s8): Delete. + (__arm_vhcaddq_rot270_x_s16): Delete. + (__arm_vhcaddq_rot270_x_s32): Delete. + (__arm_vcaddq_rot90_f16): Delete. + (__arm_vcaddq_rot270_f16): Delete. + (__arm_vcaddq_rot90_f32): Delete. + (__arm_vcaddq_rot270_f32): Delete. + (__arm_vcaddq_rot270_m_f32): Delete. + (__arm_vcaddq_rot270_m_f16): Delete. + (__arm_vcaddq_rot90_m_f32): Delete. + (__arm_vcaddq_rot90_m_f16): Delete. + (__arm_vcaddq_rot90_x_f16): Delete. + (__arm_vcaddq_rot90_x_f32): Delete. + (__arm_vcaddq_rot270_x_f16): Delete. + (__arm_vcaddq_rot270_x_f32): Delete. + (__arm_vcaddq_rot90): Delete. + (__arm_vcaddq_rot270): Delete. + (__arm_vhcaddq_rot90): Delete. + (__arm_vhcaddq_rot270): Delete. + (__arm_vcaddq_rot270_m): Delete. + (__arm_vcaddq_rot90_m): Delete. + (__arm_vhcaddq_rot270_m): Delete. + (__arm_vhcaddq_rot90_m): Delete. + (__arm_vcaddq_rot90_x): Delete. + (__arm_vcaddq_rot270_x): Delete. + (__arm_vhcaddq_rot90_x): Delete. + (__arm_vhcaddq_rot270_x): Delete. + +2023-07-14 Christophe Lyon + + * config/arm/arm_mve_builtins.def (vcaddq_rot90_, vcaddq_rot270_) + (vcaddq_rot90_f, vcaddq_rot90_f): Add "_" or "_f" suffix. + * config/arm/iterators.md (mve_insn): Add vcadd, vhcadd. + (isu): Add UNSPEC_VCADD90, UNSPEC_VCADD270, VCADDQ_ROT270_M_U, + VCADDQ_ROT270_M_S, VCADDQ_ROT90_M_U, VCADDQ_ROT90_M_S, + VHCADDQ_ROT90_M_S, VHCADDQ_ROT270_M_S, VHCADDQ_ROT90_S, + VHCADDQ_ROT270_S. + (rot): Add VCADDQ_ROT90_M_F, VCADDQ_ROT90_M_S, VCADDQ_ROT90_M_U, + VCADDQ_ROT270_M_F, VCADDQ_ROT270_M_S, VCADDQ_ROT270_M_U, + VHCADDQ_ROT90_S, VHCADDQ_ROT270_S, VHCADDQ_ROT90_M_S, + VHCADDQ_ROT270_M_S. + (mve_rot): Add VCADDQ_ROT90_M_F, VCADDQ_ROT90_M_S, + VCADDQ_ROT90_M_U, VCADDQ_ROT270_M_F, VCADDQ_ROT270_M_S, + VCADDQ_ROT270_M_U, VHCADDQ_ROT90_S, VHCADDQ_ROT270_S, + VHCADDQ_ROT90_M_S, VHCADDQ_ROT270_M_S. + (supf): Add VHCADDQ_ROT90_M_S, VHCADDQ_ROT270_M_S, + VHCADDQ_ROT90_S, VHCADDQ_ROT270_S, UNSPEC_VCADD90, + UNSPEC_VCADD270. + (VCADDQ_ROT270_M): Delete. + (VCADDQ_M_F VxCADDQ VxCADDQ_M): New. + (VCADDQ_ROT90_M): Delete. + * config/arm/mve.md (mve_vcaddq) + (mve_vhcaddq_rot270_s, mve_vhcaddq_rot90_s): Merge + into ... + (@mve_q_): ... this. + (mve_vcaddq): Rename into ... + (@mve_q_f): ... this + (mve_vcaddq_rot270_m_) + (mve_vcaddq_rot90_m_, mve_vhcaddq_rot270_m_s) + (mve_vhcaddq_rot90_m_s): Merge into ... + (@mve_q_m_): ... this. + (mve_vcaddq_rot270_m_f, mve_vcaddq_rot90_m_f): Merge + into ... + (@mve_q_m_f): ... this. + +2023-07-14 Roger Sayle + + PR target/110588 + * config/i386/i386.md (*bt_setcqi): Prefer string form + preparation statement over braces for a single statement. + (*bt_setncqi): Likewise. + (*bt_setncqi_2): New define_insn_and_split. + +2023-07-14 Roger Sayle + + * config/i386/i386-expand.cc (ix86_expand_move): Generalize special + case inserting of 64-bit values into a TImode register, to handle + both DImode and DFmode using either *insvti_lowpart_1 + or *isnvti_highpart_1. + +2023-07-14 Uros Bizjak + + PR target/110206 + * fwprop.cc (contains_paradoxical_subreg_p): Move to ... + * rtlanal.cc (contains_paradoxical_subreg_p): ... here. + * rtlanal.h (contains_paradoxical_subreg_p): Add prototype. + * cprop.cc (try_replace_reg): Do not set REG_EQUAL note + when the original source contains a paradoxical subreg. + +2023-07-14 Jan Hubicka + + * passes.cc (execute_function_todo): Remove + TODO_rebuild_frequencies + * passes.def: Add rebuild_frequencies pass. + * predict.cc (estimate_bb_frequencies): Drop + force parameter. + (tree_estimate_probability): Update call of + estimate_bb_frequencies. + (rebuild_frequencies): Turn into a pass; verify CFG profile consistency + first and do not rebuild if not necessary. + (class pass_rebuild_frequencies): New. + (make_pass_rebuild_frequencies): New. + * profile-count.h: Add profile_count::very_large_p. + * tree-inline.cc (optimize_inline_calls): Do not return + TODO_rebuild_frequencies + * tree-pass.h (TODO_rebuild_frequencies): Remove. + (make_pass_rebuild_frequencies): Declare. + +2023-07-14 Juzhe-Zhong + + * config/riscv/autovec.md (cond_len_fma): New pattern. + * config/riscv/riscv-protos.h (enum insn_type): New enum. + (expand_cond_len_ternop): New function. + * config/riscv/riscv-v.cc (emit_nonvlmax_fp_ternary_tu_insn): Ditto. + (expand_cond_len_ternop): Ditto. + +2023-07-14 Jose E. Marchesi + + PR target/110657 + * config/bpf/bpf.md: Enable instruction scheduling. + +2023-07-14 Tamar Christina + + PR tree-optimization/109154 + * tree-if-conv.cc (INCLUDE_ALGORITHM): Include. + (struct bb_predicate): Add no_predicate_stmts. + (set_bb_predicate): Increase predicate count. + (set_bb_predicate_gimplified_stmts): Conditionally initialize + no_predicate_stmts. + (get_bb_num_predicate_stmts): New. + (init_bb_predicate): Initialzie no_predicate_stmts. + (release_bb_predicate): Cleanup no_predicate_stmts. + (insert_gimplified_predicates): Preserve no_predicate_stmts. + +2023-07-14 Tamar Christina + + PR tree-optimization/109154 + * tree-if-conv.cc (gen_simplified_condition, + gen_phi_nest_statement): New. + (gen_phi_arg_condition, predicate_scalar_phi): Use it. + +2023-07-14 Richard Biener + + * gimple.h (gimple_phi_arg): New const overload. + (gimple_phi_arg_def): Make gimple arg const. + (gimple_phi_arg_def_from_edge): New inline function. + * tree-phinodes.h (gimple_phi_arg_imm_use_ptr_from_edge): + Likewise. + * tree-ssa-operands.h (PHI_ARG_DEF_FROM_EDGE): Direct to + new inline function. + (PHI_ARG_DEF_PTR_FROM_EDGE): Likewise. + +2023-07-14 Monk Chiang + + * common/config/riscv/riscv-common.cc: + (riscv_implied_info): Add zihintntl item. + (riscv_ext_version_table): Ditto. + (riscv_ext_flag_table): Ditto. + * config/riscv/riscv-opts.h (MASK_ZIHINTNTL): New macro. + (TARGET_ZIHINTNTL): Ditto. + +2023-07-14 Die Li + + * config/riscv/riscv.md: Remove redundant portion in and3. + +2023-07-14 Oleg Endo + + PR target/101469 + * config/sh/sh.md (peephole2): Handle case where eliminated reg is also + used by the address of the following memory operand. + 2023-07-13 Mikael Pettersson PR target/107841 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index f1d3077..fc4e8ed 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230714 +20230715 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 19cf1da..d1ba71b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2023-07-14 Nathaniel Shead + + * constexpr.cc (cxx_eval_constant_expression): Pass t to get_value. + +2023-07-14 Jason Merrill + + PR c++/110344 + * constexpr.cc (cxx_eval_constant_expression): Move P2738 handling + after heap handling. + * name-lookup.cc (get_cxx_dialect_name): Add C++26. + +2023-07-14 Marek Polacek + Jason Merrill + + PR c++/109876 + * decl.cc (cp_finish_decl): Set TREE_CONSTANT when initializing + an object of empty class type. + * pt.cc (value_dependent_expression_p) : Treat a + constexpr-declared non-constant variable as value-dependent. + 2023-07-11 Patrick Palka PR c++/110580 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7f8d96f..b864810 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,43 @@ +2023-07-14 Mikael Morin + + PR fortran/92178 + * trans.h (gfc_reset_vptr): Add class_container argument. + * trans-expr.cc (gfc_reset_vptr): Ditto. If a valid vptr can + be obtained through class_container argument, bypass evaluation + of e. + (gfc_conv_procedure_call): Wrap the argument evaluation code + in a conditional if the associated dummy is optional. Evaluate + the data reference to a pointer now, and replace later + references with usage of the pointer. + +2023-07-14 Mikael Morin + + PR fortran/92178 + * trans.h (struct gfc_se): New field class_container. + (struct gfc_ss_info): Ditto. + (gfc_evaluate_data_ref_now): New prototype. + * trans.cc (gfc_evaluate_data_ref_now): Implement it. + * trans-array.cc (gfc_conv_ss_descriptor): Copy class_container + field from gfc_se struct to gfc_ss_info struct. + (gfc_conv_expr_descriptor): Copy class_container field from + gfc_ss_info struct to gfc_se struct. + * trans-expr.cc (gfc_conv_class_to_class): Use class container + set in class_container field if available. + (gfc_conv_variable): Set class_container field on encountering + class variables or components, clear it on encountering + non-class components. + (gfc_conv_procedure_call): Evaluate data ref to a pointer now, + and replace later references by usage of the pointer. + +2023-07-14 Mikael Morin + + PR fortran/92178 + * trans-expr.cc (gfc_conv_procedure_call): Use a separate gfc_se + struct, initalized from parmse, to generate the class wrapper. + After the class wrapper code has been generated, copy it back + depending on whether parameter deallocation code has been + generated. + 2023-07-13 Mikael Morin PR fortran/106050 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 58d58c0..e6f2c80 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,68 @@ +2023-07-14 Jason Merrill + + PR c++/110344 + * g++.dg/cpp0x/constexpr-cast2.C: Adjust for P2738. + * g++.dg/ipa/devirt-45.C: Handle -fimplicit-constexpr. + +2023-07-14 Roger Sayle + + PR target/110588 + * gcc.target/i386/pr110588.c: New test case. + +2023-07-14 Marek Polacek + Jason Merrill + + PR c++/109876 + * g++.dg/cpp0x/constexpr-template12.C: New test. + * g++.dg/cpp1z/constexpr-template1.C: New test. + * g++.dg/cpp1z/constexpr-template2.C: New test. + +2023-07-14 Uros Bizjak + + PR target/110206 + * gcc.target/i386/pr110206.c: New test. + +2023-07-14 Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-7.c: + Adapt testcase for link fail. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-1.c: New test. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c: New test. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-3.c: New test. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-1.c: New test. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-2.c: New test. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm_run-3.c: New test. + +2023-07-14 Mikael Morin + + PR fortran/92178 + * gfortran.dg/intent_out_21.f90: New test. + +2023-07-14 Mikael Morin + + PR fortran/92178 + * gfortran.dg/intent_out_20.f90: New test. + +2023-07-14 Mikael Morin + + PR fortran/92178 + * gfortran.dg/intent_out_19.f90: New test. + +2023-07-14 Tamar Christina + + PR tree-optimization/109154 + * gcc.dg/vect/vect-ifcvt-20.c: New test. + +2023-07-14 Tamar Christina + + PR tree-optimization/109154 + * gcc.dg/vect/vect-ifcvt-19.c: New test. + +2023-07-14 Monk Chiang + + * gcc.target/riscv/arch-22.c: New test. + * gcc.target/riscv/predef-28.c: New test. + 2023-07-13 Mikael Pettersson PR target/107841 -- cgit v1.1 From 97ceaa110e1607ec8f4f1223200868e1642f3cc7 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sat, 15 Jul 2023 09:47:36 -0400 Subject: c++: mangling template-id of unknown template [PR110524] This fixes a crash when mangling an ADL-enabled call to a template-id naming an unknown template (as per P0846R0). PR c++/110524 gcc/cp/ChangeLog: * mangle.cc (write_expression): Handle TEMPLATE_ID_EXPR whose template is already an IDENTIFIER_NODE. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/fn-template26.C: New test. --- gcc/cp/mangle.cc | 3 ++- gcc/testsuite/g++.dg/cpp2a/fn-template26.C | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/fn-template26.C (limited to 'gcc') diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 7dab4e6..bef0fda 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -3312,7 +3312,8 @@ write_expression (tree expr) else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR) { tree fn = TREE_OPERAND (expr, 0); - fn = OVL_NAME (fn); + if (!identifier_p (fn)) + fn = OVL_NAME (fn); if (IDENTIFIER_ANY_OP_P (fn)) write_string ("on"); write_unqualified_id (fn); diff --git a/gcc/testsuite/g++.dg/cpp2a/fn-template26.C b/gcc/testsuite/g++.dg/cpp2a/fn-template26.C new file mode 100644 index 0000000..d4a17eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/fn-template26.C @@ -0,0 +1,16 @@ +// PR c++/110524 +// { dg-do compile { target c++20 } } + +template +auto f(T t) -> decltype(g(t)); + +namespace N { + struct A { }; + template void g(T); +}; + +int main() { + f(N::A{}); +} + +// { dg-final { scan-assembler "_Z1fIN1N1AEEDTcl1gIT_Efp_EES2_" } } -- cgit v1.1 From 0de651db45c758f54e9ed917069795a3835499de Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sat, 15 Jul 2023 09:50:51 -0400 Subject: c++: copy elision w/ obj arg and static memfn call [PR110441] Here the call A().f() is represented as a COMPOUND_EXPR whose first operand is the otherwise unused object argument A() and second operand is the call result (both are TARGET_EXPRs). Within the return statement, this outermost COMPOUND_EXPR ends up foiling the copy elision check in build_special_member_call, resulting in us introducing a bogus call to the deleted move constructor. (Within the variable initialization, which goes through ocp_convert instead of convert_for_initialization, we've already been eliding the copy -- despite the outermost COMPOUND_EXPR -- ever since r10-7410-g72809d6fe8e085 made ocp_convert look through COMPOUND_EXPR). In contrast I noticed '(A(), A::f())' (which should be equivalent to the above call) is represented with the COMPOUND_EXPR inside the RHS's TARGET_EXPR initializer thanks to a special case in cp_build_compound_expr. So this patch fixes this by making keep_unused_object_arg use cp_build_compound_expr as well. PR c++/110441 gcc/cp/ChangeLog: * call.cc (keep_unused_object_arg): Use cp_build_compound_expr instead of building a COMPOUND_EXPR directly. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/elide8.C: New test. --- gcc/cp/call.cc | 2 +- gcc/testsuite/g++.dg/cpp1z/elide8.C | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/elide8.C (limited to 'gcc') diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 15a3d6f..976330c 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -5216,7 +5216,7 @@ keep_unused_object_arg (tree result, tree obj, tree fn) if (TREE_THIS_VOLATILE (a)) a = build_this (a); if (TREE_SIDE_EFFECTS (a)) - return build2 (COMPOUND_EXPR, TREE_TYPE (result), a, result); + return cp_build_compound_expr (a, result, tf_error); return result; } diff --git a/gcc/testsuite/g++.dg/cpp1z/elide8.C b/gcc/testsuite/g++.dg/cpp1z/elide8.C new file mode 100644 index 0000000..7d471be --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/elide8.C @@ -0,0 +1,25 @@ +// PR c++/110441 +// { dg-do compile { target c++11 } } + +struct immovable { + immovable(immovable &&) = delete; +}; + +struct A { + static immovable f(); +}; + +immovable f() { + immovable m = A().f(); // { dg-error "deleted" "" { target c++14_down } } + return A().f(); // { dg-error "deleted" "" { target c++14_down } } +} + +struct B { + A* operator->(); +}; + +immovable g() { + B b; + immovable m = b->f(); // { dg-error "deleted" "" { target c++14_down } } + return b->f(); // { dg-error "deleted" "" { target c++14_down } } +} -- cgit v1.1 From 96d1e233f2f06605628afea29797d1e6f1c69c14 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sat, 15 Jul 2023 17:20:24 +0000 Subject: hppa: Modify TLS patterns to provide both 32 and 64-bit support. 2023-07-15 John David Anglin gcc/ChangeLog: * config/pa/pa.md: Define constants R1_REGNUM, R19_REGNUM and R27_REGNUM. (tgd_load): Restrict to !TARGET_64BIT. Use register constants. (tld_load): Likewise. (tgd_load_pic): Change to expander. (tld_load_pic, tld_offset_load, tp_load): Likewise. (tie_load_pic, tle_load): Likewise. (tgd_load_picsi, tgd_load_picdi): New. (tld_load_picsi, tld_load_picdi): New. (tld_offset_load): New. (tp_load): New. (tie_load_picsi, tie_load_picdi): New. (tle_load): New. --- gcc/config/pa/pa.md | 196 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 162 insertions(+), 34 deletions(-) (limited to 'gcc') diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 726e127..f603591 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -108,6 +108,14 @@ (MAX_17BIT_OFFSET 262100) ; 17-bit branch ]) +;; Register numbers + +(define_constants + [(R1_REGNUM 1) + (R19_REGNUM 19) + (R27_REGNUM 27) + ]) + ;; Mode and code iterators ;; This mode iterator allows :P to be used for patterns that operate on @@ -10262,9 +10270,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" (define_insn "tgd_load" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD)) - (clobber (reg:SI 1)) - (use (reg:SI 27))] - "" + (clobber (reg:SI R1_REGNUM)) + (use (reg:SI R27_REGNUM))] + "!TARGET_64BIT" "* { return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\"; @@ -10272,12 +10280,25 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "multi") (set_attr "length" "8")]) -(define_insn "tgd_load_pic" +(define_expand "tgd_load_pic" + [(set (match_operand 0 "register_operand") + (unspec [(match_operand 1 "tgd_symbolic_operand")] UNSPEC_TLSGD_PIC)) + (clobber (reg R1_REGNUM))] + "" +{ + if (TARGET_64BIT) + emit_insn (gen_tgd_load_picdi (operands[0], operands[1])); + else + emit_insn (gen_tgd_load_picsi (operands[0], operands[1])); + DONE; +}) + +(define_insn "tgd_load_picsi" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC)) - (clobber (reg:SI 1)) - (use (reg:SI 19))] - "" + (clobber (reg:SI R1_REGNUM)) + (use (reg:SI R19_REGNUM))] + "!TARGET_64BIT" "* { return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\"; @@ -10285,12 +10306,25 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "multi") (set_attr "length" "8")]) +(define_insn "tgd_load_picdi" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC)) + (clobber (reg:DI R1_REGNUM)) + (use (reg:DI R27_REGNUM))] + "TARGET_64BIT" + "* +{ + return \"addil LT'%1-$tls_gdidx$,%%r27\;ldo RT'%1-$tls_gdidx$(%%r1),%0\"; +}" + [(set_attr "type" "multi") + (set_attr "length" "8")]) + (define_insn "tld_load" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM)) - (clobber (reg:SI 1)) - (use (reg:SI 27))] - "" + (clobber (reg:SI R1_REGNUM)) + (use (reg:SI R27_REGNUM))] + "!TARGET_64BIT" "* { return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\"; @@ -10298,12 +10332,25 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "multi") (set_attr "length" "8")]) -(define_insn "tld_load_pic" +(define_expand "tld_load_pic" + [(set (match_operand 0 "register_operand") + (unspec [(match_operand 1 "tld_symbolic_operand")] UNSPEC_TLSLDM_PIC)) + (clobber (reg R1_REGNUM))] + "" +{ + if (TARGET_64BIT) + emit_insn (gen_tld_load_picdi (operands[0], operands[1])); + else + emit_insn (gen_tld_load_picsi (operands[0], operands[1])); + DONE; +}) + +(define_insn "tld_load_picsi" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC)) - (clobber (reg:SI 1)) - (use (reg:SI 19))] - "" + (clobber (reg:SI R1_REGNUM)) + (use (reg:SI R19_REGNUM))] + "!TARGET_64BIT" "* { return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\"; @@ -10311,12 +10358,40 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "multi") (set_attr "length" "8")]) -(define_insn "tld_offset_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] +(define_insn "tld_load_picdi" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC)) + (clobber (reg:DI R1_REGNUM)) + (use (reg:DI R27_REGNUM))] + "TARGET_64BIT" + "* +{ + return \"addil LT'%1-$tls_ldidx$,%%r27\;ldo RT'%1-$tls_ldidx$(%%r1),%0\"; +}" + [(set_attr "type" "multi") + (set_attr "length" "8")]) + +(define_expand "tld_offset_load" + [(set (match_operand 0 "register_operand") + (plus (unspec [(match_operand 1 "tld_symbolic_operand")] UNSPEC_TLSLDO) - (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:SI 1))] + (match_operand 2 "register_operand"))) + (clobber (reg R1_REGNUM))] + "" +{ + if (TARGET_64BIT) + emit_insn (gen_tld_offset_loaddi (operands[0], operands[1], operands[2])); + else + emit_insn (gen_tld_offset_loadsi (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_insn "tld_offset_load" + [(set (match_operand:P 0 "register_operand" "=r") + (plus:P (unspec:P [(match_operand 1 "tld_symbolic_operand" "")] + UNSPEC_TLSLDO) + (match_operand:P 2 "register_operand" "r"))) + (clobber (reg:P R1_REGNUM))] "" "* { @@ -10325,9 +10400,21 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "multi") (set_attr "length" "8")]) -(define_insn "tp_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(const_int 0)] UNSPEC_TP))] +(define_expand "tp_load" + [(set (match_operand 0 "register_operand") + (unspec [(const_int 0)] UNSPEC_TP))] + "" +{ + if (TARGET_64BIT) + emit_insn (gen_tp_loaddi (operands[0])); + else + emit_insn (gen_tp_loadsi (operands[0])); + DONE; +}) + +(define_insn "tp_load" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(const_int 0)] UNSPEC_TP))] "" "mfctl %%cr27,%0" [(set_attr "type" "multi") @@ -10336,9 +10423,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" (define_insn "tie_load" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE)) - (clobber (reg:SI 1)) - (use (reg:SI 27))] - "" + (clobber (reg:SI R1_REGNUM)) + (use (reg:SI R27_REGNUM))] + "!TARGET_64BIT" "* { return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\"; @@ -10346,12 +10433,25 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "multi") (set_attr "length" "8")]) -(define_insn "tie_load_pic" +(define_expand "tie_load_pic" + [(set (match_operand 0 "register_operand") + (unspec [(match_operand 1 "tie_symbolic_operand")] UNSPEC_TLSIE_PIC)) + (clobber (reg R1_REGNUM))] + "" +{ + if (TARGET_64BIT) + emit_insn (gen_tie_load_picdi (operands[0], operands[1])); + else + emit_insn (gen_tie_load_picsi (operands[0], operands[1])); + DONE; +}) + +(define_insn "tie_load_picsi" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC)) - (clobber (reg:SI 1)) - (use (reg:SI 19))] - "" + (clobber (reg:SI R1_REGNUM)) + (use (reg:SI R19_REGNUM))] + "!TARGET_64BIT" "* { return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\"; @@ -10359,12 +10459,40 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "multi") (set_attr "length" "8")]) -(define_insn "tle_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")] +(define_insn "tie_load_picdi" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC)) + (clobber (reg:DI R1_REGNUM)) + (use (reg:DI R27_REGNUM))] + "!TARGET_64BIT" + "* +{ + return \"addil LT'%1-$tls_ieoff$,%%r27\;ldd RT'%1-$tls_ieoff$(%%r1),%0\"; +}" + [(set_attr "type" "multi") + (set_attr "length" "8")]) + +(define_expand "tle_load" + [(set (match_operand 0 "register_operand") + (plus (unspec [(match_operand 1 "tle_symbolic_operand")] UNSPEC_TLSLE) - (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:SI 1))] + (match_operand 2 "register_operand"))) + (clobber (reg R1_REGNUM))] + "" +{ + if (TARGET_64BIT) + emit_insn (gen_tle_loaddi (operands[0], operands[1], operands[2])); + else + emit_insn (gen_tle_loadsi (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_insn "tle_load" + [(set (match_operand:P 0 "register_operand" "=r") + (plus:P (unspec:P [(match_operand 1 "tle_symbolic_operand" "")] + UNSPEC_TLSLE) + (match_operand:P 2 "register_operand" "r"))) + (clobber (reg:P R1_REGNUM))] "" "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0" [(set_attr "type" "multi") -- cgit v1.1 From 05a1156d03f5c9a2a7d646340e82f82c51cbe0b0 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 15 Jul 2023 21:35:04 +0000 Subject: Update my contrib entry Committed as obvious after making sure the documentation still builds. gcc/ChangeLog: * doc/contrib.texi: Update my entry. --- gcc/doc/contrib.texi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi index fa551c5..d7b73e1 100644 --- a/gcc/doc/contrib.texi +++ b/gcc/doc/contrib.texi @@ -809,7 +809,8 @@ Marek Polacek for his work on the C front end, the sanitizers and general bug fixing. @item -Andrew Pinski for processing bug reports by the dozen. +Andrew Pinski for processing bug reports by the dozen, maintenance of the +Objective-C runtime libraries, and many scalar optimizations. @item Ovidiu Predescu for his work on the Objective-C front end and runtime -- cgit v1.1 From 87646d160fa1a1d965610c2f0b17b53a465a45b2 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Sat, 15 Jul 2023 18:44:25 -0400 Subject: testsuite: Require 128 bit long double for ibmlongdouble. pr103628.f90 adds the -mabi=ibmlongdouble option, but AIX defaults to 64 bit long double. This patch adds -mlong-double-128 to ensure that the testcase is compiled with 128 bit long double. gcc/testsuite/ChangeLog: * gfortran.dg/pr103628.f90: Add -mlong-double-128 option. Signed-off-by: David Edelsohn --- gcc/testsuite/gfortran.dg/pr103628.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/gfortran.dg/pr103628.f90 b/gcc/testsuite/gfortran.dg/pr103628.f90 index 255d5bd..98ec0f4 100644 --- a/gcc/testsuite/gfortran.dg/pr103628.f90 +++ b/gcc/testsuite/gfortran.dg/pr103628.f90 @@ -1,5 +1,5 @@ ! { dg-do compile { target powerpc*-*-* } } -! { dg-options "-O2 -mabi=ibmlongdouble" } +! { dg-options "-O2 -mlong-double-128 -mabi=ibmlongdouble" } ! Test to ensure that it reports an "Cannot simplify expression" error ! instead of throwing an ICE when the memory represent of the HOLLERITH -- cgit v1.1 From d76d19c9bc5ef1138af65fa3546eb628b7a756c9 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 16 Jul 2023 00:16:53 +0000 Subject: Daily bump. --- gcc/ChangeLog | 20 ++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/testsuite/ChangeLog | 14 ++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 165f9f4..42057d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2023-07-15 Andrew Pinski + + * doc/contrib.texi: Update my entry. + +2023-07-15 John David Anglin + + * config/pa/pa.md: Define constants R1_REGNUM, R19_REGNUM and + R27_REGNUM. + (tgd_load): Restrict to !TARGET_64BIT. Use register constants. + (tld_load): Likewise. + (tgd_load_pic): Change to expander. + (tld_load_pic, tld_offset_load, tp_load): Likewise. + (tie_load_pic, tle_load): Likewise. + (tgd_load_picsi, tgd_load_picdi): New. + (tld_load_picsi, tld_load_picdi): New. + (tld_offset_load): New. + (tp_load): New. + (tie_load_picsi, tie_load_picdi): New. + (tle_load): New. + 2023-07-14 Christophe Lyon * config/arm/arm-mve-builtins-base.cc (vcmlaq, vcmlaq_rot90) diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index fc4e8ed..d452cda 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230715 +20230716 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d1ba71b..108312d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2023-07-15 Patrick Palka + + PR c++/110441 + * call.cc (keep_unused_object_arg): Use cp_build_compound_expr + instead of building a COMPOUND_EXPR directly. + +2023-07-15 Patrick Palka + + PR c++/110524 + * mangle.cc (write_expression): Handle TEMPLATE_ID_EXPR + whose template is already an IDENTIFIER_NODE. + 2023-07-14 Nathaniel Shead * constexpr.cc (cxx_eval_constant_expression): Pass t to get_value. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e6f2c80..8e19069 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2023-07-15 David Edelsohn + + * gfortran.dg/pr103628.f90: Add -mlong-double-128 option. + +2023-07-15 Patrick Palka + + PR c++/110441 + * g++.dg/cpp1z/elide8.C: New test. + +2023-07-15 Patrick Palka + + PR c++/110524 + * g++.dg/cpp2a/fn-template26.C: New test. + 2023-07-14 Jason Merrill PR c++/110344 -- cgit v1.1 From 1d203d4c90adb064edfa9680768d1f83a41f17e0 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 16 Jul 2023 23:53:56 +0200 Subject: Avoid double profile udpate in try_peel_loop try_peel_loop uses gimple_duplicate_loop_body_to_header_edge which subtracts the profile from the original loop. However then it tries to scale the profile in a wrong way (it forces header count to be entry count). This eliminates to profile misupdates in the internal loop of sphinx3. gcc/ChangeLog: PR middle-end/110649 * tree-ssa-loop-ivcanon.cc (try_peel_loop): Avoid double profile update. --- gcc/tree-ssa-loop-ivcanon.cc | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc index 0117dbf..bdb738a 100644 --- a/gcc/tree-ssa-loop-ivcanon.cc +++ b/gcc/tree-ssa-loop-ivcanon.cc @@ -1152,6 +1152,7 @@ try_peel_loop (class loop *loop, } if (may_be_zero) bitmap_clear_bit (wont_exit, 1); + if (!gimple_duplicate_loop_body_to_header_edge ( loop, loop_preheader_edge (loop), npeel, wont_exit, exit, &edges_to_remove, DLTHE_FLAG_UPDATE_FREQ)) @@ -1168,18 +1169,6 @@ try_peel_loop (class loop *loop, adjust_loop_info_after_peeling (loop, npeel, true); profile_count entry_count = profile_count::zero (); - edge e; - edge_iterator ei; - FOR_EACH_EDGE (e, ei, loop->header->preds) - if (e->src != loop->latch) - { - if (e->src->count.initialized_p ()) - entry_count += e->src->count; - gcc_assert (!flow_bb_inside_loop_p (loop, e->src)); - } - profile_probability p; - p = entry_count.probability_in (loop->header->count); - scale_loop_profile (loop, p, -1); bitmap_set_bit (peeled_loops, loop->num); return true; } -- cgit v1.1 From c62791fa413a49fc6476ce186b324250f8ae6d40 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 16 Jul 2023 23:55:14 +0200 Subject: Fix optimize_mask_stores profile update While looking into sphinx3 regression I noticed that vectorizer produces BBs with overall probability count 120%. This patch fixes it. Richi, I don't know how to create a testcase, but having one would be nice. Bootstrapped/regtested x86_64-linux, will commit it shortly. gcc/ChangeLog: PR tree-optimization/110649 * tree-vect-loop.cc (optimize_mask_stores): Set correctly probability of the if-then-else construct. --- gcc/tree-vect-loop.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 7d917bf..61343ea 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -11680,6 +11680,7 @@ optimize_mask_stores (class loop *loop) efalse = make_edge (bb, store_bb, EDGE_FALSE_VALUE); /* Put STORE_BB to likely part. */ efalse->probability = profile_probability::unlikely (); + e->probability = efalse->probability.invert (); store_bb->count = efalse->count (); make_single_succ_edge (store_bb, join_bb, EDGE_FALLTHRU); if (dom_info_available_p (CDI_DOMINATORS)) -- cgit v1.1 From 061f74c06735e1fa35b910ae0bcf01b61a74ec23 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 16 Jul 2023 23:56:59 +0200 Subject: Fix profile update in scale_profile_for_vect_loop When vectorizing 4 times, we sometimes do for <4x vectorized body> for <2x vectorized body> for <1x vectorized body> Here the second two fors handling epilogue never iterates. Currently vecotrizer thinks that the middle for itrates twice. This turns out to be scale_profile_for_vect_loop that uses niter_for_unrolled_loop. At that time we know epilogue will iterate at most 2 times but niter_for_unrolled_loop does not know that the last iteration will be taken by the epilogue-of-epilogue and thus it think that the loop may iterate once and exit in middle of second iteration. We already do correct job updating niter bounds and this is just ordering issue. This patch makes us to first update the bounds and then do updating of the loop. I re-implemented the function more correctly and precisely. The loop reducing iteration factor for overly flat profiles is bit funny, but only other method I can think of is to compute sreal scale that would have similar overhead I think. Bootstrapped/regtested x86_64-linux, will commit it shortly. gcc/ChangeLog: PR middle-end/110649 * tree-vect-loop.cc (scale_profile_for_vect_loop): Rewrite. (vect_transform_loop): Move scale_profile_for_vect_loop after upper bound updates. --- gcc/tree-vect-loop.cc | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 61343ea..b44fb9c 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -10842,31 +10842,30 @@ vect_get_loop_len (loop_vec_info loop_vinfo, gimple_stmt_iterator *gsi, static void scale_profile_for_vect_loop (class loop *loop, unsigned vf) { - edge preheader = loop_preheader_edge (loop); - /* Reduce loop iterations by the vectorization factor. */ - gcov_type new_est_niter = niter_for_unrolled_loop (loop, vf); - profile_count freq_h = loop->header->count, freq_e = preheader->count (); - - if (freq_h.nonzero_p ()) - { - profile_probability p; - - /* Avoid dropping loop body profile counter to 0 because of zero count - in loop's preheader. */ - if (!(freq_e == profile_count::zero ())) - freq_e = freq_e.force_nonzero (); - p = (freq_e * (new_est_niter + 1)).probability_in (freq_h); - scale_loop_frequencies (loop, p); - } - + /* Loop body executes VF fewer times and exit increases VF times. */ edge exit_e = single_exit (loop); - exit_e->probability = profile_probability::always () / (new_est_niter + 1); - - edge exit_l = single_pred_edge (loop->latch); - profile_probability prob = exit_l->probability; - exit_l->probability = exit_e->probability.invert (); - if (prob.initialized_p () && exit_l->probability.initialized_p ()) - scale_bbs_frequencies (&loop->latch, 1, exit_l->probability / prob); + profile_count entry_count = loop_preheader_edge (loop)->count (); + + /* If we have unreliable loop profile avoid dropping entry + count bellow header count. This can happen since loops + has unrealistically low trip counts. */ + while (vf > 1 + && loop->header->count > entry_count + && loop->header->count < entry_count * vf) + vf /= 2; + + if (entry_count.nonzero_p ()) + set_edge_probability_and_rescale_others + (exit_e, + entry_count.probability_in (loop->header->count / vf)); + /* Avoid producing very large exit probability when we do not have + sensible profile. */ + else if (exit_e->probability < profile_probability::always () / (vf * 2)) + set_edge_probability_and_rescale_others (exit_e, exit_e->probability * vf); + loop->latch->count = single_pred_edge (loop->latch)->count (); + + scale_loop_profile (loop, profile_probability::always () / vf, + get_likely_max_loop_iterations_int (loop)); } /* For a vectorized stmt DEF_STMT_INFO adjust all vectorized PHI @@ -11476,7 +11475,6 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) niters_vector_mult_vf, !niters_no_overflow); unsigned int assumed_vf = vect_vf_for_cost (loop_vinfo); - scale_profile_for_vect_loop (loop, assumed_vf); /* True if the final iteration might not handle a full vector's worth of scalar iterations. */ @@ -11547,6 +11545,7 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) assumed_vf) - 1 : wi::udiv_floor (loop->nb_iterations_estimate + bias_for_assumed, assumed_vf) - 1); + scale_profile_for_vect_loop (loop, assumed_vf); if (dump_enabled_p ()) { -- cgit v1.1 From 71a907abdb4c03d4a3419190dbaad15c308ac8c7 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 17 Jul 2023 00:17:26 +0000 Subject: Daily bump. --- gcc/ChangeLog | 18 ++++++++++++++++++ gcc/DATESTAMP | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 42057d3..70103a6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2023-07-16 Jan Hubicka + + PR middle-end/110649 + * tree-vect-loop.cc (scale_profile_for_vect_loop): Rewrite. + (vect_transform_loop): Move scale_profile_for_vect_loop after + upper bound updates. + +2023-07-16 Jan Hubicka + + PR tree-optimization/110649 + * tree-vect-loop.cc (optimize_mask_stores): Set correctly + probability of the if-then-else construct. + +2023-07-16 Jan Hubicka + + PR middle-end/110649 + * tree-ssa-loop-ivcanon.cc (try_peel_loop): Avoid double profile update. + 2023-07-15 Andrew Pinski * doc/contrib.texi: Update my entry. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index d452cda..4a97c3e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230716 +20230717 -- cgit v1.1 From 1dbc1081e877c81270d2f954f2f605165fc44aa4 Mon Sep 17 00:00:00 2001 From: Kong Lingling Date: Mon, 17 Jul 2023 10:45:42 +0800 Subject: Support Intel AVX-VNNI-INT16 gcc/ChangeLog * common/config/i386/cpuinfo.h (get_available_features): Detect avxvnniint16. * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_AVXVNNIINT16_SET): New. (OPTION_MASK_ISA2_AVXVNNIINT16_UNSET): Ditto. (ix86_handle_option): Handle -mavxvnniint16. * common/config/i386/i386-cpuinfo.h (enum processor_features): Add FEATURE_AVXVNNIINT16. * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for avxvnniint16. * config.gcc: Add avxvnniint16.h. * config/i386/avxvnniint16intrin.h: New file. * config/i386/cpuid.h (bit_AVXVNNIINT16): New. * config/i386/i386-builtin.def: Add new builtins. * config/i386/i386-c.cc (ix86_target_macros_internal): Define __AVXVNNIINT16__. * config/i386/i386-options.cc (isa2_opts): Add -mavxvnniint16. (ix86_valid_target_attribute_inner_p): Handle avxvnniint16intrin.h. * config/i386/i386-isa.def: Add DEF_PTA(AVXVNNIINT16). * config/i386/i386.opt: Add option -mavxvnniint16. * config/i386/immintrin.h: Include avxvnniint16.h. * config/i386/sse.md (vpdp_): New define_insn. * doc/extend.texi: Document avxvnniint16. * doc/invoke.texi: Document -mavxvnniint16. * doc/sourcebuild.texi: Document target avxvnniint16. gcc/testsuite/ChangeLog * g++.dg/other/i386-2.C: Add -mavxvnniint16. * g++.dg/other/i386-3.C: Ditto. * gcc.target/i386/avx-check.h: Add avxvnniint16 check. * gcc.target/i386/sse-12.c: Add -mavxvnniint16. * gcc.target/i386/sse-13.c: Ditto. * gcc.target/i386/sse-14.c: Ditto. * gcc.target/i386/sse-22.c: Ditto. * gcc.target/i386/sse-23.c: Ditto. * gcc.target/i386/funcspec-56.inc: Add new target attribute. * lib/target-supports.exp (check_effective_target_avxvnniint16): New. * gcc.target/i386/avxvnniint16-1.c: Ditto. * gcc.target/i386/avxvnniint16-vpdpwusd-2.c: Ditto. * gcc.target/i386/avxvnniint16-vpdpwusds-2.c: Ditto. * gcc.target/i386/avxvnniint16-vpdpwsud-2.c: Ditto. * gcc.target/i386/avxvnniint16-vpdpwsuds-2.c: Ditto. * gcc.target/i386/avxvnniint16-vpdpwuud-2.c: Ditto. * gcc.target/i386/avxvnniint16-vpdpwuuds-2.c: Ditto. Co-authored-by: Haochen Jiang --- gcc/common/config/i386/cpuinfo.h | 2 + gcc/common/config/i386/i386-common.cc | 22 +++- gcc/common/config/i386/i386-cpuinfo.h | 1 + gcc/common/config/i386/i386-isas.h | 2 + gcc/config.gcc | 2 +- gcc/config/i386/avxvnniint16intrin.h | 138 +++++++++++++++++++++ gcc/config/i386/cpuid.h | 1 + gcc/config/i386/i386-builtin.def | 14 +++ gcc/config/i386/i386-c.cc | 2 + gcc/config/i386/i386-isa.def | 1 + gcc/config/i386/i386-options.cc | 4 +- gcc/config/i386/i386.opt | 5 + gcc/config/i386/immintrin.h | 2 + gcc/config/i386/sse.md | 32 +++++ gcc/doc/extend.texi | 5 + gcc/doc/invoke.texi | 10 +- gcc/doc/sourcebuild.texi | 3 + gcc/testsuite/g++.dg/other/i386-2.C | 2 +- gcc/testsuite/g++.dg/other/i386-3.C | 2 +- gcc/testsuite/gcc.target/i386/avx-check.h | 3 + gcc/testsuite/gcc.target/i386/avxvnniint16-1.c | 43 +++++++ .../gcc.target/i386/avxvnniint16-vpdpwsud-2.c | 71 +++++++++++ .../gcc.target/i386/avxvnniint16-vpdpwsuds-2.c | 72 +++++++++++ .../gcc.target/i386/avxvnniint16-vpdpwusd-2.c | 71 +++++++++++ .../gcc.target/i386/avxvnniint16-vpdpwusds-2.c | 72 +++++++++++ .../gcc.target/i386/avxvnniint16-vpdpwuud-2.c | 71 +++++++++++ .../gcc.target/i386/avxvnniint16-vpdpwuuds-2.c | 71 +++++++++++ gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + gcc/testsuite/gcc.target/i386/sse-12.c | 2 +- gcc/testsuite/gcc.target/i386/sse-13.c | 2 +- gcc/testsuite/gcc.target/i386/sse-14.c | 2 +- gcc/testsuite/gcc.target/i386/sse-22.c | 4 +- gcc/testsuite/gcc.target/i386/sse-23.c | 2 +- gcc/testsuite/lib/target-supports.exp | 12 ++ 34 files changed, 735 insertions(+), 15 deletions(-) create mode 100644 gcc/config/i386/avxvnniint16intrin.h create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsud-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsuds-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusd-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusds-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuud-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuuds-2.c (limited to 'gcc') diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 7c2565c..3599f9d 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -875,6 +875,8 @@ get_available_features (struct __processor_model *cpu_model, set_feature (FEATURE_AVXVNNIINT8); if (edx & bit_AVXNECONVERT) set_feature (FEATURE_AVXNECONVERT); + if (edx & bit_AVXVNNIINT16) + set_feature (FEATURE_AVXVNNIINT16); } if (avx512_usable) { diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 8cea366..32c6d00 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -119,6 +119,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_RAOINT_SET OPTION_MASK_ISA2_RAOINT #define OPTION_MASK_ISA2_AMX_COMPLEX_SET \ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_COMPLEX) +#define OPTION_MASK_ISA2_AVXVNNIINT16_SET OPTION_MASK_ISA2_AVXVNNIINT16 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same as -msse4.2. */ @@ -228,7 +229,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AVX2_UNSET \ (OPTION_MASK_ISA2_AVXIFMA_UNSET | OPTION_MASK_ISA2_AVXVNNI_UNSET \ | OPTION_MASK_ISA2_AVXVNNIINT8_UNSET | OPTION_MASK_ISA2_AVXNECONVERT_UNSET \ - | OPTION_MASK_ISA2_AVX512F_UNSET) + | OPTION_MASK_ISA2_AVXVNNIINT16_UNSET | OPTION_MASK_ISA2_AVX512F_UNSET) #define OPTION_MASK_ISA_AVX512F_UNSET \ (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX512CD_UNSET \ | OPTION_MASK_ISA_AVX512PF_UNSET | OPTION_MASK_ISA_AVX512ER_UNSET \ @@ -301,6 +302,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_PREFETCHI_UNSET OPTION_MASK_ISA2_PREFETCHI #define OPTION_MASK_ISA2_RAOINT_UNSET OPTION_MASK_ISA2_RAOINT #define OPTION_MASK_ISA2_AMX_COMPLEX_UNSET OPTION_MASK_ISA2_AMX_COMPLEX +#define OPTION_MASK_ISA2_AVXVNNIINT16_UNSET OPTION_MASK_ISA2_AVXVNNIINT16 /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -1268,6 +1270,24 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_mavxvnniint16: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AVXVNNIINT16_SET; + opts->x_ix86_isa_flags2_explicit |= + OPTION_MASK_ISA2_AVXVNNIINT16_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX2_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX2_SET; + } + else + { + opts->x_ix86_isa_flags2 &= + ~OPTION_MASK_ISA2_AVXVNNIINT16_UNSET; + opts->x_ix86_isa_flags2_explicit |= + OPTION_MASK_ISA2_AVXVNNIINT16_UNSET; + } + return true; + case OPT_mfma: if (value) { diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index 254dfec..ae4e6a0 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -255,6 +255,7 @@ enum processor_features FEATURE_PREFETCHI, FEATURE_RAOINT, FEATURE_AMX_COMPLEX, + FEATURE_AVXVNNIINT16, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index d4b0b23..fc6abde 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -186,4 +186,6 @@ ISA_NAMES_TABLE_START ISA_NAMES_TABLE_ENTRY("raoint", FEATURE_RAOINT, P_NONE, "-mraoint") ISA_NAMES_TABLE_ENTRY("amx-complex", FEATURE_AMX_COMPLEX, P_NONE, "-mamx-complex") + ISA_NAMES_TABLE_ENTRY("avxvnniint16", FEATURE_AVXVNNIINT16, + P_NONE, "-mavxvnniint16") ISA_NAMES_TABLE_END diff --git a/gcc/config.gcc b/gcc/config.gcc index 1446eb2..fc74d77 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -435,7 +435,7 @@ i[34567]86-*-* | x86_64-*-*) mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h cmpccxaddintrin.h amxfp16intrin.h prfchiintrin.h - raointintrin.h amxcomplexintrin.h" + raointintrin.h amxcomplexintrin.h avxvnniint16intrin.h" ;; ia64-*-*) extra_headers=ia64intrin.h diff --git a/gcc/config/i386/avxvnniint16intrin.h b/gcc/config/i386/avxvnniint16intrin.h new file mode 100644 index 0000000..f87d76c --- /dev/null +++ b/gcc/config/i386/avxvnniint16intrin.h @@ -0,0 +1,138 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#if !defined _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif + +#ifndef _AVXVNNIINT16INTRIN_H_INCLUDED +#define _AVXVNNIINT16INTRIN_H_INCLUDED + +#if !defined(__AVXVNNIINT16__) +#pragma GCC push_options +#pragma GCC target("avxvnniint16") +#define __DISABLE_AVXVNNIINT16__ +#endif /* __AVXVNNIINT16__ */ + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwsud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwsud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwsuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwsuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwusd_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwusd128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwusds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwusds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwuud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwuud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwuuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwuuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwsud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwsud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwsuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwsuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwusd_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwusd256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwusds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwusds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwuud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwuud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwuuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwuuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} + +#ifdef __DISABLE_AVXVNNIINT16__ +#undef __DISABLE_AVXVNNIINT16__ +#pragma GCC pop_options +#endif /* __DISABLE_AVXVNNIINT16__ */ + +#endif /* __AVXVNNIINT16INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 4cc4461..98d0f19 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -144,6 +144,7 @@ /* %edx */ #define bit_AVXVNNIINT8 (1 << 4) #define bit_AVXNECONVERT (1 << 5) +#define bit_AVXVNNIINT16 (1 << 10) #define bit_PREFETCHI (1 << 14) /* Extended State Enumeration Sub-leaf (%eax == 0xd, %ecx == 1) */ diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index 7ba5b6a..ff5b3dc 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -2740,6 +2740,20 @@ BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT8, CODE_FOR_vpdpbsuds_v4si, "__builtin_ia32 BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT8, CODE_FOR_vpdpbuud_v4si, "__builtin_ia32_vpdpbuud128", IX86_BUILTIN_VPDPBUUDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT8, CODE_FOR_vpdpbuuds_v4si, "__builtin_ia32_vpdpbuuds128", IX86_BUILTIN_VPDPBUUDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +/* AVXVNNIINT16 */ +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusd_v8si, "__builtin_ia32_vpdpwusd256", IX86_BUILTIN_VPDPWUSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusds_v8si, "__builtin_ia32_vpdpwusds256", IX86_BUILTIN_VPDPWUSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsud_v8si, "__builtin_ia32_vpdpwsud256", IX86_BUILTIN_VPDPWSUDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsuds_v8si, "__builtin_ia32_vpdpwsuds256", IX86_BUILTIN_VPDPWSUDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuud_v8si, "__builtin_ia32_vpdpwuud256", IX86_BUILTIN_VPDPWUUDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuuds_v8si, "__builtin_ia32_vpdpwuuds256", IX86_BUILTIN_VPDPWUUDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusd_v4si, "__builtin_ia32_vpdpwusd128", IX86_BUILTIN_VPDPWUSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwusds_v4si, "__builtin_ia32_vpdpwusds128", IX86_BUILTIN_VPDPWUSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsud_v4si, "__builtin_ia32_vpdpwsud128", IX86_BUILTIN_VPDPWSUDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwsuds_v4si, "__builtin_ia32_vpdpwsuds128", IX86_BUILTIN_VPDPWSUDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuud_v4si, "__builtin_ia32_vpdpwuud128", IX86_BUILTIN_VPDPWUUDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_AVXVNNIINT16, CODE_FOR_vpdpwuuds_v4si, "__builtin_ia32_vpdpwuuds128", IX86_BUILTIN_VPDPWUUDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) + /* VPCLMULQDQ */ BDESC (OPTION_MASK_ISA_VPCLMULQDQ | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpclmulqdq_v2di, "__builtin_ia32_vpclmulqdq_v2di", IX86_BUILTIN_VPCLMULQDQ2, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT) BDESC (OPTION_MASK_ISA_VPCLMULQDQ | OPTION_MASK_ISA_AVX, 0, CODE_FOR_vpclmulqdq_v4di, "__builtin_ia32_vpclmulqdq_v4di", IX86_BUILTIN_VPCLMULQDQ4, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT) diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index e7bd7cc..d3514dd 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -677,6 +677,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__RAOINT__"); if (isa_flag2 & OPTION_MASK_ISA2_AMX_COMPLEX) def_or_undef (parse_in, "__AMX_COMPLEX__"); + if (isa_flag2 & OPTION_MASK_ISA2_AVXVNNIINT16) + def_or_undef (parse_in, "__AVXVNNIINT16__"); if (TARGET_IAMCU) { def_or_undef (parse_in, "__iamcu"); diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def index 0634c6f..fbf22f7 100644 --- a/gcc/config/i386/i386-isa.def +++ b/gcc/config/i386/i386-isa.def @@ -117,3 +117,4 @@ DEF_PTA(AMX_FP16) DEF_PTA(PREFETCHI) DEF_PTA(RAOINT) DEF_PTA(AMX_COMPLEX) +DEF_PTA(AVXVNNIINT16) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 37cb5a0..d981666 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -239,7 +239,8 @@ static struct ix86_target_opts isa2_opts[] = { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 }, { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI }, { "-mraoint", OPTION_MASK_ISA2_RAOINT }, - { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX } + { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX }, + { "-mavxvnniint16", OPTION_MASK_ISA2_AVXVNNIINT16 }, }; static struct ix86_target_opts isa_opts[] = { @@ -1091,6 +1092,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("prefetchi", OPT_mprefetchi), IX86_ATTR_ISA ("raoint", OPT_mraoint), IX86_ATTR_ISA ("amx-complex", OPT_mamx_complex), + IX86_ATTR_ISA ("avxvnniint16", OPT_mavxvnniint16), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index d74f6b1..618d713 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1278,3 +1278,8 @@ Enum(lam_type) String(u57) Value(lam_u57) mamx-complex Target Mask(ISA2_AMX_COMPLEX) Var(ix86_isa_flags2) Save Support AMX-COMPLEX built-in functions and code generation. + +mavxvnniint16 +Target Mask(ISA2_AVXVNNIINT16) Var(ix86_isa_flags2) Save +Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and +AVXVNNIINT16 built-in functions and code generation. diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h index b220d87..52dc35d 100644 --- a/gcc/config/i386/immintrin.h +++ b/gcc/config/i386/immintrin.h @@ -48,6 +48,8 @@ #include +#include + #include #include diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 6bf9c99..85a5f80 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -204,6 +204,14 @@ UNSPEC_VPDPBSUDS UNSPEC_VPDPBUUD UNSPEC_VPDPBUUDS + + ;; For AVX-VNNI-INT16 support + UNSPEC_VPDPWUSD + UNSPEC_VPDPWUSDS + UNSPEC_VPDPWSUD + UNSPEC_VPDPWSUDS + UNSPEC_VPDPWUUD + UNSPEC_VPDPWUUDS ]) (define_c_enum "unspecv" [ @@ -30209,3 +30217,27 @@ "vcvtneo2ps\t{%1, %0|%0, %1}" [(set_attr "prefix" "vex") (set_attr "mode" "")]) + +(define_int_iterator VPDPWPROD + [UNSPEC_VPDPWUSD + UNSPEC_VPDPWUSDS + UNSPEC_VPDPWSUD + UNSPEC_VPDPWSUDS + UNSPEC_VPDPWUUD + UNSPEC_VPDPWUUDS]) + +(define_int_attr vpdpwprodtype + [(UNSPEC_VPDPWUSD "wusd") (UNSPEC_VPDPWUSDS "wusds") + (UNSPEC_VPDPWSUD "wsud") (UNSPEC_VPDPWSUDS "wsuds") + (UNSPEC_VPDPWUUD "wuud") (UNSPEC_VPDPWUUDS "wuuds")]) + +(define_insn "vpdp_" + [(set (match_operand:VI4_AVX 0 "register_operand" "=x") + (unspec:VI4_AVX + [(match_operand:VI4_AVX 1 "register_operand" "0") + (match_operand:VI4_AVX 2 "register_operand" "x") + (match_operand:VI4_AVX 3 "nonimmediate_operand" "xm")] + VPDPWPROD))] + "TARGET_AVXVNNIINT16" + "vpdp\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "prefix" "vex")]) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index dda3535..2646dd5 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7163,6 +7163,11 @@ Enable/disable the generation of the RAOINT instructions. @itemx no-amx-complex Enable/disable the generation of the AMX-COMPLEX instructions. +@cindex @code{target("avxvnniint16")} function attribute, x86 +@item avxvnniint16 +@itemx no-avxvnniint16 +Enable/disable the generation of the AVXVNNIINT16 instructions. + @cindex @code{target("cld")} function attribute, x86 @item cld @itemx no-cld diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index cbc1282..359887db 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1433,7 +1433,7 @@ See RS/6000 and PowerPC Options. -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 --mprefetchi -mraoint -mamx-complex +-mprefetchi -mraoint -mamx-complex -mavxvnniint16 -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops -minline-stringops-dynamically -mstringop-strategy=@var{alg} -mkl -mwidekl @@ -33552,8 +33552,10 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @need 200 @opindex mamx-complex @itemx -mamx-complex +@need 200 +@opindex mavxvnniint16 +@itemx -mavxvnniint16 These switches enable the use of instructions in the MMX, SSE, -SSE2, SSE3, SSSE3, SSE4, SSE4A, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, AES, PCLMUL, CLFLUSHOPT, CLWB, FSGSBASE, PTWRITE, RDRND, F16C, FMA, PCONFIG, WBNOINVD, FMA4, PREFETCHW, RDPID, PREFETCHWT1, RDSEED, SGX, XOP, LWP, @@ -33563,8 +33565,8 @@ GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AMX-FP16, PREFETCHI, RAOINT, -AMX-COMPLEX or CLDEMOTE extended instruction sets. Each has a corresponding -@option{-mno-} option to disable use of these instructions. +AMX-COMPLEX, AVXVNNIINT16 or CLDEMOTE extended instruction sets. Each has a +corresponding @option{-mno-} option to disable use of these instructions. These extensions are also available as built-in functions: see @ref{x86 Built-in Functions}, for details of the functions enabled and diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index ffb6eb1..40919b3 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2511,6 +2511,9 @@ Target supports the execution of @code{avxneconvert} instructions. @item avxvnniint8 Target supports the execution of @code{avxvnniint8} instructions. +@item avxvnniint16 +Target supports the execution of @code{avxvnniint16} instructions. + @item amx_tile Target supports the execution of @code{amx-tile} instructions. diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C index 6fe07e1..53622df 100644 --- a/gcc/testsuite/g++.dg/other/i386-2.C +++ b/gcc/testsuite/g++.dg/other/i386-2.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex" } */ +/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C index 55c8167..3b76cee 100644 --- a/gcc/testsuite/g++.dg/other/i386-3.C +++ b/gcc/testsuite/g++.dg/other/i386-3.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex" } */ +/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/gcc.target/i386/avx-check.h b/gcc/testsuite/gcc.target/i386/avx-check.h index 666eff5..3d417ea1 100644 --- a/gcc/testsuite/gcc.target/i386/avx-check.h +++ b/gcc/testsuite/gcc.target/i386/avx-check.h @@ -32,6 +32,9 @@ main () #ifdef AVXNECONVERT && __builtin_cpu_supports ("avxneconvert") #endif +#ifdef AVXVNNIINT16 + && __builtin_cpu_supports ("avxvnniint16") +#endif ) { do_test (); diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-1.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-1.c new file mode 100644 index 0000000..6ae57b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-1.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-mavxvnniint16 -O2" } */ +/* { dg-final { scan-assembler-times "vpdpwusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsud\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsud\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsuds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwsuds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuud\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuud\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuuds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpdpwuuds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ + + +#include + +volatile __m256i x,y,z; +volatile __m128i x_,y_,z_; +volatile __mmask8 m; + +void extern +avxvnniint16_test (void) +{ + x = _mm256_dpwusd_avx_epi32 (x, y, z); + x_ = _mm_dpwusd_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwusds_avx_epi32 (x, y, z); + x_ = _mm_dpwusds_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwsud_avx_epi32 (x, y, z); + x_ = _mm_dpwsud_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwsuds_avx_epi32 (x, y, z); + x_ = _mm_dpwsuds_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwuud_avx_epi32 (x, y, z); + x_ = _mm_dpwuud_avx_epi32 (x_, y_, z_); + + x = _mm256_dpwuuds_avx_epi32 (x, y, z); + x_ = _mm_dpwuuds_avx_epi32 (x_, y_, z_); +} diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsud-2.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsud-2.c new file mode 100644 index 0000000..bc57a8a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsud-2.c @@ -0,0 +1,71 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavxvnniint16" } */ +/* { dg-require-effective-target avxvnniint16 } */ +#define AVXVNNIINT16 +#ifndef CHECK +#define CHECK "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include CHECK + +static void +CALC (int *r, int *dst, short *s1, unsigned short *s2, int size) +{ + int tempres[16]; + for (int i = 0; i < size; i++) + tempres[i] = (int) s1[i] * (unsigned int) s2[i]; + for (int i = 0; i < size / 2; i++) + { + int test = (int) dst[i] + tempres[i * 2] + tempres[i * 2 + 1]; + r[i] = test; + } +} + +void +TEST (void) +{ + int i; + union256i_d res_256; + union256i_w src1_256; + union256i_uw src2_256; + int res_ref_256[8]; + + for (i = 0; i < 16; i++) + { + int sign = i % 2 ? 1 : -1; + src1_256.a[i] = 10 + 3 * i + sign; + src2_256.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 8; i++) + res_256.a[i] = 0x7fffffff; + + CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16); + res_256.x = _mm256_dpwsud_avx_epi32 (res_256.x, src1_256.x, src2_256.x); + if (check_union256i_d (res_256, res_ref_256)) + abort (); + + union128i_d res_128; + union128i_w src1_128; + union128i_uw src2_128; + int res_ref_128[4]; + + for (i = 0; i < 8; i++) + { + int sign = i % 2 ? 1 : -1; + src1_128.a[i] = 10 + 3 * i * i + sign; + src2_128.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 4; i++) + res_128.a[i] = 0x7fffffff; + + CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8); + res_128.x = _mm_dpwsud_avx_epi32 (res_128.x, src1_128.x, src2_128.x); + if (check_union128i_d (res_128, res_ref_128)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsuds-2.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsuds-2.c new file mode 100644 index 0000000..fbcf46a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwsuds-2.c @@ -0,0 +1,72 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavxvnniint16" } */ +/* { dg-require-effective-target avxvnniint16 } */ +#define AVXVNNIINT16 +#ifndef CHECK +#define CHECK "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include CHECK + +static void +CALC (int *r, int *dst, short *s1, unsigned short *s2, int size) +{ + int tempres[16]; + for (int i = 0; i < size; i++) + tempres[i] = (int) s1[i] * (unsigned int) s2[i]; + for (int i = 0; i < size / 2; i++) + { + long long test = (long long) dst[i] + tempres[i * 2] + tempres[i * 2 + 1]; + r[i] = test > 0x7FFFFFFF ? 0x7FFFFFFF : + (test < 0xffffffff80000000LL ? 0x80000000 : test); + } +} + +void +TEST (void) +{ + int i; + union256i_d res_256; + union256i_w src1_256; + union256i_uw src2_256; + int res_ref_256[8]; + + for (i = 0; i < 16; i++) + { + int sign = i % 2 ? 1 : -1; + src1_256.a[i] = 10 + 3 * i + sign; + src2_256.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 8; i++) + res_256.a[i] = 0x7fffffff; + + CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16); + res_256.x = _mm256_dpwsuds_avx_epi32 (res_256.x, src1_256.x, src2_256.x); + if (check_union256i_d (res_256, res_ref_256)) + abort (); + + union128i_d res_128; + union128i_w src1_128; + union128i_uw src2_128; + int res_ref_128[4]; + + for (i = 0; i < 8; i++) + { + int sign = i % 2 ? 1 : -1; + src1_128.a[i] = 10 + 3 * i * i + sign; + src2_128.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 4; i++) + res_128.a[i] = 0x7fffffff; + + CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8); + res_128.x = _mm_dpwsuds_avx_epi32 (res_128.x, src1_128.x, src2_128.x); + if (check_union128i_d (res_128, res_ref_128)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusd-2.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusd-2.c new file mode 100644 index 0000000..54cf271 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusd-2.c @@ -0,0 +1,71 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavxvnniint16" } */ +/* { dg-require-effective-target avxvnniint16 } */ +#define AVXVNNIINT16 +#ifndef CHECK +#define CHECK "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include CHECK + +static void +CALC (int *r, int *dst, unsigned short *s1, short *s2, int size) +{ + int tempres[16]; + for (int i = 0; i < size; i++) + tempres[i] = (unsigned int) s1[i] * (int) s2[i]; + for (int i = 0; i < size / 2; i++) + { + int test = (int) dst[i] + tempres[i * 2] + tempres[i * 2 + 1]; + r[i] = test; + } +} + +void +TEST (void) +{ + int i; + union256i_d res_256; + union256i_uw src1_256; + union256i_w src2_256; + int res_ref_256[8]; + + for (i = 0; i < 16; i++) + { + int sign = i % 2 ? 1 : -1; + src1_256.a[i] = 10 + 3 * i + sign; + src2_256.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 8; i++) + res_256.a[i] = 0x7fffffff; + + CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16); + res_256.x = _mm256_dpwusd_avx_epi32 (res_256.x, src1_256.x, src2_256.x); + if (check_union256i_d (res_256, res_ref_256)) + abort (); + + union128i_d res_128; + union128i_uw src1_128; + union128i_w src2_128; + int res_ref_128[4]; + + for (i = 0; i < 8; i++) + { + int sign = i % 2 ? 1 : -1; + src1_128.a[i] = 10 + 3 * i * i + sign; + src2_128.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 4; i++) + res_128.a[i] = 0x7fffffff; + + CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8); + res_128.x = _mm_dpwusd_avx_epi32 (res_128.x, src1_128.x, src2_128.x); + if (check_union128i_d (res_128, res_ref_128)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusds-2.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusds-2.c new file mode 100644 index 0000000..ed9594c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwusds-2.c @@ -0,0 +1,72 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavxvnniint16" } */ +/* { dg-require-effective-target avxvnniint16 } */ +#define AVXVNNIINT16 +#ifndef CHECK +#define CHECK "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include CHECK + +static void +CALC (int *r, int *dst, unsigned short *s1, short *s2, int size) +{ + int tempres[16]; + for (int i = 0; i < size; i++) + tempres[i] = (unsigned int) s1[i] * (int) s2[i]; + for (int i = 0; i < size / 2; i++) + { + long long test = (long long) dst[i] + tempres[i * 2] + tempres[i * 2 + 1]; + r[i] = test > 0x7FFFFFFF ? 0x7FFFFFFF : + (test < 0xffffffff80000000LL ? 0x80000000 : test); + } +} + +void +TEST (void) +{ + int i; + union256i_d res_256; + union256i_uw src1_256; + union256i_w src2_256; + int res_ref_256[8]; + + for (i = 0; i < 16; i++) + { + int sign = i % 2 ? 1 : -1; + src1_256.a[i] = 10 + 3 * i + sign; + src2_256.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 8; i++) + res_256.a[i] = 0x7fffffff; + + CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16); + res_256.x = _mm256_dpwusds_avx_epi32 (res_256.x, src1_256.x, src2_256.x); + if (check_union256i_d (res_256, res_ref_256)) + abort (); + + union128i_d res_128; + union128i_uw src1_128; + union128i_w src2_128; + int res_ref_128[4]; + + for (i = 0; i < 8; i++) + { + int sign = i % 2 ? 1 : -1; + src1_128.a[i] = 10 + 3 * i * i + sign; + src2_128.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 4; i++) + res_128.a[i] = 0x7fffffff; + + CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8); + res_128.x = _mm_dpwusds_avx_epi32 (res_128.x, src1_128.x, src2_128.x); + if (check_union128i_d (res_128, res_ref_128)) + abort(); +} diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuud-2.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuud-2.c new file mode 100644 index 0000000..8bdc433 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuud-2.c @@ -0,0 +1,71 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavxvnniint16" } */ +/* { dg-require-effective-target avxvnniint16 } */ +#define AVXVNNIINT16 +#ifndef CHECK +#define CHECK "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include CHECK + +static void +CALC (unsigned int *r, unsigned int *dst, unsigned short *s1, unsigned short *s2, int size) +{ + unsigned int tempres[16]; + for (int i = 0; i < size; i++) + tempres[i] = (unsigned int) s1[i] * (unsigned int) s2[i]; + for (int i = 0; i < size / 2; i++) + { + unsigned int test = (unsigned) dst[i] + tempres[i * 2] + tempres[i * 2 + 1]; + r[i] = test; + } +} + +void +TEST (void) +{ + int i; + union256i_ud res_256; + union256i_uw src1_256; + union256i_uw src2_256; + unsigned int res_ref_256[8]; + + for (i = 0; i < 16; i++) + { + int sign = i % 2 ? 1 : -1; + src1_256.a[i] = 10 + 3 * i + sign; + src2_256.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 8; i++) + res_256.a[i] = 0x7fffffff; + + CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16); + res_256.x = _mm256_dpwuud_avx_epi32 (res_256.x, src1_256.x, src2_256.x); + if (check_union256i_ud (res_256, res_ref_256)) + abort (); + + union128i_ud res_128; + union128i_uw src2_128; + union128i_uw src1_128; + unsigned int res_ref_128[4]; + + for (i = 0; i < 8; i++) + { + int sign = i % 2 ? 1 : -1; + src1_128.a[i] = 10 + 3 * i * i + sign; + src2_128.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 4; i++) + res_128.a[i] = 0x7fffffff; + + CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8); + res_128.x = _mm_dpwuud_avx_epi32 (res_128.x, src1_128.x, src2_128.x); + if (check_union128i_ud (res_128, res_ref_128)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuuds-2.c b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuuds-2.c new file mode 100644 index 0000000..3220412 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avxvnniint16-vpdpwuuds-2.c @@ -0,0 +1,71 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavxvnniint16" } */ +/* { dg-require-effective-target avxvnniint16 } */ +#define AVXVNNIINT16 +#ifndef CHECK +#define CHECK "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include CHECK + +static void +CALC (unsigned int *r, unsigned int *dst, unsigned short *s1, unsigned short *s2, int size) +{ + unsigned int tempres[16]; + for (int i = 0; i < size; i++) + tempres[i] = (unsigned int) s1[i] * (unsigned int) s2[i]; + for (int i = 0; i < size / 2; i++) + { + unsigned int test = (unsigned) dst[i] + tempres[i * 2] + tempres[i * 2 + 1]; + r[i] = test > 0xFFFFFFFF ? 0xFFFFFFFF : test; + } +} + +void +TEST (void) +{ + int i; + union256i_ud res_256; + union256i_uw src1_256; + union256i_uw src2_256; + unsigned int res_ref_256[8]; + + for (i = 0; i < 16; i++) + { + int sign = i % 2 ? 1 : -1; + src1_256.a[i] = 10 + 3 * i + sign; + src2_256.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 8; i++) + res_256.a[i] = 0x7fffffff; + + CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16); + res_256.x = _mm256_dpwuuds_avx_epi32 (res_256.x, src1_256.x, src2_256.x); + if (check_union256i_ud (res_256, res_ref_256)) + abort (); + + union128i_ud res_128; + union128i_uw src2_128; + union128i_uw src1_128; + unsigned int res_ref_128[4]; + + for (i = 0; i < 8; i++) + { + int sign = i % 2 ? 1 : -1; + src1_128.a[i] = 10 + 3 * i * i + sign; + src2_128.a[i] = sign * 10 * i * i; + } + + for (i = 0; i < 4; i++) + res_128.a[i] = 0x7fffffff; + + CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8); + res_128.x = _mm_dpwuuds_avx_epi32 (res_128.x, src1_128.x, src2_128.x); + if (check_union128i_ud (res_128, res_ref_128)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index f466962..bba0fa3 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -88,6 +88,7 @@ extern void test_amx_fp16 (void) __attribute__((__target__("amx-fp16"))); extern void test_prefetchi (void) __attribute__((__target__("prefetchi"))); extern void test_raoint (void) __attribute__((__target__("raoint"))); extern void test_amx_complex (void) __attribute__((__target__("amx-complex"))); +extern void test_avxvnniint16 (void) __attribute__((__target__("avxvnniint16"))); extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); @@ -177,6 +178,7 @@ extern void test_no_amx_fp16 (void) __attribute__((__target__("no-amx-fp16"))); extern void test_no_prefetchi (void) __attribute__((__target__("no-prefetchi"))); extern void test_no_raoint (void) __attribute__((__target__("no-raoint"))); extern void test_no_amx_complex (void) __attribute__((__target__("no-amx-complex"))); +extern void test_no_avxvnniint16 (void) __attribute__((__target__("no-avxvnniint16"))); extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c index ae4ffd1..2b7d78c 100644 --- a/gcc/testsuite/gcc.target/i386/sse-12.c +++ b/gcc/testsuite/gcc.target/i386/sse-12.c @@ -3,7 +3,7 @@ popcntintrin.h gfniintrin.h and mm_malloc.h are usable with -O -std=c89 -pedantic-errors. */ /* { dg-do compile } */ -/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex" } */ +/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16" } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c index f046a68..3369348 100644 --- a/gcc/testsuite/gcc.target/i386/sse-13.c +++ b/gcc/testsuite/gcc.target/i386/sse-13.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex" } */ +/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16" } */ /* { dg-add-options bind_pic_locally } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c index 05322f7..51c2946 100644 --- a/gcc/testsuite/gcc.target/i386/sse-14.c +++ b/gcc/testsuite/gcc.target/i386/sse-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex" } */ +/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16" } */ /* { dg-add-options bind_pic_locally } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c index 53c38b7..4982fde 100644 --- a/gcc/testsuite/gcc.target/i386/sse-22.c +++ b/gcc/testsuite/gcc.target/i386/sse-22.c @@ -103,7 +103,7 @@ #ifndef DIFFERENT_PRAGMAS -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16") #endif /* Following intrinsics require immediate arguments. They @@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1) /* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */ #ifdef DIFFERENT_PRAGMAS -#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex") +#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16") #endif #include test_1 (_cvtss_sh, unsigned short, float, 1) diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c index 50bf85a..7e9c9f2 100644 --- a/gcc/testsuite/gcc.target/i386/sse-23.c +++ b/gcc/testsuite/gcc.target/i386/sse-23.c @@ -847,6 +847,6 @@ #define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1) #define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1) -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex,avxvnniint16") #include diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 33482b2..60de239 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9856,6 +9856,18 @@ proc check_effective_target_amx_complex { } { } "-mamx-complex" ] } +# Return 1 if avxvnniint16 instructions can be compiled. +proc check_effective_target_avxvnniint16 { } { + return [check_no_compiler_messages avxvnniint16 object { + typedef int __v8si __attribute__ ((__vector_size__ (32))); + __v8si + _mm256_dpwsud_avx_epi32 (__v8si __A, __v8si __B, __v8si __C) + { + return __builtin_ia32_vpdpwsud256 (__A, __B, __C); + } + } "-O0 -mavxvnniint16" ] +} + # Return 1 if sse instructions can be compiled. proc check_effective_target_sse { } { return [check_no_compiler_messages sse object { -- cgit v1.1 From 8643bcbaafeb00da04be01909ac01e6c1ce262b3 Mon Sep 17 00:00:00 2001 From: Haochen Jiang Date: Mon, 17 Jul 2023 10:45:50 +0800 Subject: Support Intel SM3 gcc/ChangeLog: * common/config/i386/cpuinfo.h (get_available_features): Detect SM3. * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_SM3_SET, OPTION_MASK_ISA2_SM3_UNSET): New. (OPTION_MASK_ISA2_AVX_UNSET): Add SM3. (ix86_handle_option): Handle -msm3. * common/config/i386/i386-cpuinfo.h (enum processor_features): Add FEATURE_SM3. * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for SM3. * config.gcc: Add sm3intrin.h * config/i386/cpuid.h (bit_SM3): New. * config/i386/i386-builtin-types.def: Add DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, V4SI, INT). * config/i386/i386-builtin.def (BDESC): Add new builtins. * config/i386/i386-c.cc (ix86_target_macros_internal): Define __SM3__. * config/i386/i386-expand.cc (ix86_expand_args_builtin): Handle V4SI_FTYPE_V4SI_V4SI_V4SI_INT. * config/i386/i386-isa.def (SM3): Add DEF_PTA(SM3). * config/i386/i386-options.cc (isa2_opts): Add -msm3. (ix86_valid_target_attribute_inner_p): Handle sm3. * config/i386/i386.opt: Add option -msm3. * config/i386/immintrin.h: Include sm3intrin.h. * config/i386/sse.md (vsm3msg1): New define insn. (vsm3msg2): Ditto. (vsm3rnds2): Ditto. * doc/extend.texi: Document sm3. * doc/invoke.texi: Document -msm3. * doc/sourcebuild.texi: Document target sm3. * config/i386/sm3intrin.h: New file. gcc/testsuite/ChangeLog: * g++.dg/other/i386-2.C: Add -msm3. * g++.dg/other/i386-3.C: Ditto. * gcc.target/i386/avx-1.c: Add new define for immediate. * gcc.target/i386/funcspec-56.inc: Add new target attribute. * gcc.target/i386/sse-12.c: Add -msm3. * gcc.target/i386/sse-13.c: Ditto. * gcc.target/i386/sse-14.c: Ditto. * gcc.target/i386/sse-22.c: Add sm3. * gcc.target/i386/sse-23.c: Ditto. * lib/target-supports.exp (check_effective_target_sm3): New. * gcc.target/i386/sm3-1.c: New test. * gcc.target/i386/sm3-check.h: Ditto. * gcc.target/i386/sm3msg1-2.c: Ditto. * gcc.target/i386/sm3msg2-2.c: Ditto. * gcc.target/i386/sm3rnds2-2.c: Ditto. --- gcc/common/config/i386/cpuinfo.h | 2 + gcc/common/config/i386/i386-common.cc | 20 ++++- gcc/common/config/i386/i386-cpuinfo.h | 1 + gcc/common/config/i386/i386-isas.h | 1 + gcc/config.gcc | 3 +- gcc/config/i386/cpuid.h | 1 + gcc/config/i386/i386-builtin-types.def | 3 + gcc/config/i386/i386-builtin.def | 5 ++ gcc/config/i386/i386-c.cc | 2 + gcc/config/i386/i386-expand.cc | 1 + gcc/config/i386/i386-isa.def | 1 + gcc/config/i386/i386-options.cc | 2 + gcc/config/i386/i386.opt | 5 ++ gcc/config/i386/immintrin.h | 2 + gcc/config/i386/sm3intrin.h | 72 ++++++++++++++++++ gcc/config/i386/sse.md | 43 +++++++++++ gcc/doc/extend.texi | 5 ++ gcc/doc/invoke.texi | 7 +- gcc/doc/sourcebuild.texi | 3 + gcc/testsuite/g++.dg/other/i386-2.C | 2 +- gcc/testsuite/g++.dg/other/i386-3.C | 2 +- gcc/testsuite/gcc.target/i386/avx-1.c | 3 + gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + gcc/testsuite/gcc.target/i386/sm3-1.c | 17 +++++ gcc/testsuite/gcc.target/i386/sm3-check.h | 37 +++++++++ gcc/testsuite/gcc.target/i386/sm3msg1-2.c | 54 +++++++++++++ gcc/testsuite/gcc.target/i386/sm3msg2-2.c | 57 ++++++++++++++ gcc/testsuite/gcc.target/i386/sm3rnds2-2.c | 104 ++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/sse-12.c | 2 +- gcc/testsuite/gcc.target/i386/sse-13.c | 5 +- gcc/testsuite/gcc.target/i386/sse-14.c | 5 +- gcc/testsuite/gcc.target/i386/sse-22.c | 7 +- gcc/testsuite/gcc.target/i386/sse-23.c | 5 +- gcc/testsuite/lib/target-supports.exp | 15 ++++ 34 files changed, 484 insertions(+), 12 deletions(-) create mode 100644 gcc/config/i386/sm3intrin.h create mode 100644 gcc/testsuite/gcc.target/i386/sm3-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sm3-check.h create mode 100644 gcc/testsuite/gcc.target/i386/sm3msg1-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sm3msg2-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sm3rnds2-2.c (limited to 'gcc') diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 3599f9d..e5cdffe 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -877,6 +877,8 @@ get_available_features (struct __processor_model *cpu_model, set_feature (FEATURE_AVXNECONVERT); if (edx & bit_AVXVNNIINT16) set_feature (FEATURE_AVXVNNIINT16); + if (eax & bit_SM3) + set_feature (FEATURE_SM3); } if (avx512_usable) { diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 32c6d00..57b008c 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -120,6 +120,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AMX_COMPLEX_SET \ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_COMPLEX) #define OPTION_MASK_ISA2_AVXVNNIINT16_SET OPTION_MASK_ISA2_AVXVNNIINT16 +#define OPTION_MASK_ISA2_SM3_SET OPTION_MASK_ISA2_SM3 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same as -msse4.2. */ @@ -303,6 +304,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_RAOINT_UNSET OPTION_MASK_ISA2_RAOINT #define OPTION_MASK_ISA2_AMX_COMPLEX_UNSET OPTION_MASK_ISA2_AMX_COMPLEX #define OPTION_MASK_ISA2_AVXVNNIINT16_UNSET OPTION_MASK_ISA2_AVXVNNIINT16 +#define OPTION_MASK_ISA2_SM3_UNSET OPTION_MASK_ISA2_SM3 /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -351,7 +353,8 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_GENERAL_REGS_ONLY_UNSET \ OPTION_MASK_ISA2_SSE_UNSET #define OPTION_MASK_ISA2_AVX_UNSET \ - (OPTION_MASK_ISA2_AVX2_UNSET | OPTION_MASK_ISA2_VAES_UNSET) + (OPTION_MASK_ISA2_AVX2_UNSET | OPTION_MASK_ISA2_VAES_UNSET \ + | OPTION_MASK_ISA2_SM3_UNSET) #define OPTION_MASK_ISA2_SSE4_2_UNSET OPTION_MASK_ISA2_AVX_UNSET #define OPTION_MASK_ISA2_SSE4_1_UNSET OPTION_MASK_ISA2_SSE4_2_UNSET #define OPTION_MASK_ISA2_SSE4_UNSET OPTION_MASK_ISA2_SSE4_1_UNSET @@ -1288,6 +1291,21 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_msm3: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_SM3_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM3_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SM3_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM3_UNSET; + } + return true; + case OPT_mfma: if (value) { diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index ae4e6a0..c340309 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -256,6 +256,7 @@ enum processor_features FEATURE_RAOINT, FEATURE_AMX_COMPLEX, FEATURE_AVXVNNIINT16, + FEATURE_SM3, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index fc6abde..961a7f0 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -188,4 +188,5 @@ ISA_NAMES_TABLE_START P_NONE, "-mamx-complex") ISA_NAMES_TABLE_ENTRY("avxvnniint16", FEATURE_AVXVNNIINT16, P_NONE, "-mavxvnniint16") + ISA_NAMES_TABLE_ENTRY("sm3", FEATURE_SM3, P_NONE, "-msm3") ISA_NAMES_TABLE_END diff --git a/gcc/config.gcc b/gcc/config.gcc index fc74d77..fbd7360 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -435,7 +435,8 @@ i[34567]86-*-* | x86_64-*-*) mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h cmpccxaddintrin.h amxfp16intrin.h prfchiintrin.h - raointintrin.h amxcomplexintrin.h avxvnniint16intrin.h" + raointintrin.h amxcomplexintrin.h avxvnniint16intrin.h + sm3intrin.h" ;; ia64-*-*) extra_headers=ia64intrin.h diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 98d0f19..28a36ad 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -132,6 +132,7 @@ /* Extended Features Sub-leaf (%eax == 7, %ecx == 1) */ /* %eax */ +#define bit_SM3 (1 << 1) #define bit_RAOINT (1 << 3) #define bit_AVXVNNI (1 << 4) #define bit_AVX512BF16 (1 << 5) diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index cb2d0cd..899eac1 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -1416,3 +1416,6 @@ DEF_FUNCTION_TYPE (LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT) # PREFETCHI builtins DEF_FUNCTION_TYPE (VOID, PCVOID, INT) DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT) + +# SM3 builtins +DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, V4SI, INT) diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index ff5b3dc..17db19c 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -1655,6 +1655,11 @@ BDESC (OPTION_MASK_ISA_SSE2, 0, CODE_FOR_sha256msg1, 0, IX86_BUILTIN_SHA256MSG1, BDESC (OPTION_MASK_ISA_SSE2, 0, CODE_FOR_sha256msg2, 0, IX86_BUILTIN_SHA256MSG2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI) BDESC (OPTION_MASK_ISA_SSE2, 0, CODE_FOR_sha256rnds2, 0, IX86_BUILTIN_SHA256RNDS2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +/* SM3 */ +BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg1, "__builtin_ia32_vsm3msg1", IX86_BUILTIN_VSM3MSG1, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg2, "__builtin_ia32_vsm3msg2", IX86_BUILTIN_VSM3MSG2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) +BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3rnds2, "__builtin_ia32_vsm3rnds2", IX86_BUILTIN_VSM3RNDS2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT) + /* AVX512VL. */ BDESC (OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_avx2_palignrv32qi_mask, "__builtin_ia32_palignr256_mask", IX86_BUILTIN_PALIGNR256_MASK, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT_V4DI_USI_CONVERT) BDESC (OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_ssse3_palignrv16qi_mask, "__builtin_ia32_palignr128_mask", IX86_BUILTIN_PALIGNR128_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT_V2DI_UHI_CONVERT) diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index d3514dd..0cb5a6d 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -679,6 +679,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__AMX_COMPLEX__"); if (isa_flag2 & OPTION_MASK_ISA2_AVXVNNIINT16) def_or_undef (parse_in, "__AVXVNNIINT16__"); + if (isa_flag2 & OPTION_MASK_ISA2_SM3) + def_or_undef (parse_in, "__SM3__"); if (TARGET_IAMCU) { def_or_undef (parse_in, "__iamcu"); diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index f9b0dc6..b082abe 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -11219,6 +11219,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, case V4SF_FTYPE_V4SF_V4SF_V4SI_INT: case V8SF_FTYPE_V8SF_V8SF_V8SI_INT: case V16SF_FTYPE_V16SF_V16SF_V16SI_INT: + case V4SI_FTYPE_V4SI_V4SI_V4SI_INT: nargs = 4; nargs_constant = 1; break; diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def index fbf22f7..432c36e 100644 --- a/gcc/config/i386/i386-isa.def +++ b/gcc/config/i386/i386-isa.def @@ -118,3 +118,4 @@ DEF_PTA(PREFETCHI) DEF_PTA(RAOINT) DEF_PTA(AMX_COMPLEX) DEF_PTA(AVXVNNIINT16) +DEF_PTA(SM3) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index d981666..db2ff0c 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -241,6 +241,7 @@ static struct ix86_target_opts isa2_opts[] = { "-mraoint", OPTION_MASK_ISA2_RAOINT }, { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX }, { "-mavxvnniint16", OPTION_MASK_ISA2_AVXVNNIINT16 }, + { "-msm3", OPTION_MASK_ISA2_SM3 } }; static struct ix86_target_opts isa_opts[] = { @@ -1093,6 +1094,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("raoint", OPT_mraoint), IX86_ATTR_ISA ("amx-complex", OPT_mamx_complex), IX86_ATTR_ISA ("avxvnniint16", OPT_mavxvnniint16), + IX86_ATTR_ISA ("sm3", OPT_msm3), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 618d713..80a8611 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1283,3 +1283,8 @@ mavxvnniint16 Target Mask(ISA2_AVXVNNIINT16) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVXVNNIINT16 built-in functions and code generation. + +msm3 +Target Mask(ISA2_SM3) Var(ix86_isa_flags2) Save +Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and +SM3 built-in functions and code generation. diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h index 52dc35d..7731990 100644 --- a/gcc/config/i386/immintrin.h +++ b/gcc/config/i386/immintrin.h @@ -108,6 +108,8 @@ #include +#include + #include #include diff --git a/gcc/config/i386/sm3intrin.h b/gcc/config/i386/sm3intrin.h new file mode 100644 index 0000000..378c3dd --- /dev/null +++ b/gcc/config/i386/sm3intrin.h @@ -0,0 +1,72 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif + +#ifndef _SM3INTRIN_H_INCLUDED +#define _SM3INTRIN_H_INCLUDED + +#ifndef __SM3__ +#pragma GCC push_options +#pragma GCC target("sm3") +#define __DISABLE_SM3__ +#endif /* __SM3__ */ + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3msg1_epi32 (__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i) __builtin_ia32_vsm3msg1 ((__v4si) __A, (__v4si) __B, + (__v4si) __C); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3msg2_epi32 (__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i) __builtin_ia32_vsm3msg2 ((__v4si) __A, (__v4si) __B, + (__v4si) __C); +} + +#ifdef __OPTIMIZE__ +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3rnds2_epi32 (__m128i __A, __m128i __B, __m128i __C, const int __D) +{ + return (__m128i) __builtin_ia32_vsm3rnds2 ((__v4si) __A, (__v4si) __B, + (__v4si) __C, __D); +} +#else +#define _mm_sm3rnds2_epi32(A, B, C, D) \ + ((__m128i) __builtin_ia32_vsm3rnds2 ((__v4si) (A), (__v4si) (B), \ + (__v4si) (C), (int) (D))) +#endif + +#ifdef __DISABLE_SM3__ +#undef __DISABLE_SM3__ +#pragma GCC pop_options +#endif /* __DISABLE_SM3__ */ + +#endif /* _SM3INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 85a5f80..25a1e5d 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -196,6 +196,11 @@ UNSPEC_COMPLEX_FMUL UNSPEC_COMPLEX_FCMUL UNSPEC_COMPLEX_MASK + + ;; For SM3 support + UNSPEC_SM3MSG1 + UNSPEC_SM3MSG2 + UNSPEC_SM3RNDS2 ;; For AVX-VNNI-INT8 support UNSPEC_VPDPBSSD @@ -28597,6 +28602,44 @@ (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) +(define_insn "vsm3msg1" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (unspec:V4SI + [(match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 2 "register_operand" "x") + (match_operand:V4SI 3 "vector_operand" "xBm")] + UNSPEC_SM3MSG1))] + "TARGET_SM3" + "vsm3msg1\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "other") + (set_attr "mode" "TI")]) + +(define_insn "vsm3msg2" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (unspec:V4SI + [(match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 2 "register_operand" "x") + (match_operand:V4SI 3 "vector_operand" "xBm")] + UNSPEC_SM3MSG2))] + "TARGET_SM3" + "vsm3msg2\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "other") + (set_attr "mode" "TI")]) + +(define_insn "vsm3rnds2" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (unspec:V4SI + [(match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 2 "register_operand" "x") + (match_operand:V4SI 3 "vector_operand" "xBm") + (match_operand:SI 4 "const_0_to_255_operand" "n")] + UNSPEC_SM3RNDS2))] + "TARGET_SM3" + "vsm3rnds2\t{%4, %3, %2, %0|%0, %2, %3, %4}" + [(set_attr "type" "other") + (set_attr "mode" "TI") + (set_attr "length_immediate" "1")]) + (define_insn_and_split "avx512f__" [(set (match_operand:AVX512MODE2P 0 "nonimmediate_operand" "=x,m") (vec_concat:AVX512MODE2P diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 2646dd5..fa8897f 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7168,6 +7168,11 @@ Enable/disable the generation of the AMX-COMPLEX instructions. @itemx no-avxvnniint16 Enable/disable the generation of the AVXVNNIINT16 instructions. +@cindex @code{target("sm3")} function attribute, x86 +@item sm3 +@itemx no-sm3 +Enable/disable the generation of the SM3 instructions. + @cindex @code{target("cld")} function attribute, x86 @item cld @itemx no-cld diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 359887db..2671d707 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1433,7 +1433,7 @@ See RS/6000 and PowerPC Options. -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 --mprefetchi -mraoint -mamx-complex -mavxvnniint16 +-mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops -minline-stringops-dynamically -mstringop-strategy=@var{alg} -mkl -mwidekl @@ -33555,6 +33555,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @need 200 @opindex mavxvnniint16 @itemx -mavxvnniint16 +@need 200 +@opindex msm3 +@itemx -msm3 These switches enable the use of instructions in the MMX, SSE, AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, AES, PCLMUL, CLFLUSHOPT, CLWB, FSGSBASE, PTWRITE, RDRND, F16C, FMA, PCONFIG, @@ -33565,7 +33568,7 @@ GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AMX-FP16, PREFETCHI, RAOINT, -AMX-COMPLEX, AVXVNNIINT16 or CLDEMOTE extended instruction sets. Each has a +AMX-COMPLEX, AVXVNNIINT16, SM3 or CLDEMOTE extended instruction sets. Each has a corresponding @option{-mno-} option to disable use of these instructions. These extensions are also available as built-in functions: see diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 40919b3..dae5113 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2589,6 +2589,9 @@ Target supports the execution of @code{raoint} instructions. @item rdrand Target supports x86 @code{rdrand} instruction. +@item sm3 +Target supports the execution of @code{sm3} instructions. + @item sqrt_insn Target has a square root instruction that the compiler can generate. diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C index 53622df..2ec9326 100644 --- a/gcc/testsuite/g++.dg/other/i386-2.C +++ b/gcc/testsuite/g++.dg/other/i386-2.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16" } */ +/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C index 3b76cee..fe03143 100644 --- a/gcc/testsuite/g++.dg/other/i386-3.C +++ b/gcc/testsuite/g++.dg/other/i386-3.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16" } */ +/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/gcc.target/i386/avx-1.c b/gcc/testsuite/gcc.target/i386/avx-1.c index 0b2b68b..a6589de 100644 --- a/gcc/testsuite/gcc.target/i386/avx-1.c +++ b/gcc/testsuite/gcc.target/i386/avx-1.c @@ -839,6 +839,9 @@ #define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1) #define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1) +/* sm3intrin.h */ +#define __builtin_ia32_vsm3rnds2(A, B, C, D) __builtin_ia32_vsm3rnds2 (A, B, C, 1) + #include #include #include diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index bba0fa3..8dd8d9b 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -89,6 +89,7 @@ extern void test_prefetchi (void) __attribute__((__target__("prefe extern void test_raoint (void) __attribute__((__target__("raoint"))); extern void test_amx_complex (void) __attribute__((__target__("amx-complex"))); extern void test_avxvnniint16 (void) __attribute__((__target__("avxvnniint16"))); +extern void test_sm3 (void) __attribute__((__target__("sm3"))); extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); @@ -179,6 +180,7 @@ extern void test_no_prefetchi (void) __attribute__((__target__("no-pr extern void test_no_raoint (void) __attribute__((__target__("no-raoint"))); extern void test_no_amx_complex (void) __attribute__((__target__("no-amx-complex"))); extern void test_no_avxvnniint16 (void) __attribute__((__target__("no-avxvnniint16"))); +extern void test_no_sm3 (void) __attribute__((__target__("no-sm3"))); extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); diff --git a/gcc/testsuite/gcc.target/i386/sm3-1.c b/gcc/testsuite/gcc.target/i386/sm3-1.c new file mode 100644 index 0000000..0a8ea65 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm3-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msm3" } */ +/* { dg-final { scan-assembler "vsm3msg1\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm3msg2\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm3rnds2\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ + +#include + +volatile __m128i x, y, z; + +void extern +sm3_test (void) +{ + x = _mm_sm3msg1_epi32 (x, y, z); + x = _mm_sm3msg2_epi32 (x, y, z); + x = _mm_sm3rnds2_epi32 (x, y, z, 1); +} diff --git a/gcc/testsuite/gcc.target/i386/sm3-check.h b/gcc/testsuite/gcc.target/i386/sm3-check.h new file mode 100644 index 0000000..ad98474 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm3-check.h @@ -0,0 +1,37 @@ +#include +#include "m128-check.h" + +static void sm3_test (void); + +static unsigned +rol32 (unsigned w, int n) +{ + int count = n % 32; + return ((w << n) | (w >> (32 - n))); +} + +static void +__attribute__ ((noinline)) +do_test (void) +{ + sm3_test (); +} + +int +main () +{ + /* Run SM3 test only if host has SM3 support. */ + if (__builtin_cpu_supports ("sm3")) + { + do_test (); +#ifdef DEBUG + printf ("PASSED\n"); +#endif + return 0; + } + +#ifdef DEBUG + printf ("SKIPPED\n"); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/sm3msg1-2.c b/gcc/testsuite/gcc.target/i386/sm3msg1-2.c new file mode 100644 index 0000000..e08abf5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm3msg1-2.c @@ -0,0 +1,54 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msm3" } */ +/* { dg-require-effective-target sm3 } */ + +#include "sm3-check.h" +#include +#include + +static unsigned +p1 (unsigned w) +{ + return rol32 (w, 15) ^ rol32 (w, 23) ^ w; +} + +static void +compute_sm3msg1 (int *src0, int *src1, int *src2, int *res) +{ + unsigned w0, w1, w2, w3, w7, w8, w9, w10, w13, w14, w15; + + w0 = src2[0]; + w1 = src2[1]; + w2 = src2[2]; + w3 = src2[3]; + w7 = src0[0]; + w8 = src0[1]; + w9 = src0[2]; + w10 = src0[3]; + w13 = src1[0]; + w14 = src1[1]; + w15 = src1[2]; + + res[0] = p1 (w7 ^ w0 ^ rol32 (w13, 15)); + res[1] = p1 (w8 ^ w1 ^ rol32 (w14, 15)); + res[2] = p1 (w9 ^ w2 ^ rol32 (w15, 15)); + res[3] = p1 (w10 ^ w3); +} + +static void +sm3_test (void) +{ + union128i_d s1, s2, s3, res; + int res_ref[4]; + + s1.x = _mm_set_epi32 (111, 222, 333, 444); + s2.x = _mm_set_epi32 (555, 666, 777, 888); + s3.x = _mm_set_epi32 (999, 123, 456, 789); + + res.x = _mm_sm3msg1_epi32 (s1.x, s2.x, s3.x); + + compute_sm3msg1 (s1.a, s2.a, s3.a, res_ref); + + if (check_union128i_d (res, res_ref)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/sm3msg2-2.c b/gcc/testsuite/gcc.target/i386/sm3msg2-2.c new file mode 100644 index 0000000..f598631 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm3msg2-2.c @@ -0,0 +1,57 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msm3" } */ +/* { dg-require-effective-target sm3 } */ + +#include "sm3-check.h" +#include +#include + +static void +compute_sm3msg2 (int *src0, int *src1, int *src2, int *res) +{ + unsigned wtmp0, wtmp1, wtmp2, wtmp3, w3, w4, w5, w6, w10, w11, w12, w13, + w16, w17, w18, w19; + + wtmp0 = src0[0]; + wtmp1 = src0[1]; + wtmp2 = src0[2]; + wtmp3 = src0[3]; + w3 = src1[0]; + w4 = src1[1]; + w5 = src1[2]; + w6 = src1[3]; + w10 = src2[0]; + w11 = src2[1]; + w12 = src2[2]; + w13 = src2[3]; + + w16 = rol32 (w3, 7) ^ w10 ^ wtmp0; + w17 = rol32 (w4, 7) ^ w11 ^ wtmp1; + w18 = rol32 (w5, 7) ^ w12 ^ wtmp2; + w19 = rol32 (w6, 7) ^ w13 ^ wtmp3; + + w19 = w19 ^ rol32 (w16, 6) ^ rol32 (w16, 15) ^ rol32 (w16, 30) ; + + res[0] = w16; + res[1] = w17; + res[2] = w18; + res[3] = w19; +} + +static void +sm3_test (void) +{ + union128i_d s1, s2, s3, res; + int res_ref[4]; + + s1.x = _mm_set_epi32 (111, 222, 333, 444); + s2.x = _mm_set_epi32 (555, 666, 777, 888); + s3.x = _mm_set_epi32 (999, 123, 456, 789); + + res.x = _mm_sm3msg2_epi32 (s1.x, s2.x, s3.x); + + compute_sm3msg2 (s1.a, s2.a, s3.a, res_ref); + + if (check_union128i_d (res, res_ref)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/sm3rnds2-2.c b/gcc/testsuite/gcc.target/i386/sm3rnds2-2.c new file mode 100644 index 0000000..ffa3ed1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm3rnds2-2.c @@ -0,0 +1,104 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msm3" } */ +/* { dg-require-effective-target sm3 } */ + +#include "sm3-check.h" +#include +#include + +static unsigned +p0 (unsigned w) +{ + return (w ^ rol32 (w, 9) ^ rol32 (w, 17)); +} + +static unsigned +ff (unsigned x, unsigned y, unsigned z, int round) +{ + if (round < 16) + return (x ^ y ^ z); + else + return ((x & y) | (x & z) | (y & z)); +} + +static unsigned +gg (unsigned x, unsigned y, unsigned z, int round) +{ + if (round < 16) + return (x ^ y ^ z); + else + return ((x & y) | ((~x) & z)); +} + +static void +compute_sm3rnds2 (int *src0, int *src1, int *src2, int imm, int *res) +{ + unsigned s1, s2, t1, t2, co; + unsigned w[6], a[3], b[3], c[3], d[3], e[3], f[3], g[3], h[3]; + int round, i; + + a[0] = src1[3]; + b[0] = src1[2]; + c[0] = src0[3]; + d[0] = src0[2]; + e[0] = src1[1]; + f[0] = src1[0]; + g[0] = src0[1]; + h[0] = src0[0]; + w[0] = src2[0]; + w[1] = src2[1]; + w[4] = src2[2]; + w[5] = src2[3]; + + c[0] = rol32 (c[0], 9); + d[0] = rol32 (d[0], 9); + g[0] = rol32 (g[0], 19); + h[0] = rol32 (h[0], 19); + + round = imm & 0x3e; + if (round < 16) + co = 0x79cc4519; + else + co = 0x7a879d8a; + co = rol32 (co, round); + + for (i = 0; i < 2; i++) + { + s1 = rol32 ((rol32 (a[i], 12) + e[i] + co), 7); + s2 = s1 ^ rol32 (a[i], 12); + t1 = ff (a[i], b[i], c[i], round) + d[i] + s2 + (w[i] ^ w[i + 4]); + t2 = gg (e[i], f[i], g[i], round) + h[i] + s1 + w[i]; + d[i + 1] = c[i]; + c[i + 1] = rol32 (b[i], 9); + b[i + 1] = a[i]; + a[i + 1] = t1; + h[i + 1] = g[i]; + g[i + 1] = rol32 (f[i], 19); + f[i + 1] = e[i]; + e[i + 1] = p0 (t2); + co = rol32 (co, 1); + } + + res[3] = a[2]; + res[2] = b[2]; + res[1] = e[2]; + res[0] = f[2]; +} + +static void +sm3_test (void) +{ + union128i_d s1, s2, s3, res; + int res_ref[4]; + + s1.x = _mm_set_epi32 (111, 222, 333, 444); + s2.x = _mm_set_epi32 (555, 666, 777, 888); + s3.x = _mm_set_epi32 (999, 123, 456, 789); + + res.x = _mm_sm3rnds2_epi32 (s1.x, s2.x, s3.x, 22); + + compute_sm3rnds2 (s1.a, s2.a, s3.a, 22, res_ref); + + if (check_union128i_d (res, res_ref)) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c index 2b7d78c..5058be6 100644 --- a/gcc/testsuite/gcc.target/i386/sse-12.c +++ b/gcc/testsuite/gcc.target/i386/sse-12.c @@ -3,7 +3,7 @@ popcntintrin.h gfniintrin.h and mm_malloc.h are usable with -O -std=c89 -pedantic-errors. */ /* { dg-do compile } */ -/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16" } */ +/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c index 3369348..d30b365 100644 --- a/gcc/testsuite/gcc.target/i386/sse-13.c +++ b/gcc/testsuite/gcc.target/i386/sse-13.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16" } */ +/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ /* { dg-add-options bind_pic_locally } */ #include @@ -846,4 +846,7 @@ #define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1) #define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1) +/* sm3intrin.h */ +#define __builtin_ia32_vsm3rnds2(A, B, C, D) __builtin_ia32_vsm3rnds2 (A, B, C, 1) + #include diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c index 51c2946..7842005 100644 --- a/gcc/testsuite/gcc.target/i386/sse-14.c +++ b/gcc/testsuite/gcc.target/i386/sse-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16" } */ +/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ /* { dg-add-options bind_pic_locally } */ #include @@ -1054,3 +1054,6 @@ test_2 (_mm512_gf2p8affineinv_epi64_epi8, __m512i, __m512i, __m512i, 1) test_2 (_mm_gf2p8affine_epi64_epi8, __m128i, __m128i, __m128i, 1) test_2 (_mm256_gf2p8affine_epi64_epi8, __m256i, __m256i, __m256i, 1) test_2 (_mm512_gf2p8affine_epi64_epi8, __m512i, __m512i, __m512i, 1) + +/* sm3intrin.h */ +test_3 (_mm_sm3rnds2_epi32, __m128i, __m128i, __m128i, __m128i, 1) diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c index 4982fde..7537db1 100644 --- a/gcc/testsuite/gcc.target/i386/sse-22.c +++ b/gcc/testsuite/gcc.target/i386/sse-22.c @@ -103,7 +103,7 @@ #ifndef DIFFERENT_PRAGMAS -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3") #endif /* Following intrinsics require immediate arguments. They @@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1) /* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */ #ifdef DIFFERENT_PRAGMAS -#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16") +#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3") #endif #include test_1 (_cvtss_sh, unsigned short, float, 1) @@ -1099,3 +1099,6 @@ test_1 ( __bextri_u32, unsigned int, unsigned int, 1) #ifdef __x86_64__ test_1 ( __bextri_u64, unsigned long long, unsigned long long, 1) #endif + +/* sm3intrin.h */ +test_3 (_mm_sm3rnds2_epi32, __m128i, __m128i, __m128i, __m128i, 1) diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c index 7e9c9f2..3fc61b5 100644 --- a/gcc/testsuite/gcc.target/i386/sse-23.c +++ b/gcc/testsuite/gcc.target/i386/sse-23.c @@ -847,6 +847,9 @@ #define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1) #define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1) -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex,avxvnniint16") +/* sm3intrin.h */ +#define __builtin_ia32_vsm3rnds2(A, B, C, D) __builtin_ia32_vsm3rnds2 (A, B, C, 1) + +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex,avxvnniint16,sm3") #include diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 60de239..c911a82 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9868,6 +9868,21 @@ proc check_effective_target_avxvnniint16 { } { } "-O0 -mavxvnniint16" ] } +# Return 1 if sm3 instructions can be compiled. +proc check_effective_target_sm3 { } { + return [check_no_compiler_messages sm3 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + __m128i + _mm_sm3msg1_epi32 (__m128i __A, __m128i __B, __m128i __C) + { + return (__m128i) __builtin_ia32_vsm3msg1 ((__v4si) __A, + (__v4si) __B, + (__v4si) __C); + } + } "-msm3" ] +} + # Return 1 if sse instructions can be compiled. proc check_effective_target_sse { } { return [check_no_compiler_messages sse object { -- cgit v1.1 From 8644613225c0973f1a030b8806c64bc65c4f3122 Mon Sep 17 00:00:00 2001 From: Haochen Jiang Date: Mon, 17 Jul 2023 10:45:57 +0800 Subject: Support Intel SHA512 gcc/ChangeLog: * common/config/i386/cpuinfo.h (get_available_features): Detect SHA512. * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_SHA512_SET, OPTION_MASK_ISA2_SHA512_UNSET): New. (OPTION_MASK_ISA2_AVX_UNSET): Add SHA512. (ix86_handle_option): Handle -msha512. * common/config/i386/i386-cpuinfo.h (enum processor_features): Add FEATURE_SHA512. * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for sha512. * config.gcc: Add sha512intrin.h. * config/i386/cpuid.h (bit_SHA512): New. * config/i386/i386-builtin-types.def: Add DEF_FUNCTION_TYPE (V4DI, V4DI, V4DI, V2DI). * config/i386/i386-builtin.def (BDESC): Add new builtins. * config/i386/i386-c.cc (ix86_target_macros_internal): Define __SHA512__. * config/i386/i386-expand.cc (ix86_expand_args_builtin): Handle V4DI_FTYPE_V4DI_V4DI_V2DI and V4DI_FTYPE_V4DI_V2DI. * config/i386/i386-isa.def (SHA512): Add DEF_PTA(SHA512). * config/i386/i386-options.cc (isa2_opts): Add -msha512. (ix86_valid_target_attribute_inner_p): Handle sha512. * config/i386/i386.opt: Add option -msha512. * config/i386/immintrin.h: Include sha512intrin.h. * config/i386/sse.md (vsha512msg1): New define insn. (vsha512msg2): Ditto. (vsha512rnds2): Ditto. * doc/extend.texi: Document sha512. * doc/invoke.texi: Document -msha512. * doc/sourcebuild.texi: Document target sha512. * config/i386/sha512intrin.h: New file. gcc/testsuite/ChangeLog: * g++.dg/other/i386-2.C: Add -msha512. * g++.dg/other/i386-3.C: Ditto. * gcc.target/i386/funcspec-56.inc: Add new target attribute. * gcc.target/i386/sse-12.c: Add -msha512. * gcc.target/i386/sse-13.c: Ditto. * gcc.target/i386/sse-14.c: Ditto. * gcc.target/i386/sse-22.c: Add sha512. * gcc.target/i386/sse-23.c: Ditto. * lib/target-supports.exp (check_effective_target_sha512): New. * gcc.target/i386/sha512-1.c: New test. * gcc.target/i386/sha512-check.h: Ditto. * gcc.target/i386/sha512msg1-2.c: Ditto. * gcc.target/i386/sha512msg2-2.c: Ditto. * gcc.target/i386/sha512rnds2-2.c: Ditto. --- gcc/common/config/i386/cpuinfo.h | 2 + gcc/common/config/i386/i386-common.cc | 19 +++++- gcc/common/config/i386/i386-cpuinfo.h | 1 + gcc/common/config/i386/i386-isas.h | 1 + gcc/config.gcc | 2 +- gcc/config/i386/cpuid.h | 1 + gcc/config/i386/i386-builtin-types.def | 3 + gcc/config/i386/i386-builtin.def | 5 ++ gcc/config/i386/i386-c.cc | 2 + gcc/config/i386/i386-expand.cc | 2 + gcc/config/i386/i386-isa.def | 1 + gcc/config/i386/i386-options.cc | 4 +- gcc/config/i386/i386.opt | 10 ++++ gcc/config/i386/immintrin.h | 2 + gcc/config/i386/sha512intrin.h | 64 ++++++++++++++++++++ gcc/config/i386/sse.md | 40 +++++++++++++ gcc/doc/extend.texi | 5 ++ gcc/doc/invoke.texi | 10 +++- gcc/doc/sourcebuild.texi | 3 + gcc/testsuite/g++.dg/other/i386-2.C | 2 +- gcc/testsuite/g++.dg/other/i386-3.C | 2 +- gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + gcc/testsuite/gcc.target/i386/sha512-1.c | 18 ++++++ gcc/testsuite/gcc.target/i386/sha512-check.h | 43 ++++++++++++++ gcc/testsuite/gcc.target/i386/sha512msg1-2.c | 48 +++++++++++++++ gcc/testsuite/gcc.target/i386/sha512msg2-2.c | 47 +++++++++++++++ gcc/testsuite/gcc.target/i386/sha512rnds2-2.c | 85 +++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/sse-12.c | 2 +- gcc/testsuite/gcc.target/i386/sse-13.c | 2 +- gcc/testsuite/gcc.target/i386/sse-14.c | 2 +- gcc/testsuite/gcc.target/i386/sse-22.c | 4 +- gcc/testsuite/gcc.target/i386/sse-23.c | 2 +- gcc/testsuite/lib/target-supports.exp | 14 +++++ 33 files changed, 436 insertions(+), 14 deletions(-) create mode 100644 gcc/config/i386/sha512intrin.h create mode 100644 gcc/testsuite/gcc.target/i386/sha512-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sha512-check.h create mode 100644 gcc/testsuite/gcc.target/i386/sha512msg1-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sha512msg2-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sha512rnds2-2.c (limited to 'gcc') diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index e5cdffe..0cfde3e 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -879,6 +879,8 @@ get_available_features (struct __processor_model *cpu_model, set_feature (FEATURE_AVXVNNIINT16); if (eax & bit_SM3) set_feature (FEATURE_SM3); + if (eax & bit_SHA512) + set_feature (FEATURE_SHA512); } if (avx512_usable) { diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 57b008c..97c3cdf 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -121,6 +121,7 @@ along with GCC; see the file COPYING3. If not see (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_COMPLEX) #define OPTION_MASK_ISA2_AVXVNNIINT16_SET OPTION_MASK_ISA2_AVXVNNIINT16 #define OPTION_MASK_ISA2_SM3_SET OPTION_MASK_ISA2_SM3 +#define OPTION_MASK_ISA2_SHA512_SET OPTION_MASK_ISA2_SHA512 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same as -msse4.2. */ @@ -305,6 +306,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AMX_COMPLEX_UNSET OPTION_MASK_ISA2_AMX_COMPLEX #define OPTION_MASK_ISA2_AVXVNNIINT16_UNSET OPTION_MASK_ISA2_AVXVNNIINT16 #define OPTION_MASK_ISA2_SM3_UNSET OPTION_MASK_ISA2_SM3 +#define OPTION_MASK_ISA2_SHA512_UNSET OPTION_MASK_ISA2_SHA512 /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -354,7 +356,7 @@ along with GCC; see the file COPYING3. If not see OPTION_MASK_ISA2_SSE_UNSET #define OPTION_MASK_ISA2_AVX_UNSET \ (OPTION_MASK_ISA2_AVX2_UNSET | OPTION_MASK_ISA2_VAES_UNSET \ - | OPTION_MASK_ISA2_SM3_UNSET) + | OPTION_MASK_ISA2_SM3_UNSET | OPTION_MASK_ISA2_SHA512_UNSET) #define OPTION_MASK_ISA2_SSE4_2_UNSET OPTION_MASK_ISA2_AVX_UNSET #define OPTION_MASK_ISA2_SSE4_1_UNSET OPTION_MASK_ISA2_SSE4_2_UNSET #define OPTION_MASK_ISA2_SSE4_UNSET OPTION_MASK_ISA2_SSE4_1_UNSET @@ -1306,6 +1308,21 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_msha512: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_SHA512_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SHA512_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SHA512_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SHA512_UNSET; + } + return true; + case OPT_mfma: if (value) { diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index c340309..a6e34d1 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -257,6 +257,7 @@ enum processor_features FEATURE_AMX_COMPLEX, FEATURE_AVXVNNIINT16, FEATURE_SM3, + FEATURE_SHA512, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index 961a7f0..250dc87 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -189,4 +189,5 @@ ISA_NAMES_TABLE_START ISA_NAMES_TABLE_ENTRY("avxvnniint16", FEATURE_AVXVNNIINT16, P_NONE, "-mavxvnniint16") ISA_NAMES_TABLE_ENTRY("sm3", FEATURE_SM3, P_NONE, "-msm3") + ISA_NAMES_TABLE_ENTRY("sha512", FEATURE_SHA512, P_NONE, "-msha512") ISA_NAMES_TABLE_END diff --git a/gcc/config.gcc b/gcc/config.gcc index fbd7360..4e753ba 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -436,7 +436,7 @@ i[34567]86-*-* | x86_64-*-*) avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h cmpccxaddintrin.h amxfp16intrin.h prfchiintrin.h raointintrin.h amxcomplexintrin.h avxvnniint16intrin.h - sm3intrin.h" + sm3intrin.h sha512intrin.h" ;; ia64-*-*) extra_headers=ia64intrin.h diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 28a36ad..f9103f1 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -132,6 +132,7 @@ /* Extended Features Sub-leaf (%eax == 7, %ecx == 1) */ /* %eax */ +#define bit_SHA512 (1 << 0) #define bit_SM3 (1 << 1) #define bit_RAOINT (1 << 3) #define bit_AVXVNNI (1 << 4) diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index 899eac1..e946312 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -1419,3 +1419,6 @@ DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT) # SM3 builtins DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, V4SI, INT) + +# SHA512 builtins +DEF_FUNCTION_TYPE (V4DI, V4DI, V4DI, V2DI) diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index 17db19c..b9e2bad 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -1660,6 +1660,11 @@ BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg1, "__builtin_ BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg2, "__builtin_ia32_vsm3msg2", IX86_BUILTIN_VSM3MSG2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3rnds2, "__builtin_ia32_vsm3rnds2", IX86_BUILTIN_VSM3RNDS2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT) +/* SHA512 */ +BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512msg1, "__builtin_ia32_vsha512msg1", IX86_BUILTIN_VSHA512MSG1, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI) +BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512msg2, "__builtin_ia32_vsha512msg2", IX86_BUILTIN_VSHA512MSG2, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI) +BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512rnds2, "__builtin_ia32_vsha512rnds2", IX86_BUILTIN_VSHA512RNDS2, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V2DI) + /* AVX512VL. */ BDESC (OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_avx2_palignrv32qi_mask, "__builtin_ia32_palignr256_mask", IX86_BUILTIN_PALIGNR256_MASK, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT_V4DI_USI_CONVERT) BDESC (OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_ssse3_palignrv16qi_mask, "__builtin_ia32_palignr128_mask", IX86_BUILTIN_PALIGNR128_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT_V2DI_UHI_CONVERT) diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index 0cb5a6d..c6311f1 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -681,6 +681,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__AVXVNNIINT16__"); if (isa_flag2 & OPTION_MASK_ISA2_SM3) def_or_undef (parse_in, "__SM3__"); + if (isa_flag2 & OPTION_MASK_ISA2_SHA512) + def_or_undef (parse_in, "__SHA512__"); if (TARGET_IAMCU) { def_or_undef (parse_in, "__iamcu"); diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index b082abe..7e94447 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -10750,6 +10750,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, case V4SF_FTYPE_V4SF_UINT: case V4SF_FTYPE_V4SF_DI: case V4SF_FTYPE_V4SF_SI: + case V4DI_FTYPE_V4DI_V2DI: case V2DI_FTYPE_V2DI_V2DI: case V2DI_FTYPE_V16QI_V16QI: case V2DI_FTYPE_V4SI_V4SI: @@ -11047,6 +11048,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, case V8HI_FTYPE_V8DI_V8HI_UQI: case V8SI_FTYPE_V8DI_V8SI_UQI: case V4SI_FTYPE_V4SI_V4SI_V4SI: + case V4DI_FTYPE_V4DI_V4DI_V2DI: case V16SI_FTYPE_V16SI_V16SI_V16SI: case V8DI_FTYPE_V8DI_V8DI_V8DI: case V32HI_FTYPE_V32HI_V32HI_V32HI: diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def index 432c36e..28f2217 100644 --- a/gcc/config/i386/i386-isa.def +++ b/gcc/config/i386/i386-isa.def @@ -119,3 +119,4 @@ DEF_PTA(RAOINT) DEF_PTA(AMX_COMPLEX) DEF_PTA(AVXVNNIINT16) DEF_PTA(SM3) +DEF_PTA(SHA512) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index db2ff0c..d79ab01 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -241,7 +241,8 @@ static struct ix86_target_opts isa2_opts[] = { "-mraoint", OPTION_MASK_ISA2_RAOINT }, { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX }, { "-mavxvnniint16", OPTION_MASK_ISA2_AVXVNNIINT16 }, - { "-msm3", OPTION_MASK_ISA2_SM3 } + { "-msm3", OPTION_MASK_ISA2_SM3 }, + { "-msha512", OPTION_MASK_ISA2_SHA512 } }; static struct ix86_target_opts isa_opts[] = { @@ -1095,6 +1096,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("amx-complex", OPT_mamx_complex), IX86_ATTR_ISA ("avxvnniint16", OPT_mavxvnniint16), IX86_ATTR_ISA ("sm3", OPT_msm3), + IX86_ATTR_ISA ("sha512", OPT_msha512), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 80a8611..cf9dbca 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1288,3 +1288,13 @@ msm3 Target Mask(ISA2_SM3) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and SM3 built-in functions and code generation. + +mvpinsrvpextr +Target Mask(ISA2_VPINSRVPEXTR) Var(ix86_isa_flags2) Save +Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, +AVX512VL and VPINSRVPEXTR built-in functions and code generation. + +msha512 +Target Mask(ISA2_SHA512) Var(ix86_isa_flags2) Save +Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and +SHA512 built-in functions and code generation. diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h index 7731990..6f2bcef 100644 --- a/gcc/config/i386/immintrin.h +++ b/gcc/config/i386/immintrin.h @@ -110,6 +110,8 @@ #include +#include + #include #include diff --git a/gcc/config/i386/sha512intrin.h b/gcc/config/i386/sha512intrin.h new file mode 100644 index 0000000..884c2bc --- /dev/null +++ b/gcc/config/i386/sha512intrin.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif + +#ifndef _SHA512INTRIN_H_INCLUDED +#define _SHA512INTRIN_H_INCLUDED + +#ifndef __SHA512__ +#pragma GCC push_options +#pragma GCC target("sha512") +#define __DISABLE_SHA512__ +#endif /* __SHA512__ */ + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512msg1_epi64 (__m256i __A, __m128i __B) +{ + return (__m256i) __builtin_ia32_vsha512msg1 ((__v4di) __A, (__v2di) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512msg2_epi64 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsha512msg2 ((__v4di) __A, (__v4di) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512rnds2_epi64 (__m256i __A, __m256i __B, __m128i __C) +{ + return (__m256i) __builtin_ia32_vsha512rnds2 ((__v4di) __A, (__v4di) __B, + (__v2di) __C); +} + +#ifdef __DISABLE_SHA512__ +#undef __DISABLE_SHA512__ +#pragma GCC pop_options +#endif /* __DISABLE_SHA512__ */ + +#endif /* _SHA512INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 25a1e5d..e16b2b5 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -217,6 +217,12 @@ UNSPEC_VPDPWSUDS UNSPEC_VPDPWUUD UNSPEC_VPDPWUUDS + + ;; For SHA512 support + UNSPEC_SHA512MSG1 + UNSPEC_SHA512MSG2 + UNSPEC_SHA512RNDS2 + ]) (define_c_enum "unspecv" [ @@ -28640,6 +28646,40 @@ (set_attr "mode" "TI") (set_attr "length_immediate" "1")]) +(define_insn "vsha512msg1" + [(set (match_operand:V4DI 0 "register_operand" "=x") + (unspec:V4DI + [(match_operand:V4DI 1 "register_operand" "0") + (match_operand:V2DI 2 "register_operand" "x")] + UNSPEC_SHA512MSG1))] + "TARGET_SHA512" + "vsha512msg1\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "mode" "OI")]) + +(define_insn "vsha512msg2" + [(set (match_operand:V4DI 0 "register_operand" "=x") + (unspec:V4DI + [(match_operand:V4DI 1 "register_operand" "0") + (match_operand:V4DI 2 "register_operand" "x")] + UNSPEC_SHA512MSG2))] + "TARGET_SHA512" + "vsha512msg2\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "mode" "OI")]) + +(define_insn "vsha512rnds2" + [(set (match_operand:V4DI 0 "register_operand" "=x") + (unspec:V4DI + [(match_operand:V4DI 1 "register_operand" "0") + (match_operand:V4DI 2 "register_operand" "x") + (match_operand:V2DI 3 "register_operand" "x")] + UNSPEC_SHA512RNDS2))] + "TARGET_SHA512" + "vsha512rnds2\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "sselog1") + (set_attr "mode" "OI")]) + (define_insn_and_split "avx512f__" [(set (match_operand:AVX512MODE2P 0 "nonimmediate_operand" "=x,m") (vec_concat:AVX512MODE2P diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index fa8897f..7086ca9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7173,6 +7173,11 @@ Enable/disable the generation of the AVXVNNIINT16 instructions. @itemx no-sm3 Enable/disable the generation of the SM3 instructions. +@cindex @code{target("sha512")} function attribute, x86 +@item sha512 +@itemx no-sha512 +Enable/disable the generation of the SHA512 instructions. + @cindex @code{target("cld")} function attribute, x86 @item cld @itemx no-cld diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 2671d707..433ccf3 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1433,7 +1433,7 @@ See RS/6000 and PowerPC Options. -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 --mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 +-mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops -minline-stringops-dynamically -mstringop-strategy=@var{alg} -mkl -mwidekl @@ -33558,6 +33558,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @need 200 @opindex msm3 @itemx -msm3 +@need 200 +@opindex msha512 +@itemx -msha512 These switches enable the use of instructions in the MMX, SSE, AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, AES, PCLMUL, CLFLUSHOPT, CLWB, FSGSBASE, PTWRITE, RDRND, F16C, FMA, PCONFIG, @@ -33568,8 +33571,9 @@ GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AMX-FP16, PREFETCHI, RAOINT, -AMX-COMPLEX, AVXVNNIINT16, SM3 or CLDEMOTE extended instruction sets. Each has a -corresponding @option{-mno-} option to disable use of these instructions. +AMX-COMPLEX, AVXVNNIINT16, SM3, SHA512 or CLDEMOTE extended instruction sets. +Each has a corresponding @option{-mno-} option to disable use of these +instructions. These extensions are also available as built-in functions: see @ref{x86 Built-in Functions}, for details of the functions enabled and diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index dae5113..54a062d 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2589,6 +2589,9 @@ Target supports the execution of @code{raoint} instructions. @item rdrand Target supports x86 @code{rdrand} instruction. +@item sha512 +Target supports the execution of @code{sha512} instructions. + @item sm3 Target supports the execution of @code{sm3} instructions. diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C index 2ec9326..985f14a 100644 --- a/gcc/testsuite/g++.dg/other/i386-2.C +++ b/gcc/testsuite/g++.dg/other/i386-2.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ +/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C index fe03143..274b0e6 100644 --- a/gcc/testsuite/g++.dg/other/i386-3.C +++ b/gcc/testsuite/g++.dg/other/i386-3.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ +/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index 8dd8d9b..eb93098 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -90,6 +90,7 @@ extern void test_raoint (void) __attribute__((__target__("raoin extern void test_amx_complex (void) __attribute__((__target__("amx-complex"))); extern void test_avxvnniint16 (void) __attribute__((__target__("avxvnniint16"))); extern void test_sm3 (void) __attribute__((__target__("sm3"))); +extern void test_sha512 (void) __attribute__((__target__("sha512"))); extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); @@ -181,6 +182,7 @@ extern void test_no_raoint (void) __attribute__((__target__("no-ra extern void test_no_amx_complex (void) __attribute__((__target__("no-amx-complex"))); extern void test_no_avxvnniint16 (void) __attribute__((__target__("no-avxvnniint16"))); extern void test_no_sm3 (void) __attribute__((__target__("no-sm3"))); +extern void test_no_sha512 (void) __attribute__((__target__("no-sha512"))); extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); diff --git a/gcc/testsuite/gcc.target/i386/sha512-1.c b/gcc/testsuite/gcc.target/i386/sha512-1.c new file mode 100644 index 0000000..c66e812 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sha512-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msha512" } */ +/* { dg-final { scan-assembler "vsha512msg1\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsha512msg2\[ \\t\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsha512rnds2\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ + +#include + +volatile __m128i x; +volatile __m256i y; + +void extern +sha512_test (void) +{ + y = _mm256_sha512msg1_epi64(y, x); + y = _mm256_sha512msg2_epi64(y, y); + y = _mm256_sha512rnds2_epi64(y, y, x); +} diff --git a/gcc/testsuite/gcc.target/i386/sha512-check.h b/gcc/testsuite/gcc.target/i386/sha512-check.h new file mode 100644 index 0000000..083bf3b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sha512-check.h @@ -0,0 +1,43 @@ +#include +#include "m256-check.h" + +static void sha512_test (void); + +static unsigned long long +ror64 (unsigned long long w, int n) +{ + int count = n % 64; + return ((w >> n) | (w << (64 - n))); +} + +static unsigned long long +shr64 (unsigned long long w, int n) +{ + return (w >> n); +} + +static void +__attribute__ ((noinline)) +do_test(void) +{ + sha512_test (); +} + +int +main () +{ + /* Check CPU support for SHA512. */ + if (__builtin_cpu_supports ("sha512")) + { + do_test (); +#ifdef DEBUG + printf ("PASSED\n"); +#endif + return 0; + } + +#ifdef DEBUG + printf ("SKIPPED\n"); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/sha512msg1-2.c b/gcc/testsuite/gcc.target/i386/sha512msg1-2.c new file mode 100644 index 0000000..b7baff1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sha512msg1-2.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msha512" } */ +/* { dg-require-effective-target sha512 } */ + +#include "sha512-check.h" +#include +#include + +static unsigned long long +s0 (unsigned long long w) +{ + return ror64 (w, 1) ^ ror64 (w, 8) ^ shr64 (w, 7); +} + +static void +compute_sha512msg1(long long* src1, long long* src2, long long* res) +{ + unsigned long long w0, w1, w2, w3, w4; + + w0 = src1[0]; + w1 = src1[1]; + w2 = src1[2]; + w3 = src1[3]; + w4 = src2[0]; + + res[0] = w0 + s0 (w1); + res[1] = w1 + s0 (w2); + res[2] = w2 + s0 (w3); + res[3] = w3 + s0 (w4); +} + +static void +sha512_test(void) +{ + union256i_q s1, res; + union128i_q s2; + long long res_ref[4]; + + s1.x = _mm256_set_epi64x (111, 222, 333, 444); + s2.x = _mm_set_epi64x (0, 555); + + res.x = _mm256_sha512msg1_epi64 (s1.x, s2.x); + + compute_sha512msg1 (s1.a, s2.a, res_ref); + + if (check_union256i_q (res, res_ref)) + abort(); +} diff --git a/gcc/testsuite/gcc.target/i386/sha512msg2-2.c b/gcc/testsuite/gcc.target/i386/sha512msg2-2.c new file mode 100644 index 0000000..e503390 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sha512msg2-2.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msha512" } */ +/* { dg-require-effective-target sha512 } */ + +#include "sha512-check.h" +#include + +static unsigned long long +s1 (unsigned long long w) +{ + return ror64 (w, 19) ^ ror64 (w, 61) ^ shr64 (w, 6); +} + +static void +compute_sha512msg2 (long long* src1, long long* src2, long long* res) +{ + unsigned long long w14, w15, w16, w17, w18, w19; + + w14 = src2[2]; + w15 = src2[3]; + w16 = src1[0] + s1 (w14); + w17 = src1[1] + s1 (w15); + w18 = src1[2] + s1 (w16); + w19 = src1[3] + s1 (w17); + + res[0] = w16; + res[1] = w17; + res[2] = w18; + res[3] = w19; +} + +static void +sha512_test (void) +{ + union256i_q s1, s2, res; + long long res_ref[4]; + + s1.x = _mm256_set_epi64x (111, 222, 333, 444); + s2.x = _mm256_set_epi64x (555, 666, 0, 0); + + res.x = _mm256_sha512msg2_epi64 (s1.x, s2.x); + + compute_sha512msg2 (s1.a, s2.a, res_ref); + + if (check_union256i_q (res, res_ref)) + abort(); +} diff --git a/gcc/testsuite/gcc.target/i386/sha512rnds2-2.c b/gcc/testsuite/gcc.target/i386/sha512rnds2-2.c new file mode 100644 index 0000000..3bc6a00 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sha512rnds2-2.c @@ -0,0 +1,85 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msha512" } */ +/* { dg-require-effective-target sha512 } */ + +#include "sha512-check.h" +#include +#include + +static unsigned long long +ch (unsigned long long e, unsigned long long f, unsigned long long g) +{ + return (e & f) ^ (~e & g); +} + +static unsigned long long +maj (unsigned long long a, unsigned long long b, unsigned long long c) +{ + return (a & b) ^ (a & c) ^ (b & c); +} + +static unsigned long long +s0 (unsigned long long w) +{ + return ror64 (w, 28) ^ ror64 (w, 34) ^ ror64 (w, 39); +} + +static unsigned long long +s1 (unsigned long long w) +{ + return ror64 (w, 14) ^ ror64 (w, 18) ^ ror64 (w, 41); +} + +static void +compute_sha512rnds2(long long* src0, long long* src1, long long* src2, long long* res) +{ + unsigned long long wk[2] = { src2[0], src2[1] }; + unsigned long long a[3], b[3], c[3], d[3], e[3], f[3], g[3], h[3]; + + a[0] = src1[3]; + b[0] = src1[2]; + c[0] = src0[3]; + d[0] = src0[2]; + e[0] = src1[1]; + f[0] = src1[0]; + g[0] = src0[1]; + h[0] = src0[0]; + + int i; + for (i = 0; i <= 1; i++) + { + a[i + 1] = ch (e[i], f[i], g[i]) + s1 (e[i]) + wk[i] + h[i] + + maj (a[i], b[i], c[i]) + s0 (a[i]); + b[i + 1] = a[i]; + c[i + 1] = b[i]; + d[i + 1] = c[i]; + e[i + 1] = ch (e[i], f[i], g[i]) + s1 (e[i]) + wk[i] + h[i] + d[i]; + f[i + 1] = e[i]; + g[i + 1] = f[i]; + h[i + 1] = g[i]; + } + + res[0] = f[2]; + res[1] = e[2]; + res[2] = b[2]; + res[3] = a[2]; +} + +static void +sha512_test (void) +{ + union256i_q s0, s1, res; + union128i_q s2; + long long res_ref[4]; + + s0.x = _mm256_set_epi64x (111, 222, 333, 444); + s1.x = _mm256_set_epi64x (555, 666, 777, 888); + s2.x = _mm_set_epi64x (999, 123); + + res.x = _mm256_sha512rnds2_epi64 (s0.x, s1.x, s2.x); + + compute_sha512rnds2 (s0.a, s1.a, s2.a, res_ref); + + if (check_union256i_q (res, res_ref)) + abort(); +} diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c index 5058be6..9765413 100644 --- a/gcc/testsuite/gcc.target/i386/sse-12.c +++ b/gcc/testsuite/gcc.target/i386/sse-12.c @@ -3,7 +3,7 @@ popcntintrin.h gfniintrin.h and mm_malloc.h are usable with -O -std=c89 -pedantic-errors. */ /* { dg-do compile } */ -/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ +/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c index d30b365..8c314e7 100644 --- a/gcc/testsuite/gcc.target/i386/sse-13.c +++ b/gcc/testsuite/gcc.target/i386/sse-13.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ +/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ /* { dg-add-options bind_pic_locally } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c index 7842005..2b4d7bc 100644 --- a/gcc/testsuite/gcc.target/i386/sse-14.c +++ b/gcc/testsuite/gcc.target/i386/sse-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3" } */ +/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ /* { dg-add-options bind_pic_locally } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c index 7537db1..d6f19b5 100644 --- a/gcc/testsuite/gcc.target/i386/sse-22.c +++ b/gcc/testsuite/gcc.target/i386/sse-22.c @@ -103,7 +103,7 @@ #ifndef DIFFERENT_PRAGMAS -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3,sha512") #endif /* Following intrinsics require immediate arguments. They @@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1) /* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */ #ifdef DIFFERENT_PRAGMAS -#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3") +#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3,sha512") #endif #include test_1 (_cvtss_sh, unsigned short, float, 1) diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c index 3fc61b5..1df66b5 100644 --- a/gcc/testsuite/gcc.target/i386/sse-23.c +++ b/gcc/testsuite/gcc.target/i386/sse-23.c @@ -850,6 +850,6 @@ /* sm3intrin.h */ #define __builtin_ia32_vsm3rnds2(A, B, C, D) __builtin_ia32_vsm3rnds2 (A, B, C, 1) -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex,avxvnniint16,sm3") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex,avxvnniint16,sm3,sha512") #include diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index c911a82..f376d83 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9883,6 +9883,20 @@ proc check_effective_target_sm3 { } { } "-msm3" ] } +# Return 1 if sha512 instructions can be compiled. +proc check_effective_target_sha512 { } { + return [check_no_compiler_messages sha512 object { + typedef long long __m256i __attribute__ ((__vector_size__ (32))); + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + __m256i + _mm256_sha512msg2_epi64 (__m256i __A, __m256i __B) + { + return (__m256i) __builtin_ia32_vsha512msg2 ((__v4di) __A, + (__v4di) __B); + } + } "-msha512" ] +} + # Return 1 if sse instructions can be compiled. proc check_effective_target_sse { } { return [check_no_compiler_messages sse object { -- cgit v1.1 From 37bdeb8f76658dfa975dd1ec574d49ee369ac34f Mon Sep 17 00:00:00 2001 From: Haochen Jiang Date: Mon, 17 Jul 2023 10:46:04 +0800 Subject: Support Intel SM4 gcc/ChangeLog: * common/config/i386/cpuinfo.h (get_available_features): Detech SM4. * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_SM4_SET, OPTION_MASK_ISA2_SM4_UNSET): New. (OPTION_MASK_ISA2_AVX_UNSET): Add SM4. (ix86_handle_option): Handle -msm4. * common/config/i386/i386-cpuinfo.h (enum processor_features): Add FEATURE_SM4. * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for sm4. * config.gcc: Add sm4intrin.h. * config/i386/cpuid.h (bit_SM4): New. * config/i386/i386-builtin.def (BDESC): Add new builtins. * config/i386/i386-c.cc (ix86_target_macros_internal): Define __SM4__. * config/i386/i386-isa.def (SM4): Add DEF_PTA(SM4). * config/i386/i386-options.cc (isa2_opts): Add -msm4. (ix86_valid_target_attribute_inner_p): Handle sm4. * config/i386/i386.opt: Add option -msm4. * config/i386/immintrin.h: Include sm4intrin.h * config/i386/sse.md (vsm4key4_): New define insn. (vsm4rnds4_): Ditto. * doc/extend.texi: Document sm4. * doc/invoke.texi: Document -msm4. * doc/sourcebuild.texi: Document target sm4. * config/i386/sm4intrin.h: New file. gcc/testsuite/ChangeLog: * g++.dg/other/i386-2.C: Add -msm4. * g++.dg/other/i386-3.C: Ditto. * gcc.target/i386/funcspec-56.inc: Add new target attribute. * gcc.target/i386/sse-12.c: Add -msm4. * gcc.target/i386/sse-13.c: Ditto. * gcc.target/i386/sse-14.c: Ditto. * gcc.target/i386/sse-22.c: Add sm4. * gcc.target/i386/sse-23.c: Ditto. * lib/target-supports.exp (check_effective_target_sm4): New. * gcc.target/i386/sm4-1.c: New test. * gcc.target/i386/sm4-check.h: Ditto. * gcc.target/i386/sm4key4-2.c: Ditto. * gcc.target/i386/sm4rnds4-2.c: Ditto. --- gcc/common/config/i386/cpuinfo.h | 2 + gcc/common/config/i386/i386-common.cc | 20 ++- gcc/common/config/i386/i386-cpuinfo.h | 1 + gcc/common/config/i386/i386-isas.h | 1 + gcc/config.gcc | 2 +- gcc/config/i386/cpuid.h | 1 + gcc/config/i386/i386-builtin.def | 6 + gcc/config/i386/i386-c.cc | 2 + gcc/config/i386/i386-isa.def | 1 + gcc/config/i386/i386-options.cc | 4 +- gcc/config/i386/i386.opt | 5 + gcc/config/i386/immintrin.h | 2 + gcc/config/i386/sm4intrin.h | 70 ++++++++++ gcc/config/i386/sse.md | 26 ++++ gcc/doc/extend.texi | 5 + gcc/doc/invoke.texi | 9 +- gcc/doc/sourcebuild.texi | 3 + gcc/testsuite/g++.dg/other/i386-2.C | 2 +- gcc/testsuite/g++.dg/other/i386-3.C | 2 +- gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + gcc/testsuite/gcc.target/i386/sm4-1.c | 20 +++ gcc/testsuite/gcc.target/i386/sm4-check.h | 183 ++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/sm4key4-2.c | 14 ++ gcc/testsuite/gcc.target/i386/sm4rnds4-2.c | 14 ++ gcc/testsuite/gcc.target/i386/sse-12.c | 2 +- gcc/testsuite/gcc.target/i386/sse-13.c | 2 +- gcc/testsuite/gcc.target/i386/sse-14.c | 2 +- gcc/testsuite/gcc.target/i386/sse-22.c | 4 +- gcc/testsuite/gcc.target/i386/sse-23.c | 2 +- gcc/testsuite/lib/target-supports.exp | 14 ++ 30 files changed, 409 insertions(+), 14 deletions(-) create mode 100644 gcc/config/i386/sm4intrin.h create mode 100644 gcc/testsuite/gcc.target/i386/sm4-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sm4-check.h create mode 100644 gcc/testsuite/gcc.target/i386/sm4key4-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sm4rnds4-2.c (limited to 'gcc') diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 0cfde3e..f9434f0 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -881,6 +881,8 @@ get_available_features (struct __processor_model *cpu_model, set_feature (FEATURE_SM3); if (eax & bit_SHA512) set_feature (FEATURE_SHA512); + if (eax & bit_SM4) + set_feature (FEATURE_SM4); } if (avx512_usable) { diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 97c3cdf..610cabe 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -122,6 +122,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AVXVNNIINT16_SET OPTION_MASK_ISA2_AVXVNNIINT16 #define OPTION_MASK_ISA2_SM3_SET OPTION_MASK_ISA2_SM3 #define OPTION_MASK_ISA2_SHA512_SET OPTION_MASK_ISA2_SHA512 +#define OPTION_MASK_ISA2_SM4_SET OPTION_MASK_ISA2_SM4 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same as -msse4.2. */ @@ -307,6 +308,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AVXVNNIINT16_UNSET OPTION_MASK_ISA2_AVXVNNIINT16 #define OPTION_MASK_ISA2_SM3_UNSET OPTION_MASK_ISA2_SM3 #define OPTION_MASK_ISA2_SHA512_UNSET OPTION_MASK_ISA2_SHA512 +#define OPTION_MASK_ISA2_SM4_UNSET OPTION_MASK_ISA2_SM4 /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -356,7 +358,8 @@ along with GCC; see the file COPYING3. If not see OPTION_MASK_ISA2_SSE_UNSET #define OPTION_MASK_ISA2_AVX_UNSET \ (OPTION_MASK_ISA2_AVX2_UNSET | OPTION_MASK_ISA2_VAES_UNSET \ - | OPTION_MASK_ISA2_SM3_UNSET | OPTION_MASK_ISA2_SHA512_UNSET) + | OPTION_MASK_ISA2_SM3_UNSET | OPTION_MASK_ISA2_SHA512_UNSET \ + | OPTION_MASK_ISA2_SM4_UNSET) #define OPTION_MASK_ISA2_SSE4_2_UNSET OPTION_MASK_ISA2_AVX_UNSET #define OPTION_MASK_ISA2_SSE4_1_UNSET OPTION_MASK_ISA2_SSE4_2_UNSET #define OPTION_MASK_ISA2_SSE4_UNSET OPTION_MASK_ISA2_SSE4_1_UNSET @@ -1323,6 +1326,21 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_msm4: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_SM4_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM4_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_SM4_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_SM4_UNSET; + } + return true; + case OPT_mfma: if (value) { diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index a6e34d1..be04d85 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -258,6 +258,7 @@ enum processor_features FEATURE_AVXVNNIINT16, FEATURE_SM3, FEATURE_SHA512, + FEATURE_SM4, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index 250dc87..2297903 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -190,4 +190,5 @@ ISA_NAMES_TABLE_START P_NONE, "-mavxvnniint16") ISA_NAMES_TABLE_ENTRY("sm3", FEATURE_SM3, P_NONE, "-msm3") ISA_NAMES_TABLE_ENTRY("sha512", FEATURE_SHA512, P_NONE, "-msha512") + ISA_NAMES_TABLE_ENTRY("sm4", FEATURE_SM4, P_NONE, "-msm4") ISA_NAMES_TABLE_END diff --git a/gcc/config.gcc b/gcc/config.gcc index 4e753ba..305e859 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -436,7 +436,7 @@ i[34567]86-*-* | x86_64-*-*) avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h cmpccxaddintrin.h amxfp16intrin.h prfchiintrin.h raointintrin.h amxcomplexintrin.h avxvnniint16intrin.h - sm3intrin.h sha512intrin.h" + sm3intrin.h sha512intrin.h sm4intrin.h" ;; ia64-*-*) extra_headers=ia64intrin.h diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index f9103f1..03fd6fc 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -134,6 +134,7 @@ /* %eax */ #define bit_SHA512 (1 << 0) #define bit_SM3 (1 << 1) +#define bit_SM4 (1 << 2) #define bit_RAOINT (1 << 3) #define bit_AVXVNNI (1 << 4) #define bit_AVX512BF16 (1 << 5) diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index b9e2bad..8738b3b 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -1660,6 +1660,12 @@ BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg1, "__builtin_ BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3msg2, "__builtin_ia32_vsm3msg2", IX86_BUILTIN_VSM3MSG2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI) BDESC (OPTION_MASK_ISA_AVX, OPTION_MASK_ISA2_SM3, CODE_FOR_vsm3rnds2, "__builtin_ia32_vsm3rnds2", IX86_BUILTIN_VSM3RNDS2, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT) +/* SM4 */ +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4key4_v4si, "__builtin_ia32_vsm4key4128", IX86_BUILTIN_VSM4KEY4128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4key4_v8si, "__builtin_ia32_vsm4key4256", IX86_BUILTIN_VSM4KEY4256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI) +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4rnds4_v4si, "__builtin_ia32_vsm4rnds4128", IX86_BUILTIN_VSM4RNDS4128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI) +BDESC (0, OPTION_MASK_ISA2_SM4, CODE_FOR_vsm4rnds4_v8si, "__builtin_ia32_vsm4rnds4256", IX86_BUILTIN_VSM4RNDS4256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI) + /* SHA512 */ BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512msg1, "__builtin_ia32_vsha512msg1", IX86_BUILTIN_VSHA512MSG1, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI) BDESC (0, OPTION_MASK_ISA2_SHA512, CODE_FOR_vsha512msg2, "__builtin_ia32_vsha512msg2", IX86_BUILTIN_VSHA512MSG2, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI) diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index c6311f1..0adec14 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -683,6 +683,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__SM3__"); if (isa_flag2 & OPTION_MASK_ISA2_SHA512) def_or_undef (parse_in, "__SHA512__"); + if (isa_flag2 & OPTION_MASK_ISA2_SM4) + def_or_undef (parse_in, "__SM4__"); if (TARGET_IAMCU) { def_or_undef (parse_in, "__iamcu"); diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def index 28f2217..aeafcf8 100644 --- a/gcc/config/i386/i386-isa.def +++ b/gcc/config/i386/i386-isa.def @@ -120,3 +120,4 @@ DEF_PTA(AMX_COMPLEX) DEF_PTA(AVXVNNIINT16) DEF_PTA(SM3) DEF_PTA(SHA512) +DEF_PTA(SM4) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index d79ab01..347ed2d 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -242,7 +242,8 @@ static struct ix86_target_opts isa2_opts[] = { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX }, { "-mavxvnniint16", OPTION_MASK_ISA2_AVXVNNIINT16 }, { "-msm3", OPTION_MASK_ISA2_SM3 }, - { "-msha512", OPTION_MASK_ISA2_SHA512 } + { "-msha512", OPTION_MASK_ISA2_SHA512 }, + { "-msm4", OPTION_MASK_ISA2_SM4 } }; static struct ix86_target_opts isa_opts[] = { @@ -1097,6 +1098,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("avxvnniint16", OPT_mavxvnniint16), IX86_ATTR_ISA ("sm3", OPT_msm3), IX86_ATTR_ISA ("sha512", OPT_msha512), + IX86_ATTR_ISA ("sm4", OPT_msm4), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index cf9dbca..db99568 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1298,3 +1298,8 @@ msha512 Target Mask(ISA2_SHA512) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and SHA512 built-in functions and code generation. + +msm4 +Target Mask(ISA2_SM4) Var(ix86_isa_flags2) Save +Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and +SM4 built-in functions and code generation. diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h index 6f2bcef..ea14354 100644 --- a/gcc/config/i386/immintrin.h +++ b/gcc/config/i386/immintrin.h @@ -112,6 +112,8 @@ #include +#include + #include #include diff --git a/gcc/config/i386/sm4intrin.h b/gcc/config/i386/sm4intrin.h new file mode 100644 index 0000000..f58a782 --- /dev/null +++ b/gcc/config/i386/sm4intrin.h @@ -0,0 +1,70 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif + +#ifndef _SM4INTRIN_H_INCLUDED +#define _SM4INTRIN_H_INCLUDED + +#ifndef __SM4__ +#pragma GCC push_options +#pragma GCC target("sm4") +#define __DISABLE_SM4__ +#endif /* __SM4__ */ + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm4key4_epi32 (__m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_vsm4key4128 ((__v4si) __A, (__v4si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sm4key4_epi32 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsm4key4256 ((__v8si) __A, (__v8si) __B); +} + +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm4rnds4_epi32 (__m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_vsm4rnds4128 ((__v4si) __A, (__v4si) __B); +} + +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sm4rnds4_epi32 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsm4rnds4256 ((__v8si) __A, (__v8si) __B); +} + +#ifdef __DISABLE_SM4__ +#undef __DISABLE_SM4__ +#pragma GCC pop_options +#endif /* __DISABLE_SM4__ */ + +#endif /* _SM4INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index e16b2b5..7471932 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -223,6 +223,10 @@ UNSPEC_SHA512MSG2 UNSPEC_SHA512RNDS2 + ;; For SM4 support + UNSPEC_SM4KEY4 + UNSPEC_SM4RNDS4 + ]) (define_c_enum "unspecv" [ @@ -28680,6 +28684,28 @@ [(set_attr "type" "sselog1") (set_attr "mode" "OI")]) +(define_insn "vsm4key4_" + [(set (match_operand:VI4_AVX 0 "register_operand" "=x") + (unspec:VI4_AVX + [(match_operand:VI4_AVX 1 "register_operand" "x") + (match_operand:VI4_AVX 2 "vector_operand" "xBm")] + UNSPEC_SM4KEY4))] + "TARGET_SM4" + "vsm4key4\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "other") + (set_attr "mode" "")]) + +(define_insn "vsm4rnds4_" + [(set (match_operand:VI4_AVX 0 "register_operand" "=x") + (unspec:VI4_AVX + [(match_operand:VI4_AVX 1 "register_operand" "x") + (match_operand:VI4_AVX 2 "vector_operand" "xBm")] + UNSPEC_SM4RNDS4))] + "TARGET_SM4" + "vsm4rnds4\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "other") + (set_attr "mode" "")]) + (define_insn_and_split "avx512f__" [(set (match_operand:AVX512MODE2P 0 "nonimmediate_operand" "=x,m") (vec_concat:AVX512MODE2P diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 7086ca9..5e20c83 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7178,6 +7178,11 @@ Enable/disable the generation of the SM3 instructions. @itemx no-sha512 Enable/disable the generation of the SHA512 instructions. +@cindex @code{target("sm4")} function attribute, x86 +@item sm4 +@itemx no-sm4 +Enable/disable the generation of the SM4 instructions. + @cindex @code{target("cld")} function attribute, x86 @item cld @itemx no-cld diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 433ccf3..dd28320 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1433,7 +1433,7 @@ See RS/6000 and PowerPC Options. -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 --mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 +-mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4 -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops -minline-stringops-dynamically -mstringop-strategy=@var{alg} -mkl -mwidekl @@ -33561,6 +33561,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @need 200 @opindex msha512 @itemx -msha512 +@need 200 +@opindex msm4 +@itemx -msm4 These switches enable the use of instructions in the MMX, SSE, AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, AES, PCLMUL, CLFLUSHOPT, CLWB, FSGSBASE, PTWRITE, RDRND, F16C, FMA, PCONFIG, @@ -33571,8 +33574,8 @@ GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AMX-FP16, PREFETCHI, RAOINT, -AMX-COMPLEX, AVXVNNIINT16, SM3, SHA512 or CLDEMOTE extended instruction sets. -Each has a corresponding @option{-mno-} option to disable use of these +AMX-COMPLEX, AVXVNNIINT16, SM3, SHA512, SM4 or CLDEMOTE extended instruction +sets. Each has a corresponding @option{-mno-} option to disable use of these instructions. These extensions are also available as built-in functions: see diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 54a062d..e5d15d6 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2595,6 +2595,9 @@ Target supports the execution of @code{sha512} instructions. @item sm3 Target supports the execution of @code{sm3} instructions. +@item sm4 +Target supports the execution of @code{sm4} instructions. + @item sqrt_insn Target has a square root instruction that the compiler can generate. diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C index 985f14a..7d68967 100644 --- a/gcc/testsuite/g++.dg/other/i386-2.C +++ b/gcc/testsuite/g++.dg/other/i386-2.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ +/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C index 274b0e6..9b775c3 100644 --- a/gcc/testsuite/g++.dg/other/i386-3.C +++ b/gcc/testsuite/g++.dg/other/i386-3.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ +/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index eb93098..577bfc7 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -91,6 +91,7 @@ extern void test_amx_complex (void) __attribute__((__target__("amx-complex"))); extern void test_avxvnniint16 (void) __attribute__((__target__("avxvnniint16"))); extern void test_sm3 (void) __attribute__((__target__("sm3"))); extern void test_sha512 (void) __attribute__((__target__("sha512"))); +extern void test_sm4 (void) __attribute__((__target__("sm4"))); extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); @@ -183,6 +184,7 @@ extern void test_no_amx_complex (void) __attribute__((__target__("no-amx-comple extern void test_no_avxvnniint16 (void) __attribute__((__target__("no-avxvnniint16"))); extern void test_no_sm3 (void) __attribute__((__target__("no-sm3"))); extern void test_no_sha512 (void) __attribute__((__target__("no-sha512"))); +extern void test_no_sm4 (void) __attribute__((__target__("no-sm4"))); extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); diff --git a/gcc/testsuite/gcc.target/i386/sm4-1.c b/gcc/testsuite/gcc.target/i386/sm4-1.c new file mode 100644 index 0000000..2d3d6c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm4-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msm4" } */ +/* { dg-final { scan-assembler "vsm4key4\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm4key4\[ \\t\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm4rnds4\[ \\t\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]" } } */ +/* { dg-final { scan-assembler "vsm4rnds4\[ \\t\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]" } } */ + +#include + +volatile __m128i a, b, c; +volatile __m256i d, e, f; + +void extern +sm4_test (void) +{ + a = _mm_sm4key4_epi32 (b, c); + d = _mm256_sm4key4_epi32 (e, f); + a = _mm_sm4rnds4_epi32 (b, c); + d = _mm256_sm4rnds4_epi32 (e, f); +} diff --git a/gcc/testsuite/gcc.target/i386/sm4-check.h b/gcc/testsuite/gcc.target/i386/sm4-check.h new file mode 100644 index 0000000..435fcf2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm4-check.h @@ -0,0 +1,183 @@ +#include +#include "m256-check.h" + +static void sm4_test (void); + +typedef union +{ + unsigned int x; + unsigned char a[4]; +} union32ui_ub; + +unsigned char sbox[256] = { +0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, +0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, +0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, +0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, +0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, +0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, +0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, +0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, +0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, +0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, +0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, +0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, +0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, +0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, +0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, +0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, +0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, +0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, +0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, +0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, +0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, +0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, +0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, +0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, +0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, +0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, +0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, +0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, +0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, +0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, +0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, +0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48 +}; + +static unsigned +rol32 (unsigned w, int n) +{ + int count = n % 32; + return ((w << count) | (w >> (32 - count))); +} + +static unsigned char +sbox_byte (unsigned w, int i) +{ + union32ui_ub tmp; + tmp.x = w; + return sbox[tmp.a[i]]; +} + +static unsigned +lower_t (unsigned w) +{ + union32ui_ub tmp; + tmp.a[0] = sbox_byte (w, 0); + tmp.a[1] = sbox_byte (w, 1); + tmp.a[2] = sbox_byte (w, 2); + tmp.a[3] = sbox_byte (w, 3); + return tmp.x; +} + +static unsigned +l_key (unsigned w) +{ + return w ^ rol32 (w, 13) ^ rol32 (w, 23); +} + +static unsigned +l_rnds (unsigned w) +{ + unsigned tmp = w; + tmp = tmp ^ rol32 (w, 2); + tmp = tmp ^ rol32 (w, 10); + tmp = tmp ^ rol32 (w, 18); + tmp = tmp ^ rol32 (w, 24); + return tmp; +} + +#define SM4_FUNC(name) \ +static unsigned \ +t_##name (unsigned w) \ +{ \ + return l_##name (lower_t (w)); \ +} \ + \ +static unsigned \ +f_##name (unsigned x0, unsigned x1, unsigned x2, unsigned x3, unsigned k) \ +{ \ + return x0 ^ t_##name (x1 ^ x2 ^ x3 ^ k); \ +} \ + \ +static void \ +compute_sm4##name##4 (int *dst, int *src1, int *src2, int vl) \ +{ \ + unsigned c[4], p[4]; \ + \ + int kl = vl / 128; \ + int i; \ + \ + for (i = 0; i < kl; i++) \ + { \ + p[0] = src1[4 * i]; \ + p[1] = src1[4 * i + 1]; \ + p[2] = src1[4 * i + 2]; \ + p[3] = src1[4 * i + 3]; \ + \ + c[0] = f_##name (p[0], p[1], p[2], p[3], src2[4 * i]); \ + c[1] = f_##name (p[1], p[2], p[3], c[0], src2[4 * i + 1]); \ + c[2] = f_##name (p[2], p[3], c[0], c[1], src2[4 * i + 2]); \ + c[3] = f_##name (p[3], c[0], c[1], c[2], src2[4 * i + 3]); \ + \ + dst[4 * i] = c[0]; \ + dst[4 * i + 1] = c[1]; \ + dst[4 * i + 2] = c[2]; \ + dst[4 * i + 3] = c[3]; \ + } \ +} + +#define SM4_AVX_SIMULATE(name) \ + union128i_d src1, src2, res1; \ + int dst1[4] = {0, 0, 0, 0}; \ + \ + src1.x = _mm_set_epi32 (111, 222, 333, 444); \ + src2.x = _mm_set_epi32 (555, 666, 777, 888); \ + res1.x = _mm_set_epi32 (0, 0, 0, 0); \ + \ + res1.x = _mm_sm4##name##4_epi32 (src1.x, src2.x); \ + \ + compute_sm4##name##4 (dst1, src1.a, src2.a, 128); \ + \ + if (check_union128i_d (res1, dst1)) \ + abort (); \ + \ + union256i_d src3, src4, res2; \ + int dst2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; \ + \ + src3.x = _mm256_set_epi32 (111, 222, 333, 444, 555, 666, 777, 888); \ + src4.x = _mm256_set_epi32 (999, 123, 456, 789, 135, 792, 468, 147); \ + res2.x = _mm256_set_epi32 (0, 0, 0, 0, 0, 0, 0, 0); \ + \ + res2.x = _mm256_sm4##name##4_epi32 (src3.x, src4.x); \ + \ + compute_sm4##name##4 (dst2, src3.a, src4.a, 256); \ + \ + if (check_union256i_d (res2, dst2)) \ + abort (); + +static void +__attribute__ ((noinline)) +do_test (void) +{ + sm4_test (); +} + +int +main () +{ + /* Check CPU support for SM4. */ + if (__builtin_cpu_supports ("sm4")) + { + do_test (); +#ifdef DEBUG + printf ("PASSED\n"); +#endif + return 0; + } + +#ifdef DEBUG + printf ("SKIPPED\n"); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/sm4key4-2.c b/gcc/testsuite/gcc.target/i386/sm4key4-2.c new file mode 100644 index 0000000..a8bec56 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm4key4-2.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msm4" } */ +/* { dg-require-effective-target sm4 } */ + +#include "sm4-check.h" + +char key; +SM4_FUNC (key); + +static void +sm4_test (void) +{ + SM4_AVX_SIMULATE (key); +} diff --git a/gcc/testsuite/gcc.target/i386/sm4rnds4-2.c b/gcc/testsuite/gcc.target/i386/sm4rnds4-2.c new file mode 100644 index 0000000..0860d0d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sm4rnds4-2.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msm4" } */ +/* { dg-require-effective-target sm4 } */ + +#include "sm4-check.h" + +char rnds; +SM4_FUNC (rnds); + +static void +sm4_test (void) +{ + SM4_AVX_SIMULATE (rnds); +} diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c index 9765413..a553a52 100644 --- a/gcc/testsuite/gcc.target/i386/sse-12.c +++ b/gcc/testsuite/gcc.target/i386/sse-12.c @@ -3,7 +3,7 @@ popcntintrin.h gfniintrin.h and mm_malloc.h are usable with -O -std=c89 -pedantic-errors. */ /* { dg-do compile } */ -/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ +/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4" } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c index 8c314e7..946182f 100644 --- a/gcc/testsuite/gcc.target/i386/sse-13.c +++ b/gcc/testsuite/gcc.target/i386/sse-13.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ +/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4" } */ /* { dg-add-options bind_pic_locally } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c index 2b4d7bc..0d07aad 100644 --- a/gcc/testsuite/gcc.target/i386/sse-14.c +++ b/gcc/testsuite/gcc.target/i386/sse-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512" } */ +/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4" } */ /* { dg-add-options bind_pic_locally } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c index d6f19b5..e6681f7 100644 --- a/gcc/testsuite/gcc.target/i386/sse-22.c +++ b/gcc/testsuite/gcc.target/i386/sse-22.c @@ -103,7 +103,7 @@ #ifndef DIFFERENT_PRAGMAS -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3,sha512") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3,sha512,sm4") #endif /* Following intrinsics require immediate arguments. They @@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1) /* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */ #ifdef DIFFERENT_PRAGMAS -#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3,sha512") +#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint,amx-complex,avxvnniint16,sm3,sha512,sm4") #endif #include test_1 (_cvtss_sh, unsigned short, float, 1) diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c index 1df66b5..92b1c46 100644 --- a/gcc/testsuite/gcc.target/i386/sse-23.c +++ b/gcc/testsuite/gcc.target/i386/sse-23.c @@ -850,6 +850,6 @@ /* sm3intrin.h */ #define __builtin_ia32_vsm3rnds2(A, B, C, D) __builtin_ia32_vsm3rnds2 (A, B, C, 1) -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex,avxvnniint16,sm3,sha512") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint,amx-complex,avxvnniint16,sm3,sha512,sm4") #include diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index f376d83..8ea0d9f 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9897,6 +9897,20 @@ proc check_effective_target_sha512 { } { } "-msha512" ] } +# Return 1 if sm4 instructions can be compiled. +proc check_effective_target_sm4 { } { + return [check_no_compiler_messages sm4 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + __m128i + _mm_sm4key4_epi32 (__m128i __A, __m128i __B) + { + return (__m128i) __builtin_ia32_vsm4key4128 ((__v4si) __A, + (__v4si) __B); + } + } "-msm4" ] +} + # Return 1 if sse instructions can be compiled. proc check_effective_target_sse { } { return [check_no_compiler_messages sse object { -- cgit v1.1 From 85c50b4a50af360026b807fca81ef65ba424bdb9 Mon Sep 17 00:00:00 2001 From: Haochen Jiang Date: Mon, 17 Jul 2023 10:46:07 +0800 Subject: i386: Auto vectorize usdot_prod, udot_prod with AVXVNNIINT16 instruction. gcc/ChangeLog: * config/i386/sse.md (VI2_AVX2): Delete V32HI since we actually have the same iterator. Also renaming all the occurence to VI2_AVX2_AVX512BW. (usdot_prod): New define_expand. (udot_prod): Ditto. gcc/testsuite/ChangeLog: * gcc.target/i386/vnniint16-auto-vectorize-1.c: New test. * gcc.target/i386/vnniint16-auto-vectorize-2.c: Ditto. --- gcc/config/i386/sse.md | 96 +++++++++++++++------- .../gcc.target/i386/vnniint16-auto-vectorize-1.c | 28 +++++++ .../gcc.target/i386/vnniint16-auto-vectorize-2.c | 76 +++++++++++++++++ 3 files changed, 170 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-1.c create mode 100644 gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-2.c (limited to 'gcc') diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 7471932..c3fa241 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -545,6 +545,9 @@ V32HI (V16HI "TARGET_AVX512VL")]) (define_mode_iterator VI2_AVX2 + [(V16HI "TARGET_AVX2") V8HI]) + +(define_mode_iterator VI2_AVX2_AVX512BW [(V32HI "TARGET_AVX512BW") (V16HI "TARGET_AVX2") V8HI]) (define_mode_iterator VI2_AVX512F @@ -637,9 +640,6 @@ (V16HI "TARGET_AVX2") V8HI (V8SI "TARGET_AVX2") V4SI]) -(define_mode_iterator VI2_AVX2_AVX512BW - [(V32HI "TARGET_AVX512BW") (V16HI "TARGET_AVX2") V8HI]) - (define_mode_iterator VI248_AVX512VL [V32HI V16SI V8DI (V16HI "TARGET_AVX512VL") (V8SI "TARGET_AVX512VL") @@ -15298,16 +15298,16 @@ }) (define_expand "mul3" - [(set (match_operand:VI2_AVX2 0 "register_operand") - (mult:VI2_AVX2 (match_operand:VI2_AVX2 1 "vector_operand") - (match_operand:VI2_AVX2 2 "vector_operand")))] + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand") + (mult:VI2_AVX2_AVX512BW (match_operand:VI2_AVX2_AVX512BW 1 "vector_operand") + (match_operand:VI2_AVX2_AVX512BW 2 "vector_operand")))] "TARGET_SSE2 && && " "ix86_fixup_binary_operands_no_copy (MULT, mode, operands);") (define_insn "*mul3" - [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,") - (mult:VI2_AVX2 (match_operand:VI2_AVX2 1 "vector_operand" "%0,") - (match_operand:VI2_AVX2 2 "vector_operand" "xBm,m")))] + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=x,") + (mult:VI2_AVX2_AVX512BW (match_operand:VI2_AVX2_AVX512BW 1 "vector_operand" "%0,") + (match_operand:VI2_AVX2_AVX512BW 2 "vector_operand" "xBm,m")))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2])) && && " "@ @@ -15320,28 +15320,28 @@ (set_attr "mode" "")]) (define_expand "mul3_highpart" - [(set (match_operand:VI2_AVX2 0 "register_operand") - (truncate:VI2_AVX2 + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand") + (truncate:VI2_AVX2_AVX512BW (lshiftrt: (mult: (any_extend: - (match_operand:VI2_AVX2 1 "vector_operand")) + (match_operand:VI2_AVX2_AVX512BW 1 "vector_operand")) (any_extend: - (match_operand:VI2_AVX2 2 "vector_operand"))) + (match_operand:VI2_AVX2_AVX512BW 2 "vector_operand"))) (const_int 16))))] "TARGET_SSE2 && && " "ix86_fixup_binary_operands_no_copy (MULT, mode, operands);") (define_insn "*mul3_highpart" - [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,") - (truncate:VI2_AVX2 + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=x,") + (truncate:VI2_AVX2_AVX512BW (lshiftrt: (mult: (any_extend: - (match_operand:VI2_AVX2 1 "vector_operand" "%0,")) + (match_operand:VI2_AVX2_AVX512BW 1 "vector_operand" "%0,")) (any_extend: - (match_operand:VI2_AVX2 2 "vector_operand" "xBm,m"))) + (match_operand:VI2_AVX2_AVX512BW 2 "vector_operand" "xBm,m"))) (const_int 16))))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2])) && && " @@ -15591,8 +15591,8 @@ (define_insn "avx512bw_pmaddwd512" [(set (match_operand: 0 "register_operand" "=v") (unspec: - [(match_operand:VI2_AVX2 1 "register_operand" "v") - (match_operand:VI2_AVX2 2 "nonimmediate_operand" "vm")] + [(match_operand:VI2_AVX2_AVX512BW 1 "register_operand" "v") + (match_operand:VI2_AVX2_AVX512BW 2 "nonimmediate_operand" "vm")] UNSPEC_PMADDWD512))] "TARGET_AVX512BW && " "vpmaddwd\t{%2, %1, %0|%0, %1, %2}"; @@ -21569,16 +21569,16 @@ }) (define_expand "smulhrs3" - [(set (match_operand:VI2_AVX2 0 "register_operand") - (truncate:VI2_AVX2 + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand") + (truncate:VI2_AVX2_AVX512BW (lshiftrt: (plus: (lshiftrt: (mult: (sign_extend: - (match_operand:VI2_AVX2 1 "nonimmediate_operand")) + (match_operand:VI2_AVX2_AVX512BW 1 "nonimmediate_operand")) (sign_extend: - (match_operand:VI2_AVX2 2 "nonimmediate_operand"))) + (match_operand:VI2_AVX2_AVX512BW 2 "nonimmediate_operand"))) (const_int 14)) (match_dup 3)) (const_int 1))))] @@ -21589,18 +21589,18 @@ }) (define_insn "*_pmulhrsw3" - [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,") - (truncate:VI2_AVX2 + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=x,") + (truncate:VI2_AVX2_AVX512BW (lshiftrt: (plus: (lshiftrt: (mult: (sign_extend: - (match_operand:VI2_AVX2 1 "vector_operand" "%0,")) + (match_operand:VI2_AVX2_AVX512BW 1 "vector_operand" "%0,")) (sign_extend: - (match_operand:VI2_AVX2 2 "vector_operand" "xBm,m"))) + (match_operand:VI2_AVX2_AVX512BW 2 "vector_operand" "xBm,m"))) (const_int 14)) - (match_operand:VI2_AVX2 3 "const1_operand")) + (match_operand:VI2_AVX2_AVX512BW 3 "const1_operand")) (const_int 1))))] "TARGET_SSSE3 && && && !(MEM_P (operands[1]) && MEM_P (operands[2]))" @@ -22327,8 +22327,8 @@ (set_attr "mode" "")]) (define_insn "_packusdw" - [(set (match_operand:VI2_AVX2 0 "register_operand" "=Yr,*x,") - (unspec:VI2_AVX2 + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=Yr,*x,") + (unspec:VI2_AVX2_AVX512BW [(match_operand: 1 "register_operand" "0,0,") (match_operand: 2 "vector_operand" "YrBm,*xBm,m")] UNSPEC_US_TRUNCATE))] @@ -30340,6 +30340,42 @@ (UNSPEC_VPDPWSUD "wsud") (UNSPEC_VPDPWSUDS "wsuds") (UNSPEC_VPDPWUUD "wuud") (UNSPEC_VPDPWUUDS "wuuds")]) +(define_expand "usdot_prod" + [(match_operand: 0 "register_operand") + (match_operand:VI2_AVX2 1 "register_operand") + (match_operand:VI2_AVX2 2 "register_operand") + (match_operand: 3 "register_operand")] + "TARGET_AVXVNNIINT16" +{ + operands[1] = lowpart_subreg (mode, + force_reg (mode, operands[1]), + mode); + operands[2] = lowpart_subreg (mode, + force_reg (mode, operands[2]), + mode); + emit_insn (gen_vpdpwusd_ (operands[0], operands[3], + operands[1], operands[2])); + DONE; +}) + +(define_expand "udot_prod" + [(match_operand: 0 "register_operand") + (match_operand:VI2_AVX2 1 "register_operand") + (match_operand:VI2_AVX2 2 "register_operand") + (match_operand: 3 "register_operand")] + "TARGET_AVXVNNIINT16" +{ + operands[1] = lowpart_subreg (mode, + force_reg (mode, operands[1]), + mode); + operands[2] = lowpart_subreg (mode, + force_reg (mode, operands[2]), + mode); + emit_insn (gen_vpdpwuud_ (operands[0], operands[3], + operands[1], operands[2])); + DONE; +}) + (define_insn "vpdp_" [(set (match_operand:VI4_AVX 0 "register_operand" "=x") (unspec:VI4_AVX diff --git a/gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-1.c b/gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-1.c new file mode 100644 index 0000000..73f0d32 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-1.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-mavxvnniint16 -O2" } */ +/* { dg-final { scan-assembler "vpdpwusd\t" } } */ +/* { dg-final { scan-assembler "vpdpwuud\t" } } */ + +int __attribute__((noinline, noclone, optimize("tree-vectorize"))) +usdot_prod_hi (unsigned short * restrict a, short * restrict b, + int c, int n) +{ + int i; + for (i = 0; i < n; i++) + { + c += ((int) a[i] * (int) b[i]); + } + return c; +} + +int __attribute__((noinline, noclone, optimize("tree-vectorize"))) +udot_prod_hi (unsigned short * restrict a, unsigned short *restrict b, + int c, int n) +{ + int i; + for (i = 0; i < n; i++) + { + c += ((int) a[i] * (int) b[i]); + } + return c; +} diff --git a/gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-2.c b/gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-2.c new file mode 100644 index 0000000..90dc0ea --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vnniint16-auto-vectorize-2.c @@ -0,0 +1,76 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavxvnniint16" } */ +/* { dg-require-effective-target avxvnniint16 } */ + +#define AVXVNNIINT16 +#ifndef CHECK +#define CHECK "avx-check.h" +#endif + +#ifndef TEST +#define TEST avx_test +#endif + +#include CHECK +#include "vnniint16-auto-vectorize-1.c" + +#define N 256 + +short a_i16[N]; +unsigned short b_u16[N], c_u16[N], d_u16[N]; +int i16_exp, i16_ref; + +int __attribute__((noinline, noclone, optimize("no-tree-vectorize"))) +udot_prod_hi_scalar (unsigned short * restrict a, unsigned short * restrict b, + int c, int n) +{ + int i; + for (i = 0; i < n; i++) + { + c += ((int) a[i] * (int) b[i]); + } + return c; +} + +int __attribute__((noinline, noclone, optimize("no-tree-vectorize"))) +usdot_prod_hi_scalar (unsigned short * restrict a, short *restrict b, + int c, int n) +{ + int i; + for (i = 0; i < n; i++) + { + c += ((int) a[i] * (int) b[i]); + } + return c; +} + +void init () +{ + int i; + + i16_exp = i16_ref = 65535; + + for (i = 0; i < N; i++) + { + a_i16[i] = -i + 2; + b_u16[i] = i * 2; + c_u16[i] = i * 3; + d_u16[i] = i * 4; + } +} + +void +TEST (void) +{ + init (); + i16_exp = usdot_prod_hi (a_i16, b_u16, i16_exp, N); + i16_ref = usdot_prod_hi_scalar (a_i16, b_u16, i16_ref, N); + if (i16_exp != i16_ref) + abort (); + + init (); + i16_exp = udot_prod_hi (c_u16, d_u16, i16_exp, N); + i16_ref = udot_prod_hi_scalar (c_u16, d_u16, i16_ref, N); + if (i16_exp != i16_ref) + abort (); +} -- cgit v1.1 From a5088dc3f5ef73c8740f0b8be3e6ebf6b535f192 Mon Sep 17 00:00:00 2001 From: "Mo, Zewei" Date: Mon, 17 Jul 2023 10:53:36 +0800 Subject: Initial Lunar Lake, Arrow Lake and Arrow Lake S Support gcc/ChangeLog: * common/config/i386/cpuinfo.h (get_intel_cpu): Handle Lunar Lake, Arrow Lake and Arrow Lake S. * common/config/i386/i386-common.cc: (processor_name): Add arrowlake. (processor_alias_table): Add arrow lake, arrow lake s and lunar lake. * common/config/i386/i386-cpuinfo.h (enum processor_subtypes): Add INTEL_COREI7_ARROWLAKE and INTEL_COREI7_ARROWLAKE_S. * config.gcc: Add -march=arrowlake and -march=arrowlake-s. * config/i386/driver-i386.cc (host_detect_local_cpu): Handle arrowlake-s. * config/i386/i386-c.cc (ix86_target_macros_internal): Add arrowlake. * config/i386/i386-options.cc (m_ARROWLAKE): New. (processor_cost_table): Add arrowlake. * config/i386/i386.h (enum processor_type): Add PROCESSOR_ARROWLAKE. * config/i386/x86-tune.def: Add m_ARROWLAKE. * doc/extend.texi: Add arrowlake and arrowlake-s. * doc/invoke.texi: Ditto. gcc/testsuite/ChangeLog: * g++.target/i386/mv16.C: Add arrowlake and arrowlake-s. * gcc.target/i386/funcspec-56.inc: Handle new march. --- gcc/common/config/i386/cpuinfo.h | 18 ++++++ gcc/common/config/i386/i386-common.cc | 7 ++ gcc/common/config/i386/i386-cpuinfo.h | 2 + gcc/config.gcc | 3 +- gcc/config/i386/driver-i386.cc | 5 +- gcc/config/i386/i386-c.cc | 7 ++ gcc/config/i386/i386-options.cc | 2 + gcc/config/i386/i386.h | 4 ++ gcc/config/i386/x86-tune.def | 92 +++++++++++++++------------ gcc/doc/extend.texi | 6 ++ gcc/doc/invoke.texi | 17 +++++ gcc/testsuite/g++.target/i386/mv16.C | 12 ++++ gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + 13 files changed, 136 insertions(+), 41 deletions(-) (limited to 'gcc') diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index f9434f0..30ef0d3 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -586,6 +586,24 @@ get_intel_cpu (struct __processor_model *cpu_model, CHECK___builtin_cpu_is ("grandridge"); cpu_model->__cpu_type = INTEL_GRANDRIDGE; break; + case 0xc5: + /* Arrow Lake. */ + cpu = "arrowlake"; + CHECK___builtin_cpu_is ("corei7"); + CHECK___builtin_cpu_is ("arrowlake"); + cpu_model->__cpu_type = INTEL_COREI7; + cpu_model->__cpu_subtype = INTEL_COREI7_ARROWLAKE; + break; + case 0xc6: + /* Arrow Lake S. */ + case 0xbd: + /* Lunar Lake. */ + cpu = "arrowlake-s"; + CHECK___builtin_cpu_is ("corei7"); + CHECK___builtin_cpu_is ("arrowlake-s"); + cpu_model->__cpu_type = INTEL_COREI7; + cpu_model->__cpu_subtype = INTEL_COREI7_ARROWLAKE_S; + break; case 0x17: case 0x1d: /* Penryn. */ diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 610cabe..3d51694 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -2044,6 +2044,7 @@ const char *const processor_names[] = "alderlake", "rocketlake", "graniterapids", + "arrowlake", "intel", "lujiazui", "geode", @@ -2169,6 +2170,12 @@ const pta processor_alias_table[] = M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS), P_PROC_AVX512F}, {"graniterapids-d", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS_D, M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS_D), P_PROC_AVX512F}, + {"arrowlake", PROCESSOR_ARROWLAKE, CPU_HASWELL, PTA_ARROWLAKE, + M_CPU_SUBTYPE (INTEL_COREI7_ARROWLAKE), P_PROC_AVX2}, + {"arrowlake-s", PROCESSOR_ARROWLAKE, CPU_HASWELL, PTA_ARROWLAKE_S, + M_CPU_SUBTYPE (INTEL_COREI7_ARROWLAKE_S), P_PROC_AVX2}, + {"lunarlake", PROCESSOR_ARROWLAKE, CPU_HASWELL, PTA_ARROWLAKE_S, + M_CPU_SUBTYPE (INTEL_COREI7_ARROWLAKE_S), P_PROC_AVX2}, {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index be04d85..9153b4d 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -99,6 +99,8 @@ enum processor_subtypes AMDFAM19H_ZNVER4, INTEL_COREI7_GRANITERAPIDS, INTEL_COREI7_GRANITERAPIDS_D, + INTEL_COREI7_ARROWLAKE, + INTEL_COREI7_ARROWLAKE_S, CPU_SUBTYPE_MAX }; diff --git a/gcc/config.gcc b/gcc/config.gcc index 305e859..eba69a4 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -683,7 +683,8 @@ silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \ skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \ sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 \ nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \ -sierraforest graniterapids graniterapids-d grandridge native" +sierraforest graniterapids graniterapids-d grandridge arrowlake arrowlake-s \ +native" # Additional x86 processors supported by --with-cpu=. Each processor # MUST be separated by exactly one space. diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc index 4c362ff..08d0aed 100644 --- a/gcc/config/i386/driver-i386.cc +++ b/gcc/config/i386/driver-i386.cc @@ -591,8 +591,11 @@ const char *host_detect_local_cpu (int argc, const char **argv) /* This is unknown family 0x6 CPU. */ if (has_feature (FEATURE_AVX)) { + /* Assume Arrow Lake S. */ + if (has_feature (FEATURE_SM3)) + cpu = "arrowlake-s"; /* Assume Grand Ridge. */ - if (has_feature (FEATURE_RAOINT)) + else if (has_feature (FEATURE_RAOINT)) cpu = "grandridge"; /* Assume Granite Rapids D. */ else if (has_feature (FEATURE_AMX_COMPLEX)) diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index 0adec14..808fc42 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -266,6 +266,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__rocketlake"); def_or_undef (parse_in, "__rocketlake__"); break; + case PROCESSOR_ARROWLAKE: + def_or_undef (parse_in, "__arrowlake"); + def_or_undef (parse_in, "__arrowlake__"); + break; /* use PROCESSOR_max to not set/unset the arch macro. */ case PROCESSOR_max: break; @@ -447,6 +451,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, case PROCESSOR_GRANITERAPIDS: def_or_undef (parse_in, "__tune_graniterapids__"); break; + case PROCESSOR_ARROWLAKE: + def_or_undef (parse_in, "__tune_arrowlake__"); + break; case PROCESSOR_INTEL: case PROCESSOR_GENERIC: break; diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 347ed2d..edbb927 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -139,6 +139,7 @@ along with GCC; see the file COPYING3. If not see #define m_TREMONT (HOST_WIDE_INT_1U<> (W-1) ^ x) - @@ -380,7 +385,8 @@ DEF_TUNE (X86_TUNE_USE_SIMODE_FIOP, "use_simode_fiop", ~(m_PENT | m_LAKEMONT | m_PPRO | m_CORE_ALL | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_AMD_MULTIPLE | m_LUJIAZUI | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT - | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)) + | m_ALDERLAKE | m_ARROWLAKE | m_CORE_ATOM + | m_GENERIC)) /* X86_TUNE_USE_FFREEP: Use freep instruction instead of fstp. */ DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE | m_LUJIAZUI) @@ -389,8 +395,8 @@ DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE | m_LUJIAZUI) DEF_TUNE (X86_TUNE_EXT_80387_CONSTANTS, "ext_80387_constants", m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_K6_GEODE | m_ATHLON_K8 | m_LUJIAZUI - | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM - | m_GENERIC) + | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_ARROWLAKE + | m_CORE_ATOM | m_GENERIC) /*****************************************************************************/ /* SSE instruction selection tuning */ @@ -406,15 +412,16 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill", DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal", m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE - | m_CORE_ATOM | m_AMDFAM10 | m_BDVER | m_BTVER | m_ZNVER | m_LUJIAZUI - | m_GENERIC) + | m_ARROWLAKE | m_CORE_ATOM | m_AMDFAM10 | m_BDVER + | m_BTVER | m_ZNVER | m_LUJIAZUI | m_GENERIC) /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL: Use movups for misaligned stores instead of a sequence loading registers by parts. */ DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal", m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE - | m_CORE_ATOM | m_BDVER | m_ZNVER | m_LUJIAZUI | m_GENERIC) + | m_ARROWLAKE | m_CORE_ATOM | m_BDVER | m_ZNVER + | m_LUJIAZUI | m_GENERIC) /* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL: Use packed single precision 128bit instructions instead of double where possible. */ @@ -424,13 +431,14 @@ DEF_TUNE (X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL, "sse_packed_single_insn_optim /* X86_TUNE_SSE_TYPELESS_STORES: Always movaps/movups for 128bit stores. */ DEF_TUNE (X86_TUNE_SSE_TYPELESS_STORES, "sse_typeless_stores", m_AMD_MULTIPLE | m_LUJIAZUI | m_CORE_ALL | m_TREMONT | m_ALDERLAKE - | m_CORE_ATOM | m_GENERIC) + | m_ARROWLAKE | m_CORE_ATOM | m_GENERIC) /* X86_TUNE_SSE_LOAD0_BY_PXOR: Always use pxor to load0 as opposed to xorps/xorpd and other variants. */ DEF_TUNE (X86_TUNE_SSE_LOAD0_BY_PXOR, "sse_load0_by_pxor", m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BDVER | m_BTVER | m_ZNVER - | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC) + | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_ARROWLAKE + | m_CORE_ATOM | m_GENERIC) /* X86_TUNE_INTER_UNIT_MOVES_TO_VEC: Enable moves in from integer to SSE registers. If disabled, the moves will be done by storing @@ -477,12 +485,13 @@ DEF_TUNE (X86_TUNE_SLOW_PSHUFB, "slow_pshufb", /* X86_TUNE_AVOID_4BYTE_PREFIXES: Avoid instructions requiring 4+ bytes of prefixes. */ DEF_TUNE (X86_TUNE_AVOID_4BYTE_PREFIXES, "avoid_4byte_prefixes", m_SILVERMONT | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE - | m_CORE_ATOM | m_INTEL) + | m_ARROWLAKE | m_CORE_ATOM | m_INTEL) /* X86_TUNE_USE_GATHER_2PARTS: Use gather instructions for vectors with 2 elements. */ DEF_TUNE (X86_TUNE_USE_GATHER_2PARTS, "use_gather_2parts", - ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ZNVER4 | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)) + ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ZNVER4 | m_ALDERLAKE + | m_ARROWLAKE | m_CORE_ATOM | m_GENERIC)) /* X86_TUNE_USE_SCATTER_2PARTS: Use scater instructions for vectors with 2 elements. */ @@ -492,7 +501,8 @@ DEF_TUNE (X86_TUNE_USE_SCATTER_2PARTS, "use_scatter_2parts", /* X86_TUNE_USE_GATHER_4PARTS: Use gather instructions for vectors with 4 elements. */ DEF_TUNE (X86_TUNE_USE_GATHER_4PARTS, "use_gather_4parts", - ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ZNVER4 | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)) + ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ZNVER4 | m_ALDERLAKE + | m_ARROWLAKE | m_CORE_ATOM | m_GENERIC)) /* X86_TUNE_USE_SCATTER_4PARTS: Use scater instructions for vectors with 4 elements. */ @@ -502,7 +512,8 @@ DEF_TUNE (X86_TUNE_USE_SCATTER_4PARTS, "use_scatter_4parts", /* X86_TUNE_USE_GATHER: Use gather instructions for vectors with 8 or more elements. */ DEF_TUNE (X86_TUNE_USE_GATHER, "use_gather", - ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER4 | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)) + ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER4 | m_ALDERLAKE | m_ARROWLAKE + | m_CORE_ATOM | m_GENERIC)) /* X86_TUNE_USE_SCATTER: Use scater instructions for vectors with 8 or more elements. */ @@ -516,7 +527,8 @@ DEF_TUNE (X86_TUNE_AVOID_128FMA_CHAINS, "avoid_fma_chains", m_ZNVER1 | m_ZNVER2 /* X86_TUNE_AVOID_256FMA_CHAINS: Avoid creating loops with tight 256bit or smaller FMA chain. */ DEF_TUNE (X86_TUNE_AVOID_256FMA_CHAINS, "avoid_fma256_chains", m_ZNVER2 | m_ZNVER3 - | m_ALDERLAKE | m_SAPPHIRERAPIDS | m_CORE_ATOM) + | m_ALDERLAKE | m_ARROWLAKE | m_SAPPHIRERAPIDS + | m_CORE_ATOM) /* X86_TUNE_AVOID_512FMA_CHAINS: Avoid creating loops with tight 512bit or smaller FMA chain. */ @@ -560,12 +572,14 @@ DEF_TUNE (X86_TUNE_AVX512_SPLIT_REGS, "avx512_split_regs", m_ZNVER4) /* X86_TUNE_AVX256_MOVE_BY_PIECES: Optimize move_by_pieces with 256-bit AVX instructions. */ DEF_TUNE (X86_TUNE_AVX256_MOVE_BY_PIECES, "avx256_move_by_pieces", - m_ALDERLAKE | m_CORE_AVX2 | m_ZNVER1 | m_ZNVER2 | m_ZNVER3) + m_ALDERLAKE | m_ARROWLAKE | m_CORE_AVX2 | m_ZNVER1 + | m_ZNVER2 | m_ZNVER3) /* X86_TUNE_AVX256_STORE_BY_PIECES: Optimize store_by_pieces with 256-bit AVX instructions. */ DEF_TUNE (X86_TUNE_AVX256_STORE_BY_PIECES, "avx256_store_by_pieces", - m_ALDERLAKE | m_CORE_AVX2 | m_ZNVER1 | m_ZNVER2 | m_ZNVER3) + m_ALDERLAKE | m_ARROWLAKE | m_CORE_AVX2 | m_ZNVER1 + | m_ZNVER2 | m_ZNVER3) /* X86_TUNE_AVX512_MOVE_BY_PIECES: Optimize move_by_pieces with 512-bit AVX instructions. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 5e20c83..093bd97 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -22269,6 +22269,12 @@ Intel Atom Sierra Forest CPU. @item grandridge Intel Atom Grand Ridge CPU. +@item arrowlake +Intel Core i7 Arrow Lake CPU. + +@item arrowlake-s +Intel Core i7 Arrow Lake S CPU. + @item knl Intel Knights Landing CPU. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index dd28320..88e3c62 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -32578,6 +32578,23 @@ PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL, AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, ENQCMD, UINTR and RAOINT instruction set support. +@item arrowlake +Intel Arrow Lake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, +SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, +XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI, +MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT, +PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL, AVX-VNNI, +AVXIFMA, AVXVNNIINT8, AVXNECONVERT and CMPCCXADD instruction set support. + +@item arrowlake-s +Intel Arrow Lake S CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, +SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, +XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI, +MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT, +PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL, AVX-VNNI, +AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AVXVNNIINT16, SHA512, SM3 +and SM4 instruction set support. + @item knl Intel Knight's Landing CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, diff --git a/gcc/testsuite/g++.target/i386/mv16.C b/gcc/testsuite/g++.target/i386/mv16.C index 2158d58..07f4a2a 100644 --- a/gcc/testsuite/g++.target/i386/mv16.C +++ b/gcc/testsuite/g++.target/i386/mv16.C @@ -108,6 +108,14 @@ int __attribute__ ((target("arch=graniterapids-d"))) foo () { return 28; } +int __attribute__ ((target("arch=arrowlake"))) foo () { + return 29; +} + +int __attribute__ ((target("arch=arrowlake-s"))) foo () { + return 30; +} + int main () { int val = foo (); @@ -154,6 +162,10 @@ int main () assert (val == 27); else if (__builtin_cpu_is ("graniterapids-d")) assert (val == 28); + else if (__builtin_cpu_is ("arrowlake")) + assert (val == 29); + else if (__builtin_cpu_is ("arrowlake-s")) + assert (val == 30); else assert (val == 0); diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index 577bfc7..ca558b3 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -212,6 +212,8 @@ extern void test_arch_alderlake (void) __attribute__((__target__("arch= extern void test_arch_rocketlake (void) __attribute__((__target__("arch=rocketlake"))); extern void test_arch_graniterapids (void) __attribute__((__target__("arch=graniterapids"))); extern void test_arch_graniterapids_d (void) __attribute__((__target__("arch=graniterapids-d"))); +extern void test_arch_arrowlake (void) __attribute__((__target__("arch=arrowlake"))); +extern void test_arch_arrowlake_s (void) __attribute__((__target__("arch=arrowlake-s"))); extern void test_arch_lujiazui (void) __attribute__((__target__("arch=lujiazui"))); extern void test_arch_k8 (void) __attribute__((__target__("arch=k8"))); extern void test_arch_k8_sse3 (void) __attribute__((__target__("arch=k8-sse3"))); -- cgit v1.1 From d20e542ecd8cfc009b120f9e432caeb7005e7c53 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Fri, 14 Jul 2023 09:55:57 -0700 Subject: Fix PR 110666: `(a != 2) == a` produces wrong code I had messed up the case where the outer operator is `==`. The check for the resulting should have been `==` and not `!=`. This patch fixes that and adds a full runtime testcase now for all cases to make sure it works. OK? Bootstrapped and tested on x86-64-linux-gnu with no regressions. gcc/ChangeLog: PR tree-optimization/110666 * match.pd (A NEEQ (A NEEQ CST)): Fix Outer EQ case. gcc/testsuite/ChangeLog: PR tree-optimization/110666 * gcc.c-torture/execute/pr110666-1.c: New test. --- gcc/match.pd | 34 +++++++++------- gcc/testsuite/gcc.c-torture/execute/pr110666-1.c | 51 ++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr110666-1.c (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index 351d928..88061fa 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6431,8 +6431,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* x != (typeof x)(x == CST) -> CST == 0 ? 1 : (CST == 1 ? (x!=0&&x!=1) : x != 0) */ /* x != (typeof x)(x != CST) -> CST == 1 ? 1 : (CST == 0 ? (x!=0&&x!=1) : x != 1) */ -/* x == (typeof x)(x == CST) -> CST == 0 ? 0 : (CST == 1 ? (x==0||x==1) : x != 0) */ -/* x == (typeof x)(x != CST) -> CST == 1 ? 0 : (CST == 0 ? (x==0||x==1) : x != 1) */ +/* x == (typeof x)(x == CST) -> CST == 0 ? 0 : (CST == 1 ? (x==0||x==1) : x == 0) */ +/* x == (typeof x)(x != CST) -> CST == 1 ? 0 : (CST == 0 ? (x==0||x==1) : x == 1) */ (for outer (ne eq) (for inner (ne eq) (simplify @@ -6443,23 +6443,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) bool innereq = inner == EQ_EXPR; bool outereq = outer == EQ_EXPR; } - (switch - (if (innereq ? cst0 : cst1) - { constant_boolean_node (!outereq, type); }) - (if (innereq ? cst1 : cst0) + (switch + (if (innereq ? cst0 : cst1) + { constant_boolean_node (!outereq, type); }) + (if (innereq ? cst1 : cst0) + (with { + tree utype = unsigned_type_for (TREE_TYPE (@0)); + tree ucst1 = build_one_cst (utype); + } + (if (!outereq) + (gt (convert:utype @0) { ucst1; }) + (le (convert:utype @0) { ucst1; }) + ) + ) + ) (with { - tree utype = unsigned_type_for (TREE_TYPE (@0)); - tree ucst1 = build_one_cst (utype); + tree value = build_int_cst (TREE_TYPE (@0), !innereq); } - (if (!outereq) - (gt (convert:utype @0) { ucst1; }) - (le (convert:utype @0) { ucst1; }) + (if (outereq) + (eq @0 { value; }) + (ne @0 { value; }) ) ) ) - (if (innereq) - (ne @0 { build_zero_cst (TREE_TYPE (@0)); })) - (ne @0 { build_one_cst (TREE_TYPE (@0)); })) ) ) ) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110666-1.c b/gcc/testsuite/gcc.c-torture/execute/pr110666-1.c new file mode 100644 index 0000000..b22eb77 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr110666-1.c @@ -0,0 +1,51 @@ + +#define func_name(outer,inner,cst) outer##inner##_##cst +#define func_name_v(outer,inner,cst) outer##inner##_##cst##_v + +#define func_decl(outer,inner,cst) \ +int outer##inner##_##cst (int) __attribute__((noipa)); \ +int outer##inner##_##cst (int a) { \ + return (a op_##inner cst) op_##outer a; \ +} \ +int outer##inner##_##cst##_v (int) __attribute__((noipa)); \ +int outer##inner##_##cst##_v (volatile int a) { \ + return (a op_##inner cst) op_##outer a; \ +} + +#define functions_n(outer, inner) \ +func_decl(outer,inner,0) \ +func_decl(outer,inner,1) \ +func_decl(outer,inner,2) + +#define functions() \ +functions_n(eq,eq) \ +functions_n(eq,ne) \ +functions_n(ne,eq) \ +functions_n(ne,ne) + +#define op_ne != +#define op_eq == + +#define test(inner,outer,cst,arg) \ +func_name_v (inner,outer,cst)(arg) != func_name(inner,outer,cst)(arg) + +functions() + +#define tests_n(inner,outer,arg) \ +if (test(inner,outer,0,arg)) __builtin_abort(); \ +if (test(inner,outer,1,arg)) __builtin_abort(); \ +if (test(inner,outer,2,arg)) __builtin_abort(); + +#define tests(arg) \ +tests_n(eq,eq,arg) \ +tests_n(eq,ne,arg) \ +tests_n(ne,eq,arg) \ +tests_n(ne,ne,arg) + + +int main() +{ + for(int n = -1; n <= 2; n++) { + tests(n) + } +} -- cgit v1.1 From 5ae1f391934a853a36f4bcc5a849c7900bec43b0 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 17 Jul 2023 07:35:08 +0100 Subject: Fix bootstrap failure (with g++ 4.8.5) in tree-if-conv.cc. This patch fixes the bootstrap failure I'm seeing using gcc 4.8.5 as the host compiler. 2023-07-17 Roger Sayle gcc/ChangeLog * tree-if-conv.cc (predicate_scalar_phi): Make the arguments to the std::sort comparison lambda function const. --- gcc/tree-if-conv.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index 91e2eff..799f071 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -2204,7 +2204,8 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) } /* Sort elements based on rankings ARGS. */ - std::sort(argsKV.begin(), argsKV.end(), [](ArgEntry &left, ArgEntry &right) { + std::sort(argsKV.begin(), argsKV.end(), [](const ArgEntry &left, + const ArgEntry &right) { return left.second < right.second; }); -- cgit v1.1 From 0407ae8a7732d90622a65ddf1798c9d51d450e9d Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sun, 16 Jul 2023 22:31:59 +0000 Subject: PR 95923: More (boolean) bitop simplifications in match.pd This adds the boolean version of some of the simplifications that were added with r8-4395-ge268a77b59cb78. That are the following: (a | b) & (a == b) --> a & b a | (a == b) --> a | (b ^ 1) (a & b) | (a == b) --> a == b OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: PR tree-optimization/95923 * match.pd ((a|b)&(a==b),a|(a==b),(a&b)|(a==b)): New transformation. gcc/testsuite/ChangeLog: PR tree-optimization/95923 * gcc.dg/tree-ssa/bitops-2.c: New test. * gcc.dg/tree-ssa/bool-checks-1.c: New test. --- gcc/match.pd | 15 ++++++++++ gcc/testsuite/gcc.dg/tree-ssa/bitops-2.c | 41 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/bool-checks-1.c | 22 ++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bitops-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-checks-1.c (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index 88061fa..054e658 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1226,11 +1226,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_and:c (bit_ior @0 @1) (bit_not (bit_xor:c @0 @1))) (bit_and @0 @1)) +/* (a | b) & (a == b) --> a & b (boolean version of the above). */ +(simplify + (bit_and:c (bit_ior @0 @1) (nop_convert? (eq:c @0 @1))) + (bit_and @0 @1)) + /* a | ~(a ^ b) --> a | ~b */ (simplify (bit_ior:c @0 (bit_not:s (bit_xor:c @0 @1))) (bit_ior @0 (bit_not @1))) +/* a | (a == b) --> a | (b^1) (boolean version of the above). */ +(simplify + (bit_ior:c @0 (nop_convert? (eq:c @0 @1))) + (bit_ior @0 (bit_xor @1 { build_one_cst (type); }))) + /* (a | b) | (a &^ b) --> a | b */ (for op (bit_and bit_xor) (simplify @@ -1242,6 +1252,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_ior:c (bit_and:c @0 @1) (bit_not@2 (bit_xor @0 @1))) @2) +/* (a & b) | (a == b) --> a == b */ +(simplify + (bit_ior:c (bit_and:c @0 @1) (nop_convert?@2 (eq @0 @1))) + @2) + /* ~(~a & b) --> a | ~b */ (simplify (bit_not (bit_and:cs (bit_not @0) @1)) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-2.c b/gcc/testsuite/gcc.dg/tree-ssa/bitops-2.c new file mode 100644 index 0000000..d8128f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/bitops-2.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O -fdump-tree-optimized-raw" } */ + +#define DECLS(n,VOL) \ +__attribute__((noinline,noclone)) \ +_Bool h##n(_Bool A,_Bool B){ \ + VOL _Bool C = A | B; \ + VOL _Bool D = A == B; \ + return C & D; \ +} \ +__attribute__((noinline,noclone)) \ +_Bool i##n(_Bool A,_Bool B){ \ + VOL _Bool C = A == B; \ + return A | C; \ +} \ +__attribute__((noinline,noclone)) \ +_Bool k##n(_Bool A,_Bool B){ \ + VOL _Bool C = A & B; \ + VOL _Bool D = A == B; \ + return C | D; \ +} \ + +DECLS(0,) +DECLS(1,volatile) + +int main(){ + for(int A = 0; A <= 1; ++A) + for(int B = 0; B <= 1; ++B) + { + if (h0 (A, B) != h1 (A, B)) __builtin_abort(); + if (i0 (A, B) != i1 (A, B)) __builtin_abort(); + if (k0 (A, B) != k1 (A, B)) __builtin_abort(); + } +} + +/* { dg-final { scan-tree-dump-times "bit_not_expr," 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "bit_and_expr," 3 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "bit_ior_expr," 4 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "eq_expr," 4 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "ne_expr," 7 "optimized"} } */ +/* { dg-final { scan-tree-dump-not "bit_xor_expr," "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-checks-1.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-checks-1.c new file mode 100644 index 0000000..370a23a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-checks-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized-raw" } */ +/* PR tree-optimization/95923 */ + +_Bool f(_Bool a, _Bool b) +{ + if (!a && !b) + return 0; + if (!a && b) + return 0; + if (a && !b) + return 0; + return 1; +} + +/* { dg-final { scan-tree-dump-times "bit_and_expr," 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-not "bit_not_expr," "optimized"} } */ +/* { dg-final { scan-tree-dump-not "bit_ior_expr," "optimized"} } */ +/* { dg-final { scan-tree-dump-not "bit_xor_expr," "optimized"} } */ +/* { dg-final { scan-tree-dump-not "eq_expr," "optimized"} } */ +/* { dg-final { scan-tree-dump-not "ne_expr," "optimized"} } */ +/* { dg-final { scan-tree-dump-not "gimple_cond" "optimized"} } */ -- cgit v1.1 From 56cf8b01fe1d4d4bb33a107e5d490f589d5f05bc Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Fri, 14 Jul 2023 12:16:17 +0200 Subject: Normalize irange_bitmask before union/intersect. The bit twiddling in union/intersect for the value/mask pair must be normalized to have the unknown bits with a value of 0 in order to make the math simpler. Normalizing at construction slowed VRP by 1.5% so I opted to normalize before updating the bitmask in range-ops, since it was the only user. However, with upcoming changes there will be multiple setters of the mask (IPA and CCP), so we need something more general. I played with various alternatives, and settled on normalizing before union/intersect which were the ones needing the bits cleared. With this patch, there's no noticeable difference in performance either in VRP or in overall compilation. gcc/ChangeLog: * value-range.cc (irange_bitmask::verify_mask): Mask need not be normalized. * value-range.h (irange_bitmask::union_): Normalize beforehand. (irange_bitmask::intersect): Same. --- gcc/value-range.cc | 3 --- gcc/value-range.h | 12 ++++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 011bdbd..2abf57b 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1953,9 +1953,6 @@ void irange_bitmask::verify_mask () const { gcc_assert (m_value.get_precision () == m_mask.get_precision ()); - // Unknown bits must have their corresponding value bits cleared as - // it simplifies union and intersect. - gcc_assert (wi::bit_and (m_mask, m_value) == 0); } void diff --git a/gcc/value-range.h b/gcc/value-range.h index 0170188..d8af6fc 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -211,8 +211,12 @@ irange_bitmask::operator== (const irange_bitmask &src) const } inline bool -irange_bitmask::union_ (const irange_bitmask &src) +irange_bitmask::union_ (const irange_bitmask &orig_src) { + // Normalize mask. + irange_bitmask src (orig_src.m_value & ~orig_src.m_mask, orig_src.m_mask); + m_value &= ~m_mask; + irange_bitmask save (*this); m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value); m_value = m_value & src.m_value; @@ -222,8 +226,12 @@ irange_bitmask::union_ (const irange_bitmask &src) } inline bool -irange_bitmask::intersect (const irange_bitmask &src) +irange_bitmask::intersect (const irange_bitmask &orig_src) { + // Normalize mask. + irange_bitmask src (orig_src.m_value & ~orig_src.m_mask, orig_src.m_mask); + m_value &= ~m_mask; + irange_bitmask save (*this); // If we have two known bits that are incompatible, the resulting // bit is undefined. It is unclear whether we should set the entire -- cgit v1.1 From 53cf0c583b0d80f9db95edfde5778b11c572559f Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Sun, 16 Jul 2023 20:44:02 +0200 Subject: Add global setter for value/mask pair for SSA names. This patch provides a way to set the value/mask pair of known bits globally, similarly to how we can use set_nonzero_bits for known 0 bits. This can then be used by CCP and IPA to set value/mask info instead of throwing away the known 1 bits. In further clean-ups, I will see if it makes sense to remove set_nonzero_bits altogether, since it is subsumed by value/mask. gcc/ChangeLog: * tree-ssanames.cc (set_bitmask): New. * tree-ssanames.h (set_bitmask): New. --- gcc/tree-ssanames.cc | 15 +++++++++++++++ gcc/tree-ssanames.h | 1 + 2 files changed, 16 insertions(+) (limited to 'gcc') diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc index 5fdb6a3..f543943 100644 --- a/gcc/tree-ssanames.cc +++ b/gcc/tree-ssanames.cc @@ -465,6 +465,21 @@ set_nonzero_bits (tree name, const wide_int &mask) set_range_info (name, r); } +/* Update the known bits of NAME. + + Zero bits in MASK cover constant values. Set bits in MASK cover + unknown values. VALUE are the known bits. */ + +void +set_bitmask (tree name, const wide_int &value, const wide_int &mask) +{ + gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); + + int_range<2> r (TREE_TYPE (name)); + r.update_bitmask (irange_bitmask (value, mask)); + set_range_info (name, r); +} + /* Return a widest_int with potentially non-zero bits in SSA_NAME NAME, the constant for INTEGER_CST, or -1 if unknown. */ diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index f3fa609..b5e3f22 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -59,6 +59,7 @@ struct GTY(()) ptr_info_def /* Sets the value range to SSA. */ extern bool set_range_info (tree, const vrange &); extern void set_nonzero_bits (tree, const wide_int &); +extern void set_bitmask (tree, const wide_int &value, const wide_int &mask); extern wide_int get_nonzero_bits (const_tree); extern bool ssa_name_has_boolean_range (tree); extern void init_ssanames (struct function *, int); -- cgit v1.1 From 3228e5c078ed2b505e4ad238b09c1817b38f9cfb Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 17 Jul 2023 09:20:33 +0200 Subject: tree-optimization/110669 - bogus matching of loop bitop The matching code lacked a check that we end up with a PHI node in the loop header. This caused us to match a random PHI argument now catched by the extra PHI_ARG_DEF_FROM_EDGE checking. PR tree-optimization/110669 * tree-scalar-evolution.cc (analyze_and_compute_bitop_with_inv_effect): Check we matched a header PHI. * gcc.dg/torture/pr110669.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr110669.c | 15 +++++++++++++++ gcc/tree-scalar-evolution.cc | 1 + 2 files changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr110669.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/torture/pr110669.c b/gcc/testsuite/gcc.dg/torture/pr110669.c new file mode 100644 index 0000000..b0a9ea4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110669.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +int g_29, func_47_p_48, func_47_p_51_l_129; +void func_47_p_51() +{ + for (;;) + { + func_47_p_51_l_129 = 0; + for (; func_47_p_51_l_129 <= 1; func_47_p_51_l_129 += 1) + { + short *l_160 = (short *)(__UINTPTR_TYPE__)(func_47_p_48 || *l_160); + *l_160 &= g_29; + } + } +} diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc index ba47a68..2abe8fa 100644 --- a/gcc/tree-scalar-evolution.cc +++ b/gcc/tree-scalar-evolution.cc @@ -3674,6 +3674,7 @@ analyze_and_compute_bitop_with_inv_effect (class loop* loop, tree phidef, if (TREE_CODE (match_op[1]) != SSA_NAME || !expr_invariant_in_loop_p (loop, match_op[0]) || !(header_phi = dyn_cast (SSA_NAME_DEF_STMT (match_op[1]))) + || gimple_bb (header_phi) != loop->header || gimple_phi_num_args (header_phi) != 2) return NULL_TREE; -- cgit v1.1 From 081c623ca88dc53abe34b5f5661e79fcde800cef Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Mon, 17 Jul 2023 03:44:59 -0500 Subject: vect: Initialize new_temp to avoid false positive warning [PR110652] As PR110652 and its duplicate PRs show, there could be one build error error: 'new_temp' may be used uninitialized for some build configurations. It's a false positive warning (or error at -Werror), but in order to make the build succeed, this patch is to initialize the reported variable 'new_temp' as NULL_TREE. PR tree-optimization/110652 gcc/ChangeLog: * tree-vect-stmts.cc (vectorizable_load): Initialize new_temp as NULL_TREE. --- gcc/tree-vect-stmts.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index c08d0ef..cb86d54 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -9297,7 +9297,8 @@ vectorizable_load (vec_info *vinfo, class loop *containing_loop = gimple_bb (stmt_info->stmt)->loop_father; bool nested_in_vect_loop = false; tree elem_type; - tree new_temp; + /* Avoid false positive uninitialized warning, see PR110652. */ + tree new_temp = NULL_TREE; machine_mode mode; tree dummy; tree dataref_ptr = NULL_TREE; -- cgit v1.1 From c29584fc29df0c5075ad57cce5bea447b1d061a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20M=C3=BCllner?= Date: Mon, 17 Jul 2023 10:59:15 +0200 Subject: riscv: Fix warning in riscv_regno_ok_for_index_p MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variable `regno` is currently not used in riscv_regno_ok_for_index_p(), which triggers a compiler warning. Let's address this. Fixes: 423604278ed5 ("riscv: Prepare backend for index registers") Reported-by: Juzhe Zhong Reported-by: Andreas Schwab Signed-off-by: Christoph Müllner gcc/ChangeLog: * config/riscv/riscv.cc (riscv_regno_ok_for_index_p): Remove parameter name from declaration of unused parameter. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 6ed735d..ae3c034 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -861,7 +861,7 @@ riscv_index_reg_class () but extensions might support that. */ int -riscv_regno_ok_for_index_p (int regno) +riscv_regno_ok_for_index_p (int) { return 0; } -- cgit v1.1 From 64c727131133d8d2abf02ff4df5026749d9bd253 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Fri, 14 Jul 2023 12:24:29 +0200 Subject: Export value/mask known bits from IPA. Currently IPA throws away the known 1 bits because VRP and irange have traditionally only had a way of tracking known 0s (set_nonzero_bits). With the ability to keep all the known bits in the irange, we can now save this between passes. gcc/ChangeLog: * ipa-prop.cc (ipcp_update_bits): Export value/mask known bits. --- gcc/ipa-prop.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index d2b998f..5d790ff 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -5853,10 +5853,9 @@ ipcp_update_bits (struct cgraph_node *node, ipcp_transformation *ts) { unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef)); signop sgn = TYPE_SIGN (TREE_TYPE (ddef)); - - wide_int nonzero_bits = wide_int::from (bits[i]->mask, prec, UNSIGNED) - | wide_int::from (bits[i]->value, prec, sgn); - set_nonzero_bits (ddef, nonzero_bits); + wide_int mask = wide_int::from (bits[i]->mask, prec, UNSIGNED); + wide_int value = wide_int::from (bits[i]->value, prec, sgn); + set_bitmask (ddef, value, mask); } else { -- cgit v1.1 From da93c41c4ea124d61d41fb8629b801f74886284c Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Mon, 17 Jul 2023 16:19:46 +0800 Subject: RISC-V: Support non-SLP unordered reduction This patch add reduc_*_scal to support reduction auto-vectorization. Use COND_LEN_* + reduc_*_scal to support unordered non-SLP auto-vectorization. Consider this following case: int __attribute__((noipa)) and_loop (int32_t * __restrict x, int32_t n, int res) { for (int i = 0; i < n; ++i) res &= x[i]; return res; } ASM: and_loop: ble a1,zero,.L4 vsetvli a3,zero,e32,m1,ta,ma vmv.v.i v1,-1 .L3: vsetvli a5,a1,e32,m1,tu,ma ------------> MUST BE "TU". slli a4,a5,2 sub a1,a1,a5 vle32.v v2,0(a0) add a0,a0,a4 vand.vv v1,v2,v1 bne a1,zero,.L3 vsetivli zero,1,e32,m1,ta,ma vmv.v.i v2,-1 vsetvli a3,zero,e32,m1,ta,ma vredand.vs v1,v1,v2 vmv.x.s a5,v1 and a0,a2,a5 ret .L4: mv a0,a2 ret Fix bug of VSETVL PASS which is caused by reduction testcase. SLP reduction and floating-point in-order reduction are not supported yet. gcc/ChangeLog: * config/riscv/autovec.md (reduc_plus_scal_): New pattern. (reduc_smax_scal_): Ditto. (reduc_umax_scal_): Ditto. (reduc_smin_scal_): Ditto. (reduc_umin_scal_): Ditto. (reduc_and_scal_): Ditto. (reduc_ior_scal_): Ditto. (reduc_xor_scal_): Ditto. * config/riscv/riscv-protos.h (enum insn_type): Add reduction. (expand_reduction): New function. * config/riscv/riscv-v.cc (emit_vlmax_reduction_insn): Ditto. (emit_vlmax_fp_reduction_insn): Ditto. (get_m1_mode): Ditto. (expand_cond_len_binop): Fix name. (expand_reduction): New function * config/riscv/riscv-vsetvl.cc (gen_vsetvl_pat): Fix VSETVL BUG. (validate_change_or_fail): New function. (change_insn): Fix VSETVL BUG. (change_vsetvl_insn): Ditto. (pass_vsetvl::backward_demand_fusion): Ditto. (pass_vsetvl::df_post_optimization): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/rvv.exp: Add reduction tests. * gcc.target/riscv/rvv/autovec/reduc/reduc-1.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc-2.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc-3.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc-4.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-1.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-2.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-3.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-4.c: New test. --- gcc/config/riscv/autovec.md | 138 +++++++++++++++++++++ gcc/config/riscv/riscv-protos.h | 2 + gcc/config/riscv/riscv-v.cc | 84 ++++++++++++- gcc/config/riscv/riscv-vsetvl.cc | 57 ++++++--- .../gcc.target/riscv/rvv/autovec/reduc/reduc-1.c | 118 ++++++++++++++++++ .../gcc.target/riscv/rvv/autovec/reduc/reduc-2.c | 129 +++++++++++++++++++ .../gcc.target/riscv/rvv/autovec/reduc/reduc-3.c | 65 ++++++++++ .../gcc.target/riscv/rvv/autovec/reduc/reduc-4.c | 59 +++++++++ .../riscv/rvv/autovec/reduc/reduc_run-1.c | 56 +++++++++ .../riscv/rvv/autovec/reduc/reduc_run-2.c | 79 ++++++++++++ .../riscv/rvv/autovec/reduc/reduc_run-3.c | 49 ++++++++ .../riscv/rvv/autovec/reduc/reduc_run-4.c | 66 ++++++++++ gcc/testsuite/gcc.target/riscv/rvv/rvv.exp | 2 + 13 files changed, 887 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-4.c (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 64a41bd..8cdec75 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1554,3 +1554,141 @@ riscv_vector::expand_cond_len_ternop (icode, operands); DONE; }) + +;; ========================================================================= +;; == Reductions +;; ========================================================================= + +;; ------------------------------------------------------------------------- +;; ---- [INT] Tree reductions +;; ------------------------------------------------------------------------- +;; Includes: +;; - vredsum.vs +;; - vredmaxu.vs +;; - vredmax.vs +;; - vredminu.vs +;; - vredmin.vs +;; - vredand.vs +;; - vredor.vs +;; - vredxor.vs +;; ------------------------------------------------------------------------- + +(define_expand "reduc_plus_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_reduction (PLUS, operands, CONST0_RTX (mode)); + DONE; +}) + +(define_expand "reduc_smax_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + int prec = GET_MODE_PRECISION (mode); + rtx min = immed_wide_int_const (wi::min_value (prec, SIGNED), mode); + riscv_vector::expand_reduction (SMAX, operands, min); + DONE; +}) + +(define_expand "reduc_umax_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_reduction (UMAX, operands, CONST0_RTX (mode)); + DONE; +}) + +(define_expand "reduc_smin_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + int prec = GET_MODE_PRECISION (mode); + rtx max = immed_wide_int_const (wi::max_value (prec, SIGNED), mode); + riscv_vector::expand_reduction (SMIN, operands, max); + DONE; +}) + +(define_expand "reduc_umin_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + int prec = GET_MODE_PRECISION (mode); + rtx max = immed_wide_int_const (wi::max_value (prec, UNSIGNED), mode); + riscv_vector::expand_reduction (UMIN, operands, max); + DONE; +}) + +(define_expand "reduc_and_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_reduction (AND, operands, CONSTM1_RTX (mode)); + DONE; +}) + +(define_expand "reduc_ior_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_reduction (IOR, operands, CONST0_RTX (mode)); + DONE; +}) + +(define_expand "reduc_xor_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VI 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_reduction (XOR, operands, CONST0_RTX (mode)); + DONE; +}) + +;; ------------------------------------------------------------------------- +;; ---- [FP] Tree reductions +;; ------------------------------------------------------------------------- +;; Includes: +;; - vfredusum.vs +;; - vfredmax.vs +;; - vfredmin.vs +;; ------------------------------------------------------------------------- + +(define_expand "reduc_plus_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VF 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_reduction (PLUS, operands, CONST0_RTX (mode)); + DONE; +}) + +(define_expand "reduc_smax_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VF 1 "register_operand")] + "TARGET_VECTOR" +{ + REAL_VALUE_TYPE rv; + real_inf (&rv, true); + rtx f = const_double_from_real_value (rv, mode); + riscv_vector::expand_reduction (SMAX, operands, f); + DONE; +}) + +(define_expand "reduc_smin_scal_" + [(match_operand: 0 "register_operand") + (match_operand:VF 1 "register_operand")] + "TARGET_VECTOR" +{ + REAL_VALUE_TYPE rv; + real_inf (&rv, false); + rtx f = const_double_from_real_value (rv, mode); + riscv_vector::expand_reduction (SMIN, operands, f); + DONE; +}) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index f91c2d5..16fb8da 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -198,6 +198,7 @@ enum insn_type RVV_COMPRESS_OP = 4, RVV_GATHER_M_OP = 5, RVV_SCATTER_M_OP = 4, + RVV_REDUCTION_OP = 3, }; enum vlmul_type { @@ -281,6 +282,7 @@ bool has_vi_variant_p (rtx_code, rtx); void expand_vec_cmp (rtx, rtx_code, rtx, rtx); bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); void expand_cond_len_binop (rtx_code, rtx *); +void expand_reduction (rtx_code, rtx *, rtx); #endif bool sew64_scalar_helper (rtx *, rtx *, rtx, machine_mode, bool, void (*)(rtx *, rtx)); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index c3fd4a1..b4884a3 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1159,6 +1159,43 @@ emit_vlmax_compress_insn (unsigned icode, rtx *ops) e.emit_insn ((enum insn_code) icode, ops); } +/* Emit reduction instruction. */ +static void +emit_vlmax_reduction_insn (unsigned icode, int op_num, rtx *ops) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (GET_MODE (ops[1])).require (); + insn_expander e (op_num, + /* HAS_DEST_P */ true, + /* FULLY_UNMASKED_P */ true, + /* USE_REAL_MERGE_P */ false, + /* HAS_AVL_P */ true, + /* VLMAX_P */ true, dest_mode, + mask_mode); + + e.set_policy (TAIL_ANY); + e.emit_insn ((enum insn_code) icode, ops); +} + +/* Emit reduction instruction. */ +static void +emit_vlmax_fp_reduction_insn (unsigned icode, int op_num, rtx *ops) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (GET_MODE (ops[1])).require (); + insn_expander e (op_num, + /* HAS_DEST_P */ true, + /* FULLY_UNMASKED_P */ true, + /* USE_REAL_MERGE_P */ false, + /* HAS_AVL_P */ true, + /* VLMAX_P */ true, dest_mode, + mask_mode); + + e.set_policy (TAIL_ANY); + e.set_rounding_mode (FRM_DYN); + e.emit_insn ((enum insn_code) icode, ops); +} + /* Emit merge instruction. */ static machine_mode @@ -1651,6 +1688,17 @@ get_mask_mode (machine_mode mode) return get_vector_mode (BImode, GET_MODE_NUNITS (mode)); } +/* Return the appropriate M1 mode for MODE. */ + +static opt_machine_mode +get_m1_mode (machine_mode mode) +{ + scalar_mode smode = GET_MODE_INNER (mode); + unsigned int bytes = GET_MODE_SIZE (smode); + poly_uint64 m1_nunits = exact_div (BYTES_PER_RISCV_VECTOR, bytes); + return get_vector_mode (smode, m1_nunits); +} + /* Return the RVV vector mode that has NUNITS elements of mode INNER_MODE. This function is not only used by builtins, but also will be used by auto-vectorization in the future. */ @@ -3121,9 +3169,9 @@ expand_cond_len_binop (rtx_code code, rtx *ops) rtx ops[] = {dest, mask, merge, src1, src2}; insn_code icode = code_for_pred (code, mode); if (needs_fp_rounding (code, mode)) - emit_nonvlmax_fp_tu_insn (icode, RVV_BINOP_MU, ops, len); + emit_nonvlmax_fp_tu_insn (icode, RVV_BINOP_TU, ops, len); else - emit_nonvlmax_tu_insn (icode, RVV_BINOP_MU, ops, len); + emit_nonvlmax_tu_insn (icode, RVV_BINOP_TU, ops, len); } else /* FIXME: Enable this case when we support it in the middle-end. */ @@ -3316,4 +3364,36 @@ expand_cond_len_ternop (unsigned icode, rtx *ops) gcc_unreachable (); } +/* Expand reduction operations. */ +void +expand_reduction (rtx_code code, rtx *ops, rtx init) +{ + machine_mode vmode = GET_MODE (ops[1]); + machine_mode m1_mode = get_m1_mode (vmode).require (); + machine_mode m1_mmode = get_mask_mode (m1_mode).require (); + + rtx m1_tmp = gen_reg_rtx (m1_mode); + rtx m1_mask = gen_scalar_move_mask (m1_mmode); + rtx m1_undef = RVV_VUNDEF (m1_mode); + rtx scalar_move_ops[] = {m1_tmp, m1_mask, m1_undef, init}; + emit_scalar_move_insn (code_for_pred_broadcast (m1_mode), scalar_move_ops); + + rtx m1_tmp2 = gen_reg_rtx (m1_mode); + rtx reduc_ops[] = {m1_tmp2, ops[1], m1_tmp}; + + if (FLOAT_MODE_P (vmode) && code == PLUS) + { + insn_code icode + = code_for_pred_reduc_plus (UNSPEC_UNORDERED, vmode, m1_mode); + emit_vlmax_fp_reduction_insn (icode, RVV_REDUCTION_OP, reduc_ops); + } + else + { + insn_code icode = code_for_pred_reduc (code, vmode, m1_mode); + emit_vlmax_reduction_insn (icode, RVV_REDUCTION_OP, reduc_ops); + } + + emit_insn (gen_pred_extract_first (m1_mode, ops[0], m1_tmp2)); +} + } // namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 586dc8e..bb7ba12 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -646,7 +646,8 @@ gen_vsetvl_pat (enum vsetvl_type insn_type, const vl_vtype_info &info, rtx vl) } static rtx -gen_vsetvl_pat (rtx_insn *rinsn, const vector_insn_info &info) +gen_vsetvl_pat (rtx_insn *rinsn, const vector_insn_info &info, + rtx vl = NULL_RTX) { rtx new_pat; vl_vtype_info new_info = info; @@ -654,15 +655,17 @@ gen_vsetvl_pat (rtx_insn *rinsn, const vector_insn_info &info) && fault_first_load_p (info.get_insn ()->rtl ())) new_info.set_avl_info ( avl_info (get_avl (info.get_insn ()->rtl ()), nullptr)); - if (vsetvl_insn_p (rinsn) || vlmax_avl_p (info.get_avl ())) + if (vl) + new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, vl); + else { - rtx dest = get_vl (rinsn); - new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, dest); + if (vsetvl_insn_p (rinsn) || vlmax_avl_p (info.get_avl ())) + new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, get_vl (rinsn)); + else if (INSN_CODE (rinsn) == CODE_FOR_vsetvl_vtype_change_only) + new_pat = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, new_info, NULL_RTX); + else + new_pat = gen_vsetvl_pat (VSETVL_DISCARD_RESULT, new_info, NULL_RTX); } - else if (INSN_CODE (rinsn) == CODE_FOR_vsetvl_vtype_change_only) - new_pat = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, new_info, NULL_RTX); - else - new_pat = gen_vsetvl_pat (VSETVL_DISCARD_RESULT, new_info, NULL_RTX); return new_pat; } @@ -805,6 +808,14 @@ get_vl_vtype_info (const insn_info *insn) return info; } +/* Change insn and Assert the change always happens. */ +static void +validate_change_or_fail (rtx object, rtx *loc, rtx new_rtx, bool in_group) +{ + bool change_p = validate_change (object, loc, new_rtx, in_group); + gcc_assert (change_p); +} + static void change_insn (rtx_insn *rinsn, rtx new_pat) { @@ -818,7 +829,7 @@ change_insn (rtx_insn *rinsn, rtx new_pat) print_rtl_single (dump_file, PATTERN (rinsn)); } - validate_change (rinsn, &PATTERN (rinsn), new_pat, false); + validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false); if (dump_file) { @@ -874,7 +885,7 @@ change_insn (function_info *ssa, insn_change change, insn_info *insn, } insn_change_watermark watermark; - validate_change (rinsn, &PATTERN (rinsn), new_pat, true); + validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, true); /* These routines report failures themselves. */ if (!recog (attempt, change) || !change_is_worthwhile (change, false)) @@ -931,7 +942,8 @@ change_insn (function_info *ssa, insn_change change, insn_info *insn, } static void -change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info) +change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info, + rtx vl = NULL_RTX) { rtx_insn *rinsn; if (vector_config_insn_p (insn->rtl ())) @@ -945,7 +957,7 @@ change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info) rinsn = PREV_INSN (insn->rtl ()); gcc_assert (vector_config_insn_p (rinsn)); } - rtx new_pat = gen_vsetvl_pat (rinsn, info); + rtx new_pat = gen_vsetvl_pat (rinsn, info, vl); change_insn (rinsn, new_pat); } @@ -3377,7 +3389,20 @@ pass_vsetvl::backward_demand_fusion (void) new_info)) continue; - change_vsetvl_insn (new_info.get_insn (), new_info); + rtx vl = NULL_RTX; + /* Backward VLMAX VL: + bb 3: + vsetivli zero, 1 ... -> vsetvli t1, zero + vmv.s.x + bb 5: + vsetvli t1, zero ... -> to be elided. + vlse16.v + + We should forward "t1". */ + if (!block_info.reaching_out.has_avl_reg () + && vlmax_avl_p (new_info.get_avl ())) + vl = get_vl (prop.get_insn ()->rtl ()); + change_vsetvl_insn (new_info.get_insn (), new_info, vl); if (block_info.local_dem == block_info.reaching_out) block_info.local_dem = new_info; block_info.reaching_out = new_info; @@ -4524,13 +4549,15 @@ pass_vsetvl::df_post_optimization (void) const { rtx new_pat = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, info, NULL_RTX); - validate_change (rinsn, &PATTERN (rinsn), new_pat, false); + validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, + false); } else if (!vlmax_avl_p (info.get_avl ())) { rtx new_pat = gen_vsetvl_pat (VSETVL_DISCARD_RESULT, info, NULL_RTX); - validate_change (rinsn, &PATTERN (rinsn), new_pat, false); + validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, + false); } } } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-1.c new file mode 100644 index 0000000..0d543af --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-1.c @@ -0,0 +1,118 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#include + +#define DEF_REDUC_PLUS(TYPE) \ +TYPE __attribute__ ((noinline, noclone)) \ +reduc_plus_##TYPE (TYPE *a, int n) \ +{ \ + TYPE r = 0; \ + for (int i = 0; i < n; ++i) \ + r += a[i]; \ + return r; \ +} + +#define TEST_PLUS(T) \ + T (int8_t) \ + T (int16_t) \ + T (int32_t) \ + T (int64_t) \ + T (uint8_t) \ + T (uint16_t) \ + T (uint32_t) \ + T (uint64_t) \ + T (_Float16) \ + T (float) \ + T (double) + +TEST_PLUS (DEF_REDUC_PLUS) + +#define DEF_REDUC_MAXMIN(TYPE, NAME, CMP_OP) \ +TYPE __attribute__ ((noinline, noclone)) \ +reduc_##NAME##_##TYPE (TYPE *a, int n) \ +{ \ + TYPE r = 13; \ + for (int i = 0; i < n; ++i) \ + r = a[i] CMP_OP r ? a[i] : r; \ + return r; \ +} + +#define TEST_MAXMIN(T) \ + T (int8_t, max, >) \ + T (int16_t, max, >) \ + T (int32_t, max, >) \ + T (int64_t, max, >) \ + T (uint8_t, max, >) \ + T (uint16_t, max, >) \ + T (uint32_t, max, >) \ + T (uint64_t, max, >) \ + T (_Float16, max, >) \ + T (float, max, >) \ + T (double, max, >) \ + \ + T (int8_t, min, <) \ + T (int16_t, min, <) \ + T (int32_t, min, <) \ + T (int64_t, min, <) \ + T (uint8_t, min, <) \ + T (uint16_t, min, <) \ + T (uint32_t, min, <) \ + T (uint64_t, min, <) \ + T (_Float16, min, <) \ + T (float, min, <) \ + T (double, min, <) + +TEST_MAXMIN (DEF_REDUC_MAXMIN) + +#define DEF_REDUC_BITWISE(TYPE, NAME, BIT_OP) \ +TYPE __attribute__ ((noinline, noclone)) \ +reduc_##NAME##_##TYPE (TYPE *a, int n) \ +{ \ + TYPE r = 13; \ + for (int i = 0; i < n; ++i) \ + r BIT_OP a[i]; \ + return r; \ +} + +#define TEST_BITWISE(T) \ + T (int8_t, and, &=) \ + T (int16_t, and, &=) \ + T (int32_t, and, &=) \ + T (int64_t, and, &=) \ + T (uint8_t, and, &=) \ + T (uint16_t, and, &=) \ + T (uint32_t, and, &=) \ + T (uint64_t, and, &=) \ + \ + T (int8_t, ior, |=) \ + T (int16_t, ior, |=) \ + T (int32_t, ior, |=) \ + T (int64_t, ior, |=) \ + T (uint8_t, ior, |=) \ + T (uint16_t, ior, |=) \ + T (uint32_t, ior, |=) \ + T (uint64_t, ior, |=) \ + \ + T (int8_t, xor, ^=) \ + T (int16_t, xor, ^=) \ + T (int32_t, xor, ^=) \ + T (int64_t, xor, ^=) \ + T (uint8_t, xor, ^=) \ + T (uint16_t, xor, ^=) \ + T (uint32_t, xor, ^=) \ + T (uint64_t, xor, ^=) + +TEST_BITWISE (DEF_REDUC_BITWISE) + +/* { dg-final { scan-assembler-times {vredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredmaxu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredminu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredand\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vredor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vredxor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vfredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-2.c new file mode 100644 index 0000000..136a8a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-2.c @@ -0,0 +1,129 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#include + +#define NUM_ELEMS(TYPE) (1024 / sizeof (TYPE)) + +#define DEF_REDUC_PLUS(TYPE) \ +void __attribute__ ((noinline, noclone)) \ +reduc_plus_##TYPE (TYPE (*restrict a)[NUM_ELEMS (TYPE)], \ + TYPE *restrict r, int n) \ +{ \ + for (int i = 0; i < n; i++) \ + { \ + r[i] = 0; \ + for (int j = 0; j < NUM_ELEMS (TYPE); j++) \ + r[i] += a[i][j]; \ + } \ +} + +#define TEST_PLUS(T) \ + T (int8_t) \ + T (int16_t) \ + T (int32_t) \ + T (int64_t) \ + T (uint8_t) \ + T (uint16_t) \ + T (uint32_t) \ + T (uint64_t) \ + T (_Float16) \ + T (float) \ + T (double) + +TEST_PLUS (DEF_REDUC_PLUS) + +#define DEF_REDUC_MAXMIN(TYPE, NAME, CMP_OP) \ +void __attribute__ ((noinline, noclone)) \ +reduc_##NAME##_##TYPE (TYPE (*restrict a)[NUM_ELEMS (TYPE)], \ + TYPE *restrict r, int n) \ +{ \ + for (int i = 0; i < n; i++) \ + { \ + r[i] = a[i][0]; \ + for (int j = 0; j < NUM_ELEMS (TYPE); j++) \ + r[i] = a[i][j] CMP_OP r[i] ? a[i][j] : r[i]; \ + } \ +} + +#define TEST_MAXMIN(T) \ + T (int8_t, max, >) \ + T (int16_t, max, >) \ + T (int32_t, max, >) \ + T (int64_t, max, >) \ + T (uint8_t, max, >) \ + T (uint16_t, max, >) \ + T (uint32_t, max, >) \ + T (uint64_t, max, >) \ + T (_Float16, max, >) \ + T (float, max, >) \ + T (double, max, >) \ + \ + T (int8_t, min, <) \ + T (int16_t, min, <) \ + T (int32_t, min, <) \ + T (int64_t, min, <) \ + T (uint8_t, min, <) \ + T (uint16_t, min, <) \ + T (uint32_t, min, <) \ + T (uint64_t, min, <) \ + T (_Float16, min, <) \ + T (float, min, <) \ + T (double, min, <) + +TEST_MAXMIN (DEF_REDUC_MAXMIN) + +#define DEF_REDUC_BITWISE(TYPE,NAME,BIT_OP) \ +void __attribute__ ((noinline, noclone)) \ +reduc_##NAME##TYPE (TYPE (*restrict a)[NUM_ELEMS(TYPE)], \ + TYPE *restrict r, int n) \ +{ \ + for (int i = 0; i < n; i++) \ + { \ + r[i] = a[i][0]; \ + for (int j = 0; j < NUM_ELEMS(TYPE); j++) \ + r[i] BIT_OP a[i][j]; \ + } \ +} + +#define TEST_BITWISE(T) \ + T (int8_t, and, &=) \ + T (int16_t, and, &=) \ + T (int32_t, and, &=) \ + T (int64_t, and, &=) \ + T (uint8_t, and, &=) \ + T (uint16_t, and, &=) \ + T (uint32_t, and, &=) \ + T (uint64_t, and, &=) \ + \ + T (int8_t, ior, |=) \ + T (int16_t, ior, |=) \ + T (int32_t, ior, |=) \ + T (int64_t, ior, |=) \ + T (uint8_t, ior, |=) \ + T (uint16_t, ior, |=) \ + T (uint32_t, ior, |=) \ + T (uint64_t, ior, |=) \ + \ + T (int8_t, xor, ^=) \ + T (int16_t, xor, ^=) \ + T (int32_t, xor, ^=) \ + T (int64_t, xor, ^=) \ + T (uint8_t, xor, ^=) \ + T (uint16_t, xor, ^=) \ + T (uint32_t, xor, ^=) \ + T (uint64_t, xor, ^=) + +TEST_BITWISE (DEF_REDUC_BITWISE) + +/* { dg-final { scan-assembler-times {vredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredmaxu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredminu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {vredand\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vredor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vredxor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 8 } } */ +/* { dg-final { scan-assembler-times {vfredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-3.c new file mode 100644 index 0000000..c363834 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-3.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#include + +unsigned short __attribute__((noipa)) +add_loop (unsigned short *x, int n) +{ + unsigned short res = 0; + for (int i = 0; i < n; ++i) + res += x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +min_loop (unsigned short *x, int n) +{ + unsigned short res = ~0; + for (int i = 0; i < n; ++i) + res = res < x[i] ? res : x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +max_loop (unsigned short *x, int n) +{ + unsigned short res = 0; + for (int i = 0; i < n; ++i) + res = res > x[i] ? res : x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +and_loop (unsigned short *x, int n) +{ + unsigned short res = ~0; + for (int i = 0; i < n; ++i) + res &= x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +or_loop (unsigned short *x, int n) +{ + unsigned short res = 0; + for (int i = 0; i < n; ++i) + res |= x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +eor_loop (unsigned short *x, int n) +{ + unsigned short res = 0; + for (int i = 0; i < n; ++i) + res ^= x[i]; + return res; +} + +/* { dg-final { scan-assembler-times {vredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredmaxu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredminu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredand\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredxor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-4.c new file mode 100644 index 0000000..f00a128 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-4.c @@ -0,0 +1,59 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#include + +unsigned short __attribute__((noipa)) +add_loop (unsigned short *x, int n, unsigned short res) +{ + for (int i = 0; i < n; ++i) + res += x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +min_loop (unsigned short *x, int n, unsigned short res) +{ + for (int i = 0; i < n; ++i) + res = res < x[i] ? res : x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +max_loop (unsigned short *x, int n, unsigned short res) +{ + for (int i = 0; i < n; ++i) + res = res > x[i] ? res : x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +and_loop (unsigned short *x, int n, unsigned short res) +{ + for (int i = 0; i < n; ++i) + res &= x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +or_loop (unsigned short *x, int n, unsigned short res) +{ + for (int i = 0; i < n; ++i) + res |= x[i]; + return res; +} + +unsigned short __attribute__((noipa)) +eor_loop (unsigned short *x, int n, unsigned short res) +{ + for (int i = 0; i < n; ++i) + res ^= x[i]; + return res; +} + +/* { dg-final { scan-assembler-times {vredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredmaxu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredminu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredand\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vredxor\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-1.c new file mode 100644 index 0000000..b500f85 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-1.c @@ -0,0 +1,56 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#include "reduc-1.c" + +#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE)) + +#define INIT_VECTOR(TYPE) \ + TYPE a[NUM_ELEMS (TYPE) + 1]; \ + for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \ + { \ + a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \ + asm volatile ("" ::: "memory"); \ + } + +#define TEST_REDUC_PLUS(TYPE) \ + { \ + INIT_VECTOR (TYPE); \ + TYPE r1 = reduc_plus_##TYPE (a, NUM_ELEMS (TYPE)); \ + volatile TYPE r2 = 0; \ + for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \ + r2 += a[i]; \ + if (r1 != r2) \ + __builtin_abort (); \ + } + +#define TEST_REDUC_MAXMIN(TYPE, NAME, CMP_OP) \ + { \ + INIT_VECTOR (TYPE); \ + TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \ + volatile TYPE r2 = 13; \ + for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \ + r2 = a[i] CMP_OP r2 ? a[i] : r2; \ + if (r1 != r2) \ + __builtin_abort (); \ + } + +#define TEST_REDUC_BITWISE(TYPE, NAME, BIT_OP) \ + { \ + INIT_VECTOR (TYPE); \ + TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \ + volatile TYPE r2 = 13; \ + for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \ + r2 BIT_OP a[i]; \ + if (r1 != r2) \ + __builtin_abort (); \ + } + +int main () +{ + TEST_PLUS (TEST_REDUC_PLUS) + TEST_MAXMIN (TEST_REDUC_MAXMIN) + TEST_BITWISE (TEST_REDUC_BITWISE) + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-2.c new file mode 100644 index 0000000..3c2f625 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-2.c @@ -0,0 +1,79 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */ + +#include "reduc-2.c" + +#define NROWS 53 + +/* -ffast-math fuzz for PLUS. */ +#define CMP__Float16(X, Y) ((X) >= (Y) * 0.875 && (X) <= (Y) * 1.125) +#define CMP_float(X, Y) ((X) == (Y)) +#define CMP_double(X, Y) ((X) == (Y)) +#define CMP_int8_t(X, Y) ((X) == (Y)) +#define CMP_int16_t(X, Y) ((X) == (Y)) +#define CMP_int32_t(X, Y) ((X) == (Y)) +#define CMP_int64_t(X, Y) ((X) == (Y)) +#define CMP_uint8_t(X, Y) ((X) == (Y)) +#define CMP_uint16_t(X, Y) ((X) == (Y)) +#define CMP_uint32_t(X, Y) ((X) == (Y)) +#define CMP_uint64_t(X, Y) ((X) == (Y)) + +#define INIT_MATRIX(TYPE) \ + TYPE mat[NROWS][NUM_ELEMS (TYPE)]; \ + TYPE r[NROWS]; \ + for (int i = 0; i < NROWS; i++) \ + for (int j = 0; j < NUM_ELEMS (TYPE); j++) \ + { \ + mat[i][j] = i + (j * 2) * (j & 1 ? 1 : -1); \ + asm volatile ("" ::: "memory"); \ + } + +#define TEST_REDUC_PLUS(TYPE) \ + { \ + INIT_MATRIX (TYPE); \ + reduc_plus_##TYPE (mat, r, NROWS); \ + for (int i = 0; i < NROWS; i++) \ + { \ + volatile TYPE r2 = 0; \ + for (int j = 0; j < NUM_ELEMS (TYPE); ++j) \ + r2 += mat[i][j]; \ + if (!CMP_##TYPE (r[i], r2)) \ + __builtin_abort (); \ + } \ + } + +#define TEST_REDUC_MAXMIN(TYPE, NAME, CMP_OP) \ + { \ + INIT_MATRIX (TYPE); \ + reduc_##NAME##_##TYPE (mat, r, NROWS); \ + for (int i = 0; i < NROWS; i++) \ + { \ + volatile TYPE r2 = mat[i][0]; \ + for (int j = 0; j < NUM_ELEMS (TYPE); ++j) \ + r2 = mat[i][j] CMP_OP r2 ? mat[i][j] : r2; \ + if (r[i] != r2) \ + __builtin_abort (); \ + } \ + } + +#define TEST_REDUC_BITWISE(TYPE, NAME, BIT_OP) \ + { \ + INIT_MATRIX (TYPE); \ + reduc_##NAME##_##TYPE (mat, r, NROWS); \ + for (int i = 0; i < NROWS; i++) \ + { \ + volatile TYPE r2 = mat[i][0]; \ + for (int j = 0; j < NUM_ELEMS (TYPE); ++j) \ + r2 BIT_OP mat[i][j]; \ + if (r[i] != r2) \ + __builtin_abort (); \ + } \ + } + +int main () +{ + TEST_PLUS (TEST_REDUC_PLUS) + TEST_MAXMIN (TEST_REDUC_MAXMIN) + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-3.c new file mode 100644 index 0000000..d1b22c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-3.c @@ -0,0 +1,49 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#include "reduc-3.c" + +#define N 0x1100 + +int +main (void) +{ + unsigned short x[N]; + for (int i = 0; i < N; ++i) + x[i] = (i + 1) * (i + 2); + + if (add_loop (x, 0) != 0 + || add_loop (x, 11) != 572 + || add_loop (x, 0x100) != 22016 + || add_loop (x, 0xfff) != 20480 + || max_loop (x, 0) != 0 + || max_loop (x, 11) != 132 + || max_loop (x, 0x100) != 65280 + || max_loop (x, 0xfff) != 65504 + || or_loop (x, 0) != 0 + || or_loop (x, 11) != 0xfe + || or_loop (x, 0x80) != 0x7ffe + || or_loop (x, 0xb4) != 0x7ffe + || or_loop (x, 0xb5) != 0xfffe + || eor_loop (x, 0) != 0 + || eor_loop (x, 11) != 0xe8 + || eor_loop (x, 0x100) != 0xcf00 + || eor_loop (x, 0xfff) != 0xa000) + __builtin_abort (); + + for (int i = 0; i < N; ++i) + x[i] = ~x[i]; + + if (min_loop (x, 0) != 65535 + || min_loop (x, 11) != 65403 + || min_loop (x, 0x100) != 255 + || min_loop (x, 0xfff) != 31 + || and_loop (x, 0) != 0xffff + || and_loop (x, 11) != 0xff01 + || and_loop (x, 0x80) != 0x8001 + || and_loop (x, 0xb4) != 0x8001 + || and_loop (x, 0xb5) != 1) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-4.c new file mode 100644 index 0000000..c17e125 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-4.c @@ -0,0 +1,66 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#include "reduc-4.c" + +#define N 0x1100 + +int +main (void) +{ + unsigned short x[N]; + for (int i = 0; i < N; ++i) + x[i] = (i + 1) * (i + 2); + + if (add_loop (x, 0, 10) != 10 + || add_loop (x, 11, 42) != 614 + || add_loop (x, 0x100, 84) != 22100 + || add_loop (x, 0xfff, 20) != 20500 + || max_loop (x, 0, 10) != 10 + || max_loop (x, 11, 131) != 132 + || max_loop (x, 11, 133) != 133 + || max_loop (x, 0x100, 65279) != 65280 + || max_loop (x, 0x100, 65281) != 65281 + || max_loop (x, 0xfff, 65503) != 65504 + || max_loop (x, 0xfff, 65505) != 65505 + || or_loop (x, 0, 0x71) != 0x71 + || or_loop (x, 11, 0) != 0xfe + || or_loop (x, 11, 0xb3c) != 0xbfe + || or_loop (x, 0x80, 0) != 0x7ffe + || or_loop (x, 0x80, 1) != 0x7fff + || or_loop (x, 0xb4, 0) != 0x7ffe + || or_loop (x, 0xb4, 1) != 0x7fff + || or_loop (x, 0xb5, 0) != 0xfffe + || or_loop (x, 0xb5, 1) != 0xffff + || eor_loop (x, 0, 0x3e) != 0x3e + || eor_loop (x, 11, 0) != 0xe8 + || eor_loop (x, 11, 0x1ff) != 0x117 + || eor_loop (x, 0x100, 0) != 0xcf00 + || eor_loop (x, 0x100, 0xeee) != 0xc1ee + || eor_loop (x, 0xfff, 0) != 0xa000 + || eor_loop (x, 0xfff, 0x8888) != 0x2888) + __builtin_abort (); + + for (int i = 0; i < N; ++i) + x[i] = ~x[i]; + + if (min_loop (x, 0, 10000) != 10000 + || min_loop (x, 11, 65404) != 65403 + || min_loop (x, 11, 65402) != 65402 + || min_loop (x, 0x100, 256) != 255 + || min_loop (x, 0x100, 254) != 254 + || min_loop (x, 0xfff, 32) != 31 + || min_loop (x, 0xfff, 30) != 30 + || and_loop (x, 0, 0x1234) != 0x1234 + || and_loop (x, 11, 0xffff) != 0xff01 + || and_loop (x, 11, 0xcdef) != 0xcd01 + || and_loop (x, 0x80, 0xffff) != 0x8001 + || and_loop (x, 0x80, 0xfffe) != 0x8000 + || and_loop (x, 0xb4, 0xffff) != 0x8001 + || and_loop (x, 0xb4, 0xfffe) != 0x8000 + || and_loop (x, 0xb5, 0xffff) != 1 + || and_loop (x, 0xb5, 0xfffe) != 0) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp index 19589fa..532c17c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp +++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp @@ -71,6 +71,8 @@ foreach op $AUTOVEC_TEST_OPTS { "" "$op" dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/ternop/*.\[cS\]]] \ "" "$op" + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/reduc/*.\[cS\]]] \ + "" "$op" } # widening operation only test on LMUL < 8 -- cgit v1.1 From 70742d08832eb7db4d90f52465966111a19ce3a5 Mon Sep 17 00:00:00 2001 From: Lehua Ding Date: Mon, 17 Jul 2023 12:27:12 +0800 Subject: RISC-V: Ensure all implied extensions are included [PR110696] This patch fix target/PR110696, recursively add all implied extensions. PR target/110696 gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_subset_list::handle_implied_ext): recur add all implied extensions. (riscv_subset_list::check_implied_ext): Add new method. (riscv_subset_list::parse): Call checker check_implied_ext. * config/riscv/riscv-subset.h: Add new method. gcc/testsuite/ChangeLog: * gcc.target/riscv/attribute-20.c: New test. * gcc.target/riscv/pr110696.c: New test. Signed-off-by: Lehua Ding --- gcc/common/config/riscv/riscv-common.cc | 33 ++++++++++++++++++++++++--- gcc/config/riscv/riscv-subset.h | 3 ++- gcc/testsuite/gcc.target/riscv/attribute-20.c | 7 ++++++ gcc/testsuite/gcc.target/riscv/pr110696.c | 7 ++++++ 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-20.c create mode 100644 gcc/testsuite/gcc.target/riscv/pr110696.c (limited to 'gcc') diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 28c8f0c..19075c0 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -949,14 +949,14 @@ riscv_subset_list::parse_std_ext (const char *p) /* Check any implied extensions for EXT. */ void -riscv_subset_list::handle_implied_ext (riscv_subset_t *ext) +riscv_subset_list::handle_implied_ext (const char *ext) { const riscv_implied_info_t *implied_info; for (implied_info = &riscv_implied_info[0]; implied_info->ext; ++implied_info) { - if (strcmp (ext->name.c_str (), implied_info->ext) != 0) + if (strcmp (ext, implied_info->ext) != 0) continue; /* Skip if implied extension already present. */ @@ -966,6 +966,9 @@ riscv_subset_list::handle_implied_ext (riscv_subset_t *ext) /* Version of implied extension will get from current ISA spec version. */ add (implied_info->implied_ext, true); + + /* Recursively add implied extension by implied_info->implied_ext. */ + handle_implied_ext (implied_info->implied_ext); } /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifence is @@ -980,6 +983,27 @@ riscv_subset_list::handle_implied_ext (riscv_subset_t *ext) } } +/* Check that all implied extensions are included. */ +bool +riscv_subset_list::check_implied_ext () +{ + riscv_subset_t *itr; + for (itr = m_head; itr != NULL; itr = itr->next) + { + const riscv_implied_info_t *implied_info; + for (implied_info = &riscv_implied_info[0]; implied_info->ext; + ++implied_info) + { + if (strcmp (itr->name.c_str(), implied_info->ext) != 0) + continue; + + if (!lookup (implied_info->implied_ext)) + return false; + } + } + return true; +} + /* Check any combine extensions for EXT. */ void riscv_subset_list::handle_combine_ext () @@ -1194,9 +1218,12 @@ riscv_subset_list::parse (const char *arch, location_t loc) for (itr = subset_list->m_head; itr != NULL; itr = itr->next) { - subset_list->handle_implied_ext (itr); + subset_list->handle_implied_ext (itr->name.c_str ()); } + /* Make sure all implied extensions are included. */ + gcc_assert (subset_list->check_implied_ext ()); + subset_list->handle_combine_ext (); if (subset_list->lookup ("zfinx") && subset_list->lookup ("f")) diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h index 92e4fb3..84a7a82 100644 --- a/gcc/config/riscv/riscv-subset.h +++ b/gcc/config/riscv/riscv-subset.h @@ -67,7 +67,8 @@ private: const char *parse_multiletter_ext (const char *, const char *, const char *); - void handle_implied_ext (riscv_subset_t *); + void handle_implied_ext (const char *); + bool check_implied_ext (); void handle_combine_ext (); public: diff --git a/gcc/testsuite/gcc.target/riscv/attribute-20.c b/gcc/testsuite/gcc.target/riscv/attribute-20.c new file mode 100644 index 0000000..f7d0b29 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-20.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl65536b -mabi=lp64d" } */ +int foo() +{ +} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl1024b1p0_zvl128b1p0_zvl16384b1p0_zvl2048b1p0_zvl256b1p0_zvl32768b1p0_zvl32b1p0_zvl4096b1p0_zvl512b1p0_zvl64b1p0_zvl65536b1p0_zvl8192b1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr110696.c b/gcc/testsuite/gcc.target/riscv/pr110696.c new file mode 100644 index 0000000..a630f04 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr110696.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d" } */ +int foo() +{ +} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl1024b1p0_zvl128b1p0_zvl2048b1p0_zvl256b1p0_zvl32b1p0_zvl4096b1p0_zvl512b1p0_zvl64b1p0\"" } } */ -- cgit v1.1 From fb9ba7047740e29c15dc5c75bcec784b4a917abf Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Sun, 16 Jul 2023 20:48:29 +0200 Subject: Export value/mask known bits from CCP. Currently CCP throws away the known 1 bits because VRP and irange have traditionally only had a way of tracking known 0s (set_nonzero_bits). With the ability to keep all the known bits in the irange, we can now save this between passes. gcc/ChangeLog: * tree-ssa-ccp.cc (ccp_finalize): Export value/mask known bits. --- gcc/tree-ssa-ccp.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc index 0d0f02a..64d5fa8 100644 --- a/gcc/tree-ssa-ccp.cc +++ b/gcc/tree-ssa-ccp.cc @@ -1020,11 +1020,9 @@ ccp_finalize (bool nonzero_p) else { unsigned int precision = TYPE_PRECISION (TREE_TYPE (val->value)); - wide_int nonzero_bits - = (wide_int::from (val->mask, precision, UNSIGNED) - | wi::to_wide (val->value)); - nonzero_bits &= get_nonzero_bits (name); - set_nonzero_bits (name, nonzero_bits); + wide_int value = wi::to_wide (val->value); + wide_int mask = wide_int::from (val->mask, precision, UNSIGNED); + set_bitmask (name, value, mask); } } -- cgit v1.1 From dee3518b7fed0cba45018bac1e4f4549e6ec69a2 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:01 +0200 Subject: fortran: Remove commented out assertion r13-6747-gd7caf313525a46f200d7f5db1ba893f853774aee commented out an assertion without any test exercising it. This adds such a test where the assertion would fail, and removes the commented code. gcc/fortran/ChangeLog: * trans.cc (gfc_build_final_call): Remove commented assertion. gcc/testsuite/ChangeLog: * gfortran.dg/finalize_53.f90: New test. --- gcc/fortran/trans.cc | 1 - gcc/testsuite/gfortran.dg/finalize_53.f90 | 34 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/finalize_53.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index f1a3aac..387d66a 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1126,7 +1126,6 @@ gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, else { gfc_conv_expr (&se, var); -// gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE); array = se.expr; /* No copy back needed, hence set attr's allocatable/pointer diff --git a/gcc/testsuite/gfortran.dg/finalize_53.f90 b/gcc/testsuite/gfortran.dg/finalize_53.f90 new file mode 100644 index 0000000..eeacb9e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/finalize_53.f90 @@ -0,0 +1,34 @@ +! { dg-do compile } +! +! Check that the data reference preliminary code is properly +! generated and accepted by the finalization handling code. + +module m + implicit none + type t + integer :: i + contains + final :: finalize_t + end type t + logical :: finalize_called = .false. +contains + subroutine finalize_t(a) + type(t) :: a + finalize_called = .true. + end subroutine finalize_t +end module m +program p + use m + type u + type(t), allocatable :: ta + end type u + class(u), allocatable :: c(:) + integer, allocatable :: a(:), b(:) + a = [1, 2, 3] + b = [3, 5, 1] + allocate(c, source = [u(t(1)), u(t(9))]) + deallocate(c(count(a + b == 4))%ta) + if (.not. allocated (c(1)%ta)) stop 11 + if (allocated (c(2)%ta)) stop 12 + if (.not. finalize_called) stop 13 +end program p -- cgit v1.1 From 607c841ea427c21c9c502461e5673f1f9113c1d2 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:09 +0200 Subject: fortran: Outline final procedure pointer evaluation gcc/fortran/ChangeLog: * trans.cc (get_final_proc_ref): New function. (gfc_build_final_call): Outline the pointer evaluation code to get_final_proc_ref. --- gcc/fortran/trans.cc | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 387d66a..3235476 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1085,6 +1085,21 @@ gfc_call_free (tree var) } +/* Generate the data reference to the finalization procedure pointer passed as + argument in FINAL_WRAPPER. */ + +static void +get_final_proc_ref (gfc_se *se, gfc_expr *final_wrapper) +{ + gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE); + + gfc_conv_expr (se, final_wrapper); + + if (POINTER_TYPE_P (TREE_TYPE (se->expr))) + se->expr = build_fold_indirect_ref_loc (input_location, se->expr); +} + + /* Build a call to a FINAL procedure, which finalizes "var". */ static tree @@ -1092,19 +1107,19 @@ gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, bool fini_coarray, gfc_expr *class_size) { stmtblock_t block; + gfc_se final_se; gfc_se se; tree final_fndecl, array, size, tmp; symbol_attribute attr; - gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE); gcc_assert (var); gfc_start_block (&block); - gfc_init_se (&se, NULL); - gfc_conv_expr (&se, final_wrapper); - final_fndecl = se.expr; - if (POINTER_TYPE_P (TREE_TYPE (final_fndecl))) - final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl); + + gfc_init_se (&final_se, NULL); + get_final_proc_ref (&final_se, final_wrapper); + gfc_add_block_to_block (&block, &final_se.pre); + final_fndecl = final_se.expr; if (ts.type == BT_DERIVED) { -- cgit v1.1 From 6ad6a6d3e5c10961507c09a4312c3edd1d39d580 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:19 +0200 Subject: fortran: Outline element size evaluation gcc/fortran/ChangeLog: * trans.cc (get_elem_size): New function. (gfc_build_final_call): Outline the element size evaluation to get_elem_size. --- gcc/fortran/trans.cc | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 3235476..5136fd6 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1100,6 +1100,30 @@ get_final_proc_ref (gfc_se *se, gfc_expr *final_wrapper) } +/* Generate the code to obtain the value of the element size whose expression + is passed as argument in CLASS_SIZE. */ + +static void +get_elem_size (gfc_se *se, gfc_typespec *ts, gfc_expr *class_size) +{ + gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS); + + if (ts->type == BT_DERIVED) + { + gcc_assert (!class_size); + se->expr = gfc_typenode_for_spec (ts); + se->expr = TYPE_SIZE_UNIT (se->expr); + se->expr = fold_convert (gfc_array_index_type, se->expr); + } + else + { + gcc_assert (class_size); + gfc_conv_expr (se, class_size); + gcc_assert (se->post.head == NULL_TREE); + } +} + + /* Build a call to a FINAL procedure, which finalizes "var". */ static tree @@ -1107,7 +1131,7 @@ gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, bool fini_coarray, gfc_expr *class_size) { stmtblock_t block; - gfc_se final_se; + gfc_se final_se, size_se; gfc_se se; tree final_fndecl, array, size, tmp; symbol_attribute attr; @@ -1121,15 +1145,13 @@ gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, gfc_add_block_to_block (&block, &final_se.pre); final_fndecl = final_se.expr; + gfc_init_se (&size_se, NULL); + get_elem_size (&size_se, &ts, class_size); + gfc_add_block_to_block (&block, &size_se.pre); + size = size_se.expr; + if (ts.type == BT_DERIVED) { - tree elem_size; - - gcc_assert (!class_size); - elem_size = gfc_typenode_for_spec (&ts); - elem_size = TYPE_SIZE_UNIT (elem_size); - size = fold_convert (gfc_array_index_type, elem_size); - gfc_init_se (&se, NULL); se.want_pointer = 1; if (var->rank) @@ -1154,12 +1176,6 @@ gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, else { gfc_expr *array_expr; - gcc_assert (class_size); - gfc_init_se (&se, NULL); - gfc_conv_expr (&se, class_size); - gfc_add_block_to_block (&block, &se.pre); - gcc_assert (se.post.head == NULL_TREE); - size = se.expr; array_expr = gfc_copy_expr (var); gfc_init_se (&se, NULL); -- cgit v1.1 From 133d9bc5426fcf94d20157f1643b80dec64985d9 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:26 +0200 Subject: fortran: Outline data reference descriptor evaluation gcc/fortran/ChangeLog: * trans.cc (get_var_descr): New function. (gfc_build_final_call): Outline the data reference descriptor evaluation code to get_var_descr. --- gcc/fortran/trans.cc | 109 +++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 46 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 5136fd6..f06c691 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1124,53 +1124,38 @@ get_elem_size (gfc_se *se, gfc_typespec *ts, gfc_expr *class_size) } -/* Build a call to a FINAL procedure, which finalizes "var". */ +/* Generate the data reference (array) descriptor corresponding to the + expression passed as argument in VAR. Use type in TS to pilot code + generation. */ -static tree -gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, - bool fini_coarray, gfc_expr *class_size) +static void +get_var_descr (gfc_se *se, gfc_typespec *ts, gfc_expr *var) { - stmtblock_t block; - gfc_se final_se, size_se; - gfc_se se; - tree final_fndecl, array, size, tmp; + gfc_se tmp_se; symbol_attribute attr; gcc_assert (var); - gfc_start_block (&block); - - gfc_init_se (&final_se, NULL); - get_final_proc_ref (&final_se, final_wrapper); - gfc_add_block_to_block (&block, &final_se.pre); - final_fndecl = final_se.expr; - - gfc_init_se (&size_se, NULL); - get_elem_size (&size_se, &ts, class_size); - gfc_add_block_to_block (&block, &size_se.pre); - size = size_se.expr; + gfc_init_se (&tmp_se, NULL); - if (ts.type == BT_DERIVED) + if (ts->type == BT_DERIVED) { - gfc_init_se (&se, NULL); - se.want_pointer = 1; + tmp_se.want_pointer = 1; if (var->rank) { - se.descriptor_only = 1; - gfc_conv_expr_descriptor (&se, var); - array = se.expr; + tmp_se.descriptor_only = 1; + gfc_conv_expr_descriptor (&tmp_se, var); } else { - gfc_conv_expr (&se, var); - array = se.expr; + gfc_conv_expr (&tmp_se, var); /* No copy back needed, hence set attr's allocatable/pointer to zero. */ gfc_clear_attr (&attr); - gfc_init_se (&se, NULL); - array = gfc_conv_scalar_to_descriptor (&se, array, attr); - gcc_assert (se.post.head == NULL_TREE); + tmp_se.expr = gfc_conv_scalar_to_descriptor (&tmp_se, tmp_se.expr, + attr); + gcc_assert (tmp_se.post.head == NULL_TREE); } } else @@ -1178,45 +1163,77 @@ gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, gfc_expr *array_expr; array_expr = gfc_copy_expr (var); - gfc_init_se (&se, NULL); - se.want_pointer = 1; + + tmp_se.want_pointer = 1; if (array_expr->rank) { gfc_add_class_array_ref (array_expr); - se.descriptor_only = 1; - gfc_conv_expr_descriptor (&se, array_expr); - array = se.expr; + tmp_se.descriptor_only = 1; + gfc_conv_expr_descriptor (&tmp_se, array_expr); } else { gfc_add_data_component (array_expr); - gfc_conv_expr (&se, array_expr); - gfc_add_block_to_block (&block, &se.pre); - gcc_assert (se.post.head == NULL_TREE); - array = se.expr; + gfc_conv_expr (&tmp_se, array_expr); + gcc_assert (tmp_se.post.head == NULL_TREE); if (!gfc_is_coarray (array_expr)) { /* No copy back needed, hence set attr's allocatable/pointer to zero. */ gfc_clear_attr (&attr); - gfc_init_se (&se, NULL); - array = gfc_conv_scalar_to_descriptor (&se, array, attr); + tmp_se.expr = gfc_conv_scalar_to_descriptor (&tmp_se, tmp_se.expr, + attr); } - gcc_assert (se.post.head == NULL_TREE); + gcc_assert (tmp_se.post.head == NULL_TREE); } gfc_free_expr (array_expr); } - if (!POINTER_TYPE_P (TREE_TYPE (array))) - array = gfc_build_addr_expr (NULL, array); + if (!POINTER_TYPE_P (TREE_TYPE (tmp_se.expr))) + tmp_se.expr = gfc_build_addr_expr (NULL, tmp_se.expr); + + gfc_add_block_to_block (&se->pre, &tmp_se.pre); + gfc_add_block_to_block (&se->post, &tmp_se.post); + se->expr = tmp_se.expr; +} + + + +/* Build a call to a FINAL procedure, which finalizes "var". */ + +static tree +gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, + bool fini_coarray, gfc_expr *class_size) +{ + stmtblock_t block; + gfc_se final_se, size_se, desc_se; + tree final_fndecl, array, size, tmp; + + gcc_assert (var); + + gfc_start_block (&block); + + gfc_init_se (&final_se, NULL); + get_final_proc_ref (&final_se, final_wrapper); + gfc_add_block_to_block (&block, &final_se.pre); + final_fndecl = final_se.expr; + + gfc_init_se (&size_se, NULL); + get_elem_size (&size_se, &ts, class_size); + gfc_add_block_to_block (&block, &size_se.pre); + size = size_se.expr; + + gfc_init_se (&desc_se, NULL); + get_var_descr (&desc_se, &ts, var); + gfc_add_block_to_block (&block, &desc_se.pre); + array = desc_se.expr; - gfc_add_block_to_block (&block, &se.pre); tmp = build_call_expr_loc (input_location, final_fndecl, 3, array, size, fini_coarray ? boolean_true_node : boolean_false_node); - gfc_add_block_to_block (&block, &se.post); + gfc_add_block_to_block (&block, &desc_se.post); gfc_add_expr_to_block (&block, tmp); return gfc_finish_block (&block); } -- cgit v1.1 From 8c4d0fe3c28e8cb48cd8ff629fbd4068048562c7 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:32 +0200 Subject: fortran: Inline gfc_build_final_call Function gfc_build_final_call has been simplified, inline it. gcc/fortran/ChangeLog: * trans.cc (gfc_build_final_call): Inline... (gfc_add_finalizer_call): ... to its one caller. --- gcc/fortran/trans.cc | 66 ++++++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 41 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index f06c691..2af433d 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1200,45 +1200,6 @@ get_var_descr (gfc_se *se, gfc_typespec *ts, gfc_expr *var) -/* Build a call to a FINAL procedure, which finalizes "var". */ - -static tree -gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, - bool fini_coarray, gfc_expr *class_size) -{ - stmtblock_t block; - gfc_se final_se, size_se, desc_se; - tree final_fndecl, array, size, tmp; - - gcc_assert (var); - - gfc_start_block (&block); - - gfc_init_se (&final_se, NULL); - get_final_proc_ref (&final_se, final_wrapper); - gfc_add_block_to_block (&block, &final_se.pre); - final_fndecl = final_se.expr; - - gfc_init_se (&size_se, NULL); - get_elem_size (&size_se, &ts, class_size); - gfc_add_block_to_block (&block, &size_se.pre); - size = size_se.expr; - - gfc_init_se (&desc_se, NULL); - get_var_descr (&desc_se, &ts, var); - gfc_add_block_to_block (&block, &desc_se.pre); - array = desc_se.expr; - - tmp = build_call_expr_loc (input_location, - final_fndecl, 3, array, - size, fini_coarray ? boolean_true_node - : boolean_false_node); - gfc_add_block_to_block (&block, &desc_se.post); - gfc_add_expr_to_block (&block, tmp); - return gfc_finish_block (&block); -} - - bool gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp, bool fini_coarray) @@ -1407,8 +1368,31 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gcc_assert (final_expr->expr_type == EXPR_VARIABLE); - tmp = gfc_build_final_call (expr->ts, final_expr, expr, - false, elem_size); + stmtblock_t tmp_block; + gfc_start_block (&tmp_block); + + gfc_se final_se; + gfc_init_se (&final_se, NULL); + get_final_proc_ref (&final_se, final_expr); + gfc_add_block_to_block (&tmp_block, &final_se.pre); + + gfc_se size_se; + gfc_init_se (&size_se, NULL); + get_elem_size (&size_se, &expr->ts, elem_size); + gfc_add_block_to_block (&tmp_block, &size_se.pre); + + gfc_se desc_se; + gfc_init_se (&desc_se, NULL); + get_var_descr (&desc_se, &expr->ts, expr); + gfc_add_block_to_block (&tmp_block, &desc_se.pre); + + tmp = build_call_expr_loc (input_location, final_se.expr, 3, + desc_se.expr, size_se.expr, + boolean_false_node); + + gfc_add_block_to_block (&tmp_block, &desc_se.post); + gfc_add_expr_to_block (&tmp_block, tmp); + tmp = gfc_finish_block (&tmp_block); if (expr->ts.type == BT_CLASS && !has_finalizer) { -- cgit v1.1 From a4519a884d0215740581c051641364f5368c0450 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:37 +0200 Subject: fortran: Add missing cleanup blocks Move cleanup code for the data descriptor after the finalization code as it makes more sense to have it after. Other cleanup blocks should be empty (element size and final pointer are just data references), but add them by the way, just in case. gcc/fortran/ChangeLog: * trans.cc (gfc_add_finalizer_call): Add post code for desc_se after the finalizer call. Add post code for final_se and size_se as well. --- gcc/fortran/trans.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 2af433d..7fcaf8e 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1390,8 +1390,12 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) desc_se.expr, size_se.expr, boolean_false_node); - gfc_add_block_to_block (&tmp_block, &desc_se.post); gfc_add_expr_to_block (&tmp_block, tmp); + + gfc_add_block_to_block (&tmp_block, &desc_se.post); + gfc_add_block_to_block (&tmp_block, &size_se.post); + gfc_add_block_to_block (&tmp_block, &final_se.post); + tmp = gfc_finish_block (&tmp_block); if (expr->ts.type == BT_CLASS && !has_finalizer) -- cgit v1.1 From 243a6b61418f47a9d04b6c3fe376e266e6cb00c0 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:44 +0200 Subject: fortran: Reuse final procedure pointer expression Reuse twice the same final procedure pointer expression instead of translating it twice. Final procedure pointer expressions were translated twice, once for the final procedure call, and once for the check for non-nullness (if applicable). gcc/fortran/ChangeLog: * trans.cc (gfc_add_finalizer_call): Move pre and post code for the final procedure pointer expression to the outer block. Reuse the previously evaluated final procedure pointer expression. --- gcc/fortran/trans.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 7fcaf8e..ba1c6dd 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1374,7 +1374,7 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_se final_se; gfc_init_se (&final_se, NULL); get_final_proc_ref (&final_se, final_expr); - gfc_add_block_to_block (&tmp_block, &final_se.pre); + gfc_add_block_to_block (block, &final_se.pre); gfc_se size_se; gfc_init_se (&size_se, NULL); @@ -1394,7 +1394,6 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_add_block_to_block (&tmp_block, &desc_se.post); gfc_add_block_to_block (&tmp_block, &size_se.post); - gfc_add_block_to_block (&tmp_block, &final_se.post); tmp = gfc_finish_block (&tmp_block); @@ -1403,11 +1402,10 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) tree cond; gfc_se se; - gfc_init_se (&se, NULL); - se.want_pointer = 1; - gfc_conv_expr (&se, final_expr); + tree ptr = gfc_build_addr_expr (NULL_TREE, final_se.expr); + cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, - se.expr, build_int_cst (TREE_TYPE (se.expr), 0)); + ptr, build_int_cst (TREE_TYPE (ptr), 0)); /* For CLASS(*) not only sym->_vtab->_final can be NULL but already sym->_vtab itself. */ @@ -1436,6 +1434,7 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) } gfc_add_expr_to_block (block, tmp); + gfc_add_block_to_block (block, &final_se.post); return true; } -- cgit v1.1 From 8ac448ebffab64ba90a6da2949e18a915046b232 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:48 +0200 Subject: fortran: Push element size expression generation close to its usage gfc_add_finalizer_call creates one expression which is only used by the get_final_proc_ref function. Move the expression generation there. gcc/fortran/ChangeLog: * trans.cc (gfc_add_finalizer_call): Remove local variable elem_size. Pass expression to get_elem_size and move the element size expression generation close to its usage there. (get_elem_size): Add argument expr, remove class_size argument and rebuild it from expr. Remove ts argument and use the type of expr instead. --- gcc/fortran/trans.cc | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index ba1c6dd..2af9a57 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1100,24 +1100,26 @@ get_final_proc_ref (gfc_se *se, gfc_expr *final_wrapper) } -/* Generate the code to obtain the value of the element size whose expression - is passed as argument in CLASS_SIZE. */ +/* Generate the code to obtain the value of the element size of the expression + passed as argument in EXPR. */ static void -get_elem_size (gfc_se *se, gfc_typespec *ts, gfc_expr *class_size) +get_elem_size (gfc_se *se, gfc_expr *expr) { - gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS); + gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS); - if (ts->type == BT_DERIVED) + if (expr->ts.type == BT_DERIVED) { - gcc_assert (!class_size); - se->expr = gfc_typenode_for_spec (ts); + se->expr = gfc_typenode_for_spec (&expr->ts); se->expr = TYPE_SIZE_UNIT (se->expr); se->expr = fold_convert (gfc_array_index_type, se->expr); } else { - gcc_assert (class_size); + gfc_expr *class_size = gfc_copy_expr (expr); + gfc_add_vptr_component (class_size); + gfc_add_size_component (class_size); + gfc_conv_expr (se, class_size); gcc_assert (se->post.head == NULL_TREE); } @@ -1306,7 +1308,6 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_ref *ref; gfc_expr *expr; gfc_expr *final_expr = NULL; - gfc_expr *elem_size = NULL; bool has_finalizer = false; if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS)) @@ -1360,10 +1361,6 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) final_expr = gfc_copy_expr (expr); gfc_add_vptr_component (final_expr); gfc_add_final_component (final_expr); - - elem_size = gfc_copy_expr (expr); - gfc_add_vptr_component (elem_size); - gfc_add_size_component (elem_size); } gcc_assert (final_expr->expr_type == EXPR_VARIABLE); @@ -1378,7 +1375,7 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_se size_se; gfc_init_se (&size_se, NULL); - get_elem_size (&size_se, &expr->ts, elem_size); + get_elem_size (&size_se, expr); gfc_add_block_to_block (&tmp_block, &size_se.pre); gfc_se desc_se; -- cgit v1.1 From ba5e2df515204ddbc52422f17351f93abd159682 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:53 +0200 Subject: fortran: Push final procedure expr gen close to its one usage. Final procedure pointer expression is generated in gfc_build_final_call and only used in get_final_proc_ref. Move the generation there. gcc/fortran/ChangeLog: * trans.cc (gfc_add_finalizer_call): Remove local variable final_expr. Pass down expr to get_final_proc_ref and move final procedure expression generation down to its one usage in get_final_proc_ref. (get_final_proc_ref): Add argument expr. Remove argument final_wrapper. Recreate final_wrapper from expr. --- gcc/fortran/trans.cc | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 2af9a57..0753ccd 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1085,12 +1085,25 @@ gfc_call_free (tree var) } -/* Generate the data reference to the finalization procedure pointer passed as - argument in FINAL_WRAPPER. */ +/* Generate the data reference to the finalization procedure pointer associated + with the expression passed as argument in EXPR. */ static void -get_final_proc_ref (gfc_se *se, gfc_expr *final_wrapper) +get_final_proc_ref (gfc_se *se, gfc_expr *expr) { + gfc_expr *final_wrapper = NULL; + + gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS); + + if (expr->ts.type == BT_DERIVED) + gfc_is_finalizable (expr->ts.u.derived, &final_wrapper); + else + { + final_wrapper = gfc_copy_expr (expr); + gfc_add_vptr_component (final_wrapper); + gfc_add_final_component (final_wrapper); + } + gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE); gfc_conv_expr (se, final_wrapper); @@ -1307,7 +1320,6 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) tree tmp; gfc_ref *ref; gfc_expr *expr; - gfc_expr *final_expr = NULL; bool has_finalizer = false; if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS)) @@ -1321,12 +1333,9 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) && expr2->ts.u.derived->attr.defined_assign_comp) return false; - if (expr2->ts.type == BT_DERIVED) - { - gfc_is_finalizable (expr2->ts.u.derived, &final_expr); - if (!final_expr) - return false; - } + if (expr2->ts.type == BT_DERIVED + && !gfc_is_finalizable (expr2->ts.u.derived, NULL)) + return false; /* If we have a class array, we need go back to the class container. */ @@ -1357,20 +1366,14 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as) expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank; - - final_expr = gfc_copy_expr (expr); - gfc_add_vptr_component (final_expr); - gfc_add_final_component (final_expr); } - gcc_assert (final_expr->expr_type == EXPR_VARIABLE); - stmtblock_t tmp_block; gfc_start_block (&tmp_block); gfc_se final_se; gfc_init_se (&final_se, NULL); - get_final_proc_ref (&final_se, final_expr); + get_final_proc_ref (&final_se, expr); gfc_add_block_to_block (block, &final_se.pre); gfc_se size_se; -- cgit v1.1 From 268fda4b427cc8f24a15ce63031709aadbf3eeb8 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:13:58 +0200 Subject: fortran: Inline variable definition The variable has_finalizer is only used in one place, inline its definition there. gcc/fortran/ChangeLog: * trans.cc (gfc_add_finalizer_call): Inline definition of variable has_finalizer. Merge nested conditions. --- gcc/fortran/trans.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 0753ccd..68e1ca9 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1320,7 +1320,6 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) tree tmp; gfc_ref *ref; gfc_expr *expr; - bool has_finalizer = false; if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS)) return false; @@ -1360,13 +1359,11 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) ref->next = NULL; } - if (expr->ts.type == BT_CLASS) - { - has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL); - - if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as) - expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank; - } + if (expr->ts.type == BT_CLASS + && !expr2->rank + && !expr2->ref + && CLASS_DATA (expr2->symtree->n.sym)->as) + expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank; stmtblock_t tmp_block; gfc_start_block (&tmp_block); @@ -1397,7 +1394,8 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) tmp = gfc_finish_block (&tmp_block); - if (expr->ts.type == BT_CLASS && !has_finalizer) + if (expr->ts.type == BT_CLASS + && !gfc_is_finalizable (expr->ts.u.derived, NULL)) { tree cond; gfc_se se; -- cgit v1.1 From 7b02a617948995a8e3ecd001ad3b44d1a1fc075a Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:14:03 +0200 Subject: fortran: Remove redundant argument in get_var_descr get_var_descr get passed as argument both expr and expr->ts. Remove the type argument which can be retrieved from the other argument. gcc/fortran/ChangeLog: * trans.cc (get_var_descr): Remove argument ts. Use var->ts instead. (gfc_add_finalizer_call): Update caller. --- gcc/fortran/trans.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 68e1ca9..a2a3be4 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1140,11 +1140,10 @@ get_elem_size (gfc_se *se, gfc_expr *expr) /* Generate the data reference (array) descriptor corresponding to the - expression passed as argument in VAR. Use type in TS to pilot code - generation. */ + expression passed as argument in VAR. */ static void -get_var_descr (gfc_se *se, gfc_typespec *ts, gfc_expr *var) +get_var_descr (gfc_se *se, gfc_expr *var) { gfc_se tmp_se; symbol_attribute attr; @@ -1153,7 +1152,7 @@ get_var_descr (gfc_se *se, gfc_typespec *ts, gfc_expr *var) gfc_init_se (&tmp_se, NULL); - if (ts->type == BT_DERIVED) + if (var->ts.type == BT_DERIVED) { tmp_se.want_pointer = 1; if (var->rank) @@ -1380,7 +1379,7 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_se desc_se; gfc_init_se (&desc_se, NULL); - get_var_descr (&desc_se, &expr->ts, expr); + get_var_descr (&desc_se, expr); gfc_add_block_to_block (&tmp_block, &desc_se.pre); tmp = build_call_expr_loc (input_location, final_se.expr, 3, -- cgit v1.1 From 3693adaf0809fa5c91ee5534abb9c6bc59b2406d Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:14:08 +0200 Subject: fortran: Outline virtual table pointer evaluation gcc/fortran/ChangeLog: * trans.cc (get_vptr): New function. (gfc_add_finalizer_call): Move virtual table pointer evaluation to get_vptr. --- gcc/fortran/trans.cc | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index a2a3be4..f8df330 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1213,6 +1213,23 @@ get_var_descr (gfc_se *se, gfc_expr *var) } +static void +get_vptr (gfc_se *se, gfc_expr *expr) +{ + gfc_expr *vptr_expr = gfc_copy_expr (expr); + gfc_add_vptr_component (vptr_expr); + + gfc_se tmp_se; + gfc_init_se (&tmp_se, NULL); + tmp_se.want_pointer = 1; + gfc_conv_expr (&tmp_se, vptr_expr); + gfc_free_expr (vptr_expr); + + gfc_add_block_to_block (&se->pre, &tmp_se.pre); + gfc_add_block_to_block (&se->post, &tmp_se.post); + se->expr = tmp_se.expr; +} + bool gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp, @@ -1397,7 +1414,6 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) && !gfc_is_finalizable (expr->ts.u.derived, NULL)) { tree cond; - gfc_se se; tree ptr = gfc_build_addr_expr (NULL_TREE, final_se.expr); @@ -1409,19 +1425,14 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) if (UNLIMITED_POLY (expr)) { tree cond2; - gfc_expr *vptr_expr; - - vptr_expr = gfc_copy_expr (expr); - gfc_add_vptr_component (vptr_expr); + gfc_se vptr_se; - gfc_init_se (&se, NULL); - se.want_pointer = 1; - gfc_conv_expr (&se, vptr_expr); - gfc_free_expr (vptr_expr); + gfc_init_se (&vptr_se, NULL); + get_vptr (&vptr_se, expr); cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, - se.expr, - build_int_cst (TREE_TYPE (se.expr), 0)); + vptr_se.expr, + build_int_cst (TREE_TYPE (vptr_se.expr), 0)); cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR, logical_type_node, cond2, cond); } -- cgit v1.1 From f60231e35d8d3f84f2ab6b3c19c254faa9519cf4 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:14:14 +0200 Subject: fortran: Factor scalar descriptor generation The same scalar descriptor generation code is present twice, in the case of derived type entities, and in the case of polymorphic non-coarray entities. Factor it in preparation for a future third case that will also need the same code for scalar descriptor generation. gcc/fortran/ChangeLog: * trans.cc (get_var_descr): Factor scalar descriptor generation. --- gcc/fortran/trans.cc | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index f8df330..75d77be 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1146,7 +1146,6 @@ static void get_var_descr (gfc_se *se, gfc_expr *var) { gfc_se tmp_se; - symbol_attribute attr; gcc_assert (var); @@ -1161,16 +1160,7 @@ get_var_descr (gfc_se *se, gfc_expr *var) gfc_conv_expr_descriptor (&tmp_se, var); } else - { - gfc_conv_expr (&tmp_se, var); - - /* No copy back needed, hence set attr's allocatable/pointer - to zero. */ - gfc_clear_attr (&attr); - tmp_se.expr = gfc_conv_scalar_to_descriptor (&tmp_se, tmp_se.expr, - attr); - gcc_assert (tmp_se.post.head == NULL_TREE); - } + gfc_conv_expr (&tmp_se, var); } else { @@ -1190,20 +1180,25 @@ get_var_descr (gfc_se *se, gfc_expr *var) gfc_add_data_component (array_expr); gfc_conv_expr (&tmp_se, array_expr); gcc_assert (tmp_se.post.head == NULL_TREE); - - if (!gfc_is_coarray (array_expr)) - { - /* No copy back needed, hence set attr's allocatable/pointer - to zero. */ - gfc_clear_attr (&attr); - tmp_se.expr = gfc_conv_scalar_to_descriptor (&tmp_se, tmp_se.expr, - attr); - } - gcc_assert (tmp_se.post.head == NULL_TREE); } gfc_free_expr (array_expr); } + if (var->rank == 0) + { + if (var->ts.type == BT_DERIVED + || !gfc_is_coarray (var)) + { + /* No copy back needed, hence set attr's allocatable/pointer + to zero. */ + symbol_attribute attr; + gfc_clear_attr (&attr); + tmp_se.expr = gfc_conv_scalar_to_descriptor (&tmp_se, tmp_se.expr, + attr); + } + gcc_assert (tmp_se.post.head == NULL_TREE); + } + if (!POINTER_TYPE_P (TREE_TYPE (tmp_se.expr))) tmp_se.expr = gfc_build_addr_expr (NULL, tmp_se.expr); -- cgit v1.1 From 1a46400e5ac0f21eead74b10752f69ebc7a8be27 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:14:18 +0200 Subject: fortran: Use pre-evaluated class container if available [PR110618] Add the possibility to provide a pre-evaluated class container argument to gfc_add_finalizer to avoid repeatedly evaluating data reference expressions in the generated code. PR fortran/110618 gcc/fortran/ChangeLog: * trans.h (gfc_add_finalizer_call): Add class container argument. * trans.cc (gfc_add_finalizer_call): Ditto. Pass down new argument to get_final_proc_ref, get_elem_size, get_var_desc, and get_vptr. (get_elem_size): Add class container argument. Use provided class container if it's available. (get_var_descr): Same. (get_vptr): Same. (get_final_proc_ref): Same. Add boolean telling the class container argument is used. Set it. Don't try to use final_wrapper if class container argument was used. --- gcc/fortran/trans.cc | 61 ++++++++++++++++++++++++++++++++++------------------ gcc/fortran/trans.h | 2 +- 2 files changed, 41 insertions(+), 22 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 75d77be..3e9a14a 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1089,14 +1089,20 @@ gfc_call_free (tree var) with the expression passed as argument in EXPR. */ static void -get_final_proc_ref (gfc_se *se, gfc_expr *expr) +get_final_proc_ref (gfc_se *se, gfc_expr *expr, tree class_container) { gfc_expr *final_wrapper = NULL; gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS); + bool using_class_container = false; if (expr->ts.type == BT_DERIVED) gfc_is_finalizable (expr->ts.u.derived, &final_wrapper); + else if (class_container) + { + using_class_container = true; + se->expr = gfc_class_vtab_final_get (class_container); + } else { final_wrapper = gfc_copy_expr (expr); @@ -1104,9 +1110,12 @@ get_final_proc_ref (gfc_se *se, gfc_expr *expr) gfc_add_final_component (final_wrapper); } - gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE); + if (!using_class_container) + { + gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE); - gfc_conv_expr (se, final_wrapper); + gfc_conv_expr (se, final_wrapper); + } if (POINTER_TYPE_P (TREE_TYPE (se->expr))) se->expr = build_fold_indirect_ref_loc (input_location, se->expr); @@ -1117,7 +1126,7 @@ get_final_proc_ref (gfc_se *se, gfc_expr *expr) passed as argument in EXPR. */ static void -get_elem_size (gfc_se *se, gfc_expr *expr) +get_elem_size (gfc_se *se, gfc_expr *expr, tree class_container) { gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS); @@ -1127,6 +1136,8 @@ get_elem_size (gfc_se *se, gfc_expr *expr) se->expr = TYPE_SIZE_UNIT (se->expr); se->expr = fold_convert (gfc_array_index_type, se->expr); } + else if (class_container) + se->expr = gfc_class_vtab_size_get (class_container); else { gfc_expr *class_size = gfc_copy_expr (expr); @@ -1143,7 +1154,7 @@ get_elem_size (gfc_se *se, gfc_expr *expr) expression passed as argument in VAR. */ static void -get_var_descr (gfc_se *se, gfc_expr *var) +get_var_descr (gfc_se *se, gfc_expr *var, tree class_container) { gfc_se tmp_se; @@ -1162,6 +1173,8 @@ get_var_descr (gfc_se *se, gfc_expr *var) else gfc_conv_expr (&tmp_se, var); } + else if (class_container) + tmp_se.expr = gfc_class_data_get (class_container); else { gfc_expr *array_expr; @@ -1209,20 +1222,25 @@ get_var_descr (gfc_se *se, gfc_expr *var) static void -get_vptr (gfc_se *se, gfc_expr *expr) +get_vptr (gfc_se *se, gfc_expr *expr, tree class_container) { - gfc_expr *vptr_expr = gfc_copy_expr (expr); - gfc_add_vptr_component (vptr_expr); + if (class_container) + se->expr = gfc_class_vptr_get (class_container); + else + { + gfc_expr *vptr_expr = gfc_copy_expr (expr); + gfc_add_vptr_component (vptr_expr); - gfc_se tmp_se; - gfc_init_se (&tmp_se, NULL); - tmp_se.want_pointer = 1; - gfc_conv_expr (&tmp_se, vptr_expr); - gfc_free_expr (vptr_expr); + gfc_se tmp_se; + gfc_init_se (&tmp_se, NULL); + tmp_se.want_pointer = 1; + gfc_conv_expr (&tmp_se, vptr_expr); + gfc_free_expr (vptr_expr); - gfc_add_block_to_block (&se->pre, &tmp_se.pre); - gfc_add_block_to_block (&se->post, &tmp_se.post); - se->expr = tmp_se.expr; + gfc_add_block_to_block (&se->pre, &tmp_se.pre); + gfc_add_block_to_block (&se->post, &tmp_se.post); + se->expr = tmp_se.expr; + } } @@ -1326,7 +1344,8 @@ gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp, true when a finalizer call has been inserted. */ bool -gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) +gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2, + tree class_container) { tree tmp; gfc_ref *ref; @@ -1381,17 +1400,17 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_se final_se; gfc_init_se (&final_se, NULL); - get_final_proc_ref (&final_se, expr); + get_final_proc_ref (&final_se, expr, class_container); gfc_add_block_to_block (block, &final_se.pre); gfc_se size_se; gfc_init_se (&size_se, NULL); - get_elem_size (&size_se, expr); + get_elem_size (&size_se, expr, class_container); gfc_add_block_to_block (&tmp_block, &size_se.pre); gfc_se desc_se; gfc_init_se (&desc_se, NULL); - get_var_descr (&desc_se, expr); + get_var_descr (&desc_se, expr, class_container); gfc_add_block_to_block (&tmp_block, &desc_se.pre); tmp = build_call_expr_loc (input_location, final_se.expr, 3, @@ -1423,7 +1442,7 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_se vptr_se; gfc_init_se (&vptr_se, NULL); - get_vptr (&vptr_se, expr); + get_vptr (&vptr_se, expr, class_container); cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, vptr_se.expr, diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 7b41e89..be9ccbc 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -457,7 +457,7 @@ tree gfc_get_class_from_gfc_expr (gfc_expr *); tree gfc_get_class_from_expr (tree); tree gfc_get_vptr_from_expr (tree); tree gfc_copy_class_to_class (tree, tree, tree, bool); -bool gfc_add_finalizer_call (stmtblock_t *, gfc_expr *); +bool gfc_add_finalizer_call (stmtblock_t *, gfc_expr *, tree = NULL_TREE); bool gfc_add_comp_finalizer_call (stmtblock_t *, tree, gfc_component *, bool); void gfc_finalize_tree_expr (gfc_se *, gfc_symbol *, symbol_attribute, int); bool gfc_assignment_finalizer_call (gfc_se *, gfc_expr *, bool); -- cgit v1.1 From e21e13e2525a042a0aabfbcb4ebf4f08609078c7 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Mon, 17 Jul 2023 14:14:22 +0200 Subject: fortran: Pass pre-calculated class container argument [pr110618] Pass already evaluated class container argument from gfc_conv_procedure_call down to gfc_add_finalizer_call through gfc_deallocate_scalar_with_status and gfc_deallocate_with_status, to avoid repeatedly evaluating the same data reference expressions in the generated code. PR fortran/110618 gcc/fortran/ChangeLog: * trans.h (gfc_deallocate_with_status): Add class container argument. (gfc_deallocate_scalar_with_status): Ditto. * trans.cc (gfc_deallocate_with_status): Add class container argument and pass it down to gfc_add_finalize_call. (gfc_deallocate_scalar_with_status): Same. * trans-array.cc (structure_alloc_comps): Update caller. * trans-stmt.cc (gfc_trans_deallocate): Ditto. * trans-expr.cc (gfc_conv_procedure_call): Ditto. Pass pre-evaluated class container argument if it's available. gcc/testsuite/ChangeLog: * gfortran.dg/intent_out_22.f90: New test. --- gcc/fortran/trans-array.cc | 2 +- gcc/fortran/trans-expr.cc | 7 ++++-- gcc/fortran/trans-stmt.cc | 3 ++- gcc/fortran/trans.cc | 11 +++++---- gcc/fortran/trans.h | 7 +++--- gcc/testsuite/gfortran.dg/intent_out_22.f90 | 37 +++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/intent_out_22.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 1c2af55..951cecf 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -9472,7 +9472,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, tmp = gfc_deallocate_with_status (comp, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, true, - NULL, caf_dereg_mode, + NULL, caf_dereg_mode, NULL_TREE, add_when_allocated, caf_token); gfc_add_expr_to_block (&tmpblock, tmp); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index dbb04f8..8258543 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6706,9 +6706,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, if (e->ts.type == BT_CLASS) ptr = gfc_class_data_get (ptr); + tree cls = parmse.class_container; tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE, NULL_TREE, true, - e, e->ts); + e, e->ts, cls); gfc_add_expr_to_block (&block, tmp); tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ptr, @@ -6900,10 +6901,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, ptr = parmse.expr; ptr = gfc_class_data_get (ptr); + tree cls = parmse.class_container; tmp = gfc_deallocate_with_status (ptr, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, true, e, - GFC_CAF_COARRAY_NOCOARRAY); + GFC_CAF_COARRAY_NOCOARRAY, + cls); gfc_add_expr_to_block (&block, tmp); tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ptr, diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc index 7e76834..93f36bf 100644 --- a/gcc/fortran/trans-stmt.cc +++ b/gcc/fortran/trans-stmt.cc @@ -7462,7 +7462,8 @@ gfc_trans_deallocate (gfc_code *code) { tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish, false, al->expr, - al->expr->ts, is_coarray); + al->expr->ts, NULL_TREE, + is_coarray); gfc_add_expr_to_block (&se.pre, tmp); /* Set to zero after deallocation. */ diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 3e9a14a..e2e1b69 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1774,8 +1774,8 @@ tree gfc_deallocate_with_status (tree pointer, tree status, tree errmsg, tree errlen, tree label_finish, bool can_fail, gfc_expr* expr, - int coarray_dealloc_mode, tree add_when_allocated, - tree caf_token) + int coarray_dealloc_mode, tree class_container, + tree add_when_allocated, tree caf_token) { stmtblock_t null, non_null; tree cond, tmp, error; @@ -1869,7 +1869,7 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg, gfc_start_block (&non_null); if (add_when_allocated) gfc_add_expr_to_block (&non_null, add_when_allocated); - gfc_add_finalizer_call (&non_null, expr); + gfc_add_finalizer_call (&non_null, expr, class_container); if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY || flag_coarray != GFC_FCOARRAY_LIB) { @@ -1974,7 +1974,8 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg, tree gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish, bool can_fail, gfc_expr* expr, - gfc_typespec ts, bool coarray) + gfc_typespec ts, tree class_container, + bool coarray) { stmtblock_t null, non_null; tree cond, tmp, error; @@ -2027,7 +2028,7 @@ gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish, gfc_start_block (&non_null); /* Free allocatable components. */ - finalizable = gfc_add_finalizer_call (&non_null, expr); + finalizable = gfc_add_finalizer_call (&non_null, expr, class_container); if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp) { int caf_mode = coarray diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index be9ccbc..109d764 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -771,10 +771,11 @@ void gfc_allocate_using_malloc (stmtblock_t *, tree, tree, tree); /* Generate code to deallocate an array. */ tree gfc_deallocate_with_status (tree, tree, tree, tree, tree, bool, - gfc_expr *, int, tree a = NULL_TREE, - tree c = NULL_TREE); + gfc_expr *, int, tree = NULL_TREE, + tree a = NULL_TREE, tree c = NULL_TREE); tree gfc_deallocate_scalar_with_status (tree, tree, tree, bool, gfc_expr*, - gfc_typespec, bool c = false); + gfc_typespec, tree = NULL_TREE, + bool c = false); /* Generate code to call realloc(). */ tree gfc_call_realloc (stmtblock_t *, tree, tree); diff --git a/gcc/testsuite/gfortran.dg/intent_out_22.f90 b/gcc/testsuite/gfortran.dg/intent_out_22.f90 new file mode 100644 index 0000000..a38afcc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intent_out_22.f90 @@ -0,0 +1,37 @@ +! { dg-do run } +! +! PR fortran/110618 +! Check that if a data reference is passed as actual argument whose dummy +! has INTENT(OUT) attribute, any other argument depending on the +! same data reference is evaluated before the data reference deallocation. + +program p + implicit none + type t + integer :: i + end type t + type u + class(t), allocatable :: ta(:) + end type u + type(u), allocatable :: c(:) + class(t), allocatable :: d(:) + allocate(c, source = [u([t(1), t(3)]), u([t(4), t(9)])]) + allocate(d, source = [t(1), t(5)]) + call bar ( & + allocated(c(d(1)%i)%ta), & + d, & + c(d(1)%i)%ta, & + allocated (c(d(1)%i)%ta) & + ) + if (allocated (c(1)%ta)) stop 11 + if (.not. allocated (c(2)%ta)) stop 11 +contains + subroutine bar (alloc, x, y, alloc2) + logical :: alloc, alloc2 + class(t), allocatable, intent(out) :: x(:) + class(t), allocatable, intent(out) :: y(:) + if (allocated (x)) stop 1 + if (.not. alloc) stop 2 + if (.not. alloc2) stop 3 + end subroutine bar +end -- cgit v1.1 From 3b9cd125cfca44d3ae18f409fb20b5c094829e41 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Mon, 17 Jul 2023 14:22:06 +0200 Subject: Restore bootstrap by removing unused variable in tree-ssa-loop-ivcanon.cc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This restores bootstrap by removing the variable causing: /home/mjambor/gcc/trunk/src/gcc/tree-ssa-loop-ivcanon.cc: In function ‘bool try_peel_loop(loop*, edge, tree, bool, long int)’: /home/mjambor/gcc/trunk/src/gcc/tree-ssa-loop-ivcanon.cc:1170:17: error: variable ‘entry_count’ set but not used [-Werror=unused-but-set-variable] 1170 | profile_count entry_count = profile_count::zero (); | ^~~~~~~~~~~ cc1plus: all warnings being treated as errors gcc/ChangeLog: 2023-07-17 Martin Jambor * tree-ssa-loop-ivcanon.cc (try_peel_loop): Remove unused variable entry_count. --- gcc/tree-ssa-loop-ivcanon.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc index bdb738a..a895e8e 100644 --- a/gcc/tree-ssa-loop-ivcanon.cc +++ b/gcc/tree-ssa-loop-ivcanon.cc @@ -1167,7 +1167,6 @@ try_peel_loop (class loop *loop, loop->num, (int) npeel); } adjust_loop_info_after_peeling (loop, npeel, true); - profile_count entry_count = profile_count::zero (); bitmap_set_bit (peeled_loops, loop->num); return true; -- cgit v1.1 From 89d0f082b3c95f68d116d4480126e3ab7fb7f36b Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Mon, 17 Jul 2023 15:13:44 +0200 Subject: OpenMP/Fortran: Parsing support for 'uses_allocators' The 'uses_allocators' clause to the 'target' construct accepts predefined allocators and can also be used to define a new allocator for a target region. As predefined allocators in GCC do not require special handling, those can and are ignored after parsing, such that this feature now works. On the other hand, defining a new allocator will fail for now with a 'sorry, unimplemented'. Note that both the OpenMP 5.0/5.1 and 5.2 syntax for uses_allocators is supported by this commit. 2023-07-17 Tobias Burnus Chung-Lin Tang gcc/fortran/ChangeLog: * dump-parse-tree.cc (show_omp_namelist, show_omp_clauses): Dump uses_allocators clause. * gfortran.h (gfc_free_omp_namelist): Add memspace_sym to u union and traits_sym to u2 union. (OMP_LIST_USES_ALLOCATORS): New enum value. (gfc_free_omp_namelist): Add 'bool free_mem_traits_space' arg. * match.cc (gfc_free_omp_namelist): Likewise. * openmp.cc (gfc_free_omp_clauses, gfc_match_omp_variable_list, gfc_match_omp_to_link, gfc_match_omp_doacross_sink, gfc_match_omp_clause_reduction, gfc_match_omp_allocate, gfc_match_omp_flush): Update call. (gfc_match_omp_clauses): Likewise. Parse uses_allocators clause. (gfc_match_omp_clause_uses_allocators): New. (enum omp_mask2): Add new OMP_CLAUSE_USES_ALLOCATORS. (OMP_TARGET_CLAUSES): Accept it. (resolve_omp_clauses): Resolve uses_allocators clause * st.cc (gfc_free_statement): Update gfc_free_omp_namelist call. * trans-openmp.cc (gfc_trans_omp_clauses): Handle OMP_LIST_USES_ALLOCATORS; fail with sorry unless predefined allocator. (gfc_split_omp_clauses): Handle uses_allocators. libgomp/ChangeLog: * testsuite/libgomp.fortran/uses_allocators_1.f90: New test. * testsuite/libgomp.fortran/uses_allocators_2.f90: New test. Co-authored-by: Chung-Lin Tang --- gcc/fortran/dump-parse-tree.cc | 24 +++++ gcc/fortran/gfortran.h | 5 +- gcc/fortran/match.cc | 7 +- gcc/fortran/openmp.cc | 194 +++++++++++++++++++++++++++++++++++++---- gcc/fortran/st.cc | 2 +- gcc/fortran/trans-openmp.cc | 11 +++ 6 files changed, 224 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index effcebe..68122e3 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -1497,6 +1497,29 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) case OMP_LINEAR_UVAL: fputs ("uval(", dumpfile); break; default: break; } + else if (list_type == OMP_LIST_USES_ALLOCATORS) + { + if (n->u.memspace_sym) + { + fputs ("memspace(", dumpfile); + fputs (n->sym->name, dumpfile); + fputc (')', dumpfile); + } + if (n->u.memspace_sym && n->u2.traits_sym) + fputc (',', dumpfile); + if (n->u2.traits_sym) + { + fputs ("traits(", dumpfile); + fputs (n->u2.traits_sym->name, dumpfile); + fputc (')', dumpfile); + } + if (n->u.memspace_sym || n->u2.traits_sym) + fputc (':', dumpfile); + fputs (n->sym->name, dumpfile); + if (n->next) + fputs (", ", dumpfile); + continue; + } fprintf (dumpfile, "%s", n->sym ? n->sym->name : "omp_all_memory"); if (list_type == OMP_LIST_LINEAR && n->u.linear.op != OMP_LINEAR_DEFAULT) fputc (')', dumpfile); @@ -1799,6 +1822,7 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) case OMP_LIST_ALLOCATE: type = "ALLOCATE"; break; case OMP_LIST_SCAN_IN: type = "INCLUSIVE"; break; case OMP_LIST_SCAN_EX: type = "EXCLUSIVE"; break; + case OMP_LIST_USES_ALLOCATORS: type = "USES_ALLOCATORS"; break; default: gcc_unreachable (); } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 74466c7..6482a88 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1368,6 +1368,7 @@ typedef struct gfc_omp_namelist bool old_modifier; } linear; struct gfc_common_head *common; + struct gfc_symbol *memspace_sym; bool lastprivate_conditional; bool present_modifier; } u; @@ -1376,6 +1377,7 @@ typedef struct gfc_omp_namelist struct gfc_omp_namelist_udr *udr; gfc_namespace *ns; gfc_expr *allocator; + struct gfc_symbol *traits_sym; } u2; struct gfc_omp_namelist *next; locus where; @@ -1419,6 +1421,7 @@ enum OMP_LIST_ALLOCATE, OMP_LIST_HAS_DEVICE_ADDR, OMP_LIST_ENTER, + OMP_LIST_USES_ALLOCATORS, OMP_LIST_NUM /* Must be the last. */ }; @@ -3600,7 +3603,7 @@ void gfc_free_iterator (gfc_iterator *, int); void gfc_free_forall_iterator (gfc_forall_iterator *); void gfc_free_alloc_list (gfc_alloc *); void gfc_free_namelist (gfc_namelist *); -void gfc_free_omp_namelist (gfc_omp_namelist *, bool, bool); +void gfc_free_omp_namelist (gfc_omp_namelist *, bool, bool, bool); void gfc_free_equiv (gfc_equiv *); void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *); void gfc_free_data (gfc_data *); diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc index 7335d98..ba23bcd 100644 --- a/gcc/fortran/match.cc +++ b/gcc/fortran/match.cc @@ -5537,7 +5537,8 @@ gfc_free_namelist (gfc_namelist *name) void gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns, - bool free_align_allocator) + bool free_align_allocator, + bool free_mem_traits_space) { gfc_omp_namelist *n; @@ -5546,10 +5547,14 @@ gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns, gfc_free_expr (name->expr); if (free_align_allocator) gfc_free_expr (name->u.align); + else if (free_mem_traits_space) + { } /* name->u.memspace_sym: shall not call gfc_free_symbol here. */ if (free_ns) gfc_free_namespace (name->u2.ns); else if (free_align_allocator) gfc_free_expr (name->u2.allocator); + else if (free_mem_traits_space) + { } /* name->u2.traits_sym: shall not call gfc_free_symbol here. */ else if (name->u2.udr) { if (name->u2.udr->combiner) diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 8efc4b3..05a697d 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -188,7 +188,8 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) for (i = 0; i < OMP_LIST_NUM; i++) gfc_free_omp_namelist (c->lists[i], i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND, - i == OMP_LIST_ALLOCATE); + i == OMP_LIST_ALLOCATE, + i == OMP_LIST_USES_ALLOCATORS); gfc_free_expr_list (c->wait_list); gfc_free_expr_list (c->tile_list); free (CONST_CAST (char *, c->critical_name)); @@ -553,7 +554,7 @@ syntax: gfc_error ("Syntax error in OpenMP variable list at %C"); cleanup: - gfc_free_omp_namelist (head, false, false); + gfc_free_omp_namelist (head, false, false, false); gfc_current_locus = old_loc; return MATCH_ERROR; } @@ -643,7 +644,7 @@ syntax: gfc_error ("Syntax error in OpenMP variable list at %C"); cleanup: - gfc_free_omp_namelist (head, false, false); + gfc_free_omp_namelist (head, false, false, false); gfc_current_locus = old_loc; return MATCH_ERROR; } @@ -752,7 +753,7 @@ syntax: gfc_error ("Syntax error in OpenMP SINK dependence-type list at %C"); cleanup: - gfc_free_omp_namelist (head, false, false); + gfc_free_omp_namelist (head, false, false, false); gfc_current_locus = old_loc; return MATCH_ERROR; } @@ -1091,6 +1092,7 @@ enum omp_mask2 OMP_CLAUSE_ENTER, /* OpenMP 5.2 */ OMP_CLAUSE_DOACROSS, /* OpenMP 5.2 */ OMP_CLAUSE_ASSUMPTIONS, /* OpenMP 5.1. */ + OMP_CLAUSE_USES_ALLOCATORS, /* OpenMP 5.0 */ /* This must come last. */ OMP_MASK2_LAST }; @@ -1502,7 +1504,7 @@ gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc, *head = NULL; gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L", buffer, &old_loc); - gfc_free_omp_namelist (n, false, false); + gfc_free_omp_namelist (n, false, false, false); } else for (n = *head; n; n = n->next) @@ -1697,6 +1699,106 @@ omp_verify_merge_absent_contains (gfc_statement st, gfc_omp_assumptions *check, return MATCH_YES; } +/* OpenMP 5.0 + uses_allocators ( allocator-list ) + + allocator: + predefined-allocator + variable ( traits-array ) + + OpenMP 5.2: + uses_allocators ( [modifier-list :] allocator-list ) + + allocator: + variable or predefined-allocator + modifier: + traits ( traits-array ) + memspace ( mem-space-handle ) */ + +static match +gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c) +{ + gfc_symbol *memspace_sym = NULL; + gfc_symbol *traits_sym = NULL; + gfc_omp_namelist *head = NULL; + gfc_omp_namelist *p, *tail, **list; + int ntraits, nmemspace; + bool has_modifiers; + locus old_loc, cur_loc; + + gfc_gobble_whitespace (); + old_loc = gfc_current_locus; + ntraits = nmemspace = 0; + do + { + cur_loc = gfc_current_locus; + if (gfc_match ("traits ( %S ) ", &traits_sym) == MATCH_YES) + ntraits++; + else if (gfc_match ("memspace ( %S ) ", &memspace_sym) == MATCH_YES) + nmemspace++; + if (ntraits > 1 || nmemspace > 1) + { + gfc_error ("Duplicate %s modifier at %L in USES_ALLOCATORS clause", + ntraits > 1 ? "TRAITS" : "MEMSPACE", &cur_loc); + return MATCH_ERROR; + } + if (gfc_match (", ") == MATCH_YES) + continue; + if (gfc_match (": ") != MATCH_YES) + { + /* Assume no modifier. */ + memspace_sym = traits_sym = NULL; + gfc_current_locus = old_loc; + break; + } + break; + } while (true); + + has_modifiers = traits_sym != NULL || memspace_sym != NULL; + do + { + p = gfc_get_omp_namelist (); + p->where = gfc_current_locus; + if (head == NULL) + head = tail = p; + else + { + tail->next = p; + tail = tail->next; + } + if (gfc_match ("%S ", &p->sym) != MATCH_YES) + goto error; + if (!has_modifiers) + gfc_match ("( %S ) ", &p->u2.traits_sym); + else if (gfc_peek_ascii_char () == '(') + { + gfc_error ("Unexpected %<(%> at %C"); + goto error; + } + else + { + p->u.memspace_sym = memspace_sym; + p->u2.traits_sym = traits_sym; + } + if (gfc_match (", ") == MATCH_YES) + continue; + if (gfc_match (") ") == MATCH_YES) + break; + goto error; + } while (true); + + list = &c->lists[OMP_LIST_USES_ALLOCATORS]; + while (*list) + list = &(*list)->next; + *list = head; + + return MATCH_YES; + +error: + gfc_free_omp_namelist (head, false, false, true); + return MATCH_ERROR; +} + /* Match with duplicate check. Matches 'name'. If expr != NULL, it then matches '(expr)', otherwise, if open_parens is true, @@ -1820,7 +1922,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES) { - gfc_free_omp_namelist (*head, false, false); + gfc_free_omp_namelist (*head, false, false, false); gfc_current_locus = old_loc; *head = NULL; break; @@ -2763,7 +2865,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, end_colon = true; else if (gfc_match (" )") != MATCH_YES) { - gfc_free_omp_namelist (*head, false, false); + gfc_free_omp_namelist (*head, false, false, false); gfc_current_locus = old_loc; *head = NULL; break; @@ -2774,7 +2876,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, { if (gfc_match (" %e )", &step) != MATCH_YES) { - gfc_free_omp_namelist (*head, false, false); + gfc_free_omp_namelist (*head, false, false, false); gfc_current_locus = old_loc; *head = NULL; goto error; @@ -2871,7 +2973,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, } if (has_error) { - gfc_free_omp_namelist (*head, false, false); + gfc_free_omp_namelist (*head, false, false, false); *head = NULL; goto error; } @@ -3561,6 +3663,13 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, ("use_device_addr (", &c->lists[OMP_LIST_USE_DEVICE_ADDR], false, NULL, NULL, true) == MATCH_YES) continue; + if ((mask & OMP_CLAUSE_USES_ALLOCATORS) + && (gfc_match ("uses_allocators ( ") == MATCH_YES)) + { + if (gfc_match_omp_clause_uses_allocators (c) != MATCH_YES) + goto error; + continue; + } break; case 'v': /* VECTOR_LENGTH must be matched before VECTOR, because the latter @@ -4290,7 +4399,7 @@ cleanup: | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \ | OMP_CLAUSE_IS_DEVICE_PTR | OMP_CLAUSE_IN_REDUCTION \ | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE \ - | OMP_CLAUSE_HAS_DEVICE_ADDR) + | OMP_CLAUSE_HAS_DEVICE_ADDR | OMP_CLAUSE_USES_ALLOCATORS) #define OMP_TARGET_DATA_CLAUSES \ (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \ | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR) @@ -4410,7 +4519,7 @@ gfc_match_omp_allocate (void) gfc_error ("Unexpected expression as list item at %L in ALLOCATE " "directive", &n->expr->where); - gfc_free_omp_namelist (vars, false, true); + gfc_free_omp_namelist (vars, false, true, false); goto error; } @@ -4814,14 +4923,14 @@ gfc_match_omp_flush (void) { gfc_error ("List specified together with memory order clause in FLUSH " "directive at %C"); - gfc_free_omp_namelist (list, false, false); + gfc_free_omp_namelist (list, false, false, false); gfc_free_omp_clauses (c); return MATCH_ERROR; } if (gfc_match_omp_eos () != MATCH_YES) { gfc_error ("Unexpected junk after $OMP FLUSH statement at %C"); - gfc_free_omp_namelist (list, false, false); + gfc_free_omp_namelist (list, false, false, false); gfc_free_omp_clauses (c); return MATCH_ERROR; } @@ -7229,7 +7338,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, "IN_REDUCTION", "TASK_REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE", "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR", - "NONTEMPORAL", "ALLOCATE", "HAS_DEVICE_ADDR", "ENTER" }; + "NONTEMPORAL", "ALLOCATE", "HAS_DEVICE_ADDR", "ENTER", + "USES_ALLOCATORS" }; STATIC_ASSERT (ARRAY_SIZE (clause_names) == OMP_LIST_NUM); if (omp_clauses == NULL) @@ -7495,7 +7605,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, " cannot be and need not be mapped", n->sym->name, &n->where); } - else + else if (list != OMP_LIST_USES_ALLOCATORS) gfc_error ("Object %qs is not a variable at %L", n->sym->name, &n->where); } @@ -7721,7 +7831,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, { prev->next = n->next; n->next = NULL; - gfc_free_omp_namelist (n, false, true); + gfc_free_omp_namelist (n, false, true, false); n = prev->next; } continue; @@ -8291,6 +8401,58 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, n = n->next; } break; + case OMP_LIST_USES_ALLOCATORS: + { + if (n != NULL + && n->u.memspace_sym + && (n->u.memspace_sym->attr.flavor != FL_PARAMETER + || n->u.memspace_sym->ts.type != BT_INTEGER + || n->u.memspace_sym->ts.kind != gfc_c_intptr_kind + || n->u.memspace_sym->attr.dimension + || (!startswith (n->u.memspace_sym->name, "omp_") + && !startswith (n->u.memspace_sym->name, "ompx_")) + || !endswith (n->u.memspace_sym->name, "_mem_space"))) + gfc_error ("Memspace %qs at %L in USES_ALLOCATORS must be " + "a predefined memory space", + n->u.memspace_sym->name, &n->where); + for (; n != NULL; n = n->next) + { + if (n->sym->ts.type != BT_INTEGER + || n->sym->ts.kind != gfc_c_intptr_kind + || n->sym->attr.dimension) + gfc_error ("Allocator %qs at %L in USES_ALLOCATORS must " + "be a scalar integer of kind " + "%", n->sym->name, + &n->where); + else if (n->sym->attr.flavor != FL_VARIABLE + && ((!startswith (n->sym->name, "omp_") + && !startswith (n->sym->name, "ompx_")) + || !endswith (n->sym->name, "_mem_alloc"))) + gfc_error ("Allocator %qs at %L in USES_ALLOCATORS must " + "either a variable or a predefined allocator", + n->sym->name, &n->where); + else if ((n->u.memspace_sym || n->u2.traits_sym) + && n->sym->attr.flavor != FL_VARIABLE) + gfc_error ("A memory space or traits array may not be " + "specified for predefined allocator %qs at %L", + n->sym->name, &n->where); + if (n->u2.traits_sym + && (n->u2.traits_sym->attr.flavor != FL_PARAMETER + || !n->u2.traits_sym->attr.dimension + || n->u2.traits_sym->as->rank != 1 + || n->u2.traits_sym->ts.type != BT_DERIVED + || strcmp (n->u2.traits_sym->ts.u.derived->name, + "omp_alloctrait") != 0)) + { + gfc_error ("Traits array %qs in USES_ALLOCATORS %L must " + "be a one-dimensional named constant array of " + "type %", + n->u2.traits_sym->name, &n->where); + break; + } + } + break; + } default: for (; n != NULL; n = n->next) { diff --git a/gcc/fortran/st.cc b/gcc/fortran/st.cc index 55debca..b6d87c4 100644 --- a/gcc/fortran/st.cc +++ b/gcc/fortran/st.cc @@ -288,7 +288,7 @@ gfc_free_statement (gfc_code *p) break; case EXEC_OMP_FLUSH: - gfc_free_omp_namelist (p->ext.omp_namelist, false, false); + gfc_free_omp_namelist (p->ext.omp_namelist, false, false, false); break; case EXEC_OMP_BARRIER: diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 4aa16fa..c88ee3c 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -3923,6 +3923,15 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, omp_clauses = gfc_trans_add_clause (node, omp_clauses); } break; + case OMP_LIST_USES_ALLOCATORS: + /* Ignore pre-defined allocators as no special treatment is needed. */ + for (; n != NULL; n = n->next) + if (n->sym->attr.flavor == FL_VARIABLE) + break; + if (n != NULL) + sorry_at (input_location, "% clause with traits " + "and memory spaces"); + break; default: break; } @@ -6581,6 +6590,8 @@ gfc_split_omp_clauses (gfc_code *code, = code->ext.omp_clauses->device; clausesa[GFC_OMP_SPLIT_TARGET].thread_limit = code->ext.omp_clauses->thread_limit; + clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_USES_ALLOCATORS] + = code->ext.omp_clauses->lists[OMP_LIST_USES_ALLOCATORS]; for (int i = 0; i < OMP_DEFAULTMAP_CAT_NUM; i++) clausesa[GFC_OMP_SPLIT_TARGET].defaultmap[i] = code->ext.omp_clauses->defaultmap[i]; -- cgit v1.1 From c1244ceed99bc37069baf164d008ff91f63d3115 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Mon, 17 Jul 2023 22:20:02 +0800 Subject: RISC-V: Add TARGET_MIN_VLEN > 4096 check gcc/ChangeLog: * config/riscv/riscv.cc (riscv_option_override): Add sorry check. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/zvl-unimplemented-1.c: New test. * gcc.target/riscv/rvv/base/zvl-unimplemented-2.c: New test. --- gcc/config/riscv/riscv.cc | 8 ++++++++ gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-1.c | 4 ++++ gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-2.c | 4 ++++ 3 files changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-2.c (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index ae3c034..195f001 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6672,6 +6672,14 @@ riscv_option_override (void) riscv_stack_protector_guard_offset = offs; } + /* FIXME: We don't allow TARGET_MIN_VLEN > 4096 since the datatypes of + both GET_MODE_SIZE and GET_MODE_BITSIZE are poly_uint16. + + We can only allow TARGET_MIN_VLEN * 8 (LMUL) < 65535. */ + if (TARGET_MIN_VLEN > 4096) + sorry ( + "Current RISC-V GCC can not support VLEN > 4096bit for 'V' Extension"); + /* Convert -march to a chunks count. */ riscv_vector_chunks = riscv_convert_vector_bits (); } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-1.c new file mode 100644 index 0000000..03f6703 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-1.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv64gcv_zvl8192b -mabi=lp64d --param riscv-autovec-preference=fixed-vlmax" } */ + +void foo () {} // { dg-excess-errors "sorry, unimplemented: Current RISC-V GCC can not support VLEN > 4096bit for 'V' Extension" } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-2.c new file mode 100644 index 0000000..075112f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvl-unimplemented-2.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv64gcv_zvl8192b -mabi=lp64d --param riscv-autovec-preference=scalable" } */ + +void foo () {} // { dg-excess-errors "sorry, unimplemented: Current RISC-V GCC can not support VLEN > 4096bit for 'V' Extension" } -- cgit v1.1 From 08b99fe8ad6c7ed1fe7a9f352df5aac0b2f3a72b Mon Sep 17 00:00:00 2001 From: Senthil Kumar Selvaraj Date: Mon, 17 Jul 2023 20:04:36 +0530 Subject: ira: Skip empty regclass when setting up reg class relations ira.cc:setup_reg_class_relations sets up ira_reg_class_subset (among other things). If reg class cl3 has no registers, then that empty set is always hard_reg_set_subset_p of any other set, and this makes ira_reg_class_subset[ALL_REGS][NO_REGS] equal to such a regclass, rather than NO_REGS. This breaks code (lra-constraints.cc:in_class_p/curr_insn_transform, for e.g.) which uses NO_REGS to check for an empty regclass. Why define an empty regclass? A regclass could be conditionally empty (via TARGET_CONDITIONAL_REGISTER_USAGE) - for the avr target, ADDW_REGS and NO_LD_REGS are empty for the avrtiny subarch, for example. Fix by continuing the innermost loop if the corresponding reg class is empty. gcc/ChangeLog: * ira.cc (setup_reg_class_relations): Continue if regclass cl3 is hard_reg_set_empty_p. --- gcc/ira.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc') diff --git a/gcc/ira.cc b/gcc/ira.cc index 4a6fb35..0b0d460 100644 --- a/gcc/ira.cc +++ b/gcc/ira.cc @@ -1259,6 +1259,9 @@ setup_reg_class_relations (void) for (cl3 = 0; cl3 < N_REG_CLASSES; cl3++) { temp_hard_regset = reg_class_contents[cl3] & ~no_unit_alloc_regs; + if (hard_reg_set_empty_p (temp_hard_regset)) + continue; + if (hard_reg_set_subset_p (temp_hard_regset, intersection_set)) { /* CL3 allocatable hard register set is inside of -- cgit v1.1 From caabf0973a4e9a26421c94d540e3e20051e93e77 Mon Sep 17 00:00:00 2001 From: Andre Vieira Date: Mon, 17 Jul 2023 17:00:54 +0100 Subject: Include insn-opinit.h in PLUGIN_H [PR110610] This patch fixes PR110610 by including insn-opinit.h in the INTERNAL_FN_H list, as insn-opinit.h is now required by internal-fn.h. This will lead to insn-opinit.h being installed in the plugin directory. gcc/ChangeLog: PR plugins/110610 * Makefile.in (INTERNAL_FN_H): Add insn-opinit.h. --- gcc/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/Makefile.in b/gcc/Makefile.in index c478ec8..683774a 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -976,7 +976,7 @@ READ_MD_H = $(OBSTACK_H) $(HASHTAB_H) read-md.h BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def \ gtm-builtins.def sanitizer.def INTERNAL_FN_DEF = internal-fn.def -INTERNAL_FN_H = internal-fn.h $(INTERNAL_FN_DEF) +INTERNAL_FN_H = internal-fn.h $(INTERNAL_FN_DEF) insn-opinit.h TREE_CORE_H = tree-core.h $(CORETYPES_H) all-tree.def tree.def \ c-family/c-common.def $(lang_tree_files) \ $(BUILTINS_DEF) $(INPUT_H) statistics.h \ -- cgit v1.1 From 95ddd2659849a904509067ec3a2770135149a722 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Sun, 16 Jul 2023 22:17:27 +0200 Subject: Fortran: intrinsics and deferred-length character arguments [PR95947,PR110658] gcc/fortran/ChangeLog: PR fortran/95947 PR fortran/110658 * trans-expr.cc (gfc_conv_procedure_call): For intrinsic procedures whose result characteristics depends on the first argument and which can be of type character, the character length will not be deferred. gcc/testsuite/ChangeLog: PR fortran/95947 PR fortran/110658 * gfortran.dg/deferred_character_37.f90: New test. --- gcc/fortran/trans-expr.cc | 7 +- .../gfortran.dg/deferred_character_37.f90 | 88 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/deferred_character_37.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 8258543..ef3e6d0 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -7657,7 +7657,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, (and other intrinsics?) and dummy functions. In the case of SPREAD, we take the character length of the first argument for the result. For dummies, we have to look through the formal argument list for - this function and use the character length found there.*/ + this function and use the character length found there. + Likewise, we handle the case of deferred-length character dummy + arguments to intrinsics that determine the characteristics of + the result, which cannot be deferred-length. */ + if (expr->value.function.isym) + ts.deferred = false; if (ts.deferred) cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen"); else if (!sym->attr.dummy) diff --git a/gcc/testsuite/gfortran.dg/deferred_character_37.f90 b/gcc/testsuite/gfortran.dg/deferred_character_37.f90 new file mode 100644 index 0000000..8a5a8c5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/deferred_character_37.f90 @@ -0,0 +1,88 @@ +! { dg-do run } +! PR fortran/95947 +! PR fortran/110658 +! +! Test deferred-length character arguments to selected intrinsics +! that may return a character result of same length as first argument: +! CSHIFT, EOSHIFT, MAXVAL, MERGE, MINVAL, PACK, SPREAD, TRANSPOSE, UNPACK + +program p + implicit none + call pr95947 () + call pr110658 () + call s () + +contains + + subroutine pr95947 + character(len=:), allocatable :: m(:) + + m = [ character(len=10) :: 'ape','bat','cat','dog','eel','fly','gnu'] + m = pack (m, mask=(m(:)(2:2) == 'a')) + +! print *, "m = '", m,"' ", "; expected is ['bat','cat']" + if (.not. all (m == ['bat','cat'])) stop 1 + +! print *, "size(m) = ", size(m), "; expected is 2" + if (size (m) /= 2) stop 2 + +! print *, "len(m) = ", len(m), "; expected is 10" + if (len (m) /= 10) stop 3 + +! print *, "len_trim(m) = ", len_trim(m), "; expected is 3 3" + if (.not. all (len_trim(m) == [3,3])) stop 4 + end + + subroutine pr110658 + character(len=:), allocatable :: array(:), array2(:,:) + character(len=:), allocatable :: res, res1(:), res2(:) + + array = ["bb", "aa", "cc"] + + res = minval (array) + if (res /= "aa") stop 11 + + res = maxval (array, mask=[.true.,.true.,.false.]) + if (res /= "bb") stop 12 + + res1 = cshift (array, 1) + if (any (res1 /= ["aa","cc","bb"])) stop 13 + + res2 = eoshift (res1, -1) + if (any (res2 /= [" ", "aa", "cc"])) stop 14 + + res2 = pack (array, mask=[.true.,.false.,.true.]) + if (any (res2 /= ["bb","cc"])) stop 15 + + res2 = unpack (res2, mask=[.true.,.false.,.true.], field="aa") + if (any (res2 /= array)) stop 16 + + res2 = merge (res2, array, [.true.,.false.,.true.]) + if (any (res2 /= array)) stop 17 + + array2 = spread (array, dim=2, ncopies=2) + array2 = transpose (array2) + if (any (shape (array2) /= [2,3])) stop 18 + if (any (array2(2,:) /= array)) stop 19 + end + + subroutine s + character(:), allocatable :: array1(:), array2(:) + array1 = ["aa","cc","bb"] + array2 = copy (array1) + if (any (array1 /= array2)) stop 20 + end + + function copy (arg) result (res) + character(:), allocatable :: res(:) + character(*), intent(in) :: arg(:) + integer :: i, k, n + k = len (arg) + n = size (arg) + allocate (character(k) :: res(n)) + do i = 1, n + res(i) = arg(i) + end do + end + +end -- cgit v1.1 From d8105b10fff95133eb636bed10822fe36c1db53b Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 17 Jul 2023 22:13:52 +0200 Subject: combine: Change return type of predicate functions from int to bool Also change some internal variables and function arguments from int to bool. gcc/ChangeLog: * combine.cc (struct reg_stat_type): Change last_set_invalid to bool. (cant_combine_insn_p): Change return type from int to bool and adjust function body accordingly. (can_combine_p): Ditto. (combinable_i3pat): Ditto. Change "i1_not_in_src" and "i0_not_in_src" function arguments from int to bool. (contains_muldiv): Change return type from int to bool and adjust function body accordingly. (try_combine): Ditto. Change "new_direct_jump" pointer function argument from int to bool. Change "substed_i2", "substed_i1", "substed_i0", "added_sets_0", "added_sets_1", "added_sets_2", "i2dest_in_i2src", "i1dest_in_i1src", "i2dest_in_i1src", "i0dest_in_i0src", "i1dest_in_i0src", "i2dest_in_i0src", "i2dest_killed", "i1dest_killed", "i0dest_killed", "i1_feeds_i2_n", "i0_feeds_i2_n", "i0_feeds_i1_n", "i3_subst_into_i2", "have_mult", "swap_i2i3", "split_i2i3" and "changed_i3_dest" variables from int to bool. (subst): Change "in_dest", "in_cond" and "unique_copy" function arguments from int to bool. (combine_simplify_rtx): Change "in_dest" and "in_cond" function arguments from int to bool. (make_extraction): Change "unsignedp", "in_dest" and "in_compare" function argument from int to bool. (force_int_to_mode): Change "just_select" function argument from int to bool. Change "next_select" variable to bool. (rtx_equal_for_field_assignment_p): Change return type from int to bool and adjust function body accordingly. (merge_outer_ops): Ditto. Change "pcomp_p" pointer function argument from int to bool. (get_last_value_validate): Change return type from int to bool and adjust function body accordingly. (reg_dead_at_p): Ditto. (reg_bitfield_target_p): Ditto. (combine_instructions): Ditto. Change "new_direct_jump" variable to bool. (can_combine_p): Change return type from int to bool and adjust function body accordingly. (likely_spilled_retval_p): Ditto. (can_change_dest_mode): Change "added_sets" function argument from int to bool. (find_split_point): Change "unsignedp" variable to bool. (simplify_if_then_else): Change "comparison_p" and "swapped" variables to bool. (simplify_set): Change "other_changed" variable to bool. (expand_compound_operation): Change "unsignedp" variable to bool. (force_to_mode): Change "just_select" function argument from int to bool. Change "next_select" variable to bool. (extended_count): Change "unsignedp" function argument to bool. (simplify_shift_const_1): Change "complement_p" variable to bool. (simplify_comparison): Change "changed" variable to bool. (rest_of_handle_combine): Change return type to void. --- gcc/combine.cc | 510 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 259 insertions(+), 251 deletions(-) (limited to 'gcc') diff --git a/gcc/combine.cc b/gcc/combine.cc index 304c020..d9161b2 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -156,7 +156,7 @@ struct reg_stat_type { register was assigned last_set_table_tick records the value of label_tick when a value using the register is assigned - last_set_invalid set to nonzero when it is not valid + last_set_invalid set to true when it is not valid to use the value of this register in some register's value @@ -202,11 +202,11 @@ struct reg_stat_type { char last_set_sign_bit_copies; ENUM_BITFIELD(machine_mode) last_set_mode : MACHINE_MODE_BITSIZE; - /* Set nonzero if references to register n in expressions should not be + /* Set to true if references to register n in expressions should not be used. last_set_invalid is set nonzero when this register is being assigned to and last_set_table_tick == label_tick. */ - char last_set_invalid; + bool last_set_invalid; /* Some registers that are set more than once and used in more than one basic block are nevertheless always set in similar ways. For example, @@ -416,35 +416,36 @@ static void do_SUBST_INT (int *, int); static void init_reg_last (void); static void setup_incoming_promotions (rtx_insn *); static void set_nonzero_bits_and_sign_copies (rtx, const_rtx, void *); -static int cant_combine_insn_p (rtx_insn *); -static int can_combine_p (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *, - rtx_insn *, rtx_insn *, rtx *, rtx *); -static int combinable_i3pat (rtx_insn *, rtx *, rtx, rtx, rtx, int, int, rtx *); -static int contains_muldiv (rtx); +static bool cant_combine_insn_p (rtx_insn *); +static bool can_combine_p (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *, + rtx_insn *, rtx_insn *, rtx *, rtx *); +static bool combinable_i3pat (rtx_insn *, rtx *, rtx, rtx, rtx, + bool, bool, rtx *); +static bool contains_muldiv (rtx); static rtx_insn *try_combine (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *, - int *, rtx_insn *); + bool *, rtx_insn *); static void undo_all (void); static void undo_commit (void); static rtx *find_split_point (rtx *, rtx_insn *, bool); -static rtx subst (rtx, rtx, rtx, int, int, int); -static rtx combine_simplify_rtx (rtx, machine_mode, int, int); +static rtx subst (rtx, rtx, rtx, bool, bool, bool); +static rtx combine_simplify_rtx (rtx, machine_mode, bool, bool); static rtx simplify_if_then_else (rtx); static rtx simplify_set (rtx); static rtx simplify_logical (rtx); static rtx expand_compound_operation (rtx); static const_rtx expand_field_assignment (const_rtx); -static rtx make_extraction (machine_mode, rtx, HOST_WIDE_INT, - rtx, unsigned HOST_WIDE_INT, int, int, int); +static rtx make_extraction (machine_mode, rtx, HOST_WIDE_INT, rtx, + unsigned HOST_WIDE_INT, bool, bool, bool); static int get_pos_from_mask (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT *); static rtx canon_reg_for_combine (rtx, rtx); static rtx force_int_to_mode (rtx, scalar_int_mode, scalar_int_mode, - scalar_int_mode, unsigned HOST_WIDE_INT, int); + scalar_int_mode, unsigned HOST_WIDE_INT, bool); static rtx force_to_mode (rtx, machine_mode, - unsigned HOST_WIDE_INT, int); + unsigned HOST_WIDE_INT, bool); static rtx if_then_else_cond (rtx, rtx *, rtx *); static rtx known_cond (rtx, enum rtx_code, rtx, rtx); -static int rtx_equal_for_field_assignment_p (rtx, rtx, bool = false); +static bool rtx_equal_for_field_assignment_p (rtx, rtx, bool = false); static rtx make_field_assignment (rtx); static rtx apply_distributive_law (rtx); static rtx distribute_and_simplify_rtx (rtx, int); @@ -452,8 +453,8 @@ static rtx simplify_and_const_int_1 (scalar_int_mode, rtx, unsigned HOST_WIDE_INT); static rtx simplify_and_const_int (rtx, scalar_int_mode, rtx, unsigned HOST_WIDE_INT); -static int merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code, - HOST_WIDE_INT, machine_mode, int *); +static bool merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code, + HOST_WIDE_INT, machine_mode, bool *); static rtx simplify_shift_const_1 (enum rtx_code, machine_mode, rtx, int); static rtx simplify_shift_const (rtx, enum rtx_code, machine_mode, rtx, int); @@ -467,13 +468,14 @@ static void record_value_for_reg (rtx, rtx_insn *, rtx); static void check_promoted_subreg (rtx_insn *, rtx); static void record_dead_and_set_regs_1 (rtx, const_rtx, void *); static void record_dead_and_set_regs (rtx_insn *); -static int get_last_value_validate (rtx *, rtx_insn *, int, int); +static bool get_last_value_validate (rtx *, rtx_insn *, int, bool); static rtx get_last_value (const_rtx); static void reg_dead_at_p_1 (rtx, const_rtx, void *); -static int reg_dead_at_p (rtx, rtx_insn *); +static bool reg_dead_at_p (rtx, rtx_insn *); static void move_deaths (rtx, rtx, int, rtx_insn *, rtx *); -static int reg_bitfield_target_p (rtx, rtx); -static void distribute_notes (rtx, rtx_insn *, rtx_insn *, rtx_insn *, rtx, rtx, rtx); +static bool reg_bitfield_target_p (rtx, rtx); +static void distribute_notes (rtx, rtx_insn *, rtx_insn *, rtx_insn *, + rtx, rtx, rtx); static void distribute_links (struct insn_link *); static void mark_used_regs_combine (rtx); static void record_promoted_value (rtx_insn *, rtx); @@ -907,7 +909,7 @@ combine_validate_cost (rtx_insn *i0, rtx_insn *i1, rtx_insn *i2, rtx_insn *i3, /* Disallow this combination if both new_cost and old_cost are greater than zero, and new_cost is greater than old cost. */ - int reject = old_cost > 0 && new_cost > old_cost; + bool reject = old_cost > 0 && new_cost > old_cost; if (dump_file) { @@ -1113,7 +1115,7 @@ insn_a_feeds_b (rtx_insn *a, rtx_insn *b) Return nonzero if the CFG was changed (e.g. if the combiner has turned an indirect jump instruction into a direct jump). */ -static int +static bool combine_instructions (rtx_insn *f, unsigned int nregs) { rtx_insn *insn, *next; @@ -1121,12 +1123,12 @@ combine_instructions (rtx_insn *f, unsigned int nregs) rtx_insn *first; basic_block last_bb; - int new_direct_jump_p = 0; + bool new_direct_jump_p = false; for (first = f; first && !NONDEBUG_INSN_P (first); ) first = NEXT_INSN (first); if (!first) - return 0; + return false; combine_attempts = 0; combine_merges = 0; @@ -1432,8 +1434,11 @@ retry: default_rtl_profile (); clear_bb_flags (); - new_direct_jump_p |= purge_all_dead_edges (); - new_direct_jump_p |= delete_noop_moves (); + + if (purge_all_dead_edges ()) + new_direct_jump_p = true; + if (delete_noop_moves ()) + new_direct_jump_p = true; /* Clean up. */ obstack_free (&insn_link_obstack, NULL); @@ -1718,13 +1723,13 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data) combined into the merger of INSN and I3. The order is PRED, PRED2, INSN, SUCC, SUCC2, I3. - Return 0 if the combination is not allowed for any reason. + Return false if the combination is not allowed for any reason. If the combination is allowed, *PDEST will be set to the single destination of INSN and *PSRC to the single source, and this function - will return 1. */ + will return true. */ -static int +static bool can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, rtx_insn *pred2 ATTRIBUTE_UNUSED, rtx_insn *succ, rtx_insn *succ2, rtx *pdest, rtx *psrc) @@ -1813,7 +1818,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, ? reg_set_between_p (XEXP (elt, 0), PREV_INSN (insn), i3) : regno >= FIRST_PSEUDO_REGISTER)) - return 0; + return false; } while (--i >= 0); } @@ -1834,14 +1839,14 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, /* If we have already found a SET, this is a second one and so we cannot combine with this insn. */ if (set) - return 0; + return false; set = elt; break; default: /* Anything else means we can't combine. */ - return 0; + return false; } } @@ -1849,13 +1854,13 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs, so don't do anything with it. */ || GET_CODE (SET_SRC (set)) == ASM_OPERANDS) - return 0; + return false; } else - return 0; + return false; if (set == 0) - return 0; + return false; /* The simplification in expand_field_assignment may call back to get_last_value, so set safe guard here. */ @@ -1871,7 +1876,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, should be harmless. */ if (REG_P (dest) && REG_USERVAR_P (dest) && HARD_REGISTER_P (dest) && extract_asm_operands (PATTERN (i3))) - return 0; + return false; /* Don't eliminate a store in the stack pointer. */ if (dest == stack_pointer_rtx @@ -1931,7 +1936,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, Exception: if source is a constant, moving it later can't hurt. Accept that as a special case. */ || (DF_INSN_LUID (insn) < last_call_luid && ! CONSTANT_P (src))) - return 0; + return false; /* DEST must be a REG. */ if (REG_P (dest)) @@ -1958,10 +1963,10 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, || (REGNO (src) < FIRST_PSEUDO_REGISTER && !targetm.hard_regno_mode_ok (REGNO (src), GET_MODE (src))))) - return 0; + return false; } else - return 0; + return false; if (GET_CODE (PATTERN (i3)) == PARALLEL) @@ -1981,7 +1986,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, || REGNO (reg) >= FIRST_PSEUDO_REGISTER || !fixed_regs[REGNO (reg)]) if (reg_overlap_mentioned_p (reg, src)) - return 0; + return false; } /* If INSN contains anything volatile, or is an `asm' (whether volatile @@ -1991,9 +1996,9 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, { /* Make sure neither succ nor succ2 contains a volatile reference. */ if (succ2 != 0 && volatile_refs_p (PATTERN (succ2))) - return 0; + return false; if (succ != 0 && volatile_refs_p (PATTERN (succ))) - return 0; + return false; /* We'll check insns between INSN and I3 below. */ } @@ -2002,7 +2007,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, if (GET_CODE (src) == ASM_OPERANDS && REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER) - return 0; + return false; /* If INSN contains volatile references (specifically volatile MEMs), we cannot combine across any other volatile references. @@ -2015,7 +2020,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p)) if (INSN_P (p) && p != succ && p != succ2 && is_volatile_p (PATTERN (p))) - return 0; + return false; /* If INSN contains an autoincrement or autodecrement, make sure that register is not used between there and I3, and not already used in @@ -2038,7 +2043,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, || (succ2 != NULL_RTX && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (succ2))) || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3)))) - return 0; + return false; /* If we get here, we have passed all the tests and the combination is to be allowed. */ @@ -2046,7 +2051,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, *pdest = dest; *psrc = src; - return 1; + return true; } /* LOC is the location within I3 that contains its pattern or the component @@ -2085,11 +2090,11 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED, we place a register that is both set and used within I3. If more than one such register is detected, we fail. - Return 1 if the combination is valid, zero otherwise. */ + Return true if the combination is valid, false otherwise. */ -static int +static bool combinable_i3pat (rtx_insn *i3, rtx *loc, rtx i2dest, rtx i1dest, rtx i0dest, - int i1_not_in_src, int i0_not_in_src, rtx *pi3dest_killed) + bool i1_not_in_src, bool i0_not_in_src, rtx *pi3dest_killed) { rtx x = *loc; @@ -2135,7 +2140,7 @@ combinable_i3pat (rtx_insn *i3, rtx *loc, rtx i2dest, rtx i1dest, rtx i0dest, GET_MODE (inner_dest))) || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)) || (i0_not_in_src && reg_overlap_mentioned_p (i0dest, src))) - return 0; + return false; /* If DEST is used in I3, it is being killed in this insn, so record that for later. We have to consider paradoxical @@ -2159,7 +2164,7 @@ combinable_i3pat (rtx_insn *i3, rtx *loc, rtx i2dest, rtx i1dest, rtx i0dest, && REGNO (subdest) != STACK_POINTER_REGNUM) { if (*pi3dest_killed) - return 0; + return false; *pi3dest_killed = subdest; } @@ -2172,22 +2177,22 @@ combinable_i3pat (rtx_insn *i3, rtx *loc, rtx i2dest, rtx i1dest, rtx i0dest, for (i = 0; i < XVECLEN (x, 0); i++) if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest, i0dest, i1_not_in_src, i0_not_in_src, pi3dest_killed)) - return 0; + return false; } - return 1; + return true; } -/* Return 1 if X is an arithmetic expression that contains a multiplication +/* Return true if X is an arithmetic expression that contains a multiplication and division. We don't count multiplications by powers of two here. */ -static int +static bool contains_muldiv (rtx x) { switch (GET_CODE (x)) { case MOD: case DIV: case UMOD: case UDIV: - return 1; + return true; case MULT: return ! (CONST_INT_P (XEXP (x, 1)) @@ -2200,15 +2205,15 @@ contains_muldiv (rtx x) if (UNARY_P (x)) return contains_muldiv (XEXP (x, 0)); - return 0; + return false; } } -/* Determine whether INSN can be used in a combination. Return nonzero if +/* Determine whether INSN can be used in a combination. Return true if not. This is used in try_combine to detect early some cases where we can't perform combinations. */ -static int +static bool cant_combine_insn_p (rtx_insn *insn) { rtx set; @@ -2218,7 +2223,7 @@ cant_combine_insn_p (rtx_insn *insn) This can occur when flow deletes an insn that it has merged into an auto-increment address. */ if (!NONDEBUG_INSN_P (insn)) - return 1; + return true; /* Never combine loads and stores involving hard regs that are likely to be spilled. The register allocator can usually handle such @@ -2229,7 +2234,7 @@ cant_combine_insn_p (rtx_insn *insn) set = single_set (insn); if (! set) - return 0; + return false; src = SET_SRC (set); dest = SET_DEST (set); if (GET_CODE (src) == SUBREG) @@ -2247,9 +2252,9 @@ cant_combine_insn_p (rtx_insn *insn) || (HARD_REGISTER_P (dest) && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dest)) && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dest)))))) - return 1; + return true; - return 0; + return false; } struct likely_spilled_retval_info @@ -2284,12 +2289,12 @@ likely_spilled_retval_1 (rtx x, const_rtx set, void *data) info->mask &= ~new_mask; } -/* Return nonzero iff part of the return value is live during INSN, and +/* Return true iff part of the return value is live during INSN, and it is likely spilled. This can happen when more than one insn is needed to copy the return value, e.g. when we consider to combine into the second copy insn for a complex value. */ -static int +static bool likely_spilled_retval_p (rtx_insn *insn) { rtx_insn *use = BB_END (this_basic_block); @@ -2303,14 +2308,14 @@ likely_spilled_retval_p (rtx_insn *insn) struct likely_spilled_retval_info info; if (!NONJUMP_INSN_P (use) || GET_CODE (PATTERN (use)) != USE || insn == use) - return 0; + return false; reg = XEXP (PATTERN (use), 0); if (!REG_P (reg) || !targetm.calls.function_value_regno_p (REGNO (reg))) - return 0; + return false; regno = REGNO (reg); nregs = REG_NREGS (reg); if (nregs == 1) - return 0; + return false; mask = (2U << (nregs - 1)) - 1; /* Disregard parts of the return value that are set later. */ @@ -2329,9 +2334,9 @@ likely_spilled_retval_p (rtx_insn *insn) { if ((mask & 1 << nregs) && targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno + nregs))) - return 1; + return true; } while (nregs--); - return 0; + return false; } /* Adjust INSN after we made a change to its destination. @@ -2366,9 +2371,9 @@ adjust_for_new_dest (rtx_insn *insn) } /* Return TRUE if combine can reuse reg X in mode MODE. - ADDED_SETS is nonzero if the original set is still required. */ + ADDED_SETS is trueif the original set is still required. */ static bool -can_change_dest_mode (rtx x, int added_sets, machine_mode mode) +can_change_dest_mode (rtx x, bool added_sets, machine_mode mode) { unsigned int regno; @@ -2509,7 +2514,7 @@ count_auto_inc (rtx, rtx, rtx, rtx, rtx, void *arg) If we did the combination, return the insn at which combine should resume scanning. - Set NEW_DIRECT_JUMP_P to a nonzero value if try_combine creates a + Set NEW_DIRECT_JUMP_P to true if try_combine creates a new direct jump instruction. LAST_COMBINED_INSN is either I3, or some insn after I3 that has @@ -2518,15 +2523,15 @@ count_auto_inc (rtx, rtx, rtx, rtx, rtx, void *arg) static rtx_insn * try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, - int *new_direct_jump_p, rtx_insn *last_combined_insn) + bool *new_direct_jump_p, rtx_insn *last_combined_insn) { /* New patterns for I3 and I2, respectively. */ rtx newpat, newi2pat = 0; rtvec newpat_vec_with_clobbers = 0; - int substed_i2 = 0, substed_i1 = 0, substed_i0 = 0; + bool substed_i2 = false, substed_i1 = false, substed_i0 = false; /* Indicates need to preserve SET in I0, I1 or I2 in I3 if it is not dead. */ - int added_sets_0, added_sets_1, added_sets_2; + bool added_sets_0, added_sets_1, added_sets_2; /* Total number of SETs to put into I3. */ int total_sets; /* Nonzero if I2's or I1's body now appears in I3. */ @@ -2546,19 +2551,20 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, /* The PATTERNs of I0, I1, and I2, or a copy of them in certain cases. */ rtx i0pat = 0, i1pat = 0, i2pat = 0; /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC. */ - int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0; - int i0dest_in_i0src = 0, i1dest_in_i0src = 0, i2dest_in_i0src = 0; - int i2dest_killed = 0, i1dest_killed = 0, i0dest_killed = 0; - int i1_feeds_i2_n = 0, i0_feeds_i2_n = 0, i0_feeds_i1_n = 0; + bool i2dest_in_i2src = false, i1dest_in_i1src = false; + bool i2dest_in_i1src = false, i0dest_in_i0src = false; + bool i1dest_in_i0src = false, i2dest_in_i0src = false;; + bool i2dest_killed = false, i1dest_killed = false, i0dest_killed = false; + bool i1_feeds_i2_n = false, i0_feeds_i2_n = false, i0_feeds_i1_n = false; /* Notes that must be added to REG_NOTES in I3 and I2. */ rtx new_i3_notes, new_i2_notes; /* Notes that we substituted I3 into I2 instead of the normal case. */ - int i3_subst_into_i2 = 0; + bool i3_subst_into_i2 = false; /* Notes that I1, I2 or I3 is a MULT operation. */ - int have_mult = 0; - int swap_i2i3 = 0; - int split_i2i3 = 0; - int changed_i3_dest = 0; + bool have_mult = false; + bool swap_i2i3 = false; + bool split_i2i3 = false; + bool changed_i3_dest = false; bool i2_was_move = false, i3_was_move = false; int n_auto_inc = 0; @@ -2761,7 +2767,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, subst_insn = i3; subst_low_luid = DF_INSN_LUID (i2); - added_sets_2 = added_sets_1 = added_sets_0 = 0; + added_sets_2 = added_sets_1 = added_sets_0 = false; i2src = SET_SRC (XVECEXP (p2, 0, i)); i2dest = SET_DEST (XVECEXP (p2, 0, i)); i2dest_killed = dead_or_set_p (i2, i2dest); @@ -2771,7 +2777,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, the pattern. Everything was set up above. */ SUBST (SET_DEST (XVECEXP (p2, 0, i)), SET_DEST (PATTERN (i3))); newpat = p2; - i3_subst_into_i2 = 1; + i3_subst_into_i2 = true; goto validate_replacement; } } @@ -2843,7 +2849,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, combine_merges++; subst_insn = i3; subst_low_luid = DF_INSN_LUID (i2); - added_sets_2 = added_sets_1 = added_sets_0 = 0; + added_sets_2 = added_sets_1 = added_sets_0 = false; i2dest = temp_dest; i2dest_killed = dead_or_set_p (i2, i2dest); @@ -2856,7 +2862,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, newpat = PATTERN (i2); /* The dest of I3 has been replaced with the dest of I2. */ - changed_i3_dest = 1; + changed_i3_dest = true; goto validate_replacement; } } @@ -3022,7 +3028,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, || (i0 != 0 && GET_CODE (i0src) == MULT) || (GET_CODE (PATTERN (i3)) == SET && GET_CODE (SET_SRC (PATTERN (i3))) == MULT)) - have_mult = 1; + have_mult = true; /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd. We used to do this EXCEPT in one case: I3 has a post-inc in an @@ -3069,7 +3075,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, added_sets_1 = !(dead_or_set_p (i3, i1dest) || (i1_feeds_i2_n && dead_or_set_p (i2, i1dest))); else - added_sets_1 = 0; + added_sets_1 = false; if (i0) added_sets_0 = !(dead_or_set_p (i3, i0dest) @@ -3077,7 +3083,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n)) && dead_or_set_p (i2, i0dest))); else - added_sets_0 = 0; + added_sets_0 = false; /* We are about to copy insns for the case where they need to be kept around. Check that they can be copied in the merged instruction. */ @@ -3282,11 +3288,11 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, if (i1) { subst_low_luid = DF_INSN_LUID (i1); - i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0, 0); + i1src = subst (i1src, pc_rtx, pc_rtx, false, false, false); } subst_low_luid = DF_INSN_LUID (i2); - i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0, 0); + i2src = subst (i2src, pc_rtx, pc_rtx, false, false, false); } n_occurrences = 0; /* `subst' counts here */ @@ -3297,11 +3303,11 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, self-referential RTL when we will be substituting I1SRC for I1DEST later. Likewise if I0 feeds into I2, either directly or indirectly through I1, and I0DEST is in I0SRC. */ - newpat = subst (PATTERN (i3), i2dest, i2src, 0, 0, + newpat = subst (PATTERN (i3), i2dest, i2src, false, false, (i1_feeds_i2_n && i1dest_in_i1src) || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n)) && i0dest_in_i0src)); - substed_i2 = 1; + substed_i2 = true; /* Record whether I2's body now appears within I3's body. */ i2_is_used = n_occurrences; @@ -3316,7 +3322,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, above (see detailed comments there) that ensures I1DEST isn't mentioned in any SETs in NEWPAT that are field assignments. */ if (!combinable_i3pat (NULL, &newpat, i1dest, NULL_RTX, NULL_RTX, - 0, 0, 0)) + false, false, 0)) { undo_all (); return 0; @@ -3334,9 +3340,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, copy of I1SRC each time we substitute it, in order to avoid creating self-referential RTL when we will be substituting I0SRC for I0DEST later. */ - newpat = subst (newpat, i1dest, i1src, 0, 0, + newpat = subst (newpat, i1dest, i1src, false, false, i0_feeds_i1_n && i0dest_in_i0src); - substed_i1 = 1; + substed_i1 = true; /* Record whether I1's body now appears within I3's body. */ i1_is_used = n_occurrences; @@ -3347,7 +3353,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, if (i0 && GET_CODE (newpat) != CLOBBER) { if (!combinable_i3pat (NULL, &newpat, i0dest, NULL_RTX, NULL_RTX, - 0, 0, 0)) + false, false, 0)) { undo_all (); return 0; @@ -3364,8 +3370,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, n_occurrences = 0; subst_low_luid = DF_INSN_LUID (i0); - newpat = subst (newpat, i0dest, i0src, 0, 0, 0); - substed_i0 = 1; + newpat = subst (newpat, i0dest, i0src, false, false, false); + substed_i0 = true; } if (n_auto_inc) @@ -3387,13 +3393,11 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0 && i2_is_used + added_sets_2 > 1) || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0 - && (i1_is_used + added_sets_1 + (added_sets_2 && i1_feeds_i2_n) - > 1)) + && (i1_is_used + added_sets_1 + (added_sets_2 && i1_feeds_i2_n) > 1)) || (i0 != 0 && FIND_REG_INC_NOTE (i0, NULL_RTX) != 0 && (n_occurrences + added_sets_0 + (added_sets_1 && i0_feeds_i1_n) - + (added_sets_2 && i0_feeds_i2_n) - > 1)) + + (added_sets_2 && i0_feeds_i2_n) > 1)) /* Fail if we tried to make a new register. */ || max_reg_num () != maxreg /* Fail if we couldn't do something and have a CLOBBER. */ @@ -3440,7 +3444,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, { rtx t = i1pat; if (i0_feeds_i1_n) - t = subst (t, i0dest, i0src_copy ? i0src_copy : i0src, 0, 0, 0); + t = subst (t, i0dest, i0src_copy ? i0src_copy : i0src, + false, false, false); XVECEXP (newpat, 0, --total_sets) = t; } @@ -3448,10 +3453,11 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, { rtx t = i2pat; if (i1_feeds_i2_n) - t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0, 0, + t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, false, false, i0_feeds_i1_n && i0dest_in_i0src); if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n) - t = subst (t, i0dest, i0src_copy2 ? i0src_copy2 : i0src, 0, 0, 0); + t = subst (t, i0dest, i0src_copy2 ? i0src_copy2 : i0src, + false, false, false); XVECEXP (newpat, 0, --total_sets) = t; } @@ -3531,7 +3537,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); if (insn_code_number >= 0) - changed_i3_dest = 1; + changed_i3_dest = true; } } @@ -4070,7 +4076,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, } if (insn_code_number >= 0) - split_i2i3 = 1; + split_i2i3 = true; } } @@ -4845,7 +4851,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src) rtx *split; unsigned HOST_WIDE_INT len = 0; HOST_WIDE_INT pos = 0; - int unsignedp = 0; + bool unsignedp = false; rtx inner = NULL_RTX; scalar_int_mode mode, inner_mode; @@ -5075,7 +5081,8 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src) { rtx extraction = make_extraction (GET_MODE (SET_DEST (x)), XEXP (SET_SRC (x), 0), - pos, NULL_RTX, 1, 1, 0, 0); + pos, NULL_RTX, 1, + true, false, false); if (extraction != 0) { SUBST (SET_SRC (x), extraction); @@ -5119,7 +5126,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src) pos = 0; len = GET_MODE_PRECISION (inner_mode); - unsignedp = 0; + unsignedp = false; break; case SIGN_EXTRACT: @@ -5317,15 +5324,15 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src) `n_occurrences' is incremented each time FROM is replaced. - IN_DEST is nonzero if we are processing the SET_DEST of a SET. + IN_DEST is true if we are processing the SET_DEST of a SET. - IN_COND is nonzero if we are at the top level of a condition. + IN_COND is true if we are at the top level of a condition. - UNIQUE_COPY is nonzero if each substitution must be unique. We do this + UNIQUE_COPY is true if each substitution must be unique. We do this by copying if `n_occurrences' is nonzero. */ static rtx -subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy) +subst (rtx x, rtx from, rtx to, bool in_dest, bool in_cond, bool unique_copy) { enum rtx_code code = GET_CODE (x); machine_mode op0_mode = VOIDmode; @@ -5391,7 +5398,7 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy) && GET_CODE (XVECEXP (x, 0, 0)) == SET && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS) { - new_rtx = subst (XVECEXP (x, 0, 0), from, to, 0, 0, unique_copy); + new_rtx = subst (XVECEXP (x, 0, 0), from, to, false, false, unique_copy); /* If this substitution failed, this whole thing fails. */ if (GET_CODE (new_rtx) == CLOBBER @@ -5406,7 +5413,7 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy) if (!REG_P (dest) && GET_CODE (dest) != PC) { - new_rtx = subst (dest, from, to, 0, 0, unique_copy); + new_rtx = subst (dest, from, to, false, false, unique_copy); /* If this substitution failed, this whole thing fails. */ if (GET_CODE (new_rtx) == CLOBBER @@ -5464,8 +5471,8 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy) } else { - new_rtx = subst (XVECEXP (x, i, j), from, to, 0, 0, - unique_copy); + new_rtx = subst (XVECEXP (x, i, j), from, to, + false, false, unique_copy); /* If this substitution failed, this whole thing fails. */ @@ -5659,13 +5666,12 @@ maybe_swap_commutative_operands (rtx x) outer level; call `subst' to simplify recursively. Return the new expression. - OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is nonzero - if we are inside a SET_DEST. IN_COND is nonzero if we are at the top level + OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is true + if we are inside a SET_DEST. IN_COND is true if we are at the top level of a condition. */ static rtx -combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, - int in_cond) +combine_simplify_rtx (rtx x, machine_mode op0_mode, bool in_dest, bool in_cond) { enum rtx_code code = GET_CODE (x); machine_mode mode = GET_MODE (x); @@ -5764,8 +5770,10 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, false arms to store-flag values. Be careful to use copy_rtx here since true_rtx or false_rtx might share RTL with x as a result of the if_then_else_cond call above. */ - true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0, 0); - false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0, 0); + true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, + false, false, false); + false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, + false, false, false); /* If true_rtx and false_rtx are not general_operands, an if_then_else is unlikely to be simpler. */ @@ -5981,7 +5989,7 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, if (HWI_COMPUTABLE_MODE_P (mode)) SUBST (XEXP (x, 0), force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)), - GET_MODE_MASK (mode), 0)); + GET_MODE_MASK (mode), false)); /* We can truncate a constant value and return it. */ { @@ -6076,7 +6084,7 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, { /* Try to simplify the expression further. */ rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1)); - temp = combine_simplify_rtx (tor, VOIDmode, in_dest, 0); + temp = combine_simplify_rtx (tor, VOIDmode, in_dest, false); /* If we could, great. If not, do not go ahead with the IOR replacement, since PLUS appears in many special purpose @@ -6367,9 +6375,7 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, force_to_mode (XEXP (x, 1), GET_MODE (XEXP (x, 1)), (HOST_WIDE_INT_1U << exact_log2 (GET_MODE_UNIT_BITSIZE - (GET_MODE (x)))) - - 1, - 0)); + (GET_MODE (x)))) - 1, false)); break; case VEC_SELECT: { @@ -6402,7 +6408,7 @@ simplify_if_then_else (rtx x) rtx true_rtx = XEXP (x, 1); rtx false_rtx = XEXP (x, 2); enum rtx_code true_code = GET_CODE (cond); - int comparison_p = COMPARISON_P (cond); + bool comparison_p = COMPARISON_P (cond); rtx temp; int i; enum rtx_code false_code; @@ -6433,13 +6439,13 @@ simplify_if_then_else (rtx x) rtx from = XEXP (cond, 0); rtx true_val = XEXP (cond, 1); rtx false_val = true_val; - int swapped = 0; + bool swapped = false; /* If FALSE_CODE is EQ, swap the codes and arms. */ if (false_code == EQ) { - swapped = 1, true_code = EQ, false_code = NE; + swapped = true, true_code = EQ, false_code = NE; std::swap (true_rtx, false_rtx); } @@ -6474,11 +6480,11 @@ simplify_if_then_else (rtx x) if (reg_mentioned_p (from, true_rtx)) true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code, from, true_val), - pc_rtx, pc_rtx, 0, 0, 0); + pc_rtx, pc_rtx, false, false, false); if (reg_mentioned_p (from, false_rtx)) false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code, from, false_val), - pc_rtx, pc_rtx, 0, 0, 0); + pc_rtx, pc_rtx, false, false, false); SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx); SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx); @@ -6705,11 +6711,11 @@ simplify_if_then_else (rtx x) cm = GET_MODE (c1); temp = subst (simplify_gen_relational (true_code, cm, VOIDmode, cond_op0, cond_op1), - pc_rtx, pc_rtx, 0, 0, 0); + pc_rtx, pc_rtx, false, false, false); temp = simplify_gen_binary (MULT, cm, temp, simplify_gen_binary (MULT, cm, c1, const_true_rtx)); - temp = subst (temp, pc_rtx, pc_rtx, 0, 0, 0); + temp = subst (temp, pc_rtx, pc_rtx, false, false, false); temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp); if (extend_op != UNKNOWN) @@ -6781,7 +6787,7 @@ simplify_set (rtx x) if (GET_MODE_CLASS (mode) == MODE_INT && HWI_COMPUTABLE_MODE_P (mode)) { - src = force_to_mode (src, mode, HOST_WIDE_INT_M1U, 0); + src = force_to_mode (src, mode, HOST_WIDE_INT_M1U, false); SUBST (SET_SRC (x), src); } @@ -6796,7 +6802,7 @@ simplify_set (rtx x) enum rtx_code old_code = GET_CODE (*cc_use); enum rtx_code new_code; rtx op0, op1, tmp; - int other_changed = 0; + bool other_changed = false; rtx inner_compare = NULL_RTX; machine_mode compare_mode = GET_MODE (dest); @@ -6881,7 +6887,7 @@ simplify_set (rtx x) SUBST (SET_DEST (x), new_dest); SUBST (XEXP (*cc_use, 0), new_dest); - other_changed = 1; + other_changed = true; dest = new_dest; } @@ -6892,13 +6898,13 @@ simplify_set (rtx x) undobuf.other_insn. */ if (new_code != old_code) { - int other_changed_previously = other_changed; + bool other_changed_previously = other_changed; unsigned HOST_WIDE_INT mask; rtx old_cc_use = *cc_use; SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use), dest, const0_rtx)); - other_changed = 1; + other_changed = true; /* If the only change we made was to change an EQ into an NE or vice versa, OP0 has only one bit that might be nonzero, and OP1 @@ -6918,7 +6924,7 @@ simplify_set (rtx x) && ! check_asm_operands (pat))) { *cc_use = old_cc_use; - other_changed = 0; + other_changed = false; op0 = simplify_gen_binary (XOR, GET_MODE (op0), op0, gen_int_mode (mask, @@ -7160,7 +7166,7 @@ static rtx expand_compound_operation (rtx x) { unsigned HOST_WIDE_INT pos = 0, len; - int unsignedp = 0; + bool unsignedp = false; unsigned int modewidth; rtx tem; scalar_int_mode inner_mode; @@ -7168,7 +7174,7 @@ expand_compound_operation (rtx x) switch (GET_CODE (x)) { case ZERO_EXTEND: - unsignedp = 1; + unsignedp = true; /* FALLTHRU */ case SIGN_EXTEND: /* We can't necessarily use a const_int for a multiword mode; @@ -7209,7 +7215,7 @@ expand_compound_operation (rtx x) break; case ZERO_EXTRACT: - unsignedp = 1; + unsignedp = true; /* fall through */ @@ -7495,14 +7501,14 @@ expand_field_assignment (const_rtx x) it is an RTX that represents the (variable) starting position; otherwise, POS is the (constant) starting bit position. Both are counted from the LSB. - UNSIGNEDP is nonzero for an unsigned reference and zero for a signed one. + UNSIGNEDP is true for an unsigned reference and zero for a signed one. - IN_DEST is nonzero if this is a reference in the destination of a SET. + IN_DEST is true if this is a reference in the destination of a SET. This is used when a ZERO_ or SIGN_EXTRACT isn't needed. If nonzero, a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will be used. - IN_COMPARE is nonzero if we are in a COMPARE. This means that a + IN_COMPARE is true if we are in a COMPARE. This means that a ZERO_EXTRACT should be built even for bits starting at bit 0. MODE is the desired mode of the result (if IN_DEST == 0). @@ -7512,8 +7518,8 @@ expand_field_assignment (const_rtx x) static rtx make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, - rtx pos_rtx, unsigned HOST_WIDE_INT len, int unsignedp, - int in_dest, int in_compare) + rtx pos_rtx, unsigned HOST_WIDE_INT len, bool unsignedp, + bool in_dest, bool in_compare) { /* This mode describes the size of the storage area to fetch the overall value from. Within that, we @@ -7675,7 +7681,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, new_rtx = force_to_mode (inner, tmode, len >= HOST_BITS_PER_WIDE_INT ? HOST_WIDE_INT_M1U - : (HOST_WIDE_INT_1U << len) - 1, 0); + : (HOST_WIDE_INT_1U << len) - 1, false); /* If this extraction is going into the destination of a SET, make a STRICT_LOW_PART unless we made a MEM. */ @@ -7868,8 +7874,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, || len + orig_pos >= HOST_BITS_PER_WIDE_INT ? HOST_WIDE_INT_M1U : (((HOST_WIDE_INT_1U << len) - 1) - << orig_pos), - 0); + << orig_pos), false); } /* Adjust mode of POS_RTX, if needed. If we want a wider mode, we @@ -8103,7 +8108,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, { new_rtx = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code); new_rtx = make_extraction (mode, new_rtx, 0, XEXP (XEXP (x, 0), 1), - i, 1, 0, in_code == COMPARE); + i, true, false, in_code == COMPARE); } /* Same as previous, but for (subreg (lshiftrt ...)) in first op. */ @@ -8118,7 +8123,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, new_rtx = make_compound_operation (XEXP (inner_x0, 0), next_code); new_rtx = make_extraction (inner_mode, new_rtx, 0, XEXP (inner_x0, 1), - i, 1, 0, in_code == COMPARE); + i, true, false, in_code == COMPARE); /* If we narrowed the mode when dropping the subreg, then we lose. */ if (GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (mode)) @@ -8129,8 +8134,8 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, if (!new_rtx && i >= 0) { new_rtx = make_compound_operation (XEXP (x, 0), next_code); - new_rtx = make_extraction (mode, new_rtx, 0, NULL_RTX, i, 1, - 0, in_code == COMPARE); + new_rtx = make_extraction (mode, new_rtx, 0, NULL_RTX, i, + true, false, in_code == COMPARE); } } /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)). */ @@ -8161,7 +8166,8 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, new_rtx = make_extraction (mode, new_rtx, (GET_MODE_PRECISION (mode) - INTVAL (XEXP (XEXP (x, 0), 1))), - NULL_RTX, i, 1, 0, in_code == COMPARE); + NULL_RTX, i, true, false, + in_code == COMPARE); } /* On machines without logical shifts, if the operand of the AND is @@ -8196,7 +8202,8 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, new_rtx = make_extraction (mode, make_compound_operation (XEXP (x, 0), next_code), - 0, NULL_RTX, i, 1, 0, in_code == COMPARE); + 0, NULL_RTX, i, + true, false, in_code == COMPARE); /* If we are in a comparison and this is an AND with a power of two, convert this into the appropriate bit extract. */ @@ -8206,7 +8213,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, new_rtx = make_extraction (mode, make_compound_operation (XEXP (x, 0), next_code), - i, NULL_RTX, 1, 1, 0, 1); + i, NULL_RTX, 1, true, false, true); /* If the one operand is a paradoxical subreg of a register or memory and the constant (limited to the smaller mode) has only zero bits where @@ -8232,7 +8239,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, { new_rtx = make_compound_operation (sub, next_code); new_rtx = make_extraction (mode, new_rtx, 0, 0, sub_width, - 1, 0, in_code == COMPARE); + true, false, in_code == COMPARE); } } } @@ -8273,7 +8280,8 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, new_rtx = make_extraction (mode, new_rtx, INTVAL (rhs) - INTVAL (XEXP (lhs, 1)), NULL_RTX, mode_width - INTVAL (rhs), - code == LSHIFTRT, 0, in_code == COMPARE); + code == LSHIFTRT, false, + in_code == COMPARE); break; } @@ -8293,7 +8301,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, new_rtx = make_extraction (mode, make_compound_operation (new_rtx, next_code), 0, NULL_RTX, mode_width - INTVAL (rhs), - code == LSHIFTRT, 0, in_code == COMPARE); + code == LSHIFTRT, false, in_code == COMPARE); break; @@ -8320,7 +8328,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, if (width > mode_width) width = mode_width; new_rtx = make_extraction (mode, new_rtx, 0, XEXP (inner, 1), - width, 1, 0, in_code == COMPARE); + width, true, false, in_code == COMPARE); break; } @@ -8354,7 +8362,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, && subreg_lowpart_p (x)) { rtx newer - = force_to_mode (tem, mode, HOST_WIDE_INT_M1U, 0); + = force_to_mode (tem, mode, HOST_WIDE_INT_M1U, false); /* If we have something other than a SUBREG, we might have done an expansion, so rerun ourselves. */ @@ -8628,16 +8636,16 @@ gen_lowpart_or_truncate (machine_mode mode, rtx x) Return a possibly simplified expression, but always convert X to MODE. If X is a CONST_INT, AND the CONST_INT with MASK. - If JUST_SELECT is nonzero, don't optimize by noticing that bits in MASK + If JUST_SELECT is true, don't optimize by noticing that bits in MASK are all off in X. This is used when X will be complemented, by either NOT, NEG, or XOR. */ static rtx force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask, - int just_select) + bool just_select) { enum rtx_code code = GET_CODE (x); - int next_select = just_select || code == XOR || code == NOT || code == NEG; + bool next_select = just_select || code == XOR || code == NOT || code == NEG; machine_mode op_mode; unsigned HOST_WIDE_INT nonzero; @@ -8724,10 +8732,10 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask, static rtx force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode, scalar_int_mode op_mode, unsigned HOST_WIDE_INT mask, - int just_select) + bool just_select) { enum rtx_code code = GET_CODE (x); - int next_select = just_select || code == XOR || code == NOT || code == NEG; + bool next_select = just_select || code == XOR || code == NOT || code == NEG; unsigned HOST_WIDE_INT fuller_mask; rtx op0, op1, temp; poly_int64 const_op0; @@ -8738,8 +8746,7 @@ force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode, if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1))) fuller_mask = HOST_WIDE_INT_M1U; else - fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1)) - - 1); + fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1)) - 1); switch (code) { @@ -9102,8 +9109,7 @@ force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode, <= GET_MODE_PRECISION (xmode) - (floor_log2 (mask) + 1)) && GET_CODE (XEXP (x, 0)) == ASHIFT && XEXP (XEXP (x, 0), 1) == XEXP (x, 1)) - return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask, - next_select); + return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask, next_select); break; @@ -9606,25 +9612,25 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val) /* See if X and Y are equal for the purposes of seeing if we can rewrite an assignment as a field assignment. */ -static int +static bool rtx_equal_for_field_assignment_p (rtx x, rtx y, bool widen_x) { if (widen_x && GET_MODE (x) != GET_MODE (y)) { if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (y))) - return 0; + return false; if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN) - return 0; + return false; x = adjust_address_nv (x, GET_MODE (y), byte_lowpart_offset (GET_MODE (y), GET_MODE (x))); } if (x == y || rtx_equal_p (x, y)) - return 1; + return true; if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y)) - return 0; + return false; /* Check for a paradoxical SUBREG of a MEM compared with the MEM. Note that all SUBREGs of MEM are paradoxical; otherwise they @@ -9633,20 +9639,20 @@ rtx_equal_for_field_assignment_p (rtx x, rtx y, bool widen_x) && MEM_P (SUBREG_REG (y)) && rtx_equal_p (SUBREG_REG (y), gen_lowpart (GET_MODE (SUBREG_REG (y)), x))) - return 1; + return true; if (MEM_P (y) && GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x)) && rtx_equal_p (SUBREG_REG (x), gen_lowpart (GET_MODE (SUBREG_REG (x)), y))) - return 1; + return true; /* We used to see if get_last_value of X and Y were the same but that's not correct. In one direction, we'll cause the assignment to have the wrong destination and in the case, we'll import a register into this insn that might have already have been dead. So fail if none of the above cases are true. */ - return 0; + return false; } /* See if X, a SET operation, can be rewritten as a bit-field assignment. @@ -9682,7 +9688,7 @@ make_field_assignment (rtx x) && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) { assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1), - 1, 1, 1, 0); + 1, true, true, false); if (assign != 0) return gen_rtx_SET (assign, const0_rtx); return x; @@ -9698,7 +9704,7 @@ make_field_assignment (rtx x) { assign = make_extraction (VOIDmode, dest, 0, XEXP (SUBREG_REG (XEXP (src, 0)), 1), - 1, 1, 1, 0); + 1, true, true, false); if (assign != 0) return gen_rtx_SET (assign, const0_rtx); return x; @@ -9711,7 +9717,7 @@ make_field_assignment (rtx x) && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1))) { assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1), - 1, 1, 1, 0); + 1, true, true, false); if (assign != 0) return gen_rtx_SET (assign, const1_rtx); return x; @@ -9815,7 +9821,8 @@ make_field_assignment (rtx x) || (c1 & nonzero_bits (other, mode)) != 0) return x; - assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0); + assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, + true, true, false); if (assign == 0) return x; @@ -9833,8 +9840,7 @@ make_field_assignment (rtx x) src = force_to_mode (src, new_mode, len >= HOST_BITS_PER_WIDE_INT ? HOST_WIDE_INT_M1U - : (HOST_WIDE_INT_1U << len) - 1, - 0); + : (HOST_WIDE_INT_1U << len) - 1, false); /* If SRC is masked by an AND that does not make a difference in the value being stored, strip it. */ @@ -10064,7 +10070,7 @@ simplify_and_const_int_1 (scalar_int_mode mode, rtx varop, CONSTOP are not significant and will never be examined. We must ensure that is the case by explicitly masking out those bits before returning. */ - varop = force_to_mode (varop, mode, constop, 0); + varop = force_to_mode (varop, mode, constop, false); /* If VAROP is a CLOBBER, we will fail so return it. */ if (GET_CODE (varop) == CLOBBER) @@ -10302,7 +10308,7 @@ reg_num_sign_bit_copies_for_combine (const_rtx x, scalar_int_mode xmode, implies that it must be called from a define_split. */ unsigned int -extended_count (const_rtx x, machine_mode mode, int unsignedp) +extended_count (const_rtx x, machine_mode mode, bool unsignedp) { if (nonzero_sign_valid == 0) return 0; @@ -10323,8 +10329,8 @@ extended_count (const_rtx x, machine_mode mode, int unsignedp) position. We would now like to also perform OP1 with constant CONST1 (with *POP0 being done last). - Return 1 if we can do the operation and update *POP0 and *PCONST0 with - the resulting operation. *PCOMP_P is set to 1 if we would need to + Return true if we can do the operation and update *POP0 and *PCONST0 with + the resulting operation. *PCOMP_P is set to true if we would need to complement the innermost operand, otherwise it is unchanged. MODE is the mode in which the operation will be done. No bits outside @@ -10336,10 +10342,12 @@ extended_count (const_rtx x, machine_mode mode, int unsignedp) result is simply *PCONST0. If the resulting operation cannot be expressed as one operation, we - return 0 and do not change *POP0, *PCONST0, and *PCOMP_P. */ + return false and do not change *POP0, *PCONST0, and *PCOMP_P. */ -static int -merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, HOST_WIDE_INT const1, machine_mode mode, int *pcomp_p) +static bool +merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, + enum rtx_code op1, HOST_WIDE_INT const1, + machine_mode mode, bool *pcomp_p) { enum rtx_code op0 = *pop0; HOST_WIDE_INT const0 = *pconst0; @@ -10355,7 +10363,7 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, if OP0 is SET. */ if (op1 == UNKNOWN || op0 == SET) - return 1; + return true; else if (op0 == UNKNOWN) op0 = op1, const0 = const1; @@ -10386,12 +10394,12 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, /* Otherwise, if either is a PLUS or NEG, we can't do anything. */ else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG) - return 0; + return false; /* If the two constants aren't the same, we can't do anything. The remaining six cases can all be done. */ else if (const0 != const1) - return 0; + return false; else switch (op0) @@ -10408,7 +10416,7 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, case XOR: if (op1 == AND) /* (a & b) ^ b == (~a) & b */ - op0 = AND, *pcomp_p = 1; + op0 = AND, *pcomp_p = true; else /* op1 == IOR */ /* (a | b) ^ b == a & ~b */ op0 = AND, const0 = ~const0; @@ -10420,7 +10428,7 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, op0 = SET; else /* op1 == XOR */ /* (a ^ b) & b) == (~a) & b */ - *pcomp_p = 1; + *pcomp_p = true; break; default: break; @@ -10445,7 +10453,7 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, if (op0 != UNKNOWN && op0 != NEG) *pconst0 = trunc_int_for_mode (const0, mode); - return 1; + return true; } /* A helper to simplify_shift_const_1 to determine the mode we can perform @@ -10524,7 +10532,7 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode, /* We form (outer_op (code varop count) (outer_const)). */ enum rtx_code outer_op = UNKNOWN; HOST_WIDE_INT outer_const = 0; - int complement_p = 0; + bool complement_p = false; rtx new_rtx, x; /* Make sure and truncate the "natural" shift on the way in. We don't @@ -12094,7 +12102,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) rtx inner_op1 = XEXP (op1, 0); HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1)); HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1)); - int changed = 0; + bool changed = false; if (paradoxical_subreg_p (inner_op0) && GET_CODE (inner_op1) == SUBREG @@ -12113,7 +12121,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) off the original sign bit. */ code = unsigned_condition (code); - changed = 1; + changed = true; } else if (c0 == c1) @@ -12124,7 +12132,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) op0 = gen_lowpart_or_truncate (tmode, inner_op0); op1 = gen_lowpart_or_truncate (tmode, inner_op1); code = unsigned_condition (code); - changed = 1; + changed = true; break; } @@ -12196,8 +12204,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) && HWI_COMPUTABLE_MODE_P (int_mode)) op0 = force_to_mode (op0, int_mode, HOST_WIDE_INT_1U - << (GET_MODE_PRECISION (int_mode) - 1), - 0); + << (GET_MODE_PRECISION (int_mode) - 1), false); if (COMPARISON_P (op0)) { @@ -13278,19 +13285,19 @@ record_value_for_reg (rtx reg, rtx_insn *insn, rtx value) rsp->last_set_label = label_tick; if (!insn || (value && rsp->last_set_table_tick >= label_tick_ebb_start)) - rsp->last_set_invalid = 1; + rsp->last_set_invalid = true; else - rsp->last_set_invalid = 0; + rsp->last_set_invalid = false; } /* The value being assigned might refer to X (like in "x++;"). In that case, we must replace it with (clobber (const_int 0)) to prevent infinite loops. */ rsp = ®_stat[regno]; - if (value && !get_last_value_validate (&value, insn, label_tick, 0)) + if (value && !get_last_value_validate (&value, insn, label_tick, false)) { value = copy_rtx (value); - if (!get_last_value_validate (&value, insn, label_tick, 1)) + if (!get_last_value_validate (&value, insn, label_tick, true)) value = 0; } @@ -13418,7 +13425,7 @@ record_dead_and_set_regs (rtx_insn *insn) It wouldn't help much anyway, since we rarely see this situation before RA. */ rsp = ®_stat[i]; - rsp->last_set_invalid = 1; + rsp->last_set_invalid = true; rsp->last_set = insn; rsp->last_set_value = 0; rsp->last_set_mode = VOIDmode; @@ -13603,15 +13610,15 @@ check_promoted_subreg (rtx_insn *insn, rtx x) /* Verify that all the registers and memory references mentioned in *LOC are still valid. *LOC was part of a value set in INSN when label_tick was - equal to TICK. Return 0 if some are not. If REPLACE is nonzero, replace - the invalid references with (clobber (const_int 0)) and return 1. This + equal to TICK. Return false if some are not. If REPLACE is true, replace + the invalid references with (clobber (const_int 0)) and return true. This replacement is useful because we often can get useful information about the form of a value (e.g., if it was produced by a shift that always produces -1 or 0) even though we don't know exactly what registers it was produced from. */ -static int -get_last_value_validate (rtx *loc, rtx_insn *insn, int tick, int replace) +static bool +get_last_value_validate (rtx *loc, rtx_insn *insn, int tick, bool replace) { rtx x = *loc; const char *fmt = GET_RTX_FORMAT (GET_CODE (x)); @@ -13644,7 +13651,7 @@ get_last_value_validate (rtx *loc, rtx_insn *insn, int tick, int replace) } } - return 1; + return true; } /* If this is a memory reference, make sure that there were no stores after it that might have clobbered the value. We don't have alias info, so we @@ -13674,14 +13681,14 @@ get_last_value_validate (rtx *loc, rtx_insn *insn, int tick, int replace) /* If x0 and x1 are identical then x is also valid. */ if (x0 == x1) - return 1; + return true; /* If x1 is identical to a subexpression of x0 then while checking x0, x1 has already been checked. Thus it is valid and so as x. */ if (ARITHMETIC_P (x0) && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1))) - return 1; + return true; /* If x0 is identical to a subexpression of x1 then x is valid iff the rest of x1 is valid. */ @@ -13693,19 +13700,18 @@ get_last_value_validate (rtx *loc, rtx_insn *insn, int tick, int replace) insn, tick, replace); } - if (get_last_value_validate (&XEXP (x, i), insn, tick, - replace) == 0) - return 0; + if (!get_last_value_validate (&XEXP (x, i), insn, tick, replace)) + return false; } else if (fmt[i] == 'E') for (j = 0; j < XVECLEN (x, i); j++) - if (get_last_value_validate (&XVECEXP (x, i, j), - insn, tick, replace) == 0) - return 0; + if (!get_last_value_validate (&XVECEXP (x, i, j), + insn, tick, replace)) + return false; } /* If we haven't found a reason for it to be invalid, it is valid. */ - return 1; + return true; } /* Get the last value assigned to X, if known. Some registers @@ -13767,14 +13773,16 @@ get_last_value (const_rtx x) return 0; /* If the value has all its registers valid, return it. */ - if (get_last_value_validate (&value, rsp->last_set, rsp->last_set_label, 0)) + if (get_last_value_validate (&value, rsp->last_set, + rsp->last_set_label, false)) return value; /* Otherwise, make a copy and replace any invalid register with (clobber (const_int 0)). If that fails for some reason, return 0. */ value = copy_rtx (value); - if (get_last_value_validate (&value, rsp->last_set, rsp->last_set_label, 1)) + if (get_last_value_validate (&value, rsp->last_set, + rsp->last_set_label, true)) return value; return 0; @@ -13806,7 +13814,7 @@ reg_dead_at_p_1 (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED) reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1; } -/* Return nonzero if REG is known to be dead at INSN. +/* Return true if REG is known to be dead at INSN. We scan backwards from INSN. If we hit a REG_DEAD note or a CLOBBER referencing REG, it is dead. If we hit a SET referencing REG, it is @@ -13814,7 +13822,7 @@ reg_dead_at_p_1 (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED) block we are in. Hard regs marked as being live in NEWPAT_USED_REGS must be assumed to be always live. */ -static int +static bool reg_dead_at_p (rtx reg, rtx_insn *insn) { basic_block block; @@ -13834,7 +13842,7 @@ reg_dead_at_p (rtx reg, rtx_insn *insn) { for (i = reg_dead_regno; i < reg_dead_endregno; i++) if (!fixed_regs[i] && TEST_HARD_REG_BIT (newpat_used_regs, i)) - return 0; + return false; } /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, or @@ -13845,14 +13853,14 @@ reg_dead_at_p (rtx reg, rtx_insn *insn) if (INSN_P (insn)) { if (find_regno_note (insn, REG_UNUSED, reg_dead_regno)) - return 1; + return true; note_stores (insn, reg_dead_at_p_1, NULL); if (reg_dead_flag) return reg_dead_flag == 1 ? 1 : 0; if (find_regno_note (insn, REG_DEAD, reg_dead_regno)) - return 1; + return true; } if (insn == BB_HEAD (block)) @@ -13864,9 +13872,9 @@ reg_dead_at_p (rtx reg, rtx_insn *insn) /* Look at live-in sets for the basic block that we were in. */ for (i = reg_dead_regno; i < reg_dead_endregno; i++) if (REGNO_REG_SET_P (df_get_live_in (block), i)) - return 0; + return false; - return 1; + return true; } /* Note hard registers in X that are used. */ @@ -14144,10 +14152,10 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn, } } -/* Return 1 if X is the target of a bit-field assignment in BODY, the +/* Return true if X is the target of a bit-field assignment in BODY, the pattern of an insn. X must be a REG. */ -static int +static bool reg_bitfield_target_p (rtx x, rtx body) { int i; @@ -14163,13 +14171,13 @@ reg_bitfield_target_p (rtx x, rtx body) else if (GET_CODE (dest) == STRICT_LOW_PART) target = SUBREG_REG (XEXP (dest, 0)); else - return 0; + return false; if (GET_CODE (target) == SUBREG) target = SUBREG_REG (target); if (!REG_P (target)) - return 0; + return false; tregno = REGNO (target), regno = REGNO (x); if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER) @@ -14184,9 +14192,9 @@ reg_bitfield_target_p (rtx x, rtx body) else if (GET_CODE (body) == PARALLEL) for (i = XVECLEN (body, 0) - 1; i >= 0; i--) if (reg_bitfield_target_p (x, XVECEXP (body, 0, i))) - return 1; + return true; - return 0; + return false; } /* Given a chain of REG_NOTES originally from FROM_INSN, try to place them @@ -14988,7 +14996,7 @@ make_more_copies (void) } /* Try combining insns through substitution. */ -static unsigned int +static void rest_of_handle_combine (void) { make_more_copies (); @@ -15000,7 +15008,7 @@ rest_of_handle_combine (void) regstat_init_n_sets_and_refs (); reg_n_sets_max = max_reg_num (); - int rebuild_jump_labels_after_combine + bool rebuild_jump_labels_after_combine = combine_instructions (get_insns (), max_reg_num ()); /* Combining insns may have turned an indirect jump into a @@ -15017,7 +15025,6 @@ rest_of_handle_combine (void) } regstat_free_n_sets_and_refs (); - return 0; } namespace { @@ -15046,7 +15053,8 @@ public: bool gate (function *) final override { return (optimize > 0); } unsigned int execute (function *) final override { - return rest_of_handle_combine (); + rest_of_handle_combine (); + return 0; } }; // class pass_combine -- cgit v1.1 From c5e9927b95debc692374a2aede21856eb94217ae Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 17 Jul 2023 22:32:57 +0200 Subject: combine-stack-adj: Change return type of predicate function from int to bool gcc/ChangeLog: * combine-stack-adj.cc (stack_memref_p): Change return type from int to bool and adjust function body accordingly. (rest_of_handle_stack_adjustments): Change return type to void. --- gcc/combine-stack-adj.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/combine-stack-adj.cc b/gcc/combine-stack-adj.cc index e479aea..4171e79 100644 --- a/gcc/combine-stack-adj.cc +++ b/gcc/combine-stack-adj.cc @@ -65,7 +65,7 @@ struct csa_reflist struct csa_reflist *next; }; -static int stack_memref_p (rtx); +static bool stack_memref_p (rtx); static rtx single_set_for_csa (rtx_insn *); static void free_csa_reflist (struct csa_reflist *); static struct csa_reflist *record_one_stack_ref (rtx_insn *, rtx *, @@ -92,21 +92,21 @@ combine_stack_adjustments (void) /* Recognize a MEM of the form (sp) or (plus sp const). */ -static int +static bool stack_memref_p (rtx x) { if (!MEM_P (x)) - return 0; + return false; x = XEXP (x, 0); if (x == stack_pointer_rtx) - return 1; + return true; if (GET_CODE (x) == PLUS && XEXP (x, 0) == stack_pointer_rtx && CONST_INT_P (XEXP (x, 1))) - return 1; + return true; - return 0; + return false; } /* Recognize either normal single_set or the hack in i386.md for @@ -791,13 +791,12 @@ combine_stack_adjustments_for_block (basic_block bb, bitmap live) BITMAP_FREE (copy); } -static unsigned int +static void rest_of_handle_stack_adjustments (void) { df_note_add_problem (); df_analyze (); combine_stack_adjustments (); - return 0; } namespace { @@ -826,7 +825,8 @@ public: bool gate (function *) final override; unsigned int execute (function *) final override { - return rest_of_handle_stack_adjustments (); + rest_of_handle_stack_adjustments (); + return 0; } }; // class pass_stack_adjustments -- cgit v1.1 From c7ac1de5f5c561b2d90c084a638c232d322d54e6 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 13 Jul 2023 17:48:05 -0400 Subject: c++: only cache constexpr calls that are constant exprs In reviewing Nathaniel's patch for PR70331, it occurred to me that instead of looking for various specific problematic things in the result of a constexpr call to decide whether to cache it, we should use reduced_constant_expression_p. The change to that function is to avoid crashing on uninitialized objects of non-class type. In a trial version of this patch I checked to see what cases this stopped caching; most were instances of partially-initialized return values, which seem fine to not cache. Some were returning pointers to expiring local variables, which we definitely want not to cache. And one was bit-cast3.C, which will be handled in a follow-up patch. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Only cache reduced_constant_expression_p results. (reduced_constant_expression_p): Handle CONSTRUCTOR of scalar type. (cxx_eval_constant_expression): Fold vectors here. (cxx_eval_bare_aggregate): Not here. --- gcc/cp/constexpr.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index c6f323e..9d85c3b 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -3033,7 +3033,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, } else { - bool cacheable = true; + bool cacheable = !!entry; if (result && result != error_mark_node) /* OK */; else if (!DECL_SAVED_TREE (fun)) @@ -3185,7 +3185,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, for the constexpr evaluation and should not be cached. It is fine if the call allocates something and deallocates it too. */ - if (entry + if (cacheable && (save_heap_alloc_count != ctx->global->heap_vars.length () || (save_heap_dealloc_count != ctx->global->heap_dealloc_count))) @@ -3204,10 +3204,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, cacheable = false; break; } - /* Also don't cache a call that returns a deallocated pointer. */ - if (cacheable && (cp_walk_tree_without_duplicates - (&result, find_heap_var_refs, NULL))) - cacheable = false; } /* Rewrite all occurrences of the function's RESULT_DECL with the @@ -3217,6 +3213,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, && !is_empty_class (TREE_TYPE (res))) if (replace_decl (&result, res, ctx->object)) cacheable = false; + + /* Only cache a permitted result of a constant expression. */ + if (cacheable && !reduced_constant_expression_p (result)) + cacheable = false; } else /* Couldn't get a function copy to evaluate. */ @@ -3268,8 +3268,9 @@ reduced_constant_expression_p (tree t) case CONSTRUCTOR: /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */ tree field; - if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - /* An initialized vector would have a VECTOR_CST. */ + if (!AGGREGATE_TYPE_P (TREE_TYPE (t))) + /* A constant vector would be folded to VECTOR_CST. + A CONSTRUCTOR of scalar type means uninitialized. */ return false; if (CONSTRUCTOR_NO_CLEARING (t)) { -- cgit v1.1 From 790fef14ba8e4c4c5fe3d5c5a8237347dc52f4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= Date: Mon, 17 Jul 2023 23:17:07 +0200 Subject: extend.texi: index __auto_type gcc/ChangeLog: * doc/extend.texi: Add @cindex on __auto_type. --- gcc/doc/extend.texi | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 093bd97..ec9ffa3 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -843,6 +843,7 @@ Thus, @code{array (pointer (char), 4)} is the type of arrays of 4 pointers to @code{char}. @end itemize +@cindex @code{__auto_type} in GNU C In GNU C, but not GNU C++, you may also declare the type of a variable as @code{__auto_type}. In that case, the declaration must declare only one variable, whose declarator must just be an identifier, the -- cgit v1.1 From 473c1b58f1fc6f87920fce8d41e0d9545097a700 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 18 Jul 2023 00:17:34 +0000 Subject: Daily bump. --- gcc/ChangeLog | 326 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 8 ++ gcc/fortran/ChangeLog | 140 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 137 ++++++++++++++++++++ 5 files changed, 612 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70103a6..4f60e5f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,329 @@ +2023-07-17 Arsen Arsenović + + * doc/extend.texi: Add @cindex on __auto_type. + +2023-07-17 Uros Bizjak + + * combine-stack-adj.cc (stack_memref_p): Change return type from + int to bool and adjust function body accordingly. + (rest_of_handle_stack_adjustments): Change return type to void. + +2023-07-17 Uros Bizjak + + * combine.cc (struct reg_stat_type): Change last_set_invalid to bool. + (cant_combine_insn_p): Change return type from int to bool and adjust + function body accordingly. + (can_combine_p): Ditto. + (combinable_i3pat): Ditto. Change "i1_not_in_src" and "i0_not_in_src" + function arguments from int to bool. + (contains_muldiv): Change return type from int to bool and adjust + function body accordingly. + (try_combine): Ditto. Change "new_direct_jump" pointer function + argument from int to bool. Change "substed_i2", "substed_i1", + "substed_i0", "added_sets_0", "added_sets_1", "added_sets_2", + "i2dest_in_i2src", "i1dest_in_i1src", "i2dest_in_i1src", + "i0dest_in_i0src", "i1dest_in_i0src", "i2dest_in_i0src", + "i2dest_killed", "i1dest_killed", "i0dest_killed", "i1_feeds_i2_n", + "i0_feeds_i2_n", "i0_feeds_i1_n", "i3_subst_into_i2", "have_mult", + "swap_i2i3", "split_i2i3" and "changed_i3_dest" variables + from int to bool. + (subst): Change "in_dest", "in_cond" and "unique_copy" function + arguments from int to bool. + (combine_simplify_rtx): Change "in_dest" and "in_cond" function + arguments from int to bool. + (make_extraction): Change "unsignedp", "in_dest" and "in_compare" + function argument from int to bool. + (force_int_to_mode): Change "just_select" function argument + from int to bool. Change "next_select" variable to bool. + (rtx_equal_for_field_assignment_p): Change return type from + int to bool and adjust function body accordingly. + (merge_outer_ops): Ditto. Change "pcomp_p" pointer function + argument from int to bool. + (get_last_value_validate): Change return type from int to bool + and adjust function body accordingly. + (reg_dead_at_p): Ditto. + (reg_bitfield_target_p): Ditto. + (combine_instructions): Ditto. Change "new_direct_jump" + variable to bool. + (can_combine_p): Change return type from int to bool + and adjust function body accordingly. + (likely_spilled_retval_p): Ditto. + (can_change_dest_mode): Change "added_sets" function argument + from int to bool. + (find_split_point): Change "unsignedp" variable to bool. + (simplify_if_then_else): Change "comparison_p" and "swapped" + variables to bool. + (simplify_set): Change "other_changed" variable to bool. + (expand_compound_operation): Change "unsignedp" variable to bool. + (force_to_mode): Change "just_select" function argument + from int to bool. Change "next_select" variable to bool. + (extended_count): Change "unsignedp" function argument to bool. + (simplify_shift_const_1): Change "complement_p" variable to bool. + (simplify_comparison): Change "changed" variable to bool. + (rest_of_handle_combine): Change return type to void. + +2023-07-17 Andre Vieira + + PR plugins/110610 + * Makefile.in (INTERNAL_FN_H): Add insn-opinit.h. + +2023-07-17 Senthil Kumar Selvaraj + + * ira.cc (setup_reg_class_relations): Continue + if regclass cl3 is hard_reg_set_empty_p. + +2023-07-17 Juzhe-Zhong + + * config/riscv/riscv.cc (riscv_option_override): Add sorry check. + +2023-07-17 Martin Jambor + + * tree-ssa-loop-ivcanon.cc (try_peel_loop): Remove unused variable + entry_count. + +2023-07-17 Aldy Hernandez + + * tree-ssa-ccp.cc (ccp_finalize): Export value/mask known bits. + +2023-07-17 Lehua Ding + + PR target/110696 + * common/config/riscv/riscv-common.cc (riscv_subset_list::handle_implied_ext): + recur add all implied extensions. + (riscv_subset_list::check_implied_ext): Add new method. + (riscv_subset_list::parse): Call checker check_implied_ext. + * config/riscv/riscv-subset.h: Add new method. + +2023-07-17 Juzhe-Zhong + + * config/riscv/autovec.md (reduc_plus_scal_): New pattern. + (reduc_smax_scal_): Ditto. + (reduc_umax_scal_): Ditto. + (reduc_smin_scal_): Ditto. + (reduc_umin_scal_): Ditto. + (reduc_and_scal_): Ditto. + (reduc_ior_scal_): Ditto. + (reduc_xor_scal_): Ditto. + * config/riscv/riscv-protos.h (enum insn_type): Add reduction. + (expand_reduction): New function. + * config/riscv/riscv-v.cc (emit_vlmax_reduction_insn): Ditto. + (emit_vlmax_fp_reduction_insn): Ditto. + (get_m1_mode): Ditto. + (expand_cond_len_binop): Fix name. + (expand_reduction): New function + * config/riscv/riscv-vsetvl.cc (gen_vsetvl_pat): Fix VSETVL BUG. + (validate_change_or_fail): New function. + (change_insn): Fix VSETVL BUG. + (change_vsetvl_insn): Ditto. + (pass_vsetvl::backward_demand_fusion): Ditto. + (pass_vsetvl::df_post_optimization): Ditto. + +2023-07-17 Aldy Hernandez + + * ipa-prop.cc (ipcp_update_bits): Export value/mask known bits. + +2023-07-17 Christoph Müllner + + * config/riscv/riscv.cc (riscv_regno_ok_for_index_p): + Remove parameter name from declaration of unused parameter. + +2023-07-17 Kewen Lin + + PR tree-optimization/110652 + * tree-vect-stmts.cc (vectorizable_load): Initialize new_temp as + NULL_TREE. + +2023-07-17 Richard Biener + + PR tree-optimization/110669 + * tree-scalar-evolution.cc (analyze_and_compute_bitop_with_inv_effect): + Check we matched a header PHI. + +2023-07-17 Aldy Hernandez + + * tree-ssanames.cc (set_bitmask): New. + * tree-ssanames.h (set_bitmask): New. + +2023-07-17 Aldy Hernandez + + * value-range.cc (irange_bitmask::verify_mask): Mask need not be + normalized. + * value-range.h (irange_bitmask::union_): Normalize beforehand. + (irange_bitmask::intersect): Same. + +2023-07-17 Andrew Pinski + + PR tree-optimization/95923 + * match.pd ((a|b)&(a==b),a|(a==b),(a&b)|(a==b)): New transformation. + +2023-07-17 Roger Sayle + + * tree-if-conv.cc (predicate_scalar_phi): Make the arguments + to the std::sort comparison lambda function const. + +2023-07-17 Andrew Pinski + + PR tree-optimization/110666 + * match.pd (A NEEQ (A NEEQ CST)): Fix Outer EQ case. + +2023-07-17 Mo, Zewei + + * common/config/i386/cpuinfo.h (get_intel_cpu): Handle Lunar Lake, + Arrow Lake and Arrow Lake S. + * common/config/i386/i386-common.cc: + (processor_name): Add arrowlake. + (processor_alias_table): Add arrow lake, arrow lake s and lunar + lake. + * common/config/i386/i386-cpuinfo.h (enum processor_subtypes): + Add INTEL_COREI7_ARROWLAKE and INTEL_COREI7_ARROWLAKE_S. + * config.gcc: Add -march=arrowlake and -march=arrowlake-s. + * config/i386/driver-i386.cc (host_detect_local_cpu): Handle + arrowlake-s. + * config/i386/i386-c.cc (ix86_target_macros_internal): Add + arrowlake. + * config/i386/i386-options.cc (m_ARROWLAKE): New. + (processor_cost_table): Add arrowlake. + * config/i386/i386.h (enum processor_type): + Add PROCESSOR_ARROWLAKE. + * config/i386/x86-tune.def: Add m_ARROWLAKE. + * doc/extend.texi: Add arrowlake and arrowlake-s. + * doc/invoke.texi: Ditto. + +2023-07-17 Haochen Jiang + + * config/i386/sse.md (VI2_AVX2): Delete V32HI since we actually + have the same iterator. Also renaming all the occurence to + VI2_AVX2_AVX512BW. + (usdot_prod): New define_expand. + (udot_prod): Ditto. + +2023-07-17 Haochen Jiang + + * common/config/i386/cpuinfo.h (get_available_features): + Detech SM4. + * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_SM4_SET, + OPTION_MASK_ISA2_SM4_UNSET): New. + (OPTION_MASK_ISA2_AVX_UNSET): Add SM4. + (ix86_handle_option): Handle -msm4. + * common/config/i386/i386-cpuinfo.h (enum processor_features): + Add FEATURE_SM4. + * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for + sm4. + * config.gcc: Add sm4intrin.h. + * config/i386/cpuid.h (bit_SM4): New. + * config/i386/i386-builtin.def (BDESC): Add new builtins. + * config/i386/i386-c.cc (ix86_target_macros_internal): Define + __SM4__. + * config/i386/i386-isa.def (SM4): Add DEF_PTA(SM4). + * config/i386/i386-options.cc (isa2_opts): Add -msm4. + (ix86_valid_target_attribute_inner_p): Handle sm4. + * config/i386/i386.opt: Add option -msm4. + * config/i386/immintrin.h: Include sm4intrin.h + * config/i386/sse.md (vsm4key4_): New define insn. + (vsm4rnds4_): Ditto. + * doc/extend.texi: Document sm4. + * doc/invoke.texi: Document -msm4. + * doc/sourcebuild.texi: Document target sm4. + * config/i386/sm4intrin.h: New file. + +2023-07-17 Haochen Jiang + + * common/config/i386/cpuinfo.h (get_available_features): + Detect SHA512. + * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_SHA512_SET, + OPTION_MASK_ISA2_SHA512_UNSET): New. + (OPTION_MASK_ISA2_AVX_UNSET): Add SHA512. + (ix86_handle_option): Handle -msha512. + * common/config/i386/i386-cpuinfo.h (enum processor_features): + Add FEATURE_SHA512. + * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for + sha512. + * config.gcc: Add sha512intrin.h. + * config/i386/cpuid.h (bit_SHA512): New. + * config/i386/i386-builtin-types.def: + Add DEF_FUNCTION_TYPE (V4DI, V4DI, V4DI, V2DI). + * config/i386/i386-builtin.def (BDESC): Add new builtins. + * config/i386/i386-c.cc (ix86_target_macros_internal): Define + __SHA512__. + * config/i386/i386-expand.cc (ix86_expand_args_builtin): Handle + V4DI_FTYPE_V4DI_V4DI_V2DI and V4DI_FTYPE_V4DI_V2DI. + * config/i386/i386-isa.def (SHA512): Add DEF_PTA(SHA512). + * config/i386/i386-options.cc (isa2_opts): Add -msha512. + (ix86_valid_target_attribute_inner_p): Handle sha512. + * config/i386/i386.opt: Add option -msha512. + * config/i386/immintrin.h: Include sha512intrin.h. + * config/i386/sse.md (vsha512msg1): New define insn. + (vsha512msg2): Ditto. + (vsha512rnds2): Ditto. + * doc/extend.texi: Document sha512. + * doc/invoke.texi: Document -msha512. + * doc/sourcebuild.texi: Document target sha512. + * config/i386/sha512intrin.h: New file. + +2023-07-17 Haochen Jiang + + * common/config/i386/cpuinfo.h (get_available_features): + Detect SM3. + * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_SM3_SET, + OPTION_MASK_ISA2_SM3_UNSET): New. + (OPTION_MASK_ISA2_AVX_UNSET): Add SM3. + (ix86_handle_option): Handle -msm3. + * common/config/i386/i386-cpuinfo.h (enum processor_features): + Add FEATURE_SM3. + * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for + SM3. + * config.gcc: Add sm3intrin.h + * config/i386/cpuid.h (bit_SM3): New. + * config/i386/i386-builtin-types.def: + Add DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, V4SI, INT). + * config/i386/i386-builtin.def (BDESC): Add new builtins. + * config/i386/i386-c.cc (ix86_target_macros_internal): Define + __SM3__. + * config/i386/i386-expand.cc (ix86_expand_args_builtin): Handle + V4SI_FTYPE_V4SI_V4SI_V4SI_INT. + * config/i386/i386-isa.def (SM3): Add DEF_PTA(SM3). + * config/i386/i386-options.cc (isa2_opts): Add -msm3. + (ix86_valid_target_attribute_inner_p): Handle sm3. + * config/i386/i386.opt: Add option -msm3. + * config/i386/immintrin.h: Include sm3intrin.h. + * config/i386/sse.md (vsm3msg1): New define insn. + (vsm3msg2): Ditto. + (vsm3rnds2): Ditto. + * doc/extend.texi: Document sm3. + * doc/invoke.texi: Document -msm3. + * doc/sourcebuild.texi: Document target sm3. + * config/i386/sm3intrin.h: New file. + +2023-07-17 Kong Lingling + Haochen Jiang + + * common/config/i386/cpuinfo.h (get_available_features): Detect + avxvnniint16. + * common/config/i386/i386-common.cc + (OPTION_MASK_ISA2_AVXVNNIINT16_SET): New. + (OPTION_MASK_ISA2_AVXVNNIINT16_UNSET): Ditto. + (ix86_handle_option): Handle -mavxvnniint16. + * common/config/i386/i386-cpuinfo.h (enum processor_features): + Add FEATURE_AVXVNNIINT16. + * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for + avxvnniint16. + * config.gcc: Add avxvnniint16.h. + * config/i386/avxvnniint16intrin.h: New file. + * config/i386/cpuid.h (bit_AVXVNNIINT16): New. + * config/i386/i386-builtin.def: Add new builtins. + * config/i386/i386-c.cc (ix86_target_macros_internal): Define + __AVXVNNIINT16__. + * config/i386/i386-options.cc (isa2_opts): Add -mavxvnniint16. + (ix86_valid_target_attribute_inner_p): Handle avxvnniint16intrin.h. + * config/i386/i386-isa.def: Add DEF_PTA(AVXVNNIINT16). + * config/i386/i386.opt: Add option -mavxvnniint16. + * config/i386/immintrin.h: Include avxvnniint16.h. + * config/i386/sse.md + (vpdp_): New define_insn. + * doc/extend.texi: Document avxvnniint16. + * doc/invoke.texi: Document -mavxvnniint16. + * doc/sourcebuild.texi: Document target avxvnniint16. + 2023-07-16 Jan Hubicka PR middle-end/110649 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4a97c3e..5e9edc9 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230717 +20230718 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 108312d..240c009 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2023-07-17 Jason Merrill + + * constexpr.cc (cxx_eval_call_expression): Only cache + reduced_constant_expression_p results. + (reduced_constant_expression_p): Handle CONSTRUCTOR of scalar type. + (cxx_eval_constant_expression): Fold vectors here. + (cxx_eval_bare_aggregate): Not here. + 2023-07-15 Patrick Palka PR c++/110441 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b864810..c64c52e 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,143 @@ +2023-07-17 Harald Anlauf + + PR fortran/95947 + PR fortran/110658 + * trans-expr.cc (gfc_conv_procedure_call): For intrinsic procedures + whose result characteristics depends on the first argument and which + can be of type character, the character length will not be deferred. + +2023-07-17 Tobias Burnus + Chung-Lin Tang + + * dump-parse-tree.cc (show_omp_namelist, show_omp_clauses): Dump + uses_allocators clause. + * gfortran.h (gfc_free_omp_namelist): Add memspace_sym to u union + and traits_sym to u2 union. + (OMP_LIST_USES_ALLOCATORS): New enum value. + (gfc_free_omp_namelist): Add 'bool free_mem_traits_space' arg. + * match.cc (gfc_free_omp_namelist): Likewise. + * openmp.cc (gfc_free_omp_clauses, gfc_match_omp_variable_list, + gfc_match_omp_to_link, gfc_match_omp_doacross_sink, + gfc_match_omp_clause_reduction, gfc_match_omp_allocate, + gfc_match_omp_flush): Update call. + (gfc_match_omp_clauses): Likewise. Parse uses_allocators clause. + (gfc_match_omp_clause_uses_allocators): New. + (enum omp_mask2): Add new OMP_CLAUSE_USES_ALLOCATORS. + (OMP_TARGET_CLAUSES): Accept it. + (resolve_omp_clauses): Resolve uses_allocators clause + * st.cc (gfc_free_statement): Update gfc_free_omp_namelist call. + * trans-openmp.cc (gfc_trans_omp_clauses): Handle + OMP_LIST_USES_ALLOCATORS; fail with sorry unless predefined allocator. + (gfc_split_omp_clauses): Handle uses_allocators. + +2023-07-17 Mikael Morin + + PR fortran/110618 + * trans.h (gfc_deallocate_with_status): Add class container + argument. + (gfc_deallocate_scalar_with_status): Ditto. + * trans.cc (gfc_deallocate_with_status): Add class container + argument and pass it down to gfc_add_finalize_call. + (gfc_deallocate_scalar_with_status): Same. + * trans-array.cc (structure_alloc_comps): Update caller. + * trans-stmt.cc (gfc_trans_deallocate): Ditto. + * trans-expr.cc (gfc_conv_procedure_call): Ditto. Pass + pre-evaluated class container argument if it's available. + +2023-07-17 Mikael Morin + + PR fortran/110618 + * trans.h (gfc_add_finalizer_call): Add class container argument. + * trans.cc (gfc_add_finalizer_call): Ditto. Pass down new + argument to get_final_proc_ref, get_elem_size, get_var_desc, + and get_vptr. + (get_elem_size): Add class container argument. + Use provided class container if it's available. + (get_var_descr): Same. + (get_vptr): Same. + (get_final_proc_ref): Same. Add boolean telling the class + container argument is used. Set it. Don't try to use + final_wrapper if class container argument was used. + +2023-07-17 Mikael Morin + + * trans.cc (get_var_descr): Factor scalar descriptor generation. + +2023-07-17 Mikael Morin + + * trans.cc (get_vptr): New function. + (gfc_add_finalizer_call): Move virtual table pointer evaluation + to get_vptr. + +2023-07-17 Mikael Morin + + * trans.cc (get_var_descr): Remove argument ts. Use var->ts + instead. + (gfc_add_finalizer_call): Update caller. + +2023-07-17 Mikael Morin + + * trans.cc (gfc_add_finalizer_call): Inline definition of + variable has_finalizer. Merge nested conditions. + +2023-07-17 Mikael Morin + + * trans.cc (gfc_add_finalizer_call): Remove local variable + final_expr. Pass down expr to get_final_proc_ref and move + final procedure expression generation down to its one usage + in get_final_proc_ref. + (get_final_proc_ref): Add argument expr. Remove argument + final_wrapper. Recreate final_wrapper from expr. + +2023-07-17 Mikael Morin + + * trans.cc (gfc_add_finalizer_call): Remove local variable + elem_size. Pass expression to get_elem_size and move the + element size expression generation close to its usage there. + (get_elem_size): Add argument expr, remove class_size argument + and rebuild it from expr. Remove ts argument and use the + type of expr instead. + +2023-07-17 Mikael Morin + + * trans.cc (gfc_add_finalizer_call): Move pre and post code for + the final procedure pointer expression to the outer block. + Reuse the previously evaluated final procedure pointer + expression. + +2023-07-17 Mikael Morin + + * trans.cc (gfc_add_finalizer_call): Add post code for desc_se + after the finalizer call. Add post code for final_se and + size_se as well. + +2023-07-17 Mikael Morin + + * trans.cc (gfc_build_final_call): Inline... + (gfc_add_finalizer_call): ... to its one caller. + +2023-07-17 Mikael Morin + + * trans.cc (get_var_descr): New function. + (gfc_build_final_call): Outline the data reference descriptor + evaluation code to get_var_descr. + +2023-07-17 Mikael Morin + + * trans.cc (get_elem_size): New function. + (gfc_build_final_call): Outline the element size evaluation + to get_elem_size. + +2023-07-17 Mikael Morin + + * trans.cc (get_final_proc_ref): New function. + (gfc_build_final_call): Outline the pointer evaluation code + to get_final_proc_ref. + +2023-07-17 Mikael Morin + + * trans.cc (gfc_build_final_call): Remove commented assertion. + 2023-07-14 Mikael Morin PR fortran/92178 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8e19069..7e6ffb0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,140 @@ +2023-07-17 Harald Anlauf + + PR fortran/95947 + PR fortran/110658 + * gfortran.dg/deferred_character_37.f90: New test. + +2023-07-17 Juzhe-Zhong + + * gcc.target/riscv/rvv/base/zvl-unimplemented-1.c: New test. + * gcc.target/riscv/rvv/base/zvl-unimplemented-2.c: New test. + +2023-07-17 Mikael Morin + + PR fortran/110618 + * gfortran.dg/intent_out_22.f90: New test. + +2023-07-17 Mikael Morin + + * gfortran.dg/finalize_53.f90: New test. + +2023-07-17 Lehua Ding + + PR target/110696 + * gcc.target/riscv/attribute-20.c: New test. + * gcc.target/riscv/pr110696.c: New test. + +2023-07-17 Juzhe-Zhong + + * gcc.target/riscv/rvv/rvv.exp: Add reduction tests. + * gcc.target/riscv/rvv/autovec/reduc/reduc-1.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc-2.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc-3.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc-4.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-1.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-2.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-3.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-4.c: New test. + +2023-07-17 Richard Biener + + PR tree-optimization/110669 + * gcc.dg/torture/pr110669.c: New testcase. + +2023-07-17 Andrew Pinski + + PR tree-optimization/95923 + * gcc.dg/tree-ssa/bitops-2.c: New test. + * gcc.dg/tree-ssa/bool-checks-1.c: New test. + +2023-07-17 Andrew Pinski + + PR tree-optimization/110666 + * gcc.c-torture/execute/pr110666-1.c: New test. + +2023-07-17 Mo, Zewei + + * g++.target/i386/mv16.C: Add arrowlake and arrowlake-s. + * gcc.target/i386/funcspec-56.inc: Handle new march. + +2023-07-17 Haochen Jiang + + * gcc.target/i386/vnniint16-auto-vectorize-1.c: New test. + * gcc.target/i386/vnniint16-auto-vectorize-2.c: Ditto. + +2023-07-17 Haochen Jiang + + * g++.dg/other/i386-2.C: Add -msm4. + * g++.dg/other/i386-3.C: Ditto. + * gcc.target/i386/funcspec-56.inc: Add new target attribute. + * gcc.target/i386/sse-12.c: Add -msm4. + * gcc.target/i386/sse-13.c: Ditto. + * gcc.target/i386/sse-14.c: Ditto. + * gcc.target/i386/sse-22.c: Add sm4. + * gcc.target/i386/sse-23.c: Ditto. + * lib/target-supports.exp (check_effective_target_sm4): New. + * gcc.target/i386/sm4-1.c: New test. + * gcc.target/i386/sm4-check.h: Ditto. + * gcc.target/i386/sm4key4-2.c: Ditto. + * gcc.target/i386/sm4rnds4-2.c: Ditto. + +2023-07-17 Haochen Jiang + + * g++.dg/other/i386-2.C: Add -msha512. + * g++.dg/other/i386-3.C: Ditto. + * gcc.target/i386/funcspec-56.inc: Add new target attribute. + * gcc.target/i386/sse-12.c: Add -msha512. + * gcc.target/i386/sse-13.c: Ditto. + * gcc.target/i386/sse-14.c: Ditto. + * gcc.target/i386/sse-22.c: Add sha512. + * gcc.target/i386/sse-23.c: Ditto. + * lib/target-supports.exp (check_effective_target_sha512): New. + * gcc.target/i386/sha512-1.c: New test. + * gcc.target/i386/sha512-check.h: Ditto. + * gcc.target/i386/sha512msg1-2.c: Ditto. + * gcc.target/i386/sha512msg2-2.c: Ditto. + * gcc.target/i386/sha512rnds2-2.c: Ditto. + +2023-07-17 Haochen Jiang + + * g++.dg/other/i386-2.C: Add -msm3. + * g++.dg/other/i386-3.C: Ditto. + * gcc.target/i386/avx-1.c: Add new define for immediate. + * gcc.target/i386/funcspec-56.inc: Add new target attribute. + * gcc.target/i386/sse-12.c: Add -msm3. + * gcc.target/i386/sse-13.c: Ditto. + * gcc.target/i386/sse-14.c: Ditto. + * gcc.target/i386/sse-22.c: Add sm3. + * gcc.target/i386/sse-23.c: Ditto. + * lib/target-supports.exp (check_effective_target_sm3): New. + * gcc.target/i386/sm3-1.c: New test. + * gcc.target/i386/sm3-check.h: Ditto. + * gcc.target/i386/sm3msg1-2.c: Ditto. + * gcc.target/i386/sm3msg2-2.c: Ditto. + * gcc.target/i386/sm3rnds2-2.c: Ditto. + +2023-07-17 Kong Lingling + Haochen Jiang + + * g++.dg/other/i386-2.C: Add -mavxvnniint16. + * g++.dg/other/i386-3.C: Ditto. + * gcc.target/i386/avx-check.h: Add avxvnniint16 check. + * gcc.target/i386/sse-12.c: Add -mavxvnniint16. + * gcc.target/i386/sse-13.c: Ditto. + * gcc.target/i386/sse-14.c: Ditto. + * gcc.target/i386/sse-22.c: Ditto. + * gcc.target/i386/sse-23.c: Ditto. + * gcc.target/i386/funcspec-56.inc: Add new target attribute. + * lib/target-supports.exp + (check_effective_target_avxvnniint16): New. + * gcc.target/i386/avxvnniint16-1.c: Ditto. + * gcc.target/i386/avxvnniint16-vpdpwusd-2.c: Ditto. + * gcc.target/i386/avxvnniint16-vpdpwusds-2.c: Ditto. + * gcc.target/i386/avxvnniint16-vpdpwsud-2.c: Ditto. + * gcc.target/i386/avxvnniint16-vpdpwsuds-2.c: Ditto. + * gcc.target/i386/avxvnniint16-vpdpwuud-2.c: Ditto. + * gcc.target/i386/avxvnniint16-vpdpwuuds-2.c: Ditto. + 2023-07-15 David Edelsohn * gfortran.dg/pr103628.f90: Add -mlong-double-128 option. -- cgit v1.1 From 45dd1d91671cbc4a868ec41ada5f070aa487d02d Mon Sep 17 00:00:00 2001 From: Pan Li Date: Fri, 14 Jul 2023 10:14:07 +0800 Subject: RISC-V: Support basic floating-point dynamic rounding mode This patch would like to support the basic floating-point dynamic rounding modes for the RVV. We implement the dynamic rounding mode by below steps. 1. Set entry to DYN and exit to DYN_EXIT. 2. Add one rtl variable into machine_function for backup/restore. 3. Backup frm value when entry. 4. Restore frm value when exit and prev mode is not DYN. 5. Restore frm when mode switching to DYN. 6. Set frm when mode switching to STATIC. Take one flow to describe the scenarios. +-------------+ | Entry (DYN) | <- frrm a5 +-------------+ / \ +-------+ +-----------+ | VFADD | <- fsrm a5 | VFADD RTZ | <- fsrmi 1(RTZ) +-------+ +-----------+ | | +-------+ +-----------+ | VFADD | | VFADD RTZ | +-------+ +-----------+ | | +-----------+ +-------+ | VFADD RUP | <- fsrmi 3(RUP) | VFADD | <- fsrm a5 +-----------+ +-------+ | / +-----------+ / | VFADD RUP | / +-----------+ / \ / +-----------------+ | Exit (DYN_EXIT) | <- fsrm a5 +-----------------+ Please *NOTE* inline asm and call during the cfun will be implemented in another PATCH(s). Signed-off-by: Pan Li Co-Authored-By: Juzhe-Zhong gcc/ChangeLog: * config/riscv/riscv.cc (struct machine_function): Add new field. (riscv_static_frm_mode_p): New function. (riscv_emit_frm_mode_set): New function for emit FRM. (riscv_emit_mode_set): Extract function for FRM. (riscv_mode_needed): Fix the TODO. (riscv_mode_entry): Initial dynamic frm RTL. (riscv_mode_exit): Return DYN_EXIT. * config/riscv/riscv.md: Add rdfrm. * config/riscv/vector-iterators.md (unspecv): Add DYN_EXIT unspecv. * config/riscv/vector.md (frm_modee): Add new mode dyn_exit. (fsrm): Removed. (fsrmsi_backup): New pattern for swap. (fsrmsi_restore): New pattern for restore. (fsrmsi_restore_exit): New pattern for restore exit. (frrmsi): New pattern for backup. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-insert-1.c: Adjust test cases. * gcc.target/riscv/rvv/base/float-point-frm-insert-10.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-2.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-3.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-4.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-5.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-7.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-8.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-insert-9.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-run-1.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-run-2.c: Ditto. * gcc.target/riscv/rvv/base/float-point-frm-run-3.c: Ditto. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c: New test. * gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c: New test. --- gcc/config/riscv/riscv.cc | 95 +++++++++++++++------- gcc/config/riscv/riscv.md | 2 +- gcc/config/riscv/vector-iterators.md | 4 +- gcc/config/riscv/vector.md | 63 ++++++++++---- .../riscv/rvv/base/float-point-dynamic-frm-1.c | 21 +++++ .../riscv/rvv/base/float-point-dynamic-frm-10.c | 26 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-11.c | 26 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-12.c | 29 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-13.c | 29 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-14.c | 28 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-15.c | 28 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-16.c | 22 +++++ .../riscv/rvv/base/float-point-dynamic-frm-17.c | 22 +++++ .../riscv/rvv/base/float-point-dynamic-frm-18.c | 25 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-19.c | 25 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-2.c | 20 +++++ .../riscv/rvv/base/float-point-dynamic-frm-20.c | 27 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-21.c | 27 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-22.c | 25 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-23.c | 25 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-24.c | 13 +++ .../riscv/rvv/base/float-point-dynamic-frm-25.c | 28 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-26.c | 23 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-27.c | 30 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-28.c | 30 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-29.c | 28 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-3.c | 21 +++++ .../riscv/rvv/base/float-point-dynamic-frm-30.c | 30 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-31.c | 29 +++++++ .../riscv/rvv/base/float-point-dynamic-frm-32.c | 25 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-4.c | 21 +++++ .../riscv/rvv/base/float-point-dynamic-frm-5.c | 21 +++++ .../riscv/rvv/base/float-point-dynamic-frm-6.c | 27 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-7.c | 27 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-8.c | 26 ++++++ .../riscv/rvv/base/float-point-dynamic-frm-9.c | 26 ++++++ .../riscv/rvv/base/float-point-frm-insert-1.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-10.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-2.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-3.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-4.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-5.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-6.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-7.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-8.c | 4 +- .../riscv/rvv/base/float-point-frm-insert-9.c | 4 +- .../riscv/rvv/base/float-point-frm-run-1.c | 5 +- .../riscv/rvv/base/float-point-frm-run-2.c | 5 +- .../riscv/rvv/base/float-point-frm-run-3.c | 9 +- 49 files changed, 967 insertions(+), 66 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 195f001..d51d6bd 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -148,6 +148,9 @@ struct GTY(()) machine_function { not be considered by the prologue and epilogue. */ bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER]; + /* The RTL variable which stores the dynamic FRM value. We always use this + RTX to restore dynamic FRM rounding mode in mode switching. */ + rtx dynamic_frm; }; /* Information about a single argument. */ @@ -7649,6 +7652,55 @@ riscv_vectorize_preferred_vector_alignment (const_tree type) return TYPE_ALIGN (type); } +/* Return true if it is static FRM rounding mode. */ + +static bool +riscv_static_frm_mode_p (int mode) +{ + switch (mode) + { + case FRM_MODE_RDN: + case FRM_MODE_RUP: + case FRM_MODE_RTZ: + case FRM_MODE_RMM: + case FRM_MODE_RNE: + return true; + default: + return false; + } + + gcc_unreachable (); +} + +/* Implement the floating-point Mode Switching. */ + +static void +riscv_emit_frm_mode_set (int mode, int prev_mode) +{ + if (mode != prev_mode) + { + rtx backup_reg = cfun->machine->dynamic_frm; + /* TODO: By design, FRM_MODE_xxx used by mode switch which is + different from the FRM value like FRM_RTZ defined in + riscv-protos.h. When mode switching we actually need a conversion + function to convert the mode of mode switching to the actual + FRM value like FRM_RTZ. For now, the value between the mode of + mode swith and the FRM value in riscv-protos.h take the same value, + and then we leverage this assumption when emit. */ + rtx frm = gen_int_mode (mode, SImode); + + if (mode == FRM_MODE_DYN_EXIT && prev_mode != FRM_MODE_DYN) + /* No need to emit when prev mode is DYN already. */ + emit_insn (gen_fsrmsi_restore_exit (backup_reg)); + else if (mode == FRM_MODE_DYN) + /* Restore frm value from backup when switch to DYN mode. */ + emit_insn (gen_fsrmsi_restore (backup_reg)); + else if (riscv_static_frm_mode_p (mode)) + /* Set frm value when switch to static mode. */ + emit_insn (gen_fsrmsi_restore (frm)); + } +} + /* Implement Mode switching. */ static void @@ -7662,25 +7714,7 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode, emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode))); break; case RISCV_FRM: - /* Switching to the dynamic rounding mode is not necessary. When an - instruction requests it, it effectively uses the rounding mode already - set in the FRM register. All other rounding modes require us to - switch the rounding mode via the FRM register. */ - if (mode != FRM_MODE_DYN && mode != prev_mode) - { - /* TODO: By design, FRM_MODE_xxx used by mode switch which is - different from the FRM value like FRM_RTZ defined in - riscv-protos.h. When mode switching we actually need a conversion - function to convert the mode of mode switching to the actual - FRM value like FRM_RTZ. For now, the value between the mode of - mode swith and the FRM value in riscv-protos.h take the same value, - and then we leverage this assumption when emit. */ - rtx scaler = gen_reg_rtx (SImode); - rtx imm = gen_int_mode (mode, SImode); - - emit_insn (gen_movsi (scaler, imm)); - emit_insn (gen_fsrm (scaler, scaler)); - } + riscv_emit_frm_mode_set (mode, prev_mode); break; default: gcc_unreachable (); @@ -7700,10 +7734,7 @@ riscv_mode_needed (int entity, rtx_insn *insn) case RISCV_VXRM: return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE; case RISCV_FRM: - /* TODO: Here we may return FRM_MODE_NONE from get_attr_frm_mode, as well - as FRM_MODE_DYN as default. It is kind of inconsistent and we will - take care of it after dynamic rounding mode. */ - return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_DYN; + return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_NONE; default: gcc_unreachable (); } @@ -7819,10 +7850,18 @@ riscv_mode_entry (int entity) case RISCV_VXRM: return VXRM_MODE_NONE; case RISCV_FRM: - /* According to RVV 1.0 spec, all vector floating-point operations use - the dynamic rounding mode in the frm register. Likewise in other - similar places. */ - return FRM_MODE_DYN; + { + if (!cfun->machine->dynamic_frm) + { + cfun->machine->dynamic_frm = gen_reg_rtx (SImode); + emit_insn_at_entry (gen_frrmsi (cfun->machine->dynamic_frm)); + } + + /* According to RVV 1.0 spec, all vector floating-point operations use + the dynamic rounding mode in the frm register. Likewise in other + similar places. */ + return FRM_MODE_DYN; + } default: gcc_unreachable (); } @@ -7839,7 +7878,7 @@ riscv_mode_exit (int entity) case RISCV_VXRM: return VXRM_MODE_NONE; case RISCV_FRM: - return FRM_MODE_DYN; + return FRM_MODE_DYN_EXIT; default: gcc_unreachable (); } diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index c4f8eb9..7edef1f 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -391,7 +391,7 @@ mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul, fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost,bitmanip,rotate, clmul,min,max,minu,maxu,clz,ctz,cpop, - atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,wrfrm,vsetvl, + atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,wrfrm,rdfrm,vsetvl, vlde,vste,vldm,vstm,vlds,vsts, vldux,vldox,vstux,vstox,vldff,vldr,vstr, vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff, diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index ec49544..fdb8731 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -81,8 +81,10 @@ UNSPEC_VCOMPRESS UNSPEC_VLEFF UNSPEC_MODIFY_VL +]) - UNSPEC_FSRM +(define_c_enum "unspecv" [ + UNSPECV_FRM_RESTORE_EXIT ]) (define_mode_iterator V [ diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index de94463..215ecb9 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -475,7 +475,7 @@ ) ;; Defines rounding mode of an floating-point operation. -(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,none" +(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,dyn_exit,none" (cond [ (eq_attr "type" "vfalu") @@ -583,24 +583,51 @@ (set_attr "mode" "SI")]) ;; Set FRM -(define_insn "fsrm" - [ - (set - (reg:SI FRM_REGNUM) - (unspec:SI - [ - (match_operand:SI 0 "register_operand" "=&r") - (match_operand:SI 1 "register_operand" "r") - ] UNSPEC_FSRM - ) - ) - ] +(define_insn "fsrmsi_backup" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (reg:SI FRM_REGNUM)) + (set (reg:SI FRM_REGNUM) + (match_operand:SI 1 "reg_or_int_operand" "r,i"))] + "TARGET_VECTOR" + "@ + fsrm\t%0,%1 + fsrmi\t%0,%1" + [(set_attr "type" "wrfrm,wrfrm") + (set_attr "mode" "SI")] +) + +(define_insn "fsrmsi_restore" + [(set (reg:SI FRM_REGNUM) + (match_operand:SI 0 "reg_or_int_operand" "r,i"))] "TARGET_VECTOR" - "fsrm\t%0,%1" - [ - (set_attr "type" "wrfrm") - (set_attr "mode" "SI") - ] + "@ + fsrm\t%0 + fsrmi\t%0" + [(set_attr "type" "wrfrm,wrfrm") + (set_attr "mode" "SI")] + ) + +;; The volatile fsrmsi restore is used for the exit point for the +;; dynamic mode switching. It will generate one volatile fsrm a5 +;; which won't be eliminated. +(define_insn "fsrmsi_restore_exit" + [(set (reg:SI FRM_REGNUM) + (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] + UNSPECV_FRM_RESTORE_EXIT))] + "TARGET_VECTOR" + "fsrm\t%0" + [(set_attr "type" "wrfrm") + (set_attr "mode" "SI")] +) + +;; Read FRM +(define_insn "frrmsi" + [(set (match_operand:SI 0 "register_operand" "=r") + (reg:SI FRM_REGNUM))] + "TARGET_VECTOR" + "frrm\t%0" + [(set_attr "type" "rdfrm") + (set_attr "mode" "SI")] ) ;; ----------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c new file mode 100644 index 0000000..75af8ee --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result; + + result = __riscv_vfadd_vv_f32m1 (op1, op2, vl); + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */ +/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c new file mode 100644 index 0000000..71428d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c new file mode 100644 index 0000000..94f8ea1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c new file mode 100644 index 0000000..66c7495 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + + if (i % 2 == 0) + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c new file mode 100644 index 0000000..0fb8498 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + + if (i % 2 == 0) + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c new file mode 100644 index 0000000..ab5fc06 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + + if (i % 2 == 0) + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c new file mode 100644 index 0000000..97dacca --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + + if (i % 2 == 0) + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c new file mode 100644 index 0000000..da710b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl); + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c new file mode 100644 index 0000000..43f2517 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl); + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c new file mode 100644 index 0000000..e725825 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl); + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c new file mode 100644 index 0000000..c0161a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c new file mode 100644 index 0000000..9f8ac99 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + + return __riscv_vfadd_vv_f32m1 (result, op2, vl); +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c new file mode 100644 index 0000000..9e75b79 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl); + else + result = __riscv_vfadd_vv_f32m1_rm(op2, result, 2, vl); + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 5 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c new file mode 100644 index 0000000..aec5642 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1_rm(op1, result, 2, vl); + else + result = __riscv_vfadd_vv_f32m1_rm(op2, result, 3, vl); + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 5 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c new file mode 100644 index 0000000..83bc26a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1_rm(op1, result, 4, vl); + else + result = __riscv_vfadd_vv_f32m1_rm(op2, result, 3, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c new file mode 100644 index 0000000..e7c51ea --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + else + result = __riscv_vfadd_vv_f32m1_rm(op2, result, 3, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c new file mode 100644 index 0000000..46ac8e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c @@ -0,0 +1,13 @@ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (vfloat32m1_t *out, vfloat32m1_t op1, size_t vl) +{ +} + +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */ +/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c new file mode 100644 index 0000000..b70f531 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, + float *out) +{ + vfloat32m1_t result = __riscv_vfadd_vv_f32m1 (op1, op2, vl); + + if (vl % 4 == 0) + { + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + *(vfloat32m1_t *) out = result; + } + else + { + result = __riscv_vfadd_vv_f32m1_rm (op2, result, 3, vl); + *(vfloat32m1_t *) out = result; + } +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c new file mode 100644 index 0000000..78b2946 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, + float *out) +{ + vfloat32m1_t result = __riscv_vfadd_vv_f32m1 (op1, op2, vl); + + if (vl % 4 == 0) + { + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + *(vfloat32m1_t *) out = result; + } +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c new file mode 100644 index 0000000..4dba680 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, + float *out) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + { + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + *(vfloat32m1_t *) out = result; + } + else + { + result = __riscv_vfadd_vv_f32m1 (op2, result, vl); + *(vfloat32m1_t *) (out + 16) = result; + } +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c new file mode 100644 index 0000000..35a37b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, + float *out) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); + + if (vl % 4 == 0) + { + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + *(vfloat32m1_t *) out = result; + } + else + { + result = __riscv_vfadd_vv_f32m1_rm (op2, result, 3, vl); + *(vfloat32m1_t *) (out + 16) = result; + } +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c new file mode 100644 index 0000000..e24c204 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (float *in, float *out, int n, size_t vl) +{ + for (int i = 0; i < n; i++) + { + vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i, vl); + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 4, vl); + __riscv_vse32_v_f32m1 (out + i, result, vl); + } + + for (int i = 0; i < n; i++) + { + vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i + 100, vl); + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 3, vl); + __riscv_vse32_v_f32m1 (out + i + 100, result, vl); + } +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c new file mode 100644 index 0000000..600ac45 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c new file mode 100644 index 0000000..bf57720 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (float *in, float *out, int n, int cond, size_t vl) +{ + for (int i = 0; i < n; i++) + { + if (cond) + { + vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i + 100, vl); + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 3, vl); + __riscv_vse32_v_f32m1 (out + i + 100, result, vl); + } + else + { + vfloat32m1_t v = __riscv_vle32_v_f32m1 (in + i + 200, vl); + vfloat32m1_t result = __riscv_vfadd_vv_f32m1_rm (v, v, 3, vl); + __riscv_vse32_v_f32m1 (out + i + 200, result, vl); + } + } +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c new file mode 100644 index 0000000..64a0c8c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +void +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, + int n, float *out) +{ + vfloat32m1_t result = __riscv_vfadd_vv_f32m1 (op1, op2, vl); + + if (vl % 4 == 0) + { + result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + *(vfloat32m1_t *) out = result; + } + + if (n > 0) + { + result = __riscv_vfadd_vv_f32m1 (op2, result, vl); + *(vfloat32m1_t *) (out + 100) = result; + } +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c new file mode 100644 index 0000000..a24ffd7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +size_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, int count, + size_t vl, float *out) +{ + vfloat32m1_t result = op1; + + if (count == 0) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl); + *(vfloat32m1_t *) out = result; + } + + return vl; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c new file mode 100644 index 0000000..aaf912e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 2, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c new file mode 100644 index 0000000..9149388 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) +{ + vfloat32m1_t result = op1; + + if (vl % 4 == 0) + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */ +/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c new file mode 100644 index 0000000..1541de8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + if (i % 2 == 0) + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 2, vl); + else + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c new file mode 100644 index 0000000..6f24317 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + if (i % 2 == 0) + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl); + else + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c new file mode 100644 index 0000000..a4846b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 2, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[asx][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[asx][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[asx][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c new file mode 100644 index 0000000..cfb8fca --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, + int count, size_t vl) +{ + vfloat32m1_t result = op1; + + for (int i = 0; i < count; i++) + { + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + result = __riscv_vfadd_vv_f32m1 (result, op2, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl); + } + + return result; +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c index 732e030..608b388 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c @@ -28,4 +28,6 @@ test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2, } /* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c index c46910b..3252f67 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-10.c @@ -20,4 +20,6 @@ test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, } /* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c index 72e5d20..96e10c7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c @@ -11,4 +11,6 @@ test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { } /* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c index c9e8d0a..519537c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c @@ -11,4 +11,6 @@ test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { } /* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c index a288e0b..f9e6bc36 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c @@ -20,4 +20,6 @@ test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, } /* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c index bb77a6e..c3f6302 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c @@ -20,4 +20,6 @@ test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, } /* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c index 6d896e0..1ef0e01 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c @@ -28,4 +28,6 @@ test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2, } /* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */ -/* { dg-final { scan-assembler-not {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} } } */ +/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */ +/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c index 7b1602f..12db112 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c @@ -26,4 +26,6 @@ test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, } /* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c index 37481dd..cc83dae 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-8.c @@ -24,4 +24,6 @@ test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, } /* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c index 7ae834a..3b650ec 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-9.c @@ -21,4 +21,6 @@ test_float_point_frm_static (float *out, vfloat32m1_t op1, vfloat32m1_t op2, } /* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c index 210c49c..245ce7d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c @@ -44,8 +44,6 @@ assert_equal (int a, int b, char *message) vfloat32m1_t __attribute__ ((noinline)) test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { - set_frm (0); - vfloat32m1_t result; result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl); @@ -73,7 +71,10 @@ main () vfloat32m1_t op1; vfloat32m1_t op2; + set_frm (4); test_float_point_frm_run (op1, op2, vl); + assert_equal (4, get_frm (), "The value of frm register should be 4."); + return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c index a703652..ec4cc26 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-2.c @@ -44,8 +44,6 @@ assert_equal (int a, int b, char *message) vfloat32m1_t __attribute__ ((noinline)) test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { - set_frm (0); - vfloat32m1_t result = {}; result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl); @@ -64,7 +62,10 @@ main () vfloat32m1_t op1 = {}; vfloat32m1_t op2 = {}; + set_frm (2); test_float_point_frm_run (op1, op2, vl); + assert_equal (2, get_frm (), "The value of frm register should be 2."); + return 0; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c index 6924bdf..32ed696 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-3.c @@ -44,17 +44,15 @@ assert_equal (int a, int b, char *message) vfloat32m1_t __attribute__ ((noinline)) test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { - set_frm (0); - vfloat32m1_t result = {}; result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); + assert_equal (4, get_frm (), "The value of frm register should be 4."); + result = __riscv_vfadd_vv_f32m1 (op1, result, vl); result = __riscv_vfadd_vv_f32m1 (op1, result, vl); - assert_equal (4, get_frm (), "The value of frm register should be 4."); - return result; } @@ -65,7 +63,10 @@ main () vfloat32m1_t op1 = {}; vfloat32m1_t op2 = {}; + set_frm (0); test_float_point_frm_run (op1, op2, vl); + assert_equal (0, get_frm (), "The value of frm register should be 0."); + return 0; } -- cgit v1.1 From 61ec6a45ae3bb741b3afef41cef01094930adf7f Mon Sep 17 00:00:00 2001 From: Pan Li Date: Tue, 18 Jul 2023 10:45:27 +0800 Subject: RISC-V: Fix RVV frm run test failure on RV32 Refine the run test case to avoid interactive checking in RV32, by separating each checks in different functions. Signed-off-by: Pan Li gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-run-1.c: Fix run failure. --- .../riscv/rvv/base/float-point-frm-run-1.c | 59 +++++++++++++--------- 1 file changed, 36 insertions(+), 23 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c index 245ce7d..1b2789a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c @@ -5,6 +5,24 @@ #include #include +#define DEFINE_TEST_FUNC(FRM) \ +vfloat32m1_t __attribute__ ((noinline)) \ +test_float_point_frm_run_##FRM (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) \ +{ \ + vfloat32m1_t result; \ + \ + set_frm (0); \ + \ + result = __riscv_vfadd_vv_f32m1_rm (op1, result, FRM, vl); \ + \ + assert_equal (FRM, get_frm (), "The value of frm should be " #FRM "."); \ + \ + return result; \ +} + +#define RUN_TEST_FUNC(FRM, op1, op2, vl) \ + test_float_point_frm_run_##FRM (op1, op2, vl) + static int get_frm () { @@ -41,28 +59,11 @@ assert_equal (int a, int b, char *message) } } -vfloat32m1_t __attribute__ ((noinline)) -test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) -{ - vfloat32m1_t result; - - result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl); - assert_equal (1, get_frm (), "The value of frm register should be 1."); - - result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl); - assert_equal (2, get_frm (), "The value of frm register should be 2."); - - result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl); - assert_equal (3, get_frm (), "The value of frm register should be 3."); - - result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl); - assert_equal (4, get_frm (), "The value of frm register should be 4."); - - result = __riscv_vfadd_vv_f32m1_rm (op1, result, 0, vl); - assert_equal (0, get_frm (), "The value of frm register should be 0."); - - return result; -} +DEFINE_TEST_FUNC (0) +DEFINE_TEST_FUNC (1) +DEFINE_TEST_FUNC (2) +DEFINE_TEST_FUNC (3) +DEFINE_TEST_FUNC (4) int main () @@ -72,8 +73,20 @@ main () vfloat32m1_t op2; set_frm (4); - test_float_point_frm_run (op1, op2, vl); + RUN_TEST_FUNC (0, op1, op2, vl); + assert_equal (4, get_frm (), "The value of frm register should be 4."); + + RUN_TEST_FUNC (1, op1, op2, vl); + assert_equal (4, get_frm (), "The value of frm register should be 4."); + + RUN_TEST_FUNC (2, op1, op2, vl); + assert_equal (4, get_frm (), "The value of frm register should be 4."); + + RUN_TEST_FUNC (3, op1, op2, vl); + assert_equal (4, get_frm (), "The value of frm register should be 4."); + + RUN_TEST_FUNC (4, op1, op2, vl); assert_equal (4, get_frm (), "The value of frm register should be 4."); return 0; -- cgit v1.1 From e6a1b23872995d5344a81cff1857bc861ffee71d Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Mon, 17 Jul 2023 22:42:09 +0800 Subject: RTL_SSA: Relax PHI_MODE in phi_setup Hi, Richard. RISC-V port needs to add a bunch VLS modes (V16QI,V32QI,V64QI,...etc) There are sharing same REG_CLASS with VLA modes (VNx16QI,VNx32QI,...etc) When I am adding those VLS modes, the RTL_SSA initialization in VSETVL PASS (inserted after RA) ICE: rvv.c:13:1: internal compiler error: in partial_subreg_p, at rtl.h:3186 13 | } | ^ 0xf7a5b1 partial_subreg_p(machine_mode, machine_mode) ../../../riscv-gcc/gcc/rtl.h:3186 0x1407616 wider_subreg_mode(machine_mode, machine_mode) ../../../riscv-gcc/gcc/rtl.h:3252 0x2a2c6ff rtl_ssa::combine_modes(machine_mode, machine_mode) ../../../riscv-gcc/gcc/rtl-ssa/internals.inl:677 0x2a2b9a4 rtl_ssa::function_info::simplify_phi_setup(rtl_ssa::phi_info*, rtl_ssa::set_info**, bitmap_head*) ../../../riscv-gcc/gcc/rtl-ssa/functions.cc:146 0x2a2c142 rtl_ssa::function_info::simplify_phis() ../../../riscv-gcc/gcc/rtl-ssa/functions.cc:258 0x2a2b3f0 rtl_ssa::function_info::function_info(function*) ../../../riscv-gcc/gcc/rtl-ssa/functions.cc:51 0x1cebab9 pass_vsetvl::init() ../../../riscv-gcc/gcc/config/riscv/riscv-vsetvl.cc:4578 0x1cec150 pass_vsetvl::execute(function*) ../../../riscv-gcc/gcc/config/riscv/riscv-vsetvl.cc:4716 The reason is that we have V32QImode (size = [32,0]) which is the mode set as regno_reg_rtx[97] When the PHI input def comes from ENTRY BLOCK (index =0), the def->mode () = V32QImode. But the phi_mode = VNx2QI for example (I use VLA modes intrinsic write the codes). Then combine_modes report ICE. gcc/ChangeLog: * rtl-ssa/internals.inl: Fix when mode1 and mode2 are not ordred. --- gcc/rtl-ssa/internals.inl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc') diff --git a/gcc/rtl-ssa/internals.inl b/gcc/rtl-ssa/internals.inl index 0a61811..e49297c 100644 --- a/gcc/rtl-ssa/internals.inl +++ b/gcc/rtl-ssa/internals.inl @@ -673,6 +673,9 @@ combine_modes (machine_mode mode1, machine_mode mode2) if (mode2 == E_BLKmode) return mode1; + if (!ordered_p (GET_MODE_SIZE (mode1), GET_MODE_SIZE (mode2))) + return BLKmode; + return wider_subreg_mode (mode1, mode2); } -- cgit v1.1 From 06cc38c1c350b34cbd6dde23aefca32442c07a73 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Mon, 10 Jul 2023 14:12:07 +0800 Subject: Add peephole to eliminate redundant comparison after cmpccxadd. Similar like we did for cmpxchg, but extended to all ix86_comparison_int_operator since cmpccxadd set EFLAGS exactly same as CMP. When operand order in compare insn is same as that in cmpccxadd, compare insn can be eliminated directly. When operand order is swapped in compare insn, only optimize cmpccxadd + cmpl + jcc/setcc to cmpccxadd + jcc/setcc when FLAGS_REG is dead after jcc/setcc. gcc/ChangeLog: PR target/110591 * config/i386/sync.md (cmpccxadd_): Adjust the pattern to explicitly set FLAGS_REG like *cmp_1, also add extra 3 define_peephole2 after the pattern. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110591.c: New test. * gcc.target/i386/pr110591-2.c: New test. --- gcc/config/i386/sync.md | 160 ++++++++++++++++++++++++++++- gcc/testsuite/gcc.target/i386/pr110591-2.c | 90 ++++++++++++++++ gcc/testsuite/gcc.target/i386/pr110591.c | 66 ++++++++++++ 3 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110591-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr110591.c (limited to 'gcc') diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md index e1fa150..e84226c 100644 --- a/gcc/config/i386/sync.md +++ b/gcc/config/i386/sync.md @@ -1093,7 +1093,9 @@ UNSPECV_CMPCCXADD)) (set (match_dup 1) (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD)) - (clobber (reg:CC FLAGS_REG))] + (set (reg:CC FLAGS_REG) + (compare:CC (match_dup 1) + (match_dup 2)))] "TARGET_CMPCCXADD && TARGET_64BIT" { char buf[128]; @@ -1105,3 +1107,159 @@ output_asm_insn (buf, operands); return ""; }) + +(define_peephole2 + [(set (match_operand:SWI48x 0 "register_operand") + (match_operand:SWI48x 1 "x86_64_general_operand")) + (parallel [(set (match_dup 0) + (unspec_volatile:SWI48x + [(match_operand:SWI48x 2 "memory_operand") + (match_dup 0) + (match_operand:SWI48x 3 "register_operand") + (match_operand:SI 4 "const_int_operand")] + UNSPECV_CMPCCXADD)) + (set (match_dup 2) + (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD)) + (set (reg:CC FLAGS_REG) + (compare:CC (match_dup 2) + (match_dup 0)))]) + (set (reg FLAGS_REG) + (compare (match_operand:SWI48x 5 "register_operand") + (match_operand:SWI48x 6 "x86_64_general_operand")))] + "TARGET_CMPCCXADD && TARGET_64BIT + && rtx_equal_p (operands[0], operands[5]) + && rtx_equal_p (operands[1], operands[6])" + [(set (match_dup 0) + (match_dup 1)) + (parallel [(set (match_dup 0) + (unspec_volatile:SWI48x + [(match_dup 2) + (match_dup 0) + (match_dup 3) + (match_dup 4)] + UNSPECV_CMPCCXADD)) + (set (match_dup 2) + (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD)) + (set (reg:CC FLAGS_REG) + (compare:CC (match_dup 2) + (match_dup 0)))]) + (set (match_dup 7) + (match_op_dup 8 + [(match_dup 9) (const_int 0)]))]) + +(define_peephole2 + [(set (match_operand:SWI48x 0 "register_operand") + (match_operand:SWI48x 1 "x86_64_general_operand")) + (parallel [(set (match_dup 0) + (unspec_volatile:SWI48x + [(match_operand:SWI48x 2 "memory_operand") + (match_dup 0) + (match_operand:SWI48x 3 "register_operand") + (match_operand:SI 4 "const_int_operand")] + UNSPECV_CMPCCXADD)) + (set (match_dup 2) + (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD)) + (set (reg:CC FLAGS_REG) + (compare:CC (match_dup 2) + (match_dup 0)))]) + (set (reg FLAGS_REG) + (compare (match_operand:SWI48x 5 "register_operand") + (match_operand:SWI48x 6 "x86_64_general_operand"))) + (set (match_operand:QI 7 "nonimmediate_operand") + (match_operator:QI 8 "ix86_comparison_int_operator" + [(reg FLAGS_REG) (const_int 0)]))] + "TARGET_CMPCCXADD && TARGET_64BIT + && rtx_equal_p (operands[0], operands[6]) + && rtx_equal_p (operands[1], operands[5]) + && peep2_regno_dead_p (4, FLAGS_REG)" + [(set (match_dup 0) + (match_dup 1)) + (parallel [(set (match_dup 0) + (unspec_volatile:SWI48x + [(match_dup 2) + (match_dup 0) + (match_dup 3) + (match_dup 4)] + UNSPECV_CMPCCXADD)) + (set (match_dup 2) + (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD)) + (set (reg:CC FLAGS_REG) + (compare:CC (match_dup 2) + (match_dup 0)))]) + (set (match_dup 7) + (match_op_dup 8 + [(match_dup 9) (const_int 0)]))] +{ + operands[9] = gen_rtx_REG (GET_MODE (XEXP (operands[8], 0)), FLAGS_REG); + if (swap_condition (GET_CODE (operands[8])) != GET_CODE (operands[8])) + { + operands[8] = shallow_copy_rtx (operands[8]); + enum rtx_code ccode = swap_condition (GET_CODE (operands[8])); + PUT_CODE (operands[8], ccode); + operands[9] = gen_rtx_REG (SELECT_CC_MODE (ccode, + operands[6], + operands[5]), + FLAGS_REG); + } +}) + +(define_peephole2 + [(set (match_operand:SWI48x 0 "register_operand") + (match_operand:SWI48x 1 "x86_64_general_operand")) + (parallel [(set (match_dup 0) + (unspec_volatile:SWI48x + [(match_operand:SWI48x 2 "memory_operand") + (match_dup 0) + (match_operand:SWI48x 3 "register_operand") + (match_operand:SI 4 "const_int_operand")] + UNSPECV_CMPCCXADD)) + (set (match_dup 2) + (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD)) + (set (reg:CC FLAGS_REG) + (compare:CC (match_dup 2) + (match_dup 0)))]) + (set (reg FLAGS_REG) + (compare (match_operand:SWI48x 5 "register_operand") + (match_operand:SWI48x 6 "x86_64_general_operand"))) + (set (pc) + (if_then_else (match_operator 7 "ix86_comparison_int_operator" + [(reg FLAGS_REG) (const_int 0)]) + (label_ref (match_operand 8)) + (pc)))] + "TARGET_CMPCCXADD && TARGET_64BIT + && rtx_equal_p (operands[0], operands[6]) + && rtx_equal_p (operands[1], operands[5]) + && peep2_regno_dead_p (4, FLAGS_REG)" + [(set (match_dup 0) + (match_dup 1)) + (parallel [(set (match_dup 0) + (unspec_volatile:SWI48x + [(match_dup 2) + (match_dup 0) + (match_dup 3) + (match_dup 4)] + UNSPECV_CMPCCXADD)) + (set (match_dup 2) + (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD)) + (set (reg:CC FLAGS_REG) + (compare:CC (match_dup 2) + (match_dup 0)))]) + (set (pc) + (if_then_else + (match_op_dup 7 + [(match_dup 9) (const_int 0)]) + (label_ref (match_dup 8)) + (pc)))] +{ + operands[9] = gen_rtx_REG (GET_MODE (XEXP (operands[7], 0)), FLAGS_REG); + if (swap_condition (GET_CODE (operands[7])) != GET_CODE (operands[7])) + { + operands[7] = shallow_copy_rtx (operands[7]); + enum rtx_code ccode = swap_condition (GET_CODE (operands[7])); + PUT_CODE (operands[7], ccode); + operands[9] = gen_rtx_REG (SELECT_CC_MODE (ccode, + operands[6], + operands[5]), + FLAGS_REG); + } +}) diff --git a/gcc/testsuite/gcc.target/i386/pr110591-2.c b/gcc/testsuite/gcc.target/i386/pr110591-2.c new file mode 100644 index 0000000..92ffdb9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110591-2.c @@ -0,0 +1,90 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mcmpccxadd -O2 -fno-if-conversion -fno-if-conversion2" } */ +/* { dg-final { scan-assembler-not {cmp[lq]?[ \t]+} } } */ +/* { dg-final { scan-assembler-times {cmpoxadd[ \t]+} 12 } } */ + +#include + +int foo_jg (int *ptr, int v) +{ + if (_cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) > v) + return 100; + return 200; +} + +int foo_jl (int *ptr, int v) +{ + if (_cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) < v) + return 300; + return 100; +} + +int foo_je(int *ptr, int v) +{ + if (_cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) == v) + return 123; + return 134; +} + +int foo_jne(int *ptr, int v) +{ + if (_cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) != v) + return 111; + return 12; +} + +int foo_jge(int *ptr, int v) +{ + if (_cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) >= v) + return 413; + return 23; +} + +int foo_jle(int *ptr, int v) +{ + if (_cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) <= v) + return 3141; + return 341; +} + +int fooq_jg (long long *ptr, long long v) +{ + if (_cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) > v) + return 123; + return 3; +} + +int fooq_jl (long long *ptr, long long v) +{ + if (_cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) < v) + return 313; + return 5; +} + +int fooq_je(long long *ptr, long long v) +{ + if (_cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) == v) + return 1313; + return 13; +} + +int fooq_jne(long long *ptr, long long v) +{ + if (_cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) != v) + return 1314; + return 132; +} + +int fooq_jge(long long *ptr, long long v) +{ + if (_cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) >= v) + return 14314; + return 434; +} + +int fooq_jle(long long *ptr, long long v) +{ + if (_cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) <= v) + return 14414; + return 43; +} diff --git a/gcc/testsuite/gcc.target/i386/pr110591.c b/gcc/testsuite/gcc.target/i386/pr110591.c new file mode 100644 index 0000000..32a515b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110591.c @@ -0,0 +1,66 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mcmpccxadd -O2" } */ +/* { dg-final { scan-assembler-not {cmp[lq]?[ \t]+} } } */ +/* { dg-final { scan-assembler-times {cmpoxadd[ \t]+} 12 } } */ + +#include + +_Bool foo_setg (int *ptr, int v) +{ + return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) > v; +} + +_Bool foo_setl (int *ptr, int v) +{ + return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) < v; +} + +_Bool foo_sete(int *ptr, int v) +{ + return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) == v; +} + +_Bool foo_setne(int *ptr, int v) +{ + return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) != v; +} + +_Bool foo_setge(int *ptr, int v) +{ + return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) >= v; +} + +_Bool foo_setle(int *ptr, int v) +{ + return _cmpccxadd_epi32(ptr, v, 1, _CMPCCX_O) <= v; +} + +_Bool fooq_setg (long long *ptr, long long v) +{ + return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) > v; +} + +_Bool fooq_setl (long long *ptr, long long v) +{ + return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) < v; +} + +_Bool fooq_sete(long long *ptr, long long v) +{ + return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) == v; +} + +_Bool fooq_setne(long long *ptr, long long v) +{ + return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) != v; +} + +_Bool fooq_setge(long long *ptr, long long v) +{ + return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) >= v; +} + +_Bool fooq_setle(long long *ptr, long long v) +{ + return _cmpccxadd_epi64(ptr, v, 1, _CMPCCX_O) <= v; +} -- cgit v1.1 From c3f1768b21e9d994c4f090405e863feb06a54002 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Mon, 17 Jul 2023 12:50:17 +0800 Subject: Remove # from one_cmpl2 assemble output. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit optimize_insn_for_speed () in assemble output is not aligned with splitter condition, and it cause an ICE when building SPEC2017 blender_r. libpng/pngread.c: In function ‘png_read_image’: libpng/pngread.c:786:1: internal compiler error: in final_scan_insn_1, at final.cc:2813 786 | } | ^ 0x73ac3d final_scan_insn_1 ../../gcc/final.cc:2813 0xb3420b final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*) ../../gcc/final.cc:2887 0xb344c4 final_1 ../../gcc/final.cc:1979 0xb34f64 rest_of_handle_final ../../gcc/final.cc:4240 0xb34f64 execute ../../gcc/final.cc:4318 gcc/ChangeLog: PR target/110438 * config/i386/sse.md (one_cmpl2): Remove # from assemble output. --- gcc/config/i386/sse.md | 4 ---- 1 file changed, 4 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index c3fa241..2d81347 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -17243,10 +17243,6 @@ || mode == SImode || mode == DImode)" { - if (! && which_alternative - && optimize_insn_for_speed_p ()) - return "#"; - if (TARGET_AVX512VL) return "vpternlog\t{$0x55, %1, %0, %0|%0, %0, %1, 0x55}"; else -- cgit v1.1 From 6bab2772dbc42ce7a1b29b03ae84e6e434e23c4e Mon Sep 17 00:00:00 2001 From: Joern Rennecke Date: Tue, 18 Jul 2023 04:28:55 +0100 Subject: Tighten regexps in gcc.target/riscv/_Float16-zhinx-1.c . The original "mv" regexp would match .ascii "\254\254\375\002e2N6\013\231,\354NDmvVP0]\304\312F!biZ\025\211" in the .gnu.lto_foo1.0.32528183c9deec41 section. gcc/testsuite/ * gcc.target/riscv/_Float16-zhinx-1.c: Tighten regexps. --- gcc/testsuite/gcc.target/riscv/_Float16-zhinx-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/riscv/_Float16-zhinx-1.c b/gcc/testsuite/gcc.target/riscv/_Float16-zhinx-1.c index 90172b5..6782617 100644 --- a/gcc/testsuite/gcc.target/riscv/_Float16-zhinx-1.c +++ b/gcc/testsuite/gcc.target/riscv/_Float16-zhinx-1.c @@ -6,5 +6,5 @@ _Float16 foo1 (_Float16 a, _Float16 b) return b; } -/* { dg-final { scan-assembler-not "fmv.h" } } */ -/* { dg-final { scan-assembler-times "mv" 1 } } */ +/* { dg-final { scan-assembler-not {\mfmv\.h\M} } } */ +/* { dg-final { scan-assembler-times {\mmv\M} 1 } } */ -- cgit v1.1 From 615c2e555d34c2b17513c869b309b8f398376874 Mon Sep 17 00:00:00 2001 From: Juergen Christ Date: Tue, 18 Jul 2023 08:30:14 +0200 Subject: IBM zSystems: Optimize vec_cmpge followed by vec_sel A vec_cmpge produces a negation. Replace this negation by swapping the two selection choices of a vec_sel based on the result of the vec_cmpge. gcc/ChangeLog: * config/s390/vx-builtins.md: New vsel pattern. gcc/testsuite/ChangeLog: * gcc.target/s390/vector/vec-cmpge.c: New test. Signed-off-by: Juergen Christ --- gcc/config/s390/vx-builtins.md | 11 +++++++++++ gcc/testsuite/gcc.target/s390/vector/vec-cmpge.c | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 gcc/testsuite/gcc.target/s390/vector/vec-cmpge.c (limited to 'gcc') diff --git a/gcc/config/s390/vx-builtins.md b/gcc/config/s390/vx-builtins.md index f4248c5..10eae76 100644 --- a/gcc/config/s390/vx-builtins.md +++ b/gcc/config/s390/vx-builtins.md @@ -530,6 +530,17 @@ "vsel\t%v0,%1,%2,%3" [(set_attr "op_type" "VRR")]) +(define_insn "*vsel_swapped" + [(set (match_operand:V_HW_FT 0 "register_operand" "=v") + (ior:V_HW_FT + (and:V_HW_FT (not:V_HW_FT (match_operand:V_HW_FT 3 "register_operand" "v")) + (match_operand:V_HW_FT 1 "register_operand" "v")) + (and:V_HW_FT (match_dup 3) + (match_operand:V_HW_FT 2 "register_operand" "v"))))] + "TARGET_VX" + "vsel\t%v0,%2,%1,%3" + [(set_attr "op_type" "VRR")]) + ; Vector sign extend to doubleword diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-cmpge.c b/gcc/testsuite/gcc.target/s390/vector/vec-cmpge.c new file mode 100644 index 0000000..eb18869 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vec-cmpge.c @@ -0,0 +1,18 @@ +/* Check that vec_sel absorbs a negation generated by vec_cmpge. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z13" } */ + +typedef __attribute__((vector_size(16))) unsigned char uv16qi; + +#include + +void f(char *res, uv16qi ctrl) +{ + uv16qi a = vec_splat_u8(0xfe); + uv16qi b = vec_splat_u8(0x80); + uv16qi mask = vec_cmpge(ctrl, b); + *(uv16qi *)res = vec_sel(a, b, mask); +} + +/* { dg-final { scan-assembler-not "vno\t" } } */ -- cgit v1.1 From 74dc7f1a94e06095108b0ac30ca35d98f3a4bb9c Mon Sep 17 00:00:00 2001 From: Lehua Ding Date: Tue, 18 Jul 2023 14:47:28 +0800 Subject: RISC-V: Remove testcase that cannot be compiled because VLEN limitation Since the latter patch (https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624689.html) forbidden VLEN > 4096, the testcase attribute-20.c is no long need. This is obvious. gcc/testsuite/ChangeLog: * gcc.target/riscv/attribute-20.c: Removed. --- gcc/testsuite/gcc.target/riscv/attribute-20.c | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 gcc/testsuite/gcc.target/riscv/attribute-20.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/riscv/attribute-20.c b/gcc/testsuite/gcc.target/riscv/attribute-20.c deleted file mode 100644 index f7d0b29..0000000 --- a/gcc/testsuite/gcc.target/riscv/attribute-20.c +++ /dev/null @@ -1,7 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv_zvl65536b -mabi=lp64d" } */ -int foo() -{ -} - -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl1024b1p0_zvl128b1p0_zvl16384b1p0_zvl2048b1p0_zvl256b1p0_zvl32768b1p0_zvl32b1p0_zvl4096b1p0_zvl512b1p0_zvl64b1p0_zvl65536b1p0_zvl8192b1p0\"" } } */ -- cgit v1.1 From 48b7404707186856523b908f1720488bf87f6b49 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Tue, 18 Jul 2023 16:44:11 +0800 Subject: RISC-V: Enable SLP un-order reduction This patch is to enable SLP un-order reduction autao-vectorization Consider this following case: int __attribute__((noipa)) add_loop (int *x, int n, int res) { for (int i = 0; i < n; ++i) { res += x[i * 2]; res += x[i * 2 + 1]; } return res; } --param riscv-autovec-preference=scalable -fopt-info-vec-missed: :4:21: missed: couldn't vectorize loop :4:21: missed: unsupported SLP instances After this patch: add_loop: ble a1,zero,.L5 csrr a6,vlenb srli a4,a6,2 slli a1,a1,1 neg a7,a4 vsetvli t1,zero,e32,m1,ta,ma vmv.v.i v2,0 vslide1up.vx v1,v2,a2 -----------> generated by VEC_SHL_INSERT .L4: mv a3,a1 mv a5,a1 bleu a1,a4,.L3 mv a5,a4 .L3: vsetvli zero,a5,e32,m1,tu,ma add a1,a1,a7 vle32.v v2,0(a0) add a0,a0,a6 vadd.vv v1,v1,v2 bgtu a3,a4,.L4 vsetivli zero,1,e32,m1,ta,ma vmv.v.i v2,0 vsetvli t1,zero,e32,m1,ta,ma vredsum.vs v1,v1,v2 vmv.x.s a0,v1 ret .L5: mv a0,a2 ret gcc/ChangeLog: * config/riscv/autovec.md (vec_shl_insert_): New patterns. * config/riscv/riscv-v.cc (shuffle_compress_patterns): Fix bugs. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/reduc/reduc-5.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc-6.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc-7.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc-8.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc-9.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-5.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-6.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-7.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-8.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c: New test. --- gcc/config/riscv/autovec.md | 25 +++ gcc/config/riscv/riscv-v.cc | 4 + .../gcc.target/riscv/rvv/autovec/reduc/reduc-5.c | 88 ++++++++++ .../gcc.target/riscv/rvv/autovec/reduc/reduc-6.c | 6 + .../gcc.target/riscv/rvv/autovec/reduc/reduc-7.c | 88 ++++++++++ .../gcc.target/riscv/rvv/autovec/reduc/reduc-8.c | 16 ++ .../gcc.target/riscv/rvv/autovec/reduc/reduc-9.c | 16 ++ .../riscv/rvv/autovec/reduc/reduc_run-5.c | 61 +++++++ .../riscv/rvv/autovec/reduc/reduc_run-6.c | 6 + .../riscv/rvv/autovec/reduc/reduc_run-7.c | 188 +++++++++++++++++++++ .../riscv/rvv/autovec/reduc/reduc_run-8.c | 22 +++ .../riscv/rvv/autovec/reduc/reduc_run-9.c | 22 +++ 12 files changed, 542 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 8cdec75..cd5b194 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -372,6 +372,31 @@ } ) +;; Slide an RVV vector left and insert a scalar into element 0. +(define_expand "vec_shl_insert_" + [(match_operand:VI 0 "register_operand") + (match_operand:VI 1 "register_operand") + (match_operand: 2 "reg_or_0_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred_slide (UNSPEC_VSLIDE1UP, mode); + rtx ops[] = {operands[0], RVV_VUNDEF (mode), operands[1], operands[2]}; + riscv_vector::emit_vlmax_slide_insn (icode, ops); + DONE; +}) + +(define_expand "vec_shl_insert_" + [(match_operand:VF 0 "register_operand") + (match_operand:VF 1 "register_operand") + (match_operand: 2 "register_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred_slide (UNSPEC_VFSLIDE1UP, mode); + rtx ops[] = {operands[0], RVV_VUNDEF (mode), operands[1], operands[2]}; + riscv_vector::emit_vlmax_slide_insn (icode, ops); + DONE; +}) + ;; ======================================================================== ;; == Vector operations ;; ========================================================================= diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index b4884a3..ff1e682 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2823,6 +2823,10 @@ shuffle_compress_patterns (struct expand_vec_perm_d *d) if (known_le (d->perm[i], d->perm[i - 1])) return false; + /* Success! */ + if (d->testing_p) + return true; + /* Check whether we need to slideup op1 to apply compress approach. E.g. For index = { 0, 2, 6, 7}, since d->perm[i - 1] = 7 which diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-5.c new file mode 100644 index 0000000..e973041 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-5.c @@ -0,0 +1,88 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math -fno-vect-cost-model" } */ + +#include + +void __attribute__((noipa)) +add_loop (unsigned int *x, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < 0x7ff; ++i) + { + res0 += x[i * 2]; + res1 += x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +min_loop (unsigned int *x, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < 0x7ff; ++i) + { + res0 = res0 < x[i * 2] ? res0 : x[i * 2]; + res1 = res1 < x[i * 2 + 1] ? res1 : x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +max_loop (unsigned int *x, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < 0x7ff; ++i) + { + res0 = res0 > x[i * 2] ? res0 : x[i * 2]; + res1 = res1 > x[i * 2 + 1] ? res1 : x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +and_loop (unsigned int *x, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < 0x7ff; ++i) + { + res0 &= x[i * 2]; + res1 &= x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +or_loop (unsigned int *x, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < 0x7ff; ++i) + { + res0 |= x[i * 2]; + res1 |= x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +eor_loop (unsigned int *x, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < 0x7ff; ++i) + { + res0 ^= x[i * 2]; + res1 ^= x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-6.c new file mode 100644 index 0000000..30961f0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-6.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model -fdump-tree-optimized-details" } */ + +#include "reduc-5.c" + +/* { dg-final { scan-tree-dump-times "VEC_SHL_INSERT" 8 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-7.c new file mode 100644 index 0000000..e2e65be --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-7.c @@ -0,0 +1,88 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model -fdump-tree-optimized-details" } */ + +void __attribute__((noipa)) +add_loop (unsigned int *x, int n, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < n; ++i) + { + res0 += x[i * 2]; + res1 += x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +min_loop (unsigned int *x, int n, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < n; ++i) + { + res0 = res0 < x[i * 2] ? res0 : x[i * 2]; + res1 = res1 < x[i * 2 + 1] ? res1 : x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +max_loop (unsigned int *x, int n, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < n; ++i) + { + res0 = res0 > x[i * 2] ? res0 : x[i * 2]; + res1 = res1 > x[i * 2 + 1] ? res1 : x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +and_loop (unsigned int *x, int n, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < n; ++i) + { + res0 &= x[i * 2]; + res1 &= x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +or_loop (unsigned int *x, int n, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < n; ++i) + { + res0 |= x[i * 2]; + res1 |= x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +void __attribute__((noipa)) +eor_loop (unsigned int *x, int n, unsigned int *res) +{ + unsigned int res0 = res[0]; + unsigned int res1 = res[1]; + for (int i = 0; i < n; ++i) + { + res0 ^= x[i * 2]; + res1 ^= x[i * 2 + 1]; + } + res[0] = res0; + res[1] = res1; +} + +/* { dg-final { scan-tree-dump-times "VEC_SHL_INSERT" 8 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c new file mode 100644 index 0000000..4cbcccd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model -fdump-tree-optimized-details" } */ + +int __attribute__((noipa)) +add_loop (int *x, int n, int res) +{ + for (int i = 0; i < n; ++i) + { + res += x[i * 2]; + res += x[i * 2 + 1]; + } + return res; +} + +/* { dg-final { scan-tree-dump-times "VEC_SHL_INSERT" 1 "optimized" } } */ +/* { dg-final { scan-assembler-times {vslide1up\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-9.c new file mode 100644 index 0000000..6810561 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-9.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model -fdump-tree-optimized-details" } */ + +float __attribute__((noipa)) +add_loop (float *x, int n, float res) +{ + for (int i = 0; i < n; ++i) + { + res += x[i * 2]; + res += x[i * 2 + 1]; + } + return res; +} + +/* { dg-final { scan-tree-dump-times "VEC_SHL_INSERT" 1 "optimized" } } */ +/* { dg-final { scan-assembler-times {vfslide1up\.vf\s+v[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-5.c new file mode 100644 index 0000000..c47463d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-5.c @@ -0,0 +1,61 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=fixed-vlmax -ffast-math -fno-vect-cost-model" } */ + +#define N 0x1100 + +#include "reduc-5.c" + +int +main (void) +{ + unsigned int x[N]; + for (int i = 0; i < N; ++i) + x[i] = ((i + 1) * (i + 2)) & 0xfffff; + + unsigned int add_res[2] = { 42, 1111 }; + add_loop (x, add_res); + if (add_res[0] != 968538154 + || add_res[1] != 964340823) + __builtin_abort (); + + unsigned int max_res1[2] = { 0, 0 }; + max_loop (x, max_res1); + if (max_res1[0] != 1048150 + || max_res1[1] != 1045506) + __builtin_abort (); + + unsigned int max_res2[2] = { 1048151, 1045507 }; + max_loop (x, max_res2); + if (max_res2[0] != 1048151 + || max_res2[1] != 1045507) + __builtin_abort (); + + unsigned int or_res[2] = { 0x1000000, 0x2000000 }; + or_loop (x, or_res); + if (or_res[0] != 0x10ffffe + || or_res[1] != 0x20ffffe) + __builtin_abort (); + + unsigned int eor_res[2] = { 0x1000000, 0x2000000 }; + eor_loop (x, eor_res); + if (eor_res[0] != 0x1010000 + || eor_res[1] != 0x20b5000) + __builtin_abort (); + + for (int i = 0; i < N; ++i) + x[i] = ~x[i] & 0xfffff; + + unsigned int min_res1[2] = { 500, 4000 }; + min_loop (x, min_res1); + if (min_res1[0] != 425 + || min_res1[1] != 3069) + __builtin_abort (); + + unsigned int min_res2[2] = { 424, 3068 }; + min_loop (x, min_res2); + if (min_res2[0] != 424 + || min_res2[1] != 3068) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-6.c new file mode 100644 index 0000000..540b2e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-6.c @@ -0,0 +1,6 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#define N 0x1100 + +#include "reduc_run-5.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-7.c new file mode 100644 index 0000000..cc141dc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-7.c @@ -0,0 +1,188 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#define N 0x1100 + +#include "reduc-7.c" + + +int +main (void) +{ + unsigned int x[N]; + for (int i = 0; i < N; ++i) + x[i] = ((i + 1) * (i + 2)) & 0xfffff; + + unsigned int add_res1[2] = { 11, 22 }; + add_loop (x, 0, add_res1); + if (add_res1[0] != 11 + || add_res1[1] != 22) + __builtin_abort (); + + unsigned int add_res2[2] = { 10, 20 }; + add_loop (x, 11, add_res2); + if (add_res2[0] != 1902 + || add_res2[1] != 2176) + __builtin_abort (); + + unsigned int add_res3[2] = { 15, 30 }; + add_loop (x, 0x100, add_res3); + if (add_res3[0] != 22435087 + || add_res3[1] != 22566686) + __builtin_abort (); + + unsigned int add_res4[2] = { 100, 200 }; + add_loop (x, 0x11f, add_res4); + if (add_res4[0] != 31602244 + || add_res4[1] != 31767656) + __builtin_abort (); + + unsigned int max_res1[2] = { 461, 500 }; + max_loop (x, 11, max_res1); + if (max_res1[0] != 462 + || max_res1[1] != 506) + __builtin_abort (); + + unsigned int max_res2[2] = { 463, 507 }; + max_loop (x, 11, max_res2); + if (max_res2[0] != 463 + || max_res2[1] != 507) + __builtin_abort (); + + unsigned int max_res3[2] = { 1000000, 1000000 }; + max_loop (x, 0x200, max_res3); + if (max_res3[0] != 1047552 + || max_res3[1] != 1045506) + __builtin_abort (); + + unsigned int max_res4[2] = { 1047553, 1045507 }; + max_loop (x, 0x200, max_res4); + if (max_res4[0] != 1047553 + || max_res4[1] != 1045507) + __builtin_abort (); + + unsigned int max_res5[2] = { 300000, 30000 }; + max_loop (x, 0x11f, max_res5); + if (max_res5[0] != 328902 + || max_res5[1] != 330050) + __builtin_abort (); + + unsigned int max_res6[2] = { 328903, 330051 }; + max_loop (x, 0x11f, max_res6); + if (max_res6[0] != 328903 + || max_res6[1] != 330051) + __builtin_abort (); + + unsigned int or_res1[2] = { 11, 22 }; + or_loop (x, 0, or_res1); + if (or_res1[0] != 11 + || or_res1[1] != 22) + __builtin_abort (); + + unsigned int or_res2[2] = { 0x200000, 0xe00000 }; + or_loop (x, 11, or_res2); + if (or_res2[0] != 0x2001fe + || or_res2[1] != 0xe001fe) + __builtin_abort (); + + unsigned int or_res3[2] = { 0x800000, 0x700000 }; + or_loop (x, 0x40, or_res3); + if (or_res3[0] != 0x803ffe + || or_res3[1] != 0x707ffe) + __builtin_abort (); + + unsigned int or_res4[2] = { 0x100001, 0x300000 }; + or_loop (x, 0x4f, or_res4); + if (or_res4[0] != 0x107fff + || or_res4[1] != 0x307ffe) + __builtin_abort (); + + unsigned int eor_res1[2] = { 11, 22 }; + eor_loop (x, 0, eor_res1); + if (eor_res1[0] != 11 + || eor_res1[1] != 22) + __builtin_abort (); + + unsigned int eor_res2[2] = { 0x2000ff, 0xe000ff }; + eor_loop (x, 11, eor_res2); + if (eor_res2[0] != 0x2001cf + || eor_res2[1] != 0xe000b7) + __builtin_abort (); + + unsigned int eor_res3[2] = { 0x805000, 0x70f000 }; + eor_loop (x, 0x100, eor_res3); + if (eor_res3[0] != 0x824200 + || eor_res3[1] != 0x77dc00) + __builtin_abort (); + + unsigned int eor_res4[2] = { 0x101201, 0x300f00 }; + eor_loop (x, 0x11f, eor_res4); + if (eor_res4[0] != 0x178801 + || eor_res4[1] != 0x337240) + __builtin_abort (); + + for (int i = 0; i < N; ++i) + x[i] = ~x[i] & 0xfffff; + + unsigned int min_res1[2] = { 1048200, 1048100 }; + min_loop (x, 11, min_res1); + if (min_res1[0] != 1048113 + || min_res1[1] != 1048069) + __builtin_abort (); + + unsigned int min_res2[2] = { 1048112, 1048068 }; + min_loop (x, 11, min_res2); + if (min_res2[0] != 1048112 + || min_res2[1] != 1048068) + __builtin_abort (); + + unsigned int min_res3[2] = { 10000, 10000 }; + min_loop (x, 0x200, min_res3); + if (min_res3[0] != 1023 + || min_res3[1] != 3069) + __builtin_abort (); + + unsigned int min_res4[2] = { 1022, 3068 }; + min_loop (x, 0x200, min_res4); + if (min_res4[0] != 1022 + || min_res4[1] != 3068) + __builtin_abort (); + + unsigned int min_res5[2] = { 719680, 718530 }; + min_loop (x, 0x11f, min_res5); + if (min_res5[0] != 719673 + || min_res5[1] != 718525) + __builtin_abort (); + + unsigned int min_res6[2] = { 719672, 718524 }; + min_loop (x, 0x11f, min_res6); + if (min_res6[0] != 719672 + || min_res6[1] != 718524) + __builtin_abort (); + + unsigned int and_res1[2] = { 11, 22 }; + and_loop (x, 0, and_res1); + if (and_res1[0] != 11 + || and_res1[1] != 22) + __builtin_abort (); + + unsigned int and_res2[2] = { 0xf5cff, 0xf78ff }; + and_loop (x, 11, and_res2); + if (and_res2[0] != 0xf5c01 + || and_res2[1] != 0xf7801) + __builtin_abort (); + + unsigned int and_res3[2] = { 0x7efff, 0xecfff }; + and_loop (x, 0x40, and_res3); + if (and_res3[0] != 0x7c001 + || and_res3[1] != 0xe8001) + __builtin_abort (); + + unsigned int and_res4[2] = { 0xffffff, 0xffffff }; + and_loop (x, 0x4f, and_res4); + if (and_res4[0] != 0xf8001 + || and_res4[1] != 0xf8001) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-8.c new file mode 100644 index 0000000..07fa76d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-8.c @@ -0,0 +1,22 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#define N 0x1100 + +#include "reduc-8.c" + +int +main (void) +{ + int x[N]; + for (int i = 0; i < N; ++i) + x[i] = ((i + 1) * (i + 2)) & 0xfffff; + + if (add_loop (x, 0, 33) != 33 + || add_loop (x, 11, 30) != 4078 + || add_loop (x, 0x100, 45) != 45001773 + || add_loop (x, 0x11f, 300) != 63369900) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c new file mode 100644 index 0000000..47f8082 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c @@ -0,0 +1,22 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ + +#define N 0x1100 + +#include "reduc-9.c" + +int +main (void) +{ + float x[N]; + for (int i = 0; i < N; ++i) + x[i] = ((i + 1) * (i + 2)) & 0xfffff; + + if (add_loop (x, 0, 33) != 33 + || add_loop (x, 11, 30) != 4078 + || add_loop (x, 0x100, 45) != 45001773 + || add_loop (x, 0x11f, 300) != 63369900) + __builtin_abort (); + + return 0; +} -- cgit v1.1 From bd93ef7f1a178079c6cdaccdf953f79a3365b028 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Tue, 18 Jul 2023 14:27:39 +0800 Subject: RISC-V: Dynamic adjust size of VLA vector according to TARGET_MIN_VLEN This patch is to dynamic adjust size of VLA vectors according to TARGET_MIN_VLEN (-march=*zvl*b). Currently, VNx16QImode is always [16,16] when TARGET_MINV_LEN >= 128. We are going to add a bunch of VLS modes (V16QI,V32QI,....etc), these modes should always be considered as having smaller size than VLA vectors. For example, the V32QImode is LMUL = 1 VLS mode when TARGET_MIN_VLEN = 256 and V16QImode is LMUL = 1 VLS mode when TARGET_MINV_LEN = 128. Since a LMUL = 1 VLA mode VNx16QI is always [16,16] before this patch, when TARGET_MIN_VLEN = 128, VNx16QImode ([16,16]) > V16QImode. when TARGET_MIN_VLEN = 256, VNx16QImode ([16,16]) possible < V32QImode. Then such inconsistency (TARGET_MIN_VLEN = 128, regno_reg_rtx[97] is VLA modes wheras it is VLS modes when TARGET_MIN_VLEN = 256). This patch now adjust VLA vector size accurately according to TARGET_MIN_VLEN which make things more reasonable: VNx16QI = [16,16] if TARGET_MIN_VLEN = 128. VNx16QI = [32,32] if TARGET_MIN_VLEN = 256. VNx16QI = [64,64] if TARGET_MIN_VLEN = 512. VNx16QI = [128,128] if TARGET_MIN_VLEN = 1024. VNx16QI = [256,256] if TARGET_MIN_VLEN = 2048. VNx16QI = [512,512] if TARGET_MIN_VLEN = 4096. gcc/ChangeLog: * config/riscv/riscv-selftests.cc (run_poly_int_selftests): Add more selftests. * config/riscv/riscv.cc (riscv_legitimize_poly_move): Dynamic adjust size of VLA vectors. (riscv_convert_vector_bits): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/zve32f_zvl1024b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32f_zvl2048b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32f_zvl4096b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32f_zvl512b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32x_zvl1024b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32x_zvl2048b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32x_zvl4096b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve32x_zvl512b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64d_zvl1024b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64d_zvl2048b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64d_zvl256b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64d_zvl4096b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64d_zvl512b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64f_zvl1024b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64f_zvl2048b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64f_zvl256b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64f_zvl4096b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64f_zvl512b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64x_zvl1024b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64x_zvl2048b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64x_zvl256b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64x_zvl4096b-1.c: New test. * gcc.target/riscv/rvv/autovec/zve64x_zvl512b-1.c: New test. --- gcc/config/riscv/riscv-selftests.cc | 10 ++++++ gcc/config/riscv/riscv.cc | 37 +++++++++++++++------- .../riscv/rvv/autovec/zve32f_zvl1024b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32f_zvl2048b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32f_zvl256b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32f_zvl4096b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32f_zvl512b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32x_zvl1024b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32x_zvl2048b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32x_zvl256b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32x_zvl4096b-1.c | 6 ++++ .../riscv/rvv/autovec/zve32x_zvl512b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64d_zvl1024b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64d_zvl2048b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64d_zvl256b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64d_zvl4096b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64d_zvl512b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64f_zvl1024b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64f_zvl2048b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64f_zvl256b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64f_zvl4096b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64f_zvl512b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64x_zvl1024b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64x_zvl2048b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64x_zvl256b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64x_zvl4096b-1.c | 6 ++++ .../riscv/rvv/autovec/zve64x_zvl512b-1.c | 6 ++++ 27 files changed, 185 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl1024b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl2048b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl4096b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl512b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl1024b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl2048b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl4096b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl512b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl1024b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl2048b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl256b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl4096b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl512b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl1024b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl2048b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl256b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl4096b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl512b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl1024b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl2048b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl256b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl4096b-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl512b-1.c (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-selftests.cc b/gcc/config/riscv/riscv-selftests.cc index 1bf1a64..b16b5c1 100644 --- a/gcc/config/riscv/riscv-selftests.cc +++ b/gcc/config/riscv/riscv-selftests.cc @@ -232,6 +232,16 @@ run_poly_int_selftests (void) worklist); run_poly_int_selftest ("rv32imafd_zve32x1p0", ABI_ILP32D, POLY_TEST_DIMODE, worklist); + simple_poly_selftest ("rv64imafdv_zvl256b", ABI_LP64D, + {QImode, HImode, SImode, DImode}); + simple_poly_selftest ("rv64imafdv_zvl512b", ABI_LP64D, + {QImode, HImode, SImode, DImode}); + simple_poly_selftest ("rv64imafdv_zvl1024b", ABI_LP64D, + {QImode, HImode, SImode, DImode}); + simple_poly_selftest ("rv64imafdv_zvl2048b", ABI_LP64D, + {QImode, HImode, SImode, DImode}); + simple_poly_selftest ("rv64imafdv_zvl4096b", ABI_LP64D, + {QImode, HImode, SImode, DImode}); } static void diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index d51d6bd..f1f5a73 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2055,18 +2055,21 @@ riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src) riscv_emit_move (dest, GEN_INT (value.to_constant ())); return; } - else if ((factor % vlenb) == 0) - div_factor = 1; - else if ((factor % (vlenb / 2)) == 0) - div_factor = 2; - else if ((factor % (vlenb / 4)) == 0) - div_factor = 4; - else if ((factor % (vlenb / 8)) == 0) - div_factor = 8; - else if ((factor % (vlenb / 16)) == 0) - div_factor = 16; else - gcc_unreachable (); + { + /* FIXME: We currently DON'T support TARGET_MIN_VLEN > 4096. */ + int max_power = exact_log2 (4096 / 128); + for (int i = 0; i < max_power; i++) + { + int possible_div_factor = 1 << i; + if (factor % (vlenb / possible_div_factor) == 0) + { + div_factor = possible_div_factor; + break; + } + } + gcc_assert (div_factor != 0); + } if (div_factor != 1) riscv_expand_op (LSHIFTRT, mode, tmp, tmp, @@ -6479,6 +6482,7 @@ riscv_init_machine_status (void) static poly_uint16 riscv_convert_vector_bits (void) { + int chunk_num = 1; if (TARGET_MIN_VLEN >= 128) { /* We have Full 'V' extension for application processors. It's specified @@ -6486,6 +6490,15 @@ riscv_convert_vector_bits (void) and Zve64d extensions. Thus the number of bytes in a vector is 16 + 16 * x1 which is riscv_vector_chunks * 16 = poly_int (16, 16). */ riscv_bytes_per_vector_chunk = 16; + /* Adjust BYTES_PER_RISCV_VECTOR according to TARGET_MIN_VLEN: + - TARGET_MIN_VLEN = 128bit: [16,16] + - TARGET_MIN_VLEN = 256bit: [32,32] + - TARGET_MIN_VLEN = 512bit: [64,64] + - TARGET_MIN_VLEN = 1024bit: [128,128] + - TARGET_MIN_VLEN = 2048bit: [256,256] + - TARGET_MIN_VLEN = 4096bit: [512,512] + FIXME: We currently DON'T support TARGET_MIN_VLEN > 4096bit. */ + chunk_num = TARGET_MIN_VLEN / 128; } else if (TARGET_MIN_VLEN > 32) { @@ -6518,7 +6531,7 @@ riscv_convert_vector_bits (void) if (riscv_autovec_preference == RVV_FIXED_VLMAX) return (int) TARGET_MIN_VLEN / (riscv_bytes_per_vector_chunk * 8); else - return poly_uint16 (1, 1); + return poly_uint16 (chunk_num, chunk_num); } else return 1; diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl1024b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl1024b-1.c new file mode 100644 index 0000000..54a36ae --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl1024b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32f_zvl1024b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 4 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl2048b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl2048b-1.c new file mode 100644 index 0000000..754aee2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl2048b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32f_zvl2048b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 4 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c new file mode 100644 index 0000000..52a2c2b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32f_zvl256b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 4 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl4096b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl4096b-1.c new file mode 100644 index 0000000..7a911d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl4096b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32f_zvl4096b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 4 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl512b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl512b-1.c new file mode 100644 index 0000000..8d26abb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl512b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32f_zvl512b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 4 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl1024b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl1024b-1.c new file mode 100644 index 0000000..15c4816 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl1024b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32x_zvl1024b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl2048b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl2048b-1.c new file mode 100644 index 0000000..46be1f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl2048b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32x_zvl2048b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c new file mode 100644 index 0000000..90e3084 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32x_zvl256b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl4096b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl4096b-1.c new file mode 100644 index 0000000..02ac73b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl4096b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32x_zvl4096b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl512b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl512b-1.c new file mode 100644 index 0000000..50cbfe1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl512b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve32x_zvl512b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl1024b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl1024b-1.c new file mode 100644 index 0000000..013af76 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl1024b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64d_zvl1024b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 6 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl2048b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl2048b-1.c new file mode 100644 index 0000000..9cfcdf1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl2048b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64d_zvl2048b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 6 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl256b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl256b-1.c new file mode 100644 index 0000000..e0c0aea --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl256b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64d_zvl256b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 6 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl4096b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl4096b-1.c new file mode 100644 index 0000000..b823e63 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl4096b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64d_zvl4096b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 6 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl512b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl512b-1.c new file mode 100644 index 0000000..6824b74 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64d_zvl512b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64d_zvl512b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 6 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl1024b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl1024b-1.c new file mode 100644 index 0000000..cc4fabd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl1024b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64f_zvl1024b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 5 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl2048b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl2048b-1.c new file mode 100644 index 0000000..5f9acbb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl2048b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64f_zvl2048b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 5 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl256b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl256b-1.c new file mode 100644 index 0000000..b3debc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl256b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64f_zvl256b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 5 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl4096b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl4096b-1.c new file mode 100644 index 0000000..5f9acbb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl4096b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64f_zvl2048b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 5 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl512b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl512b-1.c new file mode 100644 index 0000000..6e99d37 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64f_zvl512b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64f_zvl512b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 5 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl1024b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl1024b-1.c new file mode 100644 index 0000000..b3d17c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl1024b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64x_zvl1024b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 3 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl2048b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl2048b-1.c new file mode 100644 index 0000000..b110771 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl2048b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64x_zvl2048b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 3 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl256b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl256b-1.c new file mode 100644 index 0000000..509d75d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl256b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64x_zvl256b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 3 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl4096b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl4096b-1.c new file mode 100644 index 0000000..0410eba --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl4096b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64x_zvl4096b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 3 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl512b-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl512b-1.c new file mode 100644 index 0000000..2af91a2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve64x_zvl512b-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zve64x_zvl512b -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +#include "template-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 3 "vect" } } */ -- cgit v1.1 From f31a63438347c628a64257cb909a400cbd5388e3 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 2 Jul 2023 10:07:55 +0200 Subject: ada: Fix Valid_Scalars attribute applied to types from limited with The attribute is wrongly computed as always True because, unlike for e.g. private types, Validated_View does not look through the limited view. gcc/ada/ * sem_util.ads (Validated_View): Document enhanced behavior. * sem_util.adb (Validated_View): Return the nonlimited view, if any, of types coming from a limited with. --- gcc/ada/sem_util.adb | 7 +++++++ gcc/ada/sem_util.ads | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 821aacf..222fd72 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -29231,6 +29231,13 @@ package body Sem_Util is return Typ; end if; + elsif From_Limited_With (Typ) then + if Has_Non_Limited_View (Typ) then + return Validated_View (Non_Limited_View (Typ)); + else + return Typ; + end if; + else return Typ; end if; diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index 3751fb7..7fc77de 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -3331,8 +3331,8 @@ package Sem_Util is function Validated_View (Typ : Entity_Id) return Entity_Id; -- Obtain the "validated view" of arbitrary type Typ which is suitable for -- verification by attribute 'Valid_Scalars. This view is the type itself - -- or its full view while stripping away concurrency, derivations, and - -- privacy. + -- or its full view or nonlimited view, while stripping away concurrency, + -- derivations, and privacy. function Visible_Ancestors (Typ : Entity_Id) return Elist_Id; -- [Ada 2012:AI-0125-1]: Collect all the visible parents and progenitors -- cgit v1.1 From 7e7c40617a6f210b5a4c7cf63970a92bd0b9ec6a Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Fri, 30 Jun 2023 14:51:53 +0200 Subject: ada: Allow warnings with explain code Change the way explain codes are handled to generate the command for the user to get the explanations, as this was not working for warnings. gcc/ada/ * errout.adb (Error_Msg_Internal): Remove call to Prescan_Message on the special continuation for the explain code command, as this does not play well with the setting of global variables for the message (like its status as a warning or not). Instead, set directly the global variables regarding content of the message in terms of special characters. --- gcc/ada/errout.adb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb index adc2608..ac6491c 100644 --- a/gcc/ada/errout.adb +++ b/gcc/ada/errout.adb @@ -1451,10 +1451,12 @@ package body Errout is if Has_Error_Code then declare Msg : constant String := - "launch ""gnatprove --explain=[]"" for more information"; + "\launch ""gnatprove --explain=[]"" for more information"; begin - Prescan_Message (Msg); + Has_Double_Exclam := False; Has_Error_Code := False; + Has_Insertion_Line := False; + Error_Msg_Internal (Msg => Msg, Span => Span, -- cgit v1.1 From 22b13ca246cbef5c7ad5b9cd5eef5cb238494c5a Mon Sep 17 00:00:00 2001 From: Vasiliy Fofanov Date: Fri, 30 Jun 2023 12:22:47 +0000 Subject: ada: Refactor s-pack* units to remove multiple returns The aim of this refactoring is to replace multiple returns from branches of case and if statements by a single return statement with a conditional expression. This is more readable and maintainable, and also conformant with a Highly Recommended design principle of ISO 26262-6. gcc/ada/ * libgnat/s-pack03.adb: Update copyright year; refactor return statements. * libgnat/s-pack05.adb: Likewise. * libgnat/s-pack06.adb: Likewise. * libgnat/s-pack07.adb: Likewise. * libgnat/s-pack09.adb: Likewise. * libgnat/s-pack10.adb: Likewise. * libgnat/s-pack100.adb: Likewise. * libgnat/s-pack101.adb: Likewise. * libgnat/s-pack102.adb: Likewise. * libgnat/s-pack103.adb: Likewise. * libgnat/s-pack104.adb: Likewise. * libgnat/s-pack105.adb: Likewise. * libgnat/s-pack106.adb: Likewise. * libgnat/s-pack107.adb: Likewise. * libgnat/s-pack108.adb: Likewise. * libgnat/s-pack109.adb: Likewise. * libgnat/s-pack11.adb: Likewise. * libgnat/s-pack110.adb: Likewise. * libgnat/s-pack111.adb: Likewise. * libgnat/s-pack112.adb: Likewise. * libgnat/s-pack113.adb: Likewise. * libgnat/s-pack114.adb: Likewise. * libgnat/s-pack115.adb: Likewise. * libgnat/s-pack116.adb: Likewise. * libgnat/s-pack117.adb: Likewise. * libgnat/s-pack118.adb: Likewise. * libgnat/s-pack119.adb: Likewise. * libgnat/s-pack12.adb: Likewise. * libgnat/s-pack120.adb: Likewise. * libgnat/s-pack121.adb: Likewise. * libgnat/s-pack122.adb: Likewise. * libgnat/s-pack123.adb: Likewise. * libgnat/s-pack124.adb: Likewise. * libgnat/s-pack125.adb: Likewise. * libgnat/s-pack126.adb: Likewise. * libgnat/s-pack127.adb: Likewise. * libgnat/s-pack13.adb: Likewise. * libgnat/s-pack14.adb: Likewise. * libgnat/s-pack15.adb: Likewise. * libgnat/s-pack17.adb: Likewise. * libgnat/s-pack18.adb: Likewise. * libgnat/s-pack19.adb: Likewise. * libgnat/s-pack20.adb: Likewise. * libgnat/s-pack21.adb: Likewise. * libgnat/s-pack22.adb: Likewise. * libgnat/s-pack23.adb: Likewise. * libgnat/s-pack24.adb: Likewise. * libgnat/s-pack25.adb: Likewise. * libgnat/s-pack26.adb: Likewise. * libgnat/s-pack27.adb: Likewise. * libgnat/s-pack28.adb: Likewise. * libgnat/s-pack29.adb: Likewise. * libgnat/s-pack30.adb: Likewise. * libgnat/s-pack31.adb: Likewise. * libgnat/s-pack33.adb: Likewise. * libgnat/s-pack34.adb: Likewise. * libgnat/s-pack35.adb: Likewise. * libgnat/s-pack36.adb: Likewise. * libgnat/s-pack37.adb: Likewise. * libgnat/s-pack38.adb: Likewise. * libgnat/s-pack39.adb: Likewise. * libgnat/s-pack40.adb: Likewise. * libgnat/s-pack41.adb: Likewise. * libgnat/s-pack42.adb: Likewise. * libgnat/s-pack43.adb: Likewise. * libgnat/s-pack44.adb: Likewise. * libgnat/s-pack45.adb: Likewise. * libgnat/s-pack46.adb: Likewise. * libgnat/s-pack47.adb: Likewise. * libgnat/s-pack48.adb: Likewise. * libgnat/s-pack49.adb: Likewise. * libgnat/s-pack50.adb: Likewise. * libgnat/s-pack51.adb: Likewise. * libgnat/s-pack52.adb: Likewise. * libgnat/s-pack53.adb: Likewise. * libgnat/s-pack54.adb: Likewise. * libgnat/s-pack55.adb: Likewise. * libgnat/s-pack56.adb: Likewise. * libgnat/s-pack57.adb: Likewise. * libgnat/s-pack58.adb: Likewise. * libgnat/s-pack59.adb: Likewise. * libgnat/s-pack60.adb: Likewise. * libgnat/s-pack61.adb: Likewise. * libgnat/s-pack62.adb: Likewise. * libgnat/s-pack63.adb: Likewise. * libgnat/s-pack65.adb: Likewise. * libgnat/s-pack66.adb: Likewise. * libgnat/s-pack67.adb: Likewise. * libgnat/s-pack68.adb: Likewise. * libgnat/s-pack69.adb: Likewise. * libgnat/s-pack70.adb: Likewise. * libgnat/s-pack71.adb: Likewise. * libgnat/s-pack72.adb: Likewise. * libgnat/s-pack73.adb: Likewise. * libgnat/s-pack74.adb: Likewise. * libgnat/s-pack75.adb: Likewise. * libgnat/s-pack76.adb: Likewise. * libgnat/s-pack77.adb: Likewise. * libgnat/s-pack78.adb: Likewise. * libgnat/s-pack79.adb: Likewise. * libgnat/s-pack80.adb: Likewise. * libgnat/s-pack81.adb: Likewise. * libgnat/s-pack82.adb: Likewise. * libgnat/s-pack83.adb: Likewise. * libgnat/s-pack84.adb: Likewise. * libgnat/s-pack85.adb: Likewise. * libgnat/s-pack86.adb: Likewise. * libgnat/s-pack87.adb: Likewise. * libgnat/s-pack88.adb: Likewise. * libgnat/s-pack89.adb: Likewise. * libgnat/s-pack90.adb: Likewise. * libgnat/s-pack91.adb: Likewise. * libgnat/s-pack92.adb: Likewise. * libgnat/s-pack93.adb: Likewise. * libgnat/s-pack94.adb: Likewise. * libgnat/s-pack95.adb: Likewise. * libgnat/s-pack96.adb: Likewise. * libgnat/s-pack97.adb: Likewise. * libgnat/s-pack98.adb: Likewise. * libgnat/s-pack99.adb: Likewise. --- gcc/ada/libgnat/s-pack03.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack05.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack06.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack07.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack09.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack10.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack100.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack101.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack102.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack103.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack104.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack105.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack106.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack107.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack108.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack109.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack11.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack110.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack111.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack112.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack113.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack114.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack115.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack116.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack117.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack118.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack119.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack12.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack120.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack121.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack122.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack123.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack124.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack125.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack126.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack127.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack13.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack14.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack15.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack17.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack18.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack19.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack20.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack21.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack22.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack23.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack24.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack25.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack26.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack27.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack28.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack29.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack30.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack31.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack33.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack34.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack35.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack36.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack37.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack38.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack39.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack40.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack41.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack42.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack43.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack44.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack45.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack46.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack47.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack48.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack49.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack50.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack51.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack52.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack53.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack54.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack55.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack56.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack57.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack58.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack59.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack60.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack61.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack62.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack63.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack65.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack66.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack67.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack68.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack69.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack70.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack71.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack72.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack73.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack74.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack75.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack76.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack77.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack78.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack79.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack80.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack81.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack82.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack83.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack84.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack85.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack86.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack87.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack88.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack89.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack90.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack91.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack92.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack93.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack94.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack95.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack96.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack97.adb | 47 +++++++++++----------- gcc/ada/libgnat/s-pack98.adb | 94 +++++++++++++++++++++---------------------- gcc/ada/libgnat/s-pack99.adb | 47 +++++++++++----------- 120 files changed, 4071 insertions(+), 4248 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/libgnat/s-pack03.adb b/gcc/ada/libgnat/s-pack03.adb index c9fb938..85e18a2 100644 --- a/gcc/ada/libgnat/s-pack03.adb +++ b/gcc/ada/libgnat/s-pack03.adb @@ -89,30 +89,29 @@ package body System.Pack_03 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_03; ------------ diff --git a/gcc/ada/libgnat/s-pack05.adb b/gcc/ada/libgnat/s-pack05.adb index e899a5d..6ed9f98 100644 --- a/gcc/ada/libgnat/s-pack05.adb +++ b/gcc/ada/libgnat/s-pack05.adb @@ -89,30 +89,29 @@ package body System.Pack_05 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_05; ------------ diff --git a/gcc/ada/libgnat/s-pack06.adb b/gcc/ada/libgnat/s-pack06.adb index 83602ca..9e5b594 100644 --- a/gcc/ada/libgnat/s-pack06.adb +++ b/gcc/ada/libgnat/s-pack06.adb @@ -104,30 +104,29 @@ package body System.Pack_06 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_06; ------------- @@ -143,30 +142,29 @@ package body System.Pack_06 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_06; ------------ diff --git a/gcc/ada/libgnat/s-pack07.adb b/gcc/ada/libgnat/s-pack07.adb index 0a59dd24..222d864 100644 --- a/gcc/ada/libgnat/s-pack07.adb +++ b/gcc/ada/libgnat/s-pack07.adb @@ -89,30 +89,29 @@ package body System.Pack_07 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_07; ------------ diff --git a/gcc/ada/libgnat/s-pack09.adb b/gcc/ada/libgnat/s-pack09.adb index 06cf669..7643e8a 100644 --- a/gcc/ada/libgnat/s-pack09.adb +++ b/gcc/ada/libgnat/s-pack09.adb @@ -89,30 +89,29 @@ package body System.Pack_09 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_09; ------------ diff --git a/gcc/ada/libgnat/s-pack10.adb b/gcc/ada/libgnat/s-pack10.adb index 864fec0..1b42cfd 100644 --- a/gcc/ada/libgnat/s-pack10.adb +++ b/gcc/ada/libgnat/s-pack10.adb @@ -104,30 +104,29 @@ package body System.Pack_10 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_10; ------------- @@ -143,30 +142,29 @@ package body System.Pack_10 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_10; ------------ diff --git a/gcc/ada/libgnat/s-pack100.adb b/gcc/ada/libgnat/s-pack100.adb index cf856d7..3318f2e 100644 --- a/gcc/ada/libgnat/s-pack100.adb +++ b/gcc/ada/libgnat/s-pack100.adb @@ -104,30 +104,29 @@ package body System.Pack_100 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_100; ------------- @@ -143,30 +142,29 @@ package body System.Pack_100 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_100; ------------ diff --git a/gcc/ada/libgnat/s-pack101.adb b/gcc/ada/libgnat/s-pack101.adb index c416d0c..947ace2 100644 --- a/gcc/ada/libgnat/s-pack101.adb +++ b/gcc/ada/libgnat/s-pack101.adb @@ -89,30 +89,29 @@ package body System.Pack_101 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_101; ------------ diff --git a/gcc/ada/libgnat/s-pack102.adb b/gcc/ada/libgnat/s-pack102.adb index 5409c7d..6f91469 100644 --- a/gcc/ada/libgnat/s-pack102.adb +++ b/gcc/ada/libgnat/s-pack102.adb @@ -104,30 +104,29 @@ package body System.Pack_102 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_102; ------------- @@ -143,30 +142,29 @@ package body System.Pack_102 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_102; ------------ diff --git a/gcc/ada/libgnat/s-pack103.adb b/gcc/ada/libgnat/s-pack103.adb index 8d70ae6..fa014b3 100644 --- a/gcc/ada/libgnat/s-pack103.adb +++ b/gcc/ada/libgnat/s-pack103.adb @@ -89,30 +89,29 @@ package body System.Pack_103 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_103; ------------ diff --git a/gcc/ada/libgnat/s-pack104.adb b/gcc/ada/libgnat/s-pack104.adb index 137127e..d699ae2 100644 --- a/gcc/ada/libgnat/s-pack104.adb +++ b/gcc/ada/libgnat/s-pack104.adb @@ -104,30 +104,29 @@ package body System.Pack_104 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_104; ------------- @@ -143,30 +142,29 @@ package body System.Pack_104 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_104; ------------ diff --git a/gcc/ada/libgnat/s-pack105.adb b/gcc/ada/libgnat/s-pack105.adb index 0685c95..694315e 100644 --- a/gcc/ada/libgnat/s-pack105.adb +++ b/gcc/ada/libgnat/s-pack105.adb @@ -89,30 +89,29 @@ package body System.Pack_105 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_105; ------------ diff --git a/gcc/ada/libgnat/s-pack106.adb b/gcc/ada/libgnat/s-pack106.adb index 21436c1..5d50459 100644 --- a/gcc/ada/libgnat/s-pack106.adb +++ b/gcc/ada/libgnat/s-pack106.adb @@ -104,30 +104,29 @@ package body System.Pack_106 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_106; ------------- @@ -143,30 +142,29 @@ package body System.Pack_106 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_106; ------------ diff --git a/gcc/ada/libgnat/s-pack107.adb b/gcc/ada/libgnat/s-pack107.adb index 255c536..d3f3aa1 100644 --- a/gcc/ada/libgnat/s-pack107.adb +++ b/gcc/ada/libgnat/s-pack107.adb @@ -89,30 +89,29 @@ package body System.Pack_107 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_107; ------------ diff --git a/gcc/ada/libgnat/s-pack108.adb b/gcc/ada/libgnat/s-pack108.adb index 8ba37db..711442d 100644 --- a/gcc/ada/libgnat/s-pack108.adb +++ b/gcc/ada/libgnat/s-pack108.adb @@ -104,30 +104,29 @@ package body System.Pack_108 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_108; ------------- @@ -143,30 +142,29 @@ package body System.Pack_108 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_108; ------------ diff --git a/gcc/ada/libgnat/s-pack109.adb b/gcc/ada/libgnat/s-pack109.adb index a719b1e..5751a62 100644 --- a/gcc/ada/libgnat/s-pack109.adb +++ b/gcc/ada/libgnat/s-pack109.adb @@ -89,30 +89,29 @@ package body System.Pack_109 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_109; ------------ diff --git a/gcc/ada/libgnat/s-pack11.adb b/gcc/ada/libgnat/s-pack11.adb index c4903b4..d16fe8e 100644 --- a/gcc/ada/libgnat/s-pack11.adb +++ b/gcc/ada/libgnat/s-pack11.adb @@ -89,30 +89,29 @@ package body System.Pack_11 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_11; ------------ diff --git a/gcc/ada/libgnat/s-pack110.adb b/gcc/ada/libgnat/s-pack110.adb index 0642474..2d70d48 100644 --- a/gcc/ada/libgnat/s-pack110.adb +++ b/gcc/ada/libgnat/s-pack110.adb @@ -104,30 +104,29 @@ package body System.Pack_110 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_110; ------------- @@ -143,30 +142,29 @@ package body System.Pack_110 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_110; ------------ diff --git a/gcc/ada/libgnat/s-pack111.adb b/gcc/ada/libgnat/s-pack111.adb index 04faca4..7ee3803 100644 --- a/gcc/ada/libgnat/s-pack111.adb +++ b/gcc/ada/libgnat/s-pack111.adb @@ -89,30 +89,29 @@ package body System.Pack_111 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_111; ------------ diff --git a/gcc/ada/libgnat/s-pack112.adb b/gcc/ada/libgnat/s-pack112.adb index c12ee83..56447c1 100644 --- a/gcc/ada/libgnat/s-pack112.adb +++ b/gcc/ada/libgnat/s-pack112.adb @@ -104,30 +104,29 @@ package body System.Pack_112 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_112; ------------- @@ -143,30 +142,29 @@ package body System.Pack_112 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_112; ------------ diff --git a/gcc/ada/libgnat/s-pack113.adb b/gcc/ada/libgnat/s-pack113.adb index 60d7f88..e456f81 100644 --- a/gcc/ada/libgnat/s-pack113.adb +++ b/gcc/ada/libgnat/s-pack113.adb @@ -89,30 +89,29 @@ package body System.Pack_113 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_113; ------------ diff --git a/gcc/ada/libgnat/s-pack114.adb b/gcc/ada/libgnat/s-pack114.adb index 26821e1..9f48f4b 100644 --- a/gcc/ada/libgnat/s-pack114.adb +++ b/gcc/ada/libgnat/s-pack114.adb @@ -104,30 +104,29 @@ package body System.Pack_114 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_114; ------------- @@ -143,30 +142,29 @@ package body System.Pack_114 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_114; ------------ diff --git a/gcc/ada/libgnat/s-pack115.adb b/gcc/ada/libgnat/s-pack115.adb index ff03f1c..0cf3318 100644 --- a/gcc/ada/libgnat/s-pack115.adb +++ b/gcc/ada/libgnat/s-pack115.adb @@ -89,30 +89,29 @@ package body System.Pack_115 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_115; ------------ diff --git a/gcc/ada/libgnat/s-pack116.adb b/gcc/ada/libgnat/s-pack116.adb index 26b1420..8bfc5b9 100644 --- a/gcc/ada/libgnat/s-pack116.adb +++ b/gcc/ada/libgnat/s-pack116.adb @@ -104,30 +104,29 @@ package body System.Pack_116 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_116; ------------- @@ -143,30 +142,29 @@ package body System.Pack_116 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_116; ------------ diff --git a/gcc/ada/libgnat/s-pack117.adb b/gcc/ada/libgnat/s-pack117.adb index b748b09..b4afc61 100644 --- a/gcc/ada/libgnat/s-pack117.adb +++ b/gcc/ada/libgnat/s-pack117.adb @@ -89,30 +89,29 @@ package body System.Pack_117 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_117; ------------ diff --git a/gcc/ada/libgnat/s-pack118.adb b/gcc/ada/libgnat/s-pack118.adb index f7bb29d..4e0fd5e 100644 --- a/gcc/ada/libgnat/s-pack118.adb +++ b/gcc/ada/libgnat/s-pack118.adb @@ -104,30 +104,29 @@ package body System.Pack_118 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_118; ------------- @@ -143,30 +142,29 @@ package body System.Pack_118 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_118; ------------ diff --git a/gcc/ada/libgnat/s-pack119.adb b/gcc/ada/libgnat/s-pack119.adb index b871f9e..0e42d14 100644 --- a/gcc/ada/libgnat/s-pack119.adb +++ b/gcc/ada/libgnat/s-pack119.adb @@ -89,30 +89,29 @@ package body System.Pack_119 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_119; ------------ diff --git a/gcc/ada/libgnat/s-pack12.adb b/gcc/ada/libgnat/s-pack12.adb index 9a60be7..41d36a6 100644 --- a/gcc/ada/libgnat/s-pack12.adb +++ b/gcc/ada/libgnat/s-pack12.adb @@ -104,30 +104,29 @@ package body System.Pack_12 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_12; ------------- @@ -143,30 +142,29 @@ package body System.Pack_12 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_12; ------------ diff --git a/gcc/ada/libgnat/s-pack120.adb b/gcc/ada/libgnat/s-pack120.adb index 16491a2..5fdde24 100644 --- a/gcc/ada/libgnat/s-pack120.adb +++ b/gcc/ada/libgnat/s-pack120.adb @@ -104,30 +104,29 @@ package body System.Pack_120 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_120; ------------- @@ -143,30 +142,29 @@ package body System.Pack_120 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_120; ------------ diff --git a/gcc/ada/libgnat/s-pack121.adb b/gcc/ada/libgnat/s-pack121.adb index 5092db3..4c7ad22 100644 --- a/gcc/ada/libgnat/s-pack121.adb +++ b/gcc/ada/libgnat/s-pack121.adb @@ -89,30 +89,29 @@ package body System.Pack_121 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_121; ------------ diff --git a/gcc/ada/libgnat/s-pack122.adb b/gcc/ada/libgnat/s-pack122.adb index 1ebe18b..45cb06b 100644 --- a/gcc/ada/libgnat/s-pack122.adb +++ b/gcc/ada/libgnat/s-pack122.adb @@ -104,30 +104,29 @@ package body System.Pack_122 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_122; ------------- @@ -143,30 +142,29 @@ package body System.Pack_122 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_122; ------------ diff --git a/gcc/ada/libgnat/s-pack123.adb b/gcc/ada/libgnat/s-pack123.adb index 0ea7d62..b524cac 100644 --- a/gcc/ada/libgnat/s-pack123.adb +++ b/gcc/ada/libgnat/s-pack123.adb @@ -89,30 +89,29 @@ package body System.Pack_123 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_123; ------------ diff --git a/gcc/ada/libgnat/s-pack124.adb b/gcc/ada/libgnat/s-pack124.adb index abf42d8..328d7dc 100644 --- a/gcc/ada/libgnat/s-pack124.adb +++ b/gcc/ada/libgnat/s-pack124.adb @@ -104,30 +104,29 @@ package body System.Pack_124 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_124; ------------- @@ -143,30 +142,29 @@ package body System.Pack_124 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_124; ------------ diff --git a/gcc/ada/libgnat/s-pack125.adb b/gcc/ada/libgnat/s-pack125.adb index 6e7fd5b..93fb70f 100644 --- a/gcc/ada/libgnat/s-pack125.adb +++ b/gcc/ada/libgnat/s-pack125.adb @@ -89,30 +89,29 @@ package body System.Pack_125 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_125; ------------ diff --git a/gcc/ada/libgnat/s-pack126.adb b/gcc/ada/libgnat/s-pack126.adb index 606ab95..abaab52 100644 --- a/gcc/ada/libgnat/s-pack126.adb +++ b/gcc/ada/libgnat/s-pack126.adb @@ -104,30 +104,29 @@ package body System.Pack_126 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_126; ------------- @@ -143,30 +142,29 @@ package body System.Pack_126 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_126; ------------ diff --git a/gcc/ada/libgnat/s-pack127.adb b/gcc/ada/libgnat/s-pack127.adb index c5ca67b..f45d8b3 100644 --- a/gcc/ada/libgnat/s-pack127.adb +++ b/gcc/ada/libgnat/s-pack127.adb @@ -89,30 +89,29 @@ package body System.Pack_127 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_127; ------------ diff --git a/gcc/ada/libgnat/s-pack13.adb b/gcc/ada/libgnat/s-pack13.adb index 894faa4..aa40ef9 100644 --- a/gcc/ada/libgnat/s-pack13.adb +++ b/gcc/ada/libgnat/s-pack13.adb @@ -89,30 +89,29 @@ package body System.Pack_13 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_13; ------------ diff --git a/gcc/ada/libgnat/s-pack14.adb b/gcc/ada/libgnat/s-pack14.adb index 731b564..c458e41 100644 --- a/gcc/ada/libgnat/s-pack14.adb +++ b/gcc/ada/libgnat/s-pack14.adb @@ -104,30 +104,29 @@ package body System.Pack_14 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_14; ------------- @@ -143,30 +142,29 @@ package body System.Pack_14 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_14; ------------ diff --git a/gcc/ada/libgnat/s-pack15.adb b/gcc/ada/libgnat/s-pack15.adb index 530c205..e08cb96 100644 --- a/gcc/ada/libgnat/s-pack15.adb +++ b/gcc/ada/libgnat/s-pack15.adb @@ -89,30 +89,29 @@ package body System.Pack_15 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_15; ------------ diff --git a/gcc/ada/libgnat/s-pack17.adb b/gcc/ada/libgnat/s-pack17.adb index 95454bf..db109ef 100644 --- a/gcc/ada/libgnat/s-pack17.adb +++ b/gcc/ada/libgnat/s-pack17.adb @@ -89,30 +89,29 @@ package body System.Pack_17 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_17; ------------ diff --git a/gcc/ada/libgnat/s-pack18.adb b/gcc/ada/libgnat/s-pack18.adb index cfc05ff..4c04564 100644 --- a/gcc/ada/libgnat/s-pack18.adb +++ b/gcc/ada/libgnat/s-pack18.adb @@ -104,30 +104,29 @@ package body System.Pack_18 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_18; ------------- @@ -143,30 +142,29 @@ package body System.Pack_18 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_18; ------------ diff --git a/gcc/ada/libgnat/s-pack19.adb b/gcc/ada/libgnat/s-pack19.adb index b3895bf..9a0b3e5 100644 --- a/gcc/ada/libgnat/s-pack19.adb +++ b/gcc/ada/libgnat/s-pack19.adb @@ -89,30 +89,29 @@ package body System.Pack_19 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_19; ------------ diff --git a/gcc/ada/libgnat/s-pack20.adb b/gcc/ada/libgnat/s-pack20.adb index e6f1cc7..c11b043 100644 --- a/gcc/ada/libgnat/s-pack20.adb +++ b/gcc/ada/libgnat/s-pack20.adb @@ -104,30 +104,29 @@ package body System.Pack_20 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_20; ------------- @@ -143,30 +142,29 @@ package body System.Pack_20 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_20; ------------ diff --git a/gcc/ada/libgnat/s-pack21.adb b/gcc/ada/libgnat/s-pack21.adb index 6adafc8..429aa13 100644 --- a/gcc/ada/libgnat/s-pack21.adb +++ b/gcc/ada/libgnat/s-pack21.adb @@ -89,30 +89,29 @@ package body System.Pack_21 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_21; ------------ diff --git a/gcc/ada/libgnat/s-pack22.adb b/gcc/ada/libgnat/s-pack22.adb index bf9fdfa..f50fa15 100644 --- a/gcc/ada/libgnat/s-pack22.adb +++ b/gcc/ada/libgnat/s-pack22.adb @@ -104,30 +104,29 @@ package body System.Pack_22 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_22; ------------- @@ -143,30 +142,29 @@ package body System.Pack_22 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_22; ------------ diff --git a/gcc/ada/libgnat/s-pack23.adb b/gcc/ada/libgnat/s-pack23.adb index 5ef5e25..8f5cf54 100644 --- a/gcc/ada/libgnat/s-pack23.adb +++ b/gcc/ada/libgnat/s-pack23.adb @@ -89,30 +89,29 @@ package body System.Pack_23 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_23; ------------ diff --git a/gcc/ada/libgnat/s-pack24.adb b/gcc/ada/libgnat/s-pack24.adb index aa69a87..504e1ce 100644 --- a/gcc/ada/libgnat/s-pack24.adb +++ b/gcc/ada/libgnat/s-pack24.adb @@ -104,30 +104,29 @@ package body System.Pack_24 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_24; ------------- @@ -143,30 +142,29 @@ package body System.Pack_24 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_24; ------------ diff --git a/gcc/ada/libgnat/s-pack25.adb b/gcc/ada/libgnat/s-pack25.adb index 71a1589e..ee12a4b 100644 --- a/gcc/ada/libgnat/s-pack25.adb +++ b/gcc/ada/libgnat/s-pack25.adb @@ -89,30 +89,29 @@ package body System.Pack_25 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_25; ------------ diff --git a/gcc/ada/libgnat/s-pack26.adb b/gcc/ada/libgnat/s-pack26.adb index 82ce3ee3..9d54c92 100644 --- a/gcc/ada/libgnat/s-pack26.adb +++ b/gcc/ada/libgnat/s-pack26.adb @@ -104,30 +104,29 @@ package body System.Pack_26 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_26; ------------- @@ -143,30 +142,29 @@ package body System.Pack_26 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_26; ------------ diff --git a/gcc/ada/libgnat/s-pack27.adb b/gcc/ada/libgnat/s-pack27.adb index 6d75a6e..9609a2b 100644 --- a/gcc/ada/libgnat/s-pack27.adb +++ b/gcc/ada/libgnat/s-pack27.adb @@ -89,30 +89,29 @@ package body System.Pack_27 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_27; ------------ diff --git a/gcc/ada/libgnat/s-pack28.adb b/gcc/ada/libgnat/s-pack28.adb index 5ad4086..883932f 100644 --- a/gcc/ada/libgnat/s-pack28.adb +++ b/gcc/ada/libgnat/s-pack28.adb @@ -104,30 +104,29 @@ package body System.Pack_28 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_28; ------------- @@ -143,30 +142,29 @@ package body System.Pack_28 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_28; ------------ diff --git a/gcc/ada/libgnat/s-pack29.adb b/gcc/ada/libgnat/s-pack29.adb index 0d8e607..c531f1a 100644 --- a/gcc/ada/libgnat/s-pack29.adb +++ b/gcc/ada/libgnat/s-pack29.adb @@ -89,30 +89,29 @@ package body System.Pack_29 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_29; ------------ diff --git a/gcc/ada/libgnat/s-pack30.adb b/gcc/ada/libgnat/s-pack30.adb index 9fac8b9..ca5ead7 100644 --- a/gcc/ada/libgnat/s-pack30.adb +++ b/gcc/ada/libgnat/s-pack30.adb @@ -104,30 +104,29 @@ package body System.Pack_30 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_30; ------------- @@ -143,30 +142,29 @@ package body System.Pack_30 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_30; ------------ diff --git a/gcc/ada/libgnat/s-pack31.adb b/gcc/ada/libgnat/s-pack31.adb index 4c300e5..537b5d2 100644 --- a/gcc/ada/libgnat/s-pack31.adb +++ b/gcc/ada/libgnat/s-pack31.adb @@ -89,30 +89,29 @@ package body System.Pack_31 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_31; ------------ diff --git a/gcc/ada/libgnat/s-pack33.adb b/gcc/ada/libgnat/s-pack33.adb index 333b533..815b5bb 100644 --- a/gcc/ada/libgnat/s-pack33.adb +++ b/gcc/ada/libgnat/s-pack33.adb @@ -89,30 +89,29 @@ package body System.Pack_33 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_33; ------------ diff --git a/gcc/ada/libgnat/s-pack34.adb b/gcc/ada/libgnat/s-pack34.adb index 44366aa..8a8ceea 100644 --- a/gcc/ada/libgnat/s-pack34.adb +++ b/gcc/ada/libgnat/s-pack34.adb @@ -104,30 +104,29 @@ package body System.Pack_34 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_34; ------------- @@ -143,30 +142,29 @@ package body System.Pack_34 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_34; ------------ diff --git a/gcc/ada/libgnat/s-pack35.adb b/gcc/ada/libgnat/s-pack35.adb index e65da9a..7f3ce98 100644 --- a/gcc/ada/libgnat/s-pack35.adb +++ b/gcc/ada/libgnat/s-pack35.adb @@ -89,30 +89,29 @@ package body System.Pack_35 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_35; ------------ diff --git a/gcc/ada/libgnat/s-pack36.adb b/gcc/ada/libgnat/s-pack36.adb index 84f3941..75963d1 100644 --- a/gcc/ada/libgnat/s-pack36.adb +++ b/gcc/ada/libgnat/s-pack36.adb @@ -104,30 +104,29 @@ package body System.Pack_36 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_36; ------------- @@ -143,30 +142,29 @@ package body System.Pack_36 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_36; ------------ diff --git a/gcc/ada/libgnat/s-pack37.adb b/gcc/ada/libgnat/s-pack37.adb index d9d48cd..2fe4d7c 100644 --- a/gcc/ada/libgnat/s-pack37.adb +++ b/gcc/ada/libgnat/s-pack37.adb @@ -89,30 +89,29 @@ package body System.Pack_37 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_37; ------------ diff --git a/gcc/ada/libgnat/s-pack38.adb b/gcc/ada/libgnat/s-pack38.adb index 9d6e489..5aa4d07 100644 --- a/gcc/ada/libgnat/s-pack38.adb +++ b/gcc/ada/libgnat/s-pack38.adb @@ -104,30 +104,29 @@ package body System.Pack_38 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_38; ------------- @@ -143,30 +142,29 @@ package body System.Pack_38 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_38; ------------ diff --git a/gcc/ada/libgnat/s-pack39.adb b/gcc/ada/libgnat/s-pack39.adb index bd0b481..4777267 100644 --- a/gcc/ada/libgnat/s-pack39.adb +++ b/gcc/ada/libgnat/s-pack39.adb @@ -89,30 +89,29 @@ package body System.Pack_39 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_39; ------------ diff --git a/gcc/ada/libgnat/s-pack40.adb b/gcc/ada/libgnat/s-pack40.adb index da3adde..35281d4 100644 --- a/gcc/ada/libgnat/s-pack40.adb +++ b/gcc/ada/libgnat/s-pack40.adb @@ -104,30 +104,29 @@ package body System.Pack_40 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_40; ------------- @@ -143,30 +142,29 @@ package body System.Pack_40 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_40; ------------ diff --git a/gcc/ada/libgnat/s-pack41.adb b/gcc/ada/libgnat/s-pack41.adb index 7a79f8b..7fe4568 100644 --- a/gcc/ada/libgnat/s-pack41.adb +++ b/gcc/ada/libgnat/s-pack41.adb @@ -89,30 +89,29 @@ package body System.Pack_41 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_41; ------------ diff --git a/gcc/ada/libgnat/s-pack42.adb b/gcc/ada/libgnat/s-pack42.adb index 09159b2..ee099e4 100644 --- a/gcc/ada/libgnat/s-pack42.adb +++ b/gcc/ada/libgnat/s-pack42.adb @@ -104,30 +104,29 @@ package body System.Pack_42 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_42; ------------- @@ -143,30 +142,29 @@ package body System.Pack_42 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_42; ------------ diff --git a/gcc/ada/libgnat/s-pack43.adb b/gcc/ada/libgnat/s-pack43.adb index 5921d3e..bd46efb 100644 --- a/gcc/ada/libgnat/s-pack43.adb +++ b/gcc/ada/libgnat/s-pack43.adb @@ -89,30 +89,29 @@ package body System.Pack_43 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_43; ------------ diff --git a/gcc/ada/libgnat/s-pack44.adb b/gcc/ada/libgnat/s-pack44.adb index 57420fe..fa6390e 100644 --- a/gcc/ada/libgnat/s-pack44.adb +++ b/gcc/ada/libgnat/s-pack44.adb @@ -104,30 +104,29 @@ package body System.Pack_44 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_44; ------------- @@ -143,30 +142,29 @@ package body System.Pack_44 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_44; ------------ diff --git a/gcc/ada/libgnat/s-pack45.adb b/gcc/ada/libgnat/s-pack45.adb index 13753bc..798c1ea 100644 --- a/gcc/ada/libgnat/s-pack45.adb +++ b/gcc/ada/libgnat/s-pack45.adb @@ -89,30 +89,29 @@ package body System.Pack_45 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_45; ------------ diff --git a/gcc/ada/libgnat/s-pack46.adb b/gcc/ada/libgnat/s-pack46.adb index 3911743..a3e637f 100644 --- a/gcc/ada/libgnat/s-pack46.adb +++ b/gcc/ada/libgnat/s-pack46.adb @@ -104,30 +104,29 @@ package body System.Pack_46 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_46; ------------- @@ -143,30 +142,29 @@ package body System.Pack_46 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_46; ------------ diff --git a/gcc/ada/libgnat/s-pack47.adb b/gcc/ada/libgnat/s-pack47.adb index ffe4edd..14b8efd 100644 --- a/gcc/ada/libgnat/s-pack47.adb +++ b/gcc/ada/libgnat/s-pack47.adb @@ -89,30 +89,29 @@ package body System.Pack_47 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_47; ------------ diff --git a/gcc/ada/libgnat/s-pack48.adb b/gcc/ada/libgnat/s-pack48.adb index 6ab8329..4ae6cff 100644 --- a/gcc/ada/libgnat/s-pack48.adb +++ b/gcc/ada/libgnat/s-pack48.adb @@ -104,30 +104,29 @@ package body System.Pack_48 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_48; ------------- @@ -143,30 +142,29 @@ package body System.Pack_48 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_48; ------------ diff --git a/gcc/ada/libgnat/s-pack49.adb b/gcc/ada/libgnat/s-pack49.adb index 745d774..a3df22a 100644 --- a/gcc/ada/libgnat/s-pack49.adb +++ b/gcc/ada/libgnat/s-pack49.adb @@ -89,30 +89,29 @@ package body System.Pack_49 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_49; ------------ diff --git a/gcc/ada/libgnat/s-pack50.adb b/gcc/ada/libgnat/s-pack50.adb index 674b61f..b0910b7 100644 --- a/gcc/ada/libgnat/s-pack50.adb +++ b/gcc/ada/libgnat/s-pack50.adb @@ -104,30 +104,29 @@ package body System.Pack_50 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_50; ------------- @@ -143,30 +142,29 @@ package body System.Pack_50 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_50; ------------ diff --git a/gcc/ada/libgnat/s-pack51.adb b/gcc/ada/libgnat/s-pack51.adb index 12ec499..3f65265 100644 --- a/gcc/ada/libgnat/s-pack51.adb +++ b/gcc/ada/libgnat/s-pack51.adb @@ -89,30 +89,29 @@ package body System.Pack_51 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_51; ------------ diff --git a/gcc/ada/libgnat/s-pack52.adb b/gcc/ada/libgnat/s-pack52.adb index 2a51513..0fb5d41 100644 --- a/gcc/ada/libgnat/s-pack52.adb +++ b/gcc/ada/libgnat/s-pack52.adb @@ -104,30 +104,29 @@ package body System.Pack_52 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_52; ------------- @@ -143,30 +142,29 @@ package body System.Pack_52 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_52; ------------ diff --git a/gcc/ada/libgnat/s-pack53.adb b/gcc/ada/libgnat/s-pack53.adb index 87f8ce4..8fbbb28 100644 --- a/gcc/ada/libgnat/s-pack53.adb +++ b/gcc/ada/libgnat/s-pack53.adb @@ -89,30 +89,29 @@ package body System.Pack_53 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_53; ------------ diff --git a/gcc/ada/libgnat/s-pack54.adb b/gcc/ada/libgnat/s-pack54.adb index 87da1cb..06fe56a 100644 --- a/gcc/ada/libgnat/s-pack54.adb +++ b/gcc/ada/libgnat/s-pack54.adb @@ -104,30 +104,29 @@ package body System.Pack_54 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_54; ------------- @@ -143,30 +142,29 @@ package body System.Pack_54 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_54; ------------ diff --git a/gcc/ada/libgnat/s-pack55.adb b/gcc/ada/libgnat/s-pack55.adb index 0ca2b10..85e0114 100644 --- a/gcc/ada/libgnat/s-pack55.adb +++ b/gcc/ada/libgnat/s-pack55.adb @@ -89,30 +89,29 @@ package body System.Pack_55 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_55; ------------ diff --git a/gcc/ada/libgnat/s-pack56.adb b/gcc/ada/libgnat/s-pack56.adb index c49841e..9346f9f 100644 --- a/gcc/ada/libgnat/s-pack56.adb +++ b/gcc/ada/libgnat/s-pack56.adb @@ -104,30 +104,29 @@ package body System.Pack_56 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_56; ------------- @@ -143,30 +142,29 @@ package body System.Pack_56 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_56; ------------ diff --git a/gcc/ada/libgnat/s-pack57.adb b/gcc/ada/libgnat/s-pack57.adb index 8bcb56e..1ff0cd8 100644 --- a/gcc/ada/libgnat/s-pack57.adb +++ b/gcc/ada/libgnat/s-pack57.adb @@ -89,30 +89,29 @@ package body System.Pack_57 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_57; ------------ diff --git a/gcc/ada/libgnat/s-pack58.adb b/gcc/ada/libgnat/s-pack58.adb index ebbc471..c8fd967 100644 --- a/gcc/ada/libgnat/s-pack58.adb +++ b/gcc/ada/libgnat/s-pack58.adb @@ -104,30 +104,29 @@ package body System.Pack_58 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_58; ------------- @@ -143,30 +142,29 @@ package body System.Pack_58 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_58; ------------ diff --git a/gcc/ada/libgnat/s-pack59.adb b/gcc/ada/libgnat/s-pack59.adb index 373a856..970b7ed 100644 --- a/gcc/ada/libgnat/s-pack59.adb +++ b/gcc/ada/libgnat/s-pack59.adb @@ -89,30 +89,29 @@ package body System.Pack_59 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_59; ------------ diff --git a/gcc/ada/libgnat/s-pack60.adb b/gcc/ada/libgnat/s-pack60.adb index eab6575..1b7bb6b 100644 --- a/gcc/ada/libgnat/s-pack60.adb +++ b/gcc/ada/libgnat/s-pack60.adb @@ -104,30 +104,29 @@ package body System.Pack_60 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_60; ------------- @@ -143,30 +142,29 @@ package body System.Pack_60 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_60; ------------ diff --git a/gcc/ada/libgnat/s-pack61.adb b/gcc/ada/libgnat/s-pack61.adb index 1b17fbc..1a43169 100644 --- a/gcc/ada/libgnat/s-pack61.adb +++ b/gcc/ada/libgnat/s-pack61.adb @@ -89,30 +89,29 @@ package body System.Pack_61 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_61; ------------ diff --git a/gcc/ada/libgnat/s-pack62.adb b/gcc/ada/libgnat/s-pack62.adb index 98725fa..1d8e62b 100644 --- a/gcc/ada/libgnat/s-pack62.adb +++ b/gcc/ada/libgnat/s-pack62.adb @@ -104,30 +104,29 @@ package body System.Pack_62 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_62; ------------- @@ -143,30 +142,29 @@ package body System.Pack_62 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_62; ------------ diff --git a/gcc/ada/libgnat/s-pack63.adb b/gcc/ada/libgnat/s-pack63.adb index 8795fdc..905cacf 100644 --- a/gcc/ada/libgnat/s-pack63.adb +++ b/gcc/ada/libgnat/s-pack63.adb @@ -89,30 +89,29 @@ package body System.Pack_63 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_63; ------------ diff --git a/gcc/ada/libgnat/s-pack65.adb b/gcc/ada/libgnat/s-pack65.adb index ee92a127..c9a3b5a 100644 --- a/gcc/ada/libgnat/s-pack65.adb +++ b/gcc/ada/libgnat/s-pack65.adb @@ -89,30 +89,29 @@ package body System.Pack_65 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_65; ------------ diff --git a/gcc/ada/libgnat/s-pack66.adb b/gcc/ada/libgnat/s-pack66.adb index abc08b5..8655191 100644 --- a/gcc/ada/libgnat/s-pack66.adb +++ b/gcc/ada/libgnat/s-pack66.adb @@ -104,30 +104,29 @@ package body System.Pack_66 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_66; ------------- @@ -143,30 +142,29 @@ package body System.Pack_66 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_66; ------------ diff --git a/gcc/ada/libgnat/s-pack67.adb b/gcc/ada/libgnat/s-pack67.adb index 1d2ac94..d8db3b5 100644 --- a/gcc/ada/libgnat/s-pack67.adb +++ b/gcc/ada/libgnat/s-pack67.adb @@ -89,30 +89,29 @@ package body System.Pack_67 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_67; ------------ diff --git a/gcc/ada/libgnat/s-pack68.adb b/gcc/ada/libgnat/s-pack68.adb index 8174c3d..46fb4c2 100644 --- a/gcc/ada/libgnat/s-pack68.adb +++ b/gcc/ada/libgnat/s-pack68.adb @@ -104,30 +104,29 @@ package body System.Pack_68 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_68; ------------- @@ -143,30 +142,29 @@ package body System.Pack_68 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_68; ------------ diff --git a/gcc/ada/libgnat/s-pack69.adb b/gcc/ada/libgnat/s-pack69.adb index 681022a..f9edfeb 100644 --- a/gcc/ada/libgnat/s-pack69.adb +++ b/gcc/ada/libgnat/s-pack69.adb @@ -89,30 +89,29 @@ package body System.Pack_69 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_69; ------------ diff --git a/gcc/ada/libgnat/s-pack70.adb b/gcc/ada/libgnat/s-pack70.adb index bd4362e..284d431 100644 --- a/gcc/ada/libgnat/s-pack70.adb +++ b/gcc/ada/libgnat/s-pack70.adb @@ -104,30 +104,29 @@ package body System.Pack_70 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_70; ------------- @@ -143,30 +142,29 @@ package body System.Pack_70 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_70; ------------ diff --git a/gcc/ada/libgnat/s-pack71.adb b/gcc/ada/libgnat/s-pack71.adb index 7bcec8a..5e2a2d0 100644 --- a/gcc/ada/libgnat/s-pack71.adb +++ b/gcc/ada/libgnat/s-pack71.adb @@ -89,30 +89,29 @@ package body System.Pack_71 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_71; ------------ diff --git a/gcc/ada/libgnat/s-pack72.adb b/gcc/ada/libgnat/s-pack72.adb index a456280..968dcf6 100644 --- a/gcc/ada/libgnat/s-pack72.adb +++ b/gcc/ada/libgnat/s-pack72.adb @@ -104,30 +104,29 @@ package body System.Pack_72 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_72; ------------- @@ -143,30 +142,29 @@ package body System.Pack_72 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_72; ------------ diff --git a/gcc/ada/libgnat/s-pack73.adb b/gcc/ada/libgnat/s-pack73.adb index a3c61b5..a775196 100644 --- a/gcc/ada/libgnat/s-pack73.adb +++ b/gcc/ada/libgnat/s-pack73.adb @@ -89,30 +89,29 @@ package body System.Pack_73 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_73; ------------ diff --git a/gcc/ada/libgnat/s-pack74.adb b/gcc/ada/libgnat/s-pack74.adb index 566a697..b7af422 100644 --- a/gcc/ada/libgnat/s-pack74.adb +++ b/gcc/ada/libgnat/s-pack74.adb @@ -104,30 +104,29 @@ package body System.Pack_74 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_74; ------------- @@ -143,30 +142,29 @@ package body System.Pack_74 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_74; ------------ diff --git a/gcc/ada/libgnat/s-pack75.adb b/gcc/ada/libgnat/s-pack75.adb index 4c46cf8..9990b25 100644 --- a/gcc/ada/libgnat/s-pack75.adb +++ b/gcc/ada/libgnat/s-pack75.adb @@ -89,30 +89,29 @@ package body System.Pack_75 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_75; ------------ diff --git a/gcc/ada/libgnat/s-pack76.adb b/gcc/ada/libgnat/s-pack76.adb index 3839d15..5f66fe3 100644 --- a/gcc/ada/libgnat/s-pack76.adb +++ b/gcc/ada/libgnat/s-pack76.adb @@ -104,30 +104,29 @@ package body System.Pack_76 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_76; ------------- @@ -143,30 +142,29 @@ package body System.Pack_76 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_76; ------------ diff --git a/gcc/ada/libgnat/s-pack77.adb b/gcc/ada/libgnat/s-pack77.adb index ca51862..1b0971a 100644 --- a/gcc/ada/libgnat/s-pack77.adb +++ b/gcc/ada/libgnat/s-pack77.adb @@ -89,30 +89,29 @@ package body System.Pack_77 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_77; ------------ diff --git a/gcc/ada/libgnat/s-pack78.adb b/gcc/ada/libgnat/s-pack78.adb index 0c302d5..7859a0f 100644 --- a/gcc/ada/libgnat/s-pack78.adb +++ b/gcc/ada/libgnat/s-pack78.adb @@ -104,30 +104,29 @@ package body System.Pack_78 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_78; ------------- @@ -143,30 +142,29 @@ package body System.Pack_78 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_78; ------------ diff --git a/gcc/ada/libgnat/s-pack79.adb b/gcc/ada/libgnat/s-pack79.adb index 0d2a21d..6f002e1 100644 --- a/gcc/ada/libgnat/s-pack79.adb +++ b/gcc/ada/libgnat/s-pack79.adb @@ -89,30 +89,29 @@ package body System.Pack_79 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_79; ------------ diff --git a/gcc/ada/libgnat/s-pack80.adb b/gcc/ada/libgnat/s-pack80.adb index 107175d..2b5a8a6 100644 --- a/gcc/ada/libgnat/s-pack80.adb +++ b/gcc/ada/libgnat/s-pack80.adb @@ -104,30 +104,29 @@ package body System.Pack_80 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_80; ------------- @@ -143,30 +142,29 @@ package body System.Pack_80 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_80; ------------ diff --git a/gcc/ada/libgnat/s-pack81.adb b/gcc/ada/libgnat/s-pack81.adb index 8a64906..bc7420a 100644 --- a/gcc/ada/libgnat/s-pack81.adb +++ b/gcc/ada/libgnat/s-pack81.adb @@ -89,30 +89,29 @@ package body System.Pack_81 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_81; ------------ diff --git a/gcc/ada/libgnat/s-pack82.adb b/gcc/ada/libgnat/s-pack82.adb index d3cc6d1..8883d05 100644 --- a/gcc/ada/libgnat/s-pack82.adb +++ b/gcc/ada/libgnat/s-pack82.adb @@ -104,30 +104,29 @@ package body System.Pack_82 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_82; ------------- @@ -143,30 +142,29 @@ package body System.Pack_82 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_82; ------------ diff --git a/gcc/ada/libgnat/s-pack83.adb b/gcc/ada/libgnat/s-pack83.adb index a030eee..2eb74e7 100644 --- a/gcc/ada/libgnat/s-pack83.adb +++ b/gcc/ada/libgnat/s-pack83.adb @@ -89,30 +89,29 @@ package body System.Pack_83 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_83; ------------ diff --git a/gcc/ada/libgnat/s-pack84.adb b/gcc/ada/libgnat/s-pack84.adb index 017bb75..4518402 100644 --- a/gcc/ada/libgnat/s-pack84.adb +++ b/gcc/ada/libgnat/s-pack84.adb @@ -104,30 +104,29 @@ package body System.Pack_84 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_84; ------------- @@ -143,30 +142,29 @@ package body System.Pack_84 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_84; ------------ diff --git a/gcc/ada/libgnat/s-pack85.adb b/gcc/ada/libgnat/s-pack85.adb index 45a35b6..b383072 100644 --- a/gcc/ada/libgnat/s-pack85.adb +++ b/gcc/ada/libgnat/s-pack85.adb @@ -89,30 +89,29 @@ package body System.Pack_85 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_85; ------------ diff --git a/gcc/ada/libgnat/s-pack86.adb b/gcc/ada/libgnat/s-pack86.adb index 487407b..d302c18 100644 --- a/gcc/ada/libgnat/s-pack86.adb +++ b/gcc/ada/libgnat/s-pack86.adb @@ -104,30 +104,29 @@ package body System.Pack_86 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_86; ------------- @@ -143,30 +142,29 @@ package body System.Pack_86 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_86; ------------ diff --git a/gcc/ada/libgnat/s-pack87.adb b/gcc/ada/libgnat/s-pack87.adb index 7f75617..0a40c2f 100644 --- a/gcc/ada/libgnat/s-pack87.adb +++ b/gcc/ada/libgnat/s-pack87.adb @@ -89,30 +89,29 @@ package body System.Pack_87 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_87; ------------ diff --git a/gcc/ada/libgnat/s-pack88.adb b/gcc/ada/libgnat/s-pack88.adb index 7a4f2a9..936dc64 100644 --- a/gcc/ada/libgnat/s-pack88.adb +++ b/gcc/ada/libgnat/s-pack88.adb @@ -104,30 +104,29 @@ package body System.Pack_88 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_88; ------------- @@ -143,30 +142,29 @@ package body System.Pack_88 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_88; ------------ diff --git a/gcc/ada/libgnat/s-pack89.adb b/gcc/ada/libgnat/s-pack89.adb index babbaa0..f1da5b9 100644 --- a/gcc/ada/libgnat/s-pack89.adb +++ b/gcc/ada/libgnat/s-pack89.adb @@ -89,30 +89,29 @@ package body System.Pack_89 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_89; ------------ diff --git a/gcc/ada/libgnat/s-pack90.adb b/gcc/ada/libgnat/s-pack90.adb index 51cf2d2..d808da8 100644 --- a/gcc/ada/libgnat/s-pack90.adb +++ b/gcc/ada/libgnat/s-pack90.adb @@ -104,30 +104,29 @@ package body System.Pack_90 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_90; ------------- @@ -143,30 +142,29 @@ package body System.Pack_90 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_90; ------------ diff --git a/gcc/ada/libgnat/s-pack91.adb b/gcc/ada/libgnat/s-pack91.adb index 9dbbc1b..6bf3bc7 100644 --- a/gcc/ada/libgnat/s-pack91.adb +++ b/gcc/ada/libgnat/s-pack91.adb @@ -89,30 +89,29 @@ package body System.Pack_91 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_91; ------------ diff --git a/gcc/ada/libgnat/s-pack92.adb b/gcc/ada/libgnat/s-pack92.adb index d9c88ea..1b0d97d 100644 --- a/gcc/ada/libgnat/s-pack92.adb +++ b/gcc/ada/libgnat/s-pack92.adb @@ -104,30 +104,29 @@ package body System.Pack_92 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_92; ------------- @@ -143,30 +142,29 @@ package body System.Pack_92 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_92; ------------ diff --git a/gcc/ada/libgnat/s-pack93.adb b/gcc/ada/libgnat/s-pack93.adb index eef512a..23ed563 100644 --- a/gcc/ada/libgnat/s-pack93.adb +++ b/gcc/ada/libgnat/s-pack93.adb @@ -89,30 +89,29 @@ package body System.Pack_93 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_93; ------------ diff --git a/gcc/ada/libgnat/s-pack94.adb b/gcc/ada/libgnat/s-pack94.adb index 5cc01eb..cb5bc1c 100644 --- a/gcc/ada/libgnat/s-pack94.adb +++ b/gcc/ada/libgnat/s-pack94.adb @@ -104,30 +104,29 @@ package body System.Pack_94 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_94; ------------- @@ -143,30 +142,29 @@ package body System.Pack_94 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_94; ------------ diff --git a/gcc/ada/libgnat/s-pack95.adb b/gcc/ada/libgnat/s-pack95.adb index 5eb5b86..824adf1 100644 --- a/gcc/ada/libgnat/s-pack95.adb +++ b/gcc/ada/libgnat/s-pack95.adb @@ -89,30 +89,29 @@ package body System.Pack_95 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_95; ------------ diff --git a/gcc/ada/libgnat/s-pack96.adb b/gcc/ada/libgnat/s-pack96.adb index dcd1d68..531fb97 100644 --- a/gcc/ada/libgnat/s-pack96.adb +++ b/gcc/ada/libgnat/s-pack96.adb @@ -104,30 +104,29 @@ package body System.Pack_96 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_96; ------------- @@ -143,30 +142,29 @@ package body System.Pack_96 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_96; ------------ diff --git a/gcc/ada/libgnat/s-pack97.adb b/gcc/ada/libgnat/s-pack97.adb index d428f01..b6c766b 100644 --- a/gcc/ada/libgnat/s-pack97.adb +++ b/gcc/ada/libgnat/s-pack97.adb @@ -89,30 +89,29 @@ package body System.Pack_97 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_97; ------------ diff --git a/gcc/ada/libgnat/s-pack98.adb b/gcc/ada/libgnat/s-pack98.adb index 97a6528..9814119 100644 --- a/gcc/ada/libgnat/s-pack98.adb +++ b/gcc/ada/libgnat/s-pack98.adb @@ -104,30 +104,29 @@ package body System.Pack_98 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_98; ------------- @@ -143,30 +142,29 @@ package body System.Pack_98 is C : ClusterU_Ref with Address => A'Address, Import; RC : Rev_ClusterU_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end GetU_98; ------------ diff --git a/gcc/ada/libgnat/s-pack99.adb b/gcc/ada/libgnat/s-pack99.adb index b285053..2c89be8 100644 --- a/gcc/ada/libgnat/s-pack99.adb +++ b/gcc/ada/libgnat/s-pack99.adb @@ -89,30 +89,29 @@ package body System.Pack_99 is C : Cluster_Ref with Address => A'Address, Import; RC : Rev_Cluster_Ref with Address => A'Address, Import; begin - if Rev_SSO then - case N07 (Uns (N) mod 8) is - when 0 => return RC.E0; - when 1 => return RC.E1; - when 2 => return RC.E2; - when 3 => return RC.E3; - when 4 => return RC.E4; - when 5 => return RC.E5; - when 6 => return RC.E6; - when 7 => return RC.E7; - end case; - - else - case N07 (Uns (N) mod 8) is - when 0 => return C.E0; - when 1 => return C.E1; - when 2 => return C.E2; - when 3 => return C.E3; - when 4 => return C.E4; - when 5 => return C.E5; - when 6 => return C.E6; - when 7 => return C.E7; - end case; - end if; + return + (if Rev_SSO then + (case N07 (Uns (N) mod 8) is + when 0 => RC.E0, + when 1 => RC.E1, + when 2 => RC.E2, + when 3 => RC.E3, + when 4 => RC.E4, + when 5 => RC.E5, + when 6 => RC.E6, + when 7 => RC.E7) + + else + (case N07 (Uns (N) mod 8) is + when 0 => C.E0, + when 1 => C.E1, + when 2 => C.E2, + when 3 => C.E3, + when 4 => C.E4, + when 5 => C.E5, + when 6 => C.E6, + when 7 => C.E7) + ); end Get_99; ------------ -- cgit v1.1 From 79cc2a75680ebcf8e9e200ddfbd61bd3ef08798a Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 28 Jun 2023 01:36:52 -0300 Subject: ada: Expose expected_throw attribute Mark exception-raising subprograms with expected_throw attribute. Document the use of the attribute in Control Flow Redundancy. Enable marking subprograms as expected_throw with Machine_Attribute pragmas. gcc/ada/ * libgnat/a-except.ads (Raise_Exception): Mark expected_throw. (Reraise_Occurrence): Likewise. (Raise_Exception_Always): Likewise. (Raise_From_Controlled_Operation): Likewise. (Reraise_Occurrence_Always): Likewise. (Reraise_Occurrence_No_Defer): Likewise. * libgnat/a-except.adb (Exception_Propagation.Propagate_Exception): Likewise. (Complete_And_Propagate_Occurrence): Likewise. (Raise_Exception_No_Defer): Likewise. (Raise_From_Signal_Handler): Likewise. (Raise_With_Msg): Likewise. (Raise_With_Location_And_Msg): Likewise. (Raise_Constraint_Error): Likewise. (Raise_Constraint_Error_Msg): Likewise. (Raise_Program_Error): Likewise. (Raise_Program_Error_Msg): Likewise. (Raise_Storage_Error): Likewise. (Raise_Storage_Error_Msg): Likewise. (Reraise, Rcheck_*): Likewise. * doc/gnat_rm/security_hardening_features.rst (Control Flow Hardening): Note the influence of expected_throw. * gnat_rm.texi: Regenerate. * gnat_ugn.texi: Regenerate. * gcc-interface/utils.cc (handle_expected_throw_attribute): New. (gnat_internal_attribute_table): Add expected_throw. --- .../doc/gnat_rm/security_hardening_features.rst | 4 +- gcc/ada/gcc-interface/utils.cc | 19 ++++ gcc/ada/gnat_rm.texi | 6 +- gcc/ada/gnat_ugn.texi | 4 +- gcc/ada/libgnat/a-except.adb | 104 +++++++++++++++++++++ gcc/ada/libgnat/a-except.ads | 14 +++ 6 files changed, 146 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst b/gcc/ada/doc/gnat_rm/security_hardening_features.rst index e057af2e..015b9ce 100644 --- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst +++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst @@ -500,7 +500,9 @@ gets modified as follows: Verification may also be performed before No_Return calls, whether all of them, with :switch:`-fhardcfr-check-noreturn-calls=always`; all but -internal subprograms involved in exception-raising or -reraising, with +internal subprograms involved in exception-raising or -reraising or +subprograms explicitly marked with both :samp:`No_Return` and +:samp:`Machine_Attribute` :samp:`expected_throw` pragmas, with :switch:`-fhardcfr-check-noreturn-calls=no-xthrow` (default); only nothrow ones, with :switch:`-fhardcfr-check-noreturn-calls=nothrow`; or none, with :switch:`-fhardcfr-check-noreturn-calls=never`. diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 8f1861b..d0a13d2 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -87,6 +87,7 @@ tree gnat_raise_decls_ext[(int) LAST_REASON_CODE + 1]; /* Forward declarations for handlers of attributes. */ static tree handle_const_attribute (tree *, tree, tree, int, bool *); static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); +static tree handle_expected_throw_attribute (tree *, tree, tree, int, bool *); static tree handle_pure_attribute (tree *, tree, tree, int, bool *); static tree handle_novops_attribute (tree *, tree, tree, int, bool *); static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); @@ -143,6 +144,8 @@ const struct attribute_spec gnat_internal_attribute_table[] = handle_const_attribute, NULL }, { "nothrow", 0, 0, true, false, false, false, handle_nothrow_attribute, NULL }, + { "expected_throw", 0, 0, true, false, false, false, + handle_expected_throw_attribute, NULL }, { "pure", 0, 0, true, false, false, false, handle_pure_attribute, NULL }, { "no vops", 0, 0, true, false, false, false, @@ -6379,6 +6382,22 @@ handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name), return NULL_TREE; } +/* Handle a "expected_throw" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_expected_throw_attribute (tree *node, tree ARG_UNUSED (name), + tree ARG_UNUSED (args), int ARG_UNUSED (flags), + bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + /* No flag to set here. */; + else + *no_add_attrs = true; + + return NULL_TREE; +} + /* Handle a "pure" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 066c066..b7e0983 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -19,7 +19,7 @@ @copying @quotation -GNAT Reference Manual , Jul 10, 2023 +GNAT Reference Manual , Jul 17, 2023 AdaCore @@ -29666,7 +29666,9 @@ end; Verification may also be performed before No_Return calls, whether all of them, with @code{-fhardcfr-check-noreturn-calls=always}; all but -internal subprograms involved in exception-raising or -reraising, with +internal subprograms involved in exception-raising or -reraising or +subprograms explicitly marked with both @code{No_Return} and +@code{Machine_Attribute} @code{expected_throw} pragmas, with @code{-fhardcfr-check-noreturn-calls=no-xthrow} (default); only nothrow ones, with @code{-fhardcfr-check-noreturn-calls=nothrow}; or none, with @code{-fhardcfr-check-noreturn-calls=never}. diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index 2721251..78f9b87 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -19,7 +19,7 @@ @copying @quotation -GNAT User's Guide for Native Platforms , Jul 10, 2023 +GNAT User's Guide for Native Platforms , Jul 17, 2023 AdaCore @@ -29531,8 +29531,8 @@ to permit their use in free software. @printindex ge -@anchor{d1}@w{ } @anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ } +@anchor{d1}@w{ } @c %**end of body @bye diff --git a/gcc/ada/libgnat/a-except.adb b/gcc/ada/libgnat/a-except.adb index 20a7736..dd5edaf 100644 --- a/gcc/ada/libgnat/a-except.adb +++ b/gcc/ada/libgnat/a-except.adb @@ -229,6 +229,7 @@ package body Ada.Exceptions is procedure Propagate_Exception (Excep : Exception_Occurrence); pragma No_Return (Propagate_Exception); + pragma Machine_Attribute (Propagate_Exception, "expected_throw"); -- This procedure propagates the exception represented by Excep end Exception_Propagation; @@ -256,6 +257,8 @@ package body Ada.Exceptions is procedure Complete_And_Propagate_Occurrence (X : EOA); pragma No_Return (Complete_And_Propagate_Occurrence); + pragma Machine_Attribute (Complete_And_Propagate_Occurrence, + "expected_throw"); -- This is a simple wrapper to Complete_Occurrence and -- Exception_Propagation.Propagate_Exception. @@ -280,6 +283,7 @@ package body Ada.Exceptions is (Ada, Raise_Exception_No_Defer, "ada__exceptions__raise_exception_no_defer"); pragma No_Return (Raise_Exception_No_Defer); + pragma Machine_Attribute (Raise_Exception_No_Defer, "expected_throw"); -- Similar to Raise_Exception, but with no abort deferral procedure Raise_From_Signal_Handler @@ -288,6 +292,7 @@ package body Ada.Exceptions is pragma Export (C, Raise_From_Signal_Handler, "__gnat_raise_from_signal_handler"); pragma No_Return (Raise_From_Signal_Handler); + pragma Machine_Attribute (Raise_From_Signal_Handler, "expected_throw"); -- This routine is used to raise an exception from a signal handler. The -- signal handler has already stored the machine state (i.e. the state that -- corresponds to the location at which the signal was raised). E is the @@ -301,6 +306,7 @@ package body Ada.Exceptions is procedure Raise_With_Msg (E : Exception_Id); pragma No_Return (Raise_With_Msg); + pragma Machine_Attribute (Raise_With_Msg, "expected_throw"); pragma Export (C, Raise_With_Msg, "__gnat_raise_with_msg"); -- Raises an exception with given exception id value. A message -- is associated with the raise, and has already been stored in the @@ -314,6 +320,7 @@ package body Ada.Exceptions is C : Integer := 0; M : System.Address := System.Null_Address); pragma No_Return (Raise_With_Location_And_Msg); + pragma Machine_Attribute (Raise_With_Location_And_Msg, "expected_throw"); -- Raise an exception with given exception id value. A filename and line -- number is associated with the raise and is stored in the exception -- occurrence and in addition a column and a string message M may be @@ -321,6 +328,7 @@ package body Ada.Exceptions is procedure Raise_Constraint_Error (File : System.Address; Line : Integer); pragma No_Return (Raise_Constraint_Error); + pragma Machine_Attribute (Raise_Constraint_Error, "expected_throw"); pragma Export (C, Raise_Constraint_Error, "__gnat_raise_constraint_error"); -- Raise constraint error with file:line information @@ -330,12 +338,14 @@ package body Ada.Exceptions is Column : Integer; Msg : System.Address); pragma No_Return (Raise_Constraint_Error_Msg); + pragma Machine_Attribute (Raise_Constraint_Error_Msg, "expected_throw"); pragma Export (C, Raise_Constraint_Error_Msg, "__gnat_raise_constraint_error_msg"); -- Raise constraint error with file:line:col + msg information procedure Raise_Program_Error (File : System.Address; Line : Integer); pragma No_Return (Raise_Program_Error); + pragma Machine_Attribute (Raise_Program_Error, "expected_throw"); pragma Export (C, Raise_Program_Error, "__gnat_raise_program_error"); -- Raise program error with file:line information @@ -344,12 +354,14 @@ package body Ada.Exceptions is Line : Integer; Msg : System.Address); pragma No_Return (Raise_Program_Error_Msg); + pragma Machine_Attribute (Raise_Program_Error_Msg, "expected_throw"); pragma Export (C, Raise_Program_Error_Msg, "__gnat_raise_program_error_msg"); -- Raise program error with file:line + msg information procedure Raise_Storage_Error (File : System.Address; Line : Integer); pragma No_Return (Raise_Storage_Error); + pragma Machine_Attribute (Raise_Storage_Error, "expected_throw"); pragma Export (C, Raise_Storage_Error, "__gnat_raise_storage_error"); -- Raise storage error with file:line information @@ -358,6 +370,7 @@ package body Ada.Exceptions is Line : Integer; Msg : System.Address); pragma No_Return (Raise_Storage_Error_Msg); + pragma Machine_Attribute (Raise_Storage_Error_Msg, "expected_throw"); pragma Export (C, Raise_Storage_Error_Msg, "__gnat_raise_storage_error_msg"); -- Raise storage error with file:line + reason msg information @@ -385,6 +398,7 @@ package body Ada.Exceptions is procedure Reraise; pragma No_Return (Reraise); + pragma Machine_Attribute (Reraise, "expected_throw"); pragma Export (C, Reraise, "__gnat_reraise"); -- Reraises the exception referenced by the Current_Excep field -- of the TSD (all fields of this exception occurrence are set). @@ -632,6 +646,96 @@ package body Ada.Exceptions is pragma No_Return (Rcheck_CE_Invalid_Data_Ext); pragma No_Return (Rcheck_CE_Range_Check_Ext); + -- These procedures are all expected to raise an exception. + -- These attributes are not visible to callers; they are made + -- visible in trans.c:build_raise_check. + + pragma Machine_Attribute (Rcheck_CE_Access_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Null_Access_Parameter, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Discriminant_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Divide_By_Zero, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Explicit_Raise, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Index_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Invalid_Data, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Length_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Null_Exception_Id, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Null_Not_Allowed, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Overflow_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Partition_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Range_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Tag_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Access_Before_Elaboration, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Accessibility_Check, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Address_Of_Intrinsic, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Aliased_Parameters, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_All_Guards_Closed, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Bad_Predicated_Generic_Type, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Build_In_Place_Mismatch, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Current_Task_In_Entry_Body, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Duplicated_Entry_Address, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Explicit_Raise, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Implicit_Return, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Misaligned_Address_Value, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Missing_Return, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Non_Transportable_Actual, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Overlaid_Controlled_Object, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Potentially_Blocking_Operation, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Stream_Operation_Not_Allowed, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Stubbed_Subprogram_Called, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Unchecked_Union_Restriction, + "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Finalize_Raised_Exception, + "expected_throw"); + pragma Machine_Attribute (Rcheck_SE_Empty_Storage_Pool, + "expected_throw"); + pragma Machine_Attribute (Rcheck_SE_Explicit_Raise, + "expected_throw"); + pragma Machine_Attribute (Rcheck_SE_Infinite_Recursion, + "expected_throw"); + pragma Machine_Attribute (Rcheck_SE_Object_Too_Large, + "expected_throw"); + + pragma Machine_Attribute (Rcheck_CE_Access_Check_Ext, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Index_Check_Ext, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Invalid_Data_Ext, + "expected_throw"); + pragma Machine_Attribute (Rcheck_CE_Range_Check_Ext, + "expected_throw"); + -- Make all of these procedures callable from strub contexts. -- These attributes are not visible to callers; they are made -- visible in trans.c:build_raise_check. diff --git a/gcc/ada/libgnat/a-except.ads b/gcc/ada/libgnat/a-except.ads index 7949b59..5583bf5 100644 --- a/gcc/ada/libgnat/a-except.ads +++ b/gcc/ada/libgnat/a-except.ads @@ -163,6 +163,14 @@ private Null_Id : constant Exception_Id := null; + pragma Machine_Attribute (Raise_Exception, "expected_throw"); + pragma Machine_Attribute (Reraise_Occurrence, "expected_throw"); + -- Tell the compiler that an exception is likely after calling + -- these subprograms. This could eventually be used for hot/cold + -- partitioning. For now, this only enables the control flow + -- redundancy to avoid duplicating a check before the No_Return + -- call and in the exception handler for the call. + ------------------------- -- Private Subprograms -- ------------------------- @@ -177,6 +185,7 @@ private procedure Raise_Exception_Always (E : Exception_Id; Message : String := ""); pragma No_Return (Raise_Exception_Always); + pragma Machine_Attribute (Raise_Exception_Always, "expected_throw"); pragma Export (Ada, Raise_Exception_Always, "__gnat_raise_exception"); -- This differs from Raise_Exception only in that the caller has determined -- that for sure the parameter E is not null, and that therefore no check @@ -195,6 +204,9 @@ private "__gnat_raise_from_controlled_operation"); -- Raise Program_Error, providing information about X (an exception raised -- during a controlled operation) in the exception message. + pragma Machine_Attribute (Raise_From_Controlled_Operation, + "expected_throw"); + -- Mark it like internal exception-raising subprograms procedure Reraise_Library_Exception_If_Any; pragma Export @@ -205,6 +217,7 @@ private procedure Reraise_Occurrence_Always (X : Exception_Occurrence); pragma No_Return (Reraise_Occurrence_Always); + pragma Machine_Attribute (Reraise_Occurrence_Always, "expected_throw"); -- This differs from Raise_Occurrence only in that the caller guarantees -- that for sure the parameter X is not the null occurrence, and that -- therefore this procedure cannot return. The expander uses this routine @@ -212,6 +225,7 @@ private procedure Reraise_Occurrence_No_Defer (X : Exception_Occurrence); pragma No_Return (Reraise_Occurrence_No_Defer); + pragma Machine_Attribute (Reraise_Occurrence_No_Defer, "expected_throw"); -- Exactly like Reraise_Occurrence, except that abort is not deferred -- before the call and the parameter X is known not to be the null -- occurrence. This is used in generated code when it is known that abort -- cgit v1.1 From 6c431c90947cb5a18d2b8807d5a94c644bd7021c Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 5 Jul 2023 19:49:40 +0200 Subject: ada: Fix assertion failure introduced by latest change The new processing is not properly guarded. gcc/ada/ * sem_ch13.adb (Replace_Type_References_Generic.Visible_Component): In the case of private discriminated types, explicitly check that we have a private declaration before examining its discriminant part. --- gcc/ada/sem_ch13.adb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index 4f97094..585c0f3 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -15593,8 +15593,6 @@ package body Sem_Ch13 is elsif Is_Private_Type (T) and then Has_Discriminants (T) then declare Decl : constant Node_Id := Declaration_Node (T); - Spec : constant List_Id := - Discriminant_Specifications (Original_Node (Decl)); Discr : Node_Id; @@ -15604,8 +15602,11 @@ package body Sem_Ch13 is -- name; then, if it exists, return the discriminant entity of -- the same name in the type, which is that of its full view. - if Present (Spec) then - Discr := First (Spec); + if Nkind (Decl) in N_Private_Extension_Declaration + | N_Private_Type_Declaration + and then Present (Discriminant_Specifications (Decl)) + then + Discr := First (Discriminant_Specifications (Decl)); while Present (Discr) loop if Chars (Defining_Identifier (Discr)) = Comp then -- cgit v1.1 From ae250f9e3c6f469ff8ed6799225a7aaf6f75cce6 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 4 Jul 2023 19:24:07 +0200 Subject: ada: Fix internal error on aggregates of self-referencing types The front-end contains a specific mechanism to deal with aggregates of self-referencing types by means of the Has_Self_Reference flag, which is supposed to be set during semantic analysis and used during expansion. The problem is that the first part overlooks aggregates of derived types which implicitly contain references to an ancestor type (the second part uses a broader condition but it is effectively guarded by the first one). This changes both parts to use the same condition based on the Is_Ancestor predicate, which seems to implement the expected semantic in this case. gcc/ada/ * sem_type.ads (Is_Ancestor): Remove mention of tagged type. * exp_aggr.adb: Add with and use clauses for Sem_Type. (Build_Record_Aggr_Code.Replace_Type): Call Is_Ancestor to spot self-references to the type of the aggregate. * sem_aggr.adb (Resolve_Record_Aggregate.Add_Discriminant_Values): Likewise. --- gcc/ada/exp_aggr.adb | 13 ++++++++----- gcc/ada/sem_aggr.adb | 11 +++++++---- gcc/ada/sem_type.ads | 7 +++---- 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index d922c3b..4c8dcae 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -61,6 +61,7 @@ with Sem_Ch13; use Sem_Ch13; with Sem_Eval; use Sem_Eval; with Sem_Mech; use Sem_Mech; with Sem_Res; use Sem_Res; +with Sem_Type; use Sem_Type; with Sem_Util; use Sem_Util; use Sem_Util.Storage_Model_Support; with Sinfo; use Sinfo; @@ -2760,19 +2761,21 @@ package body Exp_Aggr is function Replace_Type (Expr : Node_Id) return Traverse_Result is begin - -- Note regarding the Root_Type test below: Aggregate components for + -- Note about the Is_Ancestor test below: aggregate components for -- self-referential types include attribute references to the current - -- instance, of the form: Typ'access, etc.. These references are + -- instance, of the form: Typ'access, etc. These references are -- rewritten as references to the target of the aggregate: the -- left-hand side of an assignment, the entity in a declaration, - -- or a temporary. Without this test, we would improperly extended - -- this rewriting to attribute references whose prefix was not the + -- or a temporary. Without this test, we would improperly extend + -- this rewriting to attribute references whose prefix is not the -- type of the aggregate. if Nkind (Expr) = N_Attribute_Reference and then Is_Entity_Name (Prefix (Expr)) and then Is_Type (Entity (Prefix (Expr))) - and then Root_Type (Etype (N)) = Root_Type (Entity (Prefix (Expr))) + and then + Is_Ancestor + (Entity (Prefix (Expr)), Etype (N), Use_Full_View => True) then if Is_Entity_Name (Lhs) then Rewrite (Prefix (Expr), New_Occurrence_Of (Entity (Lhs), Loc)); diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index 3918946..5bfbde5 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -4546,14 +4546,17 @@ package body Sem_Aggr is Component_Associations (New_Aggr)); -- If the discriminant constraint is a current instance, mark the - -- current aggregate so that the self-reference can be expanded - -- later. The constraint may refer to the subtype of aggregate, so - -- use base type for comparison. + -- current aggregate so that the self-reference can be expanded by + -- Build_Record_Aggr_Code.Replace_Type later. if Nkind (Discr_Val) = N_Attribute_Reference and then Is_Entity_Name (Prefix (Discr_Val)) and then Is_Type (Entity (Prefix (Discr_Val))) - and then Base_Type (Etype (N)) = Entity (Prefix (Discr_Val)) + and then + Is_Ancestor + (Entity (Prefix (Discr_Val)), + Etype (N), + Use_Full_View => True) then Set_Has_Self_Reference (N); end if; diff --git a/gcc/ada/sem_type.ads b/gcc/ada/sem_type.ads index 6bc776a..e867885 100644 --- a/gcc/ada/sem_type.ads +++ b/gcc/ada/sem_type.ads @@ -222,10 +222,9 @@ package Sem_Type is (T1 : Entity_Id; T2 : Entity_Id; Use_Full_View : Boolean := False) return Boolean; - -- T1 is a tagged type (not class-wide). Verify that it is one of the - -- ancestors of type T2 (which may or not be class-wide). If Use_Full_View - -- is True then the full-view of private parents is used when climbing - -- through the parents of T2. + -- T1 is a type (not class-wide). Verify that it is one of the ancestors of + -- type T2 (which may or not be class-wide). If Use_Full_View is True, then + -- the full view of private parents is used when climbing T2's parents. -- -- Note: For analysis purposes the flag Use_Full_View must be set to False -- (otherwise we break the privacy contract since this routine returns true -- cgit v1.1 From 82ed6ed61113f110f474f7a638b7032a105a65f8 Mon Sep 17 00:00:00 2001 From: Ronan Desplanques Date: Thu, 29 Jun 2023 10:00:44 +0200 Subject: ada: Tweak CPU affinity handling on Linux Before this patch, the run-time assumed that not specifying a CPU affinity mask when creating a thread was equivalent to specifying a CPU affinity mask that included all CPUs. As documented in the man pages for pthread_create and pthread_setaffinity_np, this assumption is incorrect: a thread created using pthread_create inherits the CPU affinity mask of the creating thread by default. There was a comment in Set_Task_Affinity that acknowledged this behavior, but the actual code made the erroneous assumption mentioned above. That assumption caused the run-time to behave incorrectly when tasks were explicity assigned to Not_A_Specific_CPU: those tasks were assigned to the same CPUs as their parents instead of being allowed to run on any CPU. This patch fixes that behavior. This patch has the negative effect of making the runtime issue sched_setaffinity syscalls that are not necessary. gcc/ada/ * libgnarl/s-taprop__linux.adb (Set_Task_Affinity, Create_Task): Tweak handling of CPU affinities. --- gcc/ada/libgnarl/s-taprop__linux.adb | 38 +++++++----------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/libgnarl/s-taprop__linux.adb b/gcc/ada/libgnarl/s-taprop__linux.adb index 821ceef..efb99b3 100644 --- a/gcc/ada/libgnarl/s-taprop__linux.adb +++ b/gcc/ada/libgnarl/s-taprop__linux.adb @@ -966,16 +966,7 @@ package body System.Task_Primitives.Operations is -- Handle dispatching domains - -- To avoid changing CPU affinities when not needed, we set the - -- affinity only when assigning to a domain other than the default - -- one, or when the default one has been modified. - - elsif T.Common.Domain /= null and then - (T.Common.Domain /= ST.System_Domain - or else T.Common.Domain.all /= - [Multiprocessors.CPU'First .. - Multiprocessors.Number_Of_CPUs => True]) - then + else declare CPUs : constant size_t := C.size_t (Multiprocessors.Number_Of_CPUs); @@ -1497,17 +1488,9 @@ package body System.Task_Primitives.Operations is -- Handle dispatching domains - elsif T.Common.Domain /= null and then - (T.Common.Domain /= ST.System_Domain - or else T.Common.Domain.all /= - [Multiprocessors.CPU'First .. - Multiprocessors.Number_Of_CPUs => True]) - then + else -- Set the affinity to all the processors belonging to the - -- dispatching domain. To avoid changing CPU affinities when - -- not needed, we set the affinity only when assigning to a - -- domain other than the default one, or when the default one - -- has been modified. + -- dispatching domain. CPU_Set := CPU_ALLOC (CPUs); System.OS_Interface.CPU_ZERO (Size, CPU_Set); @@ -1519,18 +1502,11 @@ package body System.Task_Primitives.Operations is end loop; end if; - -- We set the new affinity if needed. Otherwise, the new task - -- will inherit its creator's CPU affinity mask (according to - -- the documentation of pthread_setaffinity_np), which is - -- consistent with Ada's required semantics. - - if CPU_Set /= null then - Result := - pthread_setaffinity_np (T.Common.LL.Thread, Size, CPU_Set); - pragma Assert (Result = 0); + Result := + pthread_setaffinity_np (T.Common.LL.Thread, Size, CPU_Set); + pragma Assert (Result = 0); - CPU_FREE (CPU_Set); - end if; + CPU_FREE (CPU_Set); end; end if; end Set_Task_Affinity; -- cgit v1.1 From e273cf2c1e7fb02eea3b73d8683c6591386587b4 Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Wed, 5 Jul 2023 17:27:14 +0000 Subject: ada: Constraint_Error caused by interface conversion When the sources have a type conversion from an interface type T2 to some ancestor interface type T1 (that is, T2 extends T1) the tag check added by the compiler may fail at runtime. gcc/ada/ * exp_disp.adb (Has_Dispatching_Constructor_Call): Removed. (Expand_Interface_Conversion): Reverse patch. --- gcc/ada/exp_disp.adb | 94 +++------------------------------------------------- 1 file changed, 4 insertions(+), 90 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb index 9381cee..9e0c87a 100644 --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -1242,92 +1242,9 @@ package body Exp_Disp is procedure Expand_Interface_Conversion (N : Node_Id) is - function Has_Dispatching_Constructor_Call - (Expr : Node_Id) return Boolean; - -- Determines if the expression has a dispatching constructor call - function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id; -- Return the underlying record type of Typ - -------------------------------------- - -- Has_Dispatching_Constructor_Call -- - -------------------------------------- - - function Has_Dispatching_Constructor_Call (Expr : Node_Id) return Boolean - is - function Is_Dispatching_Constructor_Call (N : Node_Id) return Boolean; - -- Determines if N is a dispatching constructor call - - function Process (Nod : Node_Id) return Traverse_Result; - -- Traverse the expression searching for constructor calls - - ------------------------------------- - -- Is_Dispatching_Constructor_Call -- - ------------------------------------- - - function Is_Dispatching_Constructor_Call (N : Node_Id) return Boolean - is - Param : Node_Id; - Param_Type : Entity_Id; - Assoc_Node : Node_Id; - Gen_Func_Id : Entity_Id; - - begin - if Nkind (N) = N_Function_Call - and then Present (Parameter_Associations (N)) - then - Param := First (Parameter_Associations (N)); - - if Nkind (Param) = N_Parameter_Association then - Param := Selector_Name (Param); - end if; - - Param_Type := Etype (Param); - - if Is_Itype (Param_Type) then - Assoc_Node := Associated_Node_For_Itype (Param_Type); - - if Nkind (Assoc_Node) = N_Function_Specification - and then Present (Generic_Parent (Assoc_Node)) - then - Gen_Func_Id := Generic_Parent (Assoc_Node); - - if Is_Intrinsic_Subprogram (Gen_Func_Id) - and then Chars (Gen_Func_Id) - = Name_Generic_Dispatching_Constructor - then - return True; - end if; - end if; - end if; - end if; - - return False; - end Is_Dispatching_Constructor_Call; - - ------------- - -- Process -- - ------------- - - function Process (Nod : Node_Id) return Traverse_Result is - begin - if Nkind (Nod) = N_Function_Call - and then Is_Dispatching_Constructor_Call (Nod) - then - return Abandon; - end if; - - return OK; - end Process; - - function Traverse_Expression is new Traverse_Func (Process); - - -- Start of processing for Has_Dispatching_Constructor_Call - - begin - return Traverse_Expression (Expr) = Abandon; - end Has_Dispatching_Constructor_Call; - ---------------------------- -- Underlying_Record_Type -- ---------------------------- @@ -1430,16 +1347,13 @@ package body Exp_Disp is -- object to reference the corresponding secondary dispatch table -- (cf. Make_DT and Expand_Dispatching_Constructor_Call)). - -- Under regular runtime this is a minor optimization that improves - -- the generated code; under configurable runtime (where generic - -- dispatching constructors are not supported) this optimization - -- allows supporting this interface conversion, which otherwise - -- would require calling the runtime routine to displace the - -- pointer to the object. + -- Under configurable runtime it is safe to skip generating code to + -- displace the pointer to the object, because generic dispatching + -- constructors are not supported. elsif Is_Interface (Iface_Typ) and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True) - and then not Has_Dispatching_Constructor_Call (Operand) + and then not RTE_Available (RE_Displace) then return; end if; -- cgit v1.1 From 086a2c9d042f14397dcde345c5011e20cc6016f4 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 5 Jul 2023 22:04:07 +0200 Subject: ada: Improve error message for ambiguous subprogram call This restores the full listing of the types for the interpretations. gcc/ada/ * sem_util.ads (Wrong_Type): Add Multiple parameter defaulting to False and document it. * sem_util.adb (Wrong_Type): Do not return early if an error has already been posted on Expr and Multiple is True. * sem_ch4.adb (Analyze_One_Call): Pass All_Errors_Mode as the actual parameter for Multiple to Wrong_Type. --- gcc/ada/sem_ch4.adb | 6 +++++- gcc/ada/sem_util.adb | 15 ++++++++++----- gcc/ada/sem_util.ads | 8 ++++++-- 3 files changed, 21 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index fafb7e6..8543f0d 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -4099,7 +4099,11 @@ package body Sem_Ch4 is Actual, Etype (Etype (Formal))); end if; - Wrong_Type (Actual, Etype (Formal)); + -- If we are going to output a secondary error message + -- below, we need to have Wrong_Type output the main one. + + Wrong_Type + (Actual, Etype (Formal), Multiple => All_Errors_Mode); if Nkind (Actual) = N_Op_Eq and then Nkind (Left_Opnd (Actual)) = N_Identifier diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 222fd72..35ec296 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -29398,7 +29398,11 @@ package body Sem_Util is -- Wrong_Type -- ---------------- - procedure Wrong_Type (Expr : Node_Id; Expected_Type : Entity_Id) is + procedure Wrong_Type + (Expr : Node_Id; + Expected_Type : Entity_Id; + Multiple : Boolean := False) + is Found_Type : constant Entity_Id := First_Subtype (Etype (Expr)); Expec_Type : constant Entity_Id := First_Subtype (Expected_Type); @@ -29485,13 +29489,14 @@ package body Sem_Util is begin -- Don't output message if either type is Any_Type, or if a message - -- has already been posted for this node. We need to do the latter - -- check explicitly (it is ordinarily done in Errout), because we - -- are using ! to force the output of the error messages. + -- has already been posted for this node and we do not want multiple + -- error messages. We need to do the latter check explicitly (it is + -- ordinarily done in Errout) because we are using '!' to force the + -- output of the error messages. if Expec_Type = Any_Type or else Found_Type = Any_Type - or else Error_Posted (Expr) + or else (Error_Posted (Expr) and then not Multiple) then return; diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index 7fc77de..b56a235 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -3362,12 +3362,16 @@ package Sem_Util is -- is potentially issued: it is the visible entity in the former case, and -- the use_clause in the latter case. - procedure Wrong_Type (Expr : Node_Id; Expected_Type : Entity_Id); + procedure Wrong_Type + (Expr : Node_Id; + Expected_Type : Entity_Id; + Multiple : Boolean := False); -- Output error message for incorrectly typed expression. Expr is the node -- for the incorrectly typed construct (Etype (Expr) is the type found), -- and Expected_Type is the entity for the expected type. Note that Expr -- does not have to be a subexpression, anything with an Etype field may - -- be used. + -- be used. If Multiple is False, do not output the message if an error + -- has already been posted for Expr. function Yields_Synchronized_Object (Typ : Entity_Id) return Boolean; -- Determine whether type Typ "yields synchronized object" as specified by -- cgit v1.1 From a6ca70c6744ed6019b1ddbc41c8a09a45331e5bb Mon Sep 17 00:00:00 2001 From: Viljar Indus Date: Wed, 5 Jul 2023 12:28:56 +0300 Subject: ada: Fix expanding container aggregates with Iterator specification The compiler should use unnamed addition methods such as Append when expanding a container aggregate with Iterator Specification. gcc/ada/ * exp_aggr.adb (Expand_Container_Aggregate): Use the positional addition method only when dealing with a container aggregate without an Iterator Specification e.g. with a loop parameter specification --- gcc/ada/exp_aggr.adb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 4c8dcae..dffc5ab 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -7259,8 +7259,11 @@ package body Exp_Aggr is -- Iterated component association. Discard -- positional insertion procedure. - Add_Named_Subp := Assign_Indexed_Subp; - Add_Unnamed_Subp := Empty; + if not Present (Iterator_Specification (Comp)) then + Add_Named_Subp := Assign_Indexed_Subp; + Add_Unnamed_Subp := Empty; + end if; + Expand_Iterated_Component (Comp); end if; -- cgit v1.1 From 99c419b2a8ce033e8be08f656edd350d97f72125 Mon Sep 17 00:00:00 2001 From: Viljar Indus Date: Wed, 5 Jul 2023 14:21:50 +0300 Subject: ada: Apply correct element type for container aggregates When dealing with a container aggregate with an iterator specification the iterator should take the value of the element of the container instead of the key. gcc/ada/ * sem_aggr.adb (Resolve_Iterated_Association): Use the element type for the iterator in a container aggregate with an iterator specification. --- gcc/ada/sem_aggr.adb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index 5bfbde5..ecd508a 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -3228,6 +3228,8 @@ package body Sem_Aggr is Analyze_And_Resolve (New_Copy_Tree (Key_Expr), Key_Type); End_Scope; + Typ := Key_Type; + elsif Present (Iterator_Specification (Comp)) then Copy := Copy_Separate_Tree (Iterator_Specification (Comp)); Id_Name := @@ -3252,7 +3254,7 @@ package body Sem_Aggr is elsif Present (Key_Type) then Analyze_And_Resolve (Choice, Key_Type); - + Typ := Key_Type; else Typ := Etype (Choice); -- assume unique for now end if; @@ -3282,12 +3284,8 @@ package body Sem_Aggr is Enter_Name (Id); - if No (Key_Type) then - pragma Assert (Present (Typ)); - Set_Etype (Id, Typ); - else - Set_Etype (Id, Key_Type); - end if; + pragma Assert (Present (Typ)); + Set_Etype (Id, Typ); Mutate_Ekind (Id, E_Variable); Set_Is_Not_Self_Hidden (Id); -- cgit v1.1 From c57fbb120dabb4fee85cc12ae99abe5060213d93 Mon Sep 17 00:00:00 2001 From: Viljar Indus Date: Thu, 6 Jul 2023 16:02:19 +0300 Subject: ada: Avoid iterator conflicts in container aggregates Create temporary scope for the iterators defined in a container aggregate so that it would not be put to the same scope where the expression was used. This would otherwise lead to multiple aggregates with iterators that have the same name leading to a name conflict. gcc/ada/ * sem_aggr.adb (Resolve_Iterated_Association): Add temporary scope when analyzing the Iterator Specification. Use preanalysis instead of Analysis to avoid polluting the tree. --- gcc/ada/sem_aggr.adb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index ecd508a..364217d 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -3231,11 +3231,24 @@ package body Sem_Aggr is Typ := Key_Type; elsif Present (Iterator_Specification (Comp)) then + -- Create a temporary scope to avoid some modifications from + -- escaping the Analyze call below. The original Tree will be + -- reanalyzed later. + + Ent := New_Internal_Entity + (E_Loop, Current_Scope, Sloc (Comp), 'L'); + Set_Etype (Ent, Standard_Void_Type); + Set_Parent (Ent, Parent (Comp)); + Push_Scope (Ent); + Copy := Copy_Separate_Tree (Iterator_Specification (Comp)); Id_Name := Chars (Defining_Identifier (Iterator_Specification (Comp))); - Analyze (Copy); + Preanalyze (Copy); + + End_Scope; + Typ := Etype (Defining_Identifier (Copy)); else -- cgit v1.1 From 99b45bbea4dbeb07e0fbc916be28ad006e0f83a7 Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Sun, 9 Jul 2023 10:58:05 +0000 Subject: ada: Constraint_Error caused by 'Image applied to interface type When the prefix of 'Image is used with a class-wide interface type object, the frontend does not generate code to displace the pointer to the underlying object to reference its base, and this is required to invoke Ada.Tags.Wide_Wide_Expanded_Name. gcc/ada/ * exp_imgv.adb (Rewrite_Object_Image): fix type of formal. Found reading sources. (Expand_Wide_Image_Attribute): ditto. (Expand_Wide_Wide_Image_Attribute): ditto. (Rewrite_Object_Image): ditto. * exp_put_image.adb (Build_Image_Call): For class-wide interface type prefix generate code to displace the pointer to the object to reference the base of the underlying object. --- gcc/ada/exp_imgv.adb | 8 ++++---- gcc/ada/exp_put_image.adb | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb index a31ce1d..6bcfec6 100644 --- a/gcc/ada/exp_imgv.adb +++ b/gcc/ada/exp_imgv.adb @@ -61,7 +61,7 @@ package body Exp_Imgv is procedure Rewrite_Object_Image (N : Node_Id; - Pref : Entity_Id; + Pref : Node_Id; Attr_Name : Name_Id; Str_Typ : Entity_Id); -- AI12-0124: Rewrite attribute 'Image when it is applied to an object @@ -1830,7 +1830,7 @@ package body Exp_Imgv is procedure Expand_Wide_Image_Attribute (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); - Pref : constant Entity_Id := Prefix (N); + Pref : constant Node_Id := Prefix (N); Rnn : constant Entity_Id := Make_Temporary (Loc, 'S'); Lnn : constant Entity_Id := Make_Temporary (Loc, 'P'); Rtyp : Entity_Id; @@ -1938,7 +1938,7 @@ package body Exp_Imgv is procedure Expand_Wide_Wide_Image_Attribute (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); - Pref : constant Entity_Id := Prefix (N); + Pref : constant Node_Id := Prefix (N); Rnn : constant Entity_Id := Make_Temporary (Loc, 'S'); Lnn : constant Entity_Id := Make_Temporary (Loc, 'P'); Rtyp : Entity_Id; @@ -2493,7 +2493,7 @@ package body Exp_Imgv is procedure Rewrite_Object_Image (N : Node_Id; - Pref : Entity_Id; + Pref : Node_Id; Attr_Name : Name_Id; Str_Typ : Entity_Id) is diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb index 9eda323..0c357f1 100644 --- a/gcc/ada/exp_put_image.adb +++ b/gcc/ada/exp_put_image.adb @@ -1190,10 +1190,41 @@ package body Exp_Put_Image is Parameter_Associations => New_List (Sink_Exp, String_Exp)); end Put_String_Exp; + -- Local variables + + Tag_Node : Node_Id; + -- Start of processing for Build_Image_Call begin if Is_Class_Wide_Type (U_Type) then + + -- For interface types we must generate code to displace the pointer + -- to the object to reference the base of the underlying object. + + -- Generate: + -- To_Tag_Ptr (Image_Prefix'Address).all + + -- Note that Image_Prefix'Address is recursively expanded into a + -- call to Ada.Tags.Base_Address (Image_Prefix'Address). + + if Is_Interface (U_Type) then + Tag_Node := + Make_Explicit_Dereference (Loc, + Unchecked_Convert_To (RTE (RE_Tag_Ptr), + Make_Attribute_Reference (Loc, + Prefix => Duplicate_Subexpr (Image_Prefix), + Attribute_Name => Name_Address))); + + -- Common case + + else + Tag_Node := + Make_Attribute_Reference (Loc, + Prefix => Duplicate_Subexpr (Image_Prefix), + Attribute_Name => Name_Tag); + end if; + -- Generate qualified-expression syntax; qualification name comes -- from calling Ada.Tags.Wide_Wide_Expanded_Name. @@ -1208,10 +1239,7 @@ package body Exp_Put_Image is (Make_Function_Call (Loc, Name => New_Occurrence_Of (RTE (RE_Wide_Wide_Expanded_Name), Loc), - Parameter_Associations => New_List ( - Make_Attribute_Reference (Loc, - Prefix => Duplicate_Subexpr (Image_Prefix), - Attribute_Name => Name_Tag))), + Parameter_Associations => New_List (Tag_Node)), Wide_Wide => True); Qualification : constant Node_Id := -- cgit v1.1 From 054e93b8757a2d619a528f7dd1b8580cce13c713 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 29 Jun 2023 09:56:59 -0600 Subject: ada: Use new typedefs in gcc-interface This changes gcc-interface to use the typedefs that were recently introduced in gnat. This is another step toward switching the code generator to emit enums rather than preprocessor defines. In a couple of spots, a 'default' case is also added. These avoid warnings from -Wswitch when the typedefs are changed to be enums. gcc/ada/ * gcc-interface/decl.cc (check_ok_for_atomic_type): Use Pragma_Id. * gcc-interface/trans.cc (lvalue_required_p, Pragma_to_gnu): Use Pragma_Id. (get_type_length, Attribute_to_gnu, get_atomic_access): Use Attribute_Id. --- gcc/ada/gcc-interface/decl.cc | 5 ++++- gcc/ada/gcc-interface/trans.cc | 15 ++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index ee913a0..ae756b3 100644 --- a/gcc/ada/gcc-interface/decl.cc +++ b/gcc/ada/gcc-interface/decl.cc @@ -6875,6 +6875,9 @@ elaborate_entity (Entity_Id gnat_entity) } break; + /* -Wswitch warning avoidance. */ + default: + break; } } @@ -9705,7 +9708,7 @@ check_ok_for_atomic_type (tree type, Entity_Id gnat_entity, bool component_p) gnat_node = Next_Rep_Item (gnat_node)) if (Nkind (gnat_node) == N_Pragma) { - unsigned char pragma_id + const Pragma_Id pragma_id = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node))); if ((pragma_id == Pragma_Atomic && !component_p) diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index f5eadbb..fd85fac 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -814,7 +814,7 @@ lvalue_required_p (Node_Id gnat_node, tree gnu_type, bool constant, case N_Pragma: if (Is_Pragma_Name (Chars (Pragma_Identifier (gnat_parent)))) { - const unsigned char id + const Pragma_Id id = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_parent))); return id == Pragma_Inspection_Point; } @@ -1331,7 +1331,7 @@ Pragma_to_gnu (Node_Id gnat_node) if (!Is_Pragma_Name (Chars (Pragma_Identifier (gnat_node)))) return gnu_result; - const unsigned char id + const Pragma_Id id = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node))); /* Save the expression of pragma Compile_Time_{Error|Warning} for later. */ @@ -1670,7 +1670,8 @@ get_type_length (tree type, tree result_type) should place the result type. ATTRIBUTE is the attribute ID. */ static tree -Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) +Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, + Attribute_Id attribute) { const Node_Id gnat_prefix = Prefix (gnat_node); tree gnu_prefix = gnat_to_gnu (gnat_prefix); @@ -2370,6 +2371,10 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) case Attr_Bit_Position: gnu_result = gnu_field_bitpos; break; + + /* -Wswitch warning avoidance. */ + default: + break; } /* If this has a PLACEHOLDER_EXPR, qualify it by the object we are @@ -4292,7 +4297,7 @@ static void get_atomic_access (Node_Id gnat_node, atomic_acces_t *type, bool *sync) { Node_Id gnat_parent, gnat_temp; - unsigned char attr_id; + Attribute_Id attr_id; /* First, scan the parent to filter out irrelevant cases. */ gnat_parent = Parent (gnat_node); @@ -6854,7 +6859,7 @@ gnat_to_gnu (Node_Id gnat_node) case N_Attribute_Reference: { /* The attribute designator. */ - const int attr = Get_Attribute_Id (Attribute_Name (gnat_node)); + const Attribute_Id attr = Get_Attribute_Id (Attribute_Name (gnat_node)); /* The Elab_Spec and Elab_Body attributes are special in that Prefix is a unit, not an object with a GCC equivalent. */ -- cgit v1.1 From 1e0f37df1b12cd91a6dbb523f5c722f9a961edaa Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 18 Jul 2023 09:21:40 -0400 Subject: c++: constrained surrogate call functions [PR110535] We weren't checking constraints on pointer/reference-to-function conversion functions during overload resolution, which caused us to ICE on the first testcase and reject the second testcase. PR c++/110535 gcc/cp/ChangeLog: * call.cc (add_conv_candidate): Check constraints. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-surrogate1.C: New test. * g++.dg/cpp2a/concepts-surrogate2.C: New test. --- gcc/cp/call.cc | 8 ++++++++ gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C | 12 ++++++++++++ gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C | 14 ++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C (limited to 'gcc') diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 976330c..24f93dd 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -2588,6 +2588,14 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, if (*candidates && (*candidates)->fn == totype) return NULL; + if (!constraints_satisfied_p (fn)) + { + reason = constraint_failure (); + viable = 0; + return add_candidate (candidates, fn, obj, arglist, len, convs, + access_path, conversion_path, viable, reason, flags); + } + for (i = 0; i < len; ++i) { tree arg, argtype, convert_type = NULL_TREE; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C new file mode 100644 index 0000000..e8481a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate1.C @@ -0,0 +1,12 @@ +// PR c++/110535 +// { dg-do compile { target c++20 } } + +using F = int(int); + +template +struct A { + operator F*() requires B; +}; + +int i = A{}(0); // OK +int j = A{}(0); // { dg-error "no match" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C new file mode 100644 index 0000000..8bf8364 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-surrogate2.C @@ -0,0 +1,14 @@ +// PR c++/110535 +// { dg-do compile { target c++20 } } + +using F = int(int); +using G = long(int); + +template +struct A { + operator F&() requires B; + operator G&() requires (!B); +}; + +int i = A{}(0); // { dg-bogus "ambiguous" } +int j = A{}(0); // { dg-bogus "ambiguous" } -- cgit v1.1 From cde17323f950ac372691efd0a740fe0b4d7914a4 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 18 Jul 2023 09:22:49 -0400 Subject: c++: non-standalone surrogate call template I noticed we're accidentally prevented from considering a pointer- or reference-to-function conversion function template if it's not the first conversion function that's considered, which for the testcase below results in us accepting the B call but not the A call despite the only difference between A and B being their order of member declarations. This patch fixes this so that the outcome of overload resolution doesn't arbitrarily depend on declaration order here. gcc/cp/ChangeLog: * call.cc (add_template_conv_candidate): Don't check for non-empty 'candidates' here. (build_op_call): Check it here, before we've considered any conversion functions. gcc/testsuite/ChangeLog: * g++.dg/overload/conv-op5.C: New test. --- gcc/cp/call.cc | 24 ++++++++++++++---------- gcc/testsuite/g++.dg/overload/conv-op5.C | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/conv-op5.C (limited to 'gcc') diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 24f93dd..b55230d 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -3709,12 +3709,6 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, tree return_type, tree access_path, tree conversion_path, tsubst_flags_t complain) { - /* Making this work broke PR 71117 and 85118, so until the committee resolves - core issue 2189, let's disable this candidate if there are any call - operators. */ - if (*candidates) - return NULL; - return add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE, NULL_TREE, arglist, return_type, access_path, @@ -5290,6 +5284,8 @@ build_op_call (tree obj, vec **args, tsubst_flags_t complain) LOOKUP_NORMAL, &candidates, complain); } + bool any_call_ops = candidates != nullptr; + convs = lookup_conversions (type); for (; convs; convs = TREE_CHAIN (convs)) @@ -5306,10 +5302,18 @@ build_op_call (tree obj, vec **args, tsubst_flags_t complain) continue; if (TREE_CODE (fn) == TEMPLATE_DECL) - add_template_conv_candidate - (&candidates, fn, obj, *args, totype, - /*access_path=*/NULL_TREE, - /*conversion_path=*/NULL_TREE, complain); + { + /* Making this work broke PR 71117 and 85118, so until the + committee resolves core issue 2189, let's disable this + candidate if there are any call operators. */ + if (any_call_ops) + continue; + + add_template_conv_candidate + (&candidates, fn, obj, *args, totype, + /*access_path=*/NULL_TREE, + /*conversion_path=*/NULL_TREE, complain); + } else add_conv_candidate (&candidates, fn, obj, *args, /*conversion_path=*/NULL_TREE, diff --git a/gcc/testsuite/g++.dg/overload/conv-op5.C b/gcc/testsuite/g++.dg/overload/conv-op5.C new file mode 100644 index 0000000..4f75092 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/conv-op5.C @@ -0,0 +1,17 @@ +// { dg-do compile { target c++11 } } + +template using F = int(*)(T); +using G = int(*)(int*); + +struct A { + template operator F(); // #1 + operator G() = delete; // #2 +}; + +struct B { + operator G() = delete; // #2 + template operator F(); // #1 +}; + +int i = A{}(0); // OK, selects #1 +int j = B{}(0); // OK, selects #1 -- cgit v1.1 From cbe5f6859a73b2acf203bd7d13f9fb245d63cbd4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 18 Jul 2023 10:02:52 +0200 Subject: middle-end/105715 - missed RTL if-conversion with COND_EXPR expansion When the COND_EXPR condition operand was split out to a separate stmt it became subject to CSE with other condition evaluations. This unfortunately leads to TER no longer applying and in turn RTL expansion of COND_EXPRs no longer seeing the condition and thus failing to try conditional move expansion. This can be seen with gcc.target/i386/pr45685.c when built with -march=cascadelake which then FAILs to produce the expected number of cmovs. It can also be seen when we create more COND_EXPRs early like for instruction selection of MIN/MAX operations that map to IEEE a > b ? a : b expression semantics. PR middle-end/105715 * gimple-isel.cc (gimple_expand_vec_exprs): Merge into... (pass_gimple_isel::execute): ... this. Duplicate comparison defs of COND_EXPRs. --- gcc/gimple-isel.cc | 121 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 41 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index e567064..8deb371 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -336,11 +336,43 @@ gimple_expand_vec_cond_expr (struct function *fun, gimple_stmt_iterator *gsi, -/* Iterate all gimple statements and try to expand - VEC_COND_EXPR assignments. */ +namespace { + +const pass_data pass_data_gimple_isel = +{ + GIMPLE_PASS, /* type */ + "isel", /* name */ + OPTGROUP_VEC, /* optinfo_flags */ + TV_NONE, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_update_ssa, /* todo_flags_finish */ +}; -static unsigned int -gimple_expand_vec_exprs (struct function *fun) +class pass_gimple_isel : public gimple_opt_pass +{ +public: + pass_gimple_isel (gcc::context *ctxt) + : gimple_opt_pass (pass_data_gimple_isel, ctxt) + {} + + /* opt_pass methods: */ + bool gate (function *) final override + { + return true; + } + + unsigned int execute (function *fun) final override; +}; // class pass_gimple_isel + + +/* Iterate all gimple statements and perform pre RTL expansion + GIMPLE massaging to improve instruction selection. */ + +unsigned int +pass_gimple_isel::execute (struct function *fun) { gimple_stmt_iterator gsi; basic_block bb; @@ -352,6 +384,8 @@ gimple_expand_vec_exprs (struct function *fun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { + /* Pre-expand VEC_COND_EXPRs to .VCOND* internal function + calls mapping to supported optabs. */ gimple *g = gimple_expand_vec_cond_expr (fun, &gsi, &vec_cond_ssa_name_uses); if (g != NULL) @@ -361,14 +395,54 @@ gimple_expand_vec_exprs (struct function *fun) gsi_replace (&gsi, g, false); } + /* Recognize .VEC_SET and .VEC_EXTRACT patterns. */ cfg_changed |= gimple_expand_vec_set_extract_expr (fun, &gsi); - if (gsi_end_p (gsi)) break; + + gassign *stmt = dyn_cast (*gsi); + if (!stmt) + continue; + + tree_code code = gimple_assign_rhs_code (stmt); + tree lhs = gimple_assign_lhs (stmt); + if (TREE_CODE_CLASS (code) == tcc_comparison + && !has_single_use (lhs)) + { + /* Duplicate COND_EXPR condition defs when they are + comparisons so RTL expansion with the help of TER + can perform better if conversion. */ + imm_use_iterator imm_iter; + use_operand_p use_p; + auto_vec cond_exprs; + unsigned cnt = 0; + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) + { + if (is_gimple_debug (USE_STMT (use_p))) + continue; + cnt++; + if (gimple_bb (USE_STMT (use_p)) == bb + && is_gimple_assign (USE_STMT (use_p)) + && gimple_assign_rhs1_ptr (USE_STMT (use_p)) == use_p->use + && gimple_assign_rhs_code (USE_STMT (use_p)) == COND_EXPR) + cond_exprs.safe_push (as_a (USE_STMT (use_p))); + } + for (unsigned i = cond_exprs.length () == cnt ? 1 : 0; + i < cond_exprs.length (); ++i) + { + gassign *copy = as_a (gimple_copy (stmt)); + tree new_def = duplicate_ssa_name (lhs, copy); + gimple_assign_set_lhs (copy, new_def); + auto gsi2 = gsi_for_stmt (cond_exprs[i]); + gsi_insert_before (&gsi2, copy, GSI_SAME_STMT); + gimple_assign_set_rhs1 (cond_exprs[i], new_def); + update_stmt (cond_exprs[i]); + } + } } } - for (hash_map::iterator it = vec_cond_ssa_name_uses.begin (); + for (auto it = vec_cond_ssa_name_uses.begin (); it != vec_cond_ssa_name_uses.end (); ++it) bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION ((*it).first)); @@ -377,41 +451,6 @@ gimple_expand_vec_exprs (struct function *fun) return cfg_changed ? TODO_cleanup_cfg : 0; } -namespace { - -const pass_data pass_data_gimple_isel = -{ - GIMPLE_PASS, /* type */ - "isel", /* name */ - OPTGROUP_VEC, /* optinfo_flags */ - TV_NONE, /* tv_id */ - PROP_cfg, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_update_ssa, /* todo_flags_finish */ -}; - -class pass_gimple_isel : public gimple_opt_pass -{ -public: - pass_gimple_isel (gcc::context *ctxt) - : gimple_opt_pass (pass_data_gimple_isel, ctxt) - {} - - /* opt_pass methods: */ - bool gate (function *) final override - { - return true; - } - - unsigned int execute (function *fun) final override - { - return gimple_expand_vec_exprs (fun); - } - -}; // class pass_gimple_isel - } // anon namespace gimple_opt_pass * -- cgit v1.1 From b80e3c468e373cc6fd4e41a5879dbca95a40ac8c Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Tue, 18 Jul 2023 16:31:49 +0100 Subject: [modula2] Uninitialized variable static analysis improvements This patch fixes many limitations of the uninitialized static analysis. NEW is understood, local variable pointers and non var parameters will be tracked. gcc/ChangeLog: * doc/gm2.texi (Semantic checking): Change example testwithptr to testnew6. gcc/m2/ChangeLog: * Make-lang.in: Minor formatting change. * gm2-compiler/M2GCCDeclare.mod (DeclareUnboundedProcedureParameters): Rename local variables. (WalkUnboundedProcedureParameters): Rename local variables. (DoVariableDeclaration): Avoid declaration of a variable if it is on the heap (used by static analysis only). * gm2-compiler/M2GenGCC.mod: Formatting. * gm2-compiler/M2Quads.def (GetQuadTrash): New procedure function. * gm2-compiler/M2Quads.mod (GetQuadTrash): New procedure function. (QuadFrame): Add Trash field. (BuildRealFuncProcCall): Detect ALLOCATE and DEALLOCATE and create a heap variable for parameter 1 saving it as the trashed variable for static analysis. (GenQuadOTrash): New procedure. (DisplayQuadRange): Bugfix. Write the scope number. * gm2-compiler/M2SymInit.mod: Rewritten to separate LValue equivalence from LValue to RValue pairings. Comprehensive detection of variant record implemented. Allow dereferencing of pointers through LValue/RValue chains. * gm2-compiler/SymbolTable.def (PutVarHeap): New procedure. (IsVarHeap): New procedure function. (ForeachParamSymDo): New procedure. * gm2-compiler/SymbolTable.mod (PutVarHeap): New procedure. (IsVarHeap): New procedure function. (ForeachParamSymDo): New procedure. (MakeVariableForParam): Reformatted. (CheckForUnknownInModule): Reformatted. (SymVar): Add field Heap. (MakeVar): Assign Heap to FALSE. gcc/testsuite/ChangeLog: * gm2/switches/uninit-variable-checking/pass/assignparam.mod: New test. * gm2/switches/uninit-variable-checking/pass/tiny.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/switches-uninit-variable-checking-procedures-fail.exp: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testnew.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testnew2.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testnew3.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testnew4.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testnew5.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testnew6.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testptrptr.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/assignparam2.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/switches-uninit-variable-checking-procedures-pass.exp: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testnew5.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testnew6.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testparamlvalue.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testparamrvalue.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testproc.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testptrptr.mod: New test. Signed-off-by: Gaius Mulley --- gcc/doc/gm2.texi | 25 +- gcc/m2/Make-lang.in | 3 +- gcc/m2/gm2-compiler/M2GCCDeclare.mod | 44 +- gcc/m2/gm2-compiler/M2GenGCC.mod | 4 +- gcc/m2/gm2-compiler/M2Quads.def | 10 +- gcc/m2/gm2-compiler/M2Quads.mod | 70 ++- gcc/m2/gm2-compiler/M2SymInit.mod | 520 ++++++++++++++++----- gcc/m2/gm2-compiler/SymbolTable.def | 25 + gcc/m2/gm2-compiler/SymbolTable.mod | 87 +++- .../uninit-variable-checking/pass/assignparam.mod | 31 ++ .../uninit-variable-checking/pass/tiny.mod | 13 + ...es-uninit-variable-checking-procedures-fail.exp | 37 ++ .../procedures/fail/testnew.mod | 31 ++ .../procedures/fail/testnew2.mod | 31 ++ .../procedures/fail/testnew3.mod | 34 ++ .../procedures/fail/testnew4.mod | 34 ++ .../procedures/fail/testnew5.mod | 31 ++ .../procedures/fail/testnew6.mod | 27 ++ .../procedures/fail/testptrptr.mod | 32 ++ .../procedures/pass/assignparam2.mod | 31 ++ ...es-uninit-variable-checking-procedures-pass.exp | 37 ++ .../procedures/pass/testnew5.mod | 27 ++ .../procedures/pass/testnew6.mod | 27 ++ .../procedures/pass/testparamlvalue.mod | 26 ++ .../procedures/pass/testparamrvalue.mod | 26 ++ .../procedures/pass/testproc.mod | 15 + .../procedures/pass/testptrptr.mod | 29 ++ 27 files changed, 1140 insertions(+), 167 deletions(-) create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/pass/assignparam.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/pass/tiny.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/switches-uninit-variable-checking-procedures-fail.exp create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew2.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew3.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew4.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew5.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew6.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testptrptr.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/assignparam2.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/switches-uninit-variable-checking-procedures-pass.exp create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew5.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew6.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamlvalue.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamrvalue.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testproc.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testptrptr.mod (limited to 'gcc') diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi index 8d5d95f..9f7f8ce 100644 --- a/gcc/doc/gm2.texi +++ b/gcc/doc/gm2.texi @@ -1471,7 +1471,7 @@ plugin is invoked. The @samp{-Wuninit-variable-checking} can be used to identify uninitialized variables within the first basic block in a procedure. The checking is limited to variables so long as they are -not an array or set or a variant record. +not an array or set or a variant record or var parameter. The following example detects whether a sub component within a record is uninitialized. @@ -1551,22 +1551,20 @@ access expression before it has been initialized @end example @example -MODULE testwithptr ; +MODULE testnew6 ; -FROM SYSTEM IMPORT ADR ; +FROM Storage IMPORT ALLOCATE ; TYPE - PtrToVec = POINTER TO Vec ; - Vec = RECORD - x, y: CARDINAL ; - END ; + PtrToVec = POINTER TO RECORD + x, y: INTEGER ; + END ; PROCEDURE test ; VAR p: PtrToVec ; - v: Vec ; BEGIN - p := ADR (v) ; + NEW (p) ; WITH p^ DO x := 1 ; x := 2 (* Deliberate typo, user meant y. *) @@ -1576,16 +1574,17 @@ BEGIN END END test ; + BEGIN test -END testwithptr. +END testnew6. @end example @example -gm2 -c -Wuninit-variable-checking testwithptr.mod -testwithptr.mod:26:9: warning: In procedure ‘test’: attempting to +$ gm2 -g -c -Wuninit-variable-checking testnew6.mod +testnew6.mod:19:9: warning: In procedure ‘test’: attempting to access expression before it has been initialized - 26 | IF p^.y = 2 + 19 | IF p^.y = 2 | ~~^~ @end example diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in index 0fe671e..ab82113 100644 --- a/gcc/m2/Make-lang.in +++ b/gcc/m2/Make-lang.in @@ -462,7 +462,8 @@ GM2_G=-g -fm2-g GM2_CPP= # GM2_DEBUG_STRMEM=-fcpp GM2_DEBUG_STRMEM= -GM2_FLAGS=-Wunused-variable -Wuninit-variable-checking -fsoft-check-all \ +GM2_FLAGS=-Wunused-variable -Wuninit-variable-checking \ + -fsoft-check-all \ -fno-return -Wreturn-type \ $(GM2_G) $(GM2_O) \ -funbounded-by-reference -fpim -fextended-opaque \ diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod index eaa3255..92de4b4 100644 --- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod +++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod @@ -95,7 +95,7 @@ FROM SymbolTable IMPORT NulSym, IsProcedureReachable, IsParameter, IsConstLit, IsDummy, IsVarAParam, IsProcedureVariable, IsGnuAsm, IsGnuAsmVolatile, IsObject, IsTuple, - IsError, IsHiddenType, + IsError, IsHiddenType, IsVarHeap, IsComponent, IsPublic, IsExtern, IsCtor, GetMainModule, GetBaseModule, GetModule, GetLocalSym, PutModuleFinallyFunction, @@ -2118,7 +2118,8 @@ END WalkTypeInfo ; PROCEDURE DeclareUnboundedProcedureParameters (sym: WORD) ; VAR - son, type, + param, + type, p, i : CARDINAL ; location : location_t ; BEGIN @@ -2129,8 +2130,8 @@ BEGIN WHILE i>0 DO IF IsUnboundedParam(sym, i) THEN - son := GetNthParam(sym, i) ; - type := GetSType(son) ; + param := GetNthParam(sym, i) ; + type := GetSType(param) ; TraverseDependants(type) ; IF GccKnowsAbout(type) THEN @@ -2138,8 +2139,8 @@ BEGIN BuildTypeDeclaration(location, Mod2Gcc(type)) END ELSE - son := GetNth(sym, i) ; - type := GetSType(son) ; + param := GetNth(sym, i) ; + type := GetSType(param) ; TraverseDependants(type) END ; DEC(i) @@ -2154,31 +2155,24 @@ END DeclareUnboundedProcedureParameters ; PROCEDURE WalkUnboundedProcedureParameters (sym: WORD) ; VAR - son, + param, type, p, i: CARDINAL ; BEGIN - IF IsProcedure(sym) + IF IsProcedure (sym) THEN - p := NoOfParam(sym) ; + p := NoOfParam (sym) ; i := p ; WHILE i>0 DO - IF IsUnboundedParam(sym, i) + IF IsUnboundedParam (sym, i) THEN - son := GetNthParam(sym, i) ; - type := GetSType(son) ; - WalkTypeInfo(type) ; -(* - type := GetUnboundedRecordType(type) ; - Assert(IsRecord(type)) ; - RecordNotPacked(type) (* which is never packed. *) -*) + param := GetNthParam (sym, i) ELSE - son := GetNth(sym, i) ; - type := GetSType(son) ; - WalkTypeInfo(type) + param := GetNth (sym, i) END ; - DEC(i) + type := GetSType (param) ; + WalkTypeInfo (type) ; + DEC (i) END END END WalkUnboundedProcedureParameters ; @@ -3173,7 +3167,7 @@ VAR varType : CARDINAL ; location: location_t ; BEGIN - IF IsComponent (var) + IF IsComponent (var) OR IsVarHeap (var) THEN RETURN END ; @@ -3909,6 +3903,10 @@ BEGIN THEN printf0('component ') END ; + IF IsVarHeap (sym) + THEN + printf0('heap ') + END ; printf0 ('\n') ; PrintInitialized (sym) ; IncludeType(l, sym) diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod index 0955106..d701543 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.mod +++ b/gcc/m2/gm2-compiler/M2GenGCC.mod @@ -1362,7 +1362,9 @@ BEGIN (* now assign param.Addr := ADR(NewArray) *) BuildAssignmentStatement (location, - BuildComponentRef (location, Mod2Gcc (param), Mod2Gcc (GetUnboundedAddressOffset (UnboundedType))), + BuildComponentRef (location, + Mod2Gcc (param), + Mod2Gcc (GetUnboundedAddressOffset (UnboundedType))), NewArray) END MakeCopyUse ; diff --git a/gcc/m2/gm2-compiler/M2Quads.def b/gcc/m2/gm2-compiler/M2Quads.def index cd011ba..3a40595 100644 --- a/gcc/m2/gm2-compiler/M2Quads.def +++ b/gcc/m2/gm2-compiler/M2Quads.def @@ -145,7 +145,8 @@ EXPORT QUALIFIED StartBuildDefFile, StartBuildModFile, EndBuildFile, IsAutoPushOn, PushAutoOn, PushAutoOff, PopAuto, PushInConstExpression, PopInConstExpression, IsInConstExpression, - MustCheckOverflow, BuildAsmElement, BuildAsmTrash ; + MustCheckOverflow, BuildAsmElement, BuildAsmTrash, + GetQuadTrash ; TYPE @@ -2771,4 +2772,11 @@ PROCEDURE BuildAsmElement (input, output: BOOLEAN) ; PROCEDURE BuildAsmTrash ; +(* + GetQuadTrash - return the symbol associated with the trashed operand. +*) + +PROCEDURE GetQuadTrash (quad: CARDINAL) : CARDINAL ; + + END M2Quads. diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod index 5ed2252..db5513d 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -85,6 +85,7 @@ FROM SymbolTable IMPORT ModeOfAddr, GetMode, PutMode, GetSymName, IsUnknown, PutPriority, GetPriority, PutProcedureBegin, PutProcedureEnd, PutVarConst, IsVarConst, + PutVarHeap, IsVarParam, IsProcedure, IsPointer, IsParameter, IsUnboundedParam, IsEnumeration, IsDefinitionForC, IsVarAParam, IsVarient, IsLegal, @@ -290,6 +291,7 @@ TYPE Operand1 : CARDINAL ; Operand2 : CARDINAL ; Operand3 : CARDINAL ; + Trash : CARDINAL ; Next : CARDINAL ; (* Next quadruple. *) LineNo : CARDINAL ; (* Line No of source text. *) TokenNo : CARDINAL ; (* Token No of source text. *) @@ -1481,6 +1483,7 @@ BEGIN Operand1 := 0 ; Operand2 := 0 ; Operand3 := 0 ; + Trash := 0 ; op1pos := UnknownTokenNo ; op2pos := UnknownTokenNo ; op3pos := UnknownTokenNo @@ -5174,17 +5177,24 @@ END BuildRealProcedureCall ; PROCEDURE BuildRealFuncProcCall (tokno: CARDINAL; IsFunc, IsForC: BOOLEAN) ; VAR + AllocateProc, + DeallocateProc, ForcedFunc, ParamConstant : BOOLEAN ; + trash, resulttok, paramtok, proctok, NoOfParameters, i, pi, + ParamType, + Param1, (* Used to remember first param for allocate/deallocate. *) ReturnVar, ProcSym, Proc : CARDINAL ; BEGIN + Param1 := NulSym ; + ParamType := NulSym ; CheckProcedureParameters (IsForC) ; PopT (NoOfParameters) ; PushT (NoOfParameters) ; (* Restore stack to original state. *) @@ -5197,6 +5207,8 @@ BEGIN paramtok := proctok ; ProcSym := SkipConst (ProcSym) ; ForcedFunc := FALSE ; + AllocateProc := FALSE ; + DeallocateProc := FALSE ; IF IsVar (ProcSym) THEN (* Procedure Variable ? *) @@ -5204,7 +5216,9 @@ BEGIN ParamConstant := FALSE ELSE Proc := ProcSym ; - ParamConstant := IsProcedureBuiltin (Proc) + ParamConstant := IsProcedureBuiltin (Proc) ; + AllocateProc := GetSymName (Proc) = MakeKey('ALLOCATE') ; + DeallocateProc := GetSymName (Proc) = MakeKey('DEALLOCATE') END ; IF IsFunc THEN @@ -5229,6 +5243,10 @@ BEGIN ForcedFunc := TRUE END END ; + IF AllocateProc OR DeallocateProc + THEN + Param1 := OperandT (NoOfParameters+1) (* Remember this before manipulating. *) + END ; ManipulateParameters (IsForC) ; CheckParameterOrdinals ; PopT(NoOfParameters) ; @@ -5244,7 +5262,21 @@ BEGIN pi := 1 ; (* stack index referencing stacked parameter, i *) WHILE i>0 DO paramtok := OperandTtok (pi) ; - GenQuadO (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE) ; + IF (AllocateProc OR DeallocateProc) AND (i = 1) AND (Param1 # NulSym) + THEN + ParamType := GetItemPointedTo (Param1) ; + IF ParamType = NulSym + THEN + GenQuadO (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE) + ELSE + trash := MakeTemporary (paramtok, RightValue) ; + PutVar (trash, ParamType) ; + PutVarHeap (trash, TRUE) ; + GenQuadOTrash (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE, trash) + END + ELSE + GenQuadO (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE) + END ; IF NOT IsConst (OperandT (pi)) THEN ParamConstant := FALSE @@ -6787,7 +6819,7 @@ BEGIN THEN RETURN GetItemPointedTo (GetSType (Sym)) ELSE - InternalError ('expecting a pointer or variable symbol') + RETURN NulSym END END GetItemPointedTo ; @@ -13079,6 +13111,19 @@ END MakeOp ; PROCEDURE GenQuadO (TokPos: CARDINAL; Operation: QuadOperator; Op1, Op2, Op3: CARDINAL; overflow: BOOLEAN) ; +BEGIN + GenQuadOTrash (TokPos, Operation, Op1, Op2, Op3, overflow, NulSym) +END GenQuadO ; + + +(* + GenQuadOTrash - generate a quadruple with Operation, Op1, Op2, Op3, overflow. +*) + +PROCEDURE GenQuadOTrash (TokPos: CARDINAL; + Operation: QuadOperator; + Op1, Op2, Op3: CARDINAL; + overflow: BOOLEAN; trash: CARDINAL) ; VAR f: QuadFrame ; BEGIN @@ -13093,6 +13138,7 @@ BEGIN PutQuadO (NextQuad, Operation, Op1, Op2, Op3, overflow) ; f := GetQF (NextQuad) ; WITH f^ DO + Trash := trash ; Next := 0 ; LineNo := GetLineNo () ; IF TokPos = UnknownTokenNo @@ -13109,7 +13155,21 @@ BEGIN (* DisplayQuad(NextQuad) ; *) NewQuad (NextQuad) END -END GenQuadO ; +END GenQuadOTrash ; + + +(* + GetQuadTrash - return the symbol associated with the trashed operand. +*) + +PROCEDURE GetQuadTrash (quad: CARDINAL) : CARDINAL ; +VAR + f: QuadFrame ; +BEGIN + f := GetQF (quad) ; + LastQuadNo := quad ; + RETURN f^.Trash +END GetQuadTrash ; (* @@ -13194,7 +13254,7 @@ PROCEDURE DisplayQuadRange (scope: CARDINAL; start, end: CARDINAL) ; VAR f: QuadFrame ; BEGIN - printf0 ('Quadruples for scope: ') ; WriteOperand (scope) ; printf0 ('\n') ; + printf1 ('Quadruples for scope: %d\n', scope) ; WHILE (start <= end) AND (start # 0) DO DisplayQuad (start) ; f := GetQF (start) ; diff --git a/gcc/m2/gm2-compiler/M2SymInit.mod b/gcc/m2/gm2-compiler/M2SymInit.mod index a5457ec..f617c40 100644 --- a/gcc/m2/gm2-compiler/M2SymInit.mod +++ b/gcc/m2/gm2-compiler/M2SymInit.mod @@ -25,7 +25,7 @@ FROM Storage IMPORT ALLOCATE, DEALLOCATE ; FROM M2Debug IMPORT Assert ; FROM M2Printf IMPORT printf0, printf1, printf2, printf3, printf4 ; FROM libc IMPORT printf ; -FROM NameKey IMPORT Name, NulName, KeyToCharStar ; +FROM NameKey IMPORT Name, NulName, KeyToCharStar, MakeKey ; FROM M2Options IMPORT UninitVariableChecking, UninitVariableConditionalChecking, CompilerDebugging ; @@ -41,6 +41,7 @@ FROM M2BasicBlock IMPORT BasicBlock, ForeachBasicBlockDo ; IMPORT Indexing ; +FROM Indexing IMPORT Index ; FROM Lists IMPORT List, InitList, GetItemFromList, PutItemIntoList, IsItemInList, IncludeItemIntoList, NoOfItemsInList, @@ -52,15 +53,19 @@ FROM SymbolTable IMPORT NulSym, ModeOfAddr, IsVar, IsRecord, GetSType, VarCheckReadInit, VarInitState, PutVarInitialized, PutVarFieldInitialized, GetVarFieldInitialized, IsConst, IsConstString, NoOfParam, IsVarParam, - ForeachLocalSymDo, IsTemporary, ModeOfAddr, + ForeachLocalSymDo, ForeachParamSymDo, + IsTemporary, ModeOfAddr, IsReallyPointer, IsUnbounded, IsVarient, IsFieldVarient, GetVarient, - IsVarArrayRef ; + IsVarArrayRef, GetSymName, + IsType, IsPointer, + GetParameterShadowVar, IsParameter, GetLType ; FROM M2Quads IMPORT QuadOperator, GetQuadOtok, GetQuad, GetNextQuad, IsNewLocalVar, IsReturn, IsKillLocalVar, IsConditional, IsUnConditional, IsBackReference, IsCall, IsGoto, - GetM2OperatorDesc, Opposite, DisplayQuadRange ; + GetM2OperatorDesc, Opposite, DisplayQuadRange, + GetQuadTrash ; FROM M2Printf IMPORT printf0, printf1, printf2 ; FROM M2GCCDeclare IMPORT PrintSym ; @@ -104,21 +109,24 @@ TYPE (* Does it end with a conditional? *) endCond, (* Does it form part of a loop? *) - topOfLoop: BOOLEAN ; + topOfLoop : BOOLEAN ; + trashQuad, indexBB, nextQuad, condQuad, nextBB, - condBB : CARDINAL ; - next : bbEntry ; + condBB : CARDINAL ; + next : bbEntry ; END ; VAR - aliasArray: Indexing.Index ; - freeList : symAlias ; - bbArray : Indexing.Index ; - bbFreeList: bbEntry ; - errorList : List ; (* Ensure that we only generate one set of warnings per token. *) + IndirectArray, + LArray : Indexing.Index ; + freeList : symAlias ; + bbArray : Indexing.Index ; + bbFreeList : bbEntry ; + ignoreList, + errorList : List ; (* Ensure that we only generate one set of warnings per token. *) (* @@ -418,10 +426,10 @@ END IsLocalVar ; RecordFieldContainsVarient - *) -PROCEDURE RecordFieldContainsVarient (sym: CARDINAL) : BOOLEAN ; +PROCEDURE RecordFieldContainsVarient (sym: CARDINAL; visited: List) : BOOLEAN ; BEGIN Assert (IsRecordField (sym)) ; - IF ContainsVariant (GetSType (sym)) + IF doContainsVariant (GetSType (sym), visited) THEN RETURN TRUE END ; @@ -430,37 +438,125 @@ END RecordFieldContainsVarient ; (* - ContainsVariant - returns TRUE if type sym contains a variant record. + RecordContainsVarient - *) -PROCEDURE ContainsVariant (sym: CARDINAL) : BOOLEAN ; +PROCEDURE RecordContainsVarient (sym: CARDINAL; visited: List) : BOOLEAN ; VAR i, fieldsym, fieldtype: CARDINAL ; BEGIN - IF IsRecord (sym) - THEN - i := 1 ; - REPEAT - fieldsym := GetNth (sym, i) ; - IF fieldsym # NulSym + Assert (IsRecord (sym)) ; + i := 1 ; + REPEAT + fieldsym := GetNth (sym, i) ; + IF fieldsym # NulSym + THEN + IF IsRecordField (fieldsym) THEN - IF IsRecordField (fieldsym) - THEN - IF RecordFieldContainsVarient (fieldsym) - THEN - RETURN TRUE - END - ELSIF IsVarient (fieldsym) + IF RecordFieldContainsVarient (fieldsym, visited) THEN RETURN TRUE - END ; - INC (i) - END - UNTIL fieldsym = NulSym + END + ELSIF IsVarient (fieldsym) + THEN + RETURN TRUE + END ; + INC (i) + END + UNTIL fieldsym = NulSym ; + RETURN FALSE +END RecordContainsVarient ; + + +(* + VarContainsVarient - +*) + +PROCEDURE VarContainsVarient (sym: CARDINAL; visited: List) : BOOLEAN ; +BEGIN + Assert (IsVar (sym)) ; + RETURN doContainsVariant (GetSType (sym), visited) +END VarContainsVarient ; + + +(* + TypeContainsVarient - +*) + +PROCEDURE TypeContainsVarient (sym: CARDINAL; visited: List) : BOOLEAN ; +BEGIN + Assert (IsType (sym)) ; + RETURN doContainsVariant (GetSType (sym), visited) +END TypeContainsVarient ; + + +(* + ArrayContainsVarient - +*) + +PROCEDURE ArrayContainsVarient (sym: CARDINAL; visited: List) : BOOLEAN ; +BEGIN + Assert (IsArray (sym)) ; + RETURN doContainsVariant (GetSType (sym), visited) +END ArrayContainsVarient ; + + +(* + PointerContainsVarient - +*) + +PROCEDURE PointerContainsVarient (sym: CARDINAL; visited: List) : BOOLEAN ; +BEGIN + Assert (IsPointer (sym)) ; + RETURN doContainsVariant (GetSType (sym), visited) +END PointerContainsVarient ; + + +(* + doContainsVariant - +*) + +PROCEDURE doContainsVariant (sym: CARDINAL; visited: List) : BOOLEAN ; +BEGIN + IF (sym # NulSym) AND (NOT IsItemInList (visited, sym)) + THEN + IncludeItemIntoList (visited, sym) ; + IF IsVar (sym) + THEN + RETURN VarContainsVarient (sym, visited) + ELSIF IsRecord (sym) + THEN + RETURN RecordContainsVarient (sym, visited) + ELSIF IsPointer (sym) + THEN + RETURN PointerContainsVarient (sym, visited) + ELSIF IsArray (sym) + THEN + RETURN ArrayContainsVarient (sym, visited) + ELSIF IsType (sym) + THEN + RETURN TypeContainsVarient (sym, visited) + END END ; RETURN FALSE +END doContainsVariant ; + + +(* + ContainsVariant - returns TRUE if type sym contains a variant record. +*) + +PROCEDURE ContainsVariant (sym: CARDINAL) : BOOLEAN ; +VAR + visited: List ; + result : BOOLEAN ; +BEGIN + InitList (visited) ; + result := doContainsVariant (sym, visited) ; + KillList (visited) ; + RETURN result END ContainsVariant ; @@ -656,9 +752,12 @@ END CheckDeferredRecordAccess ; PROCEDURE SetVarUninitialized (sym: CARDINAL) ; BEGIN - IF IsVar (sym) AND (NOT IsUnbounded (GetSType (sym))) AND (NOT IsVarAParam (sym)) + IF IsVar (sym) THEN - VarInitState (sym) + IF NOT IsUnbounded (GetSType (sym)) + THEN + VarInitState (sym) + END END END SetVarUninitialized ; @@ -667,19 +766,21 @@ END SetVarUninitialized ; ComponentFindVar - *) -PROCEDURE ComponentFindVar (sym: CARDINAL) : CARDINAL ; +PROCEDURE ComponentFindVar (sym: CARDINAL; VAR lvalue: BOOLEAN) : CARDINAL ; VAR nsym, i : CARDINAL ; BEGIN i := 1 ; REPEAT - nsym := getAlias (GetNth (sym, i)) ; + nsym := GetNth (sym, i) ; + lvalue := GetMode (nsym) = LeftValue ; + nsym := getLAlias (nsym) ; IF (nsym # NulSym) AND IsVar (nsym) THEN IF (nsym # sym) AND IsComponent (nsym) THEN - RETURN ComponentFindVar (nsym) + RETURN ComponentFindVar (nsym, lvalue) ELSE RETURN nsym END @@ -742,17 +843,34 @@ END ComponentBuildFieldList ; (* + deRefComponent - +*) + +PROCEDURE deRefComponent (component: CARDINAL; lvalue: BOOLEAN) : CARDINAL ; +BEGIN + IF lvalue + THEN + RETURN getContent (component) + ELSE + RETURN component + END +END deRefComponent ; + + +(* SetVarComponentInitialized - *) PROCEDURE SetVarComponentInitialized (sym: CARDINAL) ; VAR + lvalue: BOOLEAN ; i, n, fsym, - vsym: CARDINAL ; - lst : List ; + vsym : CARDINAL ; + lst : List ; BEGIN - vsym := ComponentFindVar (sym) ; + vsym := ComponentFindVar (sym, lvalue) ; + vsym := deRefComponent (vsym, lvalue) ; IF vsym # NulSym THEN IF Debugging @@ -795,26 +913,34 @@ END SetVarComponentInitialized ; PROCEDURE GetVarComponentInitialized (sym: CARDINAL) : BOOLEAN ; VAR - init: BOOLEAN ; - vsym: CARDINAL ; - lst : List ; -BEGIN - init := FALSE ; - vsym := ComponentFindVar (sym) ; - IF vsym # NulSym + lvalue, + init : BOOLEAN ; + component, + vsym : CARDINAL ; + lst : List ; +BEGIN + component := ComponentFindVar (sym, lvalue) ; + IF IsItemInList (ignoreList, component) OR IsExempt (component) THEN - IF IsExempt (vsym) + RETURN TRUE + ELSE + init := FALSE ; + vsym := deRefComponent (component, lvalue) ; + IF vsym # NulSym THEN - init := TRUE - ELSE - (* Create list representing how the field is accessed. *) - lst := ComponentCreateFieldList (sym) ; - (* Now obtain the mark indicating whether this field was initialized. *) - init := GetVarFieldInitialized (vsym, RightValue, lst) ; - KillList (lst) - END - END ; - RETURN init + IF IsExempt (vsym) + THEN + init := TRUE + ELSE + (* Create list representing how the field is accessed. *) + lst := ComponentCreateFieldList (sym) ; + (* Now obtain the mark indicating whether this field was initialized. *) + init := GetVarFieldInitialized (vsym, RightValue, lst) ; + KillList (lst) + END + END ; + RETURN init + END END GetVarComponentInitialized ; @@ -841,6 +967,7 @@ PROCEDURE SetVarInitialized (sym: CARDINAL; canDereference: BOOLEAN) ; BEGIN IF IsVar (sym) THEN + RemoveItemFromList (ignoreList, sym) ; IF IsComponent (sym) THEN Trace ("SetVarInitialized sym %d is a component and calling SetVarComponentInitialized", sym); @@ -913,10 +1040,12 @@ END GetVarInitialized ; PROCEDURE IsExempt (sym: CARDINAL) : BOOLEAN ; BEGIN RETURN (sym # NulSym) AND IsVar (sym) AND - (IsGlobalVar (sym) OR IsVarAParam (sym) OR - ContainsVariant (GetSType (sym)) OR + (IsGlobalVar (sym) OR + (IsVarAParam (sym) AND (GetMode (sym) = LeftValue)) OR + ContainsVariant (sym) OR IsArray (GetSType (sym)) OR IsSet (GetSType (sym)) OR - IsUnbounded (GetSType (sym)) OR IsVarArrayRef (sym)) + IsUnbounded (GetSType (sym)) OR IsVarArrayRef (sym) OR + IsItemInList (ignoreList, sym)) END IsExempt ; @@ -964,8 +1093,8 @@ BEGIN CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, bblst, i) ; CheckDeferredRecordAccess (procSym, lhstok, lhs, FALSE, warning, bblst, i) ; (* Now see if we know what lhs is pointing to and set fields if necessary. *) - vsym := getAlias (lhs) ; - IF (vsym # lhs) AND (GetSType (vsym) = type) + vsym := getContent (getLAlias (lhs)) ; + IF (vsym # NulSym) AND (vsym # lhs) AND (GetSType (vsym) = type) THEN IF IsRecord (type) THEN @@ -990,10 +1119,20 @@ END CheckXIndr ; PROCEDURE CheckIndrX (procSym, lhstok, lhs, type, rhstok, rhs: CARDINAL; warning: BOOLEAN; lst: List; i: CARDINAL) ; +VAR + content: CARDINAL ; BEGIN CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, lst, i) ; - CheckDeferredRecordAccess (procSym, rhstok, rhs, TRUE, warning, lst, i) ; - SetVarInitialized (lhs, IsVarAParam (rhs)) + content := getContent (getLAlias (rhs)) ; + IF content = NulSym + THEN + IncludeItemIntoList (ignoreList, lhs) + ELSE + CheckDeferredRecordAccess (procSym, rhstok, content, TRUE, warning, lst, i) ; + (* SetVarInitialized (lhs, IsVarAParam (rhs)) -- was -- *) + (* SetVarInitialized (lhs, FALSE) -- was -- *) + SetVarInitialized (lhs, VarCheckReadInit (content, RightValue)) + END END CheckIndrX ; @@ -1014,22 +1153,27 @@ END CheckRecordField ; PROCEDURE CheckBecomes (procSym, destok, des, exprtok, expr: CARDINAL; warning: BOOLEAN; bblst: List; i: CARDINAL) ; VAR - lst : List ; - vsym: CARDINAL ; + lvalue: BOOLEAN ; + lst : List ; + vsym : CARDINAL ; BEGIN CheckDeferredRecordAccess (procSym, exprtok, expr, FALSE, warning, bblst, i) ; - SetupAlias (des, expr) ; + SetupLAlias (des, expr) ; SetVarInitialized (des, FALSE) ; (* Now see if we know what lhs is pointing to and set fields if necessary. *) IF IsComponent (des) THEN - vsym := ComponentFindVar (des) ; - (* Set only the field assigned in vsym as initialized. *) - lst := ComponentCreateFieldList (des) ; - IF PutVarFieldInitialized (vsym, RightValue, lst) + vsym := ComponentFindVar (des, lvalue) ; + vsym := deRefComponent (vsym, lvalue) ; + IF vsym # NulSym THEN - END ; - KillList (lst) + (* Set only the field assigned in vsym as initialized. *) + lst := ComponentCreateFieldList (des) ; + IF PutVarFieldInitialized (vsym, RightValue, lst) + THEN + END ; + KillList (lst) + END END END CheckBecomes ; @@ -1050,10 +1194,10 @@ END CheckComparison ; CheckAddr - *) -PROCEDURE CheckAddr (procSym, op1tok, op1, op3tok, op3: CARDINAL) ; +PROCEDURE CheckAddr (procSym, ptrtok, ptr, contenttok, content: CARDINAL) ; BEGIN - SetVarInitialized (op1, GetVarInitialized (op3)) ; - SetupAlias (op1, op3) + SetVarInitialized (ptr, GetVarInitialized (content)) ; + SetupIndr (ptr, content) END CheckAddr ; @@ -1367,6 +1511,64 @@ END DumpBBSequence ; (* + trashParam - +*) + +PROCEDURE trashParam (trashQuad: CARDINAL) ; +VAR + op : QuadOperator ; + op1, op2, op3: CARDINAL ; + heapSym, ptr : CARDINAL ; +BEGIN + IF trashQuad # 0 + THEN + GetQuad (trashQuad, op, op1, op2, op3) ; + heapSym := GetQuadTrash (trashQuad) ; + IF Debugging + THEN + printf1 ("heapSym = %d\n", heapSym) + END ; + IF heapSym # NulSym + THEN + SetVarInitialized (op3, FALSE) ; + ptr := getContent (getLAlias (op3)) ; + IF ptr # NulSym + THEN + SetupIndr (ptr, heapSym) ; + SetVarInitialized (ptr, FALSE) + END +(* + vsym := getLAlias (op3) ; + VarInitState (vsym) ; + VarInitState (heapSym) ; + PutVarInitialized (vsym, GetMode (vsym)) ; + PutVarInitialized (heapSym, LeftValue) ; + SetupLAlias (vsym, heapSym) +*) + END + END ; + DumpAliases +END trashParam ; + + +(* + SetVarLRInitialized - +*) + +PROCEDURE SetVarLRInitialized (param: CARDINAL) ; +VAR + sym: CARDINAL ; +BEGIN + Assert (IsParameter (param)) ; + sym := GetParameterShadowVar (param) ; + IF sym # NulSym + THEN + IncludeItemIntoList (ignoreList, sym) + END +END SetVarLRInitialized ; + + +(* TestBBSequence - *) @@ -1381,20 +1583,26 @@ BEGIN THEN DumpBBSequence (procSym, lst) END ; - ForeachLocalSymDo (procSym, SetVarUninitialized) ; initBlock ; + ForeachLocalSymDo (procSym, SetVarUninitialized) ; + ForeachParamSymDo (procSym, SetVarLRInitialized) ; n := NoOfItemsInList (lst) ; i := 1 ; warning := TRUE ; WHILE i <= n DO bbi := GetItemFromList (lst, i) ; bbPtr := Indexing.GetIndice (bbArray, bbi) ; - CheckReadBeforeInitFirstBasicBlock (procSym, bbPtr^.start, bbPtr^.end, warning, lst, i) ; + CheckReadBeforeInitFirstBasicBlock (procSym, + bbPtr^.start, bbPtr^.end, + warning, lst, i) ; IF bbPtr^.endCond THEN (* Check to see if we are moving into an conditional block in which case we will issue a note. *) warning := FALSE + ELSIF bbPtr^.endCall AND (bbPtr^.trashQuad # 0) + THEN + trashParam (bbPtr^.trashQuad) END ; INC (i) END ; @@ -1422,7 +1630,7 @@ BEGIN ELSE duplst := DuplicateList (lst) ; IncludeItemIntoList (duplst, i) ; - IF iPtr^.endCall + IF iPtr^.endCall AND (iPtr^.trashQuad = 0) THEN TestBBSequence (procSym, duplst) ELSIF iPtr^.endGoto @@ -1571,6 +1779,45 @@ END NewEntry ; (* + IsAllocate - return TRUE is sym is ALLOCATE. +*) + +PROCEDURE IsAllocate (sym: CARDINAL) : BOOLEAN ; +BEGIN + RETURN IsProcedure (sym) AND (GetSymName (sym) = MakeKey('ALLOCATE')) +END IsAllocate ; + + +(* + DetectTrash - +*) + +PROCEDURE DetectTrash (bbPtr: bbEntry) ; +VAR + i : CARDINAL ; + op : QuadOperator ; + op1, op2, op3: CARDINAL ; +BEGIN + IF bbPtr^.endCall + THEN + i := bbPtr^.start ; + LOOP + GetQuad (i, op, op1, op2, op3) ; + IF (op = ParamOp) AND (op1 = 1) AND IsAllocate (op2) + THEN + bbPtr^.trashQuad := i + END ; + IF i = bbPtr^.end + THEN + RETURN + END ; + i := GetNextQuad (i) + END + END +END DetectTrash ; + + +(* AppendEntry - *) @@ -1589,6 +1836,7 @@ BEGIN endGoto := IsGoto (End) ; endCond := IsConditional (End) ; topOfLoop := IsBackReference (Start) ; + trashQuad := 0 ; indexBB := high + 1 ; nextQuad := 0 ; condQuad := 0 ; @@ -1596,6 +1844,7 @@ BEGIN condBB := 0 ; next := NIL END ; + DetectTrash (bbPtr) ; Indexing.PutIndice (bbArray, high + 1, bbPtr) END AppendEntry ; @@ -1604,31 +1853,44 @@ END AppendEntry ; DumpAlias - *) -PROCEDURE DumpAlias (aliasIndex: CARDINAL) ; +PROCEDURE DumpAlias (array: Index; aliasIndex: CARDINAL) ; VAR sa: symAlias ; BEGIN - sa := Indexing.GetIndice (aliasArray, aliasIndex) ; - printf2 ("keySym = %d: alias = %d\n", sa^.keySym, sa^.alias) ; + sa := Indexing.GetIndice (array, aliasIndex) ; + printf2 ("keySym = %d: alias = %d\n", sa^.keySym, sa^.alias) END DumpAlias ; (* - DumpAliases - + doDumpAliases - *) -PROCEDURE DumpAliases ; +PROCEDURE doDumpAliases (array: Index) ; VAR i, n: CARDINAL ; BEGIN + i := 1 ; + n := Indexing.HighIndice (array) ; + WHILE i <= n DO + DumpAlias (array, i) ; + INC (i) + END +END doDumpAliases ; + + +(* + DumpAliases - +*) + +PROCEDURE DumpAliases ; +BEGIN IF Debugging THEN - i := 1 ; - n := Indexing.HighIndice (aliasArray) ; - WHILE i <= n DO - DumpAlias (i) ; - INC (i) - END + printf0 ("LArray\n") ; + doDumpAliases (LArray) ; + printf0 ("IndirectArray\n") ; + doDumpAliases (IndirectArray) END END DumpAliases ; @@ -1687,7 +1949,9 @@ END killAlias ; PROCEDURE initBlock ; BEGIN - aliasArray := Indexing.InitIndex (1) ; + LArray := Indexing.InitIndex (1) ; + IndirectArray := Indexing.InitIndex (1) ; + InitList (ignoreList) END initBlock ; @@ -1696,32 +1960,40 @@ END initBlock ; *) PROCEDURE killBlock ; +BEGIN + doKillBlock (LArray) ; + doKillBlock (IndirectArray) ; + KillList (ignoreList) +END killBlock ; + + +PROCEDURE doKillBlock (VAR array: Index) ; VAR i, n: CARDINAL ; BEGIN i := 1 ; - n := Indexing.HighIndice (aliasArray) ; + n := Indexing.HighIndice (array) ; WHILE i <= n DO - killAlias (Indexing.GetIndice (aliasArray, i)) ; + killAlias (Indexing.GetIndice (array, i)) ; INC (i) END ; - aliasArray := Indexing.KillIndex (aliasArray) -END killBlock ; + array := Indexing.KillIndex (array) +END doKillBlock ; (* addAlias - *) -PROCEDURE addAlias (sym: CARDINAL; aliased: CARDINAL) ; +PROCEDURE addAlias (array: Index; sym: CARDINAL; aliased: CARDINAL) ; VAR i, n: CARDINAL ; sa : symAlias ; BEGIN i := 1 ; - n := Indexing.HighIndice (aliasArray) ; + n := Indexing.HighIndice (array) ; WHILE i <= n DO - sa := Indexing.GetIndice (aliasArray, i) ; + sa := Indexing.GetIndice (array, i) ; IF sa^.keySym = sym THEN sa^.alias := aliased ; @@ -1730,7 +2002,7 @@ BEGIN INC (i) END ; sa := initAlias (sym) ; - Indexing.IncludeIndiceIntoIndex (aliasArray, sa) ; + Indexing.IncludeIndiceIntoIndex (array, sa) ; sa^.alias := aliased END addAlias ; @@ -1739,15 +2011,15 @@ END addAlias ; lookupAlias - *) -PROCEDURE lookupAlias (sym: CARDINAL) : symAlias ; +PROCEDURE lookupAlias (array: Index; sym: CARDINAL) : symAlias ; VAR i, n: CARDINAL ; sa : symAlias ; BEGIN i := 1 ; - n := Indexing.HighIndice (aliasArray) ; + n := Indexing.HighIndice (array) ; WHILE i <= n DO - sa := Indexing.GetIndice (aliasArray, i) ; + sa := Indexing.GetIndice (array, i) ; IF sa^.keySym = sym THEN RETURN sa @@ -1762,11 +2034,11 @@ END lookupAlias ; doGetAlias - *) -PROCEDURE doGetAlias (sym: CARDINAL) : CARDINAL ; +PROCEDURE doGetAlias (array: Index; sym: CARDINAL) : CARDINAL ; VAR sa: symAlias ; BEGIN - sa := lookupAlias (sym) ; + sa := lookupAlias (array, sym) ; IF (sa # NIL) AND (sa^.alias # NulSym) THEN RETURN sa^.alias @@ -1776,10 +2048,10 @@ END doGetAlias ; (* - getAlias - attempts to looks up an alias which is not a temporary variable. + getLAlias - attempts to looks up an alias which is not a temporary variable. *) -PROCEDURE getAlias (sym: CARDINAL) : CARDINAL ; +PROCEDURE getLAlias (sym: CARDINAL) : CARDINAL ; VAR type, nsym: CARDINAL ; @@ -1791,28 +2063,48 @@ BEGIN IF (IsTemporary (sym) AND (GetMode (sym) = LeftValue)) OR ((type # NulSym) AND IsReallyPointer (type)) THEN - nsym := doGetAlias (sym) + nsym := doGetAlias (LArray, sym) ELSE RETURN sym END UNTIL nsym = NulSym ; RETURN sym -END getAlias ; +END getLAlias ; (* - SetupAlias - + SetupLAlias - *) -PROCEDURE SetupAlias (des, exp: CARDINAL) ; +PROCEDURE SetupLAlias (des, exp: CARDINAL) ; BEGIN IF IsVar (exp) AND ((GetMode (des) = LeftValue) OR IsReallyPointer (GetSType (des))) THEN - addAlias (des, exp) ; + addAlias (LArray, des, exp) ; DumpAliases END -END SetupAlias ; +END SetupLAlias ; + + +(* + SetupIndr - +*) + +PROCEDURE SetupIndr (ptr, content: CARDINAL) ; +BEGIN + addAlias (IndirectArray, ptr, content) ; +END SetupIndr ; + + +(* + getContent - +*) + +PROCEDURE getContent (ptr: CARDINAL) : CARDINAL ; +BEGIN + RETURN doGetAlias (IndirectArray, ptr) +END getContent ; (* diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def index 8c4feed..2cfa0d4 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.def +++ b/gcc/m2/gm2-compiler/SymbolTable.def @@ -92,6 +92,8 @@ EXPORT QUALIFIED NulSym, ForeachModuleDo, ForeachInnerModuleDo, ForeachLocalSymDo, + ForeachParamSymDo, + ForeachFieldEnumerationDo, GetModule, GetCurrentModule, @@ -204,6 +206,7 @@ EXPORT QUALIFIED NulSym, PutVariableSSA, IsVariableSSA, PutPublic, IsPublic, PutCtor, IsCtor, PutExtern, IsExtern, PutMonoName, IsMonoName, + PutVarHeap, IsVarHeap, IsDefImp, IsModule, @@ -695,6 +698,20 @@ PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL; external: BOOLEAN) (* + PutVarHeap - assigns ArrayRef field with value. +*) + +PROCEDURE PutVarHeap (sym: CARDINAL; value: BOOLEAN) ; + + +(* + IsVarHeap - returns ArrayRef field value. +*) + +PROCEDURE IsVarHeap (sym: CARDINAL) : BOOLEAN ; + + +(* MakeVar - creates a variable sym with VarName. It returns the symbol index. *) @@ -2399,6 +2416,14 @@ PROCEDURE ForeachLocalSymDo (Sym: CARDINAL; P: PerformOperation) ; (* + ForeachParamSymDo - foreach parameter symbol in procedure, Sym, + perform the procedure, P. +*) + +PROCEDURE ForeachParamSymDo (Sym: CARDINAL; P: PerformOperation) ; + + +(* ForeachFieldEnumerationDo - for each field in enumeration, Sym, do procedure, P. *) diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod index 73528b5..1768966 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.mod +++ b/gcc/m2/gm2-compiler/SymbolTable.mod @@ -527,6 +527,7 @@ TYPE IsConst : BOOLEAN ; (* Is variable read/only? *) ArrayRef : BOOLEAN ; (* Is variable used to point *) (* to an array? *) + Heap : BOOLEAN ; (* Is var on the heap? *) InitState : LRInitDesc ; (* Initialization state. *) At : Where ; (* Where was sym declared/used *) ReadUsageList, (* list of var read quads *) @@ -4263,6 +4264,7 @@ BEGIN IsSSA := FALSE ; IsConst := FALSE ; ArrayRef := FALSE ; + Heap := FALSE ; InitWhereDeclaredTok(tok, At) ; InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used. *) InitList(ReadUsageList[RightValue]) ; @@ -6950,6 +6952,48 @@ END IsVarArrayRef ; (* + PutVarHeap - assigns ArrayRef field with value. +*) + +PROCEDURE PutVarHeap (sym: CARDINAL; value: BOOLEAN) ; +VAR + pSym: PtrToSymbol ; +BEGIN + pSym := GetPsym(sym) ; + WITH pSym^ DO + CASE SymbolType OF + + VarSym: Var.Heap := value + + ELSE + InternalError ('expecting VarSym') + END + END +END PutVarHeap ; + + +(* + IsVarHeap - returns ArrayRef field value. +*) + +PROCEDURE IsVarHeap (sym: CARDINAL) : BOOLEAN ; +VAR + pSym: PtrToSymbol ; +BEGIN + pSym := GetPsym(sym) ; + WITH pSym^ DO + CASE SymbolType OF + + VarSym: RETURN (Var.Heap) + + ELSE + InternalError ('expecting VarSym') + END + END +END IsVarHeap ; + + +(* PutFieldRecord - places a field, FieldName and FieldType into a record, Sym. VarSym is a optional varient symbol which can be returned by a call to GetVarient(fieldsymbol). The created field @@ -9044,6 +9088,31 @@ END ForeachLocalSymDo ; (* + ForeachParamSymDo - foreach parameter symbol in procedure, Sym, + perform the procedure, P. Each symbol + looked up will be VarParam or Param + (not the shadow variable). +*) + +PROCEDURE ForeachParamSymDo (Sym: CARDINAL; P: PerformOperation) ; +VAR + param: CARDINAL ; + p, i : CARDINAL ; +BEGIN + IF IsProcedure (Sym) + THEN + p := NoOfParam (Sym) ; + i := p ; + WHILE i>0 DO + param := GetNthParam (Sym, i) ; + P (param) ; + DEC(i) + END + END +END ForeachParamSymDo ; + + +(* CheckForUnknownInModule - checks for any unknown symbols in the current module. If any unknown symbols are found then @@ -10116,31 +10185,31 @@ VAR pSym : PtrToSymbol ; VariableSym: CARDINAL ; BEGIN - VariableSym := MakeVar(tok, ParamName) ; - pSym := GetPsym(VariableSym) ; + VariableSym := MakeVar (tok, ParamName) ; + pSym := GetPsym (VariableSym) ; WITH pSym^ DO CASE SymbolType OF ErrorSym: RETURN( NulSym ) | - VarSym : Var.IsParam := TRUE (* Variable is really a parameter *) + VarSym : Var.IsParam := TRUE (* Variable is really a parameter. *) ELSE InternalError ('expecting a Var symbol') END END ; - (* Note that the parameter is now treated as a local variable *) - PutVar(VariableSym, GetType(GetNthParam(ProcSym, no))) ; - PutDeclared(tok, VariableSym) ; + (* Note that the parameter is now treated as a local variable. *) + PutVar (VariableSym, GetType(GetNthParam(ProcSym, no))) ; + PutDeclared (tok, VariableSym) ; (* Normal VAR parameters have LeftValue, however Unbounded VAR parameters have RightValue. Non VAR parameters always have RightValue. *) - IF IsVarParam(ProcSym, no) AND (NOT IsUnboundedParam(ProcSym, no)) + IF IsVarParam (ProcSym, no) AND (NOT IsUnboundedParam (ProcSym, no)) THEN - PutMode(VariableSym, LeftValue) + PutMode (VariableSym, LeftValue) ELSE - PutMode(VariableSym, RightValue) + PutMode (VariableSym, RightValue) END ; RETURN( VariableSym ) END MakeVariableForParam ; diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/assignparam.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/assignparam.mod new file mode 100644 index 0000000..9344ad0 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/assignparam.mod @@ -0,0 +1,31 @@ +MODULE assignparam ; + +FROM SYSTEM IMPORT ADR ; + +TYPE + PtrToVec = POINTER TO Vec ; + Vec = RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test (p: PtrToVec) ; +VAR + s: PtrToVec ; + v: Vec ; +BEGIN + s := ADR (v) ; + s^ := p^ ; + IF s^.x = 1 + THEN + END +END test ; + + +VAR + q: PtrToVec ; + w: Vec ; +BEGIN + q := ADR (w) ; + test (q) +END assignparam. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/tiny.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/tiny.mod new file mode 100644 index 0000000..668e09c --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/pass/tiny.mod @@ -0,0 +1,13 @@ +MODULE tiny ; + + +PROCEDURE test ; +VAR + p: CARDINAL ; +BEGIN + p := 1 +END test ; + +BEGIN + test +END tiny. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/switches-uninit-variable-checking-procedures-fail.exp b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/switches-uninit-variable-checking-procedures-fail.exp new file mode 100644 index 0000000..6d22f36 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/switches-uninit-variable-checking-procedures-fail.exp @@ -0,0 +1,37 @@ +# Expect driver script for GCC Regression Tests +# Copyright (C) 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file was written by Gaius Mulley (gaius.mulley@southwales.ac.uk) +# for GNU Modula-2. + +if $tracelevel then { + strace $tracelevel +} + +# load support procs +load_lib gm2-torture.exp + +gm2_init_pim "${srcdir}/gm2/switches/uninit-variable-checking/procedures/fail" -Wuninit-variable-checking=all + +foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $testcase] then { + continue + } + + gm2-torture-fail $testcase +} diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew.mod new file mode 100644 index 0000000..f0abe0a --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew.mod @@ -0,0 +1,31 @@ +MODULE testnew ; + +FROM Storage IMPORT ALLOCATE ; + +TYPE + ptr = POINTER TO RECORD + a, b: CARDINAL ; + END ; + +(* + test - +*) + +PROCEDURE test (p: ptr) ; +BEGIN + NEW (p) ; + WITH p^ DO + a := 1 ; + (* user forgets to assign b. *) + IF b = 2 + THEN + END + END +END test ; + + +VAR + n: ptr ; +BEGIN + test (n) +END testnew. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew2.mod new file mode 100644 index 0000000..4511302 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew2.mod @@ -0,0 +1,31 @@ +MODULE testnew2 ; + +FROM Storage IMPORT ALLOCATE ; + +TYPE + ptr = POINTER TO RECORD + a, b: CARDINAL ; + END ; + +(* + test - +*) + +PROCEDURE test ; +VAR + p: ptr ; +BEGIN + NEW (p) ; + WITH p^ DO + a := 1 ; + (* user forgets to assign b. *) + IF b = 2 + THEN + END + END +END test ; + + +BEGIN + test +END testnew2. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew3.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew3.mod new file mode 100644 index 0000000..bb8ceba --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew3.mod @@ -0,0 +1,34 @@ +MODULE testnew3 ; + +FROM Storage IMPORT ALLOCATE ; +FROM SYSTEM IMPORT ADR ; + +TYPE + ptr = POINTER TO rec ; + rec = RECORD + a, b: CARDINAL ; + END ; + +(* + test - +*) + +PROCEDURE test ; +VAR + p: ptr ; + r: rec ; +BEGIN + p := ADR (r) ; + WITH p^ DO + a := 1 ; + (* user forgets to assign b. *) + IF b = 2 + THEN + END + END +END test ; + + +BEGIN + test +END testnew3. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew4.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew4.mod new file mode 100644 index 0000000..5c65ba8 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew4.mod @@ -0,0 +1,34 @@ +MODULE testnew4 ; + +FROM Storage IMPORT ALLOCATE ; +FROM SYSTEM IMPORT ADR ; + +TYPE + ptr = POINTER TO rec ; + rec = RECORD + a, b: CARDINAL ; + END ; + +(* + test - +*) + +PROCEDURE test ; +VAR + p: ptr ; + r: rec ; +BEGIN + p := ADR (r) ; + WITH p^ DO + a := 1 ; + (* user forgets to assign b. *) + IF b = 2 + THEN + END + END +END test ; + + +BEGIN + test +END testnew4. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew5.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew5.mod new file mode 100644 index 0000000..7cad3c2 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew5.mod @@ -0,0 +1,31 @@ +MODULE testnew5 ; + +FROM Storage IMPORT ALLOCATE ; + +TYPE + ptr = POINTER TO RECORD + a, b: CARDINAL ; + END ; + +(* + test - +*) + +PROCEDURE test (p: ptr) ; +BEGIN + NEW (p) ; + WITH p^ DO + a := 1 ; + (* user forgets to assign b. *) + IF b = 2 + THEN + END + END +END test ; + + +VAR + n: ptr ; +BEGIN + test (n) +END testnew5. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew6.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew6.mod new file mode 100644 index 0000000..f77a8d8 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnew6.mod @@ -0,0 +1,27 @@ +MODULE testnew6 ; + +FROM Storage IMPORT ALLOCATE ; + +TYPE + PtrToVec = POINTER TO RECORD + x, y: INTEGER ; + END ; + +PROCEDURE test ; +VAR + p: PtrToVec ; +BEGIN + NEW (p) ; + WITH p^ DO + x := 1 ; + x := 2 (* Deliberate typo, user meant y. *) + END ; + IF p^.y = 2 + THEN + END +END test ; + + +BEGIN + test +END testnew6. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testptrptr.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testptrptr.mod new file mode 100644 index 0000000..7750364 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testptrptr.mod @@ -0,0 +1,32 @@ +MODULE testptrptr ; + +FROM SYSTEM IMPORT ADR ; + +TYPE + PtrToPtrToVec = POINTER TO PtrToVec ; + PtrToVec = POINTER TO Vec ; + Vec = RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test ; +VAR + vec: Vec ; + ptr: PtrToVec ; + ptrptr: PtrToPtrToVec ; +BEGIN + ptr := ADR (vec) ; + ptrptr := ADR (ptr) ; + WITH ptrptr^^ DO + x := 1 ; + IF y = 2 (* error here. *) + THEN + END + END +END test ; + + +BEGIN + test +END testptrptr. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/assignparam2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/assignparam2.mod new file mode 100644 index 0000000..4a51efa --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/assignparam2.mod @@ -0,0 +1,31 @@ +MODULE assignparam2 ; + +FROM SYSTEM IMPORT ADR ; +FROM Storage IMPORT ALLOCATE ; + +TYPE + PtrToVec = POINTER TO Vec ; + Vec = RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test (p: PtrToVec) ; +VAR + s: PtrToVec ; +BEGIN + NEW (s) ; + s^ := p^ ; + IF s^.x = 1 + THEN + END +END test ; + + +VAR + q: PtrToVec ; + w: Vec ; +BEGIN + q := ADR (w) ; + test (q) +END assignparam2. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/switches-uninit-variable-checking-procedures-pass.exp b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/switches-uninit-variable-checking-procedures-pass.exp new file mode 100644 index 0000000..ad1e971 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/switches-uninit-variable-checking-procedures-pass.exp @@ -0,0 +1,37 @@ +# Expect driver script for GCC Regression Tests +# Copyright (C) 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file was written by Gaius Mulley (gaius.mulley@southwales.ac.uk) +# for GNU Modula-2. + +if $tracelevel then { + strace $tracelevel +} + +# load support procs +load_lib gm2-torture.exp + +gm2_init_pim "${srcdir}/gm2/switches/pedantic-params/procedures/pass" -Wuninit-variable-checking + +foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $testcase] then { + continue + } + + gm2-torture $testcase +} diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew5.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew5.mod new file mode 100644 index 0000000..1cdca60 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew5.mod @@ -0,0 +1,27 @@ +MODULE testnew5 ; + +FROM Storage IMPORT ALLOCATE ; + +TYPE + ptr = POINTER TO RECORD + a, b: CARDINAL ; + END ; + +(* + test - +*) + +PROCEDURE test (VAR p: ptr) ; +BEGIN + NEW (p) ; + WITH p^ DO + a := 1 ; + END +END test ; + + +VAR + n: ptr ; +BEGIN + test (n) +END testnew5. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew6.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew6.mod new file mode 100644 index 0000000..b3a4018 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testnew6.mod @@ -0,0 +1,27 @@ +MODULE testnew6 ; + +FROM Storage IMPORT ALLOCATE ; + +TYPE + ptr = POINTER TO RECORD + a, b: CARDINAL ; + END ; + +(* + test - +*) + +PROCEDURE test (p: ptr) ; +BEGIN + NEW (p) ; + WITH p^ DO + a := 1 ; + END +END test ; + + +VAR + n: ptr ; +BEGIN + test (n) +END testnew6. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamlvalue.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamlvalue.mod new file mode 100644 index 0000000..a783fbf --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamlvalue.mod @@ -0,0 +1,26 @@ +MODULE testparamlvalue ; + +FROM SYSTEM IMPORT ADR ; + +TYPE + PtrToVec = POINTER TO Vec ; + Vec = RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test (VAR p: PtrToVec) ; +BEGIN + IF p^.x = 1 + THEN + END +END test ; + + +VAR + q: PtrToVec ; + v: Vec ; +BEGIN + q := ADR (v) ; + test (q) +END testparamlvalue. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamrvalue.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamrvalue.mod new file mode 100644 index 0000000..eb9d0e9 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testparamrvalue.mod @@ -0,0 +1,26 @@ +MODULE testparamrvalue ; + +FROM SYSTEM IMPORT ADR ; + +TYPE + PtrToVec = POINTER TO Vec ; + Vec = RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test (p: PtrToVec) ; +BEGIN + IF p^.x = 1 + THEN + END +END test ; + + +VAR + q: PtrToVec ; + v: Vec ; +BEGIN + q := ADR (v) ; + test (q) +END testparamrvalue. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testproc.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testproc.mod new file mode 100644 index 0000000..647b2ff --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testproc.mod @@ -0,0 +1,15 @@ +MODULE testproc ; + + +PROCEDURE test (i: INTEGER) ; +BEGIN + IF i = 3 + THEN + + END +END test ; + + +BEGIN + test (3) +END testproc. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testptrptr.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testptrptr.mod new file mode 100644 index 0000000..f8c5b65 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testptrptr.mod @@ -0,0 +1,29 @@ +MODULE testptrptr ; + +FROM SYSTEM IMPORT ADR ; + +TYPE + PtrToPtrToVec = POINTER TO PtrToVec ; + PtrToVec = POINTER TO Vec ; + Vec = RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test ; +VAR + vec: Vec ; + ptr: PtrToVec ; + ptrptr: PtrToPtrToVec ; +BEGIN + ptr := ADR (vec) ; + ptrptr := ADR (ptr) ; + WITH ptrptr^^ DO + x := 1 + END +END test ; + + +BEGIN + test +END testptrptr. -- cgit v1.1 From b41a927bcbdf27723b9d420f0b403f2af12129f1 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 14 Jul 2023 12:25:51 -0400 Subject: c++: constexpr bit_cast with empty field The change to only cache constexpr calls that are reduced_constant_expression_p tripped on bit-cast3.C, which failed that predicate due to the presence of an empty field in the result of native_interpret_aggregate, which reduced_constant_expression_p rejects to avoid confusing output_constructor. This patch proposes to skip such fields in native_interpret_aggregate, since they aren't actually involved in the value representation. gcc/ChangeLog: * fold-const.cc (native_interpret_aggregate): Skip empty fields. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_bit_cast): Check that the result of native_interpret_aggregate doesn't need more evaluation. --- gcc/cp/constexpr.cc | 9 +++++++++ gcc/fold-const.cc | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 9d85c3b..6e8f1c2 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -1440,6 +1440,8 @@ enum value_cat { static tree cxx_eval_constant_expression (const constexpr_ctx *, tree, value_cat, bool *, bool *, tree * = NULL); +static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree, + value_cat, bool *, bool *); static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree, bool * = NULL); static tree find_heap_var_refs (tree *, int *, void *); @@ -4803,6 +4805,13 @@ cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p, { clear_type_padding_in_mask (TREE_TYPE (t), mask); clear_uchar_or_std_byte_in_mask (loc, r, mask); + if (CHECKING_P) + { + tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue, + non_constant_p, overflow_p); + gcc_checking_assert (e == r); + r = e; + } } } diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index a02ede7..7e5494d 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -8935,7 +8935,8 @@ native_interpret_aggregate (tree type, const unsigned char *ptr, int off, return NULL_TREE; for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { - if (TREE_CODE (field) != FIELD_DECL || DECL_PADDING_P (field)) + if (TREE_CODE (field) != FIELD_DECL || DECL_PADDING_P (field) + || is_empty_type (TREE_TYPE (field))) continue; tree fld = field; HOST_WIDE_INT bitoff = 0, pos = 0, sz = 0; -- cgit v1.1 From c11a3aedec2649d72d1b7a3a2bd909c5863eefa1 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 18 Jul 2023 17:47:50 +0200 Subject: tree-ssa-loop-ch improvements, part 3 Extend range query done by loop-ch to also support basic blocks that are not headers of the loop. This is easy to do, since we already do path specific query so we only need to extend the path by headers we decided to dulicate earlier. This makes it possible to track situations where exit that is always false in the first iteration (wihch is a common case) is not in the first iteration of the loop. Doing so lets us to update profile better and do better heuristics. In particular I changed logic as follows 1) should_duplicate_loop_header_p counts size of duplicated region. When we know that a given conditional will be constant true or constant false either in the duplicated region, by range query, or in the loop body after duplication (since it is loop invariant), we do not account it to code size costs 2) don't need account loop invariant compuations that will be duplicated as they will become fully invariant (maybe we want to have some cap for register pressure eventually?) 3) optimize_size logic is now different. Originally we started duplicating iff the first conditional was known to be true by ranger query, but then we used same limits as for -O2. I now simply lower limits to 0. This means that every conditional in duplicated sequence must be either loop invariant or constant when duplicated and we only duplicate statements computing loop invariants and those we account to 0 size anyway, This makes code IMO more logical, but makes little difference in practice. The problem is that in loop: void test2(); void test(int n) { for (int i = 0; n && i < 10; i++) test2(); } We produce: [local count: 1073741824 freq: 9.090909]: # i_4 = PHI <0(2), i_9(3)> _1 = n_7(D) != 0; _2 = i_4 <= 9; _3 = _1 & _2; if (_3 != 0) goto ; [89.00%] else goto ; [11.00%] and do not understand that the final conditional is a combination of a conditional that is always true in first iteration and a conditional that is loop invariant. This is also the case of void test2(); void test(int n) { for (int i = 0; n; i++) { if (i > 10) break; test2(); } } Which we turn to the earlier case in ifcombine. With disabled ifcombine things however works as exepcted. This is something I plan to handle incrementally. However extending loop-ch and peeling passes to understand such combined conditionals is still not good enough: at the time ifcombine merged the two conditionals we lost profile information on how often n is 0, so we can't recover correct profile or know what is expected number of iterations after the transofrm. gcc/ChangeLog: * tree-ssa-loop-ch.cc (edge_range_query): Take loop argument; be ready for queries not in headers. (static_loop_exit): Add basic blck parameter; update use of edge_range_query (should_duplicate_loop_header_p): Add ranger and static_exits parameter. Do not account statements that will be optimized out after duplicaiton in overall size. Add ranger query to find static exits. (update_profile_after_ch): Take static_exits has set instead of single eliminated_edge. (ch_base::copy_headers): Do all analysis in the first pass; remember invariant_exits and static_exits. --- gcc/tree-ssa-loop-ch.cc | 205 +++++++++++++++++++++++++++++------------------- 1 file changed, 123 insertions(+), 82 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 24e7fbc..e0139cb 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -49,11 +49,13 @@ along with GCC; see the file COPYING3. If not see the range of the solved conditional in R. */ static void -edge_range_query (irange &r, edge e, gcond *cond, gimple_ranger &ranger) +edge_range_query (irange &r, class loop *loop, gcond *cond, gimple_ranger &ranger) { - auto_vec path (2); - path.safe_push (e->dest); - path.safe_push (e->src); + auto_vec path; + for (basic_block bb = gimple_bb (cond); bb != loop->header; bb = single_pred_edge (bb)->src) + path.safe_push (bb); + path.safe_push (loop->header); + path.safe_push (loop_preheader_edge (loop)->src); path_range_query query (ranger, path); if (!query.range_of_stmt (r, cond)) r.set_varying (boolean_type_node); @@ -63,17 +65,16 @@ edge_range_query (irange &r, edge e, gcond *cond, gimple_ranger &ranger) and NULL otherwise. */ static edge -static_loop_exit (class loop *l, gimple_ranger *ranger) +static_loop_exit (class loop *l, basic_block bb, gimple_ranger *ranger) { - edge e = loop_preheader_edge (l); - gcond *last = safe_dyn_cast (*gsi_last_bb (e->dest)); + gcond *last = safe_dyn_cast (*gsi_last_bb (bb)); edge ret_e; if (!last) return NULL; edge true_e, false_e; - extract_true_false_edges_from_block (e->dest, &true_e, &false_e); + extract_true_false_edges_from_block (bb, &true_e, &false_e); /* If neither edge is the exit edge, this is not a case we'd like to special-case. */ @@ -93,7 +94,7 @@ static_loop_exit (class loop *l, gimple_ranger *ranger) } int_range<2> r; - edge_range_query (r, e, last, *ranger); + edge_range_query (r, l, last, *ranger); return r == desired_static_range ? ret_e : NULL; } @@ -131,8 +132,10 @@ loop_iv_derived_p (class loop *loop, static bool should_duplicate_loop_header_p (basic_block header, class loop *loop, + gimple_ranger *ranger, int *limit, - hash_set *invariant_exits) + hash_set *invariant_exits, + hash_set *static_exits) { gimple_stmt_iterator bsi; @@ -209,6 +212,9 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, if (is_gimple_debug (last)) continue; + if (gimple_code (last) == GIMPLE_COND) + break; + if (gimple_code (last) == GIMPLE_CALL && (!gimple_inexpensive_call_p (as_a (last)) /* IFN_LOOP_DIST_ALIAS means that inner loop is distributed @@ -222,16 +228,6 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, return false; } - *limit -= estimate_num_insns (last, &eni_size_weights); - if (*limit < 0) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " Not duplicating bb %i contains too many insns.\n", - header->index); - return false; - } - /* Classify the stmt based on whether its computation is based on a IV or whether it is invariant in the loop. */ gimple_set_uid (last, 0); @@ -257,9 +253,36 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, inv = false; } gimple_set_uid (last, (iv ? 1 : 0) | (inv ? 2 : 0)); + /* Loop invariants will be optimized out in loop body after + duplication; do not account invariant computation in code + size costs. */ + if (inv) + continue; + } + + *limit -= estimate_num_insns (last, &eni_size_weights); + if (*limit < 0) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Not duplicating bb %i contains too many insns.\n", + header->index); + return false; } } + edge static_exit = static_loop_exit (loop, header, ranger); + + if (static_exit && static_exits) + { + static_exits->add (static_exit); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Will eliminate peeled conditional in bb %d.\n", + static_exit->src->index); + /* Still look for invariant exits; exit may be both. */ + } + /* If the condition tests a non-IV loop variant we do not want to rotate the loop further. Unless this is the original loop header. */ tree lhs = gimple_cond_lhs (last); @@ -284,12 +307,28 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, } return true; } + + if (static_exit) + return true; + + /* We was not able to prove that conditional will be eliminated. */ + *limit -= estimate_num_insns (last, &eni_size_weights); + if (*limit < 0) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Not duplicating bb %i contains too many insns.\n", + header->index); + return false; + } + /* TODO: This is heuristics that claims that IV based ocnditionals will likely be optimized out in duplicated header. We could use ranger query instead to tell this more precisely. */ - if (header != loop->header - && ((!lhs_invariant && !loop_iv_derived_p (loop, lhs)) - || (!rhs_invariant && !loop_iv_derived_p (loop, rhs)))) + if ((lhs_invariant || loop_iv_derived_p (loop, lhs)) + && (rhs_invariant || loop_iv_derived_p (loop, rhs))) + return true; + if (header != loop->header) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, @@ -386,8 +425,9 @@ do_while_loop_p (class loop *loop) static void update_profile_after_ch (class loop *loop, basic_block *region, basic_block *region_copy, - unsigned n_region, edge eliminated_edge, + unsigned n_region, hash_set *invariant_exits, + hash_set *static_exits, profile_count entry_count) { for (unsigned int i = 0; i < n_region; i++) @@ -421,10 +461,13 @@ update_profile_after_ch (class loop *loop, && e_copy->dest == region_copy[i + 1])); region_copy[i]->count = entry_count; profile_count exit_e_count = exit_e->count (); - if (eliminated_edge == exit_e) + bool was_static = false; + if (static_exits->contains (exit_e)) { /* Update profile and the conditional. CFG update is done by caller. */ + static_exits->remove (exit_e); + was_static = true; e_copy->probability = profile_probability::always (); exit_e_copy->probability = profile_probability::never (); gcond *cond_stmt @@ -437,7 +480,6 @@ update_profile_after_ch (class loop *loop, /* Header copying is a special case of jump threading, so use common code to update loop body exit condition. */ update_bb_profile_for_threading (region[i], entry_count, e); - eliminated_edge = NULL; } else region[i]->count -= region_copy[i]->count; @@ -448,7 +490,7 @@ update_profile_after_ch (class loop *loop, loop, so increase probability accordingly. If the edge is eliminated_edge we already corrected profile above. */ - if (entry_count.nonzero_p () && eliminated_edge != exit_e) + if (entry_count.nonzero_p () && !was_static) set_edge_probability_and_rescale_others (exit_e_copy, exit_e_count.probability_in (entry_count)); @@ -465,7 +507,7 @@ update_profile_after_ch (class loop *loop, entry_count = e_copy->count (); } /* Be sure that we seen all edges we are supposed to update. */ - gcc_checking_assert (!eliminated_edge + gcc_checking_assert (static_exits->is_empty () && invariant_exits->is_empty ()); } @@ -564,10 +606,7 @@ protected: unsigned int ch_base::copy_headers (function *fun) { - basic_block header; - edge exit, nonexit, entry; basic_block *bbs, *copied_bbs; - unsigned n_bbs; unsigned bbs_size; bool changed = false; @@ -578,7 +617,12 @@ ch_base::copy_headers (function *fun) copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun)); bbs_size = n_basic_blocks_for_fn (fun); - struct candidate {class loop *loop; edge static_exit;}; + struct candidate + { + class loop *loop; + unsigned int nheaders; + hash_set *invariant_exits, *static_exits; + }; auto_vec candidates; auto_vec > copied; auto_vec loops_to_unloop; @@ -588,13 +632,14 @@ ch_base::copy_headers (function *fun) gimple_ranger *ranger = new gimple_ranger; for (auto loop : loops_list (cfun, 0)) { - int initial_limit = param_max_loop_header_insns; + int initial_limit = optimize_loop_for_speed_p (loop) + ? param_max_loop_header_insns : 0; int remaining_limit = initial_limit; if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Analyzing loop %i\n", loop->num); - header = loop->header; + basic_block header = loop->header; if (!get_max_loop_iterations_int (loop)) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -613,24 +658,38 @@ ch_base::copy_headers (function *fun) || !process_loop_p (loop)) continue; - edge static_exit = static_loop_exit (loop, ranger); - - /* Avoid loop header copying when optimizing for size unless we can - determine that the loop condition is static in the first - iteration. */ - if (optimize_loop_for_size_p (loop) - && !loop->force_vectorize - && !static_exit) + /* Iterate the header copying up to limit; this takes care of the cases + like while (a && b) {...}, where we want to have both of the conditions + copied. TODO -- handle while (a || b) - like cases, by not requiring + the header to have just a single successor and copying up to + postdominator. */ + int nheaders = 0; + hash_set *invariant_exits = new hash_set ; + hash_set *static_exits = new hash_set ; + while (should_duplicate_loop_header_p (header, loop, ranger, + &remaining_limit, + invariant_exits, + static_exits)) { + nheaders++; if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " Not duplicating bb %i: optimizing for size.\n", - header->index); - continue; + fprintf (dump_file, " Will duplicate bb %i\n", header->index); + + /* Find a successor of header that is inside a loop; i.e. the new + header after the condition is copied. */ + if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)) + header = EDGE_SUCC (header, 0)->dest; + else + header = EDGE_SUCC (header, 1)->dest; } - if (should_duplicate_loop_header_p (header, loop, &remaining_limit, NULL)) - candidates.safe_push ({loop, static_exit}); + if (nheaders) + candidates.safe_push ({loop, nheaders, invariant_exits, static_exits}); + else + { + delete invariant_exits; + delete static_exits; + } } /* Do not use ranger after we change the IL and not have updated SSA. */ delete ranger; @@ -638,37 +697,25 @@ ch_base::copy_headers (function *fun) for (auto candidate : candidates) { class loop *loop = candidate.loop; - int initial_limit = param_max_loop_header_insns; - int remaining_limit = initial_limit; if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Copying headers of loop %i\n", loop->num); - header = loop->header; - - /* Iterate the header copying up to limit; this takes care of the cases - like while (a && b) {...}, where we want to have both of the conditions - copied. TODO -- handle while (a || b) - like cases, by not requiring - the header to have just a single successor and copying up to - postdominator. */ - - nonexit = NULL; - n_bbs = 0; + basic_block header = loop->header; + edge nonexit = NULL; + edge exit = NULL; + unsigned int n_bbs = 0; int nexits = 0; profile_count exit_count = profile_count::zero (); profile_count entry_count = profile_count::zero (); edge e; edge_iterator ei; - hash_set invariant_exits; + FOR_EACH_EDGE (e, ei, loop->header->preds) if (e->src != loop->latch) entry_count += e->count (); - while (should_duplicate_loop_header_p (header, loop, &remaining_limit, - &invariant_exits)) + while (n_bbs < candidate.nheaders) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Will duplicate bb %i\n", header->index); - /* Find a successor of header that is inside a loop; i.e. the new header after the condition is copied. */ if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)) @@ -688,21 +735,10 @@ ch_base::copy_headers (function *fun) header = nonexit->dest; } - if (!nonexit) - continue; - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, - "Duplicating header of the loop %d up to edge %d->%d," - " %i insns.\n", - loop->num, exit->src->index, exit->dest->index, - initial_limit - remaining_limit); - if (candidate.static_exit) - fprintf (dump_file, - " Will eliminate peeled conditional in bb %d.\n", - candidate.static_exit->src->index); - } + fprintf (dump_file, + "Duplicating header of the loop %d up to edge %d->%d\n", + loop->num, exit->src->index, exit->dest->index); /* Ensure that the header will have just the latch as a predecessor inside the loop. */ @@ -712,20 +748,25 @@ ch_base::copy_headers (function *fun) exit = single_pred_edge (header); } - entry = loop_preheader_edge (loop); + edge entry = loop_preheader_edge (loop); propagate_threaded_block_debug_into (exit->dest, entry->dest); if (!gimple_duplicate_seme_region (entry, exit, bbs, n_bbs, copied_bbs, true)) { + delete candidate.static_exits; + delete candidate.invariant_exits; if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Duplication failed.\n"); continue; } if (loop->header->count.initialized_p ()) update_profile_after_ch (loop, bbs, copied_bbs, n_bbs, - candidate.static_exit, &invariant_exits, + candidate.invariant_exits, + candidate.static_exits, entry_count); + delete candidate.static_exits; + delete candidate.invariant_exits; copied.safe_push (std::make_pair (entry, loop)); /* If the loop has the form "for (i = j; i < j + 10; i++)" then -- cgit v1.1 From e9ba2ccf5b3f927fe6397a8eef23e2874a2edf05 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 18 Jul 2023 18:46:46 +0200 Subject: dwarf2: Change return type of predicate functions from int to bool Also change some internal variables and function arguments from int to bool. gcc/ChangeLog: * dwarf2asm.cc: Change FALSE to false. * dwarf2cfi.cc (execute_dwarf2_frame): Change return type to void. * dwarf2out.cc (matches_main_base): Change return type from int to bool. Change "last_match" variable to bool. (dump_struct_debug): Change return type from int to bool. Change "matches" and "result" function arguments to bool. (is_pseudo_reg): Change return type from int to bool. (is_tagged_type): Ditto. (same_loc_p): Ditto. (same_dw_val_p): Change return type from int to bool and adjust function body accordingly. (same_attr_p): Ditto. (same_die_p): Ditto. (is_type_die): Ditto. (is_declaration_die): Ditto. (should_move_die_to_comdat): Ditto. (is_base_type): Ditto. (is_based_loc): Ditto. (local_scope_p): Ditto. (class_scope_p): Ditto. (class_or_namespace_scope_p): Ditto. (is_tagged_type): Ditto. (is_rust): Use void argument. (is_nested_in_subprogram): Change return type from int to bool. (contains_subprogram_definition): Ditto. (gen_struct_or_union_type_die): Change "nested", "complete" and "ns_decl" variables to bool. (is_naming_typedef_decl): Change FALSE to false. --- gcc/dwarf2asm.cc | 6 +- gcc/dwarf2cfi.cc | 7 +- gcc/dwarf2out.cc | 198 +++++++++++++++++++++++++++---------------------------- 3 files changed, 105 insertions(+), 106 deletions(-) (limited to 'gcc') diff --git a/gcc/dwarf2asm.cc b/gcc/dwarf2asm.cc index 65b95fe..ea3f398 100644 --- a/gcc/dwarf2asm.cc +++ b/gcc/dwarf2asm.cc @@ -52,7 +52,7 @@ dw2_assemble_integer (int size, rtx x) relocations usually result in assembler errors. Assume all such values are positive and emit the relocation only in the least significant half. */ - const char *op = integer_asm_op (DWARF2_ADDR_SIZE, FALSE); + const char *op = integer_asm_op (DWARF2_ADDR_SIZE, false); if (BYTES_BIG_ENDIAN) { if (op) @@ -92,7 +92,7 @@ dw2_assemble_integer (int size, rtx x) return; } - const char *op = integer_asm_op (size, FALSE); + const char *op = integer_asm_op (size, false); if (op) { @@ -142,7 +142,7 @@ dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value, const char *comment, ...) { va_list ap; - const char *op = integer_asm_op (size, FALSE); + const char *op = integer_asm_op (size, false); va_start (ap, comment); diff --git a/gcc/dwarf2cfi.cc b/gcc/dwarf2cfi.cc index 57283c1..ddc728f 100644 --- a/gcc/dwarf2cfi.cc +++ b/gcc/dwarf2cfi.cc @@ -3291,7 +3291,7 @@ create_cie_data (void) state at each location within the function. These notes will be emitted during pass_final. */ -static unsigned int +static void execute_dwarf2_frame (void) { /* Different HARD_FRAME_POINTER_REGNUM might coexist in the same file. */ @@ -3322,8 +3322,6 @@ execute_dwarf2_frame (void) delete trace_index; trace_index = NULL; - - return 0; } /* Convert a DWARF call frame info. operation to its string name */ @@ -3796,7 +3794,8 @@ public: bool gate (function *) final override; unsigned int execute (function *) final override { - return execute_dwarf2_frame (); + execute_dwarf2_frame (); + return 0; } }; // class pass_dwarf2_frame diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 238d0a9..fa0fe4c 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -339,12 +339,12 @@ static unsigned int rnglist_idx; /* Match the base name of a file to the base name of a compilation unit. */ -static int +static bool matches_main_base (const char *path) { /* Cache the last query. */ static const char *last_path = NULL; - static int last_match = 0; + static bool last_match = false; if (path != last_path) { const char *base; @@ -358,10 +358,10 @@ matches_main_base (const char *path) #ifdef DEBUG_DEBUG_STRUCT -static int +static bool dump_struct_debug (tree type, enum debug_info_usage usage, enum debug_struct_file criterion, int generic, - int matches, int result) + bool matches, bool result) { /* Find the type name. */ tree type_decl = TYPE_STUB_DECL (type); @@ -3730,9 +3730,9 @@ enum dw_scalar_form /* Forward declarations for functions defined in this file. */ -static int is_pseudo_reg (const_rtx); +static bool is_pseudo_reg (const_rtx); static tree type_main_variant (tree); -static int is_tagged_type (const_tree); +static bool is_tagged_type (const_tree); static const char *dwarf_tag_name (unsigned); static const char *dwarf_attr_name (unsigned); static const char *dwarf_form_name (unsigned); @@ -3805,14 +3805,14 @@ static void collect_checksum_attributes (struct checksum_attributes *, dw_die_re static void die_checksum_ordered (dw_die_ref, struct md5_ctx *, int *); static void checksum_die_context (dw_die_ref, struct md5_ctx *); static void generate_type_signature (dw_die_ref, comdat_type_node *); -static int same_loc_p (dw_loc_descr_ref, dw_loc_descr_ref, int *); -static int same_dw_val_p (const dw_val_node *, const dw_val_node *, int *); -static int same_attr_p (dw_attr_node *, dw_attr_node *, int *); -static int same_die_p (dw_die_ref, dw_die_ref, int *); -static int is_type_die (dw_die_ref); +static bool same_loc_p (dw_loc_descr_ref, dw_loc_descr_ref, int *); +static bool same_dw_val_p (const dw_val_node *, const dw_val_node *, int *); +static bool same_attr_p (dw_attr_node *, dw_attr_node *, int *); +static bool same_die_p (dw_die_ref, dw_die_ref, int *); +static bool is_type_die (dw_die_ref); static inline bool is_template_instantiation (dw_die_ref); -static int is_declaration_die (dw_die_ref); -static int should_move_die_to_comdat (dw_die_ref); +static bool is_declaration_die (dw_die_ref); +static bool should_move_die_to_comdat (dw_die_ref); static dw_die_ref clone_as_declaration (dw_die_ref); static dw_die_ref clone_die (dw_die_ref); static dw_die_ref clone_tree (dw_die_ref); @@ -3859,7 +3859,7 @@ static void output_ranges (void); static dw_line_info_table *new_line_info_table (void); static void output_line_info (bool); static void output_file_names (void); -static int is_base_type (tree); +static bool is_base_type (tree); static dw_die_ref subrange_type_die (tree, tree, tree, tree, dw_die_ref); static int decl_quals (const_tree); static dw_die_ref modified_type_die (tree, int, bool, dw_die_ref); @@ -3874,7 +3874,7 @@ static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx, enum var_init_status); static dw_loc_descr_ref based_loc_descr (rtx, poly_int64, enum var_init_status); -static int is_based_loc (const_rtx); +static bool is_based_loc (const_rtx); static bool resolve_one_addr (rtx *); static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx, enum var_init_status); @@ -3927,9 +3927,9 @@ static void add_discr_value (dw_die_ref, dw_discr_value *); static void add_discr_list (dw_die_ref, dw_discr_list_ref); static inline dw_discr_list_ref AT_discr_list (dw_attr_node *); static dw_die_ref scope_die_for (tree, dw_die_ref); -static inline int local_scope_p (dw_die_ref); -static inline int class_scope_p (dw_die_ref); -static inline int class_or_namespace_scope_p (dw_die_ref); +static inline bool local_scope_p (dw_die_ref); +static inline bool class_scope_p (dw_die_ref); +static inline bool class_or_namespace_scope_p (dw_die_ref); static void add_type_attribute (dw_die_ref, tree, int, bool, dw_die_ref); static void add_calling_convention_attribute (dw_die_ref, tree); static const char *type_tag (const_tree); @@ -4308,7 +4308,7 @@ dwarf2out_set_demangle_name_func (const char *(*func) (const char *)) /* Test if rtl node points to a pseudo register. */ -static inline int +static inline bool is_pseudo_reg (const_rtx rtl) { return ((REG_P (rtl) && REGNO (rtl) >= FIRST_PSEUDO_REGISTER) @@ -4336,9 +4336,9 @@ type_main_variant (tree type) return type; } -/* Return nonzero if the given type node represents a tagged type. */ +/* Return true if the given type node represents a tagged type. */ -static inline int +static inline bool is_tagged_type (const_tree type) { enum tree_code code = TREE_CODE (type); @@ -5100,7 +5100,7 @@ bool addr_hasher::equal (addr_table_entry *a1, addr_table_entry *a2) { if (a1->kind != a2->kind) - return 0; + return false; switch (a1->kind) { case ate_kind_rtx: @@ -5604,7 +5604,7 @@ is_fortran (const_tree decl) Note, returns FALSE for dwarf_version < 5 && dwarf_strict. */ static inline bool -is_rust () +is_rust (void) { unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language); @@ -5957,7 +5957,7 @@ decl_die_hasher::hash (die_node *x) return (hashval_t) x->decl_id; } -/* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */ +/* Return true if decl_id of die_struct X is the same as UID of decl *Y. */ inline bool decl_die_hasher::equal (die_node *x, tree y) @@ -6217,7 +6217,7 @@ decl_loc_hasher::hash (var_loc_list *x) return (hashval_t) x->decl_id; } -/* Return nonzero if decl_id of var_loc_list X is the same as +/* Return true if decl_id of var_loc_list X is the same as UID of decl *Y. */ inline bool @@ -6244,7 +6244,7 @@ dw_loc_list_hasher::hash (cached_dw_loc_list *x) return (hashval_t) x->decl_id; } -/* Return nonzero if decl_id of cached_dw_loc_list X is the same as +/* Return true if decl_id of cached_dw_loc_list X is the same as UID of decl *Y. */ inline bool @@ -7837,7 +7837,7 @@ generate_type_signature (dw_die_ref die, comdat_type_node *type_node) } /* Do the location expressions look same? */ -static inline int +static inline bool same_loc_p (dw_loc_descr_ref loc1, dw_loc_descr_ref loc2, int *mark) { return loc1->dw_loc_opc == loc2->dw_loc_opc @@ -7846,14 +7846,14 @@ same_loc_p (dw_loc_descr_ref loc1, dw_loc_descr_ref loc2, int *mark) } /* Do the values look the same? */ -static int +static bool same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) { dw_loc_descr_ref loc1, loc2; rtx r1, r2; if (v1->val_class != v2->val_class) - return 0; + return false; switch (v1->val_class) { @@ -7871,11 +7871,11 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) case dw_val_class_vec: if (v1->v.val_vec.length != v2->v.val_vec.length || v1->v.val_vec.elt_size != v2->v.val_vec.elt_size) - return 0; + return false; if (memcmp (v1->v.val_vec.array, v2->v.val_vec.array, v1->v.val_vec.length * v1->v.val_vec.elt_size)) - return 0; - return 1; + return false; + return true; case dw_val_class_flag: return v1->v.val_flag == v2->v.val_flag; case dw_val_class_str: @@ -7885,7 +7885,7 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) r1 = v1->v.val_addr; r2 = v2->v.val_addr; if (GET_CODE (r1) != GET_CODE (r2)) - return 0; + return false; return !rtx_equal_p (r1, r2); case dw_val_class_offset: @@ -7896,7 +7896,7 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) loc1 && loc2; loc1 = loc1->dw_loc_next, loc2 = loc2->dw_loc_next) if (!same_loc_p (loc1, loc2, mark)) - return 0; + return false; return !loc1 && !loc2; case dw_val_class_die_ref: @@ -7912,7 +7912,7 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) case dw_val_class_macptr: case dw_val_class_loclistsptr: case dw_val_class_high_pc: - return 1; + return true; case dw_val_class_file: case dw_val_class_file_implicit: @@ -7922,29 +7922,29 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) return !memcmp (v1->v.val_data8, v2->v.val_data8, 8); default: - return 1; + return true; } } /* Do the attributes look the same? */ -static int +static bool same_attr_p (dw_attr_node *at1, dw_attr_node *at2, int *mark) { if (at1->dw_attr != at2->dw_attr) - return 0; + return false; /* We don't care that this was compiled with a different compiler snapshot; if the output is the same, that's what matters. */ if (at1->dw_attr == DW_AT_producer) - return 1; + return true; return same_dw_val_p (&at1->dw_attr_val, &at2->dw_attr_val, mark); } /* Do the dies look the same? */ -static int +static bool same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark) { dw_die_ref c1, c2; @@ -7957,27 +7957,27 @@ same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark) die1->die_mark = die2->die_mark = ++(*mark); if (die1->die_tag != die2->die_tag) - return 0; + return false; if (vec_safe_length (die1->die_attr) != vec_safe_length (die2->die_attr)) - return 0; + return false; FOR_EACH_VEC_SAFE_ELT (die1->die_attr, ix, a1) if (!same_attr_p (a1, &(*die2->die_attr)[ix], mark)) - return 0; + return false; c1 = die1->die_child; c2 = die2->die_child; if (! c1) { if (c2) - return 0; + return false; } else for (;;) { if (!same_die_p (c1, c2, mark)) - return 0; + return false; c1 = c1->die_sib; c2 = c2->die_sib; if (c1 == die1->die_child) @@ -7985,11 +7985,11 @@ same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark) if (c2 == die2->die_child) break; else - return 0; + return false; } } - return 1; + return true; } /* Calculate the MD5 checksum of the compilation unit DIE UNIT_DIE and its @@ -8032,9 +8032,9 @@ compute_comp_unit_symbol (dw_die_ref unit_die) unit_die->die_id.die_symbol = xstrdup (name); } -/* Returns nonzero if DIE represents a type, in the sense of TYPE_P. */ +/* Returns true if DIE represents a type, in the sense of TYPE_P. */ -static int +static bool is_type_die (dw_die_ref die) { switch (die->die_tag) @@ -8059,9 +8059,9 @@ is_type_die (dw_die_ref die) case DW_TAG_packed_type: case DW_TAG_volatile_type: case DW_TAG_typedef: - return 1; + return true; default: - return 0; + return false; } } @@ -8093,7 +8093,7 @@ is_namespace_die (dw_die_ref c) return c && c->die_tag == DW_TAG_namespace; } -/* Return non-zero if this DIE is a template parameter. */ +/* Return true if this DIE is a template parameter. */ static inline bool is_template_parameter (dw_die_ref die) @@ -8110,7 +8110,7 @@ is_template_parameter (dw_die_ref die) } } -/* Return non-zero if this DIE represents a template instantiation. */ +/* Return true if this DIE represents a template instantiation. */ static inline bool is_template_instantiation (dw_die_ref die) @@ -8132,9 +8132,9 @@ gen_internal_sym (const char *prefix) return xstrdup (buf); } -/* Return non-zero if this DIE is a declaration. */ +/* Return true if this DIE is a declaration. */ -static int +static bool is_declaration_die (dw_die_ref die) { dw_attr_node *a; @@ -8142,14 +8142,14 @@ is_declaration_die (dw_die_ref die) FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a) if (a->dw_attr == DW_AT_declaration) - return 1; + return true; - return 0; + return false; } -/* Return non-zero if this DIE is nested inside a subprogram. */ +/* Return true if this DIE is nested inside a subprogram. */ -static int +static bool is_nested_in_subprogram (dw_die_ref die) { dw_die_ref decl = get_AT_ref (die, DW_AT_specification); @@ -8159,25 +8159,25 @@ is_nested_in_subprogram (dw_die_ref die) return local_scope_p (decl); } -/* Return non-zero if this DIE contains a defining declaration of a +/* Return true if this DIE contains a defining declaration of a subprogram. */ -static int +static bool contains_subprogram_definition (dw_die_ref die) { dw_die_ref c; if (die->die_tag == DW_TAG_subprogram && ! is_declaration_die (die)) - return 1; + return true; FOR_EACH_CHILD (die, c, if (contains_subprogram_definition (c)) return 1); - return 0; + return false; } -/* Return non-zero if this is a type DIE that should be moved to a +/* Return true if this is a type DIE that should be moved to a COMDAT .debug_types section or .debug_info section with DW_UT_*type unit type. */ -static int +static bool should_move_die_to_comdat (dw_die_ref die) { switch (die->die_tag) @@ -8192,8 +8192,8 @@ should_move_die_to_comdat (dw_die_ref die) || get_AT (die, DW_AT_abstract_origin) || is_nested_in_subprogram (die) || contains_subprogram_definition (die)) - return 0; - return 1; + return false; + return true; case DW_TAG_array_type: case DW_TAG_interface_type: case DW_TAG_pointer_type: @@ -8211,7 +8211,7 @@ should_move_die_to_comdat (dw_die_ref die) case DW_TAG_volatile_type: case DW_TAG_typedef: default: - return 0; + return false; } } @@ -13379,10 +13379,10 @@ is_cxx_auto (tree type) return false; } -/* Given a pointer to an arbitrary ..._TYPE tree node, return nonzero if the +/* Given a pointer to an arbitrary ..._TYPE tree node, return true if the given input type is a Dwarf "fundamental" type. Otherwise return null. */ -static inline int +static inline bool is_base_type (tree type) { switch (TREE_CODE (type)) @@ -13392,7 +13392,7 @@ is_base_type (tree type) case FIXED_POINT_TYPE: case COMPLEX_TYPE: case BOOLEAN_TYPE: - return 1; + return true; case VOID_TYPE: case OPAQUE_TYPE: @@ -13409,11 +13409,11 @@ is_base_type (tree type) case OFFSET_TYPE: case LANG_TYPE: case VECTOR_TYPE: - return 0; + return false; default: if (is_cxx_auto (type)) - return 0; + return false; gcc_unreachable (); } } @@ -14919,7 +14919,7 @@ based_loc_descr (rtx reg, poly_int64 offset, /* Return true if this RTL expression describes a base+offset calculation. */ -static inline int +static inline bool is_based_loc (const_rtx rtl) { return (GET_CODE (rtl) == PLUS @@ -17857,8 +17857,8 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) return list; } -/* Return if the loc_list has only single element and thus can be represented - as location description. */ +/* Return true if the loc_list has only single element and thus + can be represented as location description. */ static bool single_element_loc_list_p (dw_loc_list_ref list) @@ -22249,22 +22249,22 @@ scope_die_for (tree t, dw_die_ref context_die) return scope_die; } -/* Returns nonzero if CONTEXT_DIE is internal to a function. */ +/* Returns true if CONTEXT_DIE is internal to a function. */ -static inline int +static inline bool local_scope_p (dw_die_ref context_die) { for (; context_die; context_die = context_die->die_parent) if (context_die->die_tag == DW_TAG_inlined_subroutine || context_die->die_tag == DW_TAG_subprogram) - return 1; + return true; - return 0; + return false; } -/* Returns nonzero if CONTEXT_DIE is a class. */ +/* Returns true if CONTEXT_DIE is a class. */ -static inline int +static inline bool class_scope_p (dw_die_ref context_die) { return (context_die @@ -22274,10 +22274,10 @@ class_scope_p (dw_die_ref context_die) || context_die->die_tag == DW_TAG_union_type)); } -/* Returns nonzero if CONTEXT_DIE is a class or namespace, for deciding +/* Returns true if CONTEXT_DIE is a class or namespace, for deciding whether or not to treat a DIE in this context as a declaration. */ -static inline int +static inline bool class_or_namespace_scope_p (dw_die_ref context_die) { return (class_scope_p (context_die) @@ -24263,7 +24263,7 @@ block_die_hasher::hash (die_struct *d) return (hashval_t) d->decl_id ^ htab_hash_pointer (d->die_parent); } -/* Return nonzero if decl_id and die_parent of die_struct X is the same +/* Return true if decl_id and die_parent of die_struct X is the same as decl_id and die_parent of die_struct Y. */ bool @@ -25898,11 +25898,11 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die, dw_die_ref type_die = lookup_type_die (type); dw_die_ref scope_die = 0; - int nested = 0; - int complete = (TYPE_SIZE (type) - && (! TYPE_STUB_DECL (type) - || ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)))); - int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace); + bool nested = false; + bool complete = (TYPE_SIZE (type) + && (! TYPE_STUB_DECL (type) + || ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)))); + bool ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace); complete = complete && should_emit_struct_debug (type, usage); if (type_die && ! complete) @@ -25911,7 +25911,7 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die, if (TYPE_CONTEXT (type) != NULL_TREE && (AGGREGATE_TYPE_P (TYPE_CONTEXT (type)) || TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL)) - nested = 1; + nested = true; scope_die = scope_die_for (type, context_die); @@ -26660,7 +26660,7 @@ is_naming_typedef_decl (const_tree decl) to C++ naming typedefs but that have different semantics. Let's be specific to c++ for now. */ || !is_cxx (decl)) - return FALSE; + return false; return (DECL_ORIGINAL_TYPE (decl) == NULL_TREE && TYPE_NAME (TREE_TYPE (decl)) == decl @@ -27649,7 +27649,7 @@ dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum) ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum); } -/* Returns nonzero if it is appropriate not to emit any debugging +/* Returns true if it is appropriate not to emit any debugging information for BLOCK, because it doesn't contain any instructions. Don't allow this for blocks with nested functions or local classes @@ -27665,16 +27665,16 @@ dwarf2out_ignore_block (const_tree block) for (decl = BLOCK_VARS (block); decl; decl = DECL_CHAIN (decl)) if (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))) - return 0; + return false; for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (block); i++) { decl = BLOCK_NONLOCALIZED_VAR (block, i); if (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))) - return 0; + return false; } - return 1; + return true; } /* Hash table routines for file_hash. */ @@ -31920,9 +31920,9 @@ loc_list_hasher::equal (const dw_loc_list_struct *a, const dw_loc_list_struct *b) { if (a == b) - return 1; + return true; if (a->hash != b->hash) - return 0; + return false; for (; a != NULL && b != NULL; a = a->dw_loc_next, b = b->dw_loc_next) if (strcmp (a->begin, b->begin) != 0 || strcmp (a->end, b->end) != 0 @@ -32652,7 +32652,7 @@ variable_value_hasher::hash (variable_value_struct *x) return (hashval_t) x->decl_id; } -/* Return nonzero if decl_id of variable_value_struct X is the same as +/* Return true if decl_id of variable_value_struct X is the same as UID of decl Y. */ inline bool -- cgit v1.1 From 05fc7db93452841280ddc5cdf71b33498ed576dc Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 5 Jul 2023 17:43:31 -0400 Subject: testsuite: fix dwarf2/utf-1.C with DWARF4 Running $ make check-c++ RUNTESTFLAGS='--target_board=unix\{-gdwarf-5,-gdwarf-4\} dwarf2.exp=utf-1.C' shows FAIL: g++.dg/debug/dwarf2/utf-1.C -std=gnu++20 scan-assembler-times DW_AT_encoding \\(0x10\\) 3 because with -gdwarf-4 the output is: .byte 0x10 # DW_AT_encoding but with -gdwarf-5 the output is the expected: # DW_AT_encoding (0x10) The difference is caused by the DWARF5 optimize_implicit_const optimization: I suppose we could do what testsuite/rust/debug/chartype.rs does and just run the test with -gdwarf-4. gcc/testsuite/ChangeLog: * g++.dg/debug/dwarf2/utf-1.C: Use -gdwarf-4. Adjust expected output. --- gcc/testsuite/g++.dg/debug/dwarf2/utf-1.C | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/utf-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/utf-1.C index 43b354f..0ce4d87 100644 --- a/gcc/testsuite/g++.dg/debug/dwarf2/utf-1.C +++ b/gcc/testsuite/g++.dg/debug/dwarf2/utf-1.C @@ -1,8 +1,13 @@ // { dg-do compile { target c++20 } } -// { dg-options { -gdwarf -dA } } +// { dg-options { -gdwarf-4 -dA } } // Test that all three use DW_ATE_UTF. -// { dg-final { scan-assembler-times {DW_AT_encoding \(0x10\)} 3 } } +// This test uses -gdwarf-4 since in DWARF5 optimize_implicit_const +// would optimize the output from: +// .byte 0x10 # DW_AT_encoding +// into: +// # DW_AT_encoding (0x10) +// { dg-final { scan-assembler-times "0x10\[ \t]\[^\n\r]* DW_AT_encoding" 3 } } char8_t c8; char16_t c16; -- cgit v1.1 From fca089e8a47314a40ad93527ba9f9d0d374b3afb Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 18 Jul 2023 13:26:39 -0400 Subject: c++: Add tests for P2621, no UB in lexer [PR110340] C++26 P2621 removes UB in the lexer and either makes the construct valid or ill-formed. We're already handling this correctly so this patch only adds tests. PR c++/110340 gcc/testsuite/ChangeLog: * g++.dg/cpp/string-4.C: New test. * g++.dg/cpp/ucn-2.C: New test. --- gcc/testsuite/g++.dg/cpp/string-4.C | 6 ++++++ gcc/testsuite/g++.dg/cpp/ucn-2.C | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp/string-4.C create mode 100644 gcc/testsuite/g++.dg/cpp/ucn-2.C (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/cpp/string-4.C b/gcc/testsuite/g++.dg/cpp/string-4.C new file mode 100644 index 0000000..37d0388 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/string-4.C @@ -0,0 +1,6 @@ +// P2621R2 - UB? In My Lexer? +// { dg-do compile } + +// [lex.phases] If a U+0027 APOSTROPHE or a U+0022 QUOTATION +// MARK matches the last category, the program is ill-formed. +const char * foo=" // { dg-error "terminating|expected" } diff --git a/gcc/testsuite/g++.dg/cpp/ucn-2.C b/gcc/testsuite/g++.dg/cpp/ucn-2.C new file mode 100644 index 0000000..c5583e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/ucn-2.C @@ -0,0 +1,15 @@ +// P2621R2 - UB? In My Lexer? +// { dg-do compile } + +// Line splicing can form a universal-character-name [lex.charset]. +int \\ +u\ +0\ +3\ +9\ +1 = 0; + +// [cpp.concat] Concatenation can form a universal-character-name. +#define CONCAT(x,y) x##y + +int CONCAT(\,u0393)=0; -- cgit v1.1 From ec842611618c9f8a50f3326d42c51961de8b28a5 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 19 Jul 2023 00:17:46 +0000 Subject: Daily bump. --- gcc/ChangeLog | 113 +++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 239 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/cp/ChangeLog | 17 ++++ gcc/m2/ChangeLog | 32 +++++++ gcc/testsuite/ChangeLog | 156 +++++++++++++++++++++++++++++++ 6 files changed, 558 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f60e5f..11ca33b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,116 @@ +2023-07-18 Uros Bizjak + + * dwarf2asm.cc: Change FALSE to false. + * dwarf2cfi.cc (execute_dwarf2_frame): Change return type to void. + * dwarf2out.cc (matches_main_base): Change return type from + int to bool. Change "last_match" variable to bool. + (dump_struct_debug): Change return type from int to bool. + Change "matches" and "result" function arguments to bool. + (is_pseudo_reg): Change return type from int to bool. + (is_tagged_type): Ditto. + (same_loc_p): Ditto. + (same_dw_val_p): Change return type from int to bool and adjust + function body accordingly. + (same_attr_p): Ditto. + (same_die_p): Ditto. + (is_type_die): Ditto. + (is_declaration_die): Ditto. + (should_move_die_to_comdat): Ditto. + (is_base_type): Ditto. + (is_based_loc): Ditto. + (local_scope_p): Ditto. + (class_scope_p): Ditto. + (class_or_namespace_scope_p): Ditto. + (is_tagged_type): Ditto. + (is_rust): Use void argument. + (is_nested_in_subprogram): Change return type from int to bool. + (contains_subprogram_definition): Ditto. + (gen_struct_or_union_type_die): Change "nested", "complete" + and "ns_decl" variables to bool. + (is_naming_typedef_decl): Change FALSE to false. + +2023-07-18 Jan Hubicka + + * tree-ssa-loop-ch.cc (edge_range_query): Take loop argument; be ready + for queries not in headers. + (static_loop_exit): Add basic blck parameter; update use of + edge_range_query + (should_duplicate_loop_header_p): Add ranger and static_exits + parameter. Do not account statements that will be optimized + out after duplicaiton in overall size. Add ranger query to + find static exits. + (update_profile_after_ch): Take static_exits has set instead of + single eliminated_edge. + (ch_base::copy_headers): Do all analysis in the first pass; + remember invariant_exits and static_exits. + +2023-07-18 Jason Merrill + + * fold-const.cc (native_interpret_aggregate): Skip empty fields. + +2023-07-18 Gaius Mulley + + * doc/gm2.texi (Semantic checking): Change example testwithptr + to testnew6. + +2023-07-18 Richard Biener + + PR middle-end/105715 + * gimple-isel.cc (gimple_expand_vec_exprs): Merge into... + (pass_gimple_isel::execute): ... this. Duplicate + comparison defs of COND_EXPRs. + +2023-07-18 Juzhe-Zhong + + * config/riscv/riscv-selftests.cc (run_poly_int_selftests): Add more selftests. + * config/riscv/riscv.cc (riscv_legitimize_poly_move): Dynamic adjust size of VLA vectors. + (riscv_convert_vector_bits): Ditto. + +2023-07-18 Juzhe-Zhong + + * config/riscv/autovec.md (vec_shl_insert_): New patterns. + * config/riscv/riscv-v.cc (shuffle_compress_patterns): Fix bugs. + +2023-07-18 Juergen Christ + + * config/s390/vx-builtins.md: New vsel pattern. + +2023-07-18 liuhongt + + PR target/110438 + * config/i386/sse.md (one_cmpl2): + Remove # from assemble output. + +2023-07-18 liuhongt + + PR target/110591 + * config/i386/sync.md (cmpccxadd_): Adjust the pattern + to explicitly set FLAGS_REG like *cmp_1, also add extra + 3 define_peephole2 after the pattern. + +2023-07-18 Ju-Zhe Zhong + + * rtl-ssa/internals.inl: Fix when mode1 and mode2 are not ordred. + +2023-07-18 Pan Li + Juzhe-Zhong + + * config/riscv/riscv.cc (struct machine_function): Add new field. + (riscv_static_frm_mode_p): New function. + (riscv_emit_frm_mode_set): New function for emit FRM. + (riscv_emit_mode_set): Extract function for FRM. + (riscv_mode_needed): Fix the TODO. + (riscv_mode_entry): Initial dynamic frm RTL. + (riscv_mode_exit): Return DYN_EXIT. + * config/riscv/riscv.md: Add rdfrm. + * config/riscv/vector-iterators.md (unspecv): Add DYN_EXIT unspecv. + * config/riscv/vector.md (frm_modee): Add new mode dyn_exit. + (fsrm): Removed. + (fsrmsi_backup): New pattern for swap. + (fsrmsi_restore): New pattern for restore. + (fsrmsi_restore_exit): New pattern for restore exit. + (frrmsi): New pattern for backup. + 2023-07-17 Arsen Arsenović * doc/extend.texi: Add @cindex on __auto_type. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 5e9edc9..2292579 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230718 +20230719 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 3820532..03db122 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,242 @@ +2023-07-18 Tom Tromey + + * gcc-interface/decl.cc (check_ok_for_atomic_type): Use Pragma_Id. + * gcc-interface/trans.cc (lvalue_required_p, Pragma_to_gnu): Use + Pragma_Id. + (get_type_length, Attribute_to_gnu, get_atomic_access): Use + Attribute_Id. + +2023-07-18 Javier Miranda + + * exp_imgv.adb (Rewrite_Object_Image): fix type of formal. Found + reading sources. + (Expand_Wide_Image_Attribute): ditto. + (Expand_Wide_Wide_Image_Attribute): ditto. + (Rewrite_Object_Image): ditto. + * exp_put_image.adb (Build_Image_Call): For class-wide interface + type prefix generate code to displace the pointer to the object to + reference the base of the underlying object. + +2023-07-18 Viljar Indus + + * sem_aggr.adb (Resolve_Iterated_Association): Add temporary scope + when analyzing the Iterator Specification. Use preanalysis instead + of Analysis to avoid polluting the tree. + +2023-07-18 Viljar Indus + + * sem_aggr.adb (Resolve_Iterated_Association): Use the element + type for the iterator in a container aggregate with an iterator + specification. + +2023-07-18 Viljar Indus + + * exp_aggr.adb (Expand_Container_Aggregate): Use the positional + addition method only when dealing with a container aggregate + without an Iterator Specification e.g. with a loop parameter + specification + +2023-07-18 Eric Botcazou + + * sem_util.ads (Wrong_Type): Add Multiple parameter defaulting to + False and document it. + * sem_util.adb (Wrong_Type): Do not return early if an error has + already been posted on Expr and Multiple is True. + * sem_ch4.adb (Analyze_One_Call): Pass All_Errors_Mode as the + actual parameter for Multiple to Wrong_Type. + +2023-07-18 Javier Miranda + + * exp_disp.adb (Has_Dispatching_Constructor_Call): Removed. + (Expand_Interface_Conversion): Reverse patch. + +2023-07-18 Ronan Desplanques + + * libgnarl/s-taprop__linux.adb (Set_Task_Affinity, Create_Task): Tweak + handling of CPU affinities. + +2023-07-18 Eric Botcazou + + * sem_type.ads (Is_Ancestor): Remove mention of tagged type. + * exp_aggr.adb: Add with and use clauses for Sem_Type. + (Build_Record_Aggr_Code.Replace_Type): Call Is_Ancestor to spot + self-references to the type of the aggregate. + * sem_aggr.adb (Resolve_Record_Aggregate.Add_Discriminant_Values): + Likewise. + +2023-07-18 Eric Botcazou + + * sem_ch13.adb (Replace_Type_References_Generic.Visible_Component): + In the case of private discriminated types, explicitly check that we + have a private declaration before examining its discriminant part. + +2023-07-18 Alexandre Oliva + + * libgnat/a-except.ads (Raise_Exception): Mark expected_throw. + (Reraise_Occurrence): Likewise. + (Raise_Exception_Always): Likewise. + (Raise_From_Controlled_Operation): Likewise. + (Reraise_Occurrence_Always): Likewise. + (Reraise_Occurrence_No_Defer): Likewise. + * libgnat/a-except.adb + (Exception_Propagation.Propagate_Exception): Likewise. + (Complete_And_Propagate_Occurrence): Likewise. + (Raise_Exception_No_Defer): Likewise. + (Raise_From_Signal_Handler): Likewise. + (Raise_With_Msg): Likewise. + (Raise_With_Location_And_Msg): Likewise. + (Raise_Constraint_Error): Likewise. + (Raise_Constraint_Error_Msg): Likewise. + (Raise_Program_Error): Likewise. + (Raise_Program_Error_Msg): Likewise. + (Raise_Storage_Error): Likewise. + (Raise_Storage_Error_Msg): Likewise. + (Reraise, Rcheck_*): Likewise. + * doc/gnat_rm/security_hardening_features.rst (Control Flow + Hardening): Note the influence of expected_throw. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + * gcc-interface/utils.cc (handle_expected_throw_attribute): New. + (gnat_internal_attribute_table): Add expected_throw. + +2023-07-18 Vasiliy Fofanov + + * libgnat/s-pack03.adb: Update copyright year; refactor return statements. + * libgnat/s-pack05.adb: Likewise. + * libgnat/s-pack06.adb: Likewise. + * libgnat/s-pack07.adb: Likewise. + * libgnat/s-pack09.adb: Likewise. + * libgnat/s-pack10.adb: Likewise. + * libgnat/s-pack100.adb: Likewise. + * libgnat/s-pack101.adb: Likewise. + * libgnat/s-pack102.adb: Likewise. + * libgnat/s-pack103.adb: Likewise. + * libgnat/s-pack104.adb: Likewise. + * libgnat/s-pack105.adb: Likewise. + * libgnat/s-pack106.adb: Likewise. + * libgnat/s-pack107.adb: Likewise. + * libgnat/s-pack108.adb: Likewise. + * libgnat/s-pack109.adb: Likewise. + * libgnat/s-pack11.adb: Likewise. + * libgnat/s-pack110.adb: Likewise. + * libgnat/s-pack111.adb: Likewise. + * libgnat/s-pack112.adb: Likewise. + * libgnat/s-pack113.adb: Likewise. + * libgnat/s-pack114.adb: Likewise. + * libgnat/s-pack115.adb: Likewise. + * libgnat/s-pack116.adb: Likewise. + * libgnat/s-pack117.adb: Likewise. + * libgnat/s-pack118.adb: Likewise. + * libgnat/s-pack119.adb: Likewise. + * libgnat/s-pack12.adb: Likewise. + * libgnat/s-pack120.adb: Likewise. + * libgnat/s-pack121.adb: Likewise. + * libgnat/s-pack122.adb: Likewise. + * libgnat/s-pack123.adb: Likewise. + * libgnat/s-pack124.adb: Likewise. + * libgnat/s-pack125.adb: Likewise. + * libgnat/s-pack126.adb: Likewise. + * libgnat/s-pack127.adb: Likewise. + * libgnat/s-pack13.adb: Likewise. + * libgnat/s-pack14.adb: Likewise. + * libgnat/s-pack15.adb: Likewise. + * libgnat/s-pack17.adb: Likewise. + * libgnat/s-pack18.adb: Likewise. + * libgnat/s-pack19.adb: Likewise. + * libgnat/s-pack20.adb: Likewise. + * libgnat/s-pack21.adb: Likewise. + * libgnat/s-pack22.adb: Likewise. + * libgnat/s-pack23.adb: Likewise. + * libgnat/s-pack24.adb: Likewise. + * libgnat/s-pack25.adb: Likewise. + * libgnat/s-pack26.adb: Likewise. + * libgnat/s-pack27.adb: Likewise. + * libgnat/s-pack28.adb: Likewise. + * libgnat/s-pack29.adb: Likewise. + * libgnat/s-pack30.adb: Likewise. + * libgnat/s-pack31.adb: Likewise. + * libgnat/s-pack33.adb: Likewise. + * libgnat/s-pack34.adb: Likewise. + * libgnat/s-pack35.adb: Likewise. + * libgnat/s-pack36.adb: Likewise. + * libgnat/s-pack37.adb: Likewise. + * libgnat/s-pack38.adb: Likewise. + * libgnat/s-pack39.adb: Likewise. + * libgnat/s-pack40.adb: Likewise. + * libgnat/s-pack41.adb: Likewise. + * libgnat/s-pack42.adb: Likewise. + * libgnat/s-pack43.adb: Likewise. + * libgnat/s-pack44.adb: Likewise. + * libgnat/s-pack45.adb: Likewise. + * libgnat/s-pack46.adb: Likewise. + * libgnat/s-pack47.adb: Likewise. + * libgnat/s-pack48.adb: Likewise. + * libgnat/s-pack49.adb: Likewise. + * libgnat/s-pack50.adb: Likewise. + * libgnat/s-pack51.adb: Likewise. + * libgnat/s-pack52.adb: Likewise. + * libgnat/s-pack53.adb: Likewise. + * libgnat/s-pack54.adb: Likewise. + * libgnat/s-pack55.adb: Likewise. + * libgnat/s-pack56.adb: Likewise. + * libgnat/s-pack57.adb: Likewise. + * libgnat/s-pack58.adb: Likewise. + * libgnat/s-pack59.adb: Likewise. + * libgnat/s-pack60.adb: Likewise. + * libgnat/s-pack61.adb: Likewise. + * libgnat/s-pack62.adb: Likewise. + * libgnat/s-pack63.adb: Likewise. + * libgnat/s-pack65.adb: Likewise. + * libgnat/s-pack66.adb: Likewise. + * libgnat/s-pack67.adb: Likewise. + * libgnat/s-pack68.adb: Likewise. + * libgnat/s-pack69.adb: Likewise. + * libgnat/s-pack70.adb: Likewise. + * libgnat/s-pack71.adb: Likewise. + * libgnat/s-pack72.adb: Likewise. + * libgnat/s-pack73.adb: Likewise. + * libgnat/s-pack74.adb: Likewise. + * libgnat/s-pack75.adb: Likewise. + * libgnat/s-pack76.adb: Likewise. + * libgnat/s-pack77.adb: Likewise. + * libgnat/s-pack78.adb: Likewise. + * libgnat/s-pack79.adb: Likewise. + * libgnat/s-pack80.adb: Likewise. + * libgnat/s-pack81.adb: Likewise. + * libgnat/s-pack82.adb: Likewise. + * libgnat/s-pack83.adb: Likewise. + * libgnat/s-pack84.adb: Likewise. + * libgnat/s-pack85.adb: Likewise. + * libgnat/s-pack86.adb: Likewise. + * libgnat/s-pack87.adb: Likewise. + * libgnat/s-pack88.adb: Likewise. + * libgnat/s-pack89.adb: Likewise. + * libgnat/s-pack90.adb: Likewise. + * libgnat/s-pack91.adb: Likewise. + * libgnat/s-pack92.adb: Likewise. + * libgnat/s-pack93.adb: Likewise. + * libgnat/s-pack94.adb: Likewise. + * libgnat/s-pack95.adb: Likewise. + * libgnat/s-pack96.adb: Likewise. + * libgnat/s-pack97.adb: Likewise. + * libgnat/s-pack98.adb: Likewise. + * libgnat/s-pack99.adb: Likewise. + +2023-07-18 Yannick Moy + + * errout.adb (Error_Msg_Internal): Remove call to + Prescan_Message on the special continuation for the explain code + command, as this does not play well with the setting of global + variables for the message (like its status as a warning or not). + Instead, set directly the global variables regarding content of + the message in terms of special characters. + +2023-07-18 Eric Botcazou + + * sem_util.ads (Validated_View): Document enhanced behavior. + * sem_util.adb (Validated_View): Return the nonlimited view, if any, + of types coming from a limited with. + 2023-07-11 Bob Duff * exp_ch3.adb (Expand_N_Object_Declaration): Avoid transforming to diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 240c009..968b815 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2023-07-18 Jason Merrill + + * constexpr.cc (cxx_eval_bit_cast): Check that the result of + native_interpret_aggregate doesn't need more evaluation. + +2023-07-18 Patrick Palka + + * call.cc (add_template_conv_candidate): Don't check for + non-empty 'candidates' here. + (build_op_call): Check it here, before we've considered any + conversion functions. + +2023-07-18 Patrick Palka + + PR c++/110535 + * call.cc (add_conv_candidate): Check constraints. + 2023-07-17 Jason Merrill * constexpr.cc (cxx_eval_call_expression): Only cache diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 774090e..62824f2 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,35 @@ +2023-07-18 Gaius Mulley + + * Make-lang.in: Minor formatting change. + * gm2-compiler/M2GCCDeclare.mod + (DeclareUnboundedProcedureParameters): Rename local variables. + (WalkUnboundedProcedureParameters): Rename local variables. + (DoVariableDeclaration): Avoid declaration of a variable if + it is on the heap (used by static analysis only). + * gm2-compiler/M2GenGCC.mod: Formatting. + * gm2-compiler/M2Quads.def (GetQuadTrash): New procedure function. + * gm2-compiler/M2Quads.mod (GetQuadTrash): New procedure function. + (QuadFrame): Add Trash field. + (BuildRealFuncProcCall): Detect ALLOCATE and DEALLOCATE and create + a heap variable for parameter 1 saving it as the trashed variable + for static analysis. + (GenQuadOTrash): New procedure. + (DisplayQuadRange): Bugfix. Write the scope number. + * gm2-compiler/M2SymInit.mod: Rewritten to separate LValue + equivalence from LValue to RValue pairings. Comprehensive + detection of variant record implemented. Allow dereferencing + of pointers through LValue/RValue chains. + * gm2-compiler/SymbolTable.def (PutVarHeap): New procedure. + (IsVarHeap): New procedure function. + (ForeachParamSymDo): New procedure. + * gm2-compiler/SymbolTable.mod (PutVarHeap): New procedure. + (IsVarHeap): New procedure function. + (ForeachParamSymDo): New procedure. + (MakeVariableForParam): Reformatted. + (CheckForUnknownInModule): Reformatted. + (SymVar): Add field Heap. + (MakeVar): Assign Heap to FALSE. + 2023-07-13 Rainer Orth * Make-lang.in (m2/boot-bin/mklink$(exeext)): Add $(LDFLAGS). diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7e6ffb0..125c209 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,159 @@ +2023-07-18 Marek Polacek + + PR c++/110340 + * g++.dg/cpp/string-4.C: New test. + * g++.dg/cpp/ucn-2.C: New test. + +2023-07-18 Marek Polacek + + * g++.dg/debug/dwarf2/utf-1.C: Use -gdwarf-4. Adjust expected + output. + +2023-07-18 Gaius Mulley + + * gm2/switches/uninit-variable-checking/pass/assignparam.mod: New test. + * gm2/switches/uninit-variable-checking/pass/tiny.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/switches-uninit-variable-checking-procedures-fail.exp: + New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testnew.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testnew2.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testnew3.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testnew4.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testnew5.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testnew6.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testptrptr.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/assignparam2.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/switches-uninit-variable-checking-procedures-pass.exp: + New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testnew5.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testnew6.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testparamlvalue.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testparamrvalue.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testproc.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testptrptr.mod: New test. + +2023-07-18 Patrick Palka + + * g++.dg/overload/conv-op5.C: New test. + +2023-07-18 Patrick Palka + + PR c++/110535 + * g++.dg/cpp2a/concepts-surrogate1.C: New test. + * g++.dg/cpp2a/concepts-surrogate2.C: New test. + +2023-07-18 Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/zve32f_zvl1024b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32f_zvl2048b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32f_zvl4096b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32f_zvl512b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32x_zvl1024b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32x_zvl2048b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32x_zvl4096b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve32x_zvl512b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64d_zvl1024b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64d_zvl2048b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64d_zvl256b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64d_zvl4096b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64d_zvl512b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64f_zvl1024b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64f_zvl2048b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64f_zvl256b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64f_zvl4096b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64f_zvl512b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64x_zvl1024b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64x_zvl2048b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64x_zvl256b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64x_zvl4096b-1.c: New test. + * gcc.target/riscv/rvv/autovec/zve64x_zvl512b-1.c: New test. + +2023-07-18 Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/reduc/reduc-5.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc-6.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc-7.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc-8.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc-9.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-5.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-6.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-7.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-8.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_run-9.c: New test. + +2023-07-18 Lehua Ding + + * gcc.target/riscv/attribute-20.c: Removed. + +2023-07-18 Juergen Christ + + * gcc.target/s390/vector/vec-cmpge.c: New test. + +2023-07-18 Joern Rennecke + + * gcc.target/riscv/_Float16-zhinx-1.c: Tighten regexps. + +2023-07-18 liuhongt + + * gcc.target/i386/pr110591.c: New test. + * gcc.target/i386/pr110591-2.c: New test. + +2023-07-18 Pan Li + + * gcc.target/riscv/rvv/base/float-point-frm-run-1.c: Fix run failure. + +2023-07-18 Pan Li + Juzhe-Zhong + + * gcc.target/riscv/rvv/base/float-point-frm-insert-1.c: Adjust + test cases. + * gcc.target/riscv/rvv/base/float-point-frm-insert-10.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-2.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-3.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-4.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-5.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-7.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-8.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-insert-9.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-run-1.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-run-2.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-frm-run-3.c: Ditto. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-1.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-10.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-11.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-12.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-13.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-14.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-15.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-16.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-17.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-18.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-19.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-2.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-20.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-21.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-22.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-23.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-24.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-25.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-26.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-27.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-28.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-29.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-3.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-30.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-31.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-32.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-4.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-5.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-6.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-7.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-8.c: New test. + * gcc.target/riscv/rvv/base/float-point-dynamic-frm-9.c: New test. + 2023-07-17 Harald Anlauf PR fortran/95947 -- cgit v1.1 From 9a19fa8b616f83474c35cc5b34a3865073ced829 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Tue, 18 Apr 2023 14:53:04 +0800 Subject: Support type _Float16/__bf16 independent of SSE2. Enable _Float16 and __bf16 all the time but issue errors when the types are used in conversion, unary operation, binary operation, parameter passing or value return when TARGET_SSE2 is not available. Also undef macros which are used by libgcc/libstdc++ to check the backend support of the _Float16/__bf16 types when TARGET_SSE2 is not available. gcc/ChangeLog: PR target/109504 * config/i386/i386-builtins.cc (ix86_register_float16_builtin_type): Remove TARGET_SSE2. (ix86_register_bf16_builtin_type): Ditto. * config/i386/i386-c.cc (ix86_target_macros): When TARGET_SSE2 isn't available, undef the macros which are used to check the backend support of the _Float16/__bf16 types when building libstdc++ and libgcc. * config/i386/i386.cc (construct_container): Issue errors for HFmode/BFmode when TARGET_SSE2 is not available. (function_value_32): Ditto. (ix86_scalar_mode_supported_p): Remove TARGET_SSE2 for HFmode/BFmode. (ix86_libgcc_floating_mode_supported_p): Ditto. (ix86_emit_support_tinfos): Adjust codes. (ix86_invalid_conversion): Return diagnostic message string when there's conversion from/to BF/HFmode w/o TARGET_SSE2. (ix86_invalid_unary_op): New function. (ix86_invalid_binary_op): Ditto. (TARGET_INVALID_UNARY_OP): Define. (TARGET_INVALID_BINARY_OP): Define. * config/i386/immintrin.h [__SSE2__]: Remove for fp16/bf16 related instrinsics header files. * config/i386/i386.h (VALID_SSE2_TYPE_MODE): New macro. gcc/testsuite/ChangeLog: * gcc.target/i386/pr109504.c: New test. * gcc.target/i386/sse2-bfloat16-1.c: Adjust error info. * gcc.target/i386/sse2-float16-1.c: Ditto. * gcc.target/i386/sse2-float16-4.c: New test. * gcc.target/i386/sse2-float16-5.c: New test. * g++.target/i386/float16-1.C: Adjust error info. libgcc/ChangeLog: * config/i386/t-softfp: Add -msse2 to libbid HFtype related files. --- gcc/config/i386/i386-builtins.cc | 4 +- gcc/config/i386/i386-c.cc | 15 +++ gcc/config/i386/i386.cc | 125 +++++++++++++++++++++--- gcc/config/i386/i386.h | 4 + gcc/config/i386/immintrin.h | 4 - gcc/testsuite/g++.target/i386/float16-1.C | 8 +- gcc/testsuite/gcc.target/i386/pr109504.c | 6 ++ gcc/testsuite/gcc.target/i386/sse2-bfloat16-1.c | 8 +- gcc/testsuite/gcc.target/i386/sse2-float16-1.c | 8 +- gcc/testsuite/gcc.target/i386/sse2-float16-4.c | 25 +++++ gcc/testsuite/gcc.target/i386/sse2-float16-5.c | 24 +++++ 11 files changed, 199 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr109504.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-float16-4.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-float16-5.c (limited to 'gcc') diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc index e436ca4..6c90334 100644 --- a/gcc/config/i386/i386-builtins.cc +++ b/gcc/config/i386/i386-builtins.cc @@ -1376,7 +1376,7 @@ ix86_register_float16_builtin_type (void) else ix86_float16_type_node = float16_type_node; - if (!maybe_get_identifier ("_Float16") && TARGET_SSE2) + if (!maybe_get_identifier ("_Float16")) lang_hooks.types.register_builtin_type (ix86_float16_type_node, "_Float16"); } @@ -1394,7 +1394,7 @@ ix86_register_bf16_builtin_type (void) else ix86_bf16_type_node = bfloat16_type_node; - if (!maybe_get_identifier ("__bf16") && TARGET_SSE2) + if (!maybe_get_identifier ("__bf16")) lang_hooks.types.register_builtin_type (ix86_bf16_type_node, "__bf16"); } diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index 808fc42..2579505 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -832,6 +832,21 @@ ix86_target_macros (void) if (!TARGET_80387) cpp_define (parse_in, "_SOFT_FLOAT"); + /* HFmode/BFmode is supported without depending any isa + in scalar_mode_supported_p and libgcc_floating_mode_supported_p, + but according to psABI, they're really supported w/ SSE2 and above. + Since libstdc++ uses __STDCPP_FLOAT16_T__ and __STDCPP_BFLOAT16_T__ + for backend support of the types, undef the macros to avoid + build failure, see PR109504. */ + if (!TARGET_SSE2) + { + if (c_dialect_cxx () && cxx_dialect > cxx20) + { + cpp_undef (parse_in, "__STDCPP_FLOAT16_T__"); + cpp_undef (parse_in, "__STDCPP_BFLOAT16_T__"); + } + } + if (TARGET_LONG_DOUBLE_64) cpp_define (parse_in, "__LONG_DOUBLE_64__"); diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index f0d6167..eabc700 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -2661,7 +2661,8 @@ construct_container (machine_mode mode, machine_mode orig_mode, /* We allowed the user to turn off SSE for kernel mode. Don't crash if some less clueful developer tries to use floating-point anyway. */ - if (needed_sseregs && !TARGET_SSE) + if (needed_sseregs + && (!TARGET_SSE || (VALID_SSE2_TYPE_MODE (mode) && !TARGET_SSE2))) { /* Return early if we shouldn't raise an error for invalid calls. */ @@ -2671,13 +2672,19 @@ construct_container (machine_mode mode, machine_mode orig_mode, { if (!issued_sse_ret_error) { - error ("SSE register return with SSE disabled"); + if (VALID_SSE2_TYPE_MODE (mode)) + error ("SSE register return with SSE2 disabled"); + else + error ("SSE register return with SSE disabled"); issued_sse_ret_error = true; } } else if (!issued_sse_arg_error) { - error ("SSE register argument with SSE disabled"); + if (VALID_SSE2_TYPE_MODE (mode)) + error ("SSE register argument with SSE2 disabled"); + else + error ("SSE register argument with SSE disabled"); issued_sse_arg_error = true; } return NULL; @@ -4032,13 +4039,26 @@ function_value_32 (machine_mode orig_mode, machine_mode mode, /* Return __bf16/ _Float16/_Complex _Foat16 by sse register. */ if (mode == HFmode || mode == BFmode) - regno = FIRST_SSE_REG; + { + if (!TARGET_SSE2) + { + error ("SSE register return with SSE2 disabled"); + regno = AX_REG; + } + else + regno = FIRST_SSE_REG; + } + if (mode == HCmode) { + if (!TARGET_SSE2) + error ("SSE register return with SSE2 disabled"); + rtx ret = gen_rtx_PARALLEL (mode, rtvec_alloc(1)); XVECEXP (ret, 0, 0) = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, FIRST_SSE_REG), + gen_rtx_REG (SImode, + TARGET_SSE2 ? FIRST_SSE_REG : AX_REG), GEN_INT (0)); return ret; } @@ -22786,14 +22806,35 @@ x86_emit_floatuns (rtx operands[2]) } /* Return the diagnostic message string if conversion from FROMTYPE to - TOTYPE is not allowed, NULL otherwise. - Currently it's used to warn for silent implicit conversion between __bf16 - and short, since __bfloat16 is refined as real __bf16 instead of short - since GCC13. */ + TOTYPE is not allowed, NULL otherwise. */ static const char * ix86_invalid_conversion (const_tree fromtype, const_tree totype) { + machine_mode from_mode = element_mode (fromtype); + machine_mode to_mode = element_mode (totype); + + if (!TARGET_SSE2 && from_mode != to_mode) + { + /* Do no allow conversions to/from BFmode/HFmode scalar types + when TARGET_SSE2 is not available. */ + if (from_mode == BFmode) + return N_("invalid conversion from type %<__bf16%> " + "without option %<-msse2%>"); + if (from_mode == HFmode) + return N_("invalid conversion from type %<_Float16%> " + "without option %<-msse2%>"); + if (to_mode == BFmode) + return N_("invalid conversion to type %<__bf16%> " + "without option %<-msse2%>"); + if (to_mode == HFmode) + return N_("invalid conversion to type %<_Float16%> " + "without option %<-msse2%>"); + } + + /* Warn for silent implicit conversion between __bf16 and short, + since __bfloat16 is refined as real __bf16 instead of short + since GCC13. */ if (element_mode (fromtype) != element_mode (totype) && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT)) { @@ -22813,6 +22854,55 @@ ix86_invalid_conversion (const_tree fromtype, const_tree totype) return NULL; } +/* Return the diagnostic message string if the unary operation OP is + not permitted on TYPE, NULL otherwise. */ + +static const char * +ix86_invalid_unary_op (int op, const_tree type) +{ + machine_mode mmode = element_mode (type); + /* Reject all single-operand operations on BFmode/HFmode except for & + when TARGET_SSE2 is not available. */ + if (!TARGET_SSE2 && op != ADDR_EXPR) + { + if (mmode == BFmode) + return N_("operation not permitted on type %<__bf16%> " + "without option %<-msse2%>"); + if (mmode == HFmode) + return N_("operation not permitted on type %<_Float16%> " + "without option %<-msse2%>"); + } + + /* Operation allowed. */ + return NULL; +} + +/* Return the diagnostic message string if the binary operation OP is + not permitted on TYPE1 and TYPE2, NULL otherwise. */ + +static const char * +ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, + const_tree type2) +{ + machine_mode type1_mode = element_mode (type1); + machine_mode type2_mode = element_mode (type2); + /* Reject all 2-operand operations on BFmode or HFmode + when TARGET_SSE2 is not available. */ + if (!TARGET_SSE2) + { + if (type1_mode == BFmode || type2_mode == BFmode) + return N_("operation not permitted on type %<__bf16%> " + "without option %<-msse2%>"); + + if (type1_mode == HFmode || type2_mode == HFmode) + return N_("operation not permitted on type %<_Float16%> " + "without option %<-msse2%>"); + } + + /* Operation allowed. */ + return NULL; +} + /* Target hook for scalar_mode_supported_p. */ static bool @@ -22822,7 +22912,7 @@ ix86_scalar_mode_supported_p (scalar_mode mode) return default_decimal_float_supported_p (); else if (mode == TFmode) return true; - else if ((mode == HFmode || mode == BFmode) && TARGET_SSE2) + else if (mode == HFmode || mode == BFmode) return true; else return default_scalar_mode_supported_p (mode); @@ -22838,7 +22928,7 @@ ix86_libgcc_floating_mode_supported_p (scalar_float_mode mode) be defined by the C front-end for AVX512FP16 intrinsics. We will issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't enabled. */ - return (((mode == HFmode || mode == BFmode) && TARGET_SSE2) + return ((mode == HFmode || mode == BFmode) ? true : default_libgcc_floating_mode_supported_p (mode)); } @@ -23168,9 +23258,10 @@ ix86_emit_support_tinfos (emit_support_tinfos_callback callback) if (!TARGET_SSE2) { - gcc_checking_assert (!float16_type_node && !bfloat16_type_node); - float16_type_node = ix86_float16_type_node; - bfloat16_type_node = ix86_bf16_type_node; + if (!float16_type_node) + float16_type_node = ix86_float16_type_node; + if (!bfloat16_type_node) + bfloat16_type_node = ix86_bf16_type_node; callback (float16_type_node); callback (bfloat16_type_node); float16_type_node = NULL_TREE; @@ -25107,6 +25198,12 @@ ix86_run_selftests (void) #undef TARGET_INVALID_CONVERSION #define TARGET_INVALID_CONVERSION ix86_invalid_conversion +#undef TARGET_INVALID_UNARY_OP +#define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op + +#undef TARGET_INVALID_BINARY_OP +#define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op + #undef TARGET_COMP_TYPE_ATTRIBUTES #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index d8adfa2..ef342fc 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1047,6 +1047,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define VALID_AVX512FP16_REG_MODE(MODE) \ ((MODE) == V8HFmode || (MODE) == V16HFmode || (MODE) == V32HFmode) +#define VALID_SSE2_TYPE_MODE(MODE) \ + ((MODE) == HFmode || (MODE) == BFmode \ + || (MODE) == HCmode || (MODE) == BCmode) + #define VALID_SSE2_REG_MODE(MODE) \ ((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \ || (MODE) == V8HFmode || (MODE) == V4HFmode || (MODE) == V2HFmode \ diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h index ea14354..29b4dbb 100644 --- a/gcc/config/i386/immintrin.h +++ b/gcc/config/i386/immintrin.h @@ -100,11 +100,9 @@ #include -#ifdef __SSE2__ #include #include -#endif #include @@ -126,13 +124,11 @@ #include -#ifdef __SSE2__ #include #include #include -#endif #include diff --git a/gcc/testsuite/g++.target/i386/float16-1.C b/gcc/testsuite/g++.target/i386/float16-1.C index f96b932..938852e 100644 --- a/gcc/testsuite/g++.target/i386/float16-1.C +++ b/gcc/testsuite/g++.target/i386/float16-1.C @@ -1,8 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2 -mno-sse2" } */ -_Float16 /* { dg-error "expected unqualified-id before '_Float16'" } */ -foo (_Float16 x) +_Float16 +foo (_Float16 x)/* { dg-error "SSE register return with SSE2 disabled" } */ { - return x; -} /* { dg-error "'_Float16' is not supported on this target" } */ + return x;/* { dg-error "SSE register return with SSE2 disabled" "" { target ia32 } } */ +} diff --git a/gcc/testsuite/gcc.target/i386/pr109504.c b/gcc/testsuite/gcc.target/i386/pr109504.c new file mode 100644 index 0000000..fe5bcda --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr109504.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sse" } */ + +#pragma GCC target("sse4.1") +#include +int main(){return 0;} diff --git a/gcc/testsuite/gcc.target/i386/sse2-bfloat16-1.c b/gcc/testsuite/gcc.target/i386/sse2-bfloat16-1.c index 612d55b..717055bc 100644 --- a/gcc/testsuite/gcc.target/i386/sse2-bfloat16-1.c +++ b/gcc/testsuite/gcc.target/i386/sse2-bfloat16-1.c @@ -1,8 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2 -mno-sse2" } */ -__bf16/* { dg-error "unknown type name '__bf16'" } */ -foo (__bf16 x) /* { dg-error "unknown type name '__bf16'" } */ -{ - return x; +__bf16 +foo (__bf16 x) /* { dg-error "SSE register return with SSE2 disabled" } */ +{ /* { dg-error "SSE register return with SSE2 disabled" "" { target ia32 } } */ + return x; /* { dg-error "SSE register return with SSE2 disabled" "" { target ia32} } */ } diff --git a/gcc/testsuite/gcc.target/i386/sse2-float16-1.c b/gcc/testsuite/gcc.target/i386/sse2-float16-1.c index 1b645eb..faf818d 100644 --- a/gcc/testsuite/gcc.target/i386/sse2-float16-1.c +++ b/gcc/testsuite/gcc.target/i386/sse2-float16-1.c @@ -1,8 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2 -mno-sse2" } */ -_Float16/* { dg-error "is not supported on this target" } */ -foo (_Float16 x) /* { dg-error "is not supported on this target" } */ -{ - return x; +_Float16 +foo (_Float16 x) /* { dg-error "SSE register return with SSE2 disabled" } */ +{ /* { dg-error "SSE register return with SSE2 disabled" "" { target ia32 } } */ + return x; /* { dg-error "SSE register return with SSE2 disabled" "" { target ia32} } */ } diff --git a/gcc/testsuite/gcc.target/i386/sse2-float16-4.c b/gcc/testsuite/gcc.target/i386/sse2-float16-4.c new file mode 100644 index 0000000..64baf92 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-float16-4.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sse2" } */ + +_Float16 a; +__bf16 c; +_Complex _Float16 ac; + +void +foo (_Float16* p) +{ + a = *p; +} + +void +foo1 (__bf16 *p) +{ + c = *p; +} + + +void +foo2 (_Complex _Float16* p) +{ + ac = *p; +} diff --git a/gcc/testsuite/gcc.target/i386/sse2-float16-5.c b/gcc/testsuite/gcc.target/i386/sse2-float16-5.c new file mode 100644 index 0000000..c3ed23b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-float16-5.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target ia32} } */ +/* { dg-options "-O2 -mno-sse2" } */ + +_Float16 a; +__bf16 c; +_Complex ac; +void +foo (_Float16 p) +{ + a = p; +} + +void +foo1 (__bf16 p) +{ + c = p; +} + + +void +foo2 (_Complex p) +{ + ac = p; +} -- cgit v1.1 From 1d3e4f4e2d19c3394dc018118a78c1f4b59cb5c2 Mon Sep 17 00:00:00 2001 From: Lewis Hyatt Date: Tue, 18 Jul 2023 17:16:08 -0400 Subject: libcpp: Handle extended characters in user-defined literal suffix [PR103902] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PR complains that we do not handle UTF-8 in the suffix for a user-defined literal, such as: bool operator ""_π (unsigned long long); In fact we don't handle any extended identifier characters there, whether UTF-8, UCNs, or the $ sign. We do handle it fine if the optional space after the "" tokens is included, since then the identifier is lexed in the "normal" way as its own token. But when it is lexed as part of the string token, this is handled in lex_string() with a one-off loop that is not aware of extended characters. This patch fixes it by adding a new function scan_cur_identifier() that can be used to lex an identifier while in the middle of lexing another token. BTW, the other place that has been mis-lexing identifiers is lex_identifier_intern(), which is used to implement #pragma push_macro and #pragma pop_macro. This does not support extended characters either. I will add that in a subsequent patch, because it can't directly reuse the new function, but rather needs to lex from a string instead of a cpp_buffer. With scan_cur_identifier(), we do also correctly warn about bidi and normalization issues in the extended identifiers comprising the suffix. libcpp/ChangeLog: PR preprocessor/103902 * lex.cc (identifier_diagnostics_on_lex): New function refactoring some common code. (lex_identifier_intern): Use the new function. (lex_identifier): Don't run identifier diagnostics here, rather let the call site do it when needed. (_cpp_lex_direct): Adjust the call sites of lex_identifier () acccordingly. (struct scan_id_result): New struct. (scan_cur_identifier): New function. (create_literal2): New function. (lit_accum::create_literal2): New function. (is_macro): Folded into new function... (maybe_ignore_udl_macro_suffix): ...here. (is_macro_not_literal_suffix): Folded likewise. (lex_raw_string): Handle UTF-8 in UDL suffix via scan_cur_identifier (). (lex_string): Likewise. gcc/testsuite/ChangeLog: PR preprocessor/103902 * g++.dg/cpp0x/udlit-extended-id-1.C: New test. * g++.dg/cpp0x/udlit-extended-id-2.C: New test. * g++.dg/cpp0x/udlit-extended-id-3.C: New test. * g++.dg/cpp0x/udlit-extended-id-4.C: New test. --- gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C | 71 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C | 6 ++ gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C | 15 +++++ gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-4.C | 14 +++++ 4 files changed, 106 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-4.C (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C new file mode 100644 index 0000000..5ea5ef0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C @@ -0,0 +1,71 @@ +// { dg-do run { target c++11 } } +// { dg-additional-options "-Wno-error=normalized" } +#include +using namespace std; + +constexpr unsigned long long operator "" _π (unsigned long long x) +{ + return 3 * x; +} + +/* Historically we didn't parse properly as part of the "" token, so check that + as well. */ +constexpr unsigned long long operator ""_Π2 (unsigned long long x) +{ + return 4 * x; +} + +char x1[1_π]; +char x2[2_Π2]; + +static_assert (sizeof x1 == 3, "test1"); +static_assert (sizeof x2 == 8, "test2"); + +const char * operator "" _1σ (const char *s, unsigned long) +{ + return s + 1; +} + +const char * operator ""_Σ2 (const char *s, unsigned long) +{ + return s + 2; +} + +const char * operator "" _\U000000e61 (const char *s, unsigned long) +{ + return "ae"; +} + +const char* operator ""_\u01532 (const char *s, unsigned long) +{ + return "oe"; +} + +bool operator "" _\u0BC7\u0BBE (unsigned long long); // { dg-warning "not in NFC" } +bool operator ""_\u0B47\U00000B3E (unsigned long long); // { dg-warning "not in NFC" } + +#define xτy +const char * str = ""xτy; // { dg-warning "invalid suffix on literal" } + +int main() +{ + if (3_π != 9) + __builtin_abort (); + if (4_Π2 != 16) + __builtin_abort (); + if (strcmp ("abc"_1σ, "bc")) + __builtin_abort (); + if (strcmp ("abcd"_Σ2, "cd")) + __builtin_abort (); + if (strcmp (R"(abcdef)"_1σ, "bcdef")) + __builtin_abort (); + if (strcmp (R"(abc +def)"_1σ, "bc\ndef")) + __builtin_abort (); + if (strcmp (R"(abcdef)"_Σ2, "cdef")) + __builtin_abort (); + if (strcmp ("xyz"_æ1, "ae")) + __builtin_abort (); + if (strcmp ("xyz"_œ2, "oe")) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C new file mode 100644 index 0000000..05a2804 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C @@ -0,0 +1,6 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wbidi-chars=any,ucn" } +bool operator ""_d\u202ae\u202cf (unsigned long long); // { dg-line line1 } +// { dg-error "universal character \\\\u202a is not valid in an identifier" "test1" { target *-*-* } line1 } +// { dg-error "universal character \\\\u202c is not valid in an identifier" "test2" { target *-*-* } line1 } +// { dg-warning "found problematic Unicode character" "test3" { target *-*-* } line1 } diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C new file mode 100644 index 0000000..11292e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C @@ -0,0 +1,15 @@ +// { dg-do compile { target c++11 } } + +// Check that we do not look for poisoned identifier when it is a suffix. +int _ħ; +#pragma GCC poison _ħ +const char * operator ""_ħ (const char *, unsigned long); // { dg-bogus "poisoned" } +bool operator ""_ħ (unsigned long long x); // { dg-bogus "poisoned" } +bool b = 1_ħ; // { dg-bogus "poisoned" } +const char *x = "hbar"_ħ; // { dg-bogus "poisoned" } + +/* Ideally, we should not warn here either, but this is not implemented yet. This + syntax has been deprecated for C++23. */ +#pragma GCC poison _ħ2 +const char * operator "" _ħ2 (const char *, unsigned long); // { dg-bogus "poisoned" "" { xfail *-*-*} } +const char *x2 = "hbar2"_ħ2; // { dg-bogus "poisoned" } diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-4.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-4.C new file mode 100644 index 0000000..d1683c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-4.C @@ -0,0 +1,14 @@ +// { dg-options "-std=c++98 -Wc++11-compat" } +#define END ; +#define εND ; +#define EηD ; +#define EN\u0394 ; + +const char *s1 = "s1"END // { dg-warning "requires a space between string literal and macro" } +const char *s2 = "s2"εND // { dg-warning "requires a space between string literal and macro" } +const char *s3 = "s3"EηD // { dg-warning "requires a space between string literal and macro" } +const char *s4 = "s4"ENΔ // { dg-warning "requires a space between string literal and macro" } + +/* Make sure we did not skip the token also in the case that it wasn't found to + be a macro; compilation should fail here. */ +const char *s5 = "s5"NØT_A_MACRO; // { dg-error "expected ',' or ';' before" } -- cgit v1.1 From c5c7f1ef5ffcabb7dcbdc96571dbe1b0d675d4a5 Mon Sep 17 00:00:00 2001 From: Lehua Ding Date: Tue, 18 Jul 2023 15:34:40 +0800 Subject: RISC-V: Fix testcase failed when default -mcmodel=medany This patch fix testcase failed when I build RISC-V GCC with -mcmodel=medany as default. If set to medany, stack_save_restore.c testcase will fail because of the reduced use of s3 registers in assembly (thus calling __riscv_save/store_3 instead of __riscv_save/store_4). So relax assert from `__riscv_save/restore_4` to `__riscv_save/restore_(3|4)` to let this testcase not brittle on any -mcmodel and add another testcase that use -march=rv64imafc. gcc/testsuite/ChangeLog: * gcc.target/riscv/stack_save_restore.c: Moved to... * gcc.target/riscv/stack_save_restore_2.c: ...here. * gcc.target/riscv/stack_save_restore_1.c: New test. --- .../gcc.target/riscv/stack_save_restore.c | 40 ---------------------- .../gcc.target/riscv/stack_save_restore_1.c | 40 ++++++++++++++++++++++ .../gcc.target/riscv/stack_save_restore_2.c | 40 ++++++++++++++++++++++ 3 files changed, 80 insertions(+), 40 deletions(-) delete mode 100644 gcc/testsuite/gcc.target/riscv/stack_save_restore.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack_save_restore_1.c create mode 100644 gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/riscv/stack_save_restore.c b/gcc/testsuite/gcc.target/riscv/stack_save_restore.c deleted file mode 100644 index 522e706..0000000 --- a/gcc/testsuite/gcc.target/riscv/stack_save_restore.c +++ /dev/null @@ -1,40 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv32imafc -mabi=ilp32f -msave-restore -O2 -fno-schedule-insns -fno-schedule-insns2 -fno-unroll-loops -fno-peel-loops -fno-lto" } */ -/* { dg-final { check-function-bodies "**" "" } } */ - -char my_getchar(); -float getf(); - -/* -**bar: -** call t0,__riscv_save_4 -** addi sp,sp,-2032 -** ... -** li t0,-12288 -** add sp,sp,t0 -** ... -** li t0,12288 -** add sp,sp,t0 -** ... -** addi sp,sp,2032 -** tail __riscv_restore_4 -*/ -int bar() -{ - float volatile farray[3568]; - - float sum = 0; - float f1 = getf(); - float f2 = getf(); - float f3 = getf(); - float f4 = getf(); - - for (int i = 0; i < 3568; i++) - { - farray[i] = my_getchar() * 1.2; - sum += farray[i]; - } - - return sum + f1 + f2 + f3 + f4; -} - diff --git a/gcc/testsuite/gcc.target/riscv/stack_save_restore_1.c b/gcc/testsuite/gcc.target/riscv/stack_save_restore_1.c new file mode 100644 index 0000000..255ce5f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack_save_restore_1.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64imafc -mabi=lp64f -msave-restore -O2 -fno-schedule-insns -fno-schedule-insns2 -fno-unroll-loops -fno-peel-loops -fno-lto" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +char my_getchar(); +float getf(); + +/* +** bar: +** call t0,__riscv_save_(3|4) +** addi sp,sp,-2032 +** ... +** li t0,-12288 +** add sp,sp,t0 +** ... +** li t0,12288 +** add sp,sp,t0 +** ... +** addi sp,sp,2032 +** tail __riscv_restore_(3|4) +*/ +int bar() +{ + float volatile farray[3568]; + + float sum = 0; + float f1 = getf(); + float f2 = getf(); + float f3 = getf(); + float f4 = getf(); + + for (int i = 0; i < 3568; i++) + { + farray[i] = my_getchar() * 1.2; + sum += farray[i]; + } + + return sum + f1 + f2 + f3 + f4; +} + diff --git a/gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c b/gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c new file mode 100644 index 0000000..4ce5e01 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack_save_restore_2.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32imafc -mabi=ilp32f -msave-restore -O2 -fno-schedule-insns -fno-schedule-insns2 -fno-unroll-loops -fno-peel-loops -fno-lto" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +char my_getchar(); +float getf(); + +/* +** bar: +** call t0,__riscv_save_(3|4) +** addi sp,sp,-2032 +** ... +** li t0,-12288 +** add sp,sp,t0 +** ... +** li t0,12288 +** add sp,sp,t0 +** ... +** addi sp,sp,2032 +** tail __riscv_restore_(3|4) +*/ +int bar() +{ + float volatile farray[3568]; + + float sum = 0; + float f1 = getf(); + float f2 = getf(); + float f3 = getf(); + float f4 = getf(); + + for (int i = 0; i < 3568; i++) + { + farray[i] = my_getchar() * 1.2; + sum += farray[i]; + } + + return sum + f1 + f2 + f3 + f4; +} + -- cgit v1.1 From fba96fd1b94bc9cd35302611be3ace0e21c97d6c Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 19 Jul 2023 10:11:11 +0200 Subject: x86: slightly enhance "vec_dupv2df" Introduce a new alternative permitting all 32 registers to be used as source without AVX512VL, by broadcasting to the full 512 bits in that case. (The insn would also permit all registers to be used as destination, but V2DFmode doesn't.) gcc/ * config/i386/sse.md (vec_dupv2df): Add new AVX512F alternative. Move AVX512VL part of condition to new "enabled" attribute. --- gcc/config/i386/sse.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 2d81347..35fd66e 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -13784,18 +13784,27 @@ (set_attr "mode" "DF,DF,V1DF,V1DF,V1DF,V2DF,V1DF,V1DF,V1DF")]) (define_insn "vec_dupv2df" - [(set (match_operand:V2DF 0 "register_operand" "=x,x,v") + [(set (match_operand:V2DF 0 "register_operand" "=x,x,v,v") (vec_duplicate:V2DF - (match_operand:DF 1 "nonimmediate_operand" " 0,xm,vm")))] - "TARGET_SSE2 && " + (match_operand:DF 1 "nonimmediate_operand" "0,xm,vm,vm")))] + "TARGET_SSE2" "@ unpcklpd\t%0, %0 %vmovddup\t{%1, %0|%0, %1} - vmovddup\t{%1, %0|%0, %1}" - [(set_attr "isa" "noavx,sse3,avx512vl") - (set_attr "type" "sselog1") - (set_attr "prefix" "orig,maybe_vex,evex") - (set_attr "mode" "V2DF,DF,DF")]) + vmovddup\t{%1, %0|%0, %1} + vbroadcastsd\t{%1, }%g0{|, %1}" + [(set_attr "isa" "noavx,sse3,avx512vl,*") + (set_attr "type" "sselog1,ssemov,ssemov,ssemov") + (set_attr "prefix" "orig,maybe_vex,evex,evex") + (set_attr "mode" "V2DF,DF,DF,V8DF") + (set (attr "enabled") + (cond [(eq_attr "alternative" "3") + (symbol_ref "TARGET_AVX512F && !TARGET_AVX512VL + && !TARGET_PREFER_AVX256") + (match_test "") + (const_string "*") + ] + (symbol_ref "false")))]) (define_insn "vec_concatv2df" [(set (match_operand:V2DF 0 "register_operand" "=x,x,v,x,x, v,x,x") -- cgit v1.1 From 96799fa4d9d4abeb1322f907331258acc4266091 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 19 Jul 2023 10:11:49 +0200 Subject: x86: avoid maybe_gen_...() In the (however unlikely) event that no insn can be found for the requested mode, using maybe_gen_...() without (really) checking its result for being a null rtx would lead to silent bad code generation. gcc/ * config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate): Use gen_vec_set_0. (ix86_expand_vector_extract): Use gen_vec_extract_lo / gen_vec_extract_hi. (expand_vec_perm_broadcast_1): Use gen_vec_interleave_high / gen_vec_interleave_low. Rename local variable. --- gcc/config/i386/i386-expand.cc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 7e94447..a82c2bd 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -15476,8 +15476,7 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, machine_mode mode, { tmp1 = force_reg (GET_MODE_INNER (mode), val); tmp2 = gen_reg_rtx (mode); - emit_insn (maybe_gen_vec_set_0 (mode, tmp2, - CONST0_RTX (mode), tmp1)); + emit_insn (gen_vec_set_0 (mode, tmp2, CONST0_RTX (mode), tmp1)); tmp1 = gen_lowpart (mode, tmp2); } else @@ -17439,9 +17438,9 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt) ? gen_reg_rtx (V16HFmode) : gen_reg_rtx (V16BFmode)); if (elt < 16) - emit_insn (maybe_gen_vec_extract_lo (mode, tmp, vec)); + emit_insn (gen_vec_extract_lo (mode, tmp, vec)); else - emit_insn (maybe_gen_vec_extract_hi (mode, tmp, vec)); + emit_insn (gen_vec_extract_hi (mode, tmp, vec)); ix86_expand_vector_extract (false, target, tmp, elt & 15); return; } @@ -17455,9 +17454,9 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt) ? gen_reg_rtx (V8HFmode) : gen_reg_rtx (V8BFmode)); if (elt < 8) - emit_insn (maybe_gen_vec_extract_lo (mode, tmp, vec)); + emit_insn (gen_vec_extract_lo (mode, tmp, vec)); else - emit_insn (maybe_gen_vec_extract_hi (mode, tmp, vec)); + emit_insn (gen_vec_extract_hi (mode, tmp, vec)); ix86_expand_vector_extract (false, target, tmp, elt & 7); return; } @@ -22521,18 +22520,18 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d) if (d->testing_p) return true; - rtx (*maybe_gen) (machine_mode, int, rtx, rtx, rtx); + rtx (*gen_interleave) (machine_mode, int, rtx, rtx, rtx); if (elt >= nelt2) { - maybe_gen = maybe_gen_vec_interleave_high; + gen_interleave = gen_vec_interleave_high; elt -= nelt2; } else - maybe_gen = maybe_gen_vec_interleave_low; + gen_interleave = gen_vec_interleave_low; nelt2 /= 2; dest = gen_reg_rtx (vmode); - emit_insn (maybe_gen (vmode, 1, dest, op0, op0)); + emit_insn (gen_interleave (vmode, 1, dest, op0, op0)); vmode = V4SImode; op0 = gen_lowpart (vmode, dest); -- cgit v1.1 From c283c4774d1cbfd12c2a15b51b18347463694ad0 Mon Sep 17 00:00:00 2001 From: Lehua Ding Date: Thu, 13 Jul 2023 16:32:09 +0800 Subject: RISC-V: Throw compilation error for unknown extensions This tiny patch add a check for extension starts with 'z' or 's' in `-march` option. Currently this unknown extension will be passed to the assembler, which then reports an error. With this patch, the compiler will throw a compilation error if the extension starts with 'z' or 's' is not a standard sub-extension or supervisor extension. Along with two extra changes. The first is to reduce repeated errors, which are currently reported at least twice. The second is to report as many mistakes as possible. e.g.: Run `riscv64-unknown-elf-gcc -march=rv64gvcw_zvl128_s123_x123 -mabi=lp64d a.c` will throw these error: riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': ISA string is not in canonical order. 'c' riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 'w' is unsupported standard single letter extension riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 'zvl128' start with `z` but is unsupported standard extension riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 's123' start with `s` but is unsupported standard supervisor extension riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 'x123' start with `x` but is unsupported non-standard extension gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_supported_std_ext): Init. (standard_extensions_p): Add check. (riscv_subset_list::add): Just return NULL if it failed before. (riscv_subset_list::parse_std_ext): Continue parse when find a error (riscv_subset_list::parse): Just return NULL if it failed before. * config/riscv/riscv-subset.h (class riscv_subset_list): Add field. gcc/testsuite/ChangeLog: * gcc.target/riscv/arch-2.c: Update -march. * gcc.target/riscv/arch-3.c: Ditto. * gcc.target/riscv/arch-5.c: Ditto. * gcc.target/riscv/arch-8.c: Ditto. * gcc.target/riscv/attribute-10.c: Ditto. * gcc.target/riscv/attribute-18.c: Ditto. * gcc.target/riscv/attribute-19.c: Ditto. * gcc.target/riscv/attribute-8.c: Ditto. * gcc.target/riscv/attribute-9.c: Ditto. * gcc.target/riscv/pr102957.c: Ditto. * gcc.target/riscv/arch-22.cc: New test. --- gcc/common/config/riscv/riscv-common.cc | 68 ++++++++++++++++++++++----- gcc/config/riscv/riscv-subset.h | 5 ++ gcc/testsuite/gcc.target/riscv/arch-2.c | 2 +- gcc/testsuite/gcc.target/riscv/arch-22.cc | 11 +++++ gcc/testsuite/gcc.target/riscv/arch-23.c | 11 +++++ gcc/testsuite/gcc.target/riscv/arch-3.c | 2 +- gcc/testsuite/gcc.target/riscv/arch-5.c | 2 +- gcc/testsuite/gcc.target/riscv/arch-8.c | 2 +- gcc/testsuite/gcc.target/riscv/attribute-10.c | 2 +- gcc/testsuite/gcc.target/riscv/attribute-18.c | 4 +- gcc/testsuite/gcc.target/riscv/attribute-19.c | 4 +- gcc/testsuite/gcc.target/riscv/attribute-8.c | 4 +- gcc/testsuite/gcc.target/riscv/attribute-9.c | 4 +- gcc/testsuite/gcc.target/riscv/pr102957.c | 2 + 14 files changed, 98 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/arch-22.cc create mode 100644 gcc/testsuite/gcc.target/riscv/arch-23.c (limited to 'gcc') diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 19075c0..884d81c 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -313,6 +313,8 @@ static const char *riscv_tunes[] = static const char *riscv_supported_std_ext (void); +bool riscv_subset_list::parse_failed = false; + static riscv_subset_list *current_subset_list = NULL; const riscv_subset_list *riscv_current_subset_list () @@ -520,6 +522,18 @@ subset_cmp (const std::string &a, const std::string &b) } } +/* Return true if EXT is a standard extension. */ + +static bool +standard_extensions_p (const char *ext) +{ + const riscv_ext_version *ext_ver; + for (ext_ver = &riscv_ext_version_table[0]; ext_ver->name != NULL; ++ext_ver) + if (strcmp (ext, ext_ver->name) == 0) + return true; + return false; +} + /* Add new subset to list. */ void @@ -548,6 +562,38 @@ riscv_subset_list::add (const char *subset, int major_version, return; } + else if (strlen (subset) == 1 && !standard_extensions_p (subset)) + { + error_at (m_loc, + "%<-march=%s%>: extension %qs is unsupported standard single " + "letter extension", + m_arch, subset); + return; + } + else if (subset[0] == 'z' && !standard_extensions_p (subset)) + { + error_at (m_loc, + "%<-march=%s%>: extension %qs starts with `z` but is " + "unsupported standard extension", + m_arch, subset); + return; + } + else if (subset[0] == 's' && !standard_extensions_p (subset)) + { + error_at (m_loc, + "%<-march=%s%>: extension %qs starts with `s` but is " + "unsupported standard supervisor extension", + m_arch, subset); + return; + } + else if (subset[0] == 'x' && !standard_extensions_p (subset)) + { + error_at (m_loc, + "%<-march=%s%>: extension %qs starts with `x` but is " + "unsupported non-standard extension", + m_arch, subset); + return; + } riscv_subset_t *s = new riscv_subset_t (); riscv_subset_t *itr; @@ -921,22 +967,16 @@ riscv_subset_list::parse_std_ext (const char *p) while (*std_exts && std_ext != *std_exts) std_exts++; - if (std_ext != *std_exts) - { - if (strchr (all_std_exts, std_ext) == NULL) - error_at (m_loc, "%<-march=%s%>: unsupported ISA subset %<%c%>", - m_arch, *p); - else - error_at (m_loc, - "%<-march=%s%>: ISA string is not in canonical order. " - "%<%c%>", m_arch, *p); - return NULL; - } + subset[0] = std_ext; + if (std_ext != *std_exts && standard_extensions_p (subset)) + error_at (m_loc, + "%<-march=%s%>: ISA string is not in canonical order. " + "%<%c%>", + m_arch, *p); std_exts++; p++; - subset[0] = std_ext; p = parsing_subset_version (subset, p, &major_version, &minor_version, /* std_ext_p= */ true, &explicit_version_p); @@ -1165,6 +1205,9 @@ riscv_subset_list::parse_multiletter_ext (const char *p, riscv_subset_list * riscv_subset_list::parse (const char *arch, location_t loc) { + if (riscv_subset_list::parse_failed) + return NULL; + riscv_subset_list *subset_list = new riscv_subset_list (arch, loc); riscv_subset_t *itr; const char *p = arch; @@ -1234,6 +1277,7 @@ riscv_subset_list::parse (const char *arch, location_t loc) fail: delete subset_list; + riscv_subset_list::parse_failed = true; return NULL; } diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h index 84a7a82..dca0728 100644 --- a/gcc/config/riscv/riscv-subset.h +++ b/gcc/config/riscv/riscv-subset.h @@ -41,6 +41,11 @@ struct riscv_subset_t /* Subset list. */ class riscv_subset_list { +public: + /* Because the parse method is called in several places, to prevent repeated + errors, use this flag to prevent it from repeating parse. */ + static bool parse_failed; + private: /* Original arch string. */ const char *m_arch; diff --git a/gcc/testsuite/gcc.target/riscv/arch-2.c b/gcc/testsuite/gcc.target/riscv/arch-2.c index 8908b4b..e308bf7 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-2.c +++ b/gcc/testsuite/gcc.target/riscv/arch-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32ixabc_xfoo -mabi=ilp32" } */ +/* { dg-options "-march=rv32ixtheadba_xtheadsync -mabi=ilp32" } */ int foo() { } diff --git a/gcc/testsuite/gcc.target/riscv/arch-22.cc b/gcc/testsuite/gcc.target/riscv/arch-22.cc new file mode 100644 index 0000000..1cb5588 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-22.cc @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gvcw_zvl128_s123_x123 -mabi=lp64d" } */ +int foo() +{ +} + +/* { dg-error "ISA string is not in canonical order. 'c'" "" { target *-*-* } 0 } */ +/* { dg-error "extension 'w' is unsupported standard single letter extension" "" { target *-*-* } 0 } */ +/* { dg-error "extension 'zvl' starts with `z` but is unsupported standard extension" "" { target *-*-* } 0 } */ +/* { dg-error "extension 's123' starts with `s` but is unsupported standard supervisor extension" "" { target *-*-* } 0 } */ +/* { dg-error "extension 'x123' starts with `x` but is unsupported non-standard extension" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-23.c b/gcc/testsuite/gcc.target/riscv/arch-23.c new file mode 100644 index 0000000..1cb5588 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-23.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gvcw_zvl128_s123_x123 -mabi=lp64d" } */ +int foo() +{ +} + +/* { dg-error "ISA string is not in canonical order. 'c'" "" { target *-*-* } 0 } */ +/* { dg-error "extension 'w' is unsupported standard single letter extension" "" { target *-*-* } 0 } */ +/* { dg-error "extension 'zvl' starts with `z` but is unsupported standard extension" "" { target *-*-* } 0 } */ +/* { dg-error "extension 's123' starts with `s` but is unsupported standard supervisor extension" "" { target *-*-* } 0 } */ +/* { dg-error "extension 'x123' starts with `x` but is unsupported non-standard extension" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-3.c b/gcc/testsuite/gcc.target/riscv/arch-3.c index 7aa945e..ac73374 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-3.c +++ b/gcc/testsuite/gcc.target/riscv/arch-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32isabc_xbar -mabi=ilp32" } */ +/* { dg-options "-march=rv32isvinval_xtheadba -mabi=ilp32" } */ int foo() { } diff --git a/gcc/testsuite/gcc.target/riscv/arch-5.c b/gcc/testsuite/gcc.target/riscv/arch-5.c index 8258552..b8b6cd0 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-5.c +++ b/gcc/testsuite/gcc.target/riscv/arch-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32i_zfoo_sabc_xbar -mabi=ilp32" } */ +/* { dg-options "-march=rv32i_zmmul_svnapot_xtheadba -mabi=ilp32" } */ int foo() { } diff --git a/gcc/testsuite/gcc.target/riscv/arch-8.c b/gcc/testsuite/gcc.target/riscv/arch-8.c index 1b9e51b..ef557ae 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-8.c +++ b/gcc/testsuite/gcc.target/riscv/arch-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32id_zicsr_zifence -mabi=ilp32" } */ +/* { dg-options "-march=rv32id_zicsr_zifencei -mabi=ilp32" } */ int foo() { } diff --git a/gcc/testsuite/gcc.target/riscv/attribute-10.c b/gcc/testsuite/gcc.target/riscv/attribute-10.c index 1e121a1..868adef 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-10.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32i -march=rv32im_sx_unexpectedstring -mabi=ilp32" } */ +/* { dg-options "-march=rv32i -march=rv32im_svnapot_unexpectedstring -mabi=ilp32" } */ int foo() { } diff --git a/gcc/testsuite/gcc.target/riscv/attribute-18.c b/gcc/testsuite/gcc.target/riscv/attribute-18.c index 492360c..fddbf15 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-18.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-18.c @@ -1,4 +1,4 @@ /* { dg-do compile } */ -/* { dg-options "-mriscv-attribute -march=rv64imafdcp -mabi=lp64d -misa-spec=2.2" } */ +/* { dg-options "-mriscv-attribute -march=rv64imafdc -mabi=lp64d -misa-spec=2.2" } */ int foo() {} -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0_p\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-19.c b/gcc/testsuite/gcc.target/riscv/attribute-19.c index 562f808..8150452 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-19.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-19.c @@ -1,4 +1,4 @@ /* { dg-do compile } */ -/* { dg-options "-mriscv-attribute -march=rv64imp0p9 -mabi=lp64 -misa-spec=2.2" } */ +/* { dg-options "-mriscv-attribute -march=rv64im -mabi=lp64 -misa-spec=2.2" } */ int foo() {} -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p0_m2p0_p0p9\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p0_m2p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-8.c b/gcc/testsuite/gcc.target/riscv/attribute-8.c index 4c91b9e..2065f74 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-8.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-8.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-mriscv-attribute -march=rv32i2p0xabc_xv5 -mabi=ilp32" } */ +/* { dg-options "-mriscv-attribute -march=rv32i2p0xtheadba_xtheadbb -mabi=ilp32" } */ int foo() { } -/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_xabc_xv5p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_xtheadba1p0_xtheadbb1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-9.c b/gcc/testsuite/gcc.target/riscv/attribute-9.c index 7e3741a..3c31848 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-9.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-9.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-mriscv-attribute -march=rv32i2p0sabc_xbar -mabi=ilp32e" } */ +/* { dg-options "-mriscv-attribute -march=rv32i2p0svinval_xtheadba -mabi=ilp32e" } */ int foo() { } -/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_sabc_xbar\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_svinval1p0_xtheadba1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr102957.c b/gcc/testsuite/gcc.target/riscv/pr102957.c index 9747dde..322d49c 100644 --- a/gcc/testsuite/gcc.target/riscv/pr102957.c +++ b/gcc/testsuite/gcc.target/riscv/pr102957.c @@ -3,3 +3,5 @@ int foo() { } + +/* { dg-error "extension 'zb' starts with `z` but is unsupported standard extension" "" { target *-*-* } 0 } */ -- cgit v1.1 From 85da0b40538fb0d17d89de1e7905984668e3dfef Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Wed, 19 Jul 2023 10:18:49 +0200 Subject: OpenMP/Fortran: Non-rectangular loops with constant steps other than 1 or -1 [PR107424] Before this commit, gfortran produced with OpenMP for 'do i = 1,10,2' the code for (count.0 = 0; count.0 < 5; count.0 = count.0 + 1) i = count.0 * 2 + 1; While such an inner loop can be collapsed, a non-rectangular could not. With this commit and for all constant loop steps, a simple loop such as 'for (i = 1; i <= 10; i = i + 2)' is created. (Before only for the constant steps of 1 and -1.) The constant step permits to know the direction (increasing/decreasing) that is required for the loop condition. The new code is only valid if one assumes no overflow of the loop variable. However, the Fortran standard can be read that this must be ensured by the user. Namely, the Fortran standard requires (F2023, 10.1.5.2.4): "The execution of any numeric operation whose result is not defined by the arithmetic used by the processor is prohibited." And, for DO loops, F2023's "11.1.7.4.3 The execution cycle" has the following: The number of loop iterations handled by an iteration count, which would permit code like 'do i = huge(i)-5, huge(i),4'. However, in step (3), this count is not only decremented by one but also: "... The DO variable, if any, is incremented by the value of the incrementation parameter m3." And for the example above, 'i' would be 'huge(i)+3' in the last execution cycle, which exceeds the largest model number and should render the example as invalid. PR fortran/107424 gcc/fortran/ChangeLog: * trans-openmp.cc (gfc_nonrect_loop_expr): Accept all constant loop steps. (gfc_trans_omp_do): Likewise; use sign to determine loop direction. libgomp/ChangeLog: * libgomp.texi (Impl. Status 5.0): Add link to new PR110735. * testsuite/libgomp.fortran/non-rectangular-loop-1.f90: Enable commented tests. * testsuite/libgomp.fortran/non-rectangular-loop-1a.f90: Remove test file; tests are in non-rectangular-loop-1.f90. * testsuite/libgomp.fortran/non-rectangular-loop-5.f90: Change testcase to use a non-constant step to retain the 'sorry' test. * testsuite/libgomp.fortran/non-rectangular-loop-6.f90: New test. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/linear-2.f90: Update dump to remove the additional count variable. --- gcc/fortran/trans-openmp.cc | 18 ++++++++---------- gcc/testsuite/gfortran.dg/gomp/linear-2.f90 | 4 ++-- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index c88ee3c..cf741ce 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -5374,10 +5374,10 @@ gfc_nonrect_loop_expr (stmtblock_t *pblock, gfc_se *sep, int loop_n, if (!simple) { - /* FIXME: Handle non-unit iter steps, cf. PR fortran/107424. */ + /* FIXME: Handle non-const iter steps, cf. PR fortran/110735. */ sorry_at (gfc_get_location (&curr_loop_var->where), - "non-rectangular loop nest with step other than constant 1 " - "or -1 for %qs", curr_loop_var->symtree->n.sym->name); + "non-rectangular loop nest with non-constant step for %qs", + curr_loop_var->symtree->n.sym->name); return false; } @@ -5394,10 +5394,10 @@ gfc_nonrect_loop_expr (stmtblock_t *pblock, gfc_se *sep, int loop_n, } else { - /* FIXME: Handle non-unit iter steps, cf. PR fortran/107424. */ + /* FIXME: Handle non-const iter steps, cf. PR fortran/110735. */ sorry_at (gfc_get_location (&code->loc), - "non-rectangular loop nest with step other than constant " - "1 or -1 for %qs", var->name); + "non-rectangular loop nest with non-constant step " + "for %qs", var->name); inform (gfc_get_location (&expr->where), "Used here"); return false; } @@ -5578,10 +5578,8 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, gfc_add_block_to_block (pblock, &se.pre); step = gfc_evaluate_now (se.expr, pblock); - if (integer_onep (step)) - simple = 1; - else if (tree_int_cst_equal (step, integer_minus_one_node)) - simple = -1; + if (TREE_CODE (step) == INTEGER_CST) + simple = tree_int_cst_sgn (step); gfc_init_se (&se, NULL); if (!clauses->non_rectangular diff --git a/gcc/testsuite/gfortran.dg/gomp/linear-2.f90 b/gcc/testsuite/gfortran.dg/gomp/linear-2.f90 index 05f007f..88df96e 100644 --- a/gcc/testsuite/gfortran.dg/gomp/linear-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/linear-2.f90 @@ -105,8 +105,8 @@ end module ! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 6 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp for linear\\(x:D\\.\[0-9\]+\\) nowait" 1 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp for linear\\(x:val,step\\(D\\.\[0-9\]+\\)\\) nowait" 1 "original" } } -! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(count\\.\[0-9\]:1\\) linear\\(i:3\\)" 2 "original" } } -! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(count\\.\[0-9\]:1\\) linear\\(i:val,step\\(3\\)\\)" 2 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:3\\)" 2 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:val,step\\(3\\)\\)" 2 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) linear\\(x:D\\.\[0-9\]+\\)" 2 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) linear\\(x:val,step\\(D\\.\[0-9\]+\\)\\)" 2 "original" } } ! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:D\\.\[0-9\]+\\)" 2 "original" } } -- cgit v1.1 From c1e420549f2305efb70ed37e693d380724eb7540 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 19 Jul 2023 11:59:29 +0100 Subject: testsuite: Add 64-bit vector variant for bb-slp-pr95839.c Add dual-single float vector test complementing bb-slp-pr95839.c. gcc/testsuite/ * gcc.dg/vect/bb-slp-pr95839-v8.c: New test. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c new file mode 100644 index 0000000..9a02107 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-additional-options "-w -Wno-psabi" } */ + +typedef float __attribute__((vector_size(8))) v2f32; + +v2f32 f(v2f32 a, v2f32 b) +{ + /* Check that we vectorize this CTOR without any loads. */ + return (v2f32){a[0] + b[0], a[1] + b[1]}; +} + +/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */ -- cgit v1.1 From ece799607c841676f4e00c2fea98bbec6976da3f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 19 Jul 2023 13:48:53 +0200 Subject: wide-int: Fix up wi::divmod_internal [PR110731] As the following testcase shows, wi::divmod_internal doesn't handle correctly signed division with precision > 64 when the dividend (and likely divisor as well) is the type's minimum and the precision isn't divisible by 64. A few lines above what the patch hunk changes is: /* Make the divisor and dividend positive and remember what we did. */ if (sgn == SIGNED) { if (wi::neg_p (dividend)) { neg_dividend = -dividend; dividend = neg_dividend; dividend_neg = true; } if (wi::neg_p (divisor)) { neg_divisor = -divisor; divisor = neg_divisor; divisor_neg = true; } } i.e. we negate negative dividend or divisor and remember those. But, after we do that, when unpacking those values into b_dividend and b_divisor we need to always treat the wide_ints as UNSIGNED, because divmod_internal_2 performs an unsigned division only. Now, if precision <= 64, we don't reach here at all, earlier code handles it. If dividend or divisor aren't the most negative values, the negation clears their most significant bit, so it doesn't really matter if we unpack SIGNED or UNSIGNED. And if precision is multiple of HOST_BITS_PER_WIDE_INT, there is no difference in behavior, while -0x80000000000000000000000000000000 negates to -0x80000000000000000000000000000000 the unpacking of it as SIGNED or UNSIGNED works the same. In the testcase, we have signed precision 119 and the dividend is val = { 0, 0xffc0000000000000 }, len = 2, precision = 119 both before and after negation. Divisor is val = { 2 }, len = 1, precision = 119 But we really want to divide 0x400000000000000000000000000000 by 2 unsigned and then negate at the end. If it is unsigned precision 119 division 0x400000000000000000000000000000 by 2 dividend is val = { 0, 0xffc0000000000000 }, len = 2, precision = 119 but as we unpack it UNSIGNED, it is unpacked into 0, 0, 0, 0x00400000 The following patch fixes it by always using UNSIGNED unpacking because we've already negated negative values at that point if sgn == SIGNED and so most negative constants should be treated as positive. 2023-07-19 Jakub Jelinek PR tree-optimization/110731 * wide-int.cc (wi::divmod_internal): Always unpack dividend and divisor as UNSIGNED regardless of sgn. * gcc.dg/pr110731.c: New test. --- gcc/testsuite/gcc.dg/pr110731.c | 17 +++++++++++++++++ gcc/wide-int.cc | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr110731.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/pr110731.c b/gcc/testsuite/gcc.dg/pr110731.c new file mode 100644 index 0000000..7da905d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110731.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/110731 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O2" } */ + +__int128 +foo (void) +{ + struct S { __int128 f : 119; } s = { ((__int128) -18014398509481984) << 64 }; + return s.f / 2; +} + +int +main () +{ + if (foo () != (((__int128) -9007199254740992) << 64)) + __builtin_abort (); +} diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc index c6a9e2d..81b7be8 100644 --- a/gcc/wide-int.cc +++ b/gcc/wide-int.cc @@ -1911,9 +1911,9 @@ wi::divmod_internal (HOST_WIDE_INT *quotient, unsigned int *remainder_len, } wi_unpack (b_dividend, dividend.get_val (), dividend.get_len (), - dividend_blocks_needed, dividend_prec, sgn); + dividend_blocks_needed, dividend_prec, UNSIGNED); wi_unpack (b_divisor, divisor.get_val (), divisor.get_len (), - divisor_blocks_needed, divisor_prec, sgn); + divisor_blocks_needed, divisor_prec, UNSIGNED); m = dividend_blocks_needed; b_dividend[m] = 0; -- cgit v1.1 From fcb38196423cd5f99a7ee44c882751b3dd37618d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 19 Jul 2023 13:51:44 +0200 Subject: tree-switch-conversion: Fix a comment typo I've noticed a comment typo, this patch fixes that. 2023-07-19 Jakub Jelinek * tree-switch-conversion.h (class bit_test_cluster): Fix comment typo. --- gcc/tree-switch-conversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/tree-switch-conversion.h b/gcc/tree-switch-conversion.h index 4e97164..a8a564a 100644 --- a/gcc/tree-switch-conversion.h +++ b/gcc/tree-switch-conversion.h @@ -303,7 +303,7 @@ public: /* A GIMPLE switch statement can be expanded to a short sequence of bit-wise comparisons. "switch(x)" is converted into "if ((1 << (x-MINVAL)) & CST)" where CST and MINVAL are integer constants. This is better than a series -of compare-and-banch insns in some cases, e.g. we can implement: +of compare-and-branch insns in some cases, e.g. we can implement: if ((x==4) || (x==6) || (x==9) || (x==11)) -- cgit v1.1 From e029635cb72e6db72f1826b6b43fa4b299b2145f Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Wed, 19 Jul 2023 13:38:07 +0100 Subject: [modula2] Variable analysis understands DISPOSE and NIL This patch allows the uninitialized variable analysis to detect pointer through NIL and incorrectly reusing a pointer after a call to DISPOSE. gcc/m2/ChangeLog: * gm2-compiler/M2Quads.mod (BuildRealFuncProcCall): Set the trash parameter value to NIL if DEALLOCATE is detected. * gm2-compiler/M2SymInit.mod (CheckDeferredRecordAccess): Pass tok to SetVarInitialized. Pass tok to GetVarComponentInitialized. (ComponentFindVar): Add tok parameter. Check aliased pointer against Nil and generate warning if necessary. (deRefComponent): Add tok and sym parameters and pass them to getContent. (SetVarComponentInitialized): Add tok parameter. Pass tok to ComponentFindVar. Pass tok and sym to deRefComponent. (GetVarComponentInitialized): Add tok parameter. Pass tok to ComponentFindVar. Pass tok to deRefComponent. (SetVarInitialized): Add tok parameter. Pass tok to SetVarComponentInitialized. (doGetVarInitialized): Add tok parameter. Pass tok to GetVarComponentInitialized. (CheckXIndr): Pass lhs and lhstok to getContent. (CheckIndrX): Pass rhs and rhstok to getContent. (CheckBecomes): Pass destok to ComponentFindVar. Pass des and destok to deRefComponent. (CheckAddr): Pass contenttok to GetVarInitialized. Pass ptrtok to SetVarInitialized. (CheckReadBeforeInitQuad): Pass op1tok to SetVarInitialized for op1 cases and op3tok for op3 cases. (trashParam): Get operand tokens. Pass op3tok to SetVarInitialized. Pass op3 and op3tok to getContent. Alias ptr to NIL if procedure is DEALLOCATE. Pass op3tok to SetVarInitialized. (IsDeallocate): New procedure function. (DetectTrash): Use IsDeallocate. (SetupLAlias): Allow exp to be Nil. (getContent): Generate warning message if ptr is Nil. gcc/testsuite/ChangeLog: * gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod: New test. Signed-off-by: Gaius Mulley --- gcc/m2/gm2-compiler/M2Quads.mod | 12 +- gcc/m2/gm2-compiler/M2SymInit.mod | 145 +++++++++++++-------- .../procedures/fail/testdispose.mod | 24 ++++ .../procedures/fail/testdispose2.mod | 24 ++++ .../procedures/fail/testnil.mod | 17 +++ 5 files changed, 163 insertions(+), 59 deletions(-) create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod (limited to 'gcc') diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod index db5513d..3e4863b 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -5269,9 +5269,15 @@ BEGIN THEN GenQuadO (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE) ELSE - trash := MakeTemporary (paramtok, RightValue) ; - PutVar (trash, ParamType) ; - PutVarHeap (trash, TRUE) ; + IF AllocateProc + THEN + trash := MakeTemporary (paramtok, RightValue) ; + PutVar (trash, ParamType) ; + PutVarHeap (trash, TRUE) + ELSE + Assert (DeallocateProc) ; + trash := Nil + END ; GenQuadOTrash (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE, trash) END ELSE diff --git a/gcc/m2/gm2-compiler/M2SymInit.mod b/gcc/m2/gm2-compiler/M2SymInit.mod index f617c40..b7978e5 100644 --- a/gcc/m2/gm2-compiler/M2SymInit.mod +++ b/gcc/m2/gm2-compiler/M2SymInit.mod @@ -26,6 +26,7 @@ FROM M2Debug IMPORT Assert ; FROM M2Printf IMPORT printf0, printf1, printf2, printf3, printf4 ; FROM libc IMPORT printf ; FROM NameKey IMPORT Name, NulName, KeyToCharStar, MakeKey ; +FROM M2Base IMPORT Nil ; FROM M2Options IMPORT UninitVariableChecking, UninitVariableConditionalChecking, CompilerDebugging ; @@ -693,11 +694,11 @@ BEGIN (* SetVarInitialized (sym, TRUE) *) ELSIF IsUnbounded (GetSType (sym)) THEN - SetVarInitialized (sym, TRUE) + SetVarInitialized (sym, TRUE, tok) ELSIF IsComponent (sym) THEN Trace ("checkReadInit IsComponent (%d) is true)", sym) ; - IF (NOT GetVarComponentInitialized (sym)) AND IsUniqueWarning (tok) + IF (NOT GetVarComponentInitialized (sym, tok)) AND IsUniqueWarning (tok) THEN GenerateNoteFlow (lst, i, warning) ; IssueWarning (tok, @@ -766,7 +767,9 @@ END SetVarUninitialized ; ComponentFindVar - *) -PROCEDURE ComponentFindVar (sym: CARDINAL; VAR lvalue: BOOLEAN) : CARDINAL ; +PROCEDURE ComponentFindVar (sym: CARDINAL; + VAR lvalue: BOOLEAN; + tok: CARDINAL) : CARDINAL ; VAR nsym, i : CARDINAL ; @@ -776,11 +779,17 @@ BEGIN nsym := GetNth (sym, i) ; lvalue := GetMode (nsym) = LeftValue ; nsym := getLAlias (nsym) ; - IF (nsym # NulSym) AND IsVar (nsym) + IF nsym = Nil + THEN + MetaErrorT1 (tok, + "attempting to dereference {%1Wad} which will be a {%kNIL} pointer", + sym) ; + RETURN NulSym + ELSIF (nsym # NulSym) AND IsVar (nsym) THEN IF (nsym # sym) AND IsComponent (nsym) THEN - RETURN ComponentFindVar (nsym, lvalue) + RETURN ComponentFindVar (nsym, lvalue, tok) ELSE RETURN nsym END @@ -846,11 +855,12 @@ END ComponentBuildFieldList ; deRefComponent - *) -PROCEDURE deRefComponent (component: CARDINAL; lvalue: BOOLEAN) : CARDINAL ; +PROCEDURE deRefComponent (component: CARDINAL; lvalue: BOOLEAN; + sym: CARDINAL; tok: CARDINAL) : CARDINAL ; BEGIN IF lvalue THEN - RETURN getContent (component) + RETURN getContent (component, sym, tok) ELSE RETURN component END @@ -861,7 +871,7 @@ END deRefComponent ; SetVarComponentInitialized - *) -PROCEDURE SetVarComponentInitialized (sym: CARDINAL) ; +PROCEDURE SetVarComponentInitialized (sym: CARDINAL; tok: CARDINAL) ; VAR lvalue: BOOLEAN ; i, n, @@ -869,8 +879,8 @@ VAR vsym : CARDINAL ; lst : List ; BEGIN - vsym := ComponentFindVar (sym, lvalue) ; - vsym := deRefComponent (vsym, lvalue) ; + vsym := ComponentFindVar (sym, lvalue, tok) ; + vsym := deRefComponent (vsym, lvalue, sym, tok) ; IF vsym # NulSym THEN IF Debugging @@ -911,7 +921,7 @@ END SetVarComponentInitialized ; GetVarComponentInitialized - *) -PROCEDURE GetVarComponentInitialized (sym: CARDINAL) : BOOLEAN ; +PROCEDURE GetVarComponentInitialized (sym: CARDINAL; tok: CARDINAL) : BOOLEAN ; VAR lvalue, init : BOOLEAN ; @@ -919,13 +929,13 @@ VAR vsym : CARDINAL ; lst : List ; BEGIN - component := ComponentFindVar (sym, lvalue) ; + component := ComponentFindVar (sym, lvalue, tok) ; IF IsItemInList (ignoreList, component) OR IsExempt (component) THEN RETURN TRUE ELSE init := FALSE ; - vsym := deRefComponent (component, lvalue) ; + vsym := deRefComponent (component, lvalue, sym, tok) ; IF vsym # NulSym THEN IF IsExempt (vsym) @@ -963,7 +973,8 @@ END Trace ; then set the left and right initialization state. *) -PROCEDURE SetVarInitialized (sym: CARDINAL; canDereference: BOOLEAN) ; +PROCEDURE SetVarInitialized (sym: CARDINAL; canDereference: BOOLEAN; + tok: CARDINAL) ; BEGIN IF IsVar (sym) THEN @@ -971,7 +982,7 @@ BEGIN IF IsComponent (sym) THEN Trace ("SetVarInitialized sym %d is a component and calling SetVarComponentInitialized", sym); - SetVarComponentInitialized (sym) + SetVarComponentInitialized (sym, tok) ELSIF (GetMode (sym) = LeftValue) AND canDereference THEN Trace ("SetVarInitialized sym %d is LeftValue and canDeference and calling PutVarInitialized LeftValue and RightValue", sym); @@ -993,7 +1004,7 @@ END SetVarInitialized ; doGetVarInitialized - *) -PROCEDURE doGetVarInitialized (sym: CARDINAL) : BOOLEAN ; +PROCEDURE doGetVarInitialized (sym: CARDINAL; tok: CARDINAL) : BOOLEAN ; BEGIN IF IsVar (sym) THEN @@ -1002,7 +1013,7 @@ BEGIN RETURN TRUE ELSIF IsComponent (sym) THEN - RETURN GetVarComponentInitialized (sym) + RETURN GetVarComponentInitialized (sym, tok) END ; RETURN VarCheckReadInit (sym, GetMode (sym)) END ; @@ -1014,11 +1025,11 @@ END doGetVarInitialized ; GetVarInitialized - *) -PROCEDURE GetVarInitialized (sym: CARDINAL) : BOOLEAN ; +PROCEDURE GetVarInitialized (sym: CARDINAL; tok: CARDINAL) : BOOLEAN ; VAR init: BOOLEAN ; BEGIN - init := doGetVarInitialized (sym) ; + init := doGetVarInitialized (sym, tok) ; IF Debugging THEN IF init @@ -1061,7 +1072,7 @@ PROCEDURE CheckBinary (procSym, BEGIN CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE, warning, lst, i) ; CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ; - SetVarInitialized (op1, FALSE) + SetVarInitialized (op1, FALSE, op1tok) END CheckBinary ; @@ -1075,7 +1086,7 @@ PROCEDURE CheckUnary (procSym, lst: List; i: CARDINAL) ; BEGIN CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, lst, i) ; - SetVarInitialized (lhs, FALSE) + SetVarInitialized (lhs, FALSE, lhstok) END CheckUnary ; @@ -1093,13 +1104,13 @@ BEGIN CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, bblst, i) ; CheckDeferredRecordAccess (procSym, lhstok, lhs, FALSE, warning, bblst, i) ; (* Now see if we know what lhs is pointing to and set fields if necessary. *) - vsym := getContent (getLAlias (lhs)) ; + vsym := getContent (getLAlias (lhs), lhs, lhstok) ; IF (vsym # NulSym) AND (vsym # lhs) AND (GetSType (vsym) = type) THEN IF IsRecord (type) THEN (* Set all fields of vsym as initialized. *) - SetVarInitialized (vsym, FALSE) + SetVarInitialized (vsym, FALSE, lhstok) ELSE (* Set only the field assigned in vsym as initialized. *) lst := ComponentCreateFieldList (rhs) ; @@ -1123,7 +1134,7 @@ VAR content: CARDINAL ; BEGIN CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, lst, i) ; - content := getContent (getLAlias (rhs)) ; + content := getContent (getLAlias (rhs), rhs, rhstok) ; IF content = NulSym THEN IncludeItemIntoList (ignoreList, lhs) @@ -1131,7 +1142,7 @@ BEGIN CheckDeferredRecordAccess (procSym, rhstok, content, TRUE, warning, lst, i) ; (* SetVarInitialized (lhs, IsVarAParam (rhs)) -- was -- *) (* SetVarInitialized (lhs, FALSE) -- was -- *) - SetVarInitialized (lhs, VarCheckReadInit (content, RightValue)) + SetVarInitialized (lhs, VarCheckReadInit (content, RightValue), lhstok) END END CheckIndrX ; @@ -1159,12 +1170,12 @@ VAR BEGIN CheckDeferredRecordAccess (procSym, exprtok, expr, FALSE, warning, bblst, i) ; SetupLAlias (des, expr) ; - SetVarInitialized (des, FALSE) ; + SetVarInitialized (des, FALSE, destok) ; (* Now see if we know what lhs is pointing to and set fields if necessary. *) IF IsComponent (des) THEN - vsym := ComponentFindVar (des, lvalue) ; - vsym := deRefComponent (vsym, lvalue) ; + vsym := ComponentFindVar (des, lvalue, destok) ; + vsym := deRefComponent (vsym, lvalue, des, destok) ; IF vsym # NulSym THEN (* Set only the field assigned in vsym as initialized. *) @@ -1196,7 +1207,7 @@ END CheckComparison ; PROCEDURE CheckAddr (procSym, ptrtok, ptr, contenttok, content: CARDINAL) ; BEGIN - SetVarInitialized (ptr, GetVarInitialized (content)) ; + SetVarInitialized (ptr, GetVarInitialized (content, contenttok), ptrtok) ; SetupIndr (ptr, content) END CheckAddr ; @@ -1281,19 +1292,19 @@ BEGIN FunctValueOp, StandardFunctionOp, HighOp, - SizeOp : SetVarInitialized (op1, FALSE) | + SizeOp : SetVarInitialized (op1, FALSE, op1tok) | AddrOp : CheckAddr (procSym, op1tok, op1, op3tok, op3) | - ReturnValueOp : SetVarInitialized (op1, FALSE) | + ReturnValueOp : SetVarInitialized (op1, FALSE, op1tok) | NewLocalVarOp : | ParamOp : CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE, warning, lst, i) ; CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ; IF (op1 > 0) AND (op1 <= NoOfParam (op2)) AND IsVarParam (op2, op1) THEN - SetVarInitialized (op3, TRUE) + SetVarInitialized (op3, TRUE, op3tok) END | ArrayOp : CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ; - SetVarInitialized (op1, TRUE) | + SetVarInitialized (op1, TRUE, op1tok) | RecordFieldOp : CheckRecordField (procSym, op1tok, op1, op2tok, op2) | LogicalShiftOp, LogicalRotateOp, @@ -1318,7 +1329,7 @@ BEGIN op1tok, op1, op2tok, op2, op3tok, op3, warning, lst, i) | XIndrOp : CheckXIndr (procSym, op1tok, op1, op2, op3tok, op3, warning, lst, i) | IndrXOp : CheckIndrX (procSym, op1tok, op1, op2, op3tok, op3, warning, lst, i) | - SaveExceptionOp : SetVarInitialized (op1, FALSE) | + SaveExceptionOp : SetVarInitialized (op1, FALSE, op1tok) | RestoreExceptionOp: CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE, warning, lst, i) | SubrangeLowOp, @@ -1516,13 +1527,16 @@ END DumpBBSequence ; PROCEDURE trashParam (trashQuad: CARDINAL) ; VAR - op : QuadOperator ; - op1, op2, op3: CARDINAL ; - heapSym, ptr : CARDINAL ; + op : QuadOperator ; + op1, op2, op3 : CARDINAL ; + op1tok, op2tok, op3tok, qtok: CARDINAL ; + overflowChecking : BOOLEAN ; + heapSym, ptr : CARDINAL ; BEGIN IF trashQuad # 0 THEN - GetQuad (trashQuad, op, op1, op2, op3) ; + GetQuadOtok (trashQuad, qtok, op, op1, op2, op3, overflowChecking, + op1tok, op2tok, op3tok) ; heapSym := GetQuadTrash (trashQuad) ; IF Debugging THEN @@ -1530,21 +1544,20 @@ BEGIN END ; IF heapSym # NulSym THEN - SetVarInitialized (op3, FALSE) ; - ptr := getContent (getLAlias (op3)) ; + SetVarInitialized (op3, FALSE, op3tok) ; + ptr := getContent (getLAlias (op3), op3, op3tok) ; IF ptr # NulSym THEN - SetupIndr (ptr, heapSym) ; - SetVarInitialized (ptr, FALSE) + IF IsDeallocate (op2) + THEN + (* SetupLAlias (ptr, heapSym) *) + (* SetupIndr (ptr, Nil) *) + SetupLAlias (ptr, Nil) + ELSE + SetupIndr (ptr, heapSym) + END ; + SetVarInitialized (ptr, FALSE, op3tok) END -(* - vsym := getLAlias (op3) ; - VarInitState (vsym) ; - VarInitState (heapSym) ; - PutVarInitialized (vsym, GetMode (vsym)) ; - PutVarInitialized (heapSym, LeftValue) ; - SetupLAlias (vsym, heapSym) -*) END END ; DumpAliases @@ -1789,6 +1802,16 @@ END IsAllocate ; (* + IsDeallocate - return TRUE is sym is DEALLOCATE. +*) + +PROCEDURE IsDeallocate (sym: CARDINAL) : BOOLEAN ; +BEGIN + RETURN IsProcedure (sym) AND (GetSymName (sym) = MakeKey('DEALLOCATE')) +END IsDeallocate ; + + +(* DetectTrash - *) @@ -1803,7 +1826,7 @@ BEGIN i := bbPtr^.start ; LOOP GetQuad (i, op, op1, op2, op3) ; - IF (op = ParamOp) AND (op1 = 1) AND IsAllocate (op2) + IF (op = ParamOp) AND (op1 = 1) AND (IsAllocate (op2) OR IsDeallocate (op2)) THEN bbPtr^.trashQuad := i END ; @@ -2078,8 +2101,9 @@ END getLAlias ; PROCEDURE SetupLAlias (des, exp: CARDINAL) ; BEGIN - IF IsVar (exp) AND - ((GetMode (des) = LeftValue) OR IsReallyPointer (GetSType (des))) + IF (exp = Nil) OR + (IsVar (exp) AND + ((GetMode (des) = LeftValue) OR IsReallyPointer (GetSType (des)))) THEN addAlias (LArray, des, exp) ; DumpAliases @@ -2098,12 +2122,21 @@ END SetupIndr ; (* - getContent - + getContent - attempts to return the content pointed to by ptr. + sym is the original symbol and ptr will be the equivalent lvalue. *) -PROCEDURE getContent (ptr: CARDINAL) : CARDINAL ; +PROCEDURE getContent (ptr: CARDINAL; sym: CARDINAL; tok: CARDINAL) : CARDINAL ; BEGIN - RETURN doGetAlias (IndirectArray, ptr) + IF ptr = Nil + THEN + MetaErrorT1 (tok, + "attempting to dereference {%1Wad} which will be a {%kNIL} pointer", + sym) ; + RETURN NulSym + ELSE + RETURN doGetAlias (IndirectArray, ptr) + END END getContent ; diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod new file mode 100644 index 0000000..366de7d --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod @@ -0,0 +1,24 @@ +MODULE testdispose ; + +FROM Storage IMPORT DEALLOCATE ; + +TYPE + PtrToVec = POINTER TO RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test ; +VAR + ptr: PtrToVec ; +BEGIN + DISPOSE (ptr) ; + IF ptr^.x = 1 + THEN + END +END test ; + + +BEGIN + test +END testdispose. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod new file mode 100644 index 0000000..e4e555c --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod @@ -0,0 +1,24 @@ +MODULE testdispose2 ; + +FROM Storage IMPORT DEALLOCATE ; + +TYPE + PtrToVec = POINTER TO RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test (ptr: PtrToVec) ; +BEGIN + DISPOSE (ptr) ; + IF ptr^.x = 1 + THEN + END +END test ; + + +VAR + p: PtrToVec ; +BEGIN + test (p) +END testdispose2. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod new file mode 100644 index 0000000..26d1d2b --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod @@ -0,0 +1,17 @@ +MODULE testnil ; + + +PROCEDURE test ; +VAR + p: POINTER TO CARDINAL ; +BEGIN + p := NIL ; + IF p^ = 1 + THEN + END +END test ; + + +BEGIN + test +END testnil. -- cgit v1.1 From ba49332baba622cb9af8e34629636f2586664c7e Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Sat, 15 Jul 2023 07:45:00 +0800 Subject: VECT: Add mask_len_fold_left_plus for in-order floating-point reduction Hi, Richard and Richi. This patch adds mask_len_fold_left_plus pattern to support in-order floating-point reduction for target support len loop control. Consider this following case: double foo2 (double *__restrict a, double init, int *__restrict cond, int n) { for (int i = 0; i < n; i++) if (cond[i]) init += a[i]; return init; } ARM SVE: ... vec_mask_and_60 = loop_mask_54 & mask__23.33_57; vect__ifc__35.37_64 = .VCOND_MASK (vec_mask_and_60, vect__8.36_61, { 0.0, ... }); _36 = .MASK_FOLD_LEFT_PLUS (init_20, vect__ifc__35.37_64, loop_mask_54); ... For RVV, we want to see: ... _36 = .MASK_LEN_FOLD_LEFT_PLUS (init_20, vect__ifc__35.37_64, control_mask, loop_len, bias); ... gcc/ChangeLog: * doc/md.texi: Add mask_len_fold_left_plus. * internal-fn.cc (mask_len_fold_left_direct): Ditto. (expand_mask_len_fold_left_optab_fn): Ditto. (direct_mask_len_fold_left_optab_supported_p): Ditto. * internal-fn.def (MASK_LEN_FOLD_LEFT_PLUS): Ditto. * optabs.def (OPTAB_D): Ditto. --- gcc/doc/md.texi | 13 +++++++++++++ gcc/internal-fn.cc | 5 +++++ gcc/internal-fn.def | 3 +++ gcc/optabs.def | 1 + 4 files changed, 22 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index cbcb992..6f44e66 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5615,6 +5615,19 @@ no reassociation. Like @samp{fold_left_plus_@var{m}}, but takes an additional mask operand (operand 3) that specifies which elements of the source vector should be added. +@cindex @code{mask_len_fold_left_plus_@var{m}} instruction pattern +@item @code{mask_len_fold_left_plus_@var{m}} +Like @samp{fold_left_plus_@var{m}}, but takes an additional mask operand +(operand 3), len operand (operand 4) and bias operand (operand 5) that +performs following operations strictly in-order (no reassociation): + +@smallexample +operand0 = operand1; +for (i = 0; i < LEN + BIAS; i++) + if (operand3[i]) + operand0 += operand2[i]; +@end smallexample + @cindex @code{sdot_prod@var{m}} instruction pattern @item @samp{sdot_prod@var{m}} diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index e698f0b..2bf4fc4 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -190,6 +190,7 @@ init_internal_fns () #define fold_extract_direct { 2, 2, false } #define fold_left_direct { 1, 1, false } #define mask_fold_left_direct { 1, 1, false } +#define mask_len_fold_left_direct { 1, 1, false } #define check_ptrs_direct { 0, 0, false } const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = { @@ -3890,6 +3891,9 @@ expand_convert_optab_fn (internal_fn fn, gcall *stmt, convert_optab optab, #define expand_mask_fold_left_optab_fn(FN, STMT, OPTAB) \ expand_direct_optab_fn (FN, STMT, OPTAB, 3) +#define expand_mask_len_fold_left_optab_fn(FN, STMT, OPTAB) \ + expand_direct_optab_fn (FN, STMT, OPTAB, 5) + #define expand_check_ptrs_optab_fn(FN, STMT, OPTAB) \ expand_direct_optab_fn (FN, STMT, OPTAB, 4) @@ -3997,6 +4001,7 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types, #define direct_fold_extract_optab_supported_p direct_optab_supported_p #define direct_fold_left_optab_supported_p direct_optab_supported_p #define direct_mask_fold_left_optab_supported_p direct_optab_supported_p +#define direct_mask_len_fold_left_optab_supported_p direct_optab_supported_p #define direct_check_ptrs_optab_supported_p direct_optab_supported_p #define direct_vec_set_optab_supported_p direct_optab_supported_p #define direct_vec_extract_optab_supported_p direct_optab_supported_p diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index ea750a9..d3aec51 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -319,6 +319,9 @@ DEF_INTERNAL_OPTAB_FN (FOLD_LEFT_PLUS, ECF_CONST | ECF_NOTHROW, DEF_INTERNAL_OPTAB_FN (MASK_FOLD_LEFT_PLUS, ECF_CONST | ECF_NOTHROW, mask_fold_left_plus, mask_fold_left) +DEF_INTERNAL_OPTAB_FN (MASK_LEN_FOLD_LEFT_PLUS, ECF_CONST | ECF_NOTHROW, + mask_len_fold_left_plus, mask_len_fold_left) + /* Unary math functions. */ DEF_INTERNAL_FLT_FN (ACOS, ECF_CONST, acos, unary) DEF_INTERNAL_FLT_FN (ACOSH, ECF_CONST, acosh, unary) diff --git a/gcc/optabs.def b/gcc/optabs.def index 3dae228..7023392 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -385,6 +385,7 @@ OPTAB_D (reduc_ior_scal_optab, "reduc_ior_scal_$a") OPTAB_D (reduc_xor_scal_optab, "reduc_xor_scal_$a") OPTAB_D (fold_left_plus_optab, "fold_left_plus_$a") OPTAB_D (mask_fold_left_plus_optab, "mask_fold_left_plus_$a") +OPTAB_D (mask_len_fold_left_plus_optab, "mask_len_fold_left_plus_$a") OPTAB_D (extract_last_optab, "extract_last_$a") OPTAB_D (fold_extract_last_optab, "fold_extract_last_$a") -- cgit v1.1 From bf20b770d9aabb15faf2644b5e3106249cb175f3 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Tue, 18 Jul 2023 21:11:46 +0000 Subject: Fix PR110726: a | (a == b) can sometimes produce wrong code So I had missed/forgot that EQ_EXPR could have an non boolean type for generic when I implemented r14-2556-g0407ae8a7732d9. This patch adds check for one bit precision intergal type which fixes the problem. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. PR tree-optimization/110726 gcc/ChangeLog: * match.pd ((a|b)&(a==b),a|(a==b),(a&b)|(a==b)): Add checks to make sure the type was one bit precision intergal type. gcc/testsuite/ChangeLog: * gcc.c-torture/execute/bitops-1.c: New test. --- gcc/match.pd | 12 +++++++--- gcc/testsuite/gcc.c-torture/execute/bitops-1.c | 33 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/bitops-1.c (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index 054e658..4dfe926 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1229,7 +1229,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (a | b) & (a == b) --> a & b (boolean version of the above). */ (simplify (bit_and:c (bit_ior @0 @1) (nop_convert? (eq:c @0 @1))) - (bit_and @0 @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_PRECISION (TREE_TYPE (@0)) == 1) + (bit_and @0 @1))) /* a | ~(a ^ b) --> a | ~b */ (simplify @@ -1239,7 +1241,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* a | (a == b) --> a | (b^1) (boolean version of the above). */ (simplify (bit_ior:c @0 (nop_convert? (eq:c @0 @1))) - (bit_ior @0 (bit_xor @1 { build_one_cst (type); }))) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_PRECISION (TREE_TYPE (@0)) == 1) + (bit_ior @0 (bit_xor @1 { build_one_cst (type); })))) /* (a | b) | (a &^ b) --> a | b */ (for op (bit_and bit_xor) @@ -1255,7 +1259,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (a & b) | (a == b) --> a == b */ (simplify (bit_ior:c (bit_and:c @0 @1) (nop_convert?@2 (eq @0 @1))) - @2) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_PRECISION (TREE_TYPE (@0)) == 1) + @2)) /* ~(~a & b) --> a | ~b */ (simplify diff --git a/gcc/testsuite/gcc.c-torture/execute/bitops-1.c b/gcc/testsuite/gcc.c-torture/execute/bitops-1.c new file mode 100644 index 0000000..cfaa6b9 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/bitops-1.c @@ -0,0 +1,33 @@ +/* PR tree-optimization/110726 */ + +#define DECLS(n,VOL) \ +__attribute__((noinline,noclone)) \ +int h##n(VOL int A, VOL int B){ \ + return (A | B) & (A == B); \ +} \ +__attribute__((noinline,noclone)) \ +int i##n(VOL int A, VOL int B){ \ + return A | (A == B); \ +} \ +__attribute__((noinline,noclone)) \ +int k##n(VOL int A, VOL int B){ \ + return (A & B) | (A == B); \ +} \ + +DECLS(0,) +DECLS(1,volatile) + +int values[] = { 0, 1, 2, 3, -1, -2, -3, 0x10080 }; +int numvalues = sizeof(values)/sizeof(values[0]); + +int main(){ + for(int A = 0; A < numvalues; A++) + for(int B = 0; B < numvalues; B++) + { + int a = values[A]; + int b = values[B]; + if (h0 (a, b) != h1 (a, b)) __builtin_abort(); + if (i0 (a, b) != i1 (a, b)) __builtin_abort(); + if (k0 (a, b) != k1 (a, b)) __builtin_abort(); + } +} -- cgit v1.1 From a86d5eca6a11c25da4aff436f53589950641675f Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Fri, 14 Jul 2023 15:14:59 -0700 Subject: Add flow_sensitive_info_storage and use it in gimple-fold. This adds flow_sensitive_info_storage and uses it in maybe_fold_comparisons_from_match_pd as mentioned in https://gcc.gnu.org/pipermail/gcc-patches/2023-June/621817.html . Since using it in maybe_fold_comparisons_from_match_pd was easy and allowed me to test the storage earlier, I did it. This also hides better how the flow sensitive information is stored and only a single place needs to be updated if that ever changes (again). OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: * gimple-fold.cc (fosa_unwind): Replace `vrange_storage *` with flow_sensitive_info_storage. (follow_outer_ssa_edges): Update how to save off the flow sensitive info. (maybe_fold_comparisons_from_match_pd): Update restoring of flow sensitive info. * tree-ssanames.cc (flow_sensitive_info_storage::save): New method. (flow_sensitive_info_storage::restore): New method. (flow_sensitive_info_storage::save_and_clear): New method. (flow_sensitive_info_storage::clear_storage): New method. * tree-ssanames.h (class flow_sensitive_info_storage): New class. --- gcc/gimple-fold.cc | 17 +++++-------- gcc/tree-ssanames.cc | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree-ssanames.h | 21 +++++++++++++++ 3 files changed, 100 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 4027ff7..de94efb 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -6947,7 +6947,7 @@ and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, } static basic_block fosa_bb; -static vec > *fosa_unwind; +static vec > *fosa_unwind; static tree follow_outer_ssa_edges (tree val) { @@ -6967,14 +6967,11 @@ follow_outer_ssa_edges (tree val) || POINTER_TYPE_P (TREE_TYPE (val))) && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val))) return NULL_TREE; + flow_sensitive_info_storage storage; + storage.save_and_clear (val); /* If the definition does not dominate fosa_bb temporarily reset flow-sensitive info. */ - if (val->ssa_name.info.range_info) - { - fosa_unwind->safe_push (std::make_pair - (val, val->ssa_name.info.range_info)); - val->ssa_name.info.range_info = NULL; - } + fosa_unwind->safe_push (std::make_pair (val, storage)); return val; } return val; @@ -7034,14 +7031,14 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, type, gimple_assign_lhs (stmt1), gimple_assign_lhs (stmt2)); fosa_bb = outer_cond_bb; - auto_vec, 8> unwind_stack; + auto_vec, 8> unwind_stack; fosa_unwind = &unwind_stack; if (op.resimplify (NULL, (!outer_cond_bb ? follow_all_ssa_edges : follow_outer_ssa_edges))) { fosa_unwind = NULL; for (auto p : unwind_stack) - p.first->ssa_name.info.range_info = p.second; + p.second.restore (p.first); if (gimple_simplified_result_is_gimple_val (&op)) { tree res = op.ops[0]; @@ -7065,7 +7062,7 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, } fosa_unwind = NULL; for (auto p : unwind_stack) - p.first->ssa_name.info.range_info = p.second; + p.second.restore (p.first); return NULL_TREE; } diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc index f543943..23387b9 100644 --- a/gcc/tree-ssanames.cc +++ b/gcc/tree-ssanames.cc @@ -931,3 +931,75 @@ make_pass_release_ssa_names (gcc::context *ctxt) { return new pass_release_ssa_names (ctxt); } + +/* Save and restore of flow sensitive information. */ + +/* Save off the flow sensitive info from NAME. */ + +void +flow_sensitive_info_storage::save (tree name) +{ + gcc_assert (state == 0); + if (!POINTER_TYPE_P (TREE_TYPE (name))) + { + range_info = SSA_NAME_RANGE_INFO (name); + state = 1; + return; + } + state = -1; + auto ptr_info = SSA_NAME_PTR_INFO (name); + if (ptr_info) + { + align = ptr_info->align; + misalign = ptr_info->misalign; + null = SSA_NAME_PTR_INFO (name)->pt.null; + } + else + { + align = 0; + misalign = 0; + null = true; + } +} + +/* Restore the flow sensitive info from NAME. */ + +void +flow_sensitive_info_storage::restore (tree name) +{ + gcc_assert (state != 0); + if (!POINTER_TYPE_P (TREE_TYPE (name))) + { + gcc_assert (state == 1); + SSA_NAME_RANGE_INFO (name) = range_info; + return; + } + gcc_assert (state == -1); + auto ptr_info = SSA_NAME_PTR_INFO (name); + /* If there was no flow sensitive info on the pointer + just return, there is nothing to restore to. */ + if (!ptr_info) + return; + if (align != 0) + set_ptr_info_alignment (ptr_info, align, misalign); + else + mark_ptr_info_alignment_unknown (ptr_info); + SSA_NAME_PTR_INFO (name)->pt.null = null; +} + +/* Save off the flow sensitive info from NAME. + And reset the flow sensitive info of NAME. */ + +void +flow_sensitive_info_storage::save_and_clear (tree name) +{ + save (name); + reset_flow_sensitive_info (name); +} + +/* Clear the storage. */ +void +flow_sensitive_info_storage::clear_storage (void) +{ + state = 0; +} diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index b5e3f22..35e4255 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -137,5 +137,26 @@ make_temp_ssa_name (tree type, gimple *stmt, const char *name) return ssa_name; } +/* A class which is used to save/restore the flow sensitive information. */ +class flow_sensitive_info_storage +{ +public: + void save (tree); + void save_and_clear (tree); + void restore (tree); + void clear_storage (); +private: + /* 0 means there is nothing saved. + 1 means non pointer is saved. + -1 means a pointer type is saved. + -2 means a pointer type is saved but no information was saved. */ + int state = 0; + /* The range info for non pointers */ + vrange_storage *range_info = nullptr; + /* Flow sensitive pointer information. */ + unsigned int align = 0; + unsigned int misalign = 0; + bool null = true; +}; #endif /* GCC_TREE_SSANAMES_H */ -- cgit v1.1 From 8c79b49cd4fa742f7be739dd21fd2aa040cc1ba3 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Fri, 14 Jul 2023 15:55:34 -0700 Subject: [PATCH] Fix tree-opt/110252: wrong code due to phiopt using flow sensitive info during match Match will query ranger via tree_nonzero_bits/get_nonzero_bits for 2 and 3rd operand of the COND_EXPR and phiopt tries to do create the COND_EXPR even if we moving one statement. That one statement could have some flow sensitive information on it based on the condition that is for the COND_EXPR but that might create wrong code if the statement was moved out. This is similar to the previous version of the patch except now we use flow_sensitive_info_storage instead of manually doing the save/restore and also handle all defs on a gimple statement rather than just for lhs of the gimple statement. Oh and a few more testcases were added that was failing before. OK? Bootsrapped and tested on x86_64-linux-gnu with no regressions. PR tree-optimization/110252 gcc/ChangeLog: * tree-ssa-phiopt.cc (class auto_flow_sensitive): New class. (auto_flow_sensitive::auto_flow_sensitive): New constructor. (auto_flow_sensitive::~auto_flow_sensitive): New deconstructor. (match_simplify_replacement): Temporarily remove the flow sensitive info on the two statements that might be moved. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/phi-opt-25b.c: Updated as __builtin_parity loses the nonzerobits info. * gcc.c-torture/execute/pr110252-1.c: New test. * gcc.c-torture/execute/pr110252-2.c: New test. * gcc.c-torture/execute/pr110252-3.c: New test. * gcc.c-torture/execute/pr110252-4.c: New test. --- gcc/testsuite/gcc.c-torture/execute/pr110252-1.c | 15 +++++++ gcc/testsuite/gcc.c-torture/execute/pr110252-2.c | 10 +++++ gcc/testsuite/gcc.c-torture/execute/pr110252-3.c | 13 ++++++ gcc/testsuite/gcc.c-torture/execute/pr110252-4.c | 8 ++++ gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25b.c | 6 +-- gcc/tree-ssa-phiopt.cc | 51 ++++++++++++++++++++++-- 6 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr110252-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr110252-2.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr110252-3.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr110252-4.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110252-1.c b/gcc/testsuite/gcc.c-torture/execute/pr110252-1.c new file mode 100644 index 0000000..4ae93ca --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr110252-1.c @@ -0,0 +1,15 @@ +/* This is reduced from sel-sched.cc which was noticed was being miscompiled too. */ +int g(int min_need_stall) __attribute__((__noipa__)); +int g(int min_need_stall) +{ + return min_need_stall < 0 ? 1 : ((min_need_stall) < (1) ? (min_need_stall) : (1)); +} +int main(void) +{ + for(int i = -100; i <= 100; i++) + { + int t = g(i); + if (t != (i!=0)) + __builtin_abort(); + } +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110252-2.c b/gcc/testsuite/gcc.c-torture/execute/pr110252-2.c new file mode 100644 index 0000000..7f1a7db --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr110252-2.c @@ -0,0 +1,10 @@ +signed char f() __attribute__((__noipa__)); +signed char f() { return 0; } +int main() +{ + int g = f() - 1; + int e = g < 0 ? 1 : ((g >> (8-2))!=0); + asm("":"+r"(e)); + if (e != 1) + __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110252-3.c b/gcc/testsuite/gcc.c-torture/execute/pr110252-3.c new file mode 100644 index 0000000..c24bf1a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr110252-3.c @@ -0,0 +1,13 @@ + +unsigned int a = 1387579096U; +void sinkandcheck(unsigned b) __attribute__((noipa)); +void sinkandcheck(unsigned b) +{ + if (a != b) + __builtin_abort(); +} +int main() { + a = 1 < (~a) ? 1 : (~a); + sinkandcheck(1); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110252-4.c b/gcc/testsuite/gcc.c-torture/execute/pr110252-4.c new file mode 100644 index 0000000..f97edd3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr110252-4.c @@ -0,0 +1,8 @@ + +int a, b = 2, c = 2; +int main() { + b = ~(1 % (a ^ (b - (1 && c) || c & b))); + if (b < -1) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25b.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25b.c index 7298da0..0fd9b00 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25b.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25b.c @@ -65,8 +65,6 @@ int test_popcountll(unsigned long long x, unsigned long long y) return x ? __builtin_popcountll(y) : 0; } -/* 3 types of functions (not including parity), each with 3 types and there are 2 goto each */ -/* { dg-final { scan-tree-dump-times "goto " 18 "optimized" } } */ +/* 4 types of functions, each with 3 types and there are 2 goto each */ +/* { dg-final { scan-tree-dump-times "goto " 24 "optimized" } } */ /* { dg-final { scan-tree-dump-times "x_..D. != 0" 12 "optimized" } } */ -/* parity case will be optimized to x!=0 & parity(y) . */ -/* { dg-final { scan-tree-dump-times " & " 3 "optimized" } } */ diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 467c9fd..9d542fd 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -708,6 +708,45 @@ move_stmt (gimple *stmt, gimple_stmt_iterator *gsi, auto_bitmap &inserted_exprs) reset_flow_sensitive_info (name); } +/* RAII style class to temporarily remove flow sensitive + from ssa names defined by a gimple statement. */ +class auto_flow_sensitive +{ +public: + auto_flow_sensitive (gimple *s); + ~auto_flow_sensitive (); +private: + auto_vec, 2> stack; +}; + +/* Constructor for auto_flow_sensitive. Saves + off the ssa names' flow sensitive information + that was defined by gimple statement S and + resets it to be non-flow based ones. */ + +auto_flow_sensitive::auto_flow_sensitive (gimple *s) +{ + if (!s) + return; + ssa_op_iter it; + tree def; + FOR_EACH_SSA_TREE_OPERAND (def, s, it, SSA_OP_DEF) + { + flow_sensitive_info_storage storage; + storage.save_and_clear (def); + stack.safe_push (std::make_pair (def, storage)); + } +} + +/* Deconstructor, restores the flow sensitive information + for the SSA names that had been saved off. */ + +auto_flow_sensitive::~auto_flow_sensitive () +{ + for (auto p : stack) + p.second.restore (p.first); +} + /* The function match_simplify_replacement does the main work of doing the replacement using match and simplify. Return true if the replacement is done. Otherwise return false. @@ -793,9 +832,15 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb, return false; tree type = TREE_TYPE (gimple_phi_result (phi)); - result = gimple_simplify_phiopt (early_p, type, stmt, - arg_true, arg_false, - &seq); + { + auto_flow_sensitive s1(stmt_to_move); + auto_flow_sensitive s_alt(stmt_to_move_alt); + + result = gimple_simplify_phiopt (early_p, type, stmt, + arg_true, arg_false, + &seq); + } + if (!result) return false; -- cgit v1.1 From 73d3bc348190b538675c9f5e88b5d8da8b63991c Mon Sep 17 00:00:00 2001 From: Andrew Carlotti Date: Tue, 7 Mar 2023 14:37:00 +0000 Subject: aarch64: Remove architecture dependencies from intrinsics Many intrinsics currently depend on both an architecture version and a feature, despite the corresponding instructions being available within GCC at lower architecture versions. LLVM has already removed these explicit architecture version dependences; this patch does the same for GCC. Note that +fp16 does not imply +simd, so we need to add an explicit +simd for the Neon fp16 intrinsics. Binutils did not previously support all of these architecture+feature combinations, but this problem is already reachable from GCC. For example, compiling the test gcc.target/aarch64/usadv16qi-dotprod.c with -O3 -march=armv8-a+dotprod has resulted in an assembler error since GCC 10. This is fixed in Binutils 2.41. This patch retains explicit architecture version dependencies for features that do not currently have a separate feature flag. gcc/ChangeLog: * config/aarch64/aarch64.h (TARGET_MEMTAG): Remove armv8.5 dependency. * config/aarch64/arm_acle.h: Remove unnecessary armv8.x dependencies from target pragmas. * config/aarch64/arm_fp16.h (target): Likewise. * config/aarch64/arm_neon.h (target): Likewise. gcc/testsuite/ChangeLog: * gcc.target/aarch64/feature-bf16-backport.c: New test. * gcc.target/aarch64/feature-dotprod-backport.c: New test. * gcc.target/aarch64/feature-fp16-backport.c: New test. * gcc.target/aarch64/feature-fp16-scalar-backport.c: New test. * gcc.target/aarch64/feature-fp16fml-backport.c: New test. * gcc.target/aarch64/feature-i8mm-backport.c: New test. * gcc.target/aarch64/feature-memtag-backport.c: New test. * gcc.target/aarch64/feature-sha3-backport.c: New test. * gcc.target/aarch64/feature-sm4-backport.c: New test. --- gcc/config/aarch64/aarch64.h | 2 +- gcc/config/aarch64/arm_acle.h | 2 +- gcc/config/aarch64/arm_fp16.h | 2 +- gcc/config/aarch64/arm_neon.h | 14 +++++++------- gcc/testsuite/gcc.target/aarch64/feature-bf16-backport.c | 10 ++++++++++ .../gcc.target/aarch64/feature-dotprod-backport.c | 10 ++++++++++ gcc/testsuite/gcc.target/aarch64/feature-fp16-backport.c | 10 ++++++++++ .../gcc.target/aarch64/feature-fp16-scalar-backport.c | 10 ++++++++++ .../gcc.target/aarch64/feature-fp16fml-backport.c | 10 ++++++++++ gcc/testsuite/gcc.target/aarch64/feature-i8mm-backport.c | 10 ++++++++++ gcc/testsuite/gcc.target/aarch64/feature-memtag-backport.c | 10 ++++++++++ gcc/testsuite/gcc.target/aarch64/feature-sha3-backport.c | 10 ++++++++++ gcc/testsuite/gcc.target/aarch64/feature-sm4-backport.c | 10 ++++++++++ 13 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-bf16-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-dotprod-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-fp16-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-fp16-scalar-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-fp16fml-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-i8mm-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-memtag-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-sha3-backport.c create mode 100644 gcc/testsuite/gcc.target/aarch64/feature-sm4-backport.c (limited to 'gcc') diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index a01f1ee..2b0fc97 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -292,7 +292,7 @@ enum class aarch64_feature : unsigned char { #define TARGET_RNG (AARCH64_ISA_RNG) /* Memory Tagging instructions optional to Armv8.5 enabled through +memtag. */ -#define TARGET_MEMTAG (AARCH64_ISA_V8_5A && AARCH64_ISA_MEMTAG) +#define TARGET_MEMTAG (AARCH64_ISA_MEMTAG) /* I8MM instructions are enabled through +i8mm. */ #define TARGET_I8MM (AARCH64_ISA_I8MM) diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index 3b6b63e..7599a32 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -292,7 +292,7 @@ __rndrrs (uint64_t *__res) #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.5-a+memtag") +#pragma GCC target ("+nothing+memtag") #define __arm_mte_create_random_tag(__ptr, __u64_mask) \ __builtin_aarch64_memtag_irg(__ptr, __u64_mask) diff --git a/gcc/config/aarch64/arm_fp16.h b/gcc/config/aarch64/arm_fp16.h index 350f8cc..c10f9dc 100644 --- a/gcc/config/aarch64/arm_fp16.h +++ b/gcc/config/aarch64/arm_fp16.h @@ -30,7 +30,7 @@ #include #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+fp16") +#pragma GCC target ("+nothing+fp16") typedef __fp16 float16_t; diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 0ace1ee..349f316 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -25590,7 +25590,7 @@ __INTERLEAVE_LIST (zip) #include "arm_fp16.h" #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+fp16") +#pragma GCC target ("+nothing+simd+fp16") /* ARMv8.2-A FP16 one operand vector intrinsics. */ @@ -26753,7 +26753,7 @@ vminnmvq_f16 (float16x8_t __a) /* AdvSIMD Dot Product intrinsics. */ #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+dotprod") +#pragma GCC target ("+nothing+dotprod") __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -26844,7 +26844,7 @@ vdotq_laneq_s32 (int32x4_t __r, int8x16_t __a, int8x16_t __b, const int __index) #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+sm4") +#pragma GCC target ("+nothing+sm4") __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -26911,7 +26911,7 @@ vsm4ekeyq_u32 (uint32x4_t __a, uint32x4_t __b) #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+sha3") +#pragma GCC target ("+nothing+sha3") __extension__ extern __inline uint64x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -27547,7 +27547,7 @@ vcmlaq_rot270_laneq_f32 (float32x4_t __r, float32x4_t __a, float32x4_t __b, #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+fp16fml") +#pragma GCC target ("+nothing+fp16fml") __extension__ extern __inline float32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -27856,7 +27856,7 @@ vrnd64xq_f64 (float64x2_t __a) #include "arm_bf16.h" #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+bf16") +#pragma GCC target ("+nothing+bf16") __extension__ extern __inline bfloat16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -28535,7 +28535,7 @@ vst4q_lane_bf16 (bfloat16_t *__ptr, bfloat16x8x4_t __val, const int __lane) /* AdvSIMD 8-bit Integer Matrix Multiply (I8MM) intrinsics. */ #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+i8mm") +#pragma GCC target ("+nothing+i8mm") __extension__ extern __inline int32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) diff --git a/gcc/testsuite/gcc.target/aarch64/feature-bf16-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-bf16-backport.c new file mode 100644 index 0000000..3a03255 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-bf16-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+bf16" } */ + +#include + +float32x4_t bar (float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { + return vbfmlalbq_f32 (r, a, b); +} + +/* { dg-final { scan-assembler {\tbfmlalb\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-dotprod-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-dotprod-backport.c new file mode 100644 index 0000000..5f66fff --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-dotprod-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+dotprod" } */ + +#include + +uint32x4_t bar (uint32x4_t r, uint8x16_t a, uint8x16_t b) { + return vdotq_u32(r, a, b); +} + +/* { dg-final { scan-assembler {\tudot\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-fp16-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-fp16-backport.c new file mode 100644 index 0000000..eb94ae0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-fp16-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+fp16" } */ + +#include + +float16x8_t bar (float16x8_t a, float16x8_t b) { + return vaddq_f16(a, b); +} + +/* { dg-final { scan-assembler {\tfadd\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-fp16-scalar-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-fp16-scalar-backport.c new file mode 100644 index 0000000..9cde6b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-fp16-scalar-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+fp16+nosimd" } */ + +#include + +float16_t bar (float16_t a, float16_t b) { + return vaddh_f16(a, b); +} + +/* { dg-final { scan-assembler {\tfadd\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-fp16fml-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-fp16fml-backport.c new file mode 100644 index 0000000..86c4748 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-fp16fml-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+fp16fml" } */ + +#include + +float32x4_t bar (float32x4_t r, float16x8_t a, float16x8_t b) { + return vfmlalq_high_f16 (r, a, b); +} + +/* { dg-final { scan-assembler {\tfmlal2\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-i8mm-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-i8mm-backport.c new file mode 100644 index 0000000..6dd0214 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-i8mm-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+i8mm" } */ + +#include + +int32x4_t bar (int32x4_t r, int8x16_t a, int8x16_t b) { + return vmmlaq_s32 (r, a, b); +} + +/* { dg-final { scan-assembler {\tsmmla\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-memtag-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-memtag-backport.c new file mode 100644 index 0000000..5cb071b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-memtag-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+memtag" } */ + +#include + +int *bar (int *src) { + return __arm_mte_create_random_tag(src, 2<<16-1); +} + +/* { dg-final { scan-assembler {\tirg\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-sha3-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-sha3-backport.c new file mode 100644 index 0000000..e194f1a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-sha3-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+sha3" } */ + +#include + +uint64x2_t bar (uint64x2_t a, uint64x2_t b, uint64x2_t c) { + return vsha512hq_u64(a, b, c); +} + +/* { dg-final { scan-assembler {\tsha512h\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/feature-sm4-backport.c b/gcc/testsuite/gcc.target/aarch64/feature-sm4-backport.c new file mode 100644 index 0000000..604a58b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/feature-sm4-backport.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+sm4" } */ + +#include + +uint32x4_t bar (uint32x4_t a, uint32x4_t b, uint32x4_t c) { + return vsm3tt1aq_u32(a, b, c, 2); +} + +/* { dg-final { scan-assembler {\tsm3tt1a\t} } } */ -- cgit v1.1 From 029c7ebe7f4f9ea37d715dbc2da36687d8657c2c Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Wed, 19 Jul 2023 17:46:52 +0100 Subject: [modula2] Location improvement and bugfix when issuing parameter errors This patch improves the accuracy of error messages mentioning a parameter in M2Quads.mod (when handling builtins). The error location now points to the parameter rather than the function or procedure. gcc/m2/ChangeLog: * gm2-compiler/M2Quads.mod (BuildDifAdrFunction): Removed unnecessary in error message. Use vartok for location. (BuildOddFunction): Use optok for location. (BuildAbsFunction): Use vartok for location. Bugfix set vartok. (BuildCapFunction): Use optok for location. (BuildOrdFunction): Use optok for location and correct format specifier. (BuildShiftFunction): Use vartok for location. (BuildRotateFunction): Use vartok for location. (BuildTruncFunction): Use vartok for location. (BuildFloatFunction): Use vartok for location. (BuildReFunction): Use vartok for location. (BuildImFunction): Use vartok for location. * gm2-compiler/M2SymInit.mod (trashParam): Remove commented code. gcc/testsuite/ChangeLog: * gm2/errors/fail/badabs.mod: New test. * gm2/errors/fail/badenum.mod: New test. Signed-off-by: Gaius Mulley --- gcc/m2/gm2-compiler/M2Quads.mod | 53 +++++++++++++++++-------------- gcc/m2/gm2-compiler/M2SymInit.mod | 2 -- gcc/testsuite/gm2/errors/fail/badabs.mod | 7 ++++ gcc/testsuite/gm2/errors/fail/badenum.mod | 8 +++++ 4 files changed, 44 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gm2/errors/fail/badabs.mod create mode 100644 gcc/testsuite/gm2/errors/fail/badenum.mod (limited to 'gcc') diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod index 3e4863b..51c2835 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -8127,22 +8127,23 @@ BEGIN PushT (2) ; (* Two parameters *) BuildConvertFunction ELSE - MetaError1 ('the second parameter to {%EkDIFADR } {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}', + MetaError1 ('the second parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}', OperandSym) ; PushTFtok (MakeConstLit (combinedtok, MakeKey ('0'), Integer), Integer, combinedtok) END ELSE - MetaError1 ('the first parameter to {%EkDIFADR } {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}', - VarSym) ; + MetaErrorT1 (vartok, + 'the first parameter to {%EkDIFADR} {%1Ea} must be a variable of type ADDRESS or a {%EkPOINTER}, rather than a {%1Etsd}', + VarSym) ; PushTFtok (MakeConstLit (combinedtok, MakeKey ('0'), Integer), Integer, combinedtok) END ELSE - MetaError0 ('{%E}SYSTEM procedure {%EkDIFADR } expects a variable of type ADDRESS or POINTER as its first parameter') ; + MetaError0 ('{%E}SYSTEM procedure {%EkDIFADR} expects a variable of type ADDRESS or POINTER as its first parameter') ; PushTFtok (MakeConstLit (combinedtok, MakeKey('0'), Integer), Integer, combinedtok) END ELSE combinedtok := MakeVirtualTok (functok, functok, optok) ; - MetaErrorT0 (functok, '{%E}SYSTEM procedure {%EkDIFADR } expects 2 parameters') ; + MetaErrorT0 (functok, '{%E}SYSTEM procedure {%EkDIFADR} expects 2 parameters') ; PopN (NoOfParam+1) ; PushTFtok (MakeConstLit (combinedtok, MakeKey('0'), Integer), Integer, combinedtok) END @@ -8522,14 +8523,14 @@ BEGIN PushTtok (Res, combinedtok) ELSE - MetaErrorT1 (combinedtok, + MetaErrorT1 (optok, 'the parameter to {%1EkODD} must be a variable or constant, seen {%1ad}', Var) ; PushTtok (False, combinedtok) END ELSE MetaErrorT1 (functok, - 'the pseudo procedure {%1EkODD} only has one parameter, seen {%1n} parameters', + 'the pseudo procedure {%E1kODD} only has one parameter, seen {%1n} parameters', NoOfParam) ; PushTtok (False, functok) END @@ -8573,6 +8574,7 @@ END BuildOddFunction ; PROCEDURE BuildAbsFunction ; VAR + vartok, functok, combinedtok: CARDINAL ; NoOfParam, @@ -8584,6 +8586,7 @@ BEGIN IF NoOfParam = 1 THEN Var := OperandT (1) ; + vartok := OperandTok (1) ; combinedtok := MakeVirtualTok (functok, functok, vartok) ; IF IsVar(Var) OR IsConst(Var) THEN @@ -8596,7 +8599,7 @@ BEGIN GenQuadO (combinedtok, StandardFunctionOp, Res, ProcSym, Var, FALSE) ; PushTFtok (Res, GetSType (Var), combinedtok) ELSE - MetaErrorT1 (combinedtok, + MetaErrorT1 (vartok, 'the parameter to {%AkABS} must be a variable or constant, seen {%1ad}', Var) END @@ -8656,7 +8659,7 @@ BEGIN GenQuadO (combinedtok, StandardFunctionOp, Res, ProcSym, Var, FALSE) ; PushTFtok (Res, Char, combinedtok) ELSE - MetaErrorT1 (functok, + MetaErrorT1 (optok, 'the parameter to {%AkCAP} must be a variable or constant, seen {%1ad}', Var) END @@ -8726,7 +8729,7 @@ BEGIN PushT (2) ; (* Two parameters *) BuildConvertFunction ELSE - MetaErrorT1 (functok, + MetaErrorT1 (optok, 'the parameter to {%AkCHR} must be a variable or constant, seen {%1ad}', Var) END @@ -8797,13 +8800,13 @@ BEGIN PushT (2) ; (* Two parameters *) BuildConvertFunction ELSE - MetaErrorT2 (functok, - 'the parameter to {%1Ak%a} must be a variable or constant, seen {%2ad}', + MetaErrorT2 (optok, + 'the parameter to {%1Aa} must be a variable or constant, seen {%2ad}', Sym, Var) END ELSE MetaErrorT2 (functok, - 'the pseudo procedure {%1Ak%a} only has one parameter, seen {%2n} parameters', + 'the pseudo procedure {%1Aa} only has one parameter, seen {%2n} parameters', Sym, NoOfParam) END END BuildOrdFunction ; @@ -8868,14 +8871,14 @@ BEGIN BuildConvertFunction ELSE combinedtok := MakeVirtualTok (functok, optok, optok) ; - MetaErrorT2 (combinedtok, - 'the parameter to {%1Ek%a} must be a variable or constant, seen {%2ad}', + MetaErrorT2 (optok, + 'the parameter to {%1Ea} must be a variable or constant, seen {%2ad}', Sym, Var) ; PushTtok (combinedtok, MakeConstLit (combinedtok, MakeKey ('0'), ZType)) END ELSE MetaErrorT2 (functok, - 'the pseudo procedure {%1Ek%a} only has one parameter, seen {%2n} parameters', + 'the pseudo procedure {%1Ea} only has one parameter, seen {%2n} parameters', Sym, NoOfParam) ; PushTtok (functok, MakeConstLit (functok, MakeKey ('0'), ZType)) END @@ -9024,8 +9027,9 @@ BEGIN GenQuad (LogicalShiftOp, returnVar, varSet, derefExp) ; PushTFtok (returnVar, GetSType (varSet), combinedtok) ELSE - MetaError1 ('SYSTEM procedure {%1EkSHIFT} expects a constant or variable which has a type of SET as its first parameter, seen {%1ad}', - varSet) ; + MetaErrorT1 (vartok, + 'SYSTEM procedure {%1EkSHIFT} expects a constant or variable which has a type of SET as its first parameter, seen {%1ad}', + varSet) ; PushTFtok (MakeConstLit (combinedtok, MakeKey ('0'), Cardinal), Cardinal, combinedtok) END ELSE @@ -9099,8 +9103,9 @@ BEGIN GenQuadO (combinedtok, LogicalRotateOp, returnVar, varSet, derefExp, TRUE) ; PushTFtok (returnVar, GetSType (varSet), combinedtok) ELSE - MetaErrorT0 (functok, - 'SYSTEM procedure {%EkROTATE} expects a constant or variable which has a type of SET as its first parameter') ; + MetaErrorT1 (vartok, + 'SYSTEM procedure {%EkROTATE} expects a constant or variable which has a type of SET as its first parameter, seen {%1ad}', + varSet) ; PushTFtok (MakeConstLit (functok, MakeKey('0'), Cardinal), Cardinal, functok) END ELSE @@ -9685,7 +9690,7 @@ BEGIN PushTFtok (MakeConstLit (functok, MakeKey('0'), Type), Type, functok) END ELSE - MetaErrorT2 (functok, + MetaErrorT2 (vartok, 'argument to {%1E%ad} must be a variable or constant, seen {%2ad}', Sym, Var) ; PushTFtok (MakeConstLit (functok, MakeKey('0'), Type), Type, functok) @@ -9764,7 +9769,7 @@ BEGIN PushT(2) ; (* two parameters. *) BuildConvertFunction ELSE - MetaErrorT1 (functok, + MetaErrorT1 (vartok, 'argument to {%1E%ad} must be a variable or constant', ProcSym) ; PushTFtok (MakeConstLit (functok, MakeKey('0.0'), Type), Type, functok) END @@ -9834,7 +9839,7 @@ BEGIN ELSE PopN (NoOfParam+1) ; (* destroy arguments to this function *) PushTFtok (MakeConstLit (combinedtok, MakeKey ('1.0'), RType), RType, combinedtok) ; - MetaErrorT2 (functok, + MetaErrorT2 (vartok, 'the parameter to the builtin procedure function {%1Ead} must be a constant or a variable, seen {%2ad}', func, Var) END @@ -9902,7 +9907,7 @@ BEGIN ELSE PopN (NoOfParam+1) ; (* destroy arguments to this function *) PushTFtok (MakeConstLit (combinedtok, MakeKey ('1.0'), RType), RType, combinedtok) ; - MetaErrorT2 (functok, + MetaErrorT2 (vartok, 'the parameter to the builtin procedure function {%1Ead} must be a constant or a variable, seen {%2ad}', func, Var) END diff --git a/gcc/m2/gm2-compiler/M2SymInit.mod b/gcc/m2/gm2-compiler/M2SymInit.mod index b7978e5..81d1e6b 100644 --- a/gcc/m2/gm2-compiler/M2SymInit.mod +++ b/gcc/m2/gm2-compiler/M2SymInit.mod @@ -1550,8 +1550,6 @@ BEGIN THEN IF IsDeallocate (op2) THEN - (* SetupLAlias (ptr, heapSym) *) - (* SetupIndr (ptr, Nil) *) SetupLAlias (ptr, Nil) ELSE SetupIndr (ptr, heapSym) diff --git a/gcc/testsuite/gm2/errors/fail/badabs.mod b/gcc/testsuite/gm2/errors/fail/badabs.mod new file mode 100644 index 0000000..a7d994a --- /dev/null +++ b/gcc/testsuite/gm2/errors/fail/badabs.mod @@ -0,0 +1,7 @@ +MODULE badabs ; + +VAR + c: CARDINAL ; +BEGIN + c := ABS (foo) +END badabs. diff --git a/gcc/testsuite/gm2/errors/fail/badenum.mod b/gcc/testsuite/gm2/errors/fail/badenum.mod new file mode 100644 index 0000000..02b7eb2 --- /dev/null +++ b/gcc/testsuite/gm2/errors/fail/badenum.mod @@ -0,0 +1,8 @@ +MODULE badenum ; + +TYPE + color = (red, blue, green) ; + +BEGIN + red := 1 +END badenum. -- cgit v1.1 From 2971ff7b1d564ac04b537d907c70e6093af70832 Mon Sep 17 00:00:00 2001 From: "Vladimir N. Makarov" Date: Wed, 19 Jul 2023 09:35:37 -0400 Subject: [LRA]: Check and update frame to stack pointer elimination after stack slot allocation Avr is an interesting target which does not use stack pointer to address stack slots. The elimination of stack pointer to frame pointer is impossible if there are stack slots. During LRA works, the stack slots can be allocated and used and the elimination can be done anymore. The situation can be complicated even more if some pseudos were allocated to the frame pointer. gcc/ChangeLog: * lra-int.h (lra_update_fp2sp_elimination): New prototype. (lra_asm_insn_error): New prototype. * lra-spills.cc (remove_pseudos): Add check for pseudo slot memory existence. (lra_spill): Call lra_update_fp2sp_elimination. * lra-eliminations.cc: Remove trailing spaces. (elimination_fp2sp_occured_p): New static flag. (lra_eliminate_regs_1): Set the flag up. (update_reg_eliminate): Modify the assert for stack to frame pointer elimination. (lra_update_fp2sp_elimination): New function. (lra_eliminate): Clear flag elimination_fp2sp_occured_p. gcc/testsuite/ChangeLog: * gcc.target/avr/lra-elim.c: New test. --- gcc/lra-eliminations.cc | 69 +++++++++++++++++++++++++++------ gcc/lra-int.h | 1 + gcc/lra-spills.cc | 6 ++- gcc/testsuite/gcc.target/avr/lra-elim.c | 14 +++++++ 4 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/avr/lra-elim.c (limited to 'gcc') diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index 6822533..cf0aa94 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -286,7 +286,7 @@ move_plus_up (rtx x) { rtx subreg_reg; machine_mode x_mode, subreg_reg_mode; - + if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x)) return x; subreg_reg = SUBREG_REG (x); @@ -309,6 +309,9 @@ move_plus_up (rtx x) return x; } +/* Flag that we already did frame pointer to stack pointer elimination. */ +static bool elimination_fp2sp_occured_p = false; + /* Scan X and replace any eliminable registers (such as fp) with a replacement (such as sp) if SUBST_P, plus an offset. The offset is a change in the offset between the eliminable register and its @@ -366,6 +369,9 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, { rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) + elimination_fp2sp_occured_p = true; + if (maybe_ne (update_sp_offset, 0)) { if (ep->to_rtx == stack_pointer_rtx) @@ -396,9 +402,12 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, poly_int64 offset, curr_offset; rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) + elimination_fp2sp_occured_p = true; + if (! update_p && ! full_p) return gen_rtx_PLUS (Pmode, to, XEXP (x, 1)); - + if (maybe_ne (update_sp_offset, 0)) offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0; else @@ -456,6 +465,9 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, { rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) + elimination_fp2sp_occured_p = true; + if (maybe_ne (update_sp_offset, 0)) { if (ep->to_rtx == stack_pointer_rtx) @@ -500,7 +512,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, case LE: case LT: case LEU: case LTU: { rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, - subst_p, update_p, + subst_p, update_p, update_sp_offset, full_p); rtx new1 = XEXP (x, 1) ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, @@ -749,7 +761,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset)))) { poly_int64 size = GET_MODE_SIZE (mem_mode); - + #ifdef PUSH_ROUNDING /* If more bytes than MEM_MODE are pushed, account for them. */ @@ -822,7 +834,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) { /* See if this is setting the replacement hard register for an elimination. - + If DEST is the hard frame pointer, we do nothing because we assume that all assignments to the frame pointer are for non-local gotos and are being done at a time when @@ -838,7 +850,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) && SET_DEST (x) != hard_frame_pointer_rtx) setup_can_eliminate (ep, false); } - + mark_not_eliminable (SET_SRC (x), mem_mode); return; @@ -1047,7 +1059,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS) { rtx reg1, reg2, op1, op2; - + reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0); reg2 = op2 = XEXP (SET_SRC (set), 1); if (GET_CODE (reg1) == SUBREG) @@ -1160,11 +1172,17 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) fprintf (lra_dump_file, " Elimination %d to %d is not possible anymore\n", ep->from, ep->to); - /* If after processing RTL we decides that SP can be used as - a result of elimination, it cannot be changed. */ - gcc_assert ((ep->to_rtx != stack_pointer_rtx) - || (ep->from < FIRST_PSEUDO_REGISTER + /* If after processing RTL we decides that SP can be used as a result + of elimination, it cannot be changed. For frame pointer to stack + pointer elimination the condition is a bit relaxed and we just require + that actual elimination has not been done yet. */ + gcc_assert (ep->to_rtx != stack_pointer_rtx + || (ep->from == FRAME_POINTER_REGNUM + && !elimination_fp2sp_occured_p) + || (ep->from != FRAME_POINTER_REGNUM + && ep->from < FIRST_PSEUDO_REGISTER && fixed_regs [ep->from])); + /* Mark that is not eliminable anymore. */ elimination_map[ep->from] = NULL; for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++) @@ -1363,6 +1381,30 @@ process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p) } } +/* Update frame pointer to stack pointer elimination if we started with + permitted frame pointer elimination and now target reports that we can not + do this elimination anymore. */ +void +lra_update_fp2sp_elimination (void) +{ + HARD_REG_SET set; + class lra_elim_table *ep; + + if (frame_pointer_needed || !targetm.frame_pointer_required ()) + return; + gcc_assert (!elimination_fp2sp_occured_p); + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + " Frame pointer can not be eliminated anymore\n"); + frame_pointer_needed = true; + CLEAR_HARD_REG_SET (set); + add_to_hard_reg_set (&set, Pmode, FRAME_POINTER_REGNUM); + spill_pseudos (set); + for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) + if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) + setup_can_eliminate (ep, false); +} + /* Entry function to do final elimination if FINAL_P or to update elimination register offsets (FIRST_P if we are doing it the first time). */ @@ -1379,7 +1421,10 @@ lra_eliminate (bool final_p, bool first_p) timevar_push (TV_LRA_ELIMINATE); if (first_p) - init_elimination (); + { + elimination_fp2sp_occured_p = false; + init_elimination (); + } bitmap_initialize (&insns_with_changed_offsets, ®_obstack); if (final_p) diff --git a/gcc/lra-int.h b/gcc/lra-int.h index a32359e5..633d9af8 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -414,6 +414,7 @@ extern int lra_get_elimination_hard_regno (int); extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode, bool, bool, poly_int64, bool); extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64); +extern void lra_update_fp2sp_elimination (void); extern void lra_eliminate (bool, bool); extern poly_int64 lra_update_sp_offset (rtx, poly_int64); diff --git a/gcc/lra-spills.cc b/gcc/lra-spills.cc index 4af85c4..3a7bb7e 100644 --- a/gcc/lra-spills.cc +++ b/gcc/lra-spills.cc @@ -453,7 +453,10 @@ remove_pseudos (rtx *loc, rtx_insn *insn) return true; if ((hard_reg = spill_hard_reg[i]) != NULL_RTX) *loc = copy_rtx (hard_reg); - else + else if (pseudo_slots[i].mem != NULL_RTX) + /* There might be no memory slot or hard reg for a pseudo when we spill + the frame pointer after elimination of frame pointer to stack + pointer became impossible. */ { rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem, GET_MODE (pseudo_slots[i].mem), @@ -629,6 +632,7 @@ lra_spill (void) for (i = 0; i < n; i++) if (pseudo_slots[pseudo_regnos[i]].mem == NULL_RTX) assign_mem_slot (pseudo_regnos[i]); + lra_update_fp2sp_elimination (); if (n > 0 && crtl->stack_alignment_needed) /* If we have a stack frame, we must align it now. The stack size may be a part of the offset computation for register diff --git a/gcc/testsuite/gcc.target/avr/lra-elim.c b/gcc/testsuite/gcc.target/avr/lra-elim.c new file mode 100644 index 0000000..d5086a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/lra-elim.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mmcu=avr25 -Os" } */ + +typedef int HItype __attribute__ ((mode (HI))); +HItype +__mulvhi3 (HItype a, HItype b) +{ + HItype w; + + if (__builtin_mul_overflow (a, b, &w)) + __builtin_trap (); + + return w; +} -- cgit v1.1 From 01f6e8b013237041adeac370f8d229aea6304591 Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Wed, 19 Jul 2023 21:01:53 +0100 Subject: PR modula2/110284 Make-lang-in m2flex.o and m2pp.o This patch moves the rule c-family/m2pp.o from Make-lang.in into Make-maintainer.in. It also adds m2/gm2-gcc/rtegraph.o and m2/gm2-compiler-boot/m2flex.o to m2_OBJS. The object m2/gm2-compiler-boot/m2flex.o is needed by cc1gm2 whereas m2/gm2-compiler/m2flex.o is required by m2/stage2/cc1gm2 (which is only built in maintainer to allow debugging via m2 sources rather than the translated to C++ sources). PR modula2/110284 * Make-lang.in (m2_OBJS): Add m2/gm2-gcc/rtegraph.o and m2/gm2-compiler-boot/m2flex.o. (c-family/m2pp.o): Remove. * Make-maintainer.in (c-family/m2pp.o): Add. Signed-off-by: Gaius Mulley --- gcc/m2/Make-lang.in | 7 ++----- gcc/m2/Make-maintainer.in | 4 ++++ 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in index ab82113..23632c2 100644 --- a/gcc/m2/Make-lang.in +++ b/gcc/m2/Make-lang.in @@ -516,7 +516,8 @@ GM2_LIBS_BOOT = m2/gm2-compiler-boot/gm2.a \ m2/gm2-libs-boot/libgm2.a \ $(GM2-BOOT-O) -m2_OBJS = $(GM2_C_OBJS) +m2_OBJS = $(GM2_C_OBJS) m2/gm2-gcc/rtegraph.o \ + m2/gm2-compiler-boot/m2flex.o cc1gm2$(exeext): m2/stage1/cc1gm2$(exeext) $(m2.prev) cp -p $< $@ @@ -586,10 +587,6 @@ m2/gm2-gcc/rtegraph.o: $(srcdir)/m2/gm2-gcc/rtegraph.cc $(GCC_HEADER_DEPENDENCIE $(COMPILER) -c -g $(GM2GCC) $(ALL_COMPILERFLAGS) \ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -c-family/m2pp.o : $(srcdir)/m2/m2pp.cc $(GCC_HEADER_DEPENDENCIES_FOR_M2) - $(COMPILER) -c -g $(ALL_COMPILERFLAGS) \ - $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) - m2/gm2-gcc/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-gcc/%.def $(MCDEPS) -test -d $(@D) || $(mkinstalldirs) $(@D) $(MC) -o=$@ $(srcdir)/m2/gm2-gcc/$*.def diff --git a/gcc/m2/Make-maintainer.in b/gcc/m2/Make-maintainer.in index 363e6ed..c94d15b 100644 --- a/gcc/m2/Make-maintainer.in +++ b/gcc/m2/Make-maintainer.in @@ -150,6 +150,10 @@ m2/gm2-ppg-boot/main.o: $(M2LINK) $(srcdir)/m2/init/mcinit m2/gm2-auto: -test -d $@ || $(mkinstalldirs) $@ +c-family/m2pp.o : $(srcdir)/m2/m2pp.cc $(GCC_HEADER_DEPENDENCIES_FOR_M2) + $(COMPILER) -c -g $(ALL_COMPILERFLAGS) \ + $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + # m2/pg$(exext) is the 2nd generation parser generator built from ebnf # without error recovery -- cgit v1.1 From 92d1425ca7804000cfe8aa635cf363a87d362d75 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 19 Jul 2023 16:10:20 -0400 Subject: c++: redundant targ coercion for var/alias tmpls When stepping through the variable/alias template specialization code paths, I noticed we perform template argument coercion twice: first from lookup_template_variable / instantiate_alias_template and again from tsubst_decl (during instantiate_template). It'd be nice to avoid this redundant second coercion. It turns out this coercion in tsubst_decl could be safely elided whenever fully specializing a primary variable/alias template, because we can rely on lookup_template_variable / instantiate_alias_template to already have coerced the arguments. The only other situation to consider seems to be when fully specializing a partial variable template specialization (from instantiate_template), in which case the passed 'args' are the (already coerced) arguments relative to the partial template, and the resulting 'argvec' are the (uncoerced) arguments relative to the primary template, so coercion is still necessary. But computing 'argvec' here is only really necessary in order to look up (and insert into) the specializations table. And instantiate_template already performs a lookup, so if we just made it register the resulting specialization too then we could avoid having to compute 'argvec' when called from instantiate_template, which in turns means we could avoid the coercion altogether. This patch implements this approach. gcc/cp/ChangeLog: * pt.cc (tsubst_function_decl): Add defaulted 'use_spec_table' flag parameter. Don't look up or insert into the specializations table if 'use_spec_table' is false. (tsubst_decl): Add defaulted 'use_spec_table' flag parameter. Check for error_mark_node. : Pass 'use_spec_table' to tsubst_function_decl. : Don't call coerce_template_parms. Don't look up or insert into the specializations table if 'use_spec_table' is false. Exit earlier if the substituted type is erroneous and we're not complaining, and do so for alias specializations as well. (instantiate_template): Pass false as 'use_spec_table' to tsubst_decl. Call register_specialization afterwards. --- gcc/cp/pt.cc | 115 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 50 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 255d18b..d882e9d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -204,7 +204,7 @@ static bool invalid_nontype_parm_type_p (tree, tsubst_flags_t); static bool dependent_template_arg_p (tree); static bool dependent_type_p_r (tree); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); -static tree tsubst_decl (tree, tree, tsubst_flags_t); +static tree tsubst_decl (tree, tree, tsubst_flags_t, bool = true); static tree tsubst_scope (tree, tree, tsubst_flags_t, tree); static void perform_instantiation_time_access_checks (tree, tree); static tree listify (tree); @@ -14304,7 +14304,7 @@ maybe_rebuild_function_decl_type (tree decl) static tree tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, - tree lambda_fntype) + tree lambda_fntype, bool use_spec_table = true) { tree gen_tmpl = NULL_TREE, argvec = NULL_TREE; hashval_t hash = 0; @@ -14345,22 +14345,27 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, /* Calculate the complete set of arguments used to specialize R. */ - argvec = tsubst_template_args (DECL_TI_ARGS - (DECL_TEMPLATE_RESULT - (DECL_TI_TEMPLATE (t))), - args, complain, in_decl); - if (argvec == error_mark_node) - return error_mark_node; - - /* Check to see if we already have this specialization. */ - if (!lambda_fntype) + if (use_spec_table) { - hash = spec_hasher::hash (gen_tmpl, argvec); - if (tree spec = retrieve_specialization (gen_tmpl, argvec, hash)) - /* The spec for these args might be a partial instantiation of the - template, but here what we want is the FUNCTION_DECL. */ - return STRIP_TEMPLATE (spec); + argvec = tsubst_template_args (DECL_TI_ARGS + (DECL_TEMPLATE_RESULT + (DECL_TI_TEMPLATE (t))), + args, complain, in_decl); + if (argvec == error_mark_node) + return error_mark_node; + + /* Check to see if we already have this specialization. */ + if (!lambda_fntype) + { + hash = spec_hasher::hash (gen_tmpl, argvec); + if (tree spec = retrieve_specialization (gen_tmpl, argvec, hash)) + /* The spec for these args might be a partial instantiation of the + template, but here what we want is the FUNCTION_DECL. */ + return STRIP_TEMPLATE (spec); + } } + else + argvec = args; } else { @@ -14527,12 +14532,15 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, = build_template_info (gen_tmpl, argvec); SET_DECL_IMPLICIT_INSTANTIATION (r); - tree new_r - = register_specialization (r, gen_tmpl, argvec, false, hash); - if (new_r != r) - /* We instantiated this while substituting into - the type earlier (template/friend54.C). */ - return new_r; + if (use_spec_table) + { + tree new_r + = register_specialization (r, gen_tmpl, argvec, false, hash); + if (new_r != r) + /* We instantiated this while substituting into + the type earlier (template/friend54.C). */ + return new_r; + } /* We're not supposed to instantiate default arguments until they are called, for a template. But, for a @@ -14855,10 +14863,14 @@ enclosing_instantiation_of (tree tctx) /* Substitute the ARGS into the T, which is a _DECL. Return the result of the substitution. Issue error and warning messages under - control of COMPLAIN. */ + control of COMPLAIN. The flag USE_SPEC_TABLE controls if we look up + and insert into the specializations table or if we can assume it's + the caller's responsibility; this is used by instantiate_template + to avoid doing some redundant work. */ static tree -tsubst_decl (tree t, tree args, tsubst_flags_t complain) +tsubst_decl (tree t, tree args, tsubst_flags_t complain, + bool use_spec_table /* = true */) { #define RETURN(EXP) do { r = (EXP); goto out; } while(0) location_t saved_loc; @@ -14866,6 +14878,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) tree in_decl = t; hashval_t hash = 0; + if (t == error_mark_node) + return error_mark_node; + /* Set the filename and linenumber to improve error-reporting. */ saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (t); @@ -14879,7 +14894,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) break; case FUNCTION_DECL: - r = tsubst_function_decl (t, args, complain, /*lambda*/NULL_TREE); + r = tsubst_function_decl (t, args, complain, /*lambda*/NULL_TREE, + use_spec_table); break; case PARM_DECL: @@ -15228,21 +15244,17 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (!spec) { tmpl = DECL_TI_TEMPLATE (t); - gen_tmpl = most_general_template (tmpl); - argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); - if (argvec != error_mark_node - && PRIMARY_TEMPLATE_P (gen_tmpl) - && TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (argvec)) - /* We're fully specializing a template declaration, so - we need to coerce the innermost arguments corresponding to - the template. */ - argvec = (coerce_template_parms - (DECL_TEMPLATE_PARMS (gen_tmpl), - argvec, tmpl, complain)); - if (argvec == error_mark_node) - RETURN (error_mark_node); - hash = spec_hasher::hash (gen_tmpl, argvec); - spec = retrieve_specialization (gen_tmpl, argvec, hash); + if (use_spec_table) + { + argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); + if (argvec == error_mark_node) + RETURN (error_mark_node); + gen_tmpl = most_general_template (tmpl); + hash = spec_hasher::hash (gen_tmpl, argvec); + spec = retrieve_specialization (gen_tmpl, argvec, hash); + } + else + argvec = args; } } else @@ -15287,20 +15299,20 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) type = tsubst (type, args, tcomplain, in_decl); /* Substituting the type might have recursively instantiated this same alias (c++/86171). */ - if (gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl) + if (use_spec_table && gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl) && (spec = retrieve_specialization (gen_tmpl, argvec, hash))) { r = spec; break; } } + if (type == error_mark_node && !(complain & tf_error)) + RETURN (error_mark_node); r = copy_decl (t); if (VAR_P (r)) { DECL_INITIALIZED_P (r) = 0; DECL_TEMPLATE_INSTANTIATED (r) = 0; - if (type == error_mark_node) - RETURN (error_mark_node); if (TREE_CODE (type) == FUNCTION_TYPE) { /* It may seem that this case cannot occur, since: @@ -15404,7 +15416,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec); SET_DECL_IMPLICIT_INSTANTIATION (r); - if (!error_operand_p (r) || (complain & tf_error)) + if (use_spec_table) register_specialization (r, gen_tmpl, argvec, false, hash); } else @@ -21991,7 +22003,6 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) tree targ_ptr = orig_args; tree fndecl; tree gen_tmpl; - tree spec; bool access_ok = true; if (tmpl == error_mark_node) @@ -22038,9 +22049,8 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (tmpl)), targ_ptr)); - /* It would be nice to avoid hashing here and then again in tsubst_decl, - but it doesn't seem to be on the hot path. */ - spec = retrieve_specialization (gen_tmpl, targ_ptr, 0); + hashval_t hash = spec_hasher::hash (gen_tmpl, targ_ptr); + tree spec = retrieve_specialization (gen_tmpl, targ_ptr, hash); gcc_checking_assert (tmpl == gen_tmpl || ((fndecl @@ -22108,13 +22118,14 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) tree partial_tmpl = TI_TEMPLATE (partial_ti); tree partial_args = TI_ARGS (partial_ti); tree partial_pat = DECL_TEMPLATE_RESULT (partial_tmpl); - fndecl = tsubst (partial_pat, partial_args, complain, gen_tmpl); + fndecl = tsubst_decl (partial_pat, partial_args, complain, + /*use_spec_table=*/false); } } /* Substitute template parameters to obtain the specialization. */ if (fndecl == NULL_TREE) - fndecl = tsubst (pattern, targ_ptr, complain, gen_tmpl); + fndecl = tsubst_decl (pattern, targ_ptr, complain, /*use_spec_table=*/false); if (DECL_CLASS_SCOPE_P (gen_tmpl)) pop_nested_class (); pop_from_top_level (); @@ -22134,6 +22145,10 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) remember the result of most_specialized_partial_spec for it. */ TI_PARTIAL_INFO (DECL_TEMPLATE_INFO (fndecl)) = partial_ti; + fndecl = register_specialization (fndecl, gen_tmpl, targ_ptr, false, hash); + if (fndecl == error_mark_node) + return error_mark_node; + set_instantiating_module (fndecl); /* Now we know the specialization, compute access previously -- cgit v1.1 From 74477d25a2c9e6790f3bc1e8b908fc32013614ca Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 19 Jul 2023 16:11:38 -0400 Subject: c++: deducing empty type vs non-type argument pack Within a template parameter list, a non-type template parameter pack is represented as a PARM_DECL. But in a couple of spots where we need to deduce and create an empty argument pack, we test for TEMPLATE_PARM_INDEX (within a template parameter list) instead of for PARM_DECL, and so we end up creating a TYPE_ARGUMENT_PACK even in the non-type case. This patch fixes this (seemingly harmless) bug. gcc/cp/ChangeLog: * pt.cc (type_unification_real): Test for PARM_DECL instead of TEMPLATE_PARM_INDEX to distinguish a type vs non-type template parameter pack. (type_targs_deducible_from): Likewise. --- gcc/cp/pt.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d882e9d..21b08a6 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -23367,7 +23367,7 @@ type_unification_real (tree tparms, { tree arg; - if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX) + if (TREE_CODE (tparm) == PARM_DECL) { arg = make_node (NONTYPE_ARGUMENT_PACK); TREE_CONSTANT (arg) = 1; @@ -30398,7 +30398,7 @@ type_targs_deducible_from (tree tmpl, tree type) if (template_parameter_pack_p (tparm)) { tree arg; - if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX) + if (TREE_CODE (tparm) == PARM_DECL) { arg = make_node (NONTYPE_ARGUMENT_PACK); TREE_CONSTANT (arg) = 1; -- cgit v1.1 From b1ae46bdd19fc2aaea41bc894168bdaf4799be80 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 19 Jul 2023 13:31:52 -0400 Subject: c++: -Wmissing-field-initializers and empty class [PR110064] Let's suppress -Wmissing-field-initializers for empty classes. Here I don't think I need the usual COMPLETE_TYPE_P/dependent_type_p checks. PR c++/110064 gcc/cp/ChangeLog: * typeck2.cc (process_init_constructor_record): Don't emit -Wmissing-field-initializers for empty classes. gcc/testsuite/ChangeLog: * g++.dg/warn/Wmissing-field-initializers-3.C: New test. --- gcc/cp/typeck2.cc | 3 +- .../g++.dg/warn/Wmissing-field-initializers-3.C | 48 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-3.C (limited to 'gcc') diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index 1c204c86..582a73b 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -1874,7 +1874,8 @@ process_init_constructor_record (tree type, tree init, int nested, int flags, to zero. */ if ((complain & tf_warning) && !cp_unevaluated_operand - && !EMPTY_CONSTRUCTOR_P (init)) + && !EMPTY_CONSTRUCTOR_P (init) + && !is_really_empty_class (fldtype, /*ignore_vptr*/false)) warning (OPT_Wmissing_field_initializers, "missing initializer for member %qD", field); diff --git a/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-3.C b/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-3.C new file mode 100644 index 0000000..a8d75b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-3.C @@ -0,0 +1,48 @@ +// PR c++/110064 +// { dg-do compile { target c++17 } } +// { dg-options "-Wmissing-field-initializers" } + +struct B { }; +struct D : B { + int x; + int y; +}; + +struct E { + int x; + int y; + B z; +}; + +template struct X { }; + +template +struct F { + int i; + int j; + X x; +}; + +int +main () +{ + D d = {.x=1, .y=2}; // { dg-bogus "missing" } + (void)d; + E e = {.x=1, .y=2}; // { dg-bogus "missing" } + (void)e; + F f = {.i=1, .j=2 }; // { dg-bogus "missing" } + (void)f; +} + +template +void fn () +{ + F f = {.i=1, .j=2 }; // { dg-bogus "missing" } + (void)f; +} + +void +g () +{ + fn (); +} -- cgit v1.1 From b86c0fe327a5196a316bd698d12765b08de5dce7 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 19 Jul 2023 17:55:09 -0400 Subject: analyzer: fix ICE on division of tainted floating-point values [PR110700] gcc/analyzer/ChangeLog: PR analyzer/110700 * region-model-manager.cc (region_model_manager::get_or_create_int_cst): Assert that we have an integral or pointer type. * sm-taint.cc (taint_state_machine::check_for_tainted_divisor): Don't check non-integral types. gcc/testsuite/ChangeLog: PR analyzer/110700 * gcc.dg/analyzer/taint-divisor-2.c: New test. Signed-off-by: David Malcolm --- gcc/analyzer/region-model-manager.cc | 1 + gcc/analyzer/sm-taint.cc | 6 ++++++ gcc/testsuite/gcc.dg/analyzer/taint-divisor-2.c | 13 +++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/taint-divisor-2.c (limited to 'gcc') diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 4f11ef4..e43b99a 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -234,6 +234,7 @@ region_model_manager::get_or_create_int_cst (tree type, const poly_wide_int_ref &cst) { gcc_assert (type); + gcc_assert (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)); tree tree_cst = wide_int_to_tree (type, cst); return get_or_create_constant_svalue (tree_cst); } diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index 6d28d1f..09c1e93 100644 --- a/gcc/analyzer/sm-taint.cc +++ b/gcc/analyzer/sm-taint.cc @@ -1344,6 +1344,12 @@ taint_state_machine::check_for_tainted_divisor (sm_context *sm_ctxt, return; tree divisor_expr = gimple_assign_rhs2 (assign);; + + /* Until we track conditions on floating point values, we can't check to + see if they've been checked against zero. */ + if (!INTEGRAL_TYPE_P (TREE_TYPE (divisor_expr))) + return; + const svalue *divisor_sval = old_model->get_rvalue (divisor_expr, NULL); state_t state = sm_ctxt->get_state (assign, divisor_sval); diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-divisor-2.c b/gcc/testsuite/gcc.dg/analyzer/taint-divisor-2.c new file mode 100644 index 0000000..de9a1cb --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/taint-divisor-2.c @@ -0,0 +1,13 @@ +// TODO: remove need for this option: +/* { dg-additional-options "-fanalyzer-checker=taint" } */ + +#include "analyzer-decls.h" + +__attribute__ ((tainted_args)) +double pr110700 (double x, double y) +{ + /* Ideally we'd complain here with -Wanalyzer-tainted-divisor, but + until we track conditions on floating point values, we can't check to + see if they've been checked against zero. */ + return x / y; +} -- cgit v1.1 From e92ca8d3b4cab96a9f79466b5158381cb3103f9d Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 19 Jul 2023 16:50:00 -0400 Subject: c++: Improve printing of base classes [PR110745] This patch changes warning: missing initializer for member 'D::' [-Wmissing-field-initializers] to warning: missing initializer for member 'D::B' [-Wmissing-field-initializers] PR c++/110745 gcc/cp/ChangeLog: * error.cc (dump_simple_decl): Print base class name. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/base.C: New test. --- gcc/cp/error.cc | 2 ++ gcc/testsuite/g++.dg/diagnostic/base.C | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 gcc/testsuite/g++.dg/diagnostic/base.C (limited to 'gcc') diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 31319aa..8a5219a 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -1177,6 +1177,8 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags) } else if (DECL_DECOMPOSITION_P (t)) pp_string (pp, M_("")); + else if (TREE_CODE (t) == FIELD_DECL && DECL_FIELD_IS_BASE (t)) + dump_type (pp, TREE_TYPE (t), flags); else pp_string (pp, M_("")); diff --git a/gcc/testsuite/g++.dg/diagnostic/base.C b/gcc/testsuite/g++.dg/diagnostic/base.C new file mode 100644 index 0000000..1540414 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/base.C @@ -0,0 +1,16 @@ +// PR c++/110745 +// { dg-do compile { target c++17 } } +// { dg-options "-Wmissing-field-initializers" } + +struct B { int i; }; +struct D : B { + int x; + int y; +}; + +int +main () +{ + D d = {.x=1, .y=2}; // { dg-warning "missing initializer for member .D::B." } + (void)d; +} -- cgit v1.1 From 49bed11d96cf727de7e6ed35f065a4df29f6c589 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 20 Jul 2023 00:17:53 +0000 Subject: Daily bump. --- gcc/ChangeLog | 124 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/analyzer/ChangeLog | 9 ++++ gcc/cp/ChangeLog | 35 ++++++++++++++ gcc/fortran/ChangeLog | 8 ++++ gcc/m2/ChangeLog | 60 +++++++++++++++++++++++ gcc/testsuite/ChangeLog | 110 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 347 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 11ca33b..47b872b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,127 @@ +2023-07-19 Vladimir N. Makarov + + * lra-int.h (lra_update_fp2sp_elimination): New prototype. + (lra_asm_insn_error): New prototype. + * lra-spills.cc (remove_pseudos): Add check for pseudo slot memory + existence. + (lra_spill): Call lra_update_fp2sp_elimination. + * lra-eliminations.cc: Remove trailing spaces. + (elimination_fp2sp_occured_p): New static flag. + (lra_eliminate_regs_1): Set the flag up. + (update_reg_eliminate): Modify the assert for stack to frame + pointer elimination. + (lra_update_fp2sp_elimination): New function. + (lra_eliminate): Clear flag elimination_fp2sp_occured_p. + +2023-07-19 Andrew Carlotti + + * config/aarch64/aarch64.h (TARGET_MEMTAG): Remove armv8.5 + dependency. + * config/aarch64/arm_acle.h: Remove unnecessary armv8.x + dependencies from target pragmas. + * config/aarch64/arm_fp16.h (target): Likewise. + * config/aarch64/arm_neon.h (target): Likewise. + +2023-07-19 Andrew Pinski + + PR tree-optimization/110252 + * tree-ssa-phiopt.cc (class auto_flow_sensitive): New class. + (auto_flow_sensitive::auto_flow_sensitive): New constructor. + (auto_flow_sensitive::~auto_flow_sensitive): New deconstructor. + (match_simplify_replacement): Temporarily + remove the flow sensitive info on the two statements that might + be moved. + +2023-07-19 Andrew Pinski + + * gimple-fold.cc (fosa_unwind): Replace `vrange_storage *` + with flow_sensitive_info_storage. + (follow_outer_ssa_edges): Update how to save off the flow + sensitive info. + (maybe_fold_comparisons_from_match_pd): Update restoring + of flow sensitive info. + * tree-ssanames.cc (flow_sensitive_info_storage::save): New method. + (flow_sensitive_info_storage::restore): New method. + (flow_sensitive_info_storage::save_and_clear): New method. + (flow_sensitive_info_storage::clear_storage): New method. + * tree-ssanames.h (class flow_sensitive_info_storage): New class. + +2023-07-19 Andrew Pinski + + PR tree-optimization/110726 + * match.pd ((a|b)&(a==b),a|(a==b),(a&b)|(a==b)): + Add checks to make sure the type was one bit precision + intergal type. + +2023-07-19 Ju-Zhe Zhong + + * doc/md.texi: Add mask_len_fold_left_plus. + * internal-fn.cc (mask_len_fold_left_direct): Ditto. + (expand_mask_len_fold_left_optab_fn): Ditto. + (direct_mask_len_fold_left_optab_supported_p): Ditto. + * internal-fn.def (MASK_LEN_FOLD_LEFT_PLUS): Ditto. + * optabs.def (OPTAB_D): Ditto. + +2023-07-19 Jakub Jelinek + + * tree-switch-conversion.h (class bit_test_cluster): Fix comment typo. + +2023-07-19 Jakub Jelinek + + PR tree-optimization/110731 + * wide-int.cc (wi::divmod_internal): Always unpack dividend and + divisor as UNSIGNED regardless of sgn. + +2023-07-19 Lehua Ding + + * common/config/riscv/riscv-common.cc (riscv_supported_std_ext): Init. + (standard_extensions_p): Add check. + (riscv_subset_list::add): Just return NULL if it failed before. + (riscv_subset_list::parse_std_ext): Continue parse when find a error + (riscv_subset_list::parse): Just return NULL if it failed before. + * config/riscv/riscv-subset.h (class riscv_subset_list): Add field. + +2023-07-19 Jan Beulich + + * config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate): + Use gen_vec_set_0. + (ix86_expand_vector_extract): Use gen_vec_extract_lo / + gen_vec_extract_hi. + (expand_vec_perm_broadcast_1): Use gen_vec_interleave_high / + gen_vec_interleave_low. Rename local variable. + +2023-07-19 Jan Beulich + + * config/i386/sse.md (vec_dupv2df): Add new AVX512F + alternative. Move AVX512VL part of condition to new "enabled" + attribute. + +2023-07-19 liuhongt + + PR target/109504 + * config/i386/i386-builtins.cc + (ix86_register_float16_builtin_type): Remove TARGET_SSE2. + (ix86_register_bf16_builtin_type): Ditto. + * config/i386/i386-c.cc (ix86_target_macros): When TARGET_SSE2 + isn't available, undef the macros which are used to check the + backend support of the _Float16/__bf16 types when building + libstdc++ and libgcc. + * config/i386/i386.cc (construct_container): Issue errors for + HFmode/BFmode when TARGET_SSE2 is not available. + (function_value_32): Ditto. + (ix86_scalar_mode_supported_p): Remove TARGET_SSE2 for HFmode/BFmode. + (ix86_libgcc_floating_mode_supported_p): Ditto. + (ix86_emit_support_tinfos): Adjust codes. + (ix86_invalid_conversion): Return diagnostic message string + when there's conversion from/to BF/HFmode w/o TARGET_SSE2. + (ix86_invalid_unary_op): New function. + (ix86_invalid_binary_op): Ditto. + (TARGET_INVALID_UNARY_OP): Define. + (TARGET_INVALID_BINARY_OP): Define. + * config/i386/immintrin.h [__SSE2__]: Remove for fp16/bf16 + related instrinsics header files. + * config/i386/i386.h (VALID_SSE2_TYPE_MODE): New macro. + 2023-07-18 Uros Bizjak * dwarf2asm.cc: Change FALSE to false. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 2292579..4b8414a 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230719 +20230720 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 6b38d38..e7565685 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,12 @@ +2023-07-19 David Malcolm + + PR analyzer/110700 + * region-model-manager.cc + (region_model_manager::get_or_create_int_cst): Assert that we have + an integral or pointer type. + * sm-taint.cc (taint_state_machine::check_for_tainted_divisor): + Don't check non-integral types. + 2023-06-29 benjamin priour PR analyzer/110198 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 968b815..59491e5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,38 @@ +2023-07-19 Marek Polacek + + PR c++/110745 + * error.cc (dump_simple_decl): Print base class name. + +2023-07-19 Marek Polacek + + PR c++/110064 + * typeck2.cc (process_init_constructor_record): Don't emit + -Wmissing-field-initializers for empty classes. + +2023-07-19 Patrick Palka + + * pt.cc (type_unification_real): Test for PARM_DECL instead + of TEMPLATE_PARM_INDEX to distinguish a type vs non-type + template parameter pack. + (type_targs_deducible_from): Likewise. + +2023-07-19 Patrick Palka + + * pt.cc (tsubst_function_decl): Add defaulted 'use_spec_table' + flag parameter. Don't look up or insert into the specializations + table if 'use_spec_table' is false. + (tsubst_decl): Add defaulted 'use_spec_table' flag parameter. + Check for error_mark_node. + : Pass 'use_spec_table' to + tsubst_function_decl. + : Don't call coerce_template_parms. + Don't look up or insert into the specializations table if + 'use_spec_table' is false. Exit earlier if the substituted + type is erroneous and we're not complaining, and do so for + alias specializations as well. + (instantiate_template): Pass false as 'use_spec_table' + to tsubst_decl. Call register_specialization afterwards. + 2023-07-18 Jason Merrill * constexpr.cc (cxx_eval_bit_cast): Check that the result of diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c64c52e..3663a74b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2023-07-19 Tobias Burnus + + PR fortran/107424 + * trans-openmp.cc (gfc_nonrect_loop_expr): Accept all + constant loop steps. + (gfc_trans_omp_do): Likewise; use sign to determine + loop direction. + 2023-07-17 Harald Anlauf PR fortran/95947 diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 62824f2..718c6f5 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,63 @@ +2023-07-19 Gaius Mulley + + PR modula2/110284 + * Make-lang.in (m2_OBJS): Add m2/gm2-gcc/rtegraph.o and + m2/gm2-compiler-boot/m2flex.o. + (c-family/m2pp.o): Remove. + * Make-maintainer.in (c-family/m2pp.o): Add. + +2023-07-19 Gaius Mulley + + * gm2-compiler/M2Quads.mod (BuildDifAdrFunction): Removed + unnecessary in error message. Use vartok for location. + (BuildOddFunction): Use optok for location. + (BuildAbsFunction): Use vartok for location. Bugfix set vartok. + (BuildCapFunction): Use optok for location. + (BuildOrdFunction): Use optok for location and correct format + specifier. + (BuildShiftFunction): Use vartok for location. + (BuildRotateFunction): Use vartok for location. + (BuildTruncFunction): Use vartok for location. + (BuildFloatFunction): Use vartok for location. + (BuildReFunction): Use vartok for location. + (BuildImFunction): Use vartok for location. + * gm2-compiler/M2SymInit.mod (trashParam): Remove commented code. + +2023-07-19 Gaius Mulley + + * gm2-compiler/M2Quads.mod (BuildRealFuncProcCall): Set the trash + parameter value to NIL if DEALLOCATE is detected. + * gm2-compiler/M2SymInit.mod (CheckDeferredRecordAccess): Pass + tok to SetVarInitialized. Pass tok to GetVarComponentInitialized. + (ComponentFindVar): Add tok parameter. Check aliased pointer + against Nil and generate warning if necessary. + (deRefComponent): Add tok and sym parameters and pass them to + getContent. + (SetVarComponentInitialized): Add tok parameter. Pass tok to + ComponentFindVar. Pass tok and sym to deRefComponent. + (GetVarComponentInitialized): Add tok parameter. Pass tok to + ComponentFindVar. Pass tok to deRefComponent. + (SetVarInitialized): Add tok parameter. Pass tok to + SetVarComponentInitialized. + (doGetVarInitialized): Add tok parameter. Pass tok to + GetVarComponentInitialized. + (CheckXIndr): Pass lhs and lhstok to getContent. + (CheckIndrX): Pass rhs and rhstok to getContent. + (CheckBecomes): Pass destok to ComponentFindVar. Pass des and + destok to deRefComponent. + (CheckAddr): Pass contenttok to GetVarInitialized. Pass ptrtok + to SetVarInitialized. + (CheckReadBeforeInitQuad): Pass op1tok to SetVarInitialized for + op1 cases and op3tok for op3 cases. + (trashParam): Get operand tokens. Pass op3tok to + SetVarInitialized. Pass op3 and op3tok to getContent. + Alias ptr to NIL if procedure is DEALLOCATE. Pass op3tok to + SetVarInitialized. + (IsDeallocate): New procedure function. + (DetectTrash): Use IsDeallocate. + (SetupLAlias): Allow exp to be Nil. + (getContent): Generate warning message if ptr is Nil. + 2023-07-18 Gaius Mulley * Make-lang.in: Minor formatting change. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 125c209..4345065 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,113 @@ +2023-07-19 Marek Polacek + + PR c++/110745 + * g++.dg/diagnostic/base.C: New test. + +2023-07-19 David Malcolm + + PR analyzer/110700 + * gcc.dg/analyzer/taint-divisor-2.c: New test. + +2023-07-19 Marek Polacek + + PR c++/110064 + * g++.dg/warn/Wmissing-field-initializers-3.C: New test. + +2023-07-19 Vladimir N. Makarov + + * gcc.target/avr/lra-elim.c: New test. + +2023-07-19 Gaius Mulley + + * gm2/errors/fail/badabs.mod: New test. + * gm2/errors/fail/badenum.mod: New test. + +2023-07-19 Andrew Carlotti + + * gcc.target/aarch64/feature-bf16-backport.c: New test. + * gcc.target/aarch64/feature-dotprod-backport.c: New test. + * gcc.target/aarch64/feature-fp16-backport.c: New test. + * gcc.target/aarch64/feature-fp16-scalar-backport.c: New test. + * gcc.target/aarch64/feature-fp16fml-backport.c: New test. + * gcc.target/aarch64/feature-i8mm-backport.c: New test. + * gcc.target/aarch64/feature-memtag-backport.c: New test. + * gcc.target/aarch64/feature-sha3-backport.c: New test. + * gcc.target/aarch64/feature-sm4-backport.c: New test. + +2023-07-19 Andrew Pinski + + PR tree-optimization/110252 + * gcc.dg/tree-ssa/phi-opt-25b.c: Updated as + __builtin_parity loses the nonzerobits info. + * gcc.c-torture/execute/pr110252-1.c: New test. + * gcc.c-torture/execute/pr110252-2.c: New test. + * gcc.c-torture/execute/pr110252-3.c: New test. + * gcc.c-torture/execute/pr110252-4.c: New test. + +2023-07-19 Andrew Pinski + + PR tree-optimization/110726 + * gcc.c-torture/execute/bitops-1.c: New test. + +2023-07-19 Gaius Mulley + + * gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod: New test. + +2023-07-19 Jakub Jelinek + + PR tree-optimization/110731 + * gcc.dg/pr110731.c: New test. + +2023-07-19 Maciej W. Rozycki + + * gcc.dg/vect/bb-slp-pr95839-v8.c: New test. + +2023-07-19 Tobias Burnus + + PR fortran/107424 + * gfortran.dg/gomp/linear-2.f90: Update dump to remove + the additional count variable. + +2023-07-19 Lehua Ding + + * gcc.target/riscv/arch-2.c: Update -march. + * gcc.target/riscv/arch-3.c: Ditto. + * gcc.target/riscv/arch-5.c: Ditto. + * gcc.target/riscv/arch-8.c: Ditto. + * gcc.target/riscv/attribute-10.c: Ditto. + * gcc.target/riscv/attribute-18.c: Ditto. + * gcc.target/riscv/attribute-19.c: Ditto. + * gcc.target/riscv/attribute-8.c: Ditto. + * gcc.target/riscv/attribute-9.c: Ditto. + * gcc.target/riscv/pr102957.c: Ditto. + * gcc.target/riscv/arch-22.cc: New test. + * gcc.target/riscv/arch-23.c: New file. + +2023-07-19 Lehua Ding + + * gcc.target/riscv/stack_save_restore.c: Moved to... + * gcc.target/riscv/stack_save_restore_2.c: ...here. + * gcc.target/riscv/stack_save_restore_1.c: New test. + +2023-07-19 Lewis Hyatt + + PR preprocessor/103902 + * g++.dg/cpp0x/udlit-extended-id-1.C: New test. + * g++.dg/cpp0x/udlit-extended-id-2.C: New test. + * g++.dg/cpp0x/udlit-extended-id-3.C: New test. + * g++.dg/cpp0x/udlit-extended-id-4.C: New test. + +2023-07-19 liuhongt + + * gcc.target/i386/pr109504.c: New test. + * gcc.target/i386/sse2-bfloat16-1.c: Adjust error info. + * gcc.target/i386/sse2-float16-1.c: Ditto. + * gcc.target/i386/sse2-float16-4.c: New test. + * gcc.target/i386/sse2-float16-5.c: New test. + * g++.target/i386/float16-1.C: Adjust error info. + 2023-07-18 Marek Polacek PR c++/110340 -- cgit v1.1 From 879c52c9dab5940a81aae8374831a6e4f78605ee Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Thu, 20 Jul 2023 07:21:20 +0800 Subject: RISC-V: Refactor RVV machine modes Current machine modes layout is hard to maintain && read && understand. For a LMUL = 1 SI vector mode: 1. VNx1SI mode when TARGET_MIN_VLEN = 32. 2. VNx2SI mode when TARGET_MIN_VLEN = 64. 3. VNx4SI mode when TARGET_MIN_VLEN = 128. Such implementation produces redundant machine modes and thus redudant machine description patterns. Now, this patch refactor machine modes into 3 follow formats: 1. mask mode: RVVMF64BImode, RVVMF32BImode, ...., RVVM1BImode. RVVMF64BImode means such mask mode occupy 1/64 of a RVV M1 reg. RVVM1BImode size = LMUL = 1 reg. 2. non-tuple vector modes: RVV: E.g. RVVMF8QImode = SEW = 8 && LMUL = MF8 3. tuple vector modes: RVVx. For example, for SEW = 16, LMUL = MF2 , int mode is always RVVMF4HImode, then adjust its size according to TARGET_MIN_VLEN. Before this patch, the machine description patterns: 17551 After this patch, the machine description patterns: 14132 =====> reduce 3K+ patterns. Regression of gcc/g++ rv32/rv64 all passed. Ok for trunk? gcc/ChangeLog: * config/riscv/autovec.md (len_mask_gather_load): Refactor RVV machine modes. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_gather_load): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (len_mask_scatter_store): Ditto. * config/riscv/riscv-modes.def (VECTOR_BOOL_MODE): Ditto. (ADJUST_NUNITS): Ditto. (ADJUST_ALIGNMENT): Ditto. (ADJUST_BYTESIZE): Ditto. (ADJUST_PRECISION): Ditto. (RVV_MODES): Ditto. (RVV_WHOLE_MODES): Ditto. (RVV_FRACT_MODE): Ditto. (RVV_NF8_MODES): Ditto. (RVV_NF4_MODES): Ditto. (VECTOR_MODES_WITH_PREFIX): Ditto. (VECTOR_MODE_WITH_PREFIX): Ditto. (RVV_TUPLE_MODES): Ditto. (RVV_NF2_MODES): Ditto. (RVV_TUPLE_PARTIAL_MODES): Ditto. * config/riscv/riscv-v.cc (struct mode_vtype_group): Ditto. (ENTRY): Ditto. (TUPLE_ENTRY): Ditto. (get_vlmul): Ditto. (get_nf): Ditto. (get_ratio): Ditto. (preferred_simd_mode): Ditto. (autovectorize_vector_modes): Ditto. * config/riscv/riscv-vector-builtins.cc (DEF_RVV_TYPE): Ditto. * config/riscv/riscv-vector-builtins.def (DEF_RVV_TYPE): Ditto. (vbool64_t): Ditto. (vbool32_t): Ditto. (vbool16_t): Ditto. (vbool8_t): Ditto. (vbool4_t): Ditto. (vbool2_t): Ditto. (vbool1_t): Ditto. (vint8mf8_t): Ditto. (vuint8mf8_t): Ditto. (vint8mf4_t): Ditto. (vuint8mf4_t): Ditto. (vint8mf2_t): Ditto. (vuint8mf2_t): Ditto. (vint8m1_t): Ditto. (vuint8m1_t): Ditto. (vint8m2_t): Ditto. (vuint8m2_t): Ditto. (vint8m4_t): Ditto. (vuint8m4_t): Ditto. (vint8m8_t): Ditto. (vuint8m8_t): Ditto. (vint16mf4_t): Ditto. (vuint16mf4_t): Ditto. (vint16mf2_t): Ditto. (vuint16mf2_t): Ditto. (vint16m1_t): Ditto. (vuint16m1_t): Ditto. (vint16m2_t): Ditto. (vuint16m2_t): Ditto. (vint16m4_t): Ditto. (vuint16m4_t): Ditto. (vint16m8_t): Ditto. (vuint16m8_t): Ditto. (vint32mf2_t): Ditto. (vuint32mf2_t): Ditto. (vint32m1_t): Ditto. (vuint32m1_t): Ditto. (vint32m2_t): Ditto. (vuint32m2_t): Ditto. (vint32m4_t): Ditto. (vuint32m4_t): Ditto. (vint32m8_t): Ditto. (vuint32m8_t): Ditto. (vint64m1_t): Ditto. (vuint64m1_t): Ditto. (vint64m2_t): Ditto. (vuint64m2_t): Ditto. (vint64m4_t): Ditto. (vuint64m4_t): Ditto. (vint64m8_t): Ditto. (vuint64m8_t): Ditto. (vfloat16mf4_t): Ditto. (vfloat16mf2_t): Ditto. (vfloat16m1_t): Ditto. (vfloat16m2_t): Ditto. (vfloat16m4_t): Ditto. (vfloat16m8_t): Ditto. (vfloat32mf2_t): Ditto. (vfloat32m1_t): Ditto. (vfloat32m2_t): Ditto. (vfloat32m4_t): Ditto. (vfloat32m8_t): Ditto. (vfloat64m1_t): Ditto. (vfloat64m2_t): Ditto. (vfloat64m4_t): Ditto. (vfloat64m8_t): Ditto. * config/riscv/riscv-vector-switch.def (ENTRY): Ditto. (TUPLE_ENTRY): Ditto. * config/riscv/riscv-vsetvl.cc (change_insn): Ditto. * config/riscv/riscv.cc (riscv_valid_lo_sum_p): Ditto. (riscv_v_adjust_nunits): Ditto. (riscv_v_adjust_bytesize): Ditto. (riscv_v_adjust_precision): Ditto. (riscv_convert_vector_bits): Ditto. * config/riscv/riscv.h (riscv_v_adjust_nunits): Ditto. * config/riscv/riscv.md: Ditto. * config/riscv/vector-iterators.md: Ditto. * config/riscv/vector.md (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_load): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. (@pred_indexed_store): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c: Adapt test. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c : Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c: Ditto. --- gcc/config/riscv/autovec.md | 198 +- gcc/config/riscv/riscv-modes.def | 570 +++-- gcc/config/riscv/riscv-v.cc | 67 +- gcc/config/riscv/riscv-vector-builtins.cc | 15 +- gcc/config/riscv/riscv-vector-builtins.def | 361 ++-- gcc/config/riscv/riscv-vector-switch.def | 581 +++-- gcc/config/riscv/riscv-vsetvl.cc | 24 +- gcc/config/riscv/riscv.cc | 87 +- gcc/config/riscv/riscv.h | 1 + gcc/config/riscv/riscv.md | 87 +- gcc/config/riscv/vector-iterators.md | 2236 ++++++++++---------- gcc/config/riscv/vector.md | 826 +++++--- .../rvv/autovec/gather-scatter/gather_load_run-7.c | 6 +- .../rvv/autovec/gather-scatter/gather_load_run-8.c | 6 +- .../autovec/gather-scatter/mask_scatter_store-9.c | 5 + .../gather-scatter/mask_scatter_store_run-8.c | 6 +- .../autovec/gather-scatter/scatter_store_run-8.c | 6 +- 17 files changed, 2496 insertions(+), 2586 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index cd5b194..0094720 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -61,105 +61,90 @@ ;; == Gather Load ;; ========================================================================= -(define_expand "len_mask_gather_load" - [(match_operand:VNX1_QHSD 0 "register_operand") +(define_expand "len_mask_gather_load" + [(match_operand:RATIO64 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX1_QHSDI 2 "register_operand") - (match_operand 3 "") - (match_operand 4 "") + (match_operand:RATIO64I 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); DONE; }) -(define_expand "len_mask_gather_load" - [(match_operand:VNX2_QHSD 0 "register_operand") +(define_expand "len_mask_gather_load" + [(match_operand:RATIO32 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX2_QHSDI 2 "register_operand") - (match_operand 3 "") - (match_operand 4 "") + (match_operand:RATIO32I 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); DONE; }) -(define_expand "len_mask_gather_load" - [(match_operand:VNX4_QHSD 0 "register_operand") +(define_expand "len_mask_gather_load" + [(match_operand:RATIO16 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX4_QHSDI 2 "register_operand") - (match_operand 3 "") - (match_operand 4 "") + (match_operand:RATIO16I 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); DONE; }) -(define_expand "len_mask_gather_load" - [(match_operand:VNX8_QHSD 0 "register_operand") +(define_expand "len_mask_gather_load" + [(match_operand:RATIO8 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX8_QHSDI 2 "register_operand") - (match_operand 3 "") - (match_operand 4 "") + (match_operand:RATIO8I 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); DONE; }) -(define_expand "len_mask_gather_load" - [(match_operand:VNX16_QHSD 0 "register_operand") +(define_expand "len_mask_gather_load" + [(match_operand:RATIO4 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX16_QHSDI 2 "register_operand") - (match_operand 3 "") - (match_operand 4 "") + (match_operand:RATIO4I 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); DONE; }) -(define_expand "len_mask_gather_load" - [(match_operand:VNX32_QHS 0 "register_operand") +(define_expand "len_mask_gather_load" + [(match_operand:RATIO2 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX32_QHSI 2 "register_operand") - (match_operand 3 "") - (match_operand 4 "") + (match_operand:RATIO2I 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] - "TARGET_VECTOR" -{ - riscv_vector::expand_gather_scatter (operands, true); - DONE; -}) - -(define_expand "len_mask_gather_load" - [(match_operand:VNX64_QH 0 "register_operand") - (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX64_QHI 2 "register_operand") - (match_operand 3 "") - (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -170,15 +155,15 @@ ;; larger SEW. Since RVV indexed load/store support zero extend ;; implicitly and not support scaling, we should only allow ;; operands[3] and operands[4] to be const_1_operand. -(define_expand "len_mask_gather_load" - [(match_operand:VNX128_Q 0 "register_operand") +(define_expand "len_mask_gather_load" + [(match_operand:RATIO1 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") - (match_operand:VNX128_Q 2 "register_operand") - (match_operand 3 "const_1_operand") - (match_operand 4 "const_1_operand") + (match_operand:RATIO1 2 "register_operand") + (match_operand 3 "") + (match_operand 4 "") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -189,105 +174,90 @@ ;; == Scatter Store ;; ========================================================================= -(define_expand "len_mask_scatter_store" - [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX1_QHSDI 1 "register_operand") - (match_operand 2 "") - (match_operand 3 "") - (match_operand:VNX1_QHSD 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] - "TARGET_VECTOR" -{ - riscv_vector::expand_gather_scatter (operands, false); - DONE; -}) - -(define_expand "len_mask_scatter_store" +(define_expand "len_mask_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX2_QHSDI 1 "register_operand") - (match_operand 2 "") - (match_operand 3 "") - (match_operand:VNX2_QHSD 4 "register_operand") + (match_operand:RATIO64I 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:RATIO64 4 "register_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "len_mask_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX4_QHSDI 1 "register_operand") - (match_operand 2 "") - (match_operand 3 "") - (match_operand:VNX4_QHSD 4 "register_operand") + (match_operand:RATIO32I 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:RATIO32 4 "register_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "len_mask_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX8_QHSDI 1 "register_operand") - (match_operand 2 "") - (match_operand 3 "") - (match_operand:VNX8_QHSD 4 "register_operand") + (match_operand:RATIO16I 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:RATIO16 4 "register_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "len_mask_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX16_QHSDI 1 "register_operand") - (match_operand 2 "") - (match_operand 3 "") - (match_operand:VNX16_QHSD 4 "register_operand") + (match_operand:RATIO8I 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:RATIO8 4 "register_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "len_mask_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX32_QHSI 1 "register_operand") - (match_operand 2 "") - (match_operand 3 "") - (match_operand:VNX32_QHS 4 "register_operand") + (match_operand:RATIO4I 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:RATIO4 4 "register_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "len_mask_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX64_QHI 1 "register_operand") - (match_operand 2 "") - (match_operand 3 "") - (match_operand:VNX64_QH 4 "register_operand") + (match_operand:RATIO2I 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:RATIO2 4 "register_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); @@ -298,15 +268,15 @@ ;; larger SEW. Since RVV indexed load/store support zero extend ;; implicitly and not support scaling, we should only allow ;; operands[3] and operands[4] to be const_1_operand. -(define_expand "len_mask_scatter_store" +(define_expand "len_mask_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") - (match_operand:VNX128_Q 1 "register_operand") - (match_operand 2 "const_1_operand") - (match_operand 3 "const_1_operand") - (match_operand:VNX128_Q 4 "register_operand") + (match_operand:RATIO1 1 "register_operand") + (match_operand 2 "") + (match_operand 3 "") + (match_operand:RATIO1 4 "register_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 7 "vector_mask_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def index 1d15270..d6b90e9 100644 --- a/gcc/config/riscv/riscv-modes.def +++ b/gcc/config/riscv/riscv-modes.def @@ -27,311 +27,287 @@ FLOAT_MODE (TF, 16, ieee_quad_format); /* Encode the ratio of SEW/LMUL into the mask types. There are the following * mask types. */ -/* | Mode | MIN_VLEN = 32 | MIN_VLEN = 64 | MIN_VLEN = 128 | - | | SEW/LMUL | SEW/LMUL | SEW/LMUL | - | VNx1BI | 32 | 64 | 128 | - | VNx2BI | 16 | 32 | 64 | - | VNx4BI | 8 | 16 | 32 | - | VNx8BI | 4 | 8 | 16 | - | VNx16BI | 2 | 4 | 8 | - | VNx32BI | 1 | 2 | 4 | - | VNx64BI | N/A | 1 | 2 | - | VNx128BI | N/A | N/A | 1 | */ +/* Encode the ratio of SEW/LMUL into the mask types. + There are the following mask types. + + n = SEW/LMUL + + |Modes| n = 1 | n = 2 | n = 4 | n = 8 | n = 16 | n = 32 | n = 64 | + |BI |RVVM1BI |RVVMF2BI |RVVMF4BI |RVVMF8BI |RVVMF16BI |RVVMF32BI |RVVMF64BI | */ /* For RVV modes, each boolean value occupies 1-bit. 4th argument is specify the minmial possible size of the vector mode, and will adjust to the right size by ADJUST_BYTESIZE. */ -VECTOR_BOOL_MODE (VNx1BI, 1, BI, 1); -VECTOR_BOOL_MODE (VNx2BI, 2, BI, 1); -VECTOR_BOOL_MODE (VNx4BI, 4, BI, 1); -VECTOR_BOOL_MODE (VNx8BI, 8, BI, 1); -VECTOR_BOOL_MODE (VNx16BI, 16, BI, 2); -VECTOR_BOOL_MODE (VNx32BI, 32, BI, 4); -VECTOR_BOOL_MODE (VNx64BI, 64, BI, 8); -VECTOR_BOOL_MODE (VNx128BI, 128, BI, 16); - -ADJUST_NUNITS (VNx1BI, riscv_v_adjust_nunits (VNx1BImode, 1)); -ADJUST_NUNITS (VNx2BI, riscv_v_adjust_nunits (VNx2BImode, 2)); -ADJUST_NUNITS (VNx4BI, riscv_v_adjust_nunits (VNx4BImode, 4)); -ADJUST_NUNITS (VNx8BI, riscv_v_adjust_nunits (VNx8BImode, 8)); -ADJUST_NUNITS (VNx16BI, riscv_v_adjust_nunits (VNx16BImode, 16)); -ADJUST_NUNITS (VNx32BI, riscv_v_adjust_nunits (VNx32BImode, 32)); -ADJUST_NUNITS (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 64)); -ADJUST_NUNITS (VNx128BI, riscv_v_adjust_nunits (VNx128BImode, 128)); - -ADJUST_ALIGNMENT (VNx1BI, 1); -ADJUST_ALIGNMENT (VNx2BI, 1); -ADJUST_ALIGNMENT (VNx4BI, 1); -ADJUST_ALIGNMENT (VNx8BI, 1); -ADJUST_ALIGNMENT (VNx16BI, 1); -ADJUST_ALIGNMENT (VNx32BI, 1); -ADJUST_ALIGNMENT (VNx64BI, 1); -ADJUST_ALIGNMENT (VNx128BI, 1); - -ADJUST_BYTESIZE (VNx1BI, riscv_v_adjust_bytesize (VNx1BImode, 1)); -ADJUST_BYTESIZE (VNx2BI, riscv_v_adjust_bytesize (VNx2BImode, 1)); -ADJUST_BYTESIZE (VNx4BI, riscv_v_adjust_bytesize (VNx4BImode, 1)); -ADJUST_BYTESIZE (VNx8BI, riscv_v_adjust_bytesize (VNx8BImode, 1)); -ADJUST_BYTESIZE (VNx16BI, riscv_v_adjust_bytesize (VNx16BImode, 2)); -ADJUST_BYTESIZE (VNx32BI, riscv_v_adjust_bytesize (VNx32BImode, 4)); -ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_bytesize (VNx64BImode, 8)); -ADJUST_BYTESIZE (VNx128BI, riscv_v_adjust_bytesize (VNx128BImode, 16)); - -ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1)); -ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2)); -ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4)); -ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8)); -ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16)); -ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32)); -ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64)); -ADJUST_PRECISION (VNx128BI, riscv_v_adjust_precision (VNx128BImode, 128)); - -/* - | Mode | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 | MIN_VLEN=128 | MIN_VLEN=128 | - | | LMUL | SEW/LMUL | LMUL | SEW/LMUL | LMUL | SEW/LMUL | - | VNx1QI | MF4 | 32 | MF8 | 64 | N/A | N/A | - | VNx2QI | MF2 | 16 | MF4 | 32 | MF8 | 64 | - | VNx4QI | M1 | 8 | MF2 | 16 | MF4 | 32 | - | VNx8QI | M2 | 4 | M1 | 8 | MF2 | 16 | - | VNx16QI | M4 | 2 | M2 | 4 | M1 | 8 | - | VNx32QI | M8 | 1 | M4 | 2 | M2 | 4 | - | VNx64QI | N/A | N/A | M8 | 1 | M4 | 2 | - | VNx128QI | N/A | N/A | N/A | N/A | M8 | 1 | - | VNx1(HI|HF) | MF2 | 32 | MF4 | 64 | N/A | N/A | - | VNx2(HI|HF) | M1 | 16 | MF2 | 32 | MF4 | 64 | - | VNx4(HI|HF) | M2 | 8 | M1 | 16 | MF2 | 32 | - | VNx8(HI|HF) | M4 | 4 | M2 | 8 | M1 | 16 | - | VNx16(HI|HF)| M8 | 2 | M4 | 4 | M2 | 8 | - | VNx32(HI|HF)| N/A | N/A | M8 | 2 | M4 | 4 | - | VNx64(HI|HF)| N/A | N/A | N/A | N/A | M8 | 2 | - | VNx1(SI|SF) | M1 | 32 | MF2 | 64 | MF2 | 64 | - | VNx2(SI|SF) | M2 | 16 | M1 | 32 | M1 | 32 | - | VNx4(SI|SF) | M4 | 8 | M2 | 16 | M2 | 16 | - | VNx8(SI|SF) | M8 | 4 | M4 | 8 | M4 | 8 | - | VNx16(SI|SF)| N/A | N/A | M8 | 4 | M8 | 4 | - | VNx1(DI|DF) | N/A | N/A | M1 | 64 | N/A | N/A | - | VNx2(DI|DF) | N/A | N/A | M2 | 32 | M1 | 64 | - | VNx4(DI|DF) | N/A | N/A | M4 | 16 | M2 | 32 | - | VNx8(DI|DF) | N/A | N/A | M8 | 8 | M4 | 16 | - | VNx16(DI|DF)| N/A | N/A | N/A | N/A | M8 | 8 | -*/ - -/* Define RVV modes whose sizes are multiples of 64-bit chunks. */ -#define RVV_MODES(NVECS, VB, VH, VS, VD) \ - VECTOR_MODE_WITH_PREFIX (VNx, INT, QI, 8 * NVECS, 0); \ - VECTOR_MODE_WITH_PREFIX (VNx, INT, HI, 4 * NVECS, 0); \ - VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, HF, 4 * NVECS, 0); \ - VECTOR_MODE_WITH_PREFIX (VNx, INT, SI, 2 * NVECS, 0); \ - VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, SF, 2 * NVECS, 0); \ - VECTOR_MODE_WITH_PREFIX (VNx, INT, DI, NVECS, 0); \ - VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, DF, NVECS, 0); \ +VECTOR_BOOL_MODE (RVVM1BI, 64, BI, 8); +VECTOR_BOOL_MODE (RVVMF2BI, 32, BI, 4); +VECTOR_BOOL_MODE (RVVMF4BI, 16, BI, 2); +VECTOR_BOOL_MODE (RVVMF8BI, 8, BI, 1); +VECTOR_BOOL_MODE (RVVMF16BI, 4, BI, 1); +VECTOR_BOOL_MODE (RVVMF32BI, 2, BI, 1); +VECTOR_BOOL_MODE (RVVMF64BI, 1, BI, 1); + +ADJUST_NUNITS (RVVM1BI, riscv_v_adjust_nunits (RVVM1BImode, 64)); +ADJUST_NUNITS (RVVMF2BI, riscv_v_adjust_nunits (RVVMF2BImode, 32)); +ADJUST_NUNITS (RVVMF4BI, riscv_v_adjust_nunits (RVVMF4BImode, 16)); +ADJUST_NUNITS (RVVMF8BI, riscv_v_adjust_nunits (RVVMF8BImode, 8)); +ADJUST_NUNITS (RVVMF16BI, riscv_v_adjust_nunits (RVVMF16BImode, 4)); +ADJUST_NUNITS (RVVMF32BI, riscv_v_adjust_nunits (RVVMF32BImode, 2)); +ADJUST_NUNITS (RVVMF64BI, riscv_v_adjust_nunits (RVVMF64BImode, 1)); + +ADJUST_ALIGNMENT (RVVM1BI, 1); +ADJUST_ALIGNMENT (RVVMF2BI, 1); +ADJUST_ALIGNMENT (RVVMF4BI, 1); +ADJUST_ALIGNMENT (RVVMF8BI, 1); +ADJUST_ALIGNMENT (RVVMF16BI, 1); +ADJUST_ALIGNMENT (RVVMF32BI, 1); +ADJUST_ALIGNMENT (RVVMF64BI, 1); + +ADJUST_PRECISION (RVVM1BI, riscv_v_adjust_precision (RVVM1BImode, 64)); +ADJUST_PRECISION (RVVMF2BI, riscv_v_adjust_precision (RVVMF2BImode, 32)); +ADJUST_PRECISION (RVVMF4BI, riscv_v_adjust_precision (RVVMF4BImode, 16)); +ADJUST_PRECISION (RVVMF8BI, riscv_v_adjust_precision (RVVMF8BImode, 8)); +ADJUST_PRECISION (RVVMF16BI, riscv_v_adjust_precision (RVVMF16BImode, 4)); +ADJUST_PRECISION (RVVMF32BI, riscv_v_adjust_precision (RVVMF32BImode, 2)); +ADJUST_PRECISION (RVVMF64BI, riscv_v_adjust_precision (RVVMF64BImode, 1)); + +ADJUST_BYTESIZE (RVVM1BI, riscv_v_adjust_bytesize (RVVM1BImode, 8)); +ADJUST_BYTESIZE (RVVMF2BI, riscv_v_adjust_bytesize (RVVMF2BImode, 4)); +ADJUST_BYTESIZE (RVVMF4BI, riscv_v_adjust_bytesize (RVVMF4BImode, 2)); +ADJUST_BYTESIZE (RVVMF8BI, riscv_v_adjust_bytesize (RVVMF8BImode, 1)); +ADJUST_BYTESIZE (RVVMF16BI, riscv_v_adjust_bytesize (RVVMF16BImode, 1)); +ADJUST_BYTESIZE (RVVMF32BI, riscv_v_adjust_bytesize (RVVMF32BImode, 1)); +ADJUST_BYTESIZE (RVVMF64BI, riscv_v_adjust_bytesize (RVVMF64BImode, 1)); + +/* Encode SEW and LMUL into data types. + We enforce the constraint LMUL ≥ SEW/ELEN in the implementation. + There are the following data types for ELEN = 64. + + |Modes|LMUL=1 |LMUL=2 |LMUL=4 |LMUL=8 |LMUL=1/2|LMUL=1/4|LMUL=1/8| + |DI |RVVM1DI|RVVM2DI|RVVM4DI|RVVM8DI|N/A |N/A |N/A | + |SI |RVVM1SI|RVVM2SI|RVVM4SI|RVVM8SI|RVVMF2SI|N/A |N/A | + |HI |RVVM1HI|RVVM2HI|RVVM4HI|RVVM8HI|RVVMF2HI|RVVMF4HI|N/A | + |QI |RVVM1QI|RVVM2QI|RVVM4QI|RVVM8QI|RVVMF2QI|RVVMF4QI|RVVMF8QI| + |DF |RVVM1DF|RVVM2DF|RVVM4DF|RVVM8DF|N/A |N/A |N/A | + |SF |RVVM1SF|RVVM2SF|RVVM4SF|RVVM8SF|RVVMF2SF|N/A |N/A | + |HF |RVVM1HF|RVVM2HF|RVVM4HF|RVVM8HF|RVVMF2HF|RVVMF4HF|N/A | + +There are the following data types for ELEN = 32. + + |Modes|LMUL=1 |LMUL=2 |LMUL=4 |LMUL=8 |LMUL=1/2|LMUL=1/4|LMUL=1/8| + |SI |RVVM1SI|RVVM2SI|RVVM4SI|RVVM8SI|N/A |N/A |N/A | + |HI |RVVM1HI|RVVM2HI|RVVM4HI|RVVM8HI|RVVMF2HI|N/A |N/A | + |QI |RVVM1QI|RVVM2QI|RVVM4QI|RVVM8QI|RVVMF2QI|RVVMF4QI|N/A | + |SF |RVVM1SF|RVVM2SF|RVVM4SF|RVVM8SF|N/A |N/A |N/A | + |HF |RVVM1HF|RVVM2HF|RVVM4HF|RVVM8HF|RVVMF2HF|N/A |N/A | */ + +#define RVV_WHOLE_MODES(LMUL) \ + VECTOR_MODE_WITH_PREFIX (RVVM, INT, QI, LMUL, 0); \ + VECTOR_MODE_WITH_PREFIX (RVVM, INT, HI, LMUL, 0); \ + VECTOR_MODE_WITH_PREFIX (RVVM, FLOAT, HF, LMUL, 0); \ + VECTOR_MODE_WITH_PREFIX (RVVM, INT, SI, LMUL, 0); \ + VECTOR_MODE_WITH_PREFIX (RVVM, FLOAT, SF, LMUL, 0); \ + VECTOR_MODE_WITH_PREFIX (RVVM, INT, DI, LMUL, 0); \ + VECTOR_MODE_WITH_PREFIX (RVVM, FLOAT, DF, LMUL, 0); \ + \ + ADJUST_NUNITS (RVVM##LMUL##QI, \ + riscv_v_adjust_nunits (RVVM##LMUL##QImode, false, LMUL, 1)); \ + ADJUST_NUNITS (RVVM##LMUL##HI, \ + riscv_v_adjust_nunits (RVVM##LMUL##HImode, false, LMUL, 1)); \ + ADJUST_NUNITS (RVVM##LMUL##SI, \ + riscv_v_adjust_nunits (RVVM##LMUL##SImode, false, LMUL, 1)); \ + ADJUST_NUNITS (RVVM##LMUL##DI, \ + riscv_v_adjust_nunits (RVVM##LMUL##DImode, false, LMUL, 1)); \ + ADJUST_NUNITS (RVVM##LMUL##HF, \ + riscv_v_adjust_nunits (RVVM##LMUL##HFmode, false, LMUL, 1)); \ + ADJUST_NUNITS (RVVM##LMUL##SF, \ + riscv_v_adjust_nunits (RVVM##LMUL##SFmode, false, LMUL, 1)); \ + ADJUST_NUNITS (RVVM##LMUL##DF, \ + riscv_v_adjust_nunits (RVVM##LMUL##DFmode, false, LMUL, 1)); \ + \ + ADJUST_ALIGNMENT (RVVM##LMUL##QI, 1); \ + ADJUST_ALIGNMENT (RVVM##LMUL##HI, 2); \ + ADJUST_ALIGNMENT (RVVM##LMUL##SI, 4); \ + ADJUST_ALIGNMENT (RVVM##LMUL##DI, 8); \ + ADJUST_ALIGNMENT (RVVM##LMUL##HF, 2); \ + ADJUST_ALIGNMENT (RVVM##LMUL##SF, 4); \ + ADJUST_ALIGNMENT (RVVM##LMUL##DF, 8); + +RVV_WHOLE_MODES (1) +RVV_WHOLE_MODES (2) +RVV_WHOLE_MODES (4) +RVV_WHOLE_MODES (8) + +#define RVV_FRACT_MODE(TYPE, MODE, LMUL, ALIGN) \ + VECTOR_MODE_WITH_PREFIX (RVVMF, TYPE, MODE, LMUL, 0); \ + ADJUST_NUNITS (RVVMF##LMUL##MODE, \ + riscv_v_adjust_nunits (RVVMF##LMUL##MODE##mode, true, LMUL, \ + 1)); \ + \ + ADJUST_ALIGNMENT (RVVMF##LMUL##MODE, ALIGN); + +RVV_FRACT_MODE (INT, QI, 2, 1) +RVV_FRACT_MODE (INT, QI, 4, 1) +RVV_FRACT_MODE (INT, QI, 8, 1) +RVV_FRACT_MODE (INT, HI, 2, 2) +RVV_FRACT_MODE (INT, HI, 4, 2) +RVV_FRACT_MODE (FLOAT, HF, 2, 2) +RVV_FRACT_MODE (FLOAT, HF, 4, 2) +RVV_FRACT_MODE (INT, SI, 2, 4) +RVV_FRACT_MODE (FLOAT, SF, 2, 4) + +/* Tuple modes for segment loads/stores according to NF. + + Tuple modes format: RVVx + + When LMUL is MF8/MF4/MF2/M1, NF can be 2 ~ 8. + When LMUL is M2, NF can be 2 ~ 4. + When LMUL is M4, NF can be 4. */ + +#define RVV_NF8_MODES(NF) \ + VECTOR_MODE_WITH_PREFIX (RVVMF8x, INT, QI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF4x, INT, QI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF2x, INT, QI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM1x, INT, QI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF4x, INT, HI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF2x, INT, HI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM1x, INT, HI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF4x, FLOAT, HF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF2x, FLOAT, HF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM1x, FLOAT, HF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF2x, INT, SI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM1x, INT, SI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVMF2x, FLOAT, SF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM1x, FLOAT, SF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM1x, INT, DI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM1x, FLOAT, DF, NF, 1); \ + \ + ADJUST_NUNITS (RVVMF8x##NF##QI, \ + riscv_v_adjust_nunits (RVVMF8x##NF##QImode, true, 8, NF)); \ + ADJUST_NUNITS (RVVMF4x##NF##QI, \ + riscv_v_adjust_nunits (RVVMF4x##NF##QImode, true, 4, NF)); \ + ADJUST_NUNITS (RVVMF2x##NF##QI, \ + riscv_v_adjust_nunits (RVVMF2x##NF##QImode, true, 2, NF)); \ + ADJUST_NUNITS (RVVM1x##NF##QI, \ + riscv_v_adjust_nunits (RVVM1x##NF##QImode, false, 1, NF)); \ + ADJUST_NUNITS (RVVMF4x##NF##HI, \ + riscv_v_adjust_nunits (RVVMF4x##NF##HImode, true, 4, NF)); \ + ADJUST_NUNITS (RVVMF2x##NF##HI, \ + riscv_v_adjust_nunits (RVVMF2x##NF##HImode, true, 2, NF)); \ + ADJUST_NUNITS (RVVM1x##NF##HI, \ + riscv_v_adjust_nunits (RVVM1x##NF##HImode, false, 1, NF)); \ + ADJUST_NUNITS (RVVMF4x##NF##HF, \ + riscv_v_adjust_nunits (RVVMF4x##NF##HFmode, true, 4, NF)); \ + ADJUST_NUNITS (RVVMF2x##NF##HF, \ + riscv_v_adjust_nunits (RVVMF2x##NF##HFmode, true, 2, NF)); \ + ADJUST_NUNITS (RVVM1x##NF##HF, \ + riscv_v_adjust_nunits (RVVM1x##NF##HFmode, false, 1, NF)); \ + ADJUST_NUNITS (RVVMF2x##NF##SI, \ + riscv_v_adjust_nunits (RVVMF2x##NF##SImode, true, 2, NF)); \ + ADJUST_NUNITS (RVVM1x##NF##SI, \ + riscv_v_adjust_nunits (RVVM1x##NF##SImode, false, 1, NF)); \ + ADJUST_NUNITS (RVVMF2x##NF##SF, \ + riscv_v_adjust_nunits (RVVMF2x##NF##SFmode, true, 2, NF)); \ + ADJUST_NUNITS (RVVM1x##NF##SF, \ + riscv_v_adjust_nunits (RVVM1x##NF##SFmode, false, 1, NF)); \ + ADJUST_NUNITS (RVVM1x##NF##DI, \ + riscv_v_adjust_nunits (RVVM1x##NF##DImode, false, 1, NF)); \ + ADJUST_NUNITS (RVVM1x##NF##DF, \ + riscv_v_adjust_nunits (RVVM1x##NF##DFmode, false, 1, NF)); \ + \ + ADJUST_ALIGNMENT (RVVMF8x##NF##QI, 1); \ + ADJUST_ALIGNMENT (RVVMF4x##NF##QI, 1); \ + ADJUST_ALIGNMENT (RVVMF2x##NF##QI, 1); \ + ADJUST_ALIGNMENT (RVVM1x##NF##QI, 1); \ + ADJUST_ALIGNMENT (RVVMF4x##NF##HI, 2); \ + ADJUST_ALIGNMENT (RVVMF2x##NF##HI, 2); \ + ADJUST_ALIGNMENT (RVVM1x##NF##HI, 2); \ + ADJUST_ALIGNMENT (RVVMF4x##NF##HF, 2); \ + ADJUST_ALIGNMENT (RVVMF2x##NF##HF, 2); \ + ADJUST_ALIGNMENT (RVVM1x##NF##HF, 2); \ + ADJUST_ALIGNMENT (RVVMF2x##NF##SI, 4); \ + ADJUST_ALIGNMENT (RVVM1x##NF##SI, 4); \ + ADJUST_ALIGNMENT (RVVMF2x##NF##SF, 4); \ + ADJUST_ALIGNMENT (RVVM1x##NF##SF, 4); \ + ADJUST_ALIGNMENT (RVVM1x##NF##DI, 8); \ + ADJUST_ALIGNMENT (RVVM1x##NF##DF, 8); + +RVV_NF8_MODES (8) +RVV_NF8_MODES (7) +RVV_NF8_MODES (6) +RVV_NF8_MODES (5) +RVV_NF8_MODES (4) +RVV_NF8_MODES (3) +RVV_NF8_MODES (2) + +#define RVV_NF4_MODES(NF) \ + VECTOR_MODE_WITH_PREFIX (RVVM2x, INT, QI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM2x, INT, HI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM2x, FLOAT, HF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM2x, INT, SI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM2x, FLOAT, SF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM2x, INT, DI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM2x, FLOAT, DF, NF, 1); \ \ - ADJUST_NUNITS (VB##QI, riscv_v_adjust_nunits (VB##QI##mode, NVECS * 8)); \ - ADJUST_NUNITS (VH##HI, riscv_v_adjust_nunits (VH##HI##mode, NVECS * 4)); \ - ADJUST_NUNITS (VS##SI, riscv_v_adjust_nunits (VS##SI##mode, NVECS * 2)); \ - ADJUST_NUNITS (VD##DI, riscv_v_adjust_nunits (VD##DI##mode, NVECS)); \ - ADJUST_NUNITS (VH##HF, riscv_v_adjust_nunits (VH##HF##mode, NVECS * 4)); \ - ADJUST_NUNITS (VS##SF, riscv_v_adjust_nunits (VS##SF##mode, NVECS * 2)); \ - ADJUST_NUNITS (VD##DF, riscv_v_adjust_nunits (VD##DF##mode, NVECS)); \ + ADJUST_NUNITS (RVVM2x##NF##QI, \ + riscv_v_adjust_nunits (RVVM2x##NF##QImode, false, 2, NF)); \ + ADJUST_NUNITS (RVVM2x##NF##HI, \ + riscv_v_adjust_nunits (RVVM2x##NF##HImode, false, 2, NF)); \ + ADJUST_NUNITS (RVVM2x##NF##HF, \ + riscv_v_adjust_nunits (RVVM2x##NF##HFmode, false, 2, NF)); \ + ADJUST_NUNITS (RVVM2x##NF##SI, \ + riscv_v_adjust_nunits (RVVM2x##NF##SImode, false, 2, NF)); \ + ADJUST_NUNITS (RVVM2x##NF##SF, \ + riscv_v_adjust_nunits (RVVM2x##NF##SFmode, false, 2, NF)); \ + ADJUST_NUNITS (RVVM2x##NF##DI, \ + riscv_v_adjust_nunits (RVVM2x##NF##DImode, false, 2, NF)); \ + ADJUST_NUNITS (RVVM2x##NF##DF, \ + riscv_v_adjust_nunits (RVVM2x##NF##DFmode, false, 2, NF)); \ \ - ADJUST_ALIGNMENT (VB##QI, 1); \ - ADJUST_ALIGNMENT (VH##HI, 2); \ - ADJUST_ALIGNMENT (VS##SI, 4); \ - ADJUST_ALIGNMENT (VD##DI, 8); \ - ADJUST_ALIGNMENT (VH##HF, 2); \ - ADJUST_ALIGNMENT (VS##SF, 4); \ - ADJUST_ALIGNMENT (VD##DF, 8); - -RVV_MODES (1, VNx8, VNx4, VNx2, VNx1) -RVV_MODES (2, VNx16, VNx8, VNx4, VNx2) -RVV_MODES (4, VNx32, VNx16, VNx8, VNx4) -RVV_MODES (8, VNx64, VNx32, VNx16, VNx8) -RVV_MODES (16, VNx128, VNx64, VNx32, VNx16) - -VECTOR_MODES_WITH_PREFIX (VNx, INT, 4, 0); -VECTOR_MODES_WITH_PREFIX (VNx, FLOAT, 4, 0); -ADJUST_NUNITS (VNx4QI, riscv_v_adjust_nunits (VNx4QImode, 4)); -ADJUST_NUNITS (VNx2HI, riscv_v_adjust_nunits (VNx2HImode, 2)); -ADJUST_NUNITS (VNx2HF, riscv_v_adjust_nunits (VNx2HFmode, 2)); -ADJUST_ALIGNMENT (VNx4QI, 1); -ADJUST_ALIGNMENT (VNx2HI, 2); -ADJUST_ALIGNMENT (VNx2HF, 2); - -/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2. - So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1SImode and VNx1SFmode. */ -VECTOR_MODE_WITH_PREFIX (VNx, INT, SI, 1, 0); -VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, SF, 1, 0); -ADJUST_NUNITS (VNx1SI, riscv_v_adjust_nunits (VNx1SImode, 1)); -ADJUST_NUNITS (VNx1SF, riscv_v_adjust_nunits (VNx1SFmode, 1)); -ADJUST_ALIGNMENT (VNx1SI, 4); -ADJUST_ALIGNMENT (VNx1SF, 4); - -VECTOR_MODES_WITH_PREFIX (VNx, INT, 2, 0); -ADJUST_NUNITS (VNx2QI, riscv_v_adjust_nunits (VNx2QImode, 2)); -ADJUST_ALIGNMENT (VNx2QI, 1); - -/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2. - So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1HImode and VNx1HFmode. */ -VECTOR_MODE_WITH_PREFIX (VNx, INT, HI, 1, 0); -VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, HF, 1, 0); -ADJUST_NUNITS (VNx1HI, riscv_v_adjust_nunits (VNx1HImode, 1)); -ADJUST_NUNITS (VNx1HF, riscv_v_adjust_nunits (VNx1HFmode, 1)); -ADJUST_ALIGNMENT (VNx1HI, 2); -ADJUST_ALIGNMENT (VNx1HF, 2); - -/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2. - So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1QImode. */ -VECTOR_MODE_WITH_PREFIX (VNx, INT, QI, 1, 0); -ADJUST_NUNITS (VNx1QI, riscv_v_adjust_nunits (VNx1QImode, 1)); -ADJUST_ALIGNMENT (VNx1QI, 1); - -/* Tuple modes for segment loads/stores according to NF, NF value can be 2 ~ 8. */ - -/* - | Mode | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 | MIN_VLEN=128 | MIN_VLEN=128 | - | | LMUL | SEW/LMUL | LMUL | SEW/LMUL | LMUL | SEW/LMUL | - | VNxNFx1QI | MF4 | 32 | MF8 | 64 | N/A | N/A | - | VNxNFx2QI | MF2 | 16 | MF4 | 32 | MF8 | 64 | - | VNxNFx4QI | M1 | 8 | MF2 | 16 | MF4 | 32 | - | VNxNFx8QI | M2 | 4 | M1 | 8 | MF2 | 16 | - | VNxNFx16QI | M4 | 2 | M2 | 4 | M1 | 8 | - | VNxNFx32QI | M8 | 1 | M4 | 2 | M2 | 4 | - | VNxNFx64QI | N/A | N/A | M8 | 1 | M4 | 2 | - | VNxNFx128QI | N/A | N/A | N/A | N/A | M8 | 1 | - | VNxNFx1(HI|HF) | MF2 | 32 | MF4 | 64 | N/A | N/A | - | VNxNFx2(HI|HF) | M1 | 16 | MF2 | 32 | MF4 | 64 | - | VNxNFx4(HI|HF) | M2 | 8 | M1 | 16 | MF2 | 32 | - | VNxNFx8(HI|HF) | M4 | 4 | M2 | 8 | M1 | 16 | - | VNxNFx16(HI|HF)| M8 | 2 | M4 | 4 | M2 | 8 | - | VNxNFx32(HI|HF)| N/A | N/A | M8 | 2 | M4 | 4 | - | VNxNFx64(HI|HF)| N/A | N/A | N/A | N/A | M8 | 2 | - | VNxNFx1(SI|SF) | M1 | 32 | MF2 | 64 | MF2 | 64 | - | VNxNFx2(SI|SF) | M2 | 16 | M1 | 32 | M1 | 32 | - | VNxNFx4(SI|SF) | M4 | 8 | M2 | 16 | M2 | 16 | - | VNxNFx8(SI|SF) | M8 | 4 | M4 | 8 | M4 | 8 | - | VNxNFx16(SI|SF)| N/A | N/A | M8 | 4 | M8 | 4 | - | VNxNFx1(DI|DF) | N/A | N/A | M1 | 64 | N/A | N/A | - | VNxNFx2(DI|DF) | N/A | N/A | M2 | 32 | M1 | 64 | - | VNxNFx4(DI|DF) | N/A | N/A | M4 | 16 | M2 | 32 | - | VNxNFx8(DI|DF) | N/A | N/A | M8 | 8 | M4 | 16 | - | VNxNFx16(DI|DF)| N/A | N/A | N/A | N/A | M8 | 8 | -*/ - -#define RVV_TUPLE_MODES(NBYTES, NSUBPARTS, VB, VH, VS, VD) \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, NBYTES, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, NBYTES / 2, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, HF, NBYTES / 2, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, SI, NBYTES / 4, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, SF, NBYTES / 4, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, DI, NBYTES / 8, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, DF, NBYTES / 8, 1); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x##VB##QI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VB##QI##mode, \ - VB * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x##VH##HI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VH##HI##mode, \ - VH * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x##VS##SI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VS##SI##mode, \ - VS * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x##VD##DI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VD##DI##mode, \ - VD * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x##VH##HF, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VH##HF##mode, \ - VH * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x##VS##SF, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VS##SF##mode, \ - VS * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x##VD##DF, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VD##DF##mode, \ - VD * NSUBPARTS)); \ + ADJUST_ALIGNMENT (RVVM2x##NF##QI, 1); \ + ADJUST_ALIGNMENT (RVVM2x##NF##HI, 2); \ + ADJUST_ALIGNMENT (RVVM2x##NF##HF, 2); \ + ADJUST_ALIGNMENT (RVVM2x##NF##SI, 4); \ + ADJUST_ALIGNMENT (RVVM2x##NF##SF, 4); \ + ADJUST_ALIGNMENT (RVVM2x##NF##DI, 8); \ + ADJUST_ALIGNMENT (RVVM2x##NF##DF, 8); + +RVV_NF4_MODES (2) +RVV_NF4_MODES (3) +RVV_NF4_MODES (4) + +#define RVV_NF2_MODES(NF) \ + VECTOR_MODE_WITH_PREFIX (RVVM4x, INT, QI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM4x, INT, HI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM4x, FLOAT, HF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM4x, INT, SI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM4x, FLOAT, SF, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM4x, INT, DI, NF, 1); \ + VECTOR_MODE_WITH_PREFIX (RVVM4x, FLOAT, DF, NF, 1); \ \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VB##QI, 1); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VH##HI, 2); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VS##SI, 4); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VD##DI, 8); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VH##HF, 2); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VS##SF, 4); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VD##DF, 8); - -RVV_TUPLE_MODES (8, 2, 8, 4, 2, 1) -RVV_TUPLE_MODES (8, 3, 8, 4, 2, 1) -RVV_TUPLE_MODES (8, 4, 8, 4, 2, 1) -RVV_TUPLE_MODES (8, 5, 8, 4, 2, 1) -RVV_TUPLE_MODES (8, 6, 8, 4, 2, 1) -RVV_TUPLE_MODES (8, 7, 8, 4, 2, 1) -RVV_TUPLE_MODES (8, 8, 8, 4, 2, 1) - -RVV_TUPLE_MODES (16, 2, 16, 8, 4, 2) -RVV_TUPLE_MODES (16, 3, 16, 8, 4, 2) -RVV_TUPLE_MODES (16, 4, 16, 8, 4, 2) -RVV_TUPLE_MODES (16, 5, 16, 8, 4, 2) -RVV_TUPLE_MODES (16, 6, 16, 8, 4, 2) -RVV_TUPLE_MODES (16, 7, 16, 8, 4, 2) -RVV_TUPLE_MODES (16, 8, 16, 8, 4, 2) - -RVV_TUPLE_MODES (32, 2, 32, 16, 8, 4) -RVV_TUPLE_MODES (32, 3, 32, 16, 8, 4) -RVV_TUPLE_MODES (32, 4, 32, 16, 8, 4) - -RVV_TUPLE_MODES (64, 2, 64, 32, 16, 8) - -#define RVV_TUPLE_PARTIAL_MODES(NSUBPARTS) \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 1, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, 1, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, HF, 1, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, SI, 1, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, SF, 1, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 2, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, 2, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, HF, 2, 1); \ - VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 4, 1); \ + ADJUST_NUNITS (RVVM4x##NF##QI, \ + riscv_v_adjust_nunits (RVVM4x##NF##QImode, false, 4, NF)); \ + ADJUST_NUNITS (RVVM4x##NF##HI, \ + riscv_v_adjust_nunits (RVVM4x##NF##HImode, false, 4, NF)); \ + ADJUST_NUNITS (RVVM4x##NF##HF, \ + riscv_v_adjust_nunits (RVVM4x##NF##HFmode, false, 4, NF)); \ + ADJUST_NUNITS (RVVM4x##NF##SI, \ + riscv_v_adjust_nunits (RVVM4x##NF##SImode, false, 4, NF)); \ + ADJUST_NUNITS (RVVM4x##NF##SF, \ + riscv_v_adjust_nunits (RVVM4x##NF##SFmode, false, 4, NF)); \ + ADJUST_NUNITS (RVVM4x##NF##DI, \ + riscv_v_adjust_nunits (RVVM4x##NF##DImode, false, 4, NF)); \ + ADJUST_NUNITS (RVVM4x##NF##DF, \ + riscv_v_adjust_nunits (RVVM4x##NF##DFmode, false, 4, NF)); \ \ - ADJUST_NUNITS (VNx##NSUBPARTS##x1QI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x1QI##mode, \ - NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x1HI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x1HI##mode, \ - NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x1HF, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x1HF##mode, \ - NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x1SI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x1SI##mode, \ - NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x1SF, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x1SF##mode, \ - NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x2QI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x2QI##mode, \ - 2 * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x2HI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x2HI##mode, \ - 2 * NSUBPARTS)); \ -ADJUST_NUNITS (VNx##NSUBPARTS##x2HF, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x2HF##mode, \ - 2 * NSUBPARTS)); \ - ADJUST_NUNITS (VNx##NSUBPARTS##x4QI, \ - riscv_v_adjust_nunits (VNx##NSUBPARTS##x4QI##mode, \ - 4 * NSUBPARTS)); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1QI, 1); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1HI, 2); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1HF, 2); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SI, 4); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SF, 4); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2QI, 1); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2HI, 2); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2HF, 2); \ - ADJUST_ALIGNMENT (VNx##NSUBPARTS##x4QI, 1); - -RVV_TUPLE_PARTIAL_MODES (2) -RVV_TUPLE_PARTIAL_MODES (3) -RVV_TUPLE_PARTIAL_MODES (4) -RVV_TUPLE_PARTIAL_MODES (5) -RVV_TUPLE_PARTIAL_MODES (6) -RVV_TUPLE_PARTIAL_MODES (7) -RVV_TUPLE_PARTIAL_MODES (8) + ADJUST_ALIGNMENT (RVVM4x##NF##QI, 1); \ + ADJUST_ALIGNMENT (RVVM4x##NF##HI, 2); \ + ADJUST_ALIGNMENT (RVVM4x##NF##HF, 2); \ + ADJUST_ALIGNMENT (RVVM4x##NF##SI, 4); \ + ADJUST_ALIGNMENT (RVVM4x##NF##SF, 4); \ + ADJUST_ALIGNMENT (RVVM4x##NF##DI, 8); \ + ADJUST_ALIGNMENT (RVVM4x##NF##DF, 8); + +RVV_NF2_MODES (2) /* TODO: According to RISC-V 'V' ISA spec, the maximun vector length can be 65536 for a single vector register which means the vector mode in diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index ff1e682..53088ed 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1550,37 +1550,20 @@ legitimize_move (rtx dest, rtx src) /* VTYPE information for machine_mode. */ struct mode_vtype_group { - enum vlmul_type vlmul_for_min_vlen32[NUM_MACHINE_MODES]; - uint8_t ratio_for_min_vlen32[NUM_MACHINE_MODES]; - enum vlmul_type vlmul_for_min_vlen64[NUM_MACHINE_MODES]; - uint8_t ratio_for_min_vlen64[NUM_MACHINE_MODES]; - enum vlmul_type vlmul_for_for_vlen128[NUM_MACHINE_MODES]; - uint8_t ratio_for_for_vlen128[NUM_MACHINE_MODES]; + enum vlmul_type vlmul[NUM_MACHINE_MODES]; + uint8_t ratio[NUM_MACHINE_MODES]; machine_mode subpart_mode[NUM_MACHINE_MODES]; uint8_t nf[NUM_MACHINE_MODES]; mode_vtype_group () { -#define ENTRY(MODE, REQUIREMENT, VLMUL_FOR_MIN_VLEN32, RATIO_FOR_MIN_VLEN32, \ - VLMUL_FOR_MIN_VLEN64, RATIO_FOR_MIN_VLEN64, \ - VLMUL_FOR_MIN_VLEN128, RATIO_FOR_MIN_VLEN128) \ - vlmul_for_min_vlen32[MODE##mode] = VLMUL_FOR_MIN_VLEN32; \ - ratio_for_min_vlen32[MODE##mode] = RATIO_FOR_MIN_VLEN32; \ - vlmul_for_min_vlen64[MODE##mode] = VLMUL_FOR_MIN_VLEN64; \ - ratio_for_min_vlen64[MODE##mode] = RATIO_FOR_MIN_VLEN64; \ - vlmul_for_for_vlen128[MODE##mode] = VLMUL_FOR_MIN_VLEN128; \ - ratio_for_for_vlen128[MODE##mode] = RATIO_FOR_MIN_VLEN128; -#define TUPLE_ENTRY(MODE, REQUIREMENT, SUBPART_MODE, NF, VLMUL_FOR_MIN_VLEN32, \ - RATIO_FOR_MIN_VLEN32, VLMUL_FOR_MIN_VLEN64, \ - RATIO_FOR_MIN_VLEN64, VLMUL_FOR_MIN_VLEN128, \ - RATIO_FOR_MIN_VLEN128) \ +#define ENTRY(MODE, REQUIREMENT, VLMUL, RATIO) \ + vlmul[MODE##mode] = VLMUL; \ + ratio[MODE##mode] = RATIO; +#define TUPLE_ENTRY(MODE, REQUIREMENT, SUBPART_MODE, NF, VLMUL, RATIO) \ subpart_mode[MODE##mode] = SUBPART_MODE##mode; \ nf[MODE##mode] = NF; \ - vlmul_for_min_vlen32[MODE##mode] = VLMUL_FOR_MIN_VLEN32; \ - ratio_for_min_vlen32[MODE##mode] = RATIO_FOR_MIN_VLEN32; \ - vlmul_for_min_vlen64[MODE##mode] = VLMUL_FOR_MIN_VLEN64; \ - ratio_for_min_vlen64[MODE##mode] = RATIO_FOR_MIN_VLEN64; \ - vlmul_for_for_vlen128[MODE##mode] = VLMUL_FOR_MIN_VLEN128; \ - ratio_for_for_vlen128[MODE##mode] = RATIO_FOR_MIN_VLEN128; + vlmul[MODE##mode] = VLMUL; \ + ratio[MODE##mode] = RATIO; #include "riscv-vector-switch.def" #undef ENTRY #undef TUPLE_ENTRY @@ -1593,12 +1576,7 @@ static mode_vtype_group mode_vtype_infos; enum vlmul_type get_vlmul (machine_mode mode) { - if (TARGET_MIN_VLEN >= 128) - return mode_vtype_infos.vlmul_for_for_vlen128[mode]; - else if (TARGET_MIN_VLEN == 32) - return mode_vtype_infos.vlmul_for_min_vlen32[mode]; - else - return mode_vtype_infos.vlmul_for_min_vlen64[mode]; + return mode_vtype_infos.vlmul[mode]; } /* Return the NF value of the corresponding mode. */ @@ -1610,8 +1588,8 @@ get_nf (machine_mode mode) return mode_vtype_infos.nf[mode]; } -/* Return the subpart mode of the tuple mode. For VNx2x1SImode, - the subpart mode is VNx1SImode. This will help to build +/* Return the subpart mode of the tuple mode. For RVVM2x2SImode, + the subpart mode is RVVM2SImode. This will help to build array/struct type in builtins. */ machine_mode get_subpart_mode (machine_mode mode) @@ -1625,12 +1603,7 @@ get_subpart_mode (machine_mode mode) unsigned int get_ratio (machine_mode mode) { - if (TARGET_MIN_VLEN >= 128) - return mode_vtype_infos.ratio_for_for_vlen128[mode]; - else if (TARGET_MIN_VLEN == 32) - return mode_vtype_infos.ratio_for_min_vlen32[mode]; - else - return mode_vtype_infos.ratio_for_min_vlen64[mode]; + return mode_vtype_infos.ratio[mode]; } /* Get ta according to operand[tail_op_idx]. */ @@ -2171,12 +2144,12 @@ preferred_simd_mode (scalar_mode mode) /* We will disable auto-vectorization when TARGET_MIN_VLEN < 128 && riscv_autovec_lmul < RVV_M2. Since GCC loop vectorizer report ICE when we enable -march=rv64gc_zve32* and -march=rv32gc_zve64*. in the - 'can_duplicate_and_interleave_p' of tree-vect-slp.cc. Since we have - VNx1SImode in -march=*zve32* and VNx1DImode in -march=*zve64*, they are - enabled in targetm. vector_mode_supported_p and SLP vectorizer will try to - use them. Currently, we can support auto-vectorization in - -march=rv32_zve32x_zvl128b. Wheras, -march=rv32_zve32x_zvl32b or - -march=rv32_zve32x_zvl64b are disabled. */ + 'can_duplicate_and_interleave_p' of tree-vect-slp.cc. Since both + RVVM1SImode in -march=*zve32*_zvl32b and RVVM1DImode in + -march=*zve64*_zvl64b are NUNITS = poly (1, 1), they will cause ICE in loop + vectorizer when we enable them in this target hook. Currently, we can + support auto-vectorization in -march=rv32_zve32x_zvl128b. Wheras, + -march=rv32_zve32x_zvl32b or -march=rv32_zve32x_zvl64b are disabled. */ if (autovec_use_vlmax_p ()) { if (TARGET_MIN_VLEN < 128 && riscv_autovec_lmul < RVV_M2) @@ -2371,9 +2344,9 @@ autovectorize_vector_modes (vector_modes *modes, bool) poly_uint64 full_size = BYTES_PER_RISCV_VECTOR * ((int) riscv_autovec_lmul); - /* Start with a VNxYYQImode where YY is the number of units that + /* Start with a RVVQImode where LMUL is the number of units that fit a whole vector. - Then try YY = nunits / 2, nunits / 4 and nunits / 8 which + Then try LMUL = nunits / 2, nunits / 4 and nunits / 8 which is guided by the extensions we have available (vf2, vf4 and vf8). - full_size: Try using full vectors for all element types. diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 3a53b56..528dca7 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -109,10 +109,8 @@ const char *const operand_suffixes[NUM_OP_TYPES] = { /* Static information about type suffix for each RVV type. */ const rvv_builtin_suffixes type_suffixes[NUM_VECTOR_TYPES + 1] = { -#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, \ - VECTOR_MODE_MIN_VLEN_128, VECTOR_MODE_MIN_VLEN_64, \ - VECTOR_MODE_MIN_VLEN_32, VECTOR_SUFFIX, SCALAR_SUFFIX, \ - VSETVL_SUFFIX) \ +#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \ + VECTOR_SUFFIX, SCALAR_SUFFIX, VSETVL_SUFFIX) \ {#VECTOR_SUFFIX, #SCALAR_SUFFIX, #VSETVL_SUFFIX}, #define DEF_RVV_TUPLE_TYPE(NAME, NCHARS, ABI_NAME, SUBPART_TYPE, SCALAR_TYPE, \ NF, VECTOR_SUFFIX) \ @@ -2802,12 +2800,9 @@ register_builtin_types () tree int64_type_node = get_typenode_from_name (INT64_TYPE); machine_mode mode; -#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, \ - VECTOR_MODE_MIN_VLEN_128, VECTOR_MODE_MIN_VLEN_64, \ - VECTOR_MODE_MIN_VLEN_32, ARGS...) \ - mode = TARGET_MIN_VLEN >= 128 ? VECTOR_MODE_MIN_VLEN_128##mode \ - : TARGET_MIN_VLEN >= 64 ? VECTOR_MODE_MIN_VLEN_64##mode \ - : VECTOR_MODE_MIN_VLEN_32##mode; \ +#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \ + ARGS...) \ + mode = VECTOR_MODE##mode; \ register_builtin_type (VECTOR_TYPE_##NAME, SCALAR_TYPE##_type_node, mode); #define DEF_RVV_TUPLE_TYPE(NAME, NCHARS, ABI_NAME, SUBPART_TYPE, SCALAR_TYPE, \ NF, VECTOR_SUFFIX) \ diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def index 1e94579..0e49480 100644 --- a/gcc/config/riscv/riscv-vector-builtins.def +++ b/gcc/config/riscv/riscv-vector-builtins.def @@ -28,24 +28,19 @@ along with GCC; see the file COPYING3. If not see "build_vector_type_for_mode". For "vint32m1_t", we use "intSI_type_node" in RV64. Otherwise, we use "long_integer_type_node". 5.The 'VECTOR_MODE' is the machine modes of corresponding RVV type used - in "build_vector_type_for_mode" when TARGET_MIN_VLEN > 32. - For example: VECTOR_MODE = VNx2SI for "vint32m1_t". - 6.The 'VECTOR_MODE_MIN_VLEN_32' is the machine modes of corresponding RVV - type used in "build_vector_type_for_mode" when TARGET_MIN_VLEN = 32. For - example: VECTOR_MODE_MIN_VLEN_32 = VNx1SI for "vint32m1_t". - 7.The 'VECTOR_SUFFIX' define mode suffix for vector type. + in "build_vector_type_for_mode". + For example: VECTOR_MODE = RVVM1SImode for "vint32m1_t". + 6.The 'VECTOR_SUFFIX' define mode suffix for vector type. For example: type_suffixes[VECTOR_TYPE_vin32m1_t].vector = i32m1. - 8.The 'SCALAR_SUFFIX' define mode suffix for scalar type. + 7.The 'SCALAR_SUFFIX' define mode suffix for scalar type. For example: type_suffixes[VECTOR_TYPE_vin32m1_t].scalar = i32. - 9.The 'VSETVL_SUFFIX' define mode suffix for vsetvli instruction. + 8.The 'VSETVL_SUFFIX' define mode suffix for vsetvli instruction. For example: type_suffixes[VECTOR_TYPE_vin32m1_t].vsetvl = e32m1. */ #ifndef DEF_RVV_TYPE -#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, \ - VECTOR_MODE_MIN_VLEN_128, VECTOR_MODE_MIN_VLEN_64, \ - VECTOR_MODE_MIN_VLEN_32, VECTOR_SUFFIX, SCALAR_SUFFIX, \ - VSETVL_SUFFIX) +#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \ + VECTOR_SUFFIX, SCALAR_SUFFIX, VSETVL_SUFFIX) #endif #ifndef DEF_RVV_TUPLE_TYPE @@ -101,47 +96,34 @@ along with GCC; see the file COPYING3. If not see /* SEW/LMUL = 64: Only enable when TARGET_MIN_VLEN > 32. - Machine mode = VNx1BImode when TARGET_MIN_VLEN < 128. - Machine mode = VNx2BImode when TARGET_MIN_VLEN >= 128. */ -DEF_RVV_TYPE (vbool64_t, 14, __rvv_bool64_t, boolean, VNx2BI, VNx1BI, VOID, _b64, , ) + Machine mode = RVVMF64BImode. */ +DEF_RVV_TYPE (vbool64_t, 14, __rvv_bool64_t, boolean, RVVMF64BI, _b64, , ) /* SEW/LMUL = 32: - Machine mode = VNx2BImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx1BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool32_t, 14, __rvv_bool32_t, boolean, VNx4BI, VNx2BI, VNx1BI, _b32, , ) + Machine mode = RVVMF32BImode. */ +DEF_RVV_TYPE (vbool32_t, 14, __rvv_bool32_t, boolean, RVVMF32BI, _b32, , ) /* SEW/LMUL = 16: - Machine mode = VNx8BImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx2BImode when TARGET_MIN_VLEN = 32. - Machine mode = VNx4BImode when TARGET_MIN_VLEN > 32. */ -DEF_RVV_TYPE (vbool16_t, 14, __rvv_bool16_t, boolean, VNx8BI, VNx4BI, VNx2BI, _b16, , ) + Machine mode = RVVMF16BImode. */ +DEF_RVV_TYPE (vbool16_t, 14, __rvv_bool16_t, boolean, RVVMF16BI, _b16, , ) /* SEW/LMUL = 8: - Machine mode = VNx16BImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx8BImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx4BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool8_t, 13, __rvv_bool8_t, boolean, VNx16BI, VNx8BI, VNx4BI, _b8, , ) + Machine mode = RVVMF8BImode. */ +DEF_RVV_TYPE (vbool8_t, 13, __rvv_bool8_t, boolean, RVVMF8BI, _b8, , ) /* SEW/LMUL = 4: - Machine mode = VNx32BImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx16BImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx8BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool4_t, 13, __rvv_bool4_t, boolean, VNx32BI, VNx16BI, VNx8BI, _b4, , ) + Machine mode = RVVMF4BImode. */ +DEF_RVV_TYPE (vbool4_t, 13, __rvv_bool4_t, boolean, RVVMF4BI, _b4, , ) /* SEW/LMUL = 2: - Machine mode = VNx64BImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx32BImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx16BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool2_t, 13, __rvv_bool2_t, boolean, VNx64BI, VNx32BI, VNx16BI, _b2, , ) + Machine mode = RVVMF2BImode. */ +DEF_RVV_TYPE (vbool2_t, 13, __rvv_bool2_t, boolean, RVVMF2BI, _b2, , ) /* SEW/LMUL = 1: - Machine mode = VNx128BImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx64BImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx32BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool1_t, 13, __rvv_bool1_t, boolean, VNx128BI, VNx64BI, VNx32BI, _b1, , ) + Machine mode = RVVM1BImode. */ +DEF_RVV_TYPE (vbool1_t, 13, __rvv_bool1_t, boolean, RVVM1BI, _b1, , ) /* LMUL = 1/8: Only enble when TARGET_MIN_VLEN > 32. - Machine mode = VNx1QImode when TARGET_MIN_VLEN < 128. - Machine mode = VNx2QImode when TARGET_MIN_VLEN >= 128. */ -DEF_RVV_TYPE (vint8mf8_t, 15, __rvv_int8mf8_t, int8, VNx2QI, VNx1QI, VOID, _i8mf8, _i8, + Machine mode = RVVMF8QImode. */ +DEF_RVV_TYPE (vint8mf8_t, 15, __rvv_int8mf8_t, int8, RVVMF8QI, _i8mf8, _i8, + _e8mf8) +DEF_RVV_TYPE (vuint8mf8_t, 16, __rvv_uint8mf8_t, uint8, RVVMF8QI, _u8mf8, _u8, _e8mf8) -DEF_RVV_TYPE (vuint8mf8_t, 16, __rvv_uint8mf8_t, uint8, VNx2QI, VNx1QI, VOID, _u8mf8, - _u8, _e8mf8) /* Define tuple types for SEW = 8, LMUL = MF8. */ DEF_RVV_TUPLE_TYPE (vint8mf8x2_t, 17, __rvv_int8mf8x2_t, vint8mf8_t, int8, 2, _i8mf8x2) DEF_RVV_TUPLE_TYPE (vuint8mf8x2_t, 18, __rvv_uint8mf8x2_t, vuint8mf8_t, uint8, 2, _u8mf8x2) @@ -158,13 +140,11 @@ DEF_RVV_TUPLE_TYPE (vuint8mf8x7_t, 18, __rvv_uint8mf8x7_t, vuint8mf8_t, uint8, 7 DEF_RVV_TUPLE_TYPE (vint8mf8x8_t, 17, __rvv_int8mf8x8_t, vint8mf8_t, int8, 8, _i8mf8x8) DEF_RVV_TUPLE_TYPE (vuint8mf8x8_t, 18, __rvv_uint8mf8x8_t, vuint8mf8_t, uint8, 8, _u8mf8x8) /* LMUL = 1/4: - Machine mode = VNx4QImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx2QImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx1QImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint8mf4_t, 15, __rvv_int8mf4_t, int8, VNx4QI, VNx2QI, VNx1QI, _i8mf4, - _i8, _e8mf4) -DEF_RVV_TYPE (vuint8mf4_t, 16, __rvv_uint8mf4_t, uint8, VNx4QI, VNx2QI, VNx1QI, _u8mf4, - _u8, _e8mf4) + Machine mode = RVVMF4QImode. */ +DEF_RVV_TYPE (vint8mf4_t, 15, __rvv_int8mf4_t, int8, RVVMF4QI, _i8mf4, _i8, + _e8mf4) +DEF_RVV_TYPE (vuint8mf4_t, 16, __rvv_uint8mf4_t, uint8, RVVMF4QI, _u8mf4, _u8, + _e8mf4) /* Define tuple types for SEW = 8, LMUL = MF4. */ DEF_RVV_TUPLE_TYPE (vint8mf4x2_t, 17, __rvv_int8mf4x2_t, vint8mf4_t, int8, 2, _i8mf4x2) DEF_RVV_TUPLE_TYPE (vuint8mf4x2_t, 18, __rvv_uint8mf4x2_t, vuint8mf4_t, uint8, 2, _u8mf4x2) @@ -181,13 +161,11 @@ DEF_RVV_TUPLE_TYPE (vuint8mf4x7_t, 18, __rvv_uint8mf4x7_t, vuint8mf4_t, uint8, 7 DEF_RVV_TUPLE_TYPE (vint8mf4x8_t, 17, __rvv_int8mf4x8_t, vint8mf4_t, int8, 8, _i8mf4x8) DEF_RVV_TUPLE_TYPE (vuint8mf4x8_t, 18, __rvv_uint8mf4x8_t, vuint8mf4_t, uint8, 8, _u8mf4x8) /* LMUL = 1/2: - Machine mode = VNx8QImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx4QImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx2QImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint8mf2_t, 15, __rvv_int8mf2_t, int8, VNx8QI, VNx4QI, VNx2QI, _i8mf2, - _i8, _e8mf2) -DEF_RVV_TYPE (vuint8mf2_t, 16, __rvv_uint8mf2_t, uint8, VNx8QI, VNx4QI, VNx2QI, _u8mf2, - _u8, _e8mf2) + Machine mode = RVVMF2QImode. */ +DEF_RVV_TYPE (vint8mf2_t, 15, __rvv_int8mf2_t, int8, RVVMF2QI, _i8mf2, _i8, + _e8mf2) +DEF_RVV_TYPE (vuint8mf2_t, 16, __rvv_uint8mf2_t, uint8, RVVMF2QI, _u8mf2, _u8, + _e8mf2) /* Define tuple types for SEW = 8, LMUL = MF2. */ DEF_RVV_TUPLE_TYPE (vint8mf2x2_t, 17, __rvv_int8mf2x2_t, vint8mf2_t, int8, 2, _i8mf2x2) DEF_RVV_TUPLE_TYPE (vuint8mf2x2_t, 18, __rvv_uint8mf2x2_t, vuint8mf2_t, uint8, 2, _u8mf2x2) @@ -204,13 +182,10 @@ DEF_RVV_TUPLE_TYPE (vuint8mf2x7_t, 18, __rvv_uint8mf2x7_t, vuint8mf2_t, uint8, 7 DEF_RVV_TUPLE_TYPE (vint8mf2x8_t, 17, __rvv_int8mf2x8_t, vint8mf2_t, int8, 8, _i8mf2x8) DEF_RVV_TUPLE_TYPE (vuint8mf2x8_t, 18, __rvv_uint8mf2x8_t, vuint8mf2_t, uint8, 8, _u8mf2x8) /* LMUL = 1: - Machine mode = VNx16QImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx8QImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx4QImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint8m1_t, 14, __rvv_int8m1_t, int8, VNx16QI, VNx8QI, VNx4QI, _i8m1, _i8, + Machine mode = RVVM1QImode. */ +DEF_RVV_TYPE (vint8m1_t, 14, __rvv_int8m1_t, int8, RVVM1QI, _i8m1, _i8, _e8m1) +DEF_RVV_TYPE (vuint8m1_t, 15, __rvv_uint8m1_t, uint8, RVVM1QI, _u8m1, _u8, _e8m1) -DEF_RVV_TYPE (vuint8m1_t, 15, __rvv_uint8m1_t, uint8, VNx16QI, VNx8QI, VNx4QI, _u8m1, - _u8, _e8m1) /* Define tuple types for SEW = 8, LMUL = M1. */ DEF_RVV_TUPLE_TYPE (vint8m1x2_t, 16, __rvv_int8m1x2_t, vint8m1_t, int8, 2, _i8m1x2) DEF_RVV_TUPLE_TYPE (vuint8m1x2_t, 17, __rvv_uint8m1x2_t, vuint8m1_t, uint8, 2, _u8m1x2) @@ -227,13 +202,10 @@ DEF_RVV_TUPLE_TYPE (vuint8m1x7_t, 17, __rvv_uint8m1x7_t, vuint8m1_t, uint8, 7, _ DEF_RVV_TUPLE_TYPE (vint8m1x8_t, 16, __rvv_int8m1x8_t, vint8m1_t, int8, 8, _i8m1x8) DEF_RVV_TUPLE_TYPE (vuint8m1x8_t, 17, __rvv_uint8m1x8_t, vuint8m1_t, uint8, 8, _u8m1x8) /* LMUL = 2: - Machine mode = VNx32QImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx16QImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx8QImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint8m2_t, 14, __rvv_int8m2_t, int8, VNx32QI, VNx16QI, VNx8QI, _i8m2, _i8, + Machine mode = RVVM2QImode. */ +DEF_RVV_TYPE (vint8m2_t, 14, __rvv_int8m2_t, int8, RVVM2QI, _i8m2, _i8, _e8m2) +DEF_RVV_TYPE (vuint8m2_t, 15, __rvv_uint8m2_t, uint8, RVVM2QI, _u8m2, _u8, _e8m2) -DEF_RVV_TYPE (vuint8m2_t, 15, __rvv_uint8m2_t, uint8, VNx32QI, VNx16QI, VNx8QI, _u8m2, - _u8, _e8m2) /* Define tuple types for SEW = 8, LMUL = M2. */ DEF_RVV_TUPLE_TYPE (vint8m2x2_t, 16, __rvv_int8m2x2_t, vint8m2_t, int8, 2, _i8m2x2) DEF_RVV_TUPLE_TYPE (vuint8m2x2_t, 17, __rvv_uint8m2x2_t, vuint8m2_t, uint8, 2, _u8m2x2) @@ -242,33 +214,26 @@ DEF_RVV_TUPLE_TYPE (vuint8m2x3_t, 17, __rvv_uint8m2x3_t, vuint8m2_t, uint8, 3, _ DEF_RVV_TUPLE_TYPE (vint8m2x4_t, 16, __rvv_int8m2x4_t, vint8m2_t, int8, 4, _i8m2x4) DEF_RVV_TUPLE_TYPE (vuint8m2x4_t, 17, __rvv_uint8m2x4_t, vuint8m2_t, uint8, 4, _u8m2x4) /* LMUL = 4: - Machine mode = VNx64QImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx32QImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx16QImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint8m4_t, 14, __rvv_int8m4_t, int8, VNx64QI, VNx32QI, VNx16QI, _i8m4, _i8, + Machine mode = RVVM4QImode. */ +DEF_RVV_TYPE (vint8m4_t, 14, __rvv_int8m4_t, int8, RVVM4QI, _i8m4, _i8, _e8m4) +DEF_RVV_TYPE (vuint8m4_t, 15, __rvv_uint8m4_t, uint8, RVVM4QI, _u8m4, _u8, _e8m4) -DEF_RVV_TYPE (vuint8m4_t, 15, __rvv_uint8m4_t, uint8, VNx64QI, VNx32QI, VNx16QI, _u8m4, - _u8, _e8m4) /* Define tuple types for SEW = 8, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vint8m4x2_t, 16, __rvv_int8m4x2_t, vint8m4_t, int8, 2, _i8m4x2) DEF_RVV_TUPLE_TYPE (vuint8m4x2_t, 17, __rvv_uint8m4x2_t, vuint8m4_t, uint8, 2, _u8m4x2) /* LMUL = 8: - Machine mode = VNx128QImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx64QImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx32QImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint8m8_t, 14, __rvv_int8m8_t, int8, VNx128QI, VNx64QI, VNx32QI, _i8m8, _i8, + Machine mode = RVVM8QImode. */ +DEF_RVV_TYPE (vint8m8_t, 14, __rvv_int8m8_t, int8, RVVM8QI, _i8m8, _i8, _e8m8) +DEF_RVV_TYPE (vuint8m8_t, 15, __rvv_uint8m8_t, uint8, RVVM8QI, _u8m8, _u8, _e8m8) -DEF_RVV_TYPE (vuint8m8_t, 15, __rvv_uint8m8_t, uint8, VNx128QI, VNx64QI, VNx32QI, _u8m8, - _u8, _e8m8) /* LMUL = 1/4: Only enble when TARGET_MIN_VLEN > 32. - Machine mode = VNx1HImode when TARGET_MIN_VLEN < 128. - Machine mode = VNx2HImode when TARGET_MIN_VLEN >= 128. */ -DEF_RVV_TYPE (vint16mf4_t, 16, __rvv_int16mf4_t, int16, VNx2HI, VNx1HI, VOID, _i16mf4, - _i16, _e16mf4) -DEF_RVV_TYPE (vuint16mf4_t, 17, __rvv_uint16mf4_t, uint16, VNx2HI, VNx1HI, VOID, - _u16mf4, _u16, _e16mf4) + Machine mode = RVVMF4HImode. */ +DEF_RVV_TYPE (vint16mf4_t, 16, __rvv_int16mf4_t, int16, RVVMF4HI, _i16mf4, _i16, + _e16mf4) +DEF_RVV_TYPE (vuint16mf4_t, 17, __rvv_uint16mf4_t, uint16, RVVMF4HI, _u16mf4, + _u16, _e16mf4) /* Define tuple types for SEW = 16, LMUL = MF4. */ DEF_RVV_TUPLE_TYPE (vint16mf4x2_t, 18, __rvv_int16mf4x2_t, vint16mf4_t, int16, 2, _i16mf4x2) DEF_RVV_TUPLE_TYPE (vuint16mf4x2_t, 19, __rvv_uint16mf4x2_t, vuint16mf4_t, uint16, 2, _u16mf4x2) @@ -285,13 +250,11 @@ DEF_RVV_TUPLE_TYPE (vuint16mf4x7_t, 19, __rvv_uint16mf4x7_t, vuint16mf4_t, uint1 DEF_RVV_TUPLE_TYPE (vint16mf4x8_t, 18, __rvv_int16mf4x8_t, vint16mf4_t, int16, 8, _i16mf4x8) DEF_RVV_TUPLE_TYPE (vuint16mf4x8_t, 19, __rvv_uint16mf4x8_t, vuint16mf4_t, uint16, 8, _u16mf4x8) /* LMUL = 1/2: - Machine mode = VNx4HImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx2HImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx1HImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint16mf2_t, 16, __rvv_int16mf2_t, int16, VNx4HI, VNx2HI, VNx1HI, _i16mf2, - _i16, _e16mf2) -DEF_RVV_TYPE (vuint16mf2_t, 17, __rvv_uint16mf2_t, uint16, VNx4HI, VNx2HI, VNx1HI, - _u16mf2, _u16, _e16mf2) + Machine mode = RVVMF2HImode. */ +DEF_RVV_TYPE (vint16mf2_t, 16, __rvv_int16mf2_t, int16, RVVMF2HI, _i16mf2, _i16, + _e16mf2) +DEF_RVV_TYPE (vuint16mf2_t, 17, __rvv_uint16mf2_t, uint16, RVVMF2HI, _u16mf2, + _u16, _e16mf2) /* Define tuple types for SEW = 16, LMUL = MF2. */ DEF_RVV_TUPLE_TYPE (vint16mf2x2_t, 18, __rvv_int16mf2x2_t, vint16mf2_t, int16, 2, _i16mf2x2) DEF_RVV_TUPLE_TYPE (vuint16mf2x2_t, 19, __rvv_uint16mf2x2_t, vuint16mf2_t, uint16, 2, _u16mf2x2) @@ -308,13 +271,11 @@ DEF_RVV_TUPLE_TYPE (vuint16mf2x7_t, 19, __rvv_uint16mf2x7_t, vuint16mf2_t, uint1 DEF_RVV_TUPLE_TYPE (vint16mf2x8_t, 18, __rvv_int16mf2x8_t, vint16mf2_t, int16, 8, _i16mf2x8) DEF_RVV_TUPLE_TYPE (vuint16mf2x8_t, 19, __rvv_uint16mf2x8_t, vuint16mf2_t, uint16, 8, _u16mf2x8) /* LMUL = 1: - Machine mode = VNx8HImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx4HImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx2HImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint16m1_t, 15, __rvv_int16m1_t, int16, VNx8HI, VNx4HI, VNx2HI, _i16m1, - _i16, _e16m1) -DEF_RVV_TYPE (vuint16m1_t, 16, __rvv_uint16m1_t, uint16, VNx8HI, VNx4HI, VNx2HI, _u16m1, - _u16, _e16m1) + Machine mode = RVVM1HImode. */ +DEF_RVV_TYPE (vint16m1_t, 15, __rvv_int16m1_t, int16, RVVM1HI, _i16m1, _i16, + _e16m1) +DEF_RVV_TYPE (vuint16m1_t, 16, __rvv_uint16m1_t, uint16, RVVM1HI, _u16m1, _u16, + _e16m1) /* Define tuple types for SEW = 16, LMUL = M1. */ DEF_RVV_TUPLE_TYPE (vint16m1x2_t, 17, __rvv_int16m1x2_t, vint16m1_t, int16, 2, _i16m1x2) DEF_RVV_TUPLE_TYPE (vuint16m1x2_t, 18, __rvv_uint16m1x2_t, vuint16m1_t, uint16, 2, _u16m1x2) @@ -331,13 +292,11 @@ DEF_RVV_TUPLE_TYPE (vuint16m1x7_t, 18, __rvv_uint16m1x7_t, vuint16m1_t, uint16, DEF_RVV_TUPLE_TYPE (vint16m1x8_t, 17, __rvv_int16m1x8_t, vint16m1_t, int16, 8, _i16m1x8) DEF_RVV_TUPLE_TYPE (vuint16m1x8_t, 18, __rvv_uint16m1x8_t, vuint16m1_t, uint16, 8, _u16m1x8) /* LMUL = 2: - Machine mode = VNx16HImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx8HImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx4HImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint16m2_t, 15, __rvv_int16m2_t, int16, VNx16HI, VNx8HI, VNx4HI, _i16m2, - _i16, _e16m2) -DEF_RVV_TYPE (vuint16m2_t, 16, __rvv_uint16m2_t, uint16, VNx16HI, VNx8HI, VNx4HI, _u16m2, - _u16, _e16m2) + Machine mode = RVVM1H2mode. */ +DEF_RVV_TYPE (vint16m2_t, 15, __rvv_int16m2_t, int16, RVVM2HI, _i16m2, _i16, + _e16m2) +DEF_RVV_TYPE (vuint16m2_t, 16, __rvv_uint16m2_t, uint16, RVVM2HI, _u16m2, _u16, + _e16m2) /* Define tuple types for SEW = 16, LMUL = M2. */ DEF_RVV_TUPLE_TYPE (vint16m2x2_t, 17, __rvv_int16m2x2_t, vint16m2_t, int16, 2, _i16m2x2) DEF_RVV_TUPLE_TYPE (vuint16m2x2_t, 18, __rvv_uint16m2x2_t, vuint16m2_t, uint16, 2, _u16m2x2) @@ -346,33 +305,28 @@ DEF_RVV_TUPLE_TYPE (vuint16m2x3_t, 18, __rvv_uint16m2x3_t, vuint16m2_t, uint16, DEF_RVV_TUPLE_TYPE (vint16m2x4_t, 17, __rvv_int16m2x4_t, vint16m2_t, int16, 4, _i16m2x4) DEF_RVV_TUPLE_TYPE (vuint16m2x4_t, 18, __rvv_uint16m2x4_t, vuint16m2_t, uint16, 4, _u16m2x4) /* LMUL = 4: - Machine mode = VNx32HImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx16HImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx8HImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint16m4_t, 15, __rvv_int16m4_t, int16, VNx32HI, VNx16HI, VNx8HI, _i16m4, - _i16, _e16m4) -DEF_RVV_TYPE (vuint16m4_t, 16, __rvv_uint16m4_t, uint16, VNx32HI, VNx16HI, VNx8HI, - _u16m4, _u16, _e16m4) + Machine mode = RVVM4HImode. */ +DEF_RVV_TYPE (vint16m4_t, 15, __rvv_int16m4_t, int16, RVVM4HI, _i16m4, _i16, + _e16m4) +DEF_RVV_TYPE (vuint16m4_t, 16, __rvv_uint16m4_t, uint16, RVVM4HI, _u16m4, _u16, + _e16m4) /* Define tuple types for SEW = 16, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vint16m4x2_t, 17, __rvv_int16m4x2_t, vint16m4_t, int16, 2, _i16m4x2) DEF_RVV_TUPLE_TYPE (vuint16m4x2_t, 18, __rvv_uint16m4x2_t, vuint16m4_t, uint16, 2, _u16m4x2) /* LMUL = 8: - Machine mode = VNx64HImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx32HImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx16HImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint16m8_t, 15, __rvv_int16m8_t, int16, VNx64HI, VNx32HI, VNx16HI, _i16m8, - _i16, _e16m8) -DEF_RVV_TYPE (vuint16m8_t, 16, __rvv_uint16m8_t, uint16, VNx64HI, VNx32HI, VNx16HI, - _u16m8, _u16, _e16m8) + Machine mode = RVVM8HImode. */ +DEF_RVV_TYPE (vint16m8_t, 15, __rvv_int16m8_t, int16, RVVM8HI, _i16m8, _i16, + _e16m8) +DEF_RVV_TYPE (vuint16m8_t, 16, __rvv_uint16m8_t, uint16, RVVM8HI, _u16m8, _u16, + _e16m8) /* LMUL = 1/2: Only enble when TARGET_MIN_VLEN > 32. - Machine mode = VNx1SImode when TARGET_MIN_VLEN < 128. - Machine mode = VNx2SImode when TARGET_MIN_VLEN >= 128. */ -DEF_RVV_TYPE (vint32mf2_t, 16, __rvv_int32mf2_t, int32, VNx2SI, VNx1SI, VOID, _i32mf2, - _i32, _e32mf2) -DEF_RVV_TYPE (vuint32mf2_t, 17, __rvv_uint32mf2_t, uint32, VNx2SI, VNx1SI, VOID, - _u32mf2, _u32, _e32mf2) + Machine mode = RVVMF2SImode. */ +DEF_RVV_TYPE (vint32mf2_t, 16, __rvv_int32mf2_t, int32, RVVMF2SI, _i32mf2, _i32, + _e32mf2) +DEF_RVV_TYPE (vuint32mf2_t, 17, __rvv_uint32mf2_t, uint32, RVVMF2SI, _u32mf2, + _u32, _e32mf2) /* Define tuple types for SEW = 32, LMUL = MF2. */ DEF_RVV_TUPLE_TYPE (vint32mf2x2_t, 18, __rvv_int32mf2x2_t, vint32mf2_t, int32, 2, _i32mf2x2) DEF_RVV_TUPLE_TYPE (vuint32mf2x2_t, 19, __rvv_uint32mf2x2_t, vuint32mf2_t, uint32, 2, _u32mf2x2) @@ -389,13 +343,11 @@ DEF_RVV_TUPLE_TYPE (vuint32mf2x7_t, 19, __rvv_uint32mf2x7_t, vuint32mf2_t, uint3 DEF_RVV_TUPLE_TYPE (vint32mf2x8_t, 18, __rvv_int32mf2x8_t, vint32mf2_t, int32, 8, _i32mf2x8) DEF_RVV_TUPLE_TYPE (vuint32mf2x8_t, 19, __rvv_uint32mf2x8_t, vuint32mf2_t, uint32, 8, _u32mf2x8) /* LMUL = 1: - Machine mode = VNx4SImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx2SImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx1SImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint32m1_t, 15, __rvv_int32m1_t, int32, VNx4SI, VNx2SI, VNx1SI, _i32m1, - _i32, _e32m1) -DEF_RVV_TYPE (vuint32m1_t, 16, __rvv_uint32m1_t, uint32, VNx4SI, VNx2SI, VNx1SI, _u32m1, - _u32, _e32m1) + Machine mode = RVVM1SImode. */ +DEF_RVV_TYPE (vint32m1_t, 15, __rvv_int32m1_t, int32, RVVM1SI, _i32m1, _i32, + _e32m1) +DEF_RVV_TYPE (vuint32m1_t, 16, __rvv_uint32m1_t, uint32, RVVM1SI, _u32m1, _u32, + _e32m1) /* Define tuple types for SEW = 32, LMUL = M1. */ DEF_RVV_TUPLE_TYPE (vint32m1x2_t, 17, __rvv_int32m1x2_t, vint32m1_t, int32, 2, _i32m1x2) DEF_RVV_TUPLE_TYPE (vuint32m1x2_t, 18, __rvv_uint32m1x2_t, vuint32m1_t, uint32, 2, _u32m1x2) @@ -412,13 +364,11 @@ DEF_RVV_TUPLE_TYPE (vuint32m1x7_t, 18, __rvv_uint32m1x7_t, vuint32m1_t, uint32, DEF_RVV_TUPLE_TYPE (vint32m1x8_t, 17, __rvv_int32m1x8_t, vint32m1_t, int32, 8, _i32m1x8) DEF_RVV_TUPLE_TYPE (vuint32m1x8_t, 18, __rvv_uint32m1x8_t, vuint32m1_t, uint32, 8, _u32m1x8) /* LMUL = 2: - Machine mode = VNx8SImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx4SImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx2SImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint32m2_t, 15, __rvv_int32m2_t, int32, VNx8SI, VNx4SI, VNx2SI, _i32m2, - _i32, _e32m2) -DEF_RVV_TYPE (vuint32m2_t, 16, __rvv_uint32m2_t, uint32, VNx8SI, VNx4SI, VNx2SI, _u32m2, - _u32, _e32m2) + Machine mode = RVVM2SImode. */ +DEF_RVV_TYPE (vint32m2_t, 15, __rvv_int32m2_t, int32, RVVM2SI, _i32m2, _i32, + _e32m2) +DEF_RVV_TYPE (vuint32m2_t, 16, __rvv_uint32m2_t, uint32, RVVM2SI, _u32m2, _u32, + _e32m2) /* Define tuple types for SEW = 32, LMUL = M2. */ DEF_RVV_TUPLE_TYPE (vint32m2x2_t, 17, __rvv_int32m2x2_t, vint32m2_t, int32, 2, _i32m2x2) DEF_RVV_TUPLE_TYPE (vuint32m2x2_t, 18, __rvv_uint32m2x2_t, vuint32m2_t, uint32, 2, _u32m2x2) @@ -427,31 +377,27 @@ DEF_RVV_TUPLE_TYPE (vuint32m2x3_t, 18, __rvv_uint32m2x3_t, vuint32m2_t, uint32, DEF_RVV_TUPLE_TYPE (vint32m2x4_t, 17, __rvv_int32m2x4_t, vint32m2_t, int32, 4, _i32m2x4) DEF_RVV_TUPLE_TYPE (vuint32m2x4_t, 18, __rvv_uint32m2x4_t, vuint32m2_t, uint32, 4, _u32m2x4) /* LMUL = 4: - Machine mode = VNx16SImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx8SImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx4SImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint32m4_t, 15, __rvv_int32m4_t, int32, VNx16SI, VNx8SI, VNx4SI, _i32m4, - _i32, _e32m4) -DEF_RVV_TYPE (vuint32m4_t, 16, __rvv_uint32m4_t, uint32, VNx16SI, VNx8SI, VNx4SI, _u32m4, - _u32, _e32m4) + Machine mode = RVVM4SImode. */ +DEF_RVV_TYPE (vint32m4_t, 15, __rvv_int32m4_t, int32, RVVM4SI, _i32m4, _i32, + _e32m4) +DEF_RVV_TYPE (vuint32m4_t, 16, __rvv_uint32m4_t, uint32, RVVM4SI, _u32m4, _u32, + _e32m4) /* Define tuple types for SEW = 32, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vint32m4x2_t, 17, __rvv_int32m4x2_t, vint32m4_t, int32, 2, _i32m4x2) DEF_RVV_TUPLE_TYPE (vuint32m4x2_t, 18, __rvv_uint32m4x2_t, vuint32m4_t, uint32, 2, _u32m4x2) /* LMUL = 8: - Machine mode = VNx32SImode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx16SImode when TARGET_MIN_VLEN > 32. - Machine mode = VNx8SImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vint32m8_t, 15, __rvv_int32m8_t, int32, VNx32SI, VNx16SI, VNx8SI, _i32m8, - _i32, _e32m8) -DEF_RVV_TYPE (vuint32m8_t, 16, __rvv_uint32m8_t, uint32, VNx32SI, VNx16SI, VNx8SI, - _u32m8, _u32, _e32m8) + Machine mode = RVVM8SImode. */ +DEF_RVV_TYPE (vint32m8_t, 15, __rvv_int32m8_t, int32, RVVM8SI, _i32m8, _i32, + _e32m8) +DEF_RVV_TYPE (vuint32m8_t, 16, __rvv_uint32m8_t, uint32, RVVM8SI, _u32m8, _u32, + _e32m8) /* SEW = 64: Disable when !TARGET_VECTOR_ELEN_64. */ -DEF_RVV_TYPE (vint64m1_t, 15, __rvv_int64m1_t, int64, VNx2DI, VNx1DI, VOID, _i64m1, - _i64, _e64m1) -DEF_RVV_TYPE (vuint64m1_t, 16, __rvv_uint64m1_t, uint64, VNx2DI, VNx1DI, VOID, _u64m1, - _u64, _e64m1) +DEF_RVV_TYPE (vint64m1_t, 15, __rvv_int64m1_t, int64, RVVM1DI, _i64m1, _i64, + _e64m1) +DEF_RVV_TYPE (vuint64m1_t, 16, __rvv_uint64m1_t, uint64, RVVM1DI, _u64m1, _u64, + _e64m1) /* Define tuple types for SEW = 64, LMUL = M1. */ DEF_RVV_TUPLE_TYPE (vint64m1x2_t, 17, __rvv_int64m1x2_t, vint64m1_t, int64, 2, _i64m1x2) DEF_RVV_TUPLE_TYPE (vuint64m1x2_t, 18, __rvv_uint64m1x2_t, vuint64m1_t, uint64, 2, _u64m1x2) @@ -467,10 +413,10 @@ DEF_RVV_TUPLE_TYPE (vint64m1x7_t, 17, __rvv_int64m1x7_t, vint64m1_t, int64, 7, _ DEF_RVV_TUPLE_TYPE (vuint64m1x7_t, 18, __rvv_uint64m1x7_t, vuint64m1_t, uint64, 7, _u64m1x7) DEF_RVV_TUPLE_TYPE (vint64m1x8_t, 17, __rvv_int64m1x8_t, vint64m1_t, int64, 8, _i64m1x8) DEF_RVV_TUPLE_TYPE (vuint64m1x8_t, 18, __rvv_uint64m1x8_t, vuint64m1_t, uint64, 8, _u64m1x8) -DEF_RVV_TYPE (vint64m2_t, 15, __rvv_int64m2_t, int64, VNx4DI, VNx2DI, VOID, _i64m2, - _i64, _e64m2) -DEF_RVV_TYPE (vuint64m2_t, 16, __rvv_uint64m2_t, uint64, VNx4DI, VNx2DI, VOID, _u64m2, - _u64, _e64m2) +DEF_RVV_TYPE (vint64m2_t, 15, __rvv_int64m2_t, int64, RVVM2DI, _i64m2, _i64, + _e64m2) +DEF_RVV_TYPE (vuint64m2_t, 16, __rvv_uint64m2_t, uint64, RVVM2DI, _u64m2, _u64, + _e64m2) /* Define tuple types for SEW = 64, LMUL = M2. */ DEF_RVV_TUPLE_TYPE (vint64m2x2_t, 17, __rvv_int64m2x2_t, vint64m2_t, int64, 2, _i64m2x2) DEF_RVV_TUPLE_TYPE (vuint64m2x2_t, 18, __rvv_uint64m2x2_t, vuint64m2_t, uint64, 2, _u64m2x2) @@ -478,22 +424,22 @@ DEF_RVV_TUPLE_TYPE (vint64m2x3_t, 17, __rvv_int64m2x3_t, vint64m2_t, int64, 3, _ DEF_RVV_TUPLE_TYPE (vuint64m2x3_t, 18, __rvv_uint64m2x3_t, vuint64m2_t, uint64, 3, _u64m2x3) DEF_RVV_TUPLE_TYPE (vint64m2x4_t, 17, __rvv_int64m2x4_t, vint64m2_t, int64, 4, _i64m2x4) DEF_RVV_TUPLE_TYPE (vuint64m2x4_t, 18, __rvv_uint64m2x4_t, vuint64m2_t, uint64, 4, _u64m2x4) -DEF_RVV_TYPE (vint64m4_t, 15, __rvv_int64m4_t, int64, VNx8DI, VNx4DI, VOID, _i64m4, - _i64, _e64m4) -DEF_RVV_TYPE (vuint64m4_t, 16, __rvv_uint64m4_t, uint64, VNx8DI, VNx4DI, VOID, _u64m4, - _u64, _e64m4) +DEF_RVV_TYPE (vint64m4_t, 15, __rvv_int64m4_t, int64, RVVM4DI, _i64m4, _i64, + _e64m4) +DEF_RVV_TYPE (vuint64m4_t, 16, __rvv_uint64m4_t, uint64, RVVM4DI, _u64m4, _u64, + _e64m4) /* Define tuple types for SEW = 64, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vint64m4x2_t, 17, __rvv_int64m4x2_t, vint64m4_t, int64, 2, _i64m4x2) DEF_RVV_TUPLE_TYPE (vuint64m4x2_t, 18, __rvv_uint64m4x2_t, vuint64m4_t, uint64, 2, _u64m4x2) -DEF_RVV_TYPE (vint64m8_t, 15, __rvv_int64m8_t, int64, VNx16DI, VNx8DI, VOID, _i64m8, - _i64, _e64m8) -DEF_RVV_TYPE (vuint64m8_t, 16, __rvv_uint64m8_t, uint64, VNx16DI, VNx8DI, VOID, _u64m8, - _u64, _e64m8) +DEF_RVV_TYPE (vint64m8_t, 15, __rvv_int64m8_t, int64, RVVM8DI, _i64m8, _i64, + _e64m8) +DEF_RVV_TYPE (vuint64m8_t, 16, __rvv_uint64m8_t, uint64, RVVM8DI, _u64m8, _u64, + _e64m8) /* Enabled if TARGET_VECTOR_ELEN_FP_16 && (TARGET_ZVFH or TARGET_ZVFHMIN). */ /* LMUL = 1/4. */ -DEF_RVV_TYPE (vfloat16mf4_t, 18, __rvv_float16mf4_t, float16, VNx2HF, VNx1HF, VOID, - _f16mf4, _f16, _e16mf4) +DEF_RVV_TYPE (vfloat16mf4_t, 18, __rvv_float16mf4_t, float16, RVVMF4HF, _f16mf4, + _f16, _e16mf4) /* Define tuple types for SEW = 16, LMUL = MF4. */ DEF_RVV_TUPLE_TYPE (vfloat16mf4x2_t, 20, __rvv_float16mf4x2_t, vfloat16mf4_t, float, 2, _f16mf4x2) DEF_RVV_TUPLE_TYPE (vfloat16mf4x3_t, 20, __rvv_float16mf4x3_t, vfloat16mf4_t, float, 3, _f16mf4x3) @@ -503,8 +449,8 @@ DEF_RVV_TUPLE_TYPE (vfloat16mf4x6_t, 20, __rvv_float16mf4x6_t, vfloat16mf4_t, fl DEF_RVV_TUPLE_TYPE (vfloat16mf4x7_t, 20, __rvv_float16mf4x7_t, vfloat16mf4_t, float, 7, _f16mf4x7) DEF_RVV_TUPLE_TYPE (vfloat16mf4x8_t, 20, __rvv_float16mf4x8_t, vfloat16mf4_t, float, 8, _f16mf4x8) /* LMUL = 1/2. */ -DEF_RVV_TYPE (vfloat16mf2_t, 18, __rvv_float16mf2_t, float16, VNx4HF, VNx2HF, VNx1HF, - _f16mf2, _f16, _e16mf2) +DEF_RVV_TYPE (vfloat16mf2_t, 18, __rvv_float16mf2_t, float16, RVVMF2HF, _f16mf2, + _f16, _e16mf2) /* Define tuple types for SEW = 16, LMUL = MF2. */ DEF_RVV_TUPLE_TYPE (vfloat16mf2x2_t, 20, __rvv_float16mf2x2_t, vfloat16mf2_t, float, 2, _f16mf2x2) DEF_RVV_TUPLE_TYPE (vfloat16mf2x3_t, 20, __rvv_float16mf2x3_t, vfloat16mf2_t, float, 3, _f16mf2x3) @@ -514,8 +460,8 @@ DEF_RVV_TUPLE_TYPE (vfloat16mf2x6_t, 20, __rvv_float16mf2x6_t, vfloat16mf2_t, fl DEF_RVV_TUPLE_TYPE (vfloat16mf2x7_t, 20, __rvv_float16mf2x7_t, vfloat16mf2_t, float, 7, _f16mf2x7) DEF_RVV_TUPLE_TYPE (vfloat16mf2x8_t, 20, __rvv_float16mf2x8_t, vfloat16mf2_t, float, 8, _f16mf2x8) /* LMUL = 1. */ -DEF_RVV_TYPE (vfloat16m1_t, 17, __rvv_float16m1_t, float16, VNx8HF, VNx4HF, VNx2HF, - _f16m1, _f16, _e16m1) +DEF_RVV_TYPE (vfloat16m1_t, 17, __rvv_float16m1_t, float16, RVVM1HF, _f16m1, + _f16, _e16m1) /* Define tuple types for SEW = 16, LMUL = M1. */ DEF_RVV_TUPLE_TYPE (vfloat16m1x2_t, 19, __rvv_float16m1x2_t, vfloat16m1_t, float, 2, _f16m1x2) DEF_RVV_TUPLE_TYPE (vfloat16m1x3_t, 19, __rvv_float16m1x3_t, vfloat16m1_t, float, 3, _f16m1x3) @@ -525,28 +471,27 @@ DEF_RVV_TUPLE_TYPE (vfloat16m1x6_t, 19, __rvv_float16m1x6_t, vfloat16m1_t, float DEF_RVV_TUPLE_TYPE (vfloat16m1x7_t, 19, __rvv_float16m1x7_t, vfloat16m1_t, float, 7, _f16m1x7) DEF_RVV_TUPLE_TYPE (vfloat16m1x8_t, 19, __rvv_float16m1x8_t, vfloat16m1_t, float, 8, _f16m1x8) /* LMUL = 2. */ -DEF_RVV_TYPE (vfloat16m2_t, 17, __rvv_float16m2_t, float16, VNx16HF, VNx8HF, VNx4HF, - _f16m2, _f16, _e16m2) +DEF_RVV_TYPE (vfloat16m2_t, 17, __rvv_float16m2_t, float16, RVVM2HF, _f16m2, + _f16, _e16m2) /* Define tuple types for SEW = 16, LMUL = M2. */ DEF_RVV_TUPLE_TYPE (vfloat16m2x2_t, 19, __rvv_float16m2x2_t, vfloat16m2_t, float, 2, _f16m2x2) DEF_RVV_TUPLE_TYPE (vfloat16m2x3_t, 19, __rvv_float16m2x3_t, vfloat16m2_t, float, 3, _f16m2x3) DEF_RVV_TUPLE_TYPE (vfloat16m2x4_t, 19, __rvv_float16m2x4_t, vfloat16m2_t, float, 4, _f16m2x4) /* LMUL = 4. */ -DEF_RVV_TYPE (vfloat16m4_t, 17, __rvv_float16m4_t, float16, VNx32HF, VNx16HF, VNx8HF, - _f16m4, _f16, _e16m4) +DEF_RVV_TYPE (vfloat16m4_t, 17, __rvv_float16m4_t, float16, RVVM4HF, _f16m4, + _f16, _e16m4) /* Define tuple types for SEW = 16, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vfloat16m4x2_t, 19, __rvv_float16m4x2_t, vfloat16m4_t, float, 2, _f16m4x2) /* LMUL = 8. */ -DEF_RVV_TYPE (vfloat16m8_t, 16, __rvv_float16m8_t, float16, VNx64HF, VNx32HF, VNx16HF, - _f16m8, _f16, _e16m8) +DEF_RVV_TYPE (vfloat16m8_t, 16, __rvv_float16m8_t, float16, RVVM8HF, _f16m8, + _f16, _e16m8) /* Disable all when !TARGET_VECTOR_ELEN_FP_32. */ /* LMUL = 1/2: Only enble when TARGET_MIN_VLEN > 32. - Machine mode = VNx1SFmode when TARGET_MIN_VLEN < 128. - Machine mode = VNx2SFmode when TARGET_MIN_VLEN >= 128. */ -DEF_RVV_TYPE (vfloat32mf2_t, 18, __rvv_float32mf2_t, float, VNx2SF, VNx1SF, VOID, - _f32mf2, _f32, _e32mf2) + Machine mode = RVVMF2SFmode. */ +DEF_RVV_TYPE (vfloat32mf2_t, 18, __rvv_float32mf2_t, float, RVVMF2SF, _f32mf2, + _f32, _e32mf2) /* Define tuple types for SEW = 32, LMUL = MF2. */ DEF_RVV_TUPLE_TYPE (vfloat32mf2x2_t, 20, __rvv_float32mf2x2_t, vfloat32mf2_t, float, 2, _f32mf2x2) DEF_RVV_TUPLE_TYPE (vfloat32mf2x3_t, 20, __rvv_float32mf2x3_t, vfloat32mf2_t, float, 3, _f32mf2x3) @@ -556,11 +501,9 @@ DEF_RVV_TUPLE_TYPE (vfloat32mf2x6_t, 20, __rvv_float32mf2x6_t, vfloat32mf2_t, fl DEF_RVV_TUPLE_TYPE (vfloat32mf2x7_t, 20, __rvv_float32mf2x7_t, vfloat32mf2_t, float, 7, _f32mf2x7) DEF_RVV_TUPLE_TYPE (vfloat32mf2x8_t, 20, __rvv_float32mf2x8_t, vfloat32mf2_t, float, 8, _f32mf2x8) /* LMUL = 1: - Machine mode = VNx4SFmode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx2SFmode when TARGET_MIN_VLEN > 32. - Machine mode = VNx1SFmode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vfloat32m1_t, 17, __rvv_float32m1_t, float, VNx4SF, VNx2SF, VNx1SF, - _f32m1, _f32, _e32m1) + Machine mode = RVVM1SFmode. */ +DEF_RVV_TYPE (vfloat32m1_t, 17, __rvv_float32m1_t, float, RVVM1SF, _f32m1, _f32, + _e32m1) /* Define tuple types for SEW = 32, LMUL = M1. */ DEF_RVV_TUPLE_TYPE (vfloat32m1x2_t, 19, __rvv_float32m1x2_t, vfloat32m1_t, float, 2, _f32m1x2) DEF_RVV_TUPLE_TYPE (vfloat32m1x3_t, 19, __rvv_float32m1x3_t, vfloat32m1_t, float, 3, _f32m1x3) @@ -570,33 +513,27 @@ DEF_RVV_TUPLE_TYPE (vfloat32m1x6_t, 19, __rvv_float32m1x6_t, vfloat32m1_t, float DEF_RVV_TUPLE_TYPE (vfloat32m1x7_t, 19, __rvv_float32m1x7_t, vfloat32m1_t, float, 7, _f32m1x7) DEF_RVV_TUPLE_TYPE (vfloat32m1x8_t, 19, __rvv_float32m1x8_t, vfloat32m1_t, float, 8, _f32m1x8) /* LMUL = 2: - Machine mode = VNx8SFmode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx4SFmode when TARGET_MIN_VLEN > 32. - Machine mode = VNx2SFmode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vfloat32m2_t, 17, __rvv_float32m2_t, float, VNx8SF, VNx4SF, VNx2SF, - _f32m2, _f32, _e32m2) + Machine mode = RVVM2SFmode. */ +DEF_RVV_TYPE (vfloat32m2_t, 17, __rvv_float32m2_t, float, RVVM2SF, _f32m2, _f32, + _e32m2) /* Define tuple types for SEW = 32, LMUL = M2. */ DEF_RVV_TUPLE_TYPE (vfloat32m2x2_t, 19, __rvv_float32m2x2_t, vfloat32m2_t, float, 2, _f32m2x2) DEF_RVV_TUPLE_TYPE (vfloat32m2x3_t, 19, __rvv_float32m2x3_t, vfloat32m2_t, float, 3, _f32m2x3) DEF_RVV_TUPLE_TYPE (vfloat32m2x4_t, 19, __rvv_float32m2x4_t, vfloat32m2_t, float, 4, _f32m2x4) /* LMUL = 4: - Machine mode = VNx16SFmode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx8SFmode when TARGET_MIN_VLEN > 32. - Machine mode = VNx4SFmode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vfloat32m4_t, 17, __rvv_float32m4_t, float, VNx16SF, VNx8SF, VNx4SF, - _f32m4, _f32, _e32m4) + Machine mode = RVVM4SFmode. */ +DEF_RVV_TYPE (vfloat32m4_t, 17, __rvv_float32m4_t, float, RVVM4SF, _f32m4, _f32, + _e32m4) /* Define tuple types for SEW = 32, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vfloat32m4x2_t, 19, __rvv_float32m4x2_t, vfloat32m4_t, float, 2, _f32m4x2) /* LMUL = 8: - Machine mode = VNx32SFmode when TARGET_MIN_VLEN >= 128. - Machine mode = VNx16SFmode when TARGET_MIN_VLEN > 32. - Machine mode = VNx8SFmode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vfloat32m8_t, 17, __rvv_float32m8_t, float, VNx32SF, VNx16SF, VNx8SF, - _f32m8, _f32, _e32m8) + Machine mode = RVVM8SFmode. */ +DEF_RVV_TYPE (vfloat32m8_t, 17, __rvv_float32m8_t, float, RVVM8SF, _f32m8, _f32, + _e32m8) /* SEW = 64: Disable when !TARGET_VECTOR_ELEN_FP_64. */ -DEF_RVV_TYPE (vfloat64m1_t, 17, __rvv_float64m1_t, double, VNx2DF, VNx1DF, VOID, _f64m1, +DEF_RVV_TYPE (vfloat64m1_t, 17, __rvv_float64m1_t, double, RVVM1DF, _f64m1, _f64, _e64m1) /* Define tuple types for SEW = 64, LMUL = M1. */ DEF_RVV_TUPLE_TYPE (vfloat64m1x2_t, 19, __rvv_float64m1x2_t, vfloat64m1_t, double, 2, _f64m1x2) @@ -606,17 +543,17 @@ DEF_RVV_TUPLE_TYPE (vfloat64m1x5_t, 19, __rvv_float64m1x5_t, vfloat64m1_t, doubl DEF_RVV_TUPLE_TYPE (vfloat64m1x6_t, 19, __rvv_float64m1x6_t, vfloat64m1_t, double, 6, _f64m1x6) DEF_RVV_TUPLE_TYPE (vfloat64m1x7_t, 19, __rvv_float64m1x7_t, vfloat64m1_t, double, 7, _f64m1x7) DEF_RVV_TUPLE_TYPE (vfloat64m1x8_t, 19, __rvv_float64m1x8_t, vfloat64m1_t, double, 8, _f64m1x8) -DEF_RVV_TYPE (vfloat64m2_t, 17, __rvv_float64m2_t, double, VNx4DF, VNx2DF, VOID, _f64m2, +DEF_RVV_TYPE (vfloat64m2_t, 17, __rvv_float64m2_t, double, RVVM2DF, _f64m2, _f64, _e64m2) /* Define tuple types for SEW = 64, LMUL = M2. */ DEF_RVV_TUPLE_TYPE (vfloat64m2x2_t, 19, __rvv_float64m2x2_t, vfloat64m2_t, double, 2, _f64m2x2) DEF_RVV_TUPLE_TYPE (vfloat64m2x3_t, 19, __rvv_float64m2x3_t, vfloat64m2_t, double, 3, _f64m2x3) DEF_RVV_TUPLE_TYPE (vfloat64m2x4_t, 19, __rvv_float64m2x4_t, vfloat64m2_t, double, 4, _f64m2x4) -DEF_RVV_TYPE (vfloat64m4_t, 17, __rvv_float64m4_t, double, VNx8DF, VNx4DF, VOID, _f64m4, +DEF_RVV_TYPE (vfloat64m4_t, 17, __rvv_float64m4_t, double, RVVM4DF, _f64m4, _f64, _e64m4) /* Define tuple types for SEW = 64, LMUL = M4. */ DEF_RVV_TUPLE_TYPE (vfloat64m4x2_t, 19, __rvv_float64m4x2_t, vfloat64m4_t, double, 2, _f64m4x2) -DEF_RVV_TYPE (vfloat64m8_t, 17, __rvv_float64m8_t, double, VNx16DF, VNx8DF, VOID, _f64m8, +DEF_RVV_TYPE (vfloat64m8_t, 17, __rvv_float64m8_t, double, RVVM8DF, _f64m8, _f64, _e64m8) DEF_RVV_OP_TYPE (vv) diff --git a/gcc/config/riscv/riscv-vector-switch.def b/gcc/config/riscv/riscv-vector-switch.def index 7f14891..c83e2ef 100644 --- a/gcc/config/riscv/riscv-vector-switch.def +++ b/gcc/config/riscv/riscv-vector-switch.def @@ -31,345 +31,260 @@ along with GCC; see the file COPYING3. If not see Note: N/A means the corresponding vector type is disabled. -|Types |LMUL=1|LMUL=2 |LMUL=4 |LMUL=8 |LMUL=1/2|LMUL=1/4|LMUL=1/8| -|int64_t |VNx1DI|VNx2DI |VNx4DI |VNx8DI |N/A |N/A |N/A | -|uint64_t|VNx1DI|VNx2DI |VNx4DI |VNx8DI |N/A |N/A |N/A | -|int32_t |VNx2SI|VNx4SI |VNx8SI |VNx16SI|VNx1SI |N/A |N/A | -|uint32_t|VNx2SI|VNx4SI |VNx8SI |VNx16SI|VNx1SI |N/A |N/A | -|int16_t |VNx4HI|VNx8HI |VNx16HI|VNx32HI|VNx2HI |VNx1HI |N/A | -|uint16_t|VNx4HI|VNx8HI |VNx16HI|VNx32HI|VNx2HI |VNx1HI |N/A | -|int8_t |VNx8QI|VNx16QI|VNx32QI|VNx64QI|VNx4QI |VNx2QI |VNx1QI | -|uint8_t |VNx8QI|VNx16QI|VNx32QI|VNx64QI|VNx4QI |VNx2QI |VNx1QI | -|float64 |VNx1DF|VNx2DF |VNx4DF |VNx8DF |N/A |N/A |N/A | -|float32 |VNx2SF|VNx4SF |VNx8SF |VNx16SF|VNx1SF |N/A |N/A | -|float16 |VNx4HF|VNx8HF |VNx16HF|VNx32HF|VNx2HF |VNx1HF |N/A | - -Mask Types Encode the ratio of SEW/LMUL into the -mask types. There are the following mask types. - -n = SEW/LMUL - -|Types|n=1 |n=2 |n=4 |n=8 |n=16 |n=32 |n=64 | -|bool |VNx64BI|VNx32BI|VNx16BI|VNx8BI|VNx4BI|VNx2BI|VNx1BI| - -There are the following data types for MIN_VLEN = 32. - -|Types |LMUL=1|LMUL=2|LMUL=4 |LMUL=8 |LMUL=1/2|LMUL=1/4|LMUL=1/8| -|int64_t |N/A |N/A |N/A |N/A |N/A |N/A |N/A | -|uint64_t|N/A |N/A |N/A |N/A |N/A |N/A |N/A | -|int32_t |VNx1SI|VNx2SI|VNx4SI |VNx8SI |N/A |N/A |N/A | -|uint32_t|VNx1SI|VNx2SI|VNx4SI |VNx8SI |N/A |N/A |N/A | -|int16_t |VNx2HI|VNx4HI|VNx8HI |VNx16HI|VNx1HI |N/A |N/A | -|uint16_t|VNx2HI|VNx4HI|VNx8HI |VNx16HI|VNx1HI |N/A |N/A | -|int8_t |VNx4QI|VNx8QI|VNx16QI|VNx32QI|VNx2QI |VNx1QI |N/A | -|uint8_t |VNx4QI|VNx8QI|VNx16QI|VNx32QI|VNx2QI |VNx1QI |N/A | -|float64 |N/A |N/A |N/A |N/A |N/A |N/A |N/A | -|float32 |VNx1SF|VNx2SF|VNx4SF |VNx8SF |N/A |N/A |N/A | -|float16 |VNx2HF|VNx4HF|VNx8HF |VNx16HF|VNx1HF |N/A |N/A | - -Mask Types Encode the ratio of SEW/LMUL into the -mask types. There are the following mask types. - -n = SEW/LMUL - -|Types|n=1 |n=2 |n=4 |n=8 |n=16 |n=32 |n=64| -|bool |VNx32BI|VNx16BI|VNx8BI|VNx4BI|VNx2BI|VNx1BI|N/A | - -TODO: FP16 vector needs support of 'zvfh', we don't support it yet. */ +Encode SEW and LMUL into data types. + We enforce the constraint LMUL ≥ SEW/ELEN in the implementation. + There are the following data types for ELEN = 64. + + |Modes|LMUL=1 |LMUL=2 |LMUL=4 |LMUL=8 |LMUL=1/2|LMUL=1/4|LMUL=1/8| + |DI |RVVM1DI|RVVM2DI|RVVM4DI|RVVM8DI|N/A |N/A |N/A | + |SI |RVVM1SI|RVVM2SI|RVVM4SI|RVVM8SI|RVVMF2SI|N/A |N/A | + |HI |RVVM1HI|RVVM2HI|RVVM4HI|RVVM8HI|RVVMF2HI|RVVMF4HI|N/A | + |QI |RVVM1QI|RVVM2QI|RVVM4QI|RVVM8QI|RVVMF2QI|RVVMF4QI|RVVMF8QI| + |DF |RVVM1DF|RVVM2DF|RVVM4DF|RVVM8DF|N/A |N/A |N/A | + |SF |RVVM1SF|RVVM2SF|RVVM4SF|RVVM8SF|RVVMF2SF|N/A |N/A | + |HF |RVVM1HF|RVVM2HF|RVVM4HF|RVVM8HF|RVVMF2HF|RVVMF4HF|N/A | + +There are the following data types for ELEN = 32. + + |Modes|LMUL=1 |LMUL=2 |LMUL=4 |LMUL=8 |LMUL=1/2|LMUL=1/4|LMUL=1/8| + |SI |RVVM1SI|RVVM2SI|RVVM4SI|RVVM8SI|N/A |N/A |N/A | + |HI |RVVM1HI|RVVM2HI|RVVM4HI|RVVM8HI|RVVMF2HI|N/A |N/A | + |QI |RVVM1QI|RVVM2QI|RVVM4QI|RVVM8QI|RVVMF2QI|RVVMF4QI|N/A | + |SF |RVVM1SF|RVVM2SF|RVVM4SF|RVVM8SF|N/A |N/A |N/A | + |HF |RVVM1HF|RVVM2HF|RVVM4HF|RVVM8HF|RVVMF2HF|N/A |N/A | + +Encode the ratio of SEW/LMUL into the mask types. + There are the following mask types. + + n = SEW/LMUL + + |Modes| n = 1 | n = 2 | n = 4 | n = 8 | n = 16 | n = 32 | n = 64 | + |BI |RVVM1BI|RVVMF2BI|RVVMF4BI|RVVMF8BI|RVVMF16BI|RVVMF32BI|RVVMF64BI| */ /* Return 'REQUIREMENT' for machine_mode 'MODE'. - For example: 'MODE' = VNx64BImode needs TARGET_MIN_VLEN > 32. */ + For example: 'MODE' = RVVMF64BImode needs TARGET_MIN_VLEN > 32. */ #ifndef ENTRY -#define ENTRY(MODE, REQUIREMENT, VLMUL_FOR_MIN_VLEN32, RATIO_FOR_MIN_VLEN32, \ - VLMUL_FOR_MIN_VLEN64, RATIO_FOR_MIN_VLEN64, \ - VLMUL_FOR_MIN_VLEN128, RATIO_FOR_MIN_VLEN128) +#define ENTRY(MODE, REQUIREMENT, VLMUL, RATIO) #endif + +/* Disable modes if TARGET_MIN_VLEN == 32. */ +ENTRY (RVVMF64BI, TARGET_MIN_VLEN > 32, LMUL_F8, 64) +ENTRY (RVVMF32BI, true, LMUL_F4, 32) +ENTRY (RVVMF16BI, true, LMUL_F2, 16) +ENTRY (RVVMF8BI, true, LMUL_1, 8) +ENTRY (RVVMF4BI, true, LMUL_2, 4) +ENTRY (RVVMF2BI, true, LMUL_4, 2) +ENTRY (RVVM1BI, true, LMUL_8, 1) + +/* Disable modes if TARGET_MIN_VLEN == 32. */ +ENTRY (RVVM8QI, true, LMUL_8, 1) +ENTRY (RVVM4QI, true, LMUL_4, 2) +ENTRY (RVVM2QI, true, LMUL_2, 4) +ENTRY (RVVM1QI, true, LMUL_1, 8) +ENTRY (RVVMF2QI, true, LMUL_F2, 16) +ENTRY (RVVMF4QI, true, LMUL_F4, 32) +ENTRY (RVVMF8QI, TARGET_MIN_VLEN > 32, LMUL_F8, 64) + +/* Disable modes if TARGET_MIN_VLEN == 32. */ +ENTRY (RVVM8HI, true, LMUL_8, 2) +ENTRY (RVVM4HI, true, LMUL_4, 4) +ENTRY (RVVM2HI, true, LMUL_2, 8) +ENTRY (RVVM1HI, true, LMUL_1, 16) +ENTRY (RVVMF2HI, true, LMUL_F2, 32) +ENTRY (RVVMF4HI, TARGET_MIN_VLEN > 32, LMUL_F4, 64) + +/* Disable modes if TARGET_MIN_VLEN == 32 or !TARGET_VECTOR_ELEN_FP_16. */ +ENTRY (RVVM8HF, TARGET_VECTOR_ELEN_FP_16, LMUL_8, 2) +ENTRY (RVVM4HF, TARGET_VECTOR_ELEN_FP_16, LMUL_4, 4) +ENTRY (RVVM2HF, TARGET_VECTOR_ELEN_FP_16, LMUL_2, 8) +ENTRY (RVVM1HF, TARGET_VECTOR_ELEN_FP_16, LMUL_1, 16) +ENTRY (RVVMF2HF, TARGET_VECTOR_ELEN_FP_16, LMUL_F2, 32) +ENTRY (RVVMF4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, LMUL_F4, 64) + +/* Disable modes if TARGET_MIN_VLEN == 32. */ +ENTRY (RVVM8SI, true, LMUL_8, 4) +ENTRY (RVVM4SI, true, LMUL_4, 8) +ENTRY (RVVM2SI, true, LMUL_2, 16) +ENTRY (RVVM1SI, true, LMUL_1, 32) +ENTRY (RVVMF2SI, TARGET_MIN_VLEN > 32, LMUL_F2, 64) + +/* Disable modes if TARGET_MIN_VLEN == 32 or !TARGET_VECTOR_ELEN_FP_32. */ +ENTRY (RVVM8SF, TARGET_VECTOR_ELEN_FP_32, LMUL_8, 4) +ENTRY (RVVM4SF, TARGET_VECTOR_ELEN_FP_32, LMUL_4, 8) +ENTRY (RVVM2SF, TARGET_VECTOR_ELEN_FP_32, LMUL_2, 16) +ENTRY (RVVM1SF, TARGET_VECTOR_ELEN_FP_32, LMUL_1, 32) +ENTRY (RVVMF2SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, LMUL_F2, 64) + +/* Disable modes if !TARGET_VECTOR_ELEN_64. */ +ENTRY (RVVM8DI, TARGET_VECTOR_ELEN_64, LMUL_8, 8) +ENTRY (RVVM4DI, TARGET_VECTOR_ELEN_64, LMUL_4, 16) +ENTRY (RVVM2DI, TARGET_VECTOR_ELEN_64, LMUL_2, 32) +ENTRY (RVVM1DI, TARGET_VECTOR_ELEN_64, LMUL_1, 64) + +/* Disable modes if !TARGET_VECTOR_ELEN_FP_64. */ +ENTRY (RVVM8DF, TARGET_VECTOR_ELEN_FP_64, LMUL_8, 8) +ENTRY (RVVM4DF, TARGET_VECTOR_ELEN_FP_64, LMUL_4, 16) +ENTRY (RVVM2DF, TARGET_VECTOR_ELEN_FP_64, LMUL_2, 32) +ENTRY (RVVM1DF, TARGET_VECTOR_ELEN_FP_64, LMUL_1, 64) + +/* Tuple modes for segment loads/stores according to NF. + + Tuple modes format: RVVx + + When LMUL is MF8/MF4/MF2/M1, NF can be 2 ~ 8. + When LMUL is M2, NF can be 2 ~ 4. + When LMUL is M4, NF can be 4. */ + #ifndef TUPLE_ENTRY -#define TUPLE_ENTRY(MODE, REQUIREMENT, SUBPART_MODE, NF, VLMUL_FOR_MIN_VLEN32, \ - RATIO_FOR_MIN_VLEN32, VLMUL_FOR_MIN_VLEN64, \ - RATIO_FOR_MIN_VLEN64, VLMUL_FOR_MIN_VLEN128, \ - RATIO_FOR_MIN_VLEN128) +#define TUPLE_ENTRY(MODE, REQUIREMENT, SUBPART_MODE, NF, VLMUL, RATIO) #endif -/* Mask modes. Disable VNx64BImode when TARGET_MIN_VLEN == 32. */ -ENTRY (VNx128BI, TARGET_MIN_VLEN >= 128, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 1) -ENTRY (VNx64BI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_8, 1, LMUL_4, 2) -ENTRY (VNx32BI, true, LMUL_8, 1, LMUL_4, 2, LMUL_2, 4) -ENTRY (VNx16BI, true, LMUL_4, 2, LMUL_2, 4, LMUL_1, 8) -ENTRY (VNx8BI, true, LMUL_2, 4, LMUL_1, 8, LMUL_F2, 16) -ENTRY (VNx4BI, true, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -ENTRY (VNx2BI, true, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -ENTRY (VNx1BI, TARGET_MIN_VLEN < 128, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) - -/* SEW = 8. Disable VNx64QImode when TARGET_MIN_VLEN == 32. */ -ENTRY (VNx128QI, TARGET_MIN_VLEN >= 128, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 1) -ENTRY (VNx64QI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_8, 1, LMUL_4, 2) -ENTRY (VNx32QI, true, LMUL_8, 1, LMUL_4, 2, LMUL_2, 4) -ENTRY (VNx16QI, true, LMUL_4, 2, LMUL_2, 4, LMUL_1, 8) -ENTRY (VNx8QI, true, LMUL_2, 4, LMUL_1, 8, LMUL_F2, 16) -ENTRY (VNx4QI, true, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -ENTRY (VNx2QI, true, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -ENTRY (VNx1QI, TARGET_MIN_VLEN < 128, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) - -/* SEW = 16. Disable VNx32HImode when TARGET_MIN_VLEN == 32. */ -ENTRY (VNx64HI, TARGET_MIN_VLEN >= 128, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 2) -ENTRY (VNx32HI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_8, 2, LMUL_4, 4) -ENTRY (VNx16HI, true, LMUL_8, 2, LMUL_4, 4, LMUL_2, 8) -ENTRY (VNx8HI, true, LMUL_4, 4, LMUL_2, 8, LMUL_1, 16) -ENTRY (VNx4HI, true, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -ENTRY (VNx2HI, true, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -ENTRY (VNx1HI, TARGET_MIN_VLEN < 128, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) - -/* SEW = 16 for float point. Enabled when 'zvfh' or 'zvfhmin' is given. */ -ENTRY (VNx64HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, \ - LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 2) -ENTRY (VNx32HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, \ - LMUL_RESERVED, 0, LMUL_8, 2, LMUL_4, 4) -ENTRY (VNx16HF, TARGET_VECTOR_ELEN_FP_16, \ - LMUL_8, 2, LMUL_4, 4, LMUL_2, 8) -ENTRY (VNx8HF, TARGET_VECTOR_ELEN_FP_16, \ - LMUL_4, 4, LMUL_2, 8, LMUL_1, 16) -ENTRY (VNx4HF, TARGET_VECTOR_ELEN_FP_16, \ - LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -ENTRY (VNx2HF, TARGET_VECTOR_ELEN_FP_16, \ - LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -ENTRY (VNx1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, \ - LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) - -/* SEW = 32. Disable VNx16SImode when TARGET_MIN_VLEN == 32. - For single-precision floating-point, we need TARGET_VECTOR_ELEN_FP_32 to be - true. */ -ENTRY (VNx32SI, TARGET_MIN_VLEN >= 128, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 4) -ENTRY (VNx16SI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_8, 4, LMUL_4, 8) -ENTRY (VNx8SI, true, LMUL_8, 4, LMUL_4, 8, LMUL_2, 16) -ENTRY (VNx4SI, true, LMUL_4, 8, LMUL_2, 16, LMUL_1, 32) -ENTRY (VNx2SI, true, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -ENTRY (VNx1SI, TARGET_MIN_VLEN < 128, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) - -ENTRY (VNx32SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 4) -ENTRY (VNx16SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, - LMUL_8, 4, LMUL_4, 8) -ENTRY (VNx8SF, TARGET_VECTOR_ELEN_FP_32, LMUL_8, 4, LMUL_4, 8, LMUL_2, 16) -ENTRY (VNx4SF, TARGET_VECTOR_ELEN_FP_32, LMUL_4, 8, LMUL_2, 16, LMUL_1, 32) -ENTRY (VNx2SF, TARGET_VECTOR_ELEN_FP_32, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -ENTRY (VNx1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) - -/* SEW = 64. Enable when TARGET_VECTOR_ELEN_64 is true. - For double-precision floating-point, we need TARGET_VECTOR_ELEN_FP_64 to be - true. */ -ENTRY (VNx16DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 8) -ENTRY (VNx8DI, TARGET_VECTOR_ELEN_64, LMUL_RESERVED, 0, LMUL_8, 8, LMUL_4, 16) -ENTRY (VNx4DI, TARGET_VECTOR_ELEN_64, LMUL_RESERVED, 0, LMUL_4, 16, LMUL_2, 32) -ENTRY (VNx2DI, TARGET_VECTOR_ELEN_64, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -ENTRY (VNx1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) - -ENTRY (VNx16DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_8, 8) -ENTRY (VNx8DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, - LMUL_8, 8, LMUL_4, 16) -ENTRY (VNx4DF, TARGET_VECTOR_ELEN_FP_64, LMUL_RESERVED, 0, LMUL_4, 16, LMUL_2, 32) -ENTRY (VNx2DF, TARGET_VECTOR_ELEN_FP_64, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -ENTRY (VNx1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) - -/* Enable or disable the tuple type. BASE_MODE is the base vector mode of the - tuple mode. For example, the BASE_MODE of VNx2x1SImode is VNx1SImode. ALL - tuple modes should always satisfy NF * BASE_MODE LMUL <= 8. */ - -/* Tuple modes for EEW = 8. */ -TUPLE_ENTRY (VNx2x64QI, TARGET_MIN_VLEN >= 128, VNx64QI, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 2) -TUPLE_ENTRY (VNx2x32QI, TARGET_MIN_VLEN >= 64, VNx32QI, 2, LMUL_RESERVED, 0, LMUL_4, 2, LMUL_2, 4) -TUPLE_ENTRY (VNx3x32QI, TARGET_MIN_VLEN >= 128, VNx32QI, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 4) -TUPLE_ENTRY (VNx4x32QI, TARGET_MIN_VLEN >= 128, VNx32QI, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 4) -TUPLE_ENTRY (VNx2x16QI, true, VNx16QI, 2, LMUL_4, 2, LMUL_2, 4, LMUL_1, 8) -TUPLE_ENTRY (VNx3x16QI, TARGET_MIN_VLEN >= 64, VNx16QI, 3, LMUL_RESERVED, 0, LMUL_2, 4, LMUL_1, 8) -TUPLE_ENTRY (VNx4x16QI, TARGET_MIN_VLEN >= 64, VNx16QI, 4, LMUL_RESERVED, 0, LMUL_2, 4, LMUL_1, 8) -TUPLE_ENTRY (VNx5x16QI, TARGET_MIN_VLEN >= 128, VNx16QI, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 8) -TUPLE_ENTRY (VNx6x16QI, TARGET_MIN_VLEN >= 128, VNx16QI, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 8) -TUPLE_ENTRY (VNx7x16QI, TARGET_MIN_VLEN >= 128, VNx16QI, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 8) -TUPLE_ENTRY (VNx8x16QI, TARGET_MIN_VLEN >= 128, VNx16QI, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 8) -TUPLE_ENTRY (VNx2x8QI, true, VNx8QI, 2, LMUL_2, 4, LMUL_1, 8, LMUL_F2, 16) -TUPLE_ENTRY (VNx3x8QI, true, VNx8QI, 3, LMUL_2, 4, LMUL_1, 8, LMUL_F2, 16) -TUPLE_ENTRY (VNx4x8QI, true, VNx8QI, 4, LMUL_2, 4, LMUL_1, 8, LMUL_F2, 16) -TUPLE_ENTRY (VNx5x8QI, TARGET_MIN_VLEN >= 64, VNx8QI, 5, LMUL_RESERVED, 0, LMUL_1, 8, LMUL_F2, 16) -TUPLE_ENTRY (VNx6x8QI, TARGET_MIN_VLEN >= 64, VNx8QI, 6, LMUL_RESERVED, 0, LMUL_1, 8, LMUL_F2, 16) -TUPLE_ENTRY (VNx7x8QI, TARGET_MIN_VLEN >= 64, VNx8QI, 7, LMUL_RESERVED, 0, LMUL_1, 8, LMUL_F2, 16) -TUPLE_ENTRY (VNx8x8QI, TARGET_MIN_VLEN >= 64, VNx8QI, 8, LMUL_RESERVED, 0, LMUL_1, 8, LMUL_F2, 16) -TUPLE_ENTRY (VNx2x4QI, true, VNx4QI, 2, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -TUPLE_ENTRY (VNx3x4QI, true, VNx4QI, 3, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -TUPLE_ENTRY (VNx4x4QI, true, VNx4QI, 4, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -TUPLE_ENTRY (VNx5x4QI, true, VNx4QI, 5, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -TUPLE_ENTRY (VNx6x4QI, true, VNx4QI, 6, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -TUPLE_ENTRY (VNx7x4QI, true, VNx4QI, 7, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -TUPLE_ENTRY (VNx8x4QI, true, VNx4QI, 8, LMUL_1, 8, LMUL_F2, 16, LMUL_F4, 32) -TUPLE_ENTRY (VNx2x2QI, true, VNx2QI, 2, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -TUPLE_ENTRY (VNx3x2QI, true, VNx2QI, 3, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -TUPLE_ENTRY (VNx4x2QI, true, VNx2QI, 4, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -TUPLE_ENTRY (VNx5x2QI, true, VNx2QI, 5, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -TUPLE_ENTRY (VNx6x2QI, true, VNx2QI, 6, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -TUPLE_ENTRY (VNx7x2QI, true, VNx2QI, 7, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -TUPLE_ENTRY (VNx8x2QI, true, VNx2QI, 8, LMUL_F2, 16, LMUL_F4, 32, LMUL_F8, 64) -TUPLE_ENTRY (VNx2x1QI, TARGET_MIN_VLEN < 128, VNx1QI, 2, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx3x1QI, TARGET_MIN_VLEN < 128, VNx1QI, 3, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx4x1QI, TARGET_MIN_VLEN < 128, VNx1QI, 4, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx5x1QI, TARGET_MIN_VLEN < 128, VNx1QI, 5, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx6x1QI, TARGET_MIN_VLEN < 128, VNx1QI, 6, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx7x1QI, TARGET_MIN_VLEN < 128, VNx1QI, 7, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx8x1QI, TARGET_MIN_VLEN < 128, VNx1QI, 8, LMUL_F4, 32, LMUL_F8, 64, LMUL_RESERVED, 0) - -/* Tuple modes for EEW = 16. */ -TUPLE_ENTRY (VNx2x32HI, TARGET_MIN_VLEN >= 128, VNx32HI, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 4) -TUPLE_ENTRY (VNx2x16HI, TARGET_MIN_VLEN >= 64, VNx16HI, 2, LMUL_RESERVED, 0, LMUL_4, 4, LMUL_2, 8) -TUPLE_ENTRY (VNx3x16HI, TARGET_MIN_VLEN >= 128, VNx16HI, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 8) -TUPLE_ENTRY (VNx4x16HI, TARGET_MIN_VLEN >= 128, VNx16HI, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 8) -TUPLE_ENTRY (VNx2x8HI, true, VNx8HI, 2, LMUL_4, 4, LMUL_2, 8, LMUL_1, 16) -TUPLE_ENTRY (VNx3x8HI, TARGET_MIN_VLEN >= 64, VNx8HI, 3, LMUL_RESERVED, 0, LMUL_2, 8, LMUL_1, 16) -TUPLE_ENTRY (VNx4x8HI, TARGET_MIN_VLEN >= 64, VNx8HI, 4, LMUL_RESERVED, 0, LMUL_2, 8, LMUL_1, 16) -TUPLE_ENTRY (VNx5x8HI, TARGET_MIN_VLEN >= 128, VNx8HI, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx6x8HI, TARGET_MIN_VLEN >= 128, VNx8HI, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx7x8HI, TARGET_MIN_VLEN >= 128, VNx8HI, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx8x8HI, TARGET_MIN_VLEN >= 128, VNx8HI, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx2x4HI, true, VNx4HI, 2, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx3x4HI, true, VNx4HI, 3, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx4x4HI, true, VNx4HI, 4, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx5x4HI, TARGET_MIN_VLEN >= 64, VNx4HI, 5, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx6x4HI, TARGET_MIN_VLEN >= 64, VNx4HI, 6, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx7x4HI, TARGET_MIN_VLEN >= 64, VNx4HI, 7, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx8x4HI, TARGET_MIN_VLEN >= 64, VNx4HI, 8, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx2x2HI, true, VNx2HI, 2, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx3x2HI, true, VNx2HI, 3, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx4x2HI, true, VNx2HI, 4, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx5x2HI, true, VNx2HI, 5, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx6x2HI, true, VNx2HI, 6, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx7x2HI, true, VNx2HI, 7, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx8x2HI, true, VNx2HI, 8, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx2x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 2, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx3x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 3, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx4x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 4, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx5x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 5, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx6x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 6, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx7x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 7, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx8x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 8, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx2x32HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx32HF, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 4) -TUPLE_ENTRY (VNx2x16HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx16HF, 2, LMUL_RESERVED, 0, LMUL_4, 4, LMUL_2, 8) -TUPLE_ENTRY (VNx3x16HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx16HF, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 8) -TUPLE_ENTRY (VNx4x16HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx16HF, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 8) -TUPLE_ENTRY (VNx2x8HF, TARGET_VECTOR_ELEN_FP_16, VNx8HF, 2, LMUL_4, 4, LMUL_2, 8, LMUL_1, 16) -TUPLE_ENTRY (VNx3x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx8HF, 3, LMUL_RESERVED, 0, LMUL_2, 8, LMUL_1, 16) -TUPLE_ENTRY (VNx4x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx8HF, 4, LMUL_RESERVED, 0, LMUL_2, 8, LMUL_1, 16) -TUPLE_ENTRY (VNx5x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx6x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx7x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx8x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16) -TUPLE_ENTRY (VNx2x4HF, TARGET_VECTOR_ELEN_FP_16, VNx4HF, 2, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx3x4HF, TARGET_VECTOR_ELEN_FP_16, VNx4HF, 3, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx4x4HF, TARGET_VECTOR_ELEN_FP_16, VNx4HF, 4, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx5x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 5, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx6x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 6, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx7x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 7, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx8x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 8, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32) -TUPLE_ENTRY (VNx2x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 2, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx3x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 3, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx4x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 4, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx5x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 5, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx6x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 6, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx7x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 7, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx8x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 8, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64) -TUPLE_ENTRY (VNx2x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 2, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx3x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 3, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx4x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 4, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx5x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 5, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx6x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 6, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx7x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 7, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx8x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 8, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0) - -/* Tuple modes for EEW = 32. */ -TUPLE_ENTRY (VNx2x16SI, TARGET_MIN_VLEN >= 128, VNx16SI, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 8) -TUPLE_ENTRY (VNx2x8SI, TARGET_MIN_VLEN >= 64, VNx8SI, 2, LMUL_RESERVED, 0, LMUL_4, 8, LMUL_2, 16) -TUPLE_ENTRY (VNx3x8SI, TARGET_MIN_VLEN >= 128, VNx8SI, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 16) -TUPLE_ENTRY (VNx4x8SI, TARGET_MIN_VLEN >= 128, VNx8SI, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 16) -TUPLE_ENTRY (VNx2x4SI, true, VNx4SI, 2, LMUL_4, 8, LMUL_2, 16, LMUL_1, 32) -TUPLE_ENTRY (VNx3x4SI, TARGET_MIN_VLEN >= 64, VNx4SI, 3, LMUL_RESERVED, 0, LMUL_2, 16, LMUL_1, 32) -TUPLE_ENTRY (VNx4x4SI, TARGET_MIN_VLEN >= 64, VNx4SI, 4, LMUL_RESERVED, 0, LMUL_2, 16, LMUL_1, 32) -TUPLE_ENTRY (VNx5x4SI, TARGET_MIN_VLEN >= 128, VNx4SI, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx6x4SI, TARGET_MIN_VLEN >= 128, VNx4SI, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx7x4SI, TARGET_MIN_VLEN >= 128, VNx4SI, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx8x4SI, TARGET_MIN_VLEN >= 128, VNx4SI, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx2x2SI, true, VNx2SI, 2, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx3x2SI, true, VNx2SI, 3, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx4x2SI, true, VNx2SI, 4, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx5x2SI, TARGET_MIN_VLEN >= 64, VNx2SI, 5, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx6x2SI, TARGET_MIN_VLEN >= 64, VNx2SI, 6, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx7x2SI, TARGET_MIN_VLEN >= 64, VNx2SI, 7, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx8x2SI, TARGET_MIN_VLEN >= 64, VNx2SI, 8, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx2x1SI, TARGET_MIN_VLEN < 128, VNx1SI, 2, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx3x1SI, TARGET_MIN_VLEN < 128, VNx1SI, 3, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx4x1SI, TARGET_MIN_VLEN < 128, VNx1SI, 4, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx5x1SI, TARGET_MIN_VLEN < 128, VNx1SI, 5, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx6x1SI, TARGET_MIN_VLEN < 128, VNx1SI, 6, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx7x1SI, TARGET_MIN_VLEN < 128, VNx1SI, 7, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx8x1SI, TARGET_MIN_VLEN < 128, VNx1SI, 8, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx2x16SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, VNx16SF, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 8) -TUPLE_ENTRY (VNx2x8SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64, VNx8SF, 2, LMUL_RESERVED, 0, LMUL_4, 8, LMUL_2, 16) -TUPLE_ENTRY (VNx3x8SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128, VNx8SF, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 16) -TUPLE_ENTRY (VNx4x8SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128, VNx8SF, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 16) -TUPLE_ENTRY (VNx2x4SF, TARGET_VECTOR_ELEN_FP_32, VNx4SF, 2, LMUL_4, 8, LMUL_2, 16, LMUL_1, 32) -TUPLE_ENTRY (VNx3x4SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64, VNx4SF, 3, LMUL_RESERVED, 0, LMUL_2, 16, LMUL_1, 32) -TUPLE_ENTRY (VNx4x4SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64, VNx4SF, 4, LMUL_RESERVED, 0, LMUL_2, 16, LMUL_1, 32) -TUPLE_ENTRY (VNx5x4SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128, VNx4SF, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx6x4SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128, VNx4SF, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx7x4SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128, VNx4SF, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx8x4SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128, VNx4SF, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 32) -TUPLE_ENTRY (VNx2x2SF, TARGET_VECTOR_ELEN_FP_32, VNx2SF, 2, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx3x2SF, TARGET_VECTOR_ELEN_FP_32, VNx2SF, 3, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx4x2SF, TARGET_VECTOR_ELEN_FP_32, VNx2SF, 4, LMUL_2, 16, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx5x2SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64, VNx2SF, 5, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx6x2SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64, VNx2SF, 6, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx7x2SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64, VNx2SF, 7, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx8x2SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64, VNx2SF, 8, LMUL_RESERVED, 0, LMUL_1, 32, LMUL_F2, 64) -TUPLE_ENTRY (VNx2x1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, VNx1SF, 2, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx3x1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, VNx1SF, 3, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx4x1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, VNx1SF, 4, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx5x1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, VNx1SF, 5, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx6x1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, VNx1SF, 6, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx7x1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, VNx1SF, 7, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx8x1SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128, VNx1SF, 8, LMUL_1, 32, LMUL_F2, 64, LMUL_RESERVED, 0) - -/* Tuple modes for EEW = 64. */ -TUPLE_ENTRY (VNx2x8DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, VNx8DI, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 16) -TUPLE_ENTRY (VNx2x4DI, TARGET_VECTOR_ELEN_64, VNx4DI, 2, LMUL_RESERVED, 0, LMUL_4, 16, LMUL_2, 32) -TUPLE_ENTRY (VNx3x4DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, VNx4DI, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 32) -TUPLE_ENTRY (VNx4x4DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, VNx4DI, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 32) -TUPLE_ENTRY (VNx2x2DI, TARGET_VECTOR_ELEN_64, VNx2DI, 2, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -TUPLE_ENTRY (VNx3x2DI, TARGET_VECTOR_ELEN_64, VNx2DI, 3, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -TUPLE_ENTRY (VNx4x2DI, TARGET_VECTOR_ELEN_64, VNx2DI, 4, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -TUPLE_ENTRY (VNx5x2DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, VNx2DI, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx6x2DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, VNx2DI, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx7x2DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, VNx2DI, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx8x2DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128, VNx2DI, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx2x1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, VNx1DI, 2, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx3x1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, VNx1DI, 3, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx4x1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, VNx1DI, 4, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx5x1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, VNx1DI, 5, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx6x1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, VNx1DI, 6, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx7x1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, VNx1DI, 7, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx8x1DI, TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128, VNx1DI, 8, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx2x8DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, VNx8DF, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 16) -TUPLE_ENTRY (VNx2x4DF, TARGET_VECTOR_ELEN_FP_64, VNx4DF, 2, LMUL_RESERVED, 0, LMUL_4, 16, LMUL_2, 32) -TUPLE_ENTRY (VNx3x4DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, VNx4DF, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 32) -TUPLE_ENTRY (VNx4x4DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, VNx4DF, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 32) -TUPLE_ENTRY (VNx2x2DF, TARGET_VECTOR_ELEN_FP_64, VNx2DF, 2, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -TUPLE_ENTRY (VNx3x2DF, TARGET_VECTOR_ELEN_FP_64, VNx2DF, 3, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -TUPLE_ENTRY (VNx4x2DF, TARGET_VECTOR_ELEN_FP_64, VNx2DF, 4, LMUL_RESERVED, 0, LMUL_2, 32, LMUL_1, 64) -TUPLE_ENTRY (VNx5x2DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, VNx2DF, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx6x2DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, VNx2DF, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx7x2DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, VNx2DF, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx8x2DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128, VNx2DF, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 64) -TUPLE_ENTRY (VNx2x1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, VNx1DF, 2, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx3x1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, VNx1DF, 3, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx4x1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, VNx1DF, 4, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx5x1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, VNx1DF, 5, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx6x1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, VNx1DF, 6, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx7x1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, VNx1DF, 7, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) -TUPLE_ENTRY (VNx8x1DF, TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128, VNx1DF, 8, LMUL_RESERVED, 0, LMUL_1, 64, LMUL_RESERVED, 0) +TUPLE_ENTRY (RVVM1x8QI, true, RVVM1QI, 8, LMUL_1, 8) +TUPLE_ENTRY (RVVMF2x8QI, true, RVVMF2QI, 8, LMUL_F2, 16) +TUPLE_ENTRY (RVVMF4x8QI, true, RVVMF4QI, 8, LMUL_F4, 32) +TUPLE_ENTRY (RVVMF8x8QI, TARGET_MIN_VLEN > 32, RVVMF8QI, 8, LMUL_F8, 64) +TUPLE_ENTRY (RVVM1x7QI, true, RVVM1QI, 7, LMUL_1, 8) +TUPLE_ENTRY (RVVMF2x7QI, true, RVVMF2QI, 7, LMUL_F2, 16) +TUPLE_ENTRY (RVVMF4x7QI, true, RVVMF4QI, 7, LMUL_F4, 32) +TUPLE_ENTRY (RVVMF8x7QI, TARGET_MIN_VLEN > 32, RVVMF8QI, 7, LMUL_F8, 64) +TUPLE_ENTRY (RVVM1x6QI, true, RVVM1QI, 6, LMUL_1, 8) +TUPLE_ENTRY (RVVMF2x6QI, true, RVVMF2QI, 6, LMUL_F2, 16) +TUPLE_ENTRY (RVVMF4x6QI, true, RVVMF4QI, 6, LMUL_F4, 32) +TUPLE_ENTRY (RVVMF8x6QI, TARGET_MIN_VLEN > 32, RVVMF8QI, 6, LMUL_F8, 64) +TUPLE_ENTRY (RVVM1x5QI, true, RVVM1QI, 5, LMUL_1, 8) +TUPLE_ENTRY (RVVMF2x5QI, true, RVVMF2QI, 5, LMUL_F2, 16) +TUPLE_ENTRY (RVVMF4x5QI, true, RVVMF4QI, 5, LMUL_F4, 32) +TUPLE_ENTRY (RVVMF8x5QI, TARGET_MIN_VLEN > 32, RVVMF8QI, 5, LMUL_F8, 64) +TUPLE_ENTRY (RVVM2x4QI, true, RVVM2QI, 4, LMUL_2, 4) +TUPLE_ENTRY (RVVM1x4QI, true, RVVM1QI, 4, LMUL_1, 8) +TUPLE_ENTRY (RVVMF2x4QI, true, RVVMF2QI, 4, LMUL_F2, 16) +TUPLE_ENTRY (RVVMF4x4QI, true, RVVMF4QI, 4, LMUL_F4, 32) +TUPLE_ENTRY (RVVMF8x4QI, TARGET_MIN_VLEN > 32, RVVMF8QI, 4, LMUL_F8, 64) +TUPLE_ENTRY (RVVM2x3QI, true, RVVM2QI, 3, LMUL_2, 4) +TUPLE_ENTRY (RVVM1x3QI, true, RVVM1QI, 3, LMUL_1, 8) +TUPLE_ENTRY (RVVMF2x3QI, true, RVVMF2QI, 3, LMUL_F2, 16) +TUPLE_ENTRY (RVVMF4x3QI, true, RVVMF4QI, 3, LMUL_F4, 32) +TUPLE_ENTRY (RVVMF8x3QI, TARGET_MIN_VLEN > 32, RVVMF8QI, 3, LMUL_F8, 64) +TUPLE_ENTRY (RVVM4x2QI, true, RVVM4QI, 2, LMUL_4, 2) +TUPLE_ENTRY (RVVM2x2QI, true, RVVM2QI, 2, LMUL_2, 4) +TUPLE_ENTRY (RVVM1x2QI, true, RVVM1QI, 2, LMUL_1, 8) +TUPLE_ENTRY (RVVMF2x2QI, true, RVVMF2QI, 2, LMUL_F2, 16) +TUPLE_ENTRY (RVVMF4x2QI, true, RVVMF4QI, 2, LMUL_F4, 32) +TUPLE_ENTRY (RVVMF8x2QI, TARGET_MIN_VLEN > 32, RVVMF8QI, 2, LMUL_F8, 64) + +TUPLE_ENTRY (RVVM1x8HI, true, RVVM1HI, 8, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x8HI, true, RVVMF2HI, 8, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x8HI, TARGET_MIN_VLEN > 32, RVVMF4HI, 8, LMUL_F4, 64) +TUPLE_ENTRY (RVVM1x7HI, true, RVVM1HI, 7, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x7HI, true, RVVMF2HI, 7, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x7HI, TARGET_MIN_VLEN > 32, RVVMF4HI, 7, LMUL_F4, 64) +TUPLE_ENTRY (RVVM1x6HI, true, RVVM1HI, 6, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x6HI, true, RVVMF2HI, 6, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x6HI, TARGET_MIN_VLEN > 32, RVVMF4HI, 6, LMUL_F4, 64) +TUPLE_ENTRY (RVVM1x5HI, true, RVVM1HI, 5, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x5HI, true, RVVMF2HI, 5, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x5HI, TARGET_MIN_VLEN > 32, RVVMF4HI, 5, LMUL_F4, 64) +TUPLE_ENTRY (RVVM2x4HI, true, RVVM2HI, 4, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x4HI, true, RVVM1HI, 4, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x4HI, true, RVVMF2HI, 4, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x4HI, TARGET_MIN_VLEN > 32, RVVMF4HI, 4, LMUL_F4, 64) +TUPLE_ENTRY (RVVM2x3HI, true, RVVM2HI, 3, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x3HI, true, RVVM1HI, 3, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x3HI, true, RVVMF2HI, 3, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x3HI, TARGET_MIN_VLEN > 32, RVVMF4HI, 3, LMUL_F4, 64) +TUPLE_ENTRY (RVVM4x2HI, true, RVVM4HI, 2, LMUL_4, 4) +TUPLE_ENTRY (RVVM2x2HI, true, RVVM2HI, 2, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x2HI, true, RVVM1HI, 2, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x2HI, true, RVVMF2HI, 2, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x2HI, TARGET_MIN_VLEN > 32, RVVMF4HI, 2, LMUL_F4, 64) + +TUPLE_ENTRY (RVVM1x8HF, TARGET_VECTOR_ELEN_FP_16, RVVM1HF, 8, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x8HF, TARGET_VECTOR_ELEN_FP_16, RVVMF2HF, 8, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, RVVMF4HF, 8, LMUL_F4, 64) +TUPLE_ENTRY (RVVM1x7HF, TARGET_VECTOR_ELEN_FP_16, RVVM1HF, 7, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x7HF, TARGET_VECTOR_ELEN_FP_16, RVVMF2HF, 7, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x7HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, RVVMF4HF, 7, LMUL_F4, 64) +TUPLE_ENTRY (RVVM1x6HF, TARGET_VECTOR_ELEN_FP_16, RVVM1HF, 6, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x6HF, TARGET_VECTOR_ELEN_FP_16, RVVMF2HF, 6, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x6HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, RVVMF4HF, 6, LMUL_F4, 64) +TUPLE_ENTRY (RVVM1x5HF, TARGET_VECTOR_ELEN_FP_16, RVVM1HF, 5, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x5HF, TARGET_VECTOR_ELEN_FP_16, RVVMF2HF, 5, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x5HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, RVVMF4HF, 5, LMUL_F4, 64) +TUPLE_ENTRY (RVVM2x4HF, TARGET_VECTOR_ELEN_FP_16, RVVM2HF, 4, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x4HF, TARGET_VECTOR_ELEN_FP_16, RVVM1HF, 4, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x4HF, TARGET_VECTOR_ELEN_FP_16, RVVMF2HF, 4, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, RVVMF4HF, 4, LMUL_F4, 64) +TUPLE_ENTRY (RVVM2x3HF, TARGET_VECTOR_ELEN_FP_16, RVVM2HF, 3, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x3HF, TARGET_VECTOR_ELEN_FP_16, RVVM1HF, 3, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x3HF, TARGET_VECTOR_ELEN_FP_16, RVVMF2HF, 3, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x3HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, RVVMF4HF, 3, LMUL_F4, 64) +TUPLE_ENTRY (RVVM4x2HF, TARGET_VECTOR_ELEN_FP_16, RVVM4HF, 2, LMUL_4, 4) +TUPLE_ENTRY (RVVM2x2HF, TARGET_VECTOR_ELEN_FP_16, RVVM2HF, 2, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x2HF, TARGET_VECTOR_ELEN_FP_16, RVVM1HF, 2, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x2HF, TARGET_VECTOR_ELEN_FP_16, RVVMF2HF, 2, LMUL_F2, 32) +TUPLE_ENTRY (RVVMF4x2HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32, RVVMF4HF, 2, LMUL_F4, 64) + +TUPLE_ENTRY (RVVM1x8SI, true, RVVM1SI, 8, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x8SI, TARGET_MIN_VLEN > 32, RVVMF2SI, 8, LMUL_F2, 32) +TUPLE_ENTRY (RVVM1x7SI, true, RVVM1SI, 7, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x7SI, TARGET_MIN_VLEN > 32, RVVMF2SI, 7, LMUL_F2, 32) +TUPLE_ENTRY (RVVM1x6SI, true, RVVM1SI, 6, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x6SI, TARGET_MIN_VLEN > 32, RVVMF2SI, 6, LMUL_F2, 32) +TUPLE_ENTRY (RVVM1x5SI, true, RVVM1SI, 5, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x5SI, TARGET_MIN_VLEN > 32, RVVMF2SI, 5, LMUL_F2, 32) +TUPLE_ENTRY (RVVM2x4SI, true, RVVM2SI, 4, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x4SI, true, RVVM1SI, 4, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x4SI, TARGET_MIN_VLEN > 32, RVVMF2SI, 4, LMUL_F2, 32) +TUPLE_ENTRY (RVVM2x3SI, true, RVVM2SI, 3, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x3SI, true, RVVM1SI, 3, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x3SI, TARGET_MIN_VLEN > 32, RVVMF2SI, 3, LMUL_F2, 32) +TUPLE_ENTRY (RVVM4x2SI, true, RVVM4SI, 2, LMUL_4, 4) +TUPLE_ENTRY (RVVM2x2SI, true, RVVM2SI, 2, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x2SI, true, RVVM1SI, 2, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x2SI, TARGET_MIN_VLEN > 32, RVVMF2SI, 2, LMUL_F2, 32) + +TUPLE_ENTRY (RVVM1x8SF, TARGET_VECTOR_ELEN_FP_32, RVVM1SF, 8, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x8SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, RVVMF2SF, 8, LMUL_F2, 32) +TUPLE_ENTRY (RVVM1x7SF, TARGET_VECTOR_ELEN_FP_32, RVVM1SF, 7, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x7SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, RVVMF2SF, 7, LMUL_F2, 32) +TUPLE_ENTRY (RVVM1x6SF, TARGET_VECTOR_ELEN_FP_32, RVVM1SF, 6, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x6SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, RVVMF2SF, 6, LMUL_F2, 32) +TUPLE_ENTRY (RVVM1x5SF, TARGET_VECTOR_ELEN_FP_32, RVVM1SF, 5, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x5SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, RVVMF2SF, 5, LMUL_F2, 32) +TUPLE_ENTRY (RVVM2x4SF, TARGET_VECTOR_ELEN_FP_32, RVVM2SF, 4, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x4SF, TARGET_VECTOR_ELEN_FP_32, RVVM1SF, 4, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x4SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, RVVMF2SF, 4, LMUL_F2, 32) +TUPLE_ENTRY (RVVM2x3SF, TARGET_VECTOR_ELEN_FP_32, RVVM2SF, 3, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x3SF, TARGET_VECTOR_ELEN_FP_32, RVVM1SF, 3, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x3SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, RVVMF2SF, 3, LMUL_F2, 32) +TUPLE_ENTRY (RVVM4x2SF, TARGET_VECTOR_ELEN_FP_32, RVVM4SF, 2, LMUL_4, 4) +TUPLE_ENTRY (RVVM2x2SF, TARGET_VECTOR_ELEN_FP_32, RVVM2SF, 2, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x2SF, TARGET_VECTOR_ELEN_FP_32, RVVM1SF, 2, LMUL_1, 16) +TUPLE_ENTRY (RVVMF2x2SF, TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32, RVVMF2SF, 2, LMUL_F2, 32) + +TUPLE_ENTRY (RVVM1x8DI, TARGET_VECTOR_ELEN_64, RVVM1DI, 8, LMUL_1, 16) +TUPLE_ENTRY (RVVM1x7DI, TARGET_VECTOR_ELEN_64, RVVM1DI, 7, LMUL_1, 16) +TUPLE_ENTRY (RVVM1x6DI, TARGET_VECTOR_ELEN_64, RVVM1DI, 6, LMUL_1, 16) +TUPLE_ENTRY (RVVM1x5DI, TARGET_VECTOR_ELEN_64, RVVM1DI, 5, LMUL_1, 16) +TUPLE_ENTRY (RVVM2x4DI, TARGET_VECTOR_ELEN_64, RVVM2DI, 4, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x4DI, TARGET_VECTOR_ELEN_64, RVVM1DI, 4, LMUL_1, 16) +TUPLE_ENTRY (RVVM2x3DI, TARGET_VECTOR_ELEN_64, RVVM2DI, 3, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x3DI, TARGET_VECTOR_ELEN_64, RVVM1DI, 3, LMUL_1, 16) +TUPLE_ENTRY (RVVM4x2DI, TARGET_VECTOR_ELEN_64, RVVM4DI, 2, LMUL_4, 4) +TUPLE_ENTRY (RVVM2x2DI, TARGET_VECTOR_ELEN_64, RVVM2DI, 2, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x2DI, TARGET_VECTOR_ELEN_64, RVVM1DI, 2, LMUL_1, 16) + +TUPLE_ENTRY (RVVM1x8DF, TARGET_VECTOR_ELEN_FP_64, RVVM1DF, 8, LMUL_1, 16) +TUPLE_ENTRY (RVVM1x7DF, TARGET_VECTOR_ELEN_FP_64, RVVM1DF, 7, LMUL_1, 16) +TUPLE_ENTRY (RVVM1x6DF, TARGET_VECTOR_ELEN_FP_64, RVVM1DF, 6, LMUL_1, 16) +TUPLE_ENTRY (RVVM1x5DF, TARGET_VECTOR_ELEN_FP_64, RVVM1DF, 5, LMUL_1, 16) +TUPLE_ENTRY (RVVM2x4DF, TARGET_VECTOR_ELEN_FP_64, RVVM2DF, 4, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x4DF, TARGET_VECTOR_ELEN_FP_64, RVVM1DF, 4, LMUL_1, 16) +TUPLE_ENTRY (RVVM2x3DF, TARGET_VECTOR_ELEN_FP_64, RVVM2DF, 3, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x3DF, TARGET_VECTOR_ELEN_FP_64, RVVM1DF, 3, LMUL_1, 16) +TUPLE_ENTRY (RVVM4x2DF, TARGET_VECTOR_ELEN_FP_64, RVVM4DF, 2, LMUL_4, 4) +TUPLE_ENTRY (RVVM2x2DF, TARGET_VECTOR_ELEN_FP_64, RVVM2DF, 2, LMUL_2, 8) +TUPLE_ENTRY (RVVM1x2DF, TARGET_VECTOR_ELEN_FP_64, RVVM1DF, 2, LMUL_1, 16) -#undef ENTRY #undef TUPLE_ENTRY +#undef ENTRY diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index bb7ba12..628bf11 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -892,9 +892,9 @@ change_insn (function_info *ssa, insn_change change, insn_info *insn, return false; /* Fix bug: - (insn 12 34 13 2 (set (reg:VNx8DI 120 v24 [orig:134 _1 ] [134]) - (if_then_else:VNx8DI (unspec:VNx8BI [ - (const_vector:VNx8BI repeat [ + (insn 12 34 13 2 (set (reg:RVVM4DI 120 v24 [orig:134 _1 ] [134]) + (if_then_else:RVVM4DI (unspec:RVVMF8BI [ + (const_vector:RVVMF8BI repeat [ (const_int 1 [0x1]) ]) (const_int 0 [0]) @@ -903,13 +903,13 @@ change_insn (function_info *ssa, insn_change change, insn_info *insn, (reg:SI 66 vl) (reg:SI 67 vtype) ] UNSPEC_VPREDICATE) - (plus:VNx8DI (reg/v:VNx8DI 104 v8 [orig:137 op1 ] [137]) - (sign_extend:VNx8DI (vec_duplicate:VNx8SI (reg:SI 15 a5 - [140])))) (unspec:VNx8DI [ (const_int 0 [0]) ] UNSPEC_VUNDEF))) "rvv.c":8:12 + (plus:RVVM4DI (reg/v:RVVM4DI 104 v8 [orig:137 op1 ] [137]) + (sign_extend:RVVM4DI (vec_duplicate:RVVM4SI (reg:SI 15 a5 + [140])))) (unspec:RVVM4DI [ (const_int 0 [0]) ] UNSPEC_VUNDEF))) "rvv.c":8:12 2784 {pred_single_widen_addsvnx8di_scalar} (expr_list:REG_EQUIV - (mem/c:VNx8DI (reg:DI 10 a0 [142]) [1 +0 S[64, 64] A128]) - (expr_list:REG_EQUAL (if_then_else:VNx8DI (unspec:VNx8BI [ - (const_vector:VNx8BI repeat [ + (mem/c:RVVM4DI (reg:DI 10 a0 [142]) [1 +0 S[64, 64] A128]) + (expr_list:REG_EQUAL (if_then_else:RVVM4DI (unspec:RVVMF8BI [ + (const_vector:RVVMF8BI repeat [ (const_int 1 [0x1]) ]) (reg/v:DI 13 a3 [orig:139 vl ] [139]) @@ -918,11 +918,11 @@ change_insn (function_info *ssa, insn_change change, insn_info *insn, (reg:SI 66 vl) (reg:SI 67 vtype) ] UNSPEC_VPREDICATE) - (plus:VNx8DI (reg/v:VNx8DI 104 v8 [orig:137 op1 ] [137]) - (const_vector:VNx8DI repeat [ + (plus:RVVM4DI (reg/v:RVVM4DI 104 v8 [orig:137 op1 ] [137]) + (const_vector:RVVM4DI repeat [ (const_int 2730 [0xaaa]) ])) - (unspec:VNx8DI [ + (unspec:RVVM4DI [ (const_int 0 [0]) ] UNSPEC_VUNDEF)) (nil)))) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index f1f5a73..332fa72 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -972,8 +972,8 @@ riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode, } /* Return true if mode is the RVV enabled mode. - For example: 'VNx1DI' mode is disabled if MIN_VLEN == 32. - 'VNx1SI' mode is enabled if MIN_VLEN == 32. */ + For example: 'RVVMF2SI' mode is disabled, + wheras 'RVVM1SI' mode is enabled if MIN_VLEN == 32. */ bool riscv_v_ext_vector_mode_p (machine_mode mode) @@ -1023,11 +1023,36 @@ riscv_v_ext_mode_p (machine_mode mode) poly_int64 riscv_v_adjust_nunits (machine_mode mode, int scale) { + gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL); if (riscv_v_ext_mode_p (mode)) - return riscv_vector_chunks * scale; + { + if (TARGET_MIN_VLEN == 32) + scale = scale / 2; + return riscv_vector_chunks * scale; + } return scale; } +/* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct + NUNITS size for corresponding machine_mode. */ + +poly_int64 +riscv_v_adjust_nunits (machine_mode mode, bool fractional_p, int lmul, int nf) +{ + if (riscv_v_ext_mode_p (mode)) + { + scalar_mode smode = GET_MODE_INNER (mode); + int size = GET_MODE_SIZE (smode); + int nunits_per_chunk = riscv_bytes_per_vector_chunk / size; + if (fractional_p) + return nunits_per_chunk / lmul * riscv_vector_chunks * nf; + else + return nunits_per_chunk * lmul * riscv_vector_chunks * nf; + } + /* Set the disabled RVV modes size as 1 by default. */ + return 1; +} + /* Call from ADJUST_BYTESIZE in riscv-modes.def. Return the correct BYTE size for corresponding machine_mode. */ @@ -1035,17 +1060,20 @@ poly_int64 riscv_v_adjust_bytesize (machine_mode mode, int scale) { if (riscv_v_ext_vector_mode_p (mode)) - { - poly_uint16 mode_size = GET_MODE_SIZE (mode); - - if (maybe_eq (mode_size, (uint16_t)-1)) - mode_size = riscv_vector_chunks * scale; + { + poly_int64 nunits = GET_MODE_NUNITS (mode); + poly_int64 mode_size = GET_MODE_SIZE (mode); - if (known_gt (mode_size, BYTES_PER_RISCV_VECTOR)) - mode_size = BYTES_PER_RISCV_VECTOR; + if (maybe_eq (mode_size, (uint16_t) -1)) + mode_size = riscv_vector_chunks * scale; - return mode_size; - } + if (nunits.coeffs[0] > 8) + return exact_div (nunits, 8); + else if (nunits.is_constant ()) + return 1; + else + return poly_int64 (1, 1); + } return scale; } @@ -1056,10 +1084,7 @@ riscv_v_adjust_bytesize (machine_mode mode, int scale) poly_int64 riscv_v_adjust_precision (machine_mode mode, int scale) { - if (riscv_v_ext_vector_mode_p (mode)) - return riscv_vector_chunks * scale; - - return scale; + return riscv_v_adjust_nunits (mode, scale); } /* Return true if X is a valid address for machine mode MODE. If it is, @@ -6482,15 +6507,18 @@ riscv_init_machine_status (void) static poly_uint16 riscv_convert_vector_bits (void) { - int chunk_num = 1; - if (TARGET_MIN_VLEN >= 128) + int chunk_num; + if (TARGET_MIN_VLEN > 32) { - /* We have Full 'V' extension for application processors. It's specified - by -march=rv64gcv/rv32gcv, The 'V' extension depends upon the Zvl128b - and Zve64d extensions. Thus the number of bytes in a vector is 16 + 16 - * x1 which is riscv_vector_chunks * 16 = poly_int (16, 16). */ - riscv_bytes_per_vector_chunk = 16; + /* When targetting minimum VLEN > 32, we should use 64-bit chunk size. + Otherwise we can not include SEW = 64bits. + Runtime invariant: The single indeterminate represent the + number of 64-bit chunks in a vector beyond minimum length of 64 bits. + Thus the number of bytes in a vector is 8 + 8 * x1 which is + riscv_vector_chunks * 8 = poly_int (8, 8). */ + riscv_bytes_per_vector_chunk = 8; /* Adjust BYTES_PER_RISCV_VECTOR according to TARGET_MIN_VLEN: + - TARGET_MIN_VLEN = 64bit: [8,8] - TARGET_MIN_VLEN = 128bit: [16,16] - TARGET_MIN_VLEN = 256bit: [32,32] - TARGET_MIN_VLEN = 512bit: [64,64] @@ -6498,17 +6526,7 @@ riscv_convert_vector_bits (void) - TARGET_MIN_VLEN = 2048bit: [256,256] - TARGET_MIN_VLEN = 4096bit: [512,512] FIXME: We currently DON'T support TARGET_MIN_VLEN > 4096bit. */ - chunk_num = TARGET_MIN_VLEN / 128; - } - else if (TARGET_MIN_VLEN > 32) - { - /* When targetting minimum VLEN > 32, we should use 64-bit chunk size. - Otherwise we can not include SEW = 64bits. - Runtime invariant: The single indeterminate represent the - number of 64-bit chunks in a vector beyond minimum length of 64 bits. - Thus the number of bytes in a vector is 8 + 8 * x1 which is - riscv_vector_chunks * 8 = poly_int (8, 8). */ - riscv_bytes_per_vector_chunk = 8; + chunk_num = TARGET_MIN_VLEN / 64; } else { @@ -6518,6 +6536,7 @@ riscv_convert_vector_bits (void) Thus the number of bytes in a vector is 4 + 4 * x1 which is riscv_vector_chunks * 4 = poly_int (4, 4). */ riscv_bytes_per_vector_chunk = 4; + chunk_num = 1; } /* Set riscv_vector_chunks as poly (1, 1) run-time constant if TARGET_VECTOR diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 1968315..643e7ea 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -1040,6 +1040,7 @@ extern unsigned riscv_stack_boundary; extern unsigned riscv_bytes_per_vector_chunk; extern poly_uint16 riscv_vector_chunks; extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int); +extern poly_int64 riscv_v_adjust_nunits (machine_mode, bool, int, int); extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int); extern poly_int64 riscv_v_adjust_bytesize (enum machine_mode, int); /* The number of bits and bytes in a RVV vector. */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 7edef1f..4615e81 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -172,44 +172,51 @@ ;; Main data type used by the insn (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,HF,SF,DF,TF, - VNx1BI,VNx2BI,VNx4BI,VNx8BI,VNx16BI,VNx32BI,VNx64BI,VNx128BI, - VNx1QI,VNx2QI,VNx4QI,VNx8QI,VNx16QI,VNx32QI,VNx64QI,VNx128QI, - VNx1HI,VNx2HI,VNx4HI,VNx8HI,VNx16HI,VNx32HI,VNx64HI, - VNx1SI,VNx2SI,VNx4SI,VNx8SI,VNx16SI,VNx32SI, - VNx1DI,VNx2DI,VNx4DI,VNx8DI,VNx16DI, - VNx1HF,VNx2HF,VNx4HF,VNx8HF,VNx16HF,VNx32HF,VNx64HF, - VNx1SF,VNx2SF,VNx4SF,VNx8SF,VNx16SF,VNx32SF, - VNx1DF,VNx2DF,VNx4DF,VNx8DF,VNx16DF, - VNx2x64QI,VNx2x32QI,VNx3x32QI,VNx4x32QI, - VNx2x16QI,VNx3x16QI,VNx4x16QI,VNx5x16QI,VNx6x16QI,VNx7x16QI,VNx8x16QI, - VNx2x8QI,VNx3x8QI,VNx4x8QI,VNx5x8QI,VNx6x8QI,VNx7x8QI,VNx8x8QI, - VNx2x4QI,VNx3x4QI,VNx4x4QI,VNx5x4QI,VNx6x4QI,VNx7x4QI,VNx8x4QI, - VNx2x2QI,VNx3x2QI,VNx4x2QI,VNx5x2QI,VNx6x2QI,VNx7x2QI,VNx8x2QI, - VNx2x1QI,VNx3x1QI,VNx4x1QI,VNx5x1QI,VNx6x1QI,VNx7x1QI,VNx8x1QI, - VNx2x32HI,VNx2x16HI,VNx3x16HI,VNx4x16HI, - VNx2x8HI,VNx3x8HI,VNx4x8HI,VNx5x8HI,VNx6x8HI,VNx7x8HI,VNx8x8HI, - VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI, - VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI, - VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI, - VNx2x32HF,VNx2x16HF,VNx3x16HF,VNx4x16HF, - VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF, - VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF, - VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF, - VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF, - VNx2x16SI,VNx2x8SI,VNx3x8SI,VNx4x8SI, - VNx2x4SI,VNx3x4SI,VNx4x4SI,VNx5x4SI,VNx6x4SI,VNx7x4SI,VNx8x4SI, - VNx2x2SI,VNx3x2SI,VNx4x2SI,VNx5x2SI,VNx6x2SI,VNx7x2SI,VNx8x2SI, - VNx2x1SI,VNx3x1SI,VNx4x1SI,VNx5x1SI,VNx6x1SI,VNx7x1SI,VNx8x1SI, - VNx2x16SF,VNx2x8SF,VNx3x8SF,VNx4x8SF, - VNx2x4SF,VNx3x4SF,VNx4x4SF,VNx5x4SF,VNx6x4SF,VNx7x4SF,VNx8x4SF, - VNx2x2SF,VNx3x2SF,VNx4x2SF,VNx5x2SF,VNx6x2SF,VNx7x2SF,VNx8x2SF, - VNx2x1SF,VNx3x1SF,VNx4x1SF,VNx5x1SF,VNx6x1SF,VNx7x1SF,VNx8x1SF, - VNx2x8DI,VNx2x4DI,VNx3x4DI,VNx4x4DI, - VNx2x2DI,VNx3x2DI,VNx4x2DI,VNx5x2DI,VNx6x2DI,VNx7x2DI,VNx8x2DI, - VNx2x1DI,VNx3x1DI,VNx4x1DI,VNx5x1DI,VNx6x1DI,VNx7x1DI,VNx8x1DI, - VNx2x8DF,VNx2x4DF,VNx3x4DF,VNx4x4DF, - VNx2x2DF,VNx3x2DF,VNx4x2DF,VNx5x2DF,VNx6x2DF,VNx7x2DF,VNx8x2DF, - VNx2x1DF,VNx3x1DF,VNx4x1DF,VNx5x1DF,VNx6x1DF,VNx7x1DF,VNx8x1DF" + RVVMF64BI,RVVMF32BI,RVVMF16BI,RVVMF8BI,RVVMF4BI,RVVMF2BI,RVVM1BI, + RVVM8QI,RVVM4QI,RVVM2QI,RVVM1QI,RVVMF2QI,RVVMF4QI,RVVMF8QI, + RVVM8HI,RVVM4HI,RVVM2HI,RVVM1HI,RVVMF2HI,RVVMF4HI, + RVVM8HF,RVVM4HF,RVVM2HF,RVVM1HF,RVVMF2HF,RVVMF4HF, + RVVM8SI,RVVM4SI,RVVM2SI,RVVM1SI,RVVMF2SI, + RVVM8SF,RVVM4SF,RVVM2SF,RVVM1SF,RVVMF2SF, + RVVM8DI,RVVM4DI,RVVM2DI,RVVM1DI, + RVVM8DF,RVVM4DF,RVVM2DF,RVVM1DF, + RVVM1x8QI,RVVMF2x8QI,RVVMF4x8QI,RVVMF8x8QI, + RVVM1x7QI,RVVMF2x7QI,RVVMF4x7QI,RVVMF8x7QI, + RVVM1x6QI,RVVMF2x6QI,RVVMF4x6QI,RVVMF8x6QI, + RVVM1x5QI,RVVMF2x5QI,RVVMF4x5QI,RVVMF8x5QI, + RVVM2x4QI,RVVM1x4QI,RVVMF2x4QI,RVVMF4x4QI,RVVMF8x4QI, + RVVM2x3QI,RVVM1x3QI,RVVMF2x3QI,RVVMF4x3QI,RVVMF8x3QI, + RVVM4x2QI,RVVM2x2QI,RVVM1x2QI,RVVMF2x2QI,RVVMF4x2QI,RVVMF8x2QI, + RVVM1x8HI,RVVMF2x8HI,RVVMF4x8HI, + RVVM1x7HI,RVVMF2x7HI,RVVMF4x7HI, + RVVM1x6HI,RVVMF2x6HI,RVVMF4x6HI, + RVVM1x5HI,RVVMF2x5HI,RVVMF4x5HI, + RVVM2x4HI,RVVM1x4HI,RVVMF2x4HI,RVVMF4x4HI, + RVVM2x3HI,RVVM1x3HI,RVVMF2x3HI,RVVMF4x3HI, + RVVM4x2HI,RVVM2x2HI,RVVM1x2HI,RVVMF2x2HI,RVVMF4x2HI, + RVVM1x8HF,RVVMF2x8HF,RVVMF4x8HF,RVVM1x7HF,RVVMF2x7HF, + RVVMF4x7HF,RVVM1x6HF,RVVMF2x6HF,RVVMF4x6HF,RVVM1x5HF, + RVVMF2x5HF,RVVMF4x5HF,RVVM2x4HF,RVVM1x4HF,RVVMF2x4HF, + RVVMF4x4HF,RVVM2x3HF,RVVM1x3HF,RVVMF2x3HF,RVVMF4x3HF, + RVVM4x2HF,RVVM2x2HF,RVVM1x2HF,RVVMF2x2HF,RVVMF4x2HF, + RVVM1x8SI,RVVMF2x8SI, + RVVM1x7SI,RVVMF2x7SI, + RVVM1x6SI,RVVMF2x6SI, + RVVM1x5SI,RVVMF2x5SI, + RVVM2x4SI,RVVM1x4SI,RVVMF2x4SI, + RVVM2x3SI,RVVM1x3SI,RVVMF2x3SI, + RVVM4x2SI,RVVM2x2SI,RVVM1x2SI,RVVMF2x2SI, + RVVM1x8SF,RVVMF2x8SF,RVVM1x7SF,RVVMF2x7SF, + RVVM1x6SF,RVVMF2x6SF,RVVM1x5SF,RVVMF2x5SF, + RVVM2x4SF,RVVM1x4SF,RVVMF2x4SF,RVVM2x3SF, + RVVM1x3SF,RVVMF2x3SF,RVVM4x2SF,RVVM2x2SF, + RVVM1x2SF,RVVMF2x2SF, + RVVM1x8DI,RVVM1x7DI,RVVM1x6DI,RVVM1x5DI, + RVVM2x4DI,RVVM1x4DI,RVVM2x3DI,RVVM1x3DI, + RVVM4x2DI,RVVM2x2DI,RVVM1x2DI,RVVM1x8DF, + RVVM1x7DF,RVVM1x6DF,RVVM1x5DF,RVVM2x4DF, + RVVM1x4DF,RVVM2x3DF,RVVM1x3DF,RVVM4x2DF, + RVVM2x2DF,RVVM1x2DF" (const_string "unknown")) ;; True if the main data type is twice the size of a word. @@ -447,13 +454,13 @@ vfncvtitof,vfwcvtftoi,vfcvtftoi,vfcvtitof, vfredo,vfredu,vfwredo,vfwredu, vfslide1up,vfslide1down") - (and (eq_attr "mode" "VNx1HF,VNx2HF,VNx4HF,VNx8HF,VNx16HF,VNx32HF,VNx64HF") + (and (eq_attr "mode" "RVVM8HF,RVVM4HF,RVVM2HF,RVVM1HF,RVVMF2HF,RVVMF4HF") (match_test "!TARGET_ZVFH"))) (const_string "yes") ;; The mode records as QI for the FP16 <=> INT8 instruction. (and (eq_attr "type" "vfncvtftoi,vfwcvtitof") - (and (eq_attr "mode" "VNx1QI,VNx2QI,VNx4QI,VNx8QI,VNx16QI,VNx32QI,VNx64QI") + (and (eq_attr "mode" "RVVM4QI,RVVM2QI,RVVM1QI,RVVMF2QI,RVVMF4QI,RVVMF8QI") (match_test "!TARGET_ZVFH"))) (const_string "yes") ] diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index fdb8731..e277e87 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -88,219 +88,213 @@ ]) (define_mode_iterator V [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") - (VNx16HF "TARGET_VECTOR_ELEN_FP_16") - (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM8HF "TARGET_VECTOR_ELEN_FP_16") (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VEEWEXT2 [ - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") (VNx2HF "TARGET_VECTOR_ELEN_FP_16") (VNx4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") (VNx16HF "TARGET_VECTOR_ELEN_FP_16") (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM8HF "TARGET_VECTOR_ELEN_FP_16") (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VEEWEXT4 [ - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VEEWEXT8 [ - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VEEWTRUNC2 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN >= 128") - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") (VNx2HF "TARGET_VECTOR_ELEN_FP_16") (VNx4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") (VNx16HF "TARGET_VECTOR_ELEN_FP_16") (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VEEWTRUNC4 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI (VNx32QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI (VNx16HI "TARGET_MIN_VLEN >= 128") - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") (VNx2HF "TARGET_VECTOR_ELEN_FP_16") (VNx4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") (VNx16HF "TARGET_VECTOR_ELEN_FP_16") + RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VEEWTRUNC8 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI (VNx16QI "TARGET_MIN_VLEN >= 128") + RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VLMULEXT2 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM4DI "TARGET_VECTOR_ELEN_64") (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VLMULEXT4 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI (VNx32QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI (VNx16HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI (VNx8SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VLMULEXT8 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI (VNx16QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI (VNx8HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI (VNx4SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VLMULEXT16 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI (VNx8QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI (VNx4HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") (VNx2SI "TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VLMULEXT32 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI (VNx4QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") (VNx2HI "TARGET_MIN_VLEN >= 128") + RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VLMULEXT64 [ - (VNx1QI "TARGET_MIN_VLEN < 128") (VNx2QI "TARGET_MIN_VLEN >= 128") + (RVVMF8QI "TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VEI16 [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + (RVVM8HF "TARGET_VECTOR_ELEN_FP_16") (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VI [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") -]) + RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") -(define_mode_iterator VWI [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) (define_mode_iterator VF_ZVFHMIN [ - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") - (VNx16HF "TARGET_VECTOR_ELEN_FP_16") - (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (RVVM8HF "TARGET_VECTOR_ELEN_FP_16") (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) ;; This iterator is the same as above but with TARGET_VECTOR_ELEN_FP_16 @@ -311,1246 +305,1186 @@ ;; since this will only disable insn alternatives in reload but still ;; allow the instruction and mode to be matched during combine et al. (define_mode_iterator VF [ - (VNx1HF "TARGET_ZVFH && TARGET_MIN_VLEN < 128") - (VNx2HF "TARGET_ZVFH") - (VNx4HF "TARGET_ZVFH") - (VNx8HF "TARGET_ZVFH") - (VNx16HF "TARGET_ZVFH") - (VNx32HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32") - (VNx64HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128") - - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") -]) - -(define_mode_iterator VWF [ - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") - (VNx16HF "TARGET_VECTOR_ELEN_FP_16") - (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_MIN_VLEN < 128") VNx2SF VNx4SF VNx8SF (VNx16SF "TARGET_MIN_VLEN > 32") (VNx32SF "TARGET_MIN_VLEN >= 128") + (RVVM8HF "TARGET_ZVFH") (RVVM4HF "TARGET_ZVFH") (RVVM2HF "TARGET_ZVFH") + (RVVM1HF "TARGET_ZVFH") (RVVMF2HF "TARGET_ZVFH") + (RVVMF4HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32") + + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VFULLI [ - (VNx1QI "!TARGET_FULL_V") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_FULL_V") - (VNx1HI "!TARGET_FULL_V") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_FULL_V") - (VNx1SI "!TARGET_FULL_V") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_FULL_V") - (VNx2DI "TARGET_FULL_V") (VNx4DI "TARGET_FULL_V") (VNx8DI "TARGET_FULL_V") (VNx16DI "TARGET_FULL_V") + RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_FULL_V") (RVVM4DI "TARGET_FULL_V") (RVVM2DI "TARGET_FULL_V") (RVVM1DI "TARGET_FULL_V") ]) (define_mode_iterator VI_QH [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") + RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VI_QHS [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") + RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") + + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VI_D [ - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) (define_mode_iterator VFULLI_D [ - (VNx2DI "TARGET_FULL_V") (VNx4DI "TARGET_FULL_V") (VNx8DI "TARGET_FULL_V") (VNx16DI "TARGET_FULL_V") + (RVVM8DI "TARGET_FULL_V") (RVVM4DI "TARGET_FULL_V") + (RVVM2DI "TARGET_FULL_V") (RVVM1DI "TARGET_FULL_V") ]) -(define_mode_iterator VNX1_QHSD [ - (VNx1QI "TARGET_MIN_VLEN < 128") - (VNx1HI "TARGET_MIN_VLEN < 128") - (VNx1SI "TARGET_MIN_VLEN < 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") +(define_mode_iterator RATIO64 [ + (RVVMF8QI "TARGET_MIN_VLEN > 32") + (RVVMF4HI "TARGET_MIN_VLEN > 32") + (RVVMF2SI "TARGET_MIN_VLEN > 32") + (RVVM1DI "TARGET_VECTOR_ELEN_64") + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) -(define_mode_iterator VNX2_QHSD [ - VNx2QI - VNx2HI - VNx2SI - (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") +(define_mode_iterator RATIO32 [ + RVVMF4QI + RVVMF2HI + RVVM1SI + (RVVM2DI "TARGET_VECTOR_ELEN_64") + (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") ]) -(define_mode_iterator VNX4_QHSD [ - VNx4QI - VNx4HI - VNx4SI - (VNx4DI "TARGET_VECTOR_ELEN_64") - (VNx4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") +(define_mode_iterator RATIO16 [ + RVVMF2QI + RVVM1HI + RVVM2SI + (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") ]) -(define_mode_iterator VNX8_QHSD [ - VNx8QI - VNx8HI - VNx8SI - (VNx8DI "TARGET_VECTOR_ELEN_64") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") +(define_mode_iterator RATIO8 [ + RVVM1QI + RVVM2HI + RVVM4SI + (RVVM8DI "TARGET_VECTOR_ELEN_64") + (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") ]) -(define_mode_iterator VNX16_QHSD [ - VNx16QI - VNx16HI - (VNx16SI "TARGET_MIN_VLEN > 32") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx16HF "TARGET_VECTOR_ELEN_FP_16") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") +(define_mode_iterator RATIO4 [ + RVVM2QI + RVVM4HI + RVVM8SI + (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") ]) -(define_mode_iterator VNX32_QHS [ - VNx32QI - (VNx32HI "TARGET_MIN_VLEN > 32") - (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") +(define_mode_iterator RATIO2 [ + RVVM4QI + RVVM8HI + (RVVM8HF "TARGET_VECTOR_ELEN_FP_16") ]) -(define_mode_iterator VNX64_QH [ - (VNx64QI "TARGET_MIN_VLEN > 32") - (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") +(define_mode_iterator RATIO1 [ + RVVM8QI ]) -(define_mode_iterator VNX128_Q [ - (VNx128QI "TARGET_MIN_VLEN >= 128") +(define_mode_iterator RATIO64I [ + (RVVMF8QI "TARGET_MIN_VLEN > 32") + (RVVMF4HI "TARGET_MIN_VLEN > 32") + (RVVMF2SI "TARGET_MIN_VLEN > 32") + (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) -(define_mode_iterator VNX1_QHSDI [ - (VNx1QI "TARGET_MIN_VLEN < 128") - (VNx1HI "TARGET_MIN_VLEN < 128") - (VNx1SI "TARGET_MIN_VLEN < 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128 && TARGET_64BIT") +(define_mode_iterator RATIO32I [ + RVVMF4QI + RVVMF2HI + RVVM1SI + (RVVM2DI "TARGET_VECTOR_ELEN_64") ]) -(define_mode_iterator VNX2_QHSDI [ - VNx2QI - VNx2HI - VNx2SI - (VNx2DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT") +(define_mode_iterator RATIO16I [ + RVVMF2QI + RVVM1HI + RVVM2SI + (RVVM4DI "TARGET_VECTOR_ELEN_64") ]) -(define_mode_iterator VNX4_QHSDI [ - VNx4QI - VNx4HI - VNx4SI - (VNx4DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT") +(define_mode_iterator RATIO8I [ + RVVM1QI + RVVM2HI + RVVM4SI + (RVVM8DI "TARGET_VECTOR_ELEN_64") ]) -(define_mode_iterator VNX8_QHSDI [ - VNx8QI - VNx8HI - VNx8SI - (VNx8DI "TARGET_VECTOR_ELEN_64 && TARGET_64BIT") +(define_mode_iterator RATIO4I [ + RVVM2QI + RVVM4HI + RVVM8SI ]) -(define_mode_iterator VNX16_QHSDI [ - VNx16QI - VNx16HI - (VNx16SI "TARGET_MIN_VLEN > 32") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128 && TARGET_64BIT") +(define_mode_iterator RATIO2I [ + RVVM4QI + RVVM8HI ]) -(define_mode_iterator VNX32_QHSI [ - VNx32QI - (VNx32HI "TARGET_MIN_VLEN > 32") - (VNx32SI "TARGET_MIN_VLEN >= 128") -]) +(define_mode_iterator V_WHOLE [ + RVVM8QI RVVM4QI RVVM2QI RVVM1QI -(define_mode_iterator VNX64_QHI [ - (VNx64QI "TARGET_MIN_VLEN > 32") - (VNx64HI "TARGET_MIN_VLEN >= 128") -]) + RVVM8HI RVVM4HI RVVM2HI RVVM1HI -(define_mode_iterator V_WHOLE [ - (VNx4QI "TARGET_MIN_VLEN == 32") (VNx8QI "TARGET_MIN_VLEN < 128") VNx16QI VNx32QI - (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") - (VNx2HI "TARGET_MIN_VLEN == 32") (VNx4HI "TARGET_MIN_VLEN < 128") VNx8HI VNx16HI - (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN == 32") (VNx2SI "TARGET_MIN_VLEN < 128") VNx4SI VNx8SI - (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - - (VNx2HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN == 32") - (VNx4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx8HF "TARGET_VECTOR_ELEN_FP_16") - (VNx16HF "TARGET_VECTOR_ELEN_FP_16") - (VNx32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx64HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN == 32") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (RVVM8HF "TARGET_VECTOR_ELEN_FP_16") (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI + + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator V_FRACT [ - (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI (VNx4QI "TARGET_MIN_VLEN > 32") (VNx8QI "TARGET_MIN_VLEN >= 128") - (VNx1HI "TARGET_MIN_VLEN < 128") (VNx2HI "TARGET_MIN_VLEN > 32") (VNx4HI "TARGET_MIN_VLEN >= 128") + RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") - (VNx1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx2HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") + RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") - (VNx1SI "TARGET_MIN_VLEN == 64") (VNx2SI "TARGET_MIN_VLEN >= 128") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN == 64") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VB [ - (VNx1BI "TARGET_MIN_VLEN < 128") VNx2BI VNx4BI VNx8BI VNx16BI VNx32BI - (VNx64BI "TARGET_MIN_VLEN > 32") (VNx128BI "TARGET_MIN_VLEN >= 128") + (RVVMF64BI "TARGET_MIN_VLEN > 32") RVVMF32BI RVVMF16BI RVVMF8BI RVVMF4BI RVVMF2BI RVVM1BI ]) (define_mode_iterator VWEXTI [ - (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") + + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) ;; Same iterator split reason as VF_ZVFHMIN and VF. (define_mode_iterator VWEXTF_ZVFHMIN [ - (VNx1SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_16") - (VNx4SF "TARGET_VECTOR_ELEN_FP_16") - (VNx8SF "TARGET_VECTOR_ELEN_FP_16") - (VNx16SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") + (RVVM8SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (RVVM4SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (RVVM2SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2SF "TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VWEXTF [ - (VNx1SF "TARGET_ZVFH && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_ZVFH") - (VNx4SF "TARGET_ZVFH") - (VNx8SF "TARGET_ZVFH") - (VNx16SF "TARGET_ZVFH && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128") + (RVVM8SF "TARGET_ZVFH && TARGET_VECTOR_ELEN_FP_32") + (RVVM4SF "TARGET_ZVFH && TARGET_VECTOR_ELEN_FP_32") + (RVVM2SF "TARGET_ZVFH && TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_ZVFH && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2SF "TARGET_ZVFH && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VWCONVERTI [ - (VNx1SI "TARGET_ZVFH && TARGET_MIN_VLEN < 128") - (VNx2SI "TARGET_ZVFH") - (VNx4SI "TARGET_ZVFH") - (VNx8SI "TARGET_ZVFH") - (VNx16SI "TARGET_ZVFH && TARGET_MIN_VLEN > 32") - (VNx32SI "TARGET_ZVFH && TARGET_MIN_VLEN >= 128") + (RVVM8SI "TARGET_ZVFH") (RVVM4SI "TARGET_ZVFH") (RVVM2SI "TARGET_ZVFH") (RVVM1SI "TARGET_ZVFH") + (RVVMF2SI "TARGET_ZVFH") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") - (VNx4DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") - (VNx8DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + (RVVM8DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") + (RVVM4DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") + (RVVM2DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") + (RVVM1DI "TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") ]) (define_mode_iterator VQEXTI [ - (VNx1SI "TARGET_MIN_VLEN < 128") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") (VNx32SI "TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") + + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) (define_mode_iterator VQEXTF [ - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VOEXTI [ - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) (define_mode_iterator VT [ - (VNx2x64QI "TARGET_MIN_VLEN >= 128") - (VNx2x32QI "TARGET_MIN_VLEN >= 64") - (VNx3x32QI "TARGET_MIN_VLEN >= 128") - (VNx4x32QI "TARGET_MIN_VLEN >= 128") - VNx2x16QI - (VNx3x16QI "TARGET_MIN_VLEN >= 64") - (VNx4x16QI "TARGET_MIN_VLEN >= 64") - (VNx5x16QI "TARGET_MIN_VLEN >= 128") - (VNx6x16QI "TARGET_MIN_VLEN >= 128") - (VNx7x16QI "TARGET_MIN_VLEN >= 128") - (VNx8x16QI "TARGET_MIN_VLEN >= 128") - VNx2x8QI - VNx3x8QI - VNx4x8QI - (VNx5x8QI "TARGET_MIN_VLEN >= 64") - (VNx6x8QI "TARGET_MIN_VLEN >= 64") - (VNx7x8QI "TARGET_MIN_VLEN >= 64") - (VNx8x8QI "TARGET_MIN_VLEN >= 64") - VNx2x4QI - VNx3x4QI - VNx4x4QI - VNx5x4QI - VNx6x4QI - VNx7x4QI - VNx8x4QI - VNx2x2QI - VNx3x2QI - VNx4x2QI - VNx5x2QI - VNx6x2QI - VNx7x2QI - VNx8x2QI - (VNx2x1QI "TARGET_MIN_VLEN < 128") - (VNx3x1QI "TARGET_MIN_VLEN < 128") - (VNx4x1QI "TARGET_MIN_VLEN < 128") - (VNx5x1QI "TARGET_MIN_VLEN < 128") - (VNx6x1QI "TARGET_MIN_VLEN < 128") - (VNx7x1QI "TARGET_MIN_VLEN < 128") - (VNx8x1QI "TARGET_MIN_VLEN < 128") - (VNx2x32HI "TARGET_MIN_VLEN >= 128") - (VNx2x16HI "TARGET_MIN_VLEN >= 64") - (VNx3x16HI "TARGET_MIN_VLEN >= 128") - (VNx4x16HI "TARGET_MIN_VLEN >= 128") - VNx2x8HI - (VNx3x8HI "TARGET_MIN_VLEN >= 64") - (VNx4x8HI "TARGET_MIN_VLEN >= 64") - (VNx5x8HI "TARGET_MIN_VLEN >= 128") - (VNx6x8HI "TARGET_MIN_VLEN >= 128") - (VNx7x8HI "TARGET_MIN_VLEN >= 128") - (VNx8x8HI "TARGET_MIN_VLEN >= 128") - VNx2x4HI - VNx3x4HI - VNx4x4HI - (VNx5x4HI "TARGET_MIN_VLEN >= 64") - (VNx6x4HI "TARGET_MIN_VLEN >= 64") - (VNx7x4HI "TARGET_MIN_VLEN >= 64") - (VNx8x4HI "TARGET_MIN_VLEN >= 64") - VNx2x2HI - VNx3x2HI - VNx4x2HI - VNx5x2HI - VNx6x2HI - VNx7x2HI - VNx8x2HI - (VNx2x1HI "TARGET_MIN_VLEN < 128") - (VNx3x1HI "TARGET_MIN_VLEN < 128") - (VNx4x1HI "TARGET_MIN_VLEN < 128") - (VNx5x1HI "TARGET_MIN_VLEN < 128") - (VNx6x1HI "TARGET_MIN_VLEN < 128") - (VNx7x1HI "TARGET_MIN_VLEN < 128") - (VNx8x1HI "TARGET_MIN_VLEN < 128") - (VNx2x16SI "TARGET_MIN_VLEN >= 128") - (VNx2x8SI "TARGET_MIN_VLEN >= 64") - (VNx3x8SI "TARGET_MIN_VLEN >= 128") - (VNx4x8SI "TARGET_MIN_VLEN >= 128") - VNx2x4SI - (VNx3x4SI "TARGET_MIN_VLEN >= 64") - (VNx4x4SI "TARGET_MIN_VLEN >= 64") - (VNx5x4SI "TARGET_MIN_VLEN >= 128") - (VNx6x4SI "TARGET_MIN_VLEN >= 128") - (VNx7x4SI "TARGET_MIN_VLEN >= 128") - (VNx8x4SI "TARGET_MIN_VLEN >= 128") - VNx2x2SI - VNx3x2SI - VNx4x2SI - (VNx5x2SI "TARGET_MIN_VLEN >= 64") - (VNx6x2SI "TARGET_MIN_VLEN >= 64") - (VNx7x2SI "TARGET_MIN_VLEN >= 64") - (VNx8x2SI "TARGET_MIN_VLEN >= 64") - (VNx2x1SI "TARGET_MIN_VLEN < 128") - (VNx3x1SI "TARGET_MIN_VLEN < 128") - (VNx4x1SI "TARGET_MIN_VLEN < 128") - (VNx5x1SI "TARGET_MIN_VLEN < 128") - (VNx6x1SI "TARGET_MIN_VLEN < 128") - (VNx7x1SI "TARGET_MIN_VLEN < 128") - (VNx8x1SI "TARGET_MIN_VLEN < 128") - (VNx2x8DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx2x4DI "TARGET_VECTOR_ELEN_64") - (VNx3x4DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx4x4DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx2x2DI "TARGET_VECTOR_ELEN_64") - (VNx3x2DI "TARGET_VECTOR_ELEN_64") - (VNx4x2DI "TARGET_VECTOR_ELEN_64") - (VNx5x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx6x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx7x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx8x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx2x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx3x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx4x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx5x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx6x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx7x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx8x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx2x32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx2x16HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (VNx3x16HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx4x16HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx2x8HF "TARGET_VECTOR_ELEN_FP_16") - (VNx3x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (VNx4x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (VNx5x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx6x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx7x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx8x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (VNx2x4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx3x4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx4x4HF "TARGET_VECTOR_ELEN_FP_16") - (VNx5x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (VNx6x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (VNx7x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (VNx8x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (VNx2x2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx3x2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx4x2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx5x2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx6x2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx7x2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx8x2HF "TARGET_VECTOR_ELEN_FP_16") - (VNx2x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx3x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx4x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx5x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx6x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx7x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx8x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128") - (VNx2x16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx2x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx3x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx4x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx2x4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx3x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx4x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx5x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx6x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx7x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx8x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx2x2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx3x2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4x2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx5x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx6x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx7x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx8x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx2x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx3x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx4x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx5x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx6x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx7x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx8x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2x8DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx2x4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx3x4DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx4x4DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx2x2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx3x2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4x2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx5x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx6x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx7x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx8x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx2x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx3x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx4x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx5x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx6x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx7x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx8x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") -]) - -(define_mode_iterator V1I [ - (VNx1QI "TARGET_MIN_VLEN < 128") - (VNx1HI "TARGET_MIN_VLEN < 128") - (VNx1SI "TARGET_MIN_VLEN < 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") -]) - -(define_mode_iterator V2I [ - VNx2QI - VNx2HI - VNx2SI - (VNx2DI "TARGET_VECTOR_ELEN_64") -]) - -(define_mode_iterator V4I [ - VNx4QI - VNx4HI - VNx4SI - (VNx4DI "TARGET_VECTOR_ELEN_64") -]) - -(define_mode_iterator V8I [ - VNx8QI - VNx8HI - VNx8SI - (VNx8DI "TARGET_VECTOR_ELEN_64") -]) - -(define_mode_iterator V16I [ - VNx16QI - VNx16HI - (VNx16SI "TARGET_MIN_VLEN > 32") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") -]) - -(define_mode_iterator V32I [ - VNx32QI - (VNx32HI "TARGET_MIN_VLEN > 32") - (VNx32SI "TARGET_MIN_VLEN >= 128") -]) - -(define_mode_iterator V64I [ - (VNx64QI "TARGET_MIN_VLEN > 32") - (VNx64HI "TARGET_MIN_VLEN >= 128") + RVVM1x8QI RVVMF2x8QI RVVMF4x8QI (RVVMF8x8QI "TARGET_MIN_VLEN > 32") + RVVM1x7QI RVVMF2x7QI RVVMF4x7QI (RVVMF8x7QI "TARGET_MIN_VLEN > 32") + RVVM1x6QI RVVMF2x6QI RVVMF4x6QI (RVVMF8x6QI "TARGET_MIN_VLEN > 32") + RVVM1x5QI RVVMF2x5QI RVVMF4x5QI (RVVMF8x5QI "TARGET_MIN_VLEN > 32") + RVVM2x4QI RVVM1x4QI RVVMF2x4QI RVVMF4x4QI (RVVMF8x4QI "TARGET_MIN_VLEN > 32") + RVVM2x3QI RVVM1x3QI RVVMF2x3QI RVVMF4x3QI (RVVMF8x3QI "TARGET_MIN_VLEN > 32") + RVVM4x2QI RVVM2x2QI RVVM1x2QI RVVMF2x2QI RVVMF4x2QI (RVVMF8x2QI "TARGET_MIN_VLEN > 32") + + RVVM1x8HI RVVMF2x8HI (RVVMF4x8HI "TARGET_MIN_VLEN > 32") + RVVM1x7HI RVVMF2x7HI (RVVMF4x7HI "TARGET_MIN_VLEN > 32") + RVVM1x6HI RVVMF2x6HI (RVVMF4x6HI "TARGET_MIN_VLEN > 32") + RVVM1x5HI RVVMF2x5HI (RVVMF4x5HI "TARGET_MIN_VLEN > 32") + RVVM2x4HI RVVM1x4HI RVVMF2x4HI (RVVMF4x4HI "TARGET_MIN_VLEN > 32") + RVVM2x3HI RVVM1x3HI RVVMF2x3HI (RVVMF4x3HI "TARGET_MIN_VLEN > 32") + RVVM4x2HI RVVM2x2HI RVVM1x2HI RVVMF2x2HI (RVVMF4x2HI "TARGET_MIN_VLEN > 32") + + (RVVM1x8HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x8HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (RVVM1x7HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x7HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x7HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (RVVM1x6HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x6HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x6HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (RVVM1x5HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x5HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x5HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (RVVM2x4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (RVVM2x3HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x3HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x3HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x3HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + (RVVM4x2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM2x2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x2HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32") + + RVVM1x8SI (RVVMF2x8SI "TARGET_MIN_VLEN > 32") + RVVM1x7SI (RVVMF2x7SI "TARGET_MIN_VLEN > 32") + RVVM1x6SI (RVVMF2x6SI "TARGET_MIN_VLEN > 32") + RVVM1x5SI (RVVMF2x5SI "TARGET_MIN_VLEN > 32") + RVVM2x4SI RVVM1x4SI (RVVMF2x4SI "TARGET_MIN_VLEN > 32") + RVVM2x3SI RVVM1x3SI (RVVMF2x3SI "TARGET_MIN_VLEN > 32") + RVVM4x2SI RVVM2x2SI RVVM1x2SI (RVVMF2x2SI "TARGET_MIN_VLEN > 32") + + (RVVM1x8SF "TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + (RVVM1x7SF "TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x7SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + (RVVM1x6SF "TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x6SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + (RVVM1x5SF "TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x5SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + (RVVM2x4SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x4SF "TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + (RVVM2x3SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x3SF "TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x3SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + (RVVM4x2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM2x2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + + (RVVM1x8DI "TARGET_VECTOR_ELEN_64") + (RVVM1x7DI "TARGET_VECTOR_ELEN_64") + (RVVM1x6DI "TARGET_VECTOR_ELEN_64") + (RVVM1x5DI "TARGET_VECTOR_ELEN_64") + (RVVM2x4DI "TARGET_VECTOR_ELEN_64") + (RVVM1x4DI "TARGET_VECTOR_ELEN_64") + (RVVM2x3DI "TARGET_VECTOR_ELEN_64") + (RVVM1x3DI "TARGET_VECTOR_ELEN_64") + (RVVM4x2DI "TARGET_VECTOR_ELEN_64") + (RVVM2x2DI "TARGET_VECTOR_ELEN_64") + (RVVM1x2DI "TARGET_VECTOR_ELEN_64") + + (RVVM1x8DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x7DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x6DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x5DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2x4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2x3DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x3DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM4x2DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2x2DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x2DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator V1T [ - (VNx2x1QI "TARGET_MIN_VLEN < 128") - (VNx3x1QI "TARGET_MIN_VLEN < 128") - (VNx4x1QI "TARGET_MIN_VLEN < 128") - (VNx5x1QI "TARGET_MIN_VLEN < 128") - (VNx6x1QI "TARGET_MIN_VLEN < 128") - (VNx7x1QI "TARGET_MIN_VLEN < 128") - (VNx8x1QI "TARGET_MIN_VLEN < 128") - (VNx2x1HI "TARGET_MIN_VLEN < 128") - (VNx3x1HI "TARGET_MIN_VLEN < 128") - (VNx4x1HI "TARGET_MIN_VLEN < 128") - (VNx5x1HI "TARGET_MIN_VLEN < 128") - (VNx6x1HI "TARGET_MIN_VLEN < 128") - (VNx7x1HI "TARGET_MIN_VLEN < 128") - (VNx8x1HI "TARGET_MIN_VLEN < 128") - (VNx2x1SI "TARGET_MIN_VLEN < 128") - (VNx3x1SI "TARGET_MIN_VLEN < 128") - (VNx4x1SI "TARGET_MIN_VLEN < 128") - (VNx5x1SI "TARGET_MIN_VLEN < 128") - (VNx6x1SI "TARGET_MIN_VLEN < 128") - (VNx7x1SI "TARGET_MIN_VLEN < 128") - (VNx8x1SI "TARGET_MIN_VLEN < 128") - (VNx2x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx3x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx4x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx5x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx6x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx7x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx8x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx2x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx3x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx4x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx5x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx6x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx7x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx8x1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx3x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx4x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx5x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx6x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx7x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx8x1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") + (RVVMF8x2QI "TARGET_MIN_VLEN > 32") + (RVVMF8x3QI "TARGET_MIN_VLEN > 32") + (RVVMF8x4QI "TARGET_MIN_VLEN > 32") + (RVVMF8x5QI "TARGET_MIN_VLEN > 32") + (RVVMF8x6QI "TARGET_MIN_VLEN > 32") + (RVVMF8x7QI "TARGET_MIN_VLEN > 32") + (RVVMF8x8QI "TARGET_MIN_VLEN > 32") + (RVVMF4x2HI "TARGET_MIN_VLEN > 32") + (RVVMF4x3HI "TARGET_MIN_VLEN > 32") + (RVVMF4x4HI "TARGET_MIN_VLEN > 32") + (RVVMF4x5HI "TARGET_MIN_VLEN > 32") + (RVVMF4x6HI "TARGET_MIN_VLEN > 32") + (RVVMF4x7HI "TARGET_MIN_VLEN > 32") + (RVVMF4x8HI "TARGET_MIN_VLEN > 32") + (RVVMF2x2SI "TARGET_MIN_VLEN > 32") + (RVVMF2x3SI "TARGET_MIN_VLEN > 32") + (RVVMF2x4SI "TARGET_MIN_VLEN > 32") + (RVVMF2x5SI "TARGET_MIN_VLEN > 32") + (RVVMF2x6SI "TARGET_MIN_VLEN > 32") + (RVVMF2x7SI "TARGET_MIN_VLEN > 32") + (RVVMF2x8SI "TARGET_MIN_VLEN > 32") + (RVVM1x2DI "TARGET_VECTOR_ELEN_64") + (RVVM1x3DI "TARGET_VECTOR_ELEN_64") + (RVVM1x4DI "TARGET_VECTOR_ELEN_64") + (RVVM1x5DI "TARGET_VECTOR_ELEN_64") + (RVVM1x6DI "TARGET_VECTOR_ELEN_64") + (RVVM1x7DI "TARGET_VECTOR_ELEN_64") + (RVVM1x8DI "TARGET_VECTOR_ELEN_64") + (RVVMF4x2HF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x3HF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x4HF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x5HF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x6HF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x7HF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16") + (RVVMF4x8HF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x2SF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x3SF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x4SF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x5SF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x6SF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x7SF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_32") + (RVVMF2x8SF "TARGET_MIN_VLEN > 32 && TARGET_VECTOR_ELEN_FP_32") + (RVVM1x2DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x3DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x5DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x6DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x7DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM1x8DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator V2T [ - VNx2x2QI - VNx3x2QI - VNx4x2QI - VNx5x2QI - VNx6x2QI - VNx7x2QI - VNx8x2QI - VNx2x2HI - VNx3x2HI - VNx4x2HI - VNx5x2HI - VNx6x2HI - VNx7x2HI - VNx8x2HI - VNx2x2SI - VNx3x2SI - VNx4x2SI - (VNx5x2SI "TARGET_MIN_VLEN >= 64") - (VNx6x2SI "TARGET_MIN_VLEN >= 64") - (VNx7x2SI "TARGET_MIN_VLEN >= 64") - (VNx8x2SI "TARGET_MIN_VLEN >= 64") - (VNx2x2DI "TARGET_VECTOR_ELEN_64") - (VNx3x2DI "TARGET_VECTOR_ELEN_64") - (VNx4x2DI "TARGET_VECTOR_ELEN_64") - (VNx5x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx6x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx7x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx8x2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx2x2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx3x2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4x2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx5x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx6x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx7x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx8x2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx2x2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx3x2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4x2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx5x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx6x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx7x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx8x2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVMF4x2QI + RVVMF4x3QI + RVVMF4x4QI + RVVMF4x5QI + RVVMF4x6QI + RVVMF4x7QI + RVVMF4x8QI + RVVMF2x2HI + RVVMF2x3HI + RVVMF2x4HI + RVVMF2x5HI + RVVMF2x6HI + RVVMF2x7HI + RVVMF2x8HI + RVVM1x2SI + RVVM1x3SI + RVVM1x4SI + RVVM1x5SI + RVVM1x6SI + RVVM1x7SI + RVVM1x8SI + (RVVM2x2DI "TARGET_VECTOR_ELEN_64") + (RVVM2x3DI "TARGET_VECTOR_ELEN_64") + (RVVM2x4DI "TARGET_VECTOR_ELEN_64") + (RVVMF2x2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x3HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x5HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x6HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x7HF "TARGET_VECTOR_ELEN_FP_16") + (RVVMF2x8HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x3SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x4SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x5SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x6SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x7SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1x8SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM2x2DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2x3DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2x4DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator V4T [ - VNx2x4QI - VNx3x4QI - VNx4x4QI - VNx5x4QI - VNx6x4QI - VNx7x4QI - VNx8x4QI - VNx2x4HI - VNx3x4HI - VNx4x4HI - (VNx5x4HI "TARGET_MIN_VLEN >= 64") - (VNx6x4HI "TARGET_MIN_VLEN >= 64") - (VNx7x4HI "TARGET_MIN_VLEN >= 64") - (VNx8x4HI "TARGET_MIN_VLEN >= 64") - VNx2x4SI - (VNx3x4SI "TARGET_MIN_VLEN >= 64") - (VNx4x4SI "TARGET_MIN_VLEN >= 64") - (VNx5x4SI "TARGET_MIN_VLEN >= 128") - (VNx6x4SI "TARGET_MIN_VLEN >= 128") - (VNx7x4SI "TARGET_MIN_VLEN >= 128") - (VNx8x4SI "TARGET_MIN_VLEN >= 128") - (VNx2x4DI "TARGET_VECTOR_ELEN_64") - (VNx3x4DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx4x4DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx2x4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx3x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx4x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx5x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx6x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx7x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx8x4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx2x4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx3x4DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx4x4DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVMF2x2QI + RVVMF2x3QI + RVVMF2x4QI + RVVMF2x5QI + RVVMF2x6QI + RVVMF2x7QI + RVVMF2x8QI + RVVM1x2HI + RVVM1x3HI + RVVM1x4HI + RVVM1x5HI + RVVM1x6HI + RVVM1x7HI + RVVM1x8HI + RVVM2x2SI + RVVM2x3SI + RVVM2x4SI + (RVVM4x2DI "TARGET_VECTOR_ELEN_64") + (RVVM1x2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x3HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x5HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x6HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x7HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM1x8HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM2x2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM2x3SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM2x4SF "TARGET_VECTOR_ELEN_FP_32") ]) (define_mode_iterator V8T [ - VNx2x8QI - VNx3x8QI - VNx4x8QI - (VNx5x8QI "TARGET_MIN_VLEN >= 64") - (VNx6x8QI "TARGET_MIN_VLEN >= 64") - (VNx7x8QI "TARGET_MIN_VLEN >= 64") - (VNx8x8QI "TARGET_MIN_VLEN >= 64") - VNx2x8HI - (VNx3x8HI "TARGET_MIN_VLEN >= 64") - (VNx4x8HI "TARGET_MIN_VLEN >= 64") - (VNx5x8HI "TARGET_MIN_VLEN >= 128") - (VNx6x8HI "TARGET_MIN_VLEN >= 128") - (VNx7x8HI "TARGET_MIN_VLEN >= 128") - (VNx8x8HI "TARGET_MIN_VLEN >= 128") - (VNx2x8SI "TARGET_MIN_VLEN >= 64") - (VNx3x8SI "TARGET_MIN_VLEN >= 128") - (VNx4x8SI "TARGET_MIN_VLEN >= 128") - (VNx2x8DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx2x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") - (VNx3x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx4x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx2x8DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + RVVM1x2QI + RVVM1x3QI + RVVM1x4QI + RVVM1x5QI + RVVM1x6QI + RVVM1x7QI + RVVM1x8QI + RVVM2x2HI + RVVM2x3HI + RVVM2x4HI + RVVM4x2SI + (RVVM2x2HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM2x3HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM2x4HF "TARGET_VECTOR_ELEN_FP_16") + (RVVM4x2SF "TARGET_VECTOR_ELEN_FP_32") ]) (define_mode_iterator V16T [ - VNx2x16QI - (VNx3x16QI "TARGET_MIN_VLEN >= 64") - (VNx4x16QI "TARGET_MIN_VLEN >= 64") - (VNx5x16QI "TARGET_MIN_VLEN >= 128") - (VNx6x16QI "TARGET_MIN_VLEN >= 128") - (VNx7x16QI "TARGET_MIN_VLEN >= 128") - (VNx8x16QI "TARGET_MIN_VLEN >= 128") - (VNx2x16HI "TARGET_MIN_VLEN >= 64") - (VNx3x16HI "TARGET_MIN_VLEN >= 128") - (VNx4x16HI "TARGET_MIN_VLEN >= 128") - (VNx2x16SI "TARGET_MIN_VLEN >= 128") - (VNx2x16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") + RVVM2x2QI + RVVM2x3QI + RVVM2x4QI + RVVM4x2HI + (RVVM4x2HF "TARGET_VECTOR_ELEN_FP_16") ]) (define_mode_iterator V32T [ - (VNx2x32QI "TARGET_MIN_VLEN >= 64") - (VNx3x32QI "TARGET_MIN_VLEN >= 128") - (VNx4x32QI "TARGET_MIN_VLEN >= 128") - (VNx2x32HI "TARGET_MIN_VLEN >= 128") -]) - -(define_mode_iterator V64T [ - (VNx2x64QI "TARGET_MIN_VLEN >= 128") + RVVM4x2QI ]) (define_mode_iterator VQI [ - (VNx1QI "TARGET_MIN_VLEN < 128") - VNx2QI - VNx4QI - VNx8QI - VNx16QI - VNx32QI - (VNx64QI "TARGET_MIN_VLEN > 32") - (VNx128QI "TARGET_MIN_VLEN >= 128") + RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VHI [ - (VNx1HI "TARGET_MIN_VLEN < 128") - VNx2HI - VNx4HI - VNx8HI - VNx16HI - (VNx32HI "TARGET_MIN_VLEN > 32") - (VNx64HI "TARGET_MIN_VLEN >= 128") + RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VSI [ - (VNx1SI "TARGET_MIN_VLEN < 128") - VNx2SI - VNx4SI - VNx8SI - (VNx16SI "TARGET_MIN_VLEN > 32") - (VNx32SI "TARGET_MIN_VLEN >= 128") + RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VDI [ - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") - (VNx2DI "TARGET_VECTOR_ELEN_64") - (VNx4DI "TARGET_VECTOR_ELEN_64") - (VNx8DI "TARGET_VECTOR_ELEN_64") - (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") + (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) (define_mode_iterator VHF [ - (VNx1HF "TARGET_ZVFH && TARGET_MIN_VLEN < 128") - (VNx2HF "TARGET_ZVFH") - (VNx4HF "TARGET_ZVFH") - (VNx8HF "TARGET_ZVFH") - (VNx16HF "TARGET_ZVFH") - (VNx32HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32") - (VNx64HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128") + (RVVM8HF "TARGET_ZVFH") (RVVM4HF "TARGET_ZVFH") (RVVM2HF "TARGET_ZVFH") + (RVVM1HF "TARGET_ZVFH") (RVVMF2HF "TARGET_ZVFH") + (RVVMF4HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VSF [ - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32") - (VNx4SF "TARGET_VECTOR_ELEN_FP_32") - (VNx8SF "TARGET_VECTOR_ELEN_FP_32") - (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") - (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32") ]) (define_mode_iterator VDF [ - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") - (VNx2DF "TARGET_VECTOR_ELEN_FP_64") - (VNx4DF "TARGET_VECTOR_ELEN_FP_64") - (VNx8DF "TARGET_VECTOR_ELEN_FP_64") - (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) (define_mode_iterator VQI_LMUL1 [ - (VNx16QI "TARGET_MIN_VLEN >= 128") - (VNx8QI "TARGET_MIN_VLEN == 64") - (VNx4QI "TARGET_MIN_VLEN == 32") + RVVM1QI ]) (define_mode_iterator VHI_LMUL1 [ - (VNx8HI "TARGET_MIN_VLEN >= 128") - (VNx4HI "TARGET_MIN_VLEN == 64") - (VNx2HI "TARGET_MIN_VLEN == 32") + RVVM1HI ]) (define_mode_iterator VSI_LMUL1 [ - (VNx4SI "TARGET_MIN_VLEN >= 128") - (VNx2SI "TARGET_MIN_VLEN == 64") - (VNx1SI "TARGET_MIN_VLEN == 32") + RVVM1SI ]) (define_mode_iterator VDI_LMUL1 [ - (VNx2DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") - (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN == 64") + (RVVM1DI "TARGET_VECTOR_ELEN_64") ]) (define_mode_iterator VHF_LMUL1 [ - (VNx8HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128") - (VNx4HF "TARGET_ZVFH && TARGET_MIN_VLEN == 64") - (VNx2HF "TARGET_ZVFH && TARGET_MIN_VLEN == 32") + (RVVM1HF "TARGET_ZVFH") ]) (define_mode_iterator VSF_LMUL1 [ - (VNx4SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") - (VNx2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN == 64") - (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN == 32") + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") ]) (define_mode_iterator VDF_LMUL1 [ - (VNx2DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") - (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN == 64") + (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") ]) -(define_mode_attr VLMULX2 [ - (VNx1QI "VNx2QI") (VNx2QI "VNx4QI") (VNx4QI "VNx8QI") (VNx8QI "VNx16QI") (VNx16QI "VNx32QI") (VNx32QI "VNx64QI") (VNx64QI "VNx128QI") - (VNx1HI "VNx2HI") (VNx2HI "VNx4HI") (VNx4HI "VNx8HI") (VNx8HI "VNx16HI") (VNx16HI "VNx32HI") (VNx32HI "VNx64HI") - (VNx1SI "VNx2SI") (VNx2SI "VNx4SI") (VNx4SI "VNx8SI") (VNx8SI "VNx16SI") (VNx16SI "VNx32SI") - (VNx1DI "VNx2DI") (VNx2DI "VNx4DI") (VNx4DI "VNx8DI") (VNx8DI "VNx16DI") - (VNx1SF "VNx2SF") (VNx2SF "VNx4SF") (VNx4SF "VNx8SF") (VNx8SF "VNx16SF") (VNx16SF "VNx32SF") - (VNx1DF "VNx2DF") (VNx2DF "VNx4DF") (VNx4DF "VNx8DF") (VNx8DF "VNx16DF") -]) +(define_mode_attr VINDEX [ + (RVVM8QI "RVVM8QI") (RVVM4QI "RVVM4QI") (RVVM2QI "RVVM2QI") (RVVM1QI "RVVM1QI") + (RVVMF2QI "RVVMF2QI") (RVVMF4QI "RVVMF4QI") (RVVMF8QI "RVVMF8QI") -(define_mode_attr VLMULX4 [ - (VNx1QI "VNx4QI") (VNx2QI "VNx8QI") (VNx4QI "VNx16QI") (VNx8QI "VNx32QI") (VNx16QI "VNx64QI") (VNx32QI "VNx128QI") - (VNx1HI "VNx4HI") (VNx2HI "VNx8HI") (VNx4HI "VNx16HI") (VNx8HI "VNx32HI") (VNx16HI "VNx64HI") - (VNx1SI "VNx4SI") (VNx2SI "VNx8SI") (VNx4SI "VNx16SI") (VNx8SI "VNx32SI") - (VNx1DI "VNx4DI") (VNx2DI "VNx8DI") (VNx4DI "VNx16DI") - (VNx1SF "VNx4SF") (VNx2SF "VNx8SF") (VNx4SF "VNx16SF") (VNx8SF "VNx32SF") - (VNx1DF "VNx4DF") (VNx2DF "VNx8DF") (VNx4DF "VNx16DF") -]) + (RVVM8HI "RVVM8HI") (RVVM4HI "RVVM4HI") (RVVM2HI "RVVM2HI") (RVVM1HI "RVVM1HI") (RVVMF2HI "RVVMF2HI") (RVVMF4HI "RVVMF4HI") -(define_mode_attr VLMULX8 [ - (VNx1QI "VNx8QI") (VNx2QI "VNx16QI") (VNx4QI "VNx32QI") (VNx8QI "VNx64QI") (VNx16QI "VNx128QI") - (VNx1HI "VNx8HI") (VNx2HI "VNx16HI") (VNx4HI "VNx32HI") (VNx8HI "VNx64HI") - (VNx1SI "VNx8SI") (VNx2SI "VNx16SI") (VNx4SI "VNx32SI") - (VNx1DI "VNx8DI") (VNx2DI "VNx16DI") - (VNx1SF "VNx8SF") (VNx2SF "VNx16SF") (VNx4SF "VNx32SF") - (VNx1DF "VNx8DF") (VNx2DF "VNx16DF") -]) + (RVVM8HF "RVVM8HI") (RVVM4HF "RVVM4HI") (RVVM2HF "RVVM2HI") (RVVM1HF "RVVM1HI") (RVVMF2HF "RVVMF2HI") (RVVMF4HF "RVVMF4HI") -(define_mode_attr VLMULX16 [ - (VNx1QI "VNx16QI") (VNx2QI "VNx32QI") (VNx4QI "VNx64QI") (VNx8QI "VNx128QI") - (VNx1HI "VNx16HI") (VNx2HI "VNx32HI") (VNx4HI "VNx64HI") - (VNx1SI "VNx16SI") (VNx2SI "VNx32SI") - (VNx1SF "VNx16SF") (VNx2SF "VNx32SF") -]) + (RVVM8SI "RVVM8SI") (RVVM4SI "RVVM4SI") (RVVM2SI "RVVM2SI") (RVVM1SI "RVVM1SI") (RVVMF2SI "RVVMF2SI") -(define_mode_attr VLMULX32 [ - (VNx1QI "VNx32QI") (VNx2QI "VNx64QI") (VNx4QI "VNx128QI") - (VNx1HI "VNx32HI") (VNx2HI "VNx64HI") -]) + (RVVM8SF "RVVM8SI") (RVVM4SF "RVVM4SI") (RVVM2SF "RVVM2SI") (RVVM1SF "RVVM1SI") (RVVMF2SF "RVVMF2SI") -(define_mode_attr VLMULX64 [ - (VNx1QI "VNx64QI") (VNx2QI "VNx128QI") -]) + (RVVM8DI "RVVM8DI") (RVVM4DI "RVVM4DI") (RVVM2DI "RVVM2DI") (RVVM1DI "RVVM1DI") -(define_mode_attr VINDEX [ - (VNx1QI "VNx1QI") (VNx2QI "VNx2QI") (VNx4QI "VNx4QI") (VNx8QI "VNx8QI") - (VNx16QI "VNx16QI") (VNx32QI "VNx32QI") (VNx64QI "VNx64QI") (VNx128QI "VNx128QI") - (VNx1HI "VNx1HI") (VNx2HI "VNx2HI") (VNx4HI "VNx4HI") (VNx8HI "VNx8HI") - (VNx16HI "VNx16HI") (VNx32HI "VNx32HI") (VNx64HI "VNx64HI") - (VNx1SI "VNx1SI") (VNx2SI "VNx2SI") (VNx4SI "VNx4SI") (VNx8SI "VNx8SI") - (VNx16SI "VNx16SI") (VNx32SI "VNx32SI") - (VNx1DI "VNx1DI") (VNx2DI "VNx2DI") (VNx4DI "VNx4DI") (VNx8DI "VNx8DI") (VNx16DI "VNx16DI") - (VNx1HF "VNx1HI") (VNx2HF "VNx2HI") (VNx4HF "VNx4HI") (VNx8HF "VNx8HI") (VNx16HF "VNx16HI") (VNx32HF "VNx32HI") (VNx64HF "VNx64HI") - (VNx1SF "VNx1SI") (VNx2SF "VNx2SI") (VNx4SF "VNx4SI") (VNx8SF "VNx8SI") - (VNx16SF "VNx16SI") (VNx32SF "VNx32SI") - (VNx1DF "VNx1DI") (VNx2DF "VNx2DI") (VNx4DF "VNx4DI") (VNx8DF "VNx8DI") (VNx16DF "VNx16DI") + (RVVM8DF "RVVM8DI") (RVVM4DF "RVVM4DI") (RVVM2DF "RVVM2DI") (RVVM1DF "RVVM1DI") ]) (define_mode_attr VINDEXEI16 [ - (VNx1QI "VNx1HI") (VNx2QI "VNx2HI") (VNx4QI "VNx4HI") (VNx8QI "VNx8HI") - (VNx16QI "VNx16HI") (VNx32QI "VNx32HI") (VNx64QI "VNx64HI") - (VNx1HI "VNx1HI") (VNx2HI "VNx2HI") (VNx4HI "VNx4HI") (VNx8HI "VNx8HI") - (VNx16HI "VNx16HI") (VNx32HI "VNx32HI") (VNx64HI "VNx64HI") - (VNx1SI "VNx1HI") (VNx2SI "VNx2HI") (VNx4SI "VNx4HI") (VNx8SI "VNx8HI") - (VNx16SI "VNx16HI") (VNx32SI "VNx32HI") - (VNx1DI "VNx1HI") (VNx2DI "VNx2HI") (VNx4DI "VNx4HI") (VNx8DI "VNx8HI") (VNx16DI "VNx16HI") - (VNx1SF "VNx1HI") (VNx2SF "VNx2HI") (VNx4SF "VNx4HI") (VNx8SF "VNx8HI") - (VNx16SF "VNx16HI") (VNx32SF "VNx32HI") - (VNx1DF "VNx1HI") (VNx2DF "VNx2HI") (VNx4DF "VNx4HI") (VNx8DF "VNx8HI") (VNx16DF "VNx16HI") + (RVVM4QI "RVVM8HI") (RVVM2QI "RVVM4HI") (RVVM1QI "RVVM2HI") (RVVMF2QI "RVVM1HI") (RVVMF4QI "RVVMF2HI") (RVVMF8QI "RVVMF4HI") + + (RVVM8HI "RVVM8HI") (RVVM4HI "RVVM4HI") (RVVM2HI "RVVM2HI") (RVVM1HI "RVVM1HI") (RVVMF2HI "RVVMF2HI") (RVVMF4HI "RVVMF4HI") + + (RVVM8SI "RVVM4HI") (RVVM4SI "RVVM2HI") (RVVM2SI "RVVM1HI") (RVVM1SI "RVVMF2HI") (RVVMF2SI "RVVMF4HI") + + (RVVM8DI "RVVM2HI") (RVVM4DI "RVVM1HI") (RVVM2DI "RVVMF2HI") (RVVM1DI "RVVMF4HI") + + (RVVM8HF "RVVM8HI") (RVVM4HF "RVVM4HI") (RVVM2HF "RVVM2HI") (RVVM1HF "RVVM1HI") (RVVMF2HF "RVVMF2HI") (RVVMF4HF "RVVMF4HI") + + (RVVM8SF "RVVM4HI") (RVVM4SF "RVVM2HI") (RVVM2SF "RVVM1HI") (RVVM1SF "RVVMF2HI") (RVVMF2SF "RVVMF4HI") + + (RVVM8DF "RVVM2HI") (RVVM4DF "RVVM1HI") (RVVM2DF "RVVMF2HI") (RVVM1DF "RVVMF4HI") ]) (define_mode_attr VM [ - (VNx1QI "VNx1BI") (VNx2QI "VNx2BI") (VNx4QI "VNx4BI") (VNx8QI "VNx8BI") (VNx16QI "VNx16BI") (VNx32QI "VNx32BI") (VNx64QI "VNx64BI") (VNx128QI "VNx128BI") - (VNx1HI "VNx1BI") (VNx2HI "VNx2BI") (VNx4HI "VNx4BI") (VNx8HI "VNx8BI") (VNx16HI "VNx16BI") (VNx32HI "VNx32BI") (VNx64HI "VNx64BI") - (VNx1SI "VNx1BI") (VNx2SI "VNx2BI") (VNx4SI "VNx4BI") (VNx8SI "VNx8BI") (VNx16SI "VNx16BI") (VNx32SI "VNx32BI") - (VNx1DI "VNx1BI") (VNx2DI "VNx2BI") (VNx4DI "VNx4BI") (VNx8DI "VNx8BI") (VNx16DI "VNx16BI") - (VNx1HF "VNx1BI") (VNx2HF "VNx2BI") (VNx4HF "VNx4BI") (VNx8HF "VNx8BI") (VNx16HF "VNx16BI") (VNx32HF "VNx32BI") (VNx64HF "VNx64BI") - (VNx1SF "VNx1BI") (VNx2SF "VNx2BI") (VNx4SF "VNx4BI") (VNx8SF "VNx8BI") (VNx16SF "VNx16BI") (VNx32SF "VNx32BI") - (VNx1DF "VNx1BI") (VNx2DF "VNx2BI") (VNx4DF "VNx4BI") (VNx8DF "VNx8BI") (VNx16DF "VNx16BI") - (VNx2x64QI "VNx64BI") (VNx2x32QI "VNx32BI") (VNx3x32QI "VNx32BI") (VNx4x32QI "VNx32BI") - (VNx2x16QI "VNx16BI") (VNx3x16QI "VNx16BI") (VNx4x16QI "VNx16BI") (VNx5x16QI "VNx16BI") (VNx6x16QI "VNx16BI") (VNx7x16QI "VNx16BI") (VNx8x16QI "VNx16BI") - (VNx2x8QI "VNx8BI") (VNx3x8QI "VNx8BI") (VNx4x8QI "VNx8BI") (VNx5x8QI "VNx8BI") (VNx6x8QI "VNx8BI") (VNx7x8QI "VNx8BI") (VNx8x8QI "VNx8BI") - (VNx2x4QI "VNx4BI") (VNx3x4QI "VNx4BI") (VNx4x4QI "VNx4BI") (VNx5x4QI "VNx4BI") (VNx6x4QI "VNx4BI") (VNx7x4QI "VNx4BI") (VNx8x4QI "VNx4BI") - (VNx2x2QI "VNx2BI") (VNx3x2QI "VNx2BI") (VNx4x2QI "VNx2BI") (VNx5x2QI "VNx2BI") (VNx6x2QI "VNx2BI") (VNx7x2QI "VNx2BI") (VNx8x2QI "VNx2BI") - (VNx2x1QI "VNx1BI") (VNx3x1QI "VNx1BI") (VNx4x1QI "VNx1BI") (VNx5x1QI "VNx1BI") (VNx6x1QI "VNx1BI") (VNx7x1QI "VNx1BI") (VNx8x1QI "VNx1BI") - (VNx2x32HI "VNx32BI") (VNx2x16HI "VNx16BI") (VNx3x16HI "VNx16BI") (VNx4x16HI "VNx16BI") - (VNx2x8HI "VNx8BI") (VNx3x8HI "VNx8BI") (VNx4x8HI "VNx8BI") (VNx5x8HI "VNx8BI") (VNx6x8HI "VNx8BI") (VNx7x8HI "VNx8BI") (VNx8x8HI "VNx8BI") - (VNx2x4HI "VNx4BI") (VNx3x4HI "VNx4BI") (VNx4x4HI "VNx4BI") (VNx5x4HI "VNx4BI") (VNx6x4HI "VNx4BI") (VNx7x4HI "VNx4BI") (VNx8x4HI "VNx4BI") - (VNx2x2HI "VNx2BI") (VNx3x2HI "VNx2BI") (VNx4x2HI "VNx2BI") (VNx5x2HI "VNx2BI") (VNx6x2HI "VNx2BI") (VNx7x2HI "VNx2BI") (VNx8x2HI "VNx2BI") - (VNx2x1HI "VNx1BI") (VNx3x1HI "VNx1BI") (VNx4x1HI "VNx1BI") (VNx5x1HI "VNx1BI") (VNx6x1HI "VNx1BI") (VNx7x1HI "VNx1BI") (VNx8x1HI "VNx1BI") - (VNx2x16SI "VNx16BI") (VNx2x8SI "VNx8BI") (VNx3x8SI "VNx8BI") (VNx4x8SI "VNx8BI") - (VNx2x4SI "VNx4BI") (VNx3x4SI "VNx4BI") (VNx4x4SI "VNx4BI") (VNx5x4SI "VNx4BI") (VNx6x4SI "VNx4BI") (VNx7x4SI "VNx4BI") (VNx8x4SI "VNx4BI") - (VNx2x2SI "VNx2BI") (VNx3x2SI "VNx2BI") (VNx4x2SI "VNx2BI") (VNx5x2SI "VNx2BI") (VNx6x2SI "VNx2BI") (VNx7x2SI "VNx2BI") (VNx8x2SI "VNx2BI") - (VNx2x1SI "VNx1BI") (VNx3x1SI "VNx1BI") (VNx4x1SI "VNx1BI") (VNx5x1SI "VNx1BI") (VNx6x1SI "VNx1BI") (VNx7x1SI "VNx1BI") (VNx8x1SI "VNx1BI") - (VNx2x8DI "VNx8BI") (VNx2x4DI "VNx4BI") (VNx3x4DI "VNx4BI") (VNx4x4DI "VNx4BI") - (VNx2x2DI "VNx2BI") (VNx3x2DI "VNx2BI") (VNx4x2DI "VNx2BI") (VNx5x2DI "VNx2BI") (VNx6x2DI "VNx2BI") (VNx7x2DI "VNx2BI") (VNx8x2DI "VNx2BI") - (VNx2x1DI "VNx1BI") (VNx3x1DI "VNx1BI") (VNx4x1DI "VNx1BI") (VNx5x1DI "VNx1BI") (VNx6x1DI "VNx1BI") (VNx7x1DI "VNx1BI") (VNx8x1DI "VNx1BI") - (VNx2x32HF "VNx32BI") (VNx2x16HF "VNx16BI") (VNx3x16HF "VNx16BI") (VNx4x16HF "VNx16BI") - (VNx2x8HF "VNx8BI") (VNx3x8HF "VNx8BI") (VNx4x8HF "VNx8BI") (VNx5x8HF "VNx8BI") (VNx6x8HF "VNx8BI") (VNx7x8HF "VNx8BI") (VNx8x8HF "VNx8BI") - (VNx2x4HF "VNx4BI") (VNx3x4HF "VNx4BI") (VNx4x4HF "VNx4BI") (VNx5x4HF "VNx4BI") (VNx6x4HF "VNx4BI") (VNx7x4HF "VNx4BI") (VNx8x4HF "VNx4BI") - (VNx2x2HF "VNx2BI") (VNx3x2HF "VNx2BI") (VNx4x2HF "VNx2BI") (VNx5x2HF "VNx2BI") (VNx6x2HF "VNx2BI") (VNx7x2HF "VNx2BI") (VNx8x2HF "VNx2BI") - (VNx2x1HF "VNx1BI") (VNx3x1HF "VNx1BI") (VNx4x1HF "VNx1BI") (VNx5x1HF "VNx1BI") (VNx6x1HF "VNx1BI") (VNx7x1HF "VNx1BI") (VNx8x1HF "VNx1BI") - (VNx2x16SF "VNx16BI") (VNx2x8SF "VNx8BI") (VNx3x8SF "VNx8BI") (VNx4x8SF "VNx8BI") - (VNx2x4SF "VNx4BI") (VNx3x4SF "VNx4BI") (VNx4x4SF "VNx4BI") (VNx5x4SF "VNx4BI") (VNx6x4SF "VNx4BI") (VNx7x4SF "VNx4BI") (VNx8x4SF "VNx4BI") - (VNx2x2SF "VNx2BI") (VNx3x2SF "VNx2BI") (VNx4x2SF "VNx2BI") (VNx5x2SF "VNx2BI") (VNx6x2SF "VNx2BI") (VNx7x2SF "VNx2BI") (VNx8x2SF "VNx2BI") - (VNx2x1SF "VNx1BI") (VNx3x1SF "VNx1BI") (VNx4x1SF "VNx1BI") (VNx5x1SF "VNx1BI") (VNx6x1SF "VNx1BI") (VNx7x1SF "VNx1BI") (VNx8x1SF "VNx1BI") - (VNx2x8DF "VNx8BI") - (VNx2x4DF "VNx4BI") (VNx3x4DF "VNx4BI") (VNx4x4DF "VNx4BI") - (VNx2x2DF "VNx2BI") (VNx3x2DF "VNx2BI") (VNx4x2DF "VNx2BI") (VNx5x2DF "VNx2BI") (VNx6x2DF "VNx2BI") (VNx7x2DF "VNx2BI") (VNx8x2DF "VNx2BI") - (VNx2x1DF "VNx1BI") (VNx3x1DF "VNx1BI") (VNx4x1DF "VNx1BI") (VNx5x1DF "VNx1BI") (VNx6x1DF "VNx1BI") (VNx7x1DF "VNx1BI") (VNx8x1DF "VNx1BI") + (RVVM8QI "RVVM1BI") (RVVM4QI "RVVMF2BI") (RVVM2QI "RVVMF4BI") (RVVM1QI "RVVMF8BI") (RVVMF2QI "RVVMF16BI") (RVVMF4QI "RVVMF32BI") (RVVMF8QI "RVVMF64BI") + + (RVVM8HI "RVVMF2BI") (RVVM4HI "RVVMF4BI") (RVVM2HI "RVVMF8BI") (RVVM1HI "RVVMF16BI") (RVVMF2HI "RVVMF32BI") (RVVMF4HI "RVVMF64BI") + + (RVVM8HF "RVVMF2BI") (RVVM4HF "RVVMF4BI") (RVVM2HF "RVVMF8BI") (RVVM1HF "RVVMF16BI") (RVVMF2HF "RVVMF32BI") (RVVMF4HF "RVVMF64BI") + + (RVVM8SI "RVVMF4BI") (RVVM4SI "RVVMF8BI") (RVVM2SI "RVVMF16BI") (RVVM1SI "RVVMF32BI") (RVVMF2SI "RVVMF64BI") + + (RVVM8SF "RVVMF4BI") (RVVM4SF "RVVMF8BI") (RVVM2SF "RVVMF16BI") (RVVM1SF "RVVMF32BI") (RVVMF2SF "RVVMF64BI") + + (RVVM8DI "RVVMF8BI") (RVVM4DI "RVVMF16BI") (RVVM2DI "RVVMF32BI") (RVVM1DI "RVVMF64BI") + + (RVVM8DF "RVVMF8BI") (RVVM4DF "RVVMF16BI") (RVVM2DF "RVVMF32BI") (RVVM1DF "RVVMF64BI") + + (RVVM1x8QI "RVVMF8BI") (RVVMF2x8QI "RVVMF16BI") (RVVMF4x8QI "RVVMF32BI") (RVVMF8x8QI "RVVMF64BI") + (RVVM1x7QI "RVVMF8BI") (RVVMF2x7QI "RVVMF16BI") (RVVMF4x7QI "RVVMF32BI") (RVVMF8x7QI "RVVMF64BI") + (RVVM1x6QI "RVVMF8BI") (RVVMF2x6QI "RVVMF16BI") (RVVMF4x6QI "RVVMF32BI") (RVVMF8x6QI "RVVMF64BI") + (RVVM1x5QI "RVVMF8BI") (RVVMF2x5QI "RVVMF16BI") (RVVMF4x5QI "RVVMF32BI") (RVVMF8x5QI "RVVMF64BI") + (RVVM2x4QI "RVVMF4BI") (RVVM1x4QI "RVVMF8BI") (RVVMF2x4QI "RVVMF16BI") (RVVMF4x4QI "RVVMF32BI") (RVVMF8x4QI "RVVMF64BI") + (RVVM2x3QI "RVVMF4BI") (RVVM1x3QI "RVVMF8BI") (RVVMF2x3QI "RVVMF16BI") (RVVMF4x3QI "RVVMF32BI") (RVVMF8x3QI "RVVMF64BI") + (RVVM4x2QI "RVVMF2BI") (RVVM2x2QI "RVVMF4BI") (RVVM1x2QI "RVVMF8BI") (RVVMF2x2QI "RVVMF16BI") (RVVMF4x2QI "RVVMF32BI") (RVVMF8x2QI "RVVMF64BI") + + (RVVM1x8HI "RVVMF16BI") (RVVMF2x8HI "RVVMF32BI") (RVVMF4x8HI "RVVMF64BI") + (RVVM1x7HI "RVVMF16BI") (RVVMF2x7HI "RVVMF32BI") (RVVMF4x7HI "RVVMF64BI") + (RVVM1x6HI "RVVMF16BI") (RVVMF2x6HI "RVVMF32BI") (RVVMF4x6HI "RVVMF64BI") + (RVVM1x5HI "RVVMF16BI") (RVVMF2x5HI "RVVMF32BI") (RVVMF4x5HI "RVVMF64BI") + (RVVM2x4HI "RVVMF8BI") (RVVM1x4HI "RVVMF16BI") (RVVMF2x4HI "RVVMF32BI") (RVVMF4x4HI "RVVMF64BI") + (RVVM2x3HI "RVVMF8BI") (RVVM1x3HI "RVVMF16BI") (RVVMF2x3HI "RVVMF32BI") (RVVMF4x3HI "RVVMF64BI") + (RVVM4x2HI "RVVMF4BI") (RVVM2x2HI "RVVMF8BI") (RVVM1x2HI "RVVMF16BI") (RVVMF2x2HI "RVVMF32BI") (RVVMF4x2HI "RVVMF64BI") + + (RVVM1x8HF "RVVMF16BI") (RVVMF2x8HF "RVVMF32BI") (RVVMF4x8HF "RVVMF64BI") + (RVVM1x7HF "RVVMF16BI") (RVVMF2x7HF "RVVMF32BI") (RVVMF4x7HF "RVVMF64BI") + (RVVM1x6HF "RVVMF16BI") (RVVMF2x6HF "RVVMF32BI") (RVVMF4x6HF "RVVMF64BI") + (RVVM1x5HF "RVVMF16BI") (RVVMF2x5HF "RVVMF32BI") (RVVMF4x5HF "RVVMF64BI") + (RVVM2x4HF "RVVMF8BI") (RVVM1x4HF "RVVMF16BI") (RVVMF2x4HF "RVVMF32BI") (RVVMF4x4HF "RVVMF64BI") + (RVVM2x3HF "RVVMF8BI") (RVVM1x3HF "RVVMF16BI") (RVVMF2x3HF "RVVMF32BI") (RVVMF4x3HF "RVVMF64BI") + (RVVM4x2HF "RVVMF4BI") (RVVM2x2HF "RVVMF8BI") (RVVM1x2HF "RVVMF16BI") (RVVMF2x2HF "RVVMF32BI") (RVVMF4x2HF "RVVMF64BI") + + (RVVM1x8SI "RVVMF32BI") (RVVMF2x8SI "RVVMF64BI") + (RVVM1x7SI "RVVMF32BI") (RVVMF2x7SI "RVVMF64BI") + (RVVM1x6SI "RVVMF32BI") (RVVMF2x6SI "RVVMF64BI") + (RVVM1x5SI "RVVMF32BI") (RVVMF2x5SI "RVVMF64BI") + (RVVM2x4SI "RVVMF16BI") (RVVM1x4SI "RVVMF32BI") (RVVMF2x4SI "RVVMF64BI") + (RVVM2x3SI "RVVMF16BI") (RVVM1x3SI "RVVMF32BI") (RVVMF2x3SI "RVVMF64BI") + (RVVM4x2SI "RVVMF8BI") (RVVM2x2SI "RVVMF16BI") (RVVM1x2SI "RVVMF32BI") (RVVMF2x2SI "RVVMF64BI") + + (RVVM1x8SF "RVVMF32BI") (RVVMF2x8SF "RVVMF64BI") + (RVVM1x7SF "RVVMF32BI") (RVVMF2x7SF "RVVMF64BI") + (RVVM1x6SF "RVVMF32BI") (RVVMF2x6SF "RVVMF64BI") + (RVVM1x5SF "RVVMF32BI") (RVVMF2x5SF "RVVMF64BI") + (RVVM2x4SF "RVVMF16BI") (RVVM1x4SF "RVVMF32BI") (RVVMF2x4SF "RVVMF64BI") + (RVVM2x3SF "RVVMF16BI") (RVVM1x3SF "RVVMF32BI") (RVVMF2x3SF "RVVMF64BI") + (RVVM4x2SF "RVVMF8BI") (RVVM2x2SF "RVVMF16BI") (RVVM1x2SF "RVVMF32BI") (RVVMF2x2SF "RVVMF64BI") + + (RVVM1x8DI "RVVMF64BI") + (RVVM1x7DI "RVVMF64BI") + (RVVM1x6DI "RVVMF64BI") + (RVVM1x5DI "RVVMF64BI") + (RVVM2x4DI "RVVMF32BI") + (RVVM1x4DI "RVVMF64BI") + (RVVM2x3DI "RVVMF32BI") + (RVVM1x3DI "RVVMF64BI") + (RVVM4x2DI "RVVMF16BI") + (RVVM2x2DI "RVVMF32BI") + (RVVM1x2DI "RVVMF64BI") + + (RVVM1x8DF "RVVMF64BI") + (RVVM1x7DF "RVVMF64BI") + (RVVM1x6DF "RVVMF64BI") + (RVVM1x5DF "RVVMF64BI") + (RVVM2x4DF "RVVMF32BI") + (RVVM1x4DF "RVVMF64BI") + (RVVM2x3DF "RVVMF32BI") + (RVVM1x3DF "RVVMF64BI") + (RVVM4x2DF "RVVMF16BI") + (RVVM2x2DF "RVVMF32BI") + (RVVM1x2DF "RVVMF64BI") ]) (define_mode_attr vm [ - (VNx1QI "vnx1bi") (VNx2QI "vnx2bi") (VNx4QI "vnx4bi") (VNx8QI "vnx8bi") (VNx16QI "vnx16bi") (VNx32QI "vnx32bi") (VNx64QI "vnx64bi") (VNx128QI "vnx128bi") - (VNx1HI "vnx1bi") (VNx2HI "vnx2bi") (VNx4HI "vnx4bi") (VNx8HI "vnx8bi") (VNx16HI "vnx16bi") (VNx32HI "vnx32bi") (VNx64HI "vnx64bi") - (VNx1SI "vnx1bi") (VNx2SI "vnx2bi") (VNx4SI "vnx4bi") (VNx8SI "vnx8bi") (VNx16SI "vnx16bi") (VNx32SI "vnx32bi") - (VNx1DI "vnx1bi") (VNx2DI "vnx2bi") (VNx4DI "vnx4bi") (VNx8DI "vnx8bi") (VNx16DI "vnx16bi") - (VNx1HF "vnx1bi") (VNx2HF "vnx2bi") (VNx4HF "vnx4bi") (VNx8HF "vnx8bi") (VNx16HF "vnx16bi") (VNx32HF "vnx32bi") (VNx64HF "vnx64bi") - (VNx1SF "vnx1bi") (VNx2SF "vnx2bi") (VNx4SF "vnx4bi") (VNx8SF "vnx8bi") (VNx16SF "vnx16bi") (VNx32SF "vnx32bi") - (VNx1DF "vnx1bi") (VNx2DF "vnx2bi") (VNx4DF "vnx4bi") (VNx8DF "vnx8bi") (VNx16DF "vnx16bi") + (RVVM8QI "rvvm1bi") (RVVM4QI "rvvmf2bi") (RVVM2QI "rvvmf4bi") (RVVM1QI "rvvmf8bi") (RVVMF2QI "rvvmf16bi") (RVVMF4QI "rvvmf32bi") (RVVMF8QI "rvvmf64bi") + + (RVVM8HI "rvvmf2bi") (RVVM4HI "rvvmf4bi") (RVVM2HI "rvvmf8bi") (RVVM1HI "rvvmf16bi") (RVVMF2HI "rvvmf32bi") (RVVMF4HI "rvvmf64bi") + + (RVVM8HF "rvvmf2bi") (RVVM4HF "rvvmf4bi") (RVVM2HF "rvvmf8bi") (RVVM1HF "rvvmf16bi") (RVVMF2HF "rvvmf32bi") (RVVMF4HF "rvvmf64bi") + + (RVVM8SI "rvvmf4bi") (RVVM4SI "rvvmf8bi") (RVVM2SI "rvvmf16bi") (RVVM1SI "rvvmf32bi") (RVVMF2SI "rvvmf64bi") + + (RVVM8SF "rvvmf4bi") (RVVM4SF "rvvmf8bi") (RVVM2SF "rvvmf16bi") (RVVM1SF "rvvmf32bi") (RVVMF2SF "rvvmf64bi") + + (RVVM8DI "rvvmf8bi") (RVVM4DI "rvvmf16bi") (RVVM2DI "rvvmf32bi") (RVVM1DI "rvvmf64bi") + + (RVVM8DF "rvvmf8bi") (RVVM4DF "rvvmf16bi") (RVVM2DF "rvvmf32bi") (RVVM1DF "rvvmf64bi") + + (RVVM1x8QI "rvvmf8bi") (RVVMF2x8QI "rvvmf16bi") (RVVMF4x8QI "rvvmf32bi") (RVVMF8x8QI "rvvmf64bi") + (RVVM1x7QI "rvvmf8bi") (RVVMF2x7QI "rvvmf16bi") (RVVMF4x7QI "rvvmf32bi") (RVVMF8x7QI "rvvmf64bi") + (RVVM1x6QI "rvvmf8bi") (RVVMF2x6QI "rvvmf16bi") (RVVMF4x6QI "rvvmf32bi") (RVVMF8x6QI "rvvmf64bi") + (RVVM1x5QI "rvvmf8bi") (RVVMF2x5QI "rvvmf16bi") (RVVMF4x5QI "rvvmf32bi") (RVVMF8x5QI "rvvmf64bi") + (RVVM2x4QI "rvvmf4bi") (RVVM1x4QI "rvvmf8bi") (RVVMF2x4QI "rvvmf16bi") (RVVMF4x4QI "rvvmf32bi") (RVVMF8x4QI "rvvmf64bi") + (RVVM2x3QI "rvvmf4bi") (RVVM1x3QI "rvvmf8bi") (RVVMF2x3QI "rvvmf16bi") (RVVMF4x3QI "rvvmf32bi") (RVVMF8x3QI "rvvmf64bi") + (RVVM4x2QI "rvvmf2bi") (RVVM2x2QI "rvvmf4bi") (RVVM1x2QI "rvvmf8bi") (RVVMF2x2QI "rvvmf16bi") (RVVMF4x2QI "rvvmf32bi") (RVVMF8x2QI "rvvmf64bi") + + (RVVM1x8HI "rvvmf16bi") (RVVMF2x8HI "rvvmf32bi") (RVVMF4x8HI "rvvmf64bi") + (RVVM1x7HI "rvvmf16bi") (RVVMF2x7HI "rvvmf32bi") (RVVMF4x7HI "rvvmf64bi") + (RVVM1x6HI "rvvmf16bi") (RVVMF2x6HI "rvvmf32bi") (RVVMF4x6HI "rvvmf64bi") + (RVVM1x5HI "rvvmf16bi") (RVVMF2x5HI "rvvmf32bi") (RVVMF4x5HI "rvvmf64bi") + (RVVM2x4HI "rvvmf8bi") (RVVM1x4HI "rvvmf16bi") (RVVMF2x4HI "rvvmf32bi") (RVVMF4x4HI "rvvmf64bi") + (RVVM2x3HI "rvvmf8bi") (RVVM1x3HI "rvvmf16bi") (RVVMF2x3HI "rvvmf32bi") (RVVMF4x3HI "rvvmf64bi") + (RVVM4x2HI "rvvmf4bi") (RVVM2x2HI "rvvmf8bi") (RVVM1x2HI "rvvmf16bi") (RVVMF2x2HI "rvvmf32bi") (RVVMF4x2HI "rvvmf64bi") + + (RVVM1x8HF "rvvmf16bi") (RVVMF2x8HF "rvvmf32bi") (RVVMF4x8HF "rvvmf64bi") + (RVVM1x7HF "rvvmf16bi") (RVVMF2x7HF "rvvmf32bi") (RVVMF4x7HF "rvvmf64bi") + (RVVM1x6HF "rvvmf16bi") (RVVMF2x6HF "rvvmf32bi") (RVVMF4x6HF "rvvmf64bi") + (RVVM1x5HF "rvvmf16bi") (RVVMF2x5HF "rvvmf32bi") (RVVMF4x5HF "rvvmf64bi") + (RVVM2x4HF "rvvmf8bi") (RVVM1x4HF "rvvmf16bi") (RVVMF2x4HF "rvvmf32bi") (RVVMF4x4HF "rvvmf64bi") + (RVVM2x3HF "rvvmf8bi") (RVVM1x3HF "rvvmf16bi") (RVVMF2x3HF "rvvmf32bi") (RVVMF4x3HF "rvvmf64bi") + (RVVM4x2HF "rvvmf4bi") (RVVM2x2HF "rvvmf8bi") (RVVM1x2HF "rvvmf16bi") (RVVMF2x2HF "rvvmf32bi") (RVVMF4x2HF "rvvmf64bi") + + (RVVM1x8SI "rvvmf32bi") (RVVMF2x8SI "rvvmf64bi") + (RVVM1x7SI "rvvmf32bi") (RVVMF2x7SI "rvvmf64bi") + (RVVM1x6SI "rvvmf32bi") (RVVMF2x6SI "rvvmf64bi") + (RVVM1x5SI "rvvmf32bi") (RVVMF2x5SI "rvvmf64bi") + (RVVM2x4SI "rvvmf16bi") (RVVM1x4SI "rvvmf32bi") (RVVMF2x4SI "rvvmf64bi") + (RVVM2x3SI "rvvmf16bi") (RVVM1x3SI "rvvmf32bi") (RVVMF2x3SI "rvvmf64bi") + (RVVM4x2SI "rvvmf4bi") (RVVM2x2SI "rvvmf16bi") (RVVM1x2SI "rvvmf32bi") (RVVMF2x2SI "rvvmf64bi") + + (RVVM1x8SF "rvvmf32bi") (RVVMF2x8SF "rvvmf64bi") + (RVVM1x7SF "rvvmf32bi") (RVVMF2x7SF "rvvmf64bi") + (RVVM1x6SF "rvvmf32bi") (RVVMF2x6SF "rvvmf64bi") + (RVVM1x5SF "rvvmf32bi") (RVVMF2x5SF "rvvmf64bi") + (RVVM2x4SF "rvvmf16bi") (RVVM1x4SF "rvvmf32bi") (RVVMF2x4SF "rvvmf64bi") + (RVVM2x3SF "rvvmf16bi") (RVVM1x3SF "rvvmf32bi") (RVVMF2x3SF "rvvmf64bi") + (RVVM4x2SF "rvvmf4bi") (RVVM2x2SF "rvvmf16bi") (RVVM1x2SF "rvvmf32bi") (RVVMF2x2SF "rvvmf64bi") + + (RVVM1x8DI "rvvmf64bi") + (RVVM1x7DI "rvvmf64bi") + (RVVM1x6DI "rvvmf64bi") + (RVVM1x5DI "rvvmf64bi") + (RVVM2x4DI "rvvmf32bi") + (RVVM1x4DI "rvvmf64bi") + (RVVM2x3DI "rvvmf32bi") + (RVVM1x3DI "rvvmf64bi") + (RVVM4x2DI "rvvmf16bi") + (RVVM2x2DI "rvvmf32bi") + (RVVM1x2DI "rvvmf64bi") + + (RVVM1x8DF "rvvmf64bi") + (RVVM1x7DF "rvvmf64bi") + (RVVM1x6DF "rvvmf64bi") + (RVVM1x5DF "rvvmf64bi") + (RVVM2x4DF "rvvmf32bi") + (RVVM1x4DF "rvvmf64bi") + (RVVM2x3DF "rvvmf32bi") + (RVVM1x3DF "rvvmf64bi") + (RVVM4x2DF "rvvmf16bi") + (RVVM2x2DF "rvvmf32bi") + (RVVM1x2DF "rvvmf64bi") ]) (define_mode_attr VEL [ - (VNx1QI "QI") (VNx2QI "QI") (VNx4QI "QI") (VNx8QI "QI") (VNx16QI "QI") (VNx32QI "QI") (VNx64QI "QI") (VNx128QI "QI") - (VNx1HI "HI") (VNx2HI "HI") (VNx4HI "HI") (VNx8HI "HI") (VNx16HI "HI") (VNx32HI "HI") (VNx64HI "HI") - (VNx1SI "SI") (VNx2SI "SI") (VNx4SI "SI") (VNx8SI "SI") (VNx16SI "SI") (VNx32SI "SI") - (VNx1DI "DI") (VNx2DI "DI") (VNx4DI "DI") (VNx8DI "DI") (VNx16DI "DI") - (VNx1HF "HF") (VNx2HF "HF") (VNx4HF "HF") (VNx8HF "HF") (VNx16HF "HF") (VNx32HF "HF") (VNx64HF "HF") - (VNx1SF "SF") (VNx2SF "SF") (VNx4SF "SF") (VNx8SF "SF") (VNx16SF "SF") (VNx32SF "SF") - (VNx1DF "DF") (VNx2DF "DF") (VNx4DF "DF") (VNx8DF "DF") (VNx16DF "DF") + (RVVM8QI "QI") (RVVM4QI "QI") (RVVM2QI "QI") (RVVM1QI "QI") (RVVMF2QI "QI") (RVVMF4QI "QI") (RVVMF8QI "QI") + + (RVVM8HI "HI") (RVVM4HI "HI") (RVVM2HI "HI") (RVVM1HI "HI") (RVVMF2HI "HI") (RVVMF4HI "HI") + + (RVVM8HF "HF") (RVVM4HF "HF") (RVVM2HF "HF") (RVVM1HF "HF") (RVVMF2HF "HF") (RVVMF4HF "HF") + + (RVVM8SI "SI") (RVVM4SI "SI") (RVVM2SI "SI") (RVVM1SI "SI") (RVVMF2SI "SI") + + (RVVM8SF "SF") (RVVM4SF "SF") (RVVM2SF "SF") (RVVM1SF "SF") (RVVMF2SF "SF") + + (RVVM8DI "DI") (RVVM4DI "DI") (RVVM2DI "DI") (RVVM1DI "DI") + + (RVVM8DF "DF") (RVVM4DF "DF") (RVVM2DF "DF") (RVVM1DF "DF") ]) (define_mode_attr vel [ - (VNx1QI "qi") (VNx2QI "qi") (VNx4QI "qi") (VNx8QI "qi") (VNx16QI "qi") (VNx32QI "qi") (VNx64QI "qi") (VNx128QI "qi") - (VNx1HI "hi") (VNx2HI "hi") (VNx4HI "hi") (VNx8HI "hi") (VNx16HI "hi") (VNx32HI "hi") (VNx64HI "hi") - (VNx1SI "si") (VNx2SI "si") (VNx4SI "si") (VNx8SI "si") (VNx16SI "si") (VNx32SI "si") - (VNx1DI "di") (VNx2DI "di") (VNx4DI "di") (VNx8DI "di") (VNx16DI "di") - (VNx1HF "hf") (VNx2HF "hf") (VNx4HF "hf") (VNx8HF "hf") (VNx16HF "hf") (VNx32HF "hf") (VNx64HF "hf") - (VNx1SF "sf") (VNx2SF "sf") (VNx4SF "sf") (VNx8SF "sf") (VNx16SF "sf") (VNx32SF "sf") - (VNx1DF "df") (VNx2DF "df") (VNx4DF "df") (VNx8DF "df") (VNx16DF "df") + (RVVM8QI "qi") (RVVM4QI "qi") (RVVM2QI "qi") (RVVM1QI "qi") (RVVMF2QI "qi") (RVVMF4QI "qi") (RVVMF8QI "qi") + + (RVVM8HI "hi") (RVVM4HI "hi") (RVVM2HI "hi") (RVVM1HI "hi") (RVVMF2HI "hi") (RVVMF4HI "hi") + + (RVVM8HF "hf") (RVVM4HF "hf") (RVVM2HF "hf") (RVVM1HF "hf") (RVVMF2HF "hf") (RVVMF4HF "hf") + + (RVVM8SI "si") (RVVM4SI "si") (RVVM2SI "si") (RVVM1SI "si") (RVVMF2SI "si") + + (RVVM8SF "sf") (RVVM4SF "sf") (RVVM2SF "sf") (RVVM1SF "sf") (RVVMF2SF "sf") + + (RVVM8DI "di") (RVVM4DI "di") (RVVM2DI "di") (RVVM1DI "di") + + (RVVM8DF "df") (RVVM4DF "df") (RVVM2DF "df") (RVVM1DF "df") ]) (define_mode_attr VSUBEL [ - (VNx1HI "QI") (VNx2HI "QI") (VNx4HI "QI") (VNx8HI "QI") (VNx16HI "QI") (VNx32HI "QI") (VNx64HI "QI") - (VNx1SI "HI") (VNx2SI "HI") (VNx4SI "HI") (VNx8SI "HI") (VNx16SI "HI") (VNx32SI "HI") - (VNx1DI "SI") (VNx2DI "SI") (VNx4DI "SI") (VNx8DI "SI") (VNx16DI "SI") - (VNx1SF "HF") (VNx2SF "HF") (VNx4SF "HF") (VNx8SF "HF") (VNx16SF "HF") (VNx32SF "HF") - (VNx1DF "SF") (VNx2DF "SF") (VNx4DF "SF") (VNx8DF "SF") (VNx16DF "SF") + (RVVM8HI "QI") (RVVM4HI "QI") (RVVM2HI "QI") (RVVM1HI "QI") (RVVMF2HI "QI") (RVVMF4HI "QI") + + (RVVM8SI "HI") (RVVM4SI "HI") (RVVM2SI "HI") (RVVM1SI "HI") (RVVMF2SI "HI") + + (RVVM8SF "HF") (RVVM4SF "HF") (RVVM2SF "HF") (RVVM1SF "HF") (RVVMF2SF "HF") + + (RVVM8DI "SI") (RVVM4DI "SI") (RVVM2DI "SI") (RVVM1DI "SI") + + (RVVM8DF "SF") (RVVM4DF "SF") (RVVM2DF "SF") (RVVM1DF "SF") ]) (define_mode_attr nf [ - (VNx2x64QI "2") (VNx2x32QI "2") (VNx3x32QI "3") (VNx4x32QI "4") - (VNx2x16QI "2") (VNx3x16QI "3") (VNx4x16QI "4") (VNx5x16QI "5") (VNx6x16QI "6") (VNx7x16QI "7") (VNx8x16QI "8") - (VNx2x8QI "2") (VNx3x8QI "3") (VNx4x8QI "4") (VNx5x8QI "5") (VNx6x8QI "6") (VNx7x8QI "7") (VNx8x8QI "8") - (VNx2x4QI "2") (VNx3x4QI "3") (VNx4x4QI "4") (VNx5x4QI "5") (VNx6x4QI "6") (VNx7x4QI "7") (VNx8x4QI "8") - (VNx2x2QI "2") (VNx3x2QI "3") (VNx4x2QI "4") (VNx5x2QI "5") (VNx6x2QI "6") (VNx7x2QI "7") (VNx8x2QI "8") - (VNx2x1QI "2") (VNx3x1QI "3") (VNx4x1QI "4") (VNx5x1QI "5") (VNx6x1QI "6") (VNx7x1QI "7") (VNx8x1QI "8") - (VNx2x32HI "2") (VNx2x16HI "2") (VNx3x16HI "3") (VNx4x16HI "4") - (VNx2x8HI "2") (VNx3x8HI "3") (VNx4x8HI "4") (VNx5x8HI "5") (VNx6x8HI "6") (VNx7x8HI "7") (VNx8x8HI "8") - (VNx2x4HI "2") (VNx3x4HI "3") (VNx4x4HI "4") (VNx5x4HI "5") (VNx6x4HI "6") (VNx7x4HI "7") (VNx8x4HI "8") - (VNx2x2HI "2") (VNx3x2HI "3") (VNx4x2HI "4") (VNx5x2HI "5") (VNx6x2HI "6") (VNx7x2HI "7") (VNx8x2HI "8") - (VNx2x1HI "2") (VNx3x1HI "3") (VNx4x1HI "4") (VNx5x1HI "5") (VNx6x1HI "6") (VNx7x1HI "7") (VNx8x1HI "8") - (VNx2x16SI "2") (VNx2x8SI "2") (VNx3x8SI "3") (VNx4x8SI "4") - (VNx2x4SI "2") (VNx3x4SI "3") (VNx4x4SI "4") (VNx5x4SI "5") (VNx6x4SI "6") (VNx7x4SI "7") (VNx8x4SI "8") - (VNx2x2SI "2") (VNx3x2SI "3") (VNx4x2SI "4") (VNx5x2SI "5") (VNx6x2SI "6") (VNx7x2SI "7") (VNx8x2SI "8") - (VNx2x1SI "2") (VNx3x1SI "3") (VNx4x1SI "4") (VNx5x1SI "5") (VNx6x1SI "6") (VNx7x1SI "7") (VNx8x1SI "8") - (VNx2x8DI "2") (VNx2x4DI "2") (VNx3x4DI "3") (VNx4x4DI "4") - (VNx2x2DI "2") (VNx3x2DI "3") (VNx4x2DI "4") (VNx5x2DI "5") (VNx6x2DI "6") (VNx7x2DI "7") (VNx8x2DI "8") - (VNx2x1DI "2") (VNx3x1DI "3") (VNx4x1DI "4") (VNx5x1DI "5") (VNx6x1DI "6") (VNx7x1DI "7") (VNx8x1DI "8") - (VNx2x16SF "2") (VNx2x8SF "2") (VNx3x8SF "3") (VNx4x8SF "4") - (VNx2x4SF "2") (VNx3x4SF "3") (VNx4x4SF "4") (VNx5x4SF "5") (VNx6x4SF "6") (VNx7x4SF "7") (VNx8x4SF "8") - (VNx2x2SF "2") (VNx3x2SF "3") (VNx4x2SF "4") (VNx5x2SF "5") (VNx6x2SF "6") (VNx7x2SF "7") (VNx8x2SF "8") - (VNx2x1SF "2") (VNx3x1SF "3") (VNx4x1SF "4") (VNx5x1SF "5") (VNx6x1SF "6") (VNx7x1SF "7") (VNx8x1SF "8") - (VNx2x8DF "2") - (VNx2x4DF "2") (VNx3x4DF "3") (VNx4x4DF "4") - (VNx2x2DF "2") (VNx3x2DF "3") (VNx4x2DF "4") (VNx5x2DF "5") (VNx6x2DF "6") (VNx7x2DF "7") (VNx8x2DF "8") - (VNx2x1DF "2") (VNx3x1DF "3") (VNx4x1DF "4") (VNx5x1DF "5") (VNx6x1DF "6") (VNx7x1DF "7") (VNx8x1DF "8") + (RVVM1x8QI "8") (RVVMF2x8QI "8") (RVVMF4x8QI "8") (RVVMF8x8QI "8") + (RVVM1x7QI "7") (RVVMF2x7QI "7") (RVVMF4x7QI "7") (RVVMF8x7QI "7") + (RVVM1x6QI "6") (RVVMF2x6QI "6") (RVVMF4x6QI "6") (RVVMF8x6QI "6") + (RVVM1x5QI "5") (RVVMF2x5QI "5") (RVVMF4x5QI "5") (RVVMF8x5QI "5") + (RVVM2x4QI "4") (RVVM1x4QI "4") (RVVMF2x4QI "4") (RVVMF4x4QI "4") (RVVMF8x4QI "4") + (RVVM2x3QI "3") (RVVM1x3QI "3") (RVVMF2x3QI "3") (RVVMF4x3QI "3") (RVVMF8x3QI "3") + (RVVM4x2QI "2") (RVVM2x2QI "2") (RVVM1x2QI "2") (RVVMF2x2QI "2") (RVVMF4x2QI "2") (RVVMF8x2QI "2") + + (RVVM1x8HI "8") (RVVMF2x8HI "8") (RVVMF4x8HI "8") + (RVVM1x7HI "7") (RVVMF2x7HI "7") (RVVMF4x7HI "7") + (RVVM1x6HI "6") (RVVMF2x6HI "6") (RVVMF4x6HI "6") + (RVVM1x5HI "5") (RVVMF2x5HI "5") (RVVMF4x5HI "5") + (RVVM2x4HI "4") (RVVM1x4HI "4") (RVVMF2x4HI "4") (RVVMF4x4HI "4") + (RVVM2x3HI "3") (RVVM1x3HI "3") (RVVMF2x3HI "3") (RVVMF4x3HI "3") + (RVVM4x2HI "2") (RVVM2x2HI "2") (RVVM1x2HI "2") (RVVMF2x2HI "2") (RVVMF4x2HI "2") + + (RVVM1x8HF "8") (RVVMF2x8HF "8") (RVVMF4x8HF "8") + (RVVM1x7HF "7") (RVVMF2x7HF "7") (RVVMF4x7HF "7") + (RVVM1x6HF "6") (RVVMF2x6HF "6") (RVVMF4x6HF "6") + (RVVM1x5HF "5") (RVVMF2x5HF "5") (RVVMF4x5HF "5") + (RVVM2x4HF "4") (RVVM1x4HF "4") (RVVMF2x4HF "4") (RVVMF4x4HF "4") + (RVVM2x3HF "3") (RVVM1x3HF "3") (RVVMF2x3HF "3") (RVVMF4x3HF "3") + (RVVM4x2HF "2") (RVVM2x2HF "2") (RVVM1x2HF "2") (RVVMF2x2HF "2") (RVVMF4x2HF "2") + + (RVVM1x8SI "8") (RVVMF2x8SI "8") + (RVVM1x7SI "7") (RVVMF2x7SI "7") + (RVVM1x6SI "6") (RVVMF2x6SI "6") + (RVVM1x5SI "5") (RVVMF2x5SI "5") + (RVVM2x4SI "4") (RVVM1x4SI "4") (RVVMF2x4SI "4") + (RVVM2x3SI "3") (RVVM1x3SI "3") (RVVMF2x3SI "3") + (RVVM4x2SI "2") (RVVM2x2SI "2") (RVVM1x2SI "2") (RVVMF2x2SI "2") + + (RVVM1x8SF "8") (RVVMF2x8SF "8") + (RVVM1x7SF "7") (RVVMF2x7SF "7") + (RVVM1x6SF "6") (RVVMF2x6SF "6") + (RVVM1x5SF "5") (RVVMF2x5SF "5") + (RVVM2x4SF "4") (RVVM1x4SF "4") (RVVMF2x4SF "4") + (RVVM2x3SF "3") (RVVM1x3SF "3") (RVVMF2x3SF "3") + (RVVM4x2SF "2") (RVVM2x2SF "2") (RVVM1x2SF "2") (RVVMF2x2SF "2") + + (RVVM1x8DI "8") + (RVVM1x7DI "7") + (RVVM1x6DI "6") + (RVVM1x5DI "5") + (RVVM2x4DI "4") + (RVVM1x4DI "4") + (RVVM2x3DI "3") + (RVVM1x3DI "3") + (RVVM4x2DI "2") + (RVVM2x2DI "2") + (RVVM1x2DI "2") + + (RVVM1x8DF "8") + (RVVM1x7DF "7") + (RVVM1x6DF "6") + (RVVM1x5DF "5") + (RVVM2x4DF "4") + (RVVM1x4DF "4") + (RVVM2x3DF "3") + (RVVM1x3DF "3") + (RVVM4x2DF "2") + (RVVM2x2DF "2") + (RVVM1x2DF "2") ]) (define_mode_attr sew [ - (VNx1QI "8") (VNx2QI "8") (VNx4QI "8") (VNx8QI "8") (VNx16QI "8") (VNx32QI "8") (VNx64QI "8") (VNx128QI "8") - (VNx1HI "16") (VNx2HI "16") (VNx4HI "16") (VNx8HI "16") (VNx16HI "16") (VNx32HI "16") (VNx64HI "16") - (VNx1SI "32") (VNx2SI "32") (VNx4SI "32") (VNx8SI "32") (VNx16SI "32") (VNx32SI "32") - (VNx1DI "64") (VNx2DI "64") (VNx4DI "64") (VNx8DI "64") (VNx16DI "64") - (VNx1HF "16") (VNx2HF "16") (VNx4HF "16") (VNx8HF "16") (VNx16HF "16") (VNx32HF "16") (VNx64HF "16") - (VNx1SF "32") (VNx2SF "32") (VNx4SF "32") (VNx8SF "32") (VNx16SF "32") (VNx32SF "32") - (VNx1DF "64") (VNx2DF "64") (VNx4DF "64") (VNx8DF "64") (VNx16DF "64") - (VNx2x64QI "8") (VNx2x32QI "8") (VNx3x32QI "8") (VNx4x32QI "8") - (VNx2x16QI "8") (VNx3x16QI "8") (VNx4x16QI "8") (VNx5x16QI "8") (VNx6x16QI "8") (VNx7x16QI "8") (VNx8x16QI "8") - (VNx2x8QI "8") (VNx3x8QI "8") (VNx4x8QI "8") (VNx5x8QI "8") (VNx6x8QI "8") (VNx7x8QI "8") (VNx8x8QI "8") - (VNx2x4QI "8") (VNx3x4QI "8") (VNx4x4QI "8") (VNx5x4QI "8") (VNx6x4QI "8") (VNx7x4QI "8") (VNx8x4QI "8") - (VNx2x2QI "8") (VNx3x2QI "8") (VNx4x2QI "8") (VNx5x2QI "8") (VNx6x2QI "8") (VNx7x2QI "8") (VNx8x2QI "8") - (VNx2x1QI "8") (VNx3x1QI "8") (VNx4x1QI "8") (VNx5x1QI "8") (VNx6x1QI "8") (VNx7x1QI "8") (VNx8x1QI "8") - (VNx2x32HI "16") (VNx2x16HI "16") (VNx3x16HI "16") (VNx4x16HI "16") - (VNx2x8HI "16") (VNx3x8HI "16") (VNx4x8HI "16") (VNx5x8HI "16") (VNx6x8HI "16") (VNx7x8HI "16") (VNx8x8HI "16") - (VNx2x4HI "16") (VNx3x4HI "16") (VNx4x4HI "16") (VNx5x4HI "16") (VNx6x4HI "16") (VNx7x4HI "16") (VNx8x4HI "16") - (VNx2x2HI "16") (VNx3x2HI "16") (VNx4x2HI "16") (VNx5x2HI "16") (VNx6x2HI "16") (VNx7x2HI "16") (VNx8x2HI "16") - (VNx2x1HI "16") (VNx3x1HI "16") (VNx4x1HI "16") (VNx5x1HI "16") (VNx6x1HI "16") (VNx7x1HI "16") (VNx8x1HI "16") - (VNx2x16SI "32") (VNx2x8SI "32") (VNx3x8SI "32") (VNx4x8SI "32") - (VNx2x4SI "32") (VNx3x4SI "32") (VNx4x4SI "32") (VNx5x4SI "32") (VNx6x4SI "32") (VNx7x4SI "32") (VNx8x4SI "32") - (VNx2x2SI "32") (VNx3x2SI "32") (VNx4x2SI "32") (VNx5x2SI "32") (VNx6x2SI "32") (VNx7x2SI "32") (VNx8x2SI "32") - (VNx2x1SI "32") (VNx3x1SI "32") (VNx4x1SI "32") (VNx5x1SI "32") (VNx6x1SI "32") (VNx7x1SI "32") (VNx8x1SI "32") - (VNx2x8DI "64") (VNx2x4DI "64") (VNx3x4DI "64") (VNx4x4DI "64") - (VNx2x2DI "64") (VNx3x2DI "64") (VNx4x2DI "64") (VNx5x2DI "64") (VNx6x2DI "64") (VNx7x2DI "64") (VNx8x2DI "64") - (VNx2x1DI "64") (VNx3x1DI "64") (VNx4x1DI "64") (VNx5x1DI "64") (VNx6x1DI "64") (VNx7x1DI "64") (VNx8x1DI "64") - (VNx2x16SF "32") (VNx2x8SF "32") (VNx3x8SF "32") (VNx4x8SF "32") - (VNx2x4SF "32") (VNx3x4SF "32") (VNx4x4SF "32") (VNx5x4SF "32") (VNx6x4SF "32") (VNx7x4SF "32") (VNx8x4SF "32") - (VNx2x2SF "32") (VNx3x2SF "32") (VNx4x2SF "32") (VNx5x2SF "32") (VNx6x2SF "32") (VNx7x2SF "32") (VNx8x2SF "32") - (VNx2x1SF "32") (VNx3x1SF "32") (VNx4x1SF "32") (VNx5x1SF "32") (VNx6x1SF "32") (VNx7x1SF "32") (VNx8x1SF "32") - (VNx2x8DF "64") - (VNx2x4DF "64") (VNx3x4DF "64") (VNx4x4DF "64") - (VNx2x2DF "64") (VNx3x2DF "64") (VNx4x2DF "64") (VNx5x2DF "64") (VNx6x2DF "64") (VNx7x2DF "64") (VNx8x2DF "64") - (VNx2x1DF "64") (VNx3x1DF "64") (VNx4x1DF "64") (VNx5x1DF "64") (VNx6x1DF "64") (VNx7x1DF "64") (VNx8x1DF "64") + (RVVM8QI "8") (RVVM4QI "8") (RVVM2QI "8") (RVVM1QI "8") (RVVMF2QI "8") (RVVMF4QI "8") (RVVMF8QI "8") + + (RVVM8HI "16") (RVVM4HI "16") (RVVM2HI "16") (RVVM1HI "16") (RVVMF2HI "16") (RVVMF4HI "16") + + (RVVM8HF "16") (RVVM4HF "16") (RVVM2HF "16") (RVVM1HF "16") (RVVMF2HF "16") (RVVMF4HF "16") + + (RVVM8SI "32") (RVVM4SI "32") (RVVM2SI "32") (RVVM1SI "32") (RVVMF2SI "32") + + (RVVM8SF "32") (RVVM4SF "32") (RVVM2SF "32") (RVVM1SF "32") (RVVMF2SF "32") + + (RVVM8DI "64") (RVVM4DI "64") (RVVM2DI "64") (RVVM1DI "64") + + (RVVM8DF "64") (RVVM4DF "64") (RVVM2DF "64") (RVVM1DF "64") + + (RVVM1x8QI "8") (RVVMF2x8QI "8") (RVVMF4x8QI "8") (RVVMF8x8QI "8") + (RVVM1x7QI "8") (RVVMF2x7QI "8") (RVVMF4x7QI "8") (RVVMF8x7QI "8") + (RVVM1x6QI "8") (RVVMF2x6QI "8") (RVVMF4x6QI "8") (RVVMF8x6QI "8") + (RVVM1x5QI "8") (RVVMF2x5QI "8") (RVVMF4x5QI "8") (RVVMF8x5QI "8") + (RVVM2x4QI "8") (RVVM1x4QI "8") (RVVMF2x4QI "8") (RVVMF4x4QI "8") (RVVMF8x4QI "8") + (RVVM2x3QI "8") (RVVM1x3QI "8") (RVVMF2x3QI "8") (RVVMF4x3QI "8") (RVVMF8x3QI "8") + (RVVM4x2QI "8") (RVVM2x2QI "8") (RVVM1x2QI "8") (RVVMF2x2QI "8") (RVVMF4x2QI "8") (RVVMF8x2QI "8") + + (RVVM1x8HI "16") (RVVMF2x8HI "16") (RVVMF4x8HI "16") + (RVVM1x7HI "16") (RVVMF2x7HI "16") (RVVMF4x7HI "16") + (RVVM1x6HI "16") (RVVMF2x6HI "16") (RVVMF4x6HI "16") + (RVVM1x5HI "16") (RVVMF2x5HI "16") (RVVMF4x5HI "16") + (RVVM2x4HI "16") (RVVM1x4HI "16") (RVVMF2x4HI "16") (RVVMF4x4HI "16") + (RVVM2x3HI "16") (RVVM1x3HI "16") (RVVMF2x3HI "16") (RVVMF4x3HI "16") + (RVVM4x2HI "16") (RVVM2x2HI "16") (RVVM1x2HI "16") (RVVMF2x2HI "16") (RVVMF4x2HI "16") + + (RVVM1x8HF "16") (RVVMF2x8HF "16") (RVVMF4x8HF "16") + (RVVM1x7HF "16") (RVVMF2x7HF "16") (RVVMF4x7HF "16") + (RVVM1x6HF "16") (RVVMF2x6HF "16") (RVVMF4x6HF "16") + (RVVM1x5HF "16") (RVVMF2x5HF "16") (RVVMF4x5HF "16") + (RVVM2x4HF "16") (RVVM1x4HF "16") (RVVMF2x4HF "16") (RVVMF4x4HF "16") + (RVVM2x3HF "16") (RVVM1x3HF "16") (RVVMF2x3HF "16") (RVVMF4x3HF "16") + (RVVM4x2HF "16") (RVVM2x2HF "16") (RVVM1x2HF "16") (RVVMF2x2HF "16") (RVVMF4x2HF "16") + + (RVVM1x8SI "32") (RVVMF2x8SI "32") + (RVVM1x7SI "32") (RVVMF2x7SI "32") + (RVVM1x6SI "32") (RVVMF2x6SI "32") + (RVVM1x5SI "32") (RVVMF2x5SI "32") + (RVVM2x4SI "32") (RVVM1x4SI "32") (RVVMF2x4SI "32") + (RVVM2x3SI "32") (RVVM1x3SI "32") (RVVMF2x3SI "32") + (RVVM4x2SI "32") (RVVM2x2SI "32") (RVVM1x2SI "32") (RVVMF2x2SI "32") + + (RVVM1x8SF "32") (RVVMF2x8SF "32") + (RVVM1x7SF "32") (RVVMF2x7SF "32") + (RVVM1x6SF "32") (RVVMF2x6SF "32") + (RVVM1x5SF "32") (RVVMF2x5SF "32") + (RVVM2x4SF "32") (RVVM1x4SF "32") (RVVMF2x4SF "32") + (RVVM2x3SF "32") (RVVM1x3SF "32") (RVVMF2x3SF "32") + (RVVM4x2SF "32") (RVVM2x2SF "32") (RVVM1x2SF "32") (RVVMF2x2SF "32") + + (RVVM1x8DI "64") + (RVVM1x7DI "64") + (RVVM1x6DI "64") + (RVVM1x5DI "64") + (RVVM2x4DI "64") + (RVVM1x4DI "64") + (RVVM2x3DI "64") + (RVVM1x3DI "64") + (RVVM4x2DI "64") + (RVVM2x2DI "64") + (RVVM1x2DI "64") + + (RVVM1x8DF "64") + (RVVM1x7DF "64") + (RVVM1x6DF "64") + (RVVM1x5DF "64") + (RVVM2x4DF "64") + (RVVM1x4DF "64") + (RVVM2x3DF "64") + (RVVM1x3DF "64") + (RVVM4x2DF "64") + (RVVM2x2DF "64") + (RVVM1x2DF "64") ]) (define_mode_attr double_trunc_sew [ - (VNx1HI "8") (VNx2HI "8") (VNx4HI "8") (VNx8HI "8") (VNx16HI "8") (VNx32HI "8") (VNx64HI "8") - (VNx1SI "16") (VNx2SI "16") (VNx4SI "16") (VNx8SI "16") (VNx16SI "16") (VNx32SI "16") - (VNx1DI "32") (VNx2DI "32") (VNx4DI "32") (VNx8DI "32") (VNx16DI "32") - (VNx1SF "16") (VNx2SF "16") (VNx4SF "16") (VNx8SF "16") (VNx16SF "16") (VNx32SF "16") - (VNx1DF "32") (VNx2DF "32") (VNx4DF "32") (VNx8DF "32") (VNx16DF "32") + (RVVM8HI "8") (RVVM4HI "8") (RVVM2HI "8") (RVVM1HI "8") (RVVMF2HI "8") (RVVMF4HI "8") + + (RVVM8HF "8") (RVVM4HF "8") (RVVM2HF "8") (RVVM1HF "8") (RVVMF2HF "8") (RVVMF4HF "8") + + (RVVM8SI "16") (RVVM4SI "16") (RVVM2SI "16") (RVVM1SI "16") (RVVMF2SI "16") + + (RVVM8SF "16") (RVVM4SF "16") (RVVM2SF "16") (RVVM1SF "16") (RVVMF2SF "16") + + (RVVM8DI "32") (RVVM4DI "32") (RVVM2DI "32") (RVVM1DI "32") + + (RVVM8DF "32") (RVVM4DF "32") (RVVM2DF "32") (RVVM1DF "32") ]) (define_mode_attr quad_trunc_sew [ - (VNx1SI "8") (VNx2SI "8") (VNx4SI "8") (VNx8SI "8") (VNx16SI "8") (VNx32SI "8") - (VNx1DI "16") (VNx2DI "16") (VNx4DI "16") (VNx8DI "16") (VNx16DI "16") - (VNx1SF "8") (VNx2SF "8") (VNx4SF "8") (VNx8SF "8") (VNx16SF "8") (VNx32SF "8") - (VNx1DF "16") (VNx2DF "16") (VNx4DF "16") (VNx8DF "16") (VNx16DF "16") + (RVVM8SI "8") (RVVM4SI "8") (RVVM2SI "8") (RVVM1SI "8") (RVVMF2SI "8") + + (RVVM8SF "8") (RVVM4SF "8") (RVVM2SF "8") (RVVM1SF "8") (RVVMF2SF "8") + + (RVVM8DI "16") (RVVM4DI "16") (RVVM2DI "16") (RVVM1DI "16") + + (RVVM8DF "16") (RVVM4DF "16") (RVVM2DF "16") (RVVM1DF "16") ]) (define_mode_attr oct_trunc_sew [ - (VNx1DI "8") (VNx2DI "8") (VNx4DI "8") (VNx8DI "8") (VNx16DI "8") - (VNx1DF "8") (VNx2DF "8") (VNx4DF "8") (VNx8DF "8") (VNx16DF "8") + (RVVM8DI "8") (RVVM4DI "8") (RVVM2DI "8") (RVVM1DI "8") + + (RVVM8DF "8") (RVVM4DF "8") (RVVM2DF "8") (RVVM1DF "8") ]) (define_mode_attr double_ext_sew [ - (VNx1QI "16") (VNx2QI "16") (VNx4QI "16") (VNx8QI "16") (VNx16QI "16") (VNx32QI "16") (VNx64QI "16") - (VNx1HI "32") (VNx2HI "32") (VNx4HI "32") (VNx8HI "32") (VNx16HI "32") (VNx32HI "32") - (VNx1SI "64") (VNx2SI "64") (VNx4SI "64") (VNx8SI "64") (VNx16SI "64") - (VNx1SF "64") (VNx2SF "64") (VNx4SF "64") (VNx8SF "64") (VNx16SF "64") + (RVVM4QI "16") (RVVM2QI "16") (RVVM1QI "16") (RVVMF2QI "16") (RVVMF4QI "16") (RVVMF8QI "16") + + (RVVM4HI "32") (RVVM2HI "32") (RVVM1HI "32") (RVVMF2HI "32") (RVVMF4HI "32") + + (RVVM4HF "32") (RVVM2HF "32") (RVVM1HF "32") (RVVMF2HF "32") (RVVMF4HF "32") + + (RVVM4SI "64") (RVVM2SI "64") (RVVM1SI "64") (RVVMF2SI "64") + + (RVVM4SF "64") (RVVM2SF "64") (RVVM1SF "64") (RVVMF2SF "64") ]) (define_mode_attr quad_ext_sew [ - (VNx1QI "32") (VNx2QI "32") (VNx4QI "32") (VNx8QI "32") (VNx16QI "32") (VNx32QI "32") - (VNx1HI "64") (VNx2HI "64") (VNx4HI "64") (VNx8HI "64") (VNx16HI "64") + (RVVM2QI "32") (RVVM1QI "32") (RVVMF2QI "32") (RVVMF4QI "32") (RVVMF8QI "32") + + (RVVM2HI "64") (RVVM1HI "64") (RVVMF2HI "64") (RVVMF4HI "64") + + (RVVM2HF "64") (RVVM1HF "64") (RVVMF2HF "64") (RVVMF4HF "64") ]) (define_mode_attr oct_ext_sew [ - (VNx1QI "64") (VNx2QI "64") (VNx4QI "64") (VNx8QI "64") (VNx16QI "64") + (RVVM1QI "64") (RVVMF2QI "64") (RVVMF4QI "64") (RVVMF8QI "64") ]) (define_mode_attr V_DOUBLE_TRUNC [ - (VNx1HI "VNx1QI") (VNx2HI "VNx2QI") (VNx4HI "VNx4QI") (VNx8HI "VNx8QI") - (VNx16HI "VNx16QI") (VNx32HI "VNx32QI") (VNx64HI "VNx64QI") - (VNx1SI "VNx1HI") (VNx2SI "VNx2HI") (VNx4SI "VNx4HI") (VNx8SI "VNx8HI") - (VNx16SI "VNx16HI") (VNx32SI "VNx32HI") - (VNx1DI "VNx1SI") (VNx2DI "VNx2SI") (VNx4DI "VNx4SI") (VNx8DI "VNx8SI") - (VNx16DI "VNx16SI") + (RVVM8HI "RVVM4QI") (RVVM4HI "RVVM2QI") (RVVM2HI "RVVM1QI") (RVVM1HI "RVVMF2QI") (RVVMF2HI "RVVMF4QI") (RVVMF4HI "RVVMF8QI") + + (RVVM8SI "RVVM4HI") (RVVM4SI "RVVM2HI") (RVVM2SI "RVVM1HI") (RVVM1SI "RVVMF2HI") (RVVMF2SI "RVVMF4HI") + + (RVVM8SF "RVVM4HF") (RVVM4SF "RVVM2HF") (RVVM2SF "RVVM1HF") (RVVM1SF "RVVMF2HF") (RVVMF2SF "RVVMF4HF") - (VNx1SF "VNx1HF") (VNx2SF "VNx2HF") (VNx4SF "VNx4HF") (VNx8SF "VNx8HF") (VNx16SF "VNx16HF") (VNx32SF "VNx32HF") - (VNx1DF "VNx1SF") (VNx2DF "VNx2SF") (VNx4DF "VNx4SF") (VNx8DF "VNx8SF") - (VNx16DF "VNx16SF") + (RVVM8DI "RVVM4SI") (RVVM4DI "RVVM2SI") (RVVM2DI "RVVM1SI") (RVVM1DI "RVVMF2SI") + + (RVVM8DF "RVVM4SF") (RVVM4DF "RVVM2SF") (RVVM2DF "RVVM1SF") (RVVM1DF "RVVMF2SF") ]) (define_mode_attr V_QUAD_TRUNC [ - (VNx1SI "VNx1QI") (VNx2SI "VNx2QI") (VNx4SI "VNx4QI") (VNx8SI "VNx8QI") - (VNx16SI "VNx16QI") (VNx32SI "VNx32QI") - (VNx1DI "VNx1HI") (VNx2DI "VNx2HI") - (VNx4DI "VNx4HI") (VNx8DI "VNx8HI") (VNx16DI "VNx16HI") + (RVVM8SI "RVVM2QI") (RVVM4SI "RVVM1QI") (RVVM2SI "RVVMF2QI") (RVVM1SI "RVVMF4QI") (RVVMF2SI "RVVMF8QI") + + (RVVM8DI "RVVM2HI") (RVVM4DI "RVVM1HI") (RVVM2DI "RVVMF2HI") (RVVM1DI "RVVMF4HI") - (VNx1DF "VNx1HF") (VNx2DF "VNx2HF") (VNx4DF "VNx4HF") (VNx8DF "VNx8HF") - (VNx16DF "VNx16HF") + (RVVM8DF "RVVM2HF") (RVVM4DF "RVVM1HF") (RVVM2DF "RVVMF2HF") (RVVM1DF "RVVMF4HF") ]) (define_mode_attr V_OCT_TRUNC [ - (VNx1DI "VNx1QI") (VNx2DI "VNx2QI") (VNx4DI "VNx4QI") (VNx8DI "VNx8QI") - (VNx16DI "VNx16QI") + (RVVM8DI "RVVM1QI") (RVVM4DI "RVVMF2QI") (RVVM2DI "RVVMF4QI") (RVVM1DI "RVVMF8QI") ]) ; Again in lower case. (define_mode_attr v_double_trunc [ - (VNx1HI "vnx1qi") (VNx2HI "vnx2qi") (VNx4HI "vnx4qi") (VNx8HI "vnx8qi") - (VNx16HI "vnx16qi") (VNx32HI "vnx32qi") (VNx64HI "vnx64qi") - (VNx1SI "vnx1hi") (VNx2SI "vnx2hi") (VNx4SI "vnx4hi") (VNx8SI "vnx8hi") - (VNx16SI "vnx16hi") (VNx32SI "vnx32hi") - (VNx1DI "vnx1si") (VNx2DI "vnx2si") (VNx4DI "vnx4si") (VNx8DI "vnx8si") - (VNx16DI "vnx16si") - (VNx1SF "vnx1hf") (VNx2SF "vnx2hf") (VNx4SF "vnx4hf") (VNx8SF "vnx8hf") (VNx16SF "vnx16hf") (VNx32SF "vnx32hf") - (VNx1DF "vnx1sf") (VNx2DF "vnx2sf") (VNx4DF "vnx4sf") (VNx8DF "vnx8sf") - (VNx16DF "vnx16sf") + (RVVM8HI "rvvm4qi") (RVVM4HI "rvvm2qi") (RVVM2HI "rvvm1qi") (RVVM1HI "rvvmf2qi") (RVVMF2HI "rvvmf4qi") (RVVMF4HI "rvvmf8qi") + + (RVVM8SI "rvvm4hi") (RVVM4SI "rvvm2hi") (RVVM2SI "rvvm1hi") (RVVM1SI "rvvmf2hi") (RVVMF2SI "rvvmf4hi") + + (RVVM8SF "rvvm4hf") (RVVM4SF "rvvm2hf") (RVVM2SF "rvvm1hf") (RVVM1SF "rvvmf2hf") (RVVMF2SF "rvvmf4hf") + + (RVVM8DI "rvvm4si") (RVVM4DI "rvvm2si") (RVVM2DI "rvvm1si") (RVVM1DI "rvvmf2si") + + (RVVM8DF "rvvm4sf") (RVVM4DF "rvvm2sf") (RVVM2DF "rvvm1sf") (RVVM1DF "rvvmf2sf") ]) (define_mode_attr v_quad_trunc [ - (VNx1SI "vnx1qi") (VNx2SI "vnx2qi") (VNx4SI "vnx4qi") (VNx8SI "vnx8qi") - (VNx16SI "vnx16qi") (VNx32SI "vnx32qi") - (VNx1DI "vnx1hi") (VNx2DI "vnx2hi") (VNx4DI "vnx4hi") (VNx8DI "vnx8hi") - (VNx16DI "vnx16hi") + (RVVM8SI "rvvm2qi") (RVVM4SI "rvvm1qi") (RVVM2SI "rvvmf2qi") (RVVM1SI "rvvmf4qi") (RVVMF2SI "rvvmf8qi") + + (RVVM8DI "rvvm2hi") (RVVM4DI "rvvm1hi") (RVVM2DI "rvvmf2hi") (RVVM1DI "rvvmf4hi") - (VNx1DF "vnx1hf") (VNx2DF "vnx2hf") (VNx4DF "vnx4hf") (VNx8DF "vnx8hf") - (VNx16DF "vnx16hf") + (RVVM8DF "rvvm2hf") (RVVM4DF "rvvm1hf") (RVVM2DF "rvvmf2hf") (RVVM1DF "rvvmf4hf") ]) (define_mode_attr v_oct_trunc [ - (VNx1DI "vnx1qi") (VNx2DI "vnx2qi") (VNx4DI "vnx4qi") (VNx8DI "vnx8qi") - (VNx16DI "vnx16qi") + (RVVM8DI "rvvm1qi") (RVVM4DI "rvvmf2qi") (RVVM2DI "rvvmf4qi") (RVVM1DI "rvvmf8qi") ]) (define_mode_attr VINDEX_DOUBLE_TRUNC [ - (VNx1HI "VNx1QI") (VNx2HI "VNx2QI") (VNx4HI "VNx4QI") (VNx8HI "VNx8QI") - (VNx16HI "VNx16QI") (VNx32HI "VNx32QI") (VNx64HI "VNx64QI") - (VNx1HF "VNx1QI") (VNx2HF "VNx2QI") (VNx4HF "VNx4QI") (VNx8HF "VNx8QI") - (VNx16HF "VNx16QI") (VNx32HF "VNx32QI") (VNx64HF "VNx64QI") - (VNx1SI "VNx1HI") (VNx2SI "VNx2HI") (VNx4SI "VNx4HI") (VNx8SI "VNx8HI") - (VNx16SI "VNx16HI") (VNx32SI "VNx32HI") - (VNx1SF "VNx1HI") (VNx2SF "VNx2HI") (VNx4SF "VNx4HI") (VNx8SF "VNx8HI") - (VNx16SF "VNx16HI") (VNx32SF "VNx32HI") - (VNx1DI "VNx1SI") (VNx2DI "VNx2SI") (VNx4DI "VNx4SI") (VNx8DI "VNx8SI") (VNx16DI "VNx16SI") - (VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI") (VNx16DF "VNx16SI") + (RVVM8HI "RVVM4QI") (RVVM4HI "RVVM2QI") (RVVM2HI "RVVM1QI") (RVVM1HI "RVVMF2QI") (RVVMF2HI "RVVMF4QI") (RVVMF4HI "RVVMF8QI") + + (RVVM8HF "RVVM4QI") (RVVM4HF "RVVM2QI") (RVVM2HF "RVVM1QI") (RVVM1HF "RVVMF2QI") (RVVMF2HF "RVVMF4QI") (RVVMF4HF "RVVMF8QI") + + (RVVM8SI "RVVM4HI") (RVVM4SI "RVVM2HI") (RVVM2SI "RVVM1HI") (RVVM1SI "RVVMF2HI") (RVVMF2SI "RVVMF4HI") + + (RVVM8SF "RVVM4HI") (RVVM4SF "RVVM2HI") (RVVM2SF "RVVM1HI") (RVVM1SF "RVVMF2HI") (RVVMF2SF "RVVMF4HI") + + (RVVM8DI "RVVM4SI") (RVVM4DI "RVVM2SI") (RVVM2DI "RVVM1SI") (RVVM1DI "RVVMF2SI") + + (RVVM8DF "RVVM4SI") (RVVM4DF "RVVM2SI") (RVVM2DF "RVVM1SI") (RVVM1DF "RVVMF2SI") ]) (define_mode_attr VINDEX_QUAD_TRUNC [ - (VNx1SI "VNx1QI") (VNx2SI "VNx2QI") (VNx4SI "VNx4QI") (VNx8SI "VNx8QI") - (VNx16SI "VNx16QI") (VNx32SI "VNx32QI") - (VNx1DI "VNx1HI") (VNx2DI "VNx2HI") - (VNx4DI "VNx4HI") (VNx8DI "VNx8HI") (VNx16DI "VNx16HI") - (VNx1SF "VNx1QI") (VNx2SF "VNx2QI") (VNx4SF "VNx4QI") (VNx8SF "VNx8QI") - (VNx16SF "VNx16QI") (VNx32SF "VNx32QI") - (VNx1DF "VNx1HI") (VNx2DF "VNx2HI") - (VNx4DF "VNx4HI") (VNx8DF "VNx8HI") (VNx16DF "VNx16HI") + (RVVM8SI "RVVM2QI") (RVVM4SI "RVVM1QI") (RVVM2SI "RVVMF2QI") (RVVM1SI "RVVMF4QI") (RVVMF2SI "RVVMF8QI") + + (RVVM8SF "RVVM2QI") (RVVM4SF "RVVM1QI") (RVVM2SF "RVVMF2QI") (RVVM1SF "RVVMF4QI") (RVVMF2SF "RVVMF8QI") + + (RVVM8DI "RVVM2HI") (RVVM4DI "RVVM1HI") (RVVM2DI "RVVMF2HI") (RVVM1DI "RVVMF4HI") + + (RVVM8DF "RVVM2HI") (RVVM4DF "RVVM1HI") (RVVM2DF "RVVMF2HI") (RVVM1DF "RVVMF4HI") ]) (define_mode_attr VINDEX_OCT_TRUNC [ - (VNx1DI "VNx1QI") (VNx2DI "VNx2QI") (VNx4DI "VNx4QI") (VNx8DI "VNx8QI") (VNx16DI "VNx16QI") - (VNx1DF "VNx1QI") (VNx2DF "VNx2QI") (VNx4DF "VNx4QI") (VNx8DF "VNx8QI") (VNx16DF "VNx16QI") + (RVVM8DI "RVVM1QI") (RVVM4DI "RVVMF2QI") (RVVM2DI "RVVMF4QI") (RVVM1DI "RVVMF8QI") + + (RVVM8DF "RVVM1QI") (RVVM4DF "RVVMF2QI") (RVVM2DF "RVVMF4QI") (RVVM1DF "RVVMF8QI") ]) (define_mode_attr VINDEX_DOUBLE_EXT [ - (VNx1QI "VNx1HI") (VNx2QI "VNx2HI") (VNx4QI "VNx4HI") (VNx8QI "VNx8HI") (VNx16QI "VNx16HI") (VNx32QI "VNx32HI") (VNx64QI "VNx64HI") - (VNx1HI "VNx1SI") (VNx2HI "VNx2SI") (VNx4HI "VNx4SI") (VNx8HI "VNx8SI") (VNx16HI "VNx16SI") (VNx32HI "VNx32SI") - (VNx1HF "VNx1SI") (VNx2HF "VNx2SI") (VNx4HF "VNx4SI") (VNx8HF "VNx8SI") (VNx16HF "VNx16SI") (VNx32HF "VNx32SI") - (VNx1SI "VNx1DI") (VNx2SI "VNx2DI") (VNx4SI "VNx4DI") (VNx8SI "VNx8DI") (VNx16SI "VNx16DI") - (VNx1SF "VNx1DI") (VNx2SF "VNx2DI") (VNx4SF "VNx4DI") (VNx8SF "VNx8DI") (VNx16SF "VNx16DI") + (RVVM4QI "RVVM8HI") (RVVM2QI "RVVM4HI") (RVVM1QI "RVVM2HI") (RVVMF2QI "RVVM1HI") (RVVMF4QI "RVVMF2HI") (RVVMF8QI "RVVMF4HI") + + (RVVM4HI "RVVM8SI") (RVVM2HI "RVVM4SI") (RVVM1HI "RVVM2SI") (RVVMF2HI "RVVM1SI") (RVVMF4HI "RVVMF2SI") + + (RVVM4HF "RVVM8SI") (RVVM2HF "RVVM4SI") (RVVM1HF "RVVM2SI") (RVVMF2HF "RVVM1SI") (RVVMF4HF "RVVMF2SI") + + (RVVM4SI "RVVM8DI") (RVVM2SI "RVVM4DI") (RVVM1SI "RVVM2DI") (RVVMF2SI "RVVM1DI") + + (RVVM4SF "RVVM8DI") (RVVM2SF "RVVM4DI") (RVVM1SF "RVVM2DI") (RVVMF2SF "RVVM1DI") ]) (define_mode_attr VINDEX_QUAD_EXT [ - (VNx1QI "VNx1SI") (VNx2QI "VNx2SI") (VNx4QI "VNx4SI") (VNx8QI "VNx8SI") (VNx16QI "VNx16SI") (VNx32QI "VNx32SI") - (VNx1HI "VNx1DI") (VNx2HI "VNx2DI") (VNx4HI "VNx4DI") (VNx8HI "VNx8DI") (VNx16HI "VNx16DI") - (VNx1HF "VNx1DI") (VNx2HF "VNx2DI") (VNx4HF "VNx4DI") (VNx8HF "VNx8DI") (VNx16HF "VNx16DI") + (RVVM2QI "RVVM8SI") (RVVM1QI "RVVM4SI") (RVVMF2QI "RVVM2SI") (RVVMF4QI "RVVM1SI") (RVVMF8QI "RVVMF2SI") + + (RVVM2HI "RVVM8DI") (RVVM1HI "RVVM4DI") (RVVMF2HI "RVVM2DI") (RVVMF4HI "RVVM1DI") + + (RVVM2HF "RVVM8DI") (RVVM1HF "RVVM4DI") (RVVMF2HF "RVVM2DI") (RVVMF4HF "RVVM1DI") ]) (define_mode_attr VINDEX_OCT_EXT [ - (VNx1QI "VNx1DI") (VNx2QI "VNx2DI") (VNx4QI "VNx4DI") (VNx8QI "VNx8DI") (VNx16QI "VNx16DI") + (RVVM1QI "RVVM8DI") (RVVMF2QI "RVVM4DI") (RVVMF4QI "RVVM2DI") (RVVMF8QI "RVVM1DI") ]) (define_mode_attr VCONVERT [ - (VNx1HF "VNx1HI") (VNx2HF "VNx2HI") (VNx4HF "VNx4HI") (VNx8HF "VNx8HI") (VNx16HF "VNx16HI") (VNx32HF "VNx32HI") (VNx64HF "VNx64HI") - (VNx1SF "VNx1SI") (VNx2SF "VNx2SI") (VNx4SF "VNx4SI") (VNx8SF "VNx8SI") (VNx16SF "VNx16SI") (VNx32SF "VNx32SI") - (VNx1DF "VNx1DI") (VNx2DF "VNx2DI") (VNx4DF "VNx4DI") (VNx8DF "VNx8DI") (VNx16DF "VNx16DI") + (RVVM8HF "RVVM8HI") (RVVM4HF "RVVM4HI") (RVVM2HF "RVVM2HI") (RVVM1HF "RVVM1HI") (RVVMF2HF "RVVMF2HI") (RVVMF4HF "RVVMF4HI") + (RVVM8SF "RVVM8SI") (RVVM4SF "RVVM4SI") (RVVM2SF "RVVM2SI") (RVVM1SF "RVVM1SI") (RVVMF2SF "RVVMF2SI") + (RVVM8DF "RVVM8DI") (RVVM4DF "RVVM4DI") (RVVM2DF "RVVM2DI") (RVVM1DF "RVVM1DI") ]) (define_mode_attr vconvert [ - (VNx1HF "vnx1hi") (VNx2HF "vnx2hi") (VNx4HF "vnx4hi") (VNx8HF "vnx8hi") (VNx16HF "vnx16hi") (VNx32HF "vnx32hi") (VNx64HF "vnx64hi") - (VNx1SF "vnx1si") (VNx2SF "vnx2si") (VNx4SF "vnx4si") (VNx8SF "vnx8si") (VNx16SF "vnx16si") (VNx32SF "vnx32si") - (VNx1DF "vnx1di") (VNx2DF "vnx2di") (VNx4DF "vnx4di") (VNx8DF "vnx8di") (VNx16DF "vnx16di") + (RVVM8HF "rvvm8hi") (RVVM4HF "rvvm4hi") (RVVM2HF "rvvm2hi") (RVVM1HF "rvvm1hi") (RVVMF2HF "rvvmf2hi") (RVVMF4HF "rvvmf4hi") + (RVVM8SF "rvvm8si") (RVVM4SF "rvvm4si") (RVVM2SF "rvvm2si") (RVVM1SF "rvvm1si") (RVVMF2SF "rvvmf2si") + (RVVM8DF "rvvm8di") (RVVM4DF "rvvm4di") (RVVM2DF "rvvm2di") (RVVM1DF "rvvm1di") ]) (define_mode_attr VNCONVERT [ - (VNx1HF "VNx1QI") (VNx2HF "VNx2QI") (VNx4HF "VNx4QI") (VNx8HF "VNx8QI") (VNx16HF "VNx16QI") (VNx32HF "VNx32QI") (VNx64HF "VNx64QI") - (VNx1SF "VNx1HI") (VNx2SF "VNx2HI") (VNx4SF "VNx4HI") (VNx8SF "VNx8HI") (VNx16SF "VNx16HI") (VNx32SF "VNx32HI") - (VNx1SI "VNx1HF") (VNx2SI "VNx2HF") (VNx4SI "VNx4HF") (VNx8SI "VNx8HF") (VNx16SI "VNx16HF") (VNx32SI "VNx32HF") - (VNx1DI "VNx1SF") (VNx2DI "VNx2SF") (VNx4DI "VNx4SF") (VNx8DI "VNx8SF") (VNx16DI "VNx16SF") - (VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI") (VNx16DF "VNx16SI") + (RVVM8HF "RVVM4QI") (RVVM4HF "RVVM2QI") (RVVM2HF "RVVM1QI") (RVVM1HF "RVVMF2QI") (RVVMF2HF "RVVMF4QI") (RVVMF4HF "RVVMF8QI") + + (RVVM8SI "RVVM4HF") (RVVM4SI "RVVM2HF") (RVVM2SI "RVVM1HF") (RVVM1SI "RVVMF2HF") (RVVMF2SI "RVVMF4HF") + (RVVM8SF "RVVM4HI") (RVVM4SF "RVVM2HI") (RVVM2SF "RVVM1HI") (RVVM1SF "RVVMF2HI") (RVVMF2SF "RVVMF4HI") + + (RVVM8DI "RVVM4SF") (RVVM4DI "RVVM2SF") (RVVM2DI "RVVM1SF") (RVVM1DI "RVVMF2SF") + (RVVM8DF "RVVM4SI") (RVVM4DF "RVVM2SI") (RVVM2DF "RVVM1SI") (RVVM1DF "RVVMF2SI") ]) (define_mode_attr vnconvert [ - (VNx1HF "vnx1qi") (VNx2HF "vnx2qi") (VNx4HF "vnx4qi") (VNx8HF "vnx8qi") (VNx16HF "vnx16qi") (VNx32HF "vnx32qi") (VNx64HF "vnx64qi") - (VNx1SF "vnx1hi") (VNx2SF "vnx2hi") (VNx4SF "vnx4hi") (VNx8SF "vnx8hi") (VNx16SF "vnx16hi") (VNx32SF "vnx32hi") - (VNx1SI "vnx1hf") (VNx2SI "vnx2hf") (VNx4SI "vnx4hf") (VNx8SI "vnx8hf") (VNx16SI "vnx16hf") (VNx32SI "vnx32hf") - (VNx1DI "vnx1sf") (VNx2DI "vnx2sf") (VNx4DI "vnx4sf") (VNx8DI "vnx8sf") (VNx16DI "vnx16sf") - (VNx1DF "vnx1si") (VNx2DF "vnx2si") (VNx4DF "vnx4si") (VNx8DF "vnx8si") (VNx16DF "vnx16si") + (RVVM8HF "rvvm4qi") (RVVM4HF "rvvm2qi") (RVVM2HF "rvvm1qi") (RVVM1HF "rvvmf2qi") (RVVMF2HF "rvvmf4qi") (RVVMF4HF "rvvmf8qi") + + (RVVM8SI "rvvm4hf") (RVVM4SI "rvvm2hf") (RVVM2SI "rvvm1hf") (RVVM1SI "rvvmf2hf") (RVVMF2SI "rvvmf4hf") + (RVVM8SF "rvvm4hi") (RVVM4SF "rvvm2hi") (RVVM2SF "rvvm1hi") (RVVM1SF "rvvmf2hi") (RVVMF2SF "rvvmf4hi") + + (RVVM8DI "rvvm4sf") (RVVM4DI "rvvm2sf") (RVVM2DI "rvvm1sf") (RVVM1DI "rvvmf2sf") + (RVVM8DF "rvvm4si") (RVVM4DF "rvvm2si") (RVVM2DF "rvvm1si") (RVVM1DF "rvvmf2si") ]) (define_mode_attr VDEMOTE [ - (VNx1DI "VNx2SI") (VNx2DI "VNx4SI") - (VNx4DI "VNx8SI") (VNx8DI "VNx16SI") (VNx16DI "VNx32SI") + (RVVM8DI "RVVM8SI") (RVVM4DI "RVVM4SI") (RVVM2DI "RVVM2SI") (RVVM1DI "RVVM1SI") ]) (define_mode_attr VMDEMOTE [ - (VNx1DI "VNx2BI") (VNx2DI "VNx4BI") - (VNx4DI "VNx8BI") (VNx8DI "VNx16BI") (VNx16DI "VNx32BI") + (RVVM8DI "RVVMF4BI") (RVVM4DI "RVVMF8BI") (RVVM2DI "RVVMF16BI") (RVVM1DI "RVVMF32BI") ]) (define_mode_attr gs_extension [ - (VNx1QI "immediate_operand") (VNx2QI "immediate_operand") (VNx4QI "immediate_operand") (VNx8QI "immediate_operand") (VNx16QI "immediate_operand") - (VNx32QI "vector_gs_extension_operand") (VNx64QI "const_1_operand") - (VNx1HI "immediate_operand") (VNx2HI "immediate_operand") (VNx4HI "immediate_operand") (VNx8HI "immediate_operand") (VNx16HI "immediate_operand") - (VNx32HI "vector_gs_extension_operand") (VNx64HI "const_1_operand") - (VNx1SI "immediate_operand") (VNx2SI "immediate_operand") (VNx4SI "immediate_operand") (VNx8SI "immediate_operand") (VNx16SI "immediate_operand") - (VNx32SI "vector_gs_extension_operand") - (VNx1DI "immediate_operand") (VNx2DI "immediate_operand") (VNx4DI "immediate_operand") (VNx8DI "immediate_operand") (VNx16DI "immediate_operand") + (RVVM8QI "const_1_operand") (RVVM4QI "vector_gs_extension_operand") + (RVVM2QI "immediate_operand") (RVVM1QI "immediate_operand") (RVVMF2QI "immediate_operand") + (RVVMF4QI "immediate_operand") (RVVMF8QI "immediate_operand") + + (RVVM8HI "const_1_operand") (RVVM4HI "vector_gs_extension_operand") + (RVVM2HI "immediate_operand") (RVVM1HI "immediate_operand") + (RVVMF2HI "immediate_operand") (RVVMF4HI "immediate_operand") - (VNx1HF "immediate_operand") (VNx2HF "immediate_operand") (VNx4HF "immediate_operand") (VNx8HF "immediate_operand") (VNx16HF "immediate_operand") - (VNx32HF "vector_gs_extension_operand") (VNx64HF "const_1_operand") - (VNx1SF "immediate_operand") (VNx2SF "immediate_operand") (VNx4SF "immediate_operand") (VNx8SF "immediate_operand") (VNx16SF "immediate_operand") - (VNx32SF "vector_gs_extension_operand") - (VNx1DF "immediate_operand") (VNx2DF "immediate_operand") (VNx4DF "immediate_operand") (VNx8DF "immediate_operand") (VNx16DF "immediate_operand") + (RVVM8HF "const_1_operand") (RVVM4HF "vector_gs_extension_operand") + (RVVM2HF "immediate_operand") (RVVM1HF "immediate_operand") + (RVVMF2HF "immediate_operand") (RVVMF4HF "immediate_operand") + + (RVVM8SI "vector_gs_extension_operand") (RVVM4SI "immediate_operand") (RVVM2SI "immediate_operand") + (RVVM1SI "immediate_operand") (RVVMF2SI "immediate_operand") + + (RVVM8SF "vector_gs_extension_operand") (RVVM4SF "immediate_operand") (RVVM2SF "immediate_operand") + (RVVM1SF "immediate_operand") (RVVMF2SF "immediate_operand") + + (RVVM8DI "immediate_operand") (RVVM4DI "immediate_operand") + (RVVM2DI "immediate_operand") (RVVM1DI "immediate_operand") + + (RVVM8DF "immediate_operand") (RVVM4DF "immediate_operand") + (RVVM2DF "immediate_operand") (RVVM1DF "immediate_operand") ]) (define_mode_attr gs_scale [ - (VNx1QI "const_1_operand") (VNx2QI "const_1_operand") (VNx4QI "const_1_operand") (VNx8QI "const_1_operand") - (VNx16QI "const_1_operand") (VNx32QI "const_1_operand") (VNx64QI "const_1_operand") - (VNx1HI "vector_gs_scale_operand_16") (VNx2HI "vector_gs_scale_operand_16") (VNx4HI "vector_gs_scale_operand_16") (VNx8HI "vector_gs_scale_operand_16") - (VNx16HI "vector_gs_scale_operand_16") (VNx32HI "vector_gs_scale_operand_16_rv32") (VNx64HI "const_1_operand") - (VNx1SI "vector_gs_scale_operand_32") (VNx2SI "vector_gs_scale_operand_32") (VNx4SI "vector_gs_scale_operand_32") (VNx8SI "vector_gs_scale_operand_32") - (VNx16SI "vector_gs_scale_operand_32") (VNx32SI "vector_gs_scale_operand_32_rv32") - (VNx1DI "vector_gs_scale_operand_64") (VNx2DI "vector_gs_scale_operand_64") (VNx4DI "vector_gs_scale_operand_64") (VNx8DI "vector_gs_scale_operand_64") - (VNx16DI "vector_gs_scale_operand_64") - - (VNx1HF "vector_gs_scale_operand_16") (VNx2HF "vector_gs_scale_operand_16") (VNx4HF "vector_gs_scale_operand_16") (VNx8HF "vector_gs_scale_operand_16") - (VNx16HF "vector_gs_scale_operand_16") (VNx32HF "vector_gs_scale_operand_16_rv32") (VNx64HF "const_1_operand") - (VNx1SF "vector_gs_scale_operand_32") (VNx2SF "vector_gs_scale_operand_32") (VNx4SF "vector_gs_scale_operand_32") (VNx8SF "vector_gs_scale_operand_32") - (VNx16SF "vector_gs_scale_operand_32") (VNx32SF "vector_gs_scale_operand_32_rv32") - (VNx1DF "vector_gs_scale_operand_64") (VNx2DF "vector_gs_scale_operand_64") (VNx4DF "vector_gs_scale_operand_64") (VNx8DF "vector_gs_scale_operand_64") - (VNx16DF "vector_gs_scale_operand_64") + (RVVM8QI "const_1_operand") (RVVM4QI "const_1_operand") + (RVVM2QI "const_1_operand") (RVVM1QI "const_1_operand") (RVVMF2QI "const_1_operand") + (RVVMF4QI "const_1_operand") (RVVMF8QI "const_1_operand") + + (RVVM8HI "const_1_operand") (RVVM4HI "vector_gs_scale_operand_16_rv32") + (RVVM2HI "vector_gs_scale_operand_16") (RVVM1HI "vector_gs_scale_operand_16") + (RVVMF2HI "vector_gs_scale_operand_16") (RVVMF4HI "vector_gs_scale_operand_16") + + (RVVM8HF "const_1_operand") (RVVM4HF "vector_gs_scale_operand_16_rv32") + (RVVM2HF "vector_gs_scale_operand_16") (RVVM1HF "vector_gs_scale_operand_16") + (RVVMF2HF "vector_gs_scale_operand_16") (RVVMF4HF "vector_gs_scale_operand_16") + + (RVVM8SI "vector_gs_scale_operand_32_rv32") (RVVM4SI "vector_gs_scale_operand_32") (RVVM2SI "vector_gs_scale_operand_32") + (RVVM1SI "vector_gs_scale_operand_32") (RVVMF2SI "vector_gs_scale_operand_32") + + (RVVM8SF "vector_gs_scale_operand_32_rv32") (RVVM4SF "vector_gs_scale_operand_32") (RVVM2SF "vector_gs_scale_operand_32") + (RVVM1SF "vector_gs_scale_operand_32") (RVVMF2SF "vector_gs_scale_operand_32") + + (RVVM8DI "vector_gs_scale_operand_64") (RVVM4DI "vector_gs_scale_operand_64") + (RVVM2DI "vector_gs_scale_operand_64") (RVVM1DI "vector_gs_scale_operand_64") + + (RVVM8DF "vector_gs_scale_operand_64") (RVVM4DF "vector_gs_scale_operand_64") + (RVVM2DF "vector_gs_scale_operand_64") (RVVM1DF "vector_gs_scale_operand_64") ]) (define_int_iterator WREDUC [UNSPEC_WREDUC_SUM UNSPEC_WREDUC_USUM]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 215ecb9..69680de 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -83,126 +83,242 @@ ;; check. However, we need default value of SEW for vsetvl instruction since there ;; is no field for ratio in the vsetvl instruction encoding. (define_attr "sew" "" - (cond [(eq_attr "mode" "VNx1QI,VNx2QI,VNx4QI,VNx8QI,VNx16QI,VNx32QI,VNx64QI,\ - VNx1BI,VNx2BI,VNx4BI,VNx8BI,VNx16BI,VNx32BI,VNx64BI,\ - VNx128QI,VNx128BI,VNx2x64QI,VNx2x32QI,VNx3x32QI,VNx4x32QI,\ - VNx2x16QI,VNx3x16QI,VNx4x16QI,VNx5x16QI,VNx6x16QI,VNx7x16QI,VNx8x16QI,\ - VNx2x8QI,VNx3x8QI,VNx4x8QI,VNx5x8QI,VNx6x8QI,VNx7x8QI,VNx8x8QI,\ - VNx2x4QI,VNx3x4QI,VNx4x4QI,VNx5x4QI,VNx6x4QI,VNx7x4QI,VNx8x4QI,\ - VNx2x2QI,VNx3x2QI,VNx4x2QI,VNx5x2QI,VNx6x2QI,VNx7x2QI,VNx8x2QI,\ - VNx2x1QI,VNx3x1QI,VNx4x1QI,VNx5x1QI,VNx6x1QI,VNx7x1QI,VNx8x1QI") + (cond [(eq_attr "mode" "RVVMF64BI,RVVMF32BI,RVVMF16BI,RVVMF8BI,RVVMF4BI,RVVMF2BI,RVVM1BI,\ + RVVM8QI,RVVM4QI,RVVM2QI,RVVM1QI,RVVMF2QI,RVVMF4QI,RVVMF8QI,\ + RVVM1x8QI,RVVMF2x8QI,RVVMF4x8QI,RVVMF8x8QI,\ + RVVM1x7QI,RVVMF2x7QI,RVVMF4x7QI,RVVMF8x7QI,\ + RVVM1x6QI,RVVMF2x6QI,RVVMF4x6QI,RVVMF8x6QI,\ + RVVM1x5QI,RVVMF2x5QI,RVVMF4x5QI,RVVMF8x5QI,\ + RVVM2x4QI,RVVM1x4QI,RVVMF2x4QI,RVVMF4x4QI,RVVMF8x4QI,\ + RVVM2x3QI,RVVM1x3QI,RVVMF2x3QI,RVVMF4x3QI,RVVMF8x3QI,\ + RVVM4x2QI,RVVM2x2QI,RVVM1x2QI,RVVMF2x2QI,RVVMF4x2QI,RVVMF8x2QI") (const_int 8) - (eq_attr "mode" "VNx1HI,VNx2HI,VNx4HI,VNx8HI,VNx16HI,VNx32HI,VNx64HI,\ - VNx1HF,VNx2HF,VNx4HF,VNx8HF,VNx16HF,VNx32HF,VNx64HF,\ - VNx2x32HI,VNx2x16HI,VNx3x16HI,VNx4x16HI,\ - VNx2x8HI,VNx3x8HI,VNx4x8HI,VNx5x8HI,VNx6x8HI,VNx7x8HI,VNx8x8HI,\ - VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI,\ - VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI,\ - VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI,\ - VNx2x32HF,VNx2x16HF,VNx3x16HF,VNx4x16HF,\ - VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF,\ - VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF,\ - VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF,\ - VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF") + (eq_attr "mode" "RVVM8HI,RVVM4HI,RVVM2HI,RVVM1HI,RVVMF2HI,RVVMF4HI,\ + RVVM1x8HI,RVVMF2x8HI,RVVMF4x8HI,\ + RVVM1x7HI,RVVMF2x7HI,RVVMF4x7HI,\ + RVVM1x6HI,RVVMF2x6HI,RVVMF4x6HI,\ + RVVM1x5HI,RVVMF2x5HI,RVVMF4x5HI,\ + RVVM2x4HI,RVVM1x4HI,RVVMF2x4HI,RVVMF4x4HI,\ + RVVM2x3HI,RVVM1x3HI,RVVMF2x3HI,RVVMF4x3HI,\ + RVVM4x2HI,RVVM2x2HI,RVVM1x2HI,RVVMF2x2HI,RVVMF4x2HI,\ + RVVM8HF,RVVM4HF,RVVM2HF,RVVM1HF,RVVMF2HF,RVVMF4HF,\ + RVVM1x8HF,RVVMF2x8HF,RVVMF4x8HF,\ + RVVM1x7HF,RVVMF2x7HF,RVVMF4x7HF,\ + RVVM1x6HF,RVVMF2x6HF,RVVMF4x6HF,\ + RVVM1x5HF,RVVMF2x5HF,RVVMF4x5HF,\ + RVVM2x4HF,RVVM1x4HF,RVVMF2x4HF,RVVMF4x4HF,\ + RVVM2x3HF,RVVM1x3HF,RVVMF2x3HF,RVVMF4x3HF,\ + RVVM4x2HF,RVVM2x2HF,RVVM1x2HF,RVVMF2x2HF,RVVMF4x2HF") (const_int 16) - (eq_attr "mode" "VNx1SI,VNx2SI,VNx4SI,VNx8SI,VNx16SI,VNx32SI,\ - VNx1SF,VNx2SF,VNx4SF,VNx8SF,VNx16SF,VNx32SF,\ - VNx2x16SI,VNx2x8SI,VNx3x8SI,VNx4x8SI,\ - VNx2x4SI,VNx3x4SI,VNx4x4SI,VNx5x4SI,VNx6x4SI,VNx7x4SI,VNx8x4SI,\ - VNx2x2SI,VNx3x2SI,VNx4x2SI,VNx5x2SI,VNx6x2SI,VNx7x2SI,VNx8x2SI,\ - VNx2x1SI,VNx3x1SI,VNx4x1SI,VNx5x1SI,VNx6x1SI,VNx7x1SI,VNx8x1SI,\ - VNx2x16SF,VNx2x8SF,VNx3x8SF,VNx4x8SF,\ - VNx2x4SF,VNx3x4SF,VNx4x4SF,VNx5x4SF,VNx6x4SF,VNx7x4SF,VNx8x4SF,\ - VNx2x2SF,VNx3x2SF,VNx4x2SF,VNx5x2SF,VNx6x2SF,VNx7x2SF,VNx8x2SF,\ - VNx2x1SF,VNx3x1SF,VNx4x1SF,VNx5x1SF,VNx6x1SF,VNx7x1SF,VNx8x1SF") + (eq_attr "mode" "RVVM8SI,RVVM4SI,RVVM2SI,RVVM1SI,RVVMF2SI,\ + RVVM8SF,RVVM4SF,RVVM2SF,RVVM1SF,RVVMF2SF,\ + RVVM1x8SI,RVVMF2x8SI,\ + RVVM1x7SI,RVVMF2x7SI,\ + RVVM1x6SI,RVVMF2x6SI,\ + RVVM1x5SI,RVVMF2x5SI,\ + RVVM2x4SI,RVVM1x4SI,\ + RVVM2x3SI,RVVM1x3SI,\ + RVVM4x2SI,RVVM2x2SI,RVVM1x2SI,RVVMF2x2SI,\ + RVVM1x8SF,RVVMF2x8SF,\ + RVVM1x7SF,RVVMF2x7SF,\ + RVVM1x6SF,RVVMF2x6SF,\ + RVVM1x5SF,RVVMF2x5SF,\ + RVVM2x4SF,RVVM1x4SF,RVVMF2x4SF,\ + RVVM2x3SF,RVVM1x3SF,RVVMF2x3SF,\ + RVVM4x2SF,RVVM2x2SF,RVVM1x2SF,RVVMF2x2SF") (const_int 32) - (eq_attr "mode" "VNx1DI,VNx2DI,VNx4DI,VNx8DI,VNx16DI,\ - VNx1DF,VNx2DF,VNx4DF,VNx8DF,VNx16DF,\ - VNx2x8DI,VNx2x4DI,VNx3x4DI,VNx4x4DI,\ - VNx2x2DI,VNx3x2DI,VNx4x2DI,VNx5x2DI,VNx6x2DI,VNx7x2DI,VNx8x2DI,\ - VNx2x1DI,VNx3x1DI,VNx4x1DI,VNx5x1DI,VNx6x1DI,VNx7x1DI,VNx8x1DI,\ - VNx2x8DF,VNx2x4DF,VNx3x4DF,VNx4x4DF,\ - VNx2x2DF,VNx3x2DF,VNx4x2DF,VNx5x2DF,VNx6x2DF,VNx7x2DF,VNx8x2DF,\ - VNx2x1DF,VNx3x1DF,VNx4x1DF,VNx5x1DF,VNx6x1DF,VNx7x1DF,VNx8x1DF") + (eq_attr "mode" "RVVM8DI,RVVM4DI,RVVM2DI,RVVM1DI,\ + RVVM8DF,RVVM4DF,RVVM2DF,RVVM1DF,\ + RVVM1x8DI,RVVM1x7DI,RVVM1x6DI,RVVM1x5DI,\ + RVVM2x4DI,RVVM1x4DI,\ + RVVM2x3DI,RVVM1x3DI,\ + RVVM4x2DI,RVVM2x2DI,RVVM1x2DI,\ + RVVM1x8DF,RVVM1x7DF,RVVM1x6DF,RVVM1x5DF,\ + RVVM2x4DF,RVVM1x4DF,\ + RVVM2x3DF,RVVM1x3DF,\ + RVVM4x2DF,RVVM2x2DF,RVVM1x2DF") (const_int 64)] (const_int INVALID_ATTRIBUTE))) ;; Ditto to LMUL. (define_attr "vlmul" "" - (cond [(eq_attr "mode" "VNx1QI,VNx1BI,VNx2x1QI,VNx3x1QI,VNx4x1QI,VNx5x1QI,VNx6x1QI,VNx7x1QI,VNx8x1QI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx1QImode)") - (eq_attr "mode" "VNx2QI,VNx2BI,VNx2x2QI,VNx3x2QI,VNx4x2QI,VNx5x2QI,VNx6x2QI,VNx7x2QI,VNx8x2QI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx2QImode)") - (eq_attr "mode" "VNx4QI,VNx4BI,VNx2x4QI,VNx3x4QI,VNx4x4QI,VNx5x4QI,VNx6x4QI,VNx7x4QI,VNx8x4QI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx4QImode)") - (eq_attr "mode" "VNx8QI,VNx8BI,VNx2x8QI,VNx3x8QI,VNx4x8QI,VNx5x8QI,VNx6x8QI,VNx7x8QI,VNx8x8QI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx8QImode)") - (eq_attr "mode" "VNx16QI,VNx16BI,VNx2x16QI,VNx3x16QI,VNx4x16QI,VNx5x16QI,VNx6x16QI,VNx7x16QI,VNx8x16QI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx16QImode)") - (eq_attr "mode" "VNx32QI,VNx32BI,VNx2x32QI,VNx3x32QI,VNx4x32QI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx32QImode)") - (eq_attr "mode" "VNx64QI,VNx64BI,VNx2x64QI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx64QImode)") - (eq_attr "mode" "VNx128QI,VNx128BI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx128QImode)") - (eq_attr "mode" "VNx1HI,VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx1HImode)") - (eq_attr "mode" "VNx2HI,VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx2HImode)") - (eq_attr "mode" "VNx4HI,VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx4HImode)") - (eq_attr "mode" "VNx8HI,VNx2x8HI,VNx3x8HI,VNx4x8HI,VNx5x8HI,VNx6x8HI,VNx7x8HI,VNx8x8HI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx8HImode)") - (eq_attr "mode" "VNx16HI,VNx2x16HI,VNx3x16HI,VNx4x16HI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx16HImode)") - (eq_attr "mode" "VNx32HI,VNx2x32HI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx32HImode)") - (eq_attr "mode" "VNx64HI") - (symbol_ref "riscv_vector::get_vlmul(E_VNx64HImode)") - - ; Half float point - (eq_attr "mode" "VNx1HF,VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx1HFmode)") - (eq_attr "mode" "VNx2HF,VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx2HFmode)") - (eq_attr "mode" "VNx4HF,VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx4HFmode)") - (eq_attr "mode" "VNx8HF,VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx8HFmode)") - (eq_attr "mode" "VNx16HF,VNx2x16HF,VNx3x16HF,VNx4x16HF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx16HFmode)") - (eq_attr "mode" "VNx32HF,VNx2x32HF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx32HFmode)") - (eq_attr "mode" "VNx64HF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx64HFmode)") - - (eq_attr "mode" "VNx1SI,VNx1SF,VNx2x1SI,VNx3x1SI,VNx4x1SI,VNx5x1SI,VNx6x1SI,VNx7x1SI,VNx8x1SI,\ - VNx2x1SF,VNx3x1SF,VNx4x1SF,VNx5x1SF,VNx6x1SF,VNx7x1SF,VNx8x1SF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx1SImode)") - (eq_attr "mode" "VNx2SI,VNx2SF,VNx2x2SI,VNx3x2SI,VNx4x2SI,VNx5x2SI,VNx6x2SI,VNx7x2SI,VNx8x2SI,\ - VNx2x2SF,VNx3x2SF,VNx4x2SF,VNx5x2SF,VNx6x2SF,VNx7x2SF,VNx8x2SF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx2SImode)") - (eq_attr "mode" "VNx4SI,VNx4SF,VNx2x4SI,VNx3x4SI,VNx4x4SI,VNx5x4SI,VNx6x4SI,VNx7x4SI,VNx8x4SI,\ - VNx2x4SF,VNx3x4SF,VNx4x4SF,VNx5x4SF,VNx6x4SF,VNx7x4SF,VNx8x4SF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx4SImode)") - (eq_attr "mode" "VNx8SI,VNx8SF,VNx2x8SI,VNx3x8SI,VNx4x8SI,VNx2x8SF,VNx3x8SF,VNx4x8SF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx8SImode)") - (eq_attr "mode" "VNx16SI,VNx16SF,VNx2x16SI,VNx2x16SF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx16SImode)") - (eq_attr "mode" "VNx32SI,VNx32SF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx32SImode)") - (eq_attr "mode" "VNx1DI,VNx1DF,VNx2x1DI,VNx3x1DI,VNx4x1DI,VNx5x1DI,VNx6x1DI,VNx7x1DI,VNx8x1DI,\ - VNx2x1DF,VNx3x1DF,VNx4x1DF,VNx5x1DF,VNx6x1DF,VNx7x1DF,VNx8x1DF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx1DImode)") - (eq_attr "mode" "VNx2DI,VNx2DF,VNx2x2DI,VNx3x2DI,VNx4x2DI,VNx5x2DI,VNx6x2DI,VNx7x2DI,VNx8x2DI,\ - VNx2x2DF,VNx3x2DF,VNx4x2DF,VNx5x2DF,VNx6x2DF,VNx7x2DF,VNx8x2DF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx2DImode)") - (eq_attr "mode" "VNx4DI,VNx4DF,VNx2x4DI,VNx3x4DI,VNx4x4DI,VNx2x4DF,VNx3x4DF,VNx4x4DF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx4DImode)") - (eq_attr "mode" "VNx8DI,VNx8DF,VNx2x8DI,VNx2x8DF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx8DImode)") - (eq_attr "mode" "VNx16DI,VNx16DF") - (symbol_ref "riscv_vector::get_vlmul(E_VNx16DImode)")] + (cond [(eq_attr "mode" "RVVM8QI,RVVM1BI") (symbol_ref "riscv_vector::LMUL_8") + (eq_attr "mode" "RVVM4QI,RVVMF2BI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2QI,RVVMF4BI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1QI,RVVMF8BI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2QI,RVVMF16BI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4QI,RVVMF32BI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8QI,RVVMF64BI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM8HI") (symbol_ref "riscv_vector::LMUL_8") + (eq_attr "mode" "RVVM4HI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2HI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM8HF") (symbol_ref "riscv_vector::LMUL_8") + (eq_attr "mode" "RVVM4HF") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2HF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM8SI") (symbol_ref "riscv_vector::LMUL_8") + (eq_attr "mode" "RVVM4SI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2SI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM8SF") (symbol_ref "riscv_vector::LMUL_8") + (eq_attr "mode" "RVVM4SF") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2SF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM8DI") (symbol_ref "riscv_vector::LMUL_8") + (eq_attr "mode" "RVVM4DI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2DI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM8DF") (symbol_ref "riscv_vector::LMUL_8") + (eq_attr "mode" "RVVM4DF") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2DF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1DF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x8QI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x8QI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x8QI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8x8QI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM1x7QI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x7QI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x7QI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8x7QI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM1x6QI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x6QI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x6QI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8x6QI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM1x5QI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x5QI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x5QI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8x5QI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM2x4QI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x4QI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x4QI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x4QI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8x4QI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM2x3QI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x3QI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x3QI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x3QI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8x3QI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM4x2QI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2x2QI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x2QI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x2QI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x2QI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVMF8x2QI") (symbol_ref "riscv_vector::LMUL_F8") + (eq_attr "mode" "RVVM1x8HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x8HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x8HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x7HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x7HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x7HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x6HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x6HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x6HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x5HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x5HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x5HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM2x4HI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x4HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x4HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x4HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM2x3HI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x3HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x3HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x3HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM4x2HI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2x2HI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x2HI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x2HI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x2HI") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x8HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x8HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x8HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x7HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x7HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x7HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x6HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x6HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x6HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x5HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x5HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x5HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM2x4HF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x4HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x4HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x4HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM2x3HF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x3HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x3HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x3HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM4x2HF") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2x2HF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x2HF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x2HF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVMF4x2HF") (symbol_ref "riscv_vector::LMUL_F4") + (eq_attr "mode" "RVVM1x8SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x8SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x7SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x7SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x6SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x6SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x5SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x5SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM2x4SI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x4SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x4SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM2x3SI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x3SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x3SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM4x2SI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2x2SI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x2SI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x2SI") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x8SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x8SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x7SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x7SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x6SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x6SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x5SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x5SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM2x4SF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x4SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x4SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM2x3SF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x3SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x3SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM4x2SF") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2x2SF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x2SF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVMF2x2SF") (symbol_ref "riscv_vector::LMUL_F2") + (eq_attr "mode" "RVVM1x8DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x7DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x6DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x5DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM2x4DI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x4DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM2x3DI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x3DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM4x2DI") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2x2DI") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x2DI") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x8DF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x7DF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x6DF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM1x5DF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM2x4DF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x4DF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM2x3DF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x3DF") (symbol_ref "riscv_vector::LMUL_1") + (eq_attr "mode" "RVVM4x2DF") (symbol_ref "riscv_vector::LMUL_4") + (eq_attr "mode" "RVVM2x2DF") (symbol_ref "riscv_vector::LMUL_2") + (eq_attr "mode" "RVVM1x2DF") (symbol_ref "riscv_vector::LMUL_1")] (const_int INVALID_ATTRIBUTE))) ;; It is valid for instruction that require sew/lmul ratio. @@ -222,80 +338,183 @@ vislide1up,vislide1down,vfslide1up,vfslide1down,\ vgather,vcompress,vlsegdux,vlsegdox,vssegtux,vssegtox") (const_int INVALID_ATTRIBUTE) - (eq_attr "mode" "VNx1QI,VNx1BI,VNx2x1QI,VNx3x1QI,VNx4x1QI,VNx5x1QI,VNx6x1QI,VNx7x1QI,VNx8x1QI") - (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)") - (eq_attr "mode" "VNx2QI,VNx2BI,VNx2x2QI,VNx3x2QI,VNx4x2QI,VNx5x2QI,VNx6x2QI,VNx7x2QI,VNx8x2QI") - (symbol_ref "riscv_vector::get_ratio(E_VNx2QImode)") - (eq_attr "mode" "VNx4QI,VNx4BI,VNx2x4QI,VNx3x4QI,VNx4x4QI,VNx5x4QI,VNx6x4QI,VNx7x4QI,VNx8x4QI") - (symbol_ref "riscv_vector::get_ratio(E_VNx4QImode)") - (eq_attr "mode" "VNx8QI,VNx8BI,VNx2x8QI,VNx3x8QI,VNx4x8QI,VNx5x8QI,VNx6x8QI,VNx7x8QI,VNx8x8QI") - (symbol_ref "riscv_vector::get_ratio(E_VNx8QImode)") - (eq_attr "mode" "VNx16QI,VNx16BI,VNx2x16QI,VNx3x16QI,VNx4x16QI,VNx5x16QI,VNx6x16QI,VNx7x16QI,VNx8x16QI") - (symbol_ref "riscv_vector::get_ratio(E_VNx16QImode)") - (eq_attr "mode" "VNx32QI,VNx32BI,VNx2x32QI,VNx3x32QI,VNx4x32QI") - (symbol_ref "riscv_vector::get_ratio(E_VNx32QImode)") - (eq_attr "mode" "VNx64QI,VNx64BI,VNx2x64QI") - (symbol_ref "riscv_vector::get_ratio(E_VNx64QImode)") - (eq_attr "mode" "VNx128QI,VNx128BI") - (symbol_ref "riscv_vector::get_ratio(E_VNx128QImode)") - (eq_attr "mode" "VNx1HI,VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI") - (symbol_ref "riscv_vector::get_ratio(E_VNx1HImode)") - (eq_attr "mode" "VNx2HI,VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI") - (symbol_ref "riscv_vector::get_ratio(E_VNx2HImode)") - (eq_attr "mode" "VNx4HI,VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI") - (symbol_ref "riscv_vector::get_ratio(E_VNx4HImode)") - (eq_attr "mode" "VNx8HI,VNx2x8HI,VNx3x8HI,VNx4x8HI,VNx5x8HI,VNx6x8HI,VNx7x8HI,VNx8x8HI") - (symbol_ref "riscv_vector::get_ratio(E_VNx8HImode)") - (eq_attr "mode" "VNx16HI,VNx2x16HI,VNx3x16HI,VNx4x16HI") - (symbol_ref "riscv_vector::get_ratio(E_VNx16HImode)") - (eq_attr "mode" "VNx32HI,VNx2x32HI") - (symbol_ref "riscv_vector::get_ratio(E_VNx32HImode)") - (eq_attr "mode" "VNx64HI") - (symbol_ref "riscv_vector::get_ratio(E_VNx64HImode)") - - ; Half float point. - (eq_attr "mode" "VNx1HF,VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF") - (symbol_ref "riscv_vector::get_ratio(E_VNx1HFmode)") - (eq_attr "mode" "VNx2HF,VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF") - (symbol_ref "riscv_vector::get_ratio(E_VNx2HFmode)") - (eq_attr "mode" "VNx4HF,VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF") - (symbol_ref "riscv_vector::get_ratio(E_VNx4HFmode)") - (eq_attr "mode" "VNx8HF,VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF") - (symbol_ref "riscv_vector::get_ratio(E_VNx8HFmode)") - (eq_attr "mode" "VNx16HF,VNx2x16HF,VNx3x16HF,VNx4x16HF") - (symbol_ref "riscv_vector::get_ratio(E_VNx16HFmode)") - (eq_attr "mode" "VNx32HF,VNx2x32HF") - (symbol_ref "riscv_vector::get_ratio(E_VNx32HFmode)") - (eq_attr "mode" "VNx64HF") - (symbol_ref "riscv_vector::get_ratio(E_VNx64HFmode)") - - (eq_attr "mode" "VNx1SI,VNx1SF,VNx2x1SI,VNx3x1SI,VNx4x1SI,VNx5x1SI,VNx6x1SI,VNx7x1SI,VNx8x1SI,\ - VNx2x1SF,VNx3x1SF,VNx4x1SF,VNx5x1SF,VNx6x1SF,VNx7x1SF,VNx8x1SF") - (symbol_ref "riscv_vector::get_ratio(E_VNx1SImode)") - (eq_attr "mode" "VNx2SI,VNx2SF,VNx2x2SI,VNx3x2SI,VNx4x2SI,VNx5x2SI,VNx6x2SI,VNx7x2SI,VNx8x2SI,\ - VNx2x2SF,VNx3x2SF,VNx4x2SF,VNx5x2SF,VNx6x2SF,VNx7x2SF,VNx8x2SF") - (symbol_ref "riscv_vector::get_ratio(E_VNx2SImode)") - (eq_attr "mode" "VNx4SI,VNx4SF,VNx2x4SI,VNx3x4SI,VNx4x4SI,VNx5x4SI,VNx6x4SI,VNx7x4SI,VNx8x4SI,\ - VNx2x4SF,VNx3x4SF,VNx4x4SF,VNx5x4SF,VNx6x4SF,VNx7x4SF,VNx8x4SF") - (symbol_ref "riscv_vector::get_ratio(E_VNx4SImode)") - (eq_attr "mode" "VNx8SI,VNx8SF,VNx2x8SI,VNx3x8SI,VNx4x8SI,VNx2x8SF,VNx3x8SF,VNx4x8SF") - (symbol_ref "riscv_vector::get_ratio(E_VNx8SImode)") - (eq_attr "mode" "VNx16SI,VNx16SF,VNx2x16SI,VNx2x16SF") - (symbol_ref "riscv_vector::get_ratio(E_VNx16SImode)") - (eq_attr "mode" "VNx32SI,VNx32SF") - (symbol_ref "riscv_vector::get_ratio(E_VNx32SImode)") - (eq_attr "mode" "VNx1DI,VNx1DF,VNx2x1DI,VNx3x1DI,VNx4x1DI,VNx5x1DI,VNx6x1DI,VNx7x1DI,VNx8x1DI,\ - VNx2x1DF,VNx3x1DF,VNx4x1DF,VNx5x1DF,VNx6x1DF,VNx7x1DF,VNx8x1DF") - (symbol_ref "riscv_vector::get_ratio(E_VNx1DImode)") - (eq_attr "mode" "VNx2DI,VNx2DF,VNx2x2DI,VNx3x2DI,VNx4x2DI,VNx5x2DI,VNx6x2DI,VNx7x2DI,VNx8x2DI,\ - VNx2x2DF,VNx3x2DF,VNx4x2DF,VNx5x2DF,VNx6x2DF,VNx7x2DF,VNx8x2DF") - (symbol_ref "riscv_vector::get_ratio(E_VNx2DImode)") - (eq_attr "mode" "VNx4DI,VNx4DF,VNx2x4DI,VNx3x4DI,VNx4x4DI,VNx2x4DF,VNx3x4DF,VNx4x4DF") - (symbol_ref "riscv_vector::get_ratio(E_VNx4DImode)") - (eq_attr "mode" "VNx8DI,VNx8DF,VNx2x8DI,VNx2x8DF") - (symbol_ref "riscv_vector::get_ratio(E_VNx8DImode)") - (eq_attr "mode" "VNx16DI,VNx16DF") - (symbol_ref "riscv_vector::get_ratio(E_VNx16DImode)")] + (eq_attr "mode" "RVVM8QI,RVVM1BI") (const_int 1) + (eq_attr "mode" "RVVM4QI,RVVMF2BI") (const_int 2) + (eq_attr "mode" "RVVM2QI,RVVMF4BI") (const_int 4) + (eq_attr "mode" "RVVM1QI,RVVMF8BI") (const_int 8) + (eq_attr "mode" "RVVMF2QI,RVVMF16BI") (const_int 16) + (eq_attr "mode" "RVVMF4QI,RVVMF32BI") (const_int 32) + (eq_attr "mode" "RVVMF8QI,RVVMF64BI") (const_int 64) + (eq_attr "mode" "RVVM8HI") (const_int 2) + (eq_attr "mode" "RVVM4HI") (const_int 4) + (eq_attr "mode" "RVVM2HI") (const_int 8) + (eq_attr "mode" "RVVM1HI") (const_int 16) + (eq_attr "mode" "RVVMF2HI") (const_int 32) + (eq_attr "mode" "RVVMF4HI") (const_int 64) + (eq_attr "mode" "RVVM8HF") (const_int 2) + (eq_attr "mode" "RVVM4HF") (const_int 4) + (eq_attr "mode" "RVVM2HF") (const_int 8) + (eq_attr "mode" "RVVM1HF") (const_int 16) + (eq_attr "mode" "RVVMF2HF") (const_int 32) + (eq_attr "mode" "RVVMF4HF") (const_int 64) + (eq_attr "mode" "RVVM8SI") (const_int 4) + (eq_attr "mode" "RVVM4SI") (const_int 8) + (eq_attr "mode" "RVVM2SI") (const_int 16) + (eq_attr "mode" "RVVM1SI") (const_int 32) + (eq_attr "mode" "RVVMF2SI") (const_int 64) + (eq_attr "mode" "RVVM8SF") (const_int 4) + (eq_attr "mode" "RVVM4SF") (const_int 8) + (eq_attr "mode" "RVVM2SF") (const_int 16) + (eq_attr "mode" "RVVM1SF") (const_int 32) + (eq_attr "mode" "RVVMF2SF") (const_int 64) + (eq_attr "mode" "RVVM8DI") (const_int 8) + (eq_attr "mode" "RVVM4DI") (const_int 16) + (eq_attr "mode" "RVVM2DI") (const_int 32) + (eq_attr "mode" "RVVM1DI") (const_int 64) + (eq_attr "mode" "RVVM8DF") (const_int 8) + (eq_attr "mode" "RVVM4DF") (const_int 16) + (eq_attr "mode" "RVVM2DF") (const_int 32) + (eq_attr "mode" "RVVM1DF") (const_int 64) + (eq_attr "mode" "RVVM1x8QI") (const_int 8) + (eq_attr "mode" "RVVMF2x8QI") (const_int 16) + (eq_attr "mode" "RVVMF4x8QI") (const_int 32) + (eq_attr "mode" "RVVMF8x8QI") (const_int 64) + (eq_attr "mode" "RVVM1x7QI") (const_int 8) + (eq_attr "mode" "RVVMF2x7QI") (const_int 16) + (eq_attr "mode" "RVVMF4x7QI") (const_int 32) + (eq_attr "mode" "RVVMF8x7QI") (const_int 64) + (eq_attr "mode" "RVVM1x6QI") (const_int 8) + (eq_attr "mode" "RVVMF2x6QI") (const_int 16) + (eq_attr "mode" "RVVMF4x6QI") (const_int 32) + (eq_attr "mode" "RVVMF8x6QI") (const_int 64) + (eq_attr "mode" "RVVM1x5QI") (const_int 8) + (eq_attr "mode" "RVVMF2x5QI") (const_int 16) + (eq_attr "mode" "RVVMF4x5QI") (const_int 32) + (eq_attr "mode" "RVVMF8x5QI") (const_int 64) + (eq_attr "mode" "RVVM2x4QI") (const_int 4) + (eq_attr "mode" "RVVM1x4QI") (const_int 8) + (eq_attr "mode" "RVVMF2x4QI") (const_int 16) + (eq_attr "mode" "RVVMF4x4QI") (const_int 32) + (eq_attr "mode" "RVVMF8x4QI") (const_int 64) + (eq_attr "mode" "RVVM2x3QI") (const_int 4) + (eq_attr "mode" "RVVM1x3QI") (const_int 8) + (eq_attr "mode" "RVVMF2x3QI") (const_int 16) + (eq_attr "mode" "RVVMF4x3QI") (const_int 32) + (eq_attr "mode" "RVVMF8x3QI") (const_int 64) + (eq_attr "mode" "RVVM4x2QI") (const_int 2) + (eq_attr "mode" "RVVM2x2QI") (const_int 4) + (eq_attr "mode" "RVVM1x2QI") (const_int 8) + (eq_attr "mode" "RVVMF2x2QI") (const_int 16) + (eq_attr "mode" "RVVMF4x2QI") (const_int 32) + (eq_attr "mode" "RVVMF8x2QI") (const_int 64) + (eq_attr "mode" "RVVM1x8HI") (const_int 16) + (eq_attr "mode" "RVVMF2x8HI") (const_int 32) + (eq_attr "mode" "RVVMF4x8HI") (const_int 64) + (eq_attr "mode" "RVVM1x7HI") (const_int 16) + (eq_attr "mode" "RVVMF2x7HI") (const_int 32) + (eq_attr "mode" "RVVMF4x7HI") (const_int 64) + (eq_attr "mode" "RVVM1x6HI") (const_int 16) + (eq_attr "mode" "RVVMF2x6HI") (const_int 32) + (eq_attr "mode" "RVVMF4x6HI") (const_int 64) + (eq_attr "mode" "RVVM1x5HI") (const_int 16) + (eq_attr "mode" "RVVMF2x5HI") (const_int 32) + (eq_attr "mode" "RVVMF4x5HI") (const_int 64) + (eq_attr "mode" "RVVM2x4HI") (const_int 8) + (eq_attr "mode" "RVVM1x4HI") (const_int 16) + (eq_attr "mode" "RVVMF2x4HI") (const_int 32) + (eq_attr "mode" "RVVMF4x4HI") (const_int 64) + (eq_attr "mode" "RVVM2x3HI") (const_int 8) + (eq_attr "mode" "RVVM1x3HI") (const_int 16) + (eq_attr "mode" "RVVMF2x3HI") (const_int 32) + (eq_attr "mode" "RVVMF4x3HI") (const_int 64) + (eq_attr "mode" "RVVM4x2HI") (const_int 4) + (eq_attr "mode" "RVVM2x2HI") (const_int 8) + (eq_attr "mode" "RVVM1x2HI") (const_int 16) + (eq_attr "mode" "RVVMF2x2HI") (const_int 32) + (eq_attr "mode" "RVVMF4x2HI") (const_int 64) + (eq_attr "mode" "RVVM1x8HF") (const_int 16) + (eq_attr "mode" "RVVMF2x8HF") (const_int 32) + (eq_attr "mode" "RVVMF4x8HF") (const_int 64) + (eq_attr "mode" "RVVM1x7HF") (const_int 16) + (eq_attr "mode" "RVVMF2x7HF") (const_int 32) + (eq_attr "mode" "RVVMF4x7HF") (const_int 64) + (eq_attr "mode" "RVVM1x6HF") (const_int 16) + (eq_attr "mode" "RVVMF2x6HF") (const_int 32) + (eq_attr "mode" "RVVMF4x6HF") (const_int 64) + (eq_attr "mode" "RVVM1x5HF") (const_int 16) + (eq_attr "mode" "RVVMF2x5HF") (const_int 32) + (eq_attr "mode" "RVVMF4x5HF") (const_int 64) + (eq_attr "mode" "RVVM2x4HF") (const_int 8) + (eq_attr "mode" "RVVM1x4HF") (const_int 16) + (eq_attr "mode" "RVVMF2x4HF") (const_int 32) + (eq_attr "mode" "RVVMF4x4HF") (const_int 64) + (eq_attr "mode" "RVVM2x3HF") (const_int 8) + (eq_attr "mode" "RVVM1x3HF") (const_int 16) + (eq_attr "mode" "RVVMF2x3HF") (const_int 32) + (eq_attr "mode" "RVVMF4x3HF") (const_int 64) + (eq_attr "mode" "RVVM4x2HF") (const_int 4) + (eq_attr "mode" "RVVM2x2HF") (const_int 8) + (eq_attr "mode" "RVVM1x2HF") (const_int 16) + (eq_attr "mode" "RVVMF2x2HF") (const_int 32) + (eq_attr "mode" "RVVMF4x2HF") (const_int 64) + (eq_attr "mode" "RVVM1x8SI") (const_int 32) + (eq_attr "mode" "RVVMF2x8SI") (const_int 64) + (eq_attr "mode" "RVVM1x7SI") (const_int 32) + (eq_attr "mode" "RVVMF2x7SI") (const_int 64) + (eq_attr "mode" "RVVM1x6SI") (const_int 32) + (eq_attr "mode" "RVVMF2x6SI") (const_int 64) + (eq_attr "mode" "RVVM1x5SI") (const_int 32) + (eq_attr "mode" "RVVMF2x5SI") (const_int 64) + (eq_attr "mode" "RVVM2x4SI") (const_int 16) + (eq_attr "mode" "RVVM1x4SI") (const_int 32) + (eq_attr "mode" "RVVMF2x4SI") (const_int 64) + (eq_attr "mode" "RVVM2x3SI") (const_int 16) + (eq_attr "mode" "RVVM1x3SI") (const_int 32) + (eq_attr "mode" "RVVMF2x3SI") (const_int 64) + (eq_attr "mode" "RVVM4x2SI") (const_int 8) + (eq_attr "mode" "RVVM2x2SI") (const_int 16) + (eq_attr "mode" "RVVM1x2SI") (const_int 32) + (eq_attr "mode" "RVVMF2x2SI") (const_int 64) + (eq_attr "mode" "RVVM1x8SF") (const_int 32) + (eq_attr "mode" "RVVMF2x8SF") (const_int 64) + (eq_attr "mode" "RVVM1x7SF") (const_int 32) + (eq_attr "mode" "RVVMF2x7SF") (const_int 64) + (eq_attr "mode" "RVVM1x6SF") (const_int 32) + (eq_attr "mode" "RVVMF2x6SF") (const_int 64) + (eq_attr "mode" "RVVM1x5SF") (const_int 32) + (eq_attr "mode" "RVVMF2x5SF") (const_int 64) + (eq_attr "mode" "RVVM2x4SF") (const_int 16) + (eq_attr "mode" "RVVM1x4SF") (const_int 32) + (eq_attr "mode" "RVVMF2x4SF") (const_int 64) + (eq_attr "mode" "RVVM2x3SF") (const_int 16) + (eq_attr "mode" "RVVM1x3SF") (const_int 32) + (eq_attr "mode" "RVVMF2x3SF") (const_int 64) + (eq_attr "mode" "RVVM4x2SF") (const_int 8) + (eq_attr "mode" "RVVM2x2SF") (const_int 16) + (eq_attr "mode" "RVVM1x2SF") (const_int 32) + (eq_attr "mode" "RVVMF2x2SF") (const_int 64) + (eq_attr "mode" "RVVM1x8DI") (const_int 64) + (eq_attr "mode" "RVVM1x7DI") (const_int 64) + (eq_attr "mode" "RVVM1x6DI") (const_int 64) + (eq_attr "mode" "RVVM1x5DI") (const_int 64) + (eq_attr "mode" "RVVM2x4DI") (const_int 32) + (eq_attr "mode" "RVVM1x4DI") (const_int 64) + (eq_attr "mode" "RVVM2x3DI") (const_int 32) + (eq_attr "mode" "RVVM1x3DI") (const_int 64) + (eq_attr "mode" "RVVM4x2DI") (const_int 16) + (eq_attr "mode" "RVVM2x2DI") (const_int 32) + (eq_attr "mode" "RVVM1x2DI") (const_int 64) + (eq_attr "mode" "RVVM1x8DF") (const_int 64) + (eq_attr "mode" "RVVM1x7DF") (const_int 64) + (eq_attr "mode" "RVVM1x6DF") (const_int 64) + (eq_attr "mode" "RVVM1x5DF") (const_int 64) + (eq_attr "mode" "RVVM2x4DF") (const_int 32) + (eq_attr "mode" "RVVM1x4DF") (const_int 64) + (eq_attr "mode" "RVVM2x3DF") (const_int 32) + (eq_attr "mode" "RVVM1x3DF") (const_int 64) + (eq_attr "mode" "RVVM4x2DF") (const_int 16) + (eq_attr "mode" "RVVM2x2DF") (const_int 32) + (eq_attr "mode" "RVVM1x2DF") (const_int 64)] (const_int INVALID_ATTRIBUTE))) ;; The index of operand[] to get the merge op. @@ -648,8 +867,8 @@ vector load/store. For example: - [(set (match_operand:VNx1QI v24) - (match_operand:VNx1QI (mem: a4))) + [(set (match_operand:RVVMF8QI v24) + (match_operand:RVVMF8QI (mem: a4))) (clobber (scratch:SI a5))] ====>> vsetvl a5,zero,e8,mf8 ====>> vle8.v v24,(a4) @@ -682,22 +901,22 @@ ;; create unexpected patterns in LRA. ;; For example: ;; ira rtl: -;; (insn 20 19 9 2 (set (reg/v:VNx2QI 97 v1 [ v1 ]) -;; (reg:VNx2QI 134 [ _1 ])) "rvv.c":9:22 571 {*movvnx2qi_fract} +;; (insn 20 19 9 2 (set (reg/v:RVVMF4QI 97 v1 [ v1 ]) +;; (reg:RVVMF4QI 134 [ _1 ])) "rvv.c":9:22 571 {*movvnx2qi_fract} ;; (nil)) ;; When the value of pseudo register 134 of the insn above is discovered already ;; spilled in the memory during LRA. ;; LRA will reload this pattern into a memory load instruction pattern. -;; Because VNx2QI is a fractional vector, we want LRA reload this pattern into +;; Because RVVMF4QI is a fractional vector, we want LRA reload this pattern into ;; (insn 20 19 9 2 (parallel [ -;; (set (reg:VNx2QI 98 v2 [orig:134 _1 ] [134]) -;; (mem/c:VNx2QI (reg:SI 13 a3 [155]) [1 %sfp+[-2, -2] S[2, 2] A8])) +;; (set (reg:RVVMF4QI 98 v2 [orig:134 _1 ] [134]) +;; (mem/c:RVVMF4QI (reg:SI 13 a3 [155]) [1 %sfp+[-2, -2] S[2, 2] A8])) ;; (clobber (reg:SI 14 a4 [149]))]) ;; So that we could be able to emit vsetvl instruction using clobber sratch a4. ;; To let LRA generate the expected pattern, we should exclude fractional vector ;; load/store in "*mov_whole". Otherwise, it will reload this pattern into: -;; (insn 20 19 9 2 (set (reg:VNx2QI 98 v2 [orig:134 _1 ] [134]) -;; (mem/c:VNx2QI (reg:SI 13 a3 [155]) [1 %sfp+[-2, -2] S[2, 2] A8]))) +;; (insn 20 19 9 2 (set (reg:RVVMF4QI 98 v2 [orig:134 _1 ] [134]) +;; (mem/c:RVVMF4QI (reg:SI 13 a3 [155]) [1 %sfp+[-2, -2] S[2, 2] A8]))) ;; which is not the pattern we want. ;; According the facts above, we make "*mov_whole" includes load/store/move for whole ;; vector modes according to '-march' and "*mov_fract" only include fractional vector modes. @@ -1090,28 +1309,28 @@ ;; constraint alternative 3 match vmv.v.v. ;; constraint alternative 4 match vmv.v.i. ;; For vmv.v.i, we allow 2 following cases: -;; 1. (const_vector:VNx1QI repeat [ +;; 1. (const_vector:RVVMF8QI repeat [ ;; (const_int:QI N)]), -15 <= N < 16. -;; 2. (const_vector:VNx1SF repeat [ +;; 2. (const_vector:RVVMF2SF repeat [ ;; (const_double:SF 0.0 [0x0.0p+0])]). ;; We add "MEM_P (operands[0]) || MEM_P (operands[3]) || CONST_VECTOR_P (operands[1])" here to ;; make sure we don't want CSE to generate the following pattern: -;; (insn 17 8 19 2 (set (reg:VNx1HI 134 [ _1 ]) -;; (if_then_else:VNx1HI (unspec:VNx1BI [ -;; (reg/v:VNx1BI 137 [ mask ]) +;; (insn 17 8 19 2 (set (reg:RVVMF4HI 134 [ _1 ]) +;; (if_then_else:RVVMF4HI (unspec:RVVM1BI [ +;; (reg/v:RVVM1BI 137 [ mask ]) ;; (reg:DI 151) ;; (const_int 0 [0]) repeated x3 ;; (reg:SI 66 vl) ;; (reg:SI 67 vtype) ;; ] UNSPEC_VPREDICATE) -;; (const_vector:VNx1HI repeat [ +;; (const_vector:RVVMF4HI repeat [ ;; (const_int 0 [0]) ;; ]) -;; (reg/v:VNx1HI 140 [ merge ]))) "rvv.c":8:12 608 {pred_movvnx1hi} +;; (reg/v:RVVMF4HI 140 [ merge ]))) "rvv.c":8:12 608 {pred_movvnx1hi} ;; (expr_list:REG_DEAD (reg:DI 151) -;; (expr_list:REG_DEAD (reg/v:VNx1HI 140 [ merge ]) -;; (expr_list:REG_DEAD (reg/v:VNx1BI 137 [ mask ]) +;; (expr_list:REG_DEAD (reg/v:RVVMF4HI 140 [ merge ]) +;; (expr_list:REG_DEAD (reg/v:RVVM1BI 137 [ mask ]) ;; (nil))))) ;; Since both vmv.v.v and vmv.v.i doesn't have mask operand. (define_insn_and_split "@pred_mov" @@ -1713,7 +1932,7 @@ [(set_attr "type" "vldx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1723,14 +1942,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX1_QHSDI 2 "register_operand" " vr") - (match_operand:VNX1_QHSD 3 "register_operand" " vr")] ORDER))] + (match_operand:RATIO64I 2 "register_operand" " vr") + (match_operand:RATIO64 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" + "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1740,14 +1959,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX2_QHSDI 2 "register_operand" " vr") - (match_operand:VNX2_QHSD 3 "register_operand" " vr")] ORDER))] + (match_operand:RATIO32I 2 "register_operand" " vr") + (match_operand:RATIO32 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" + "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1757,14 +1976,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX4_QHSDI 2 "register_operand" " vr") - (match_operand:VNX4_QHSD 3 "register_operand" " vr")] ORDER))] + (match_operand:RATIO16I 2 "register_operand" " vr") + (match_operand:RATIO16 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" + "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1774,14 +1993,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX8_QHSDI 2 "register_operand" " vr") - (match_operand:VNX8_QHSD 3 "register_operand" " vr")] ORDER))] + (match_operand:RATIO8I 2 "register_operand" " vr") + (match_operand:RATIO8 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" + "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1791,14 +2010,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX16_QHSDI 2 "register_operand" " vr") - (match_operand:VNX16_QHSD 3 "register_operand" " vr")] ORDER))] + (match_operand:RATIO4I 2 "register_operand" " vr") + (match_operand:RATIO4 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" + "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1808,14 +2027,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX32_QHSI 2 "register_operand" " vr") - (match_operand:VNX32_QHS 3 "register_operand" " vr")] ORDER))] + (match_operand:RATIO2I 2 "register_operand" " vr") + (match_operand:RATIO2 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" + "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -1825,29 +2044,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX64_QHI 2 "register_operand" " vr") - (match_operand:VNX64_QH 3 "register_operand" " vr")] ORDER))] + (match_operand:RATIO1 2 "register_operand" " vr") + (match_operand:RATIO1 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" + "vsxei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vstx") - (set_attr "mode" "")]) - -(define_insn "@pred_indexed_store" - [(set (mem:BLK (scratch)) - (unspec:BLK - [(unspec: - [(match_operand: 0 "vector_mask_operand" "vmWc1") - (match_operand 4 "vector_length_operand" " rK") - (match_operand 5 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:VNX128_Q 2 "register_operand" " vr") - (match_operand:VNX128_Q 3 "register_operand" " vr")] ORDER))] - "TARGET_VECTOR" - "vsxei.v\t%3,(%z1),%2%p0" - [(set_attr "type" "vstx") - (set_attr "mode" "")]) + (set_attr "mode" "")]) ;; ------------------------------------------------------------------------------- ;; ---- Predicated integer binary operations @@ -7426,8 +7628,6 @@ ;; and the MIN_VLEN >= 128 from the well defined iterators. ;; Since reduction need LMUL = 1 scalar operand as the input operand ;; and they are different. -;; For example, The LMUL = 1 corresponding mode of VNx16QImode is VNx4QImode -;; for -march=rv*zve32* wheras VNx8QImode for -march=rv*zve64* ;; Integer Reduction for QI (define_insn "@pred_reduc_" @@ -8481,7 +8681,7 @@ [(set_attr "type" "vlsegdff") (set_attr "mode" "")]) -(define_insn "@pred_indexed_load" +(define_insn "@pred_indexed_load" [(set (match_operand:V1T 0 "register_operand" "=&vr, &vr") (if_then_else:V1T (unspec: @@ -8495,14 +8695,14 @@ (unspec:V1T [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ") (mem:BLK (scratch)) - (match_operand:V1I 4 "register_operand" " vr, vr")] ORDER) + (match_operand:RATIO64I 4 "register_operand" " vr, vr")] ORDER) (match_operand:V1T 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" - "vlxsegei.v\t%0,(%z3),%4%p1" + "vlxsegei.v\t%0,(%z3),%4%p1" [(set_attr "type" "vlsegdx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_load" +(define_insn "@pred_indexed_load" [(set (match_operand:V2T 0 "register_operand" "=&vr, &vr") (if_then_else:V2T (unspec: @@ -8516,14 +8716,14 @@ (unspec:V2T [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ") (mem:BLK (scratch)) - (match_operand:V2I 4 "register_operand" " vr, vr")] ORDER) + (match_operand:RATIO32I 4 "register_operand" " vr, vr")] ORDER) (match_operand:V2T 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" - "vlxsegei.v\t%0,(%z3),%4%p1" + "vlxsegei.v\t%0,(%z3),%4%p1" [(set_attr "type" "vlsegdx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_load" +(define_insn "@pred_indexed_load" [(set (match_operand:V4T 0 "register_operand" "=&vr, &vr") (if_then_else:V4T (unspec: @@ -8537,14 +8737,14 @@ (unspec:V4T [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ") (mem:BLK (scratch)) - (match_operand:V4I 4 "register_operand" " vr, vr")] ORDER) + (match_operand:RATIO16I 4 "register_operand" " vr, vr")] ORDER) (match_operand:V4T 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" - "vlxsegei.v\t%0,(%z3),%4%p1" + "vlxsegei.v\t%0,(%z3),%4%p1" [(set_attr "type" "vlsegdx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_load" +(define_insn "@pred_indexed_load" [(set (match_operand:V8T 0 "register_operand" "=&vr, &vr") (if_then_else:V8T (unspec: @@ -8558,14 +8758,14 @@ (unspec:V8T [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ") (mem:BLK (scratch)) - (match_operand:V8I 4 "register_operand" " vr, vr")] ORDER) + (match_operand:RATIO8I 4 "register_operand" " vr, vr")] ORDER) (match_operand:V8T 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" - "vlxsegei.v\t%0,(%z3),%4%p1" + "vlxsegei.v\t%0,(%z3),%4%p1" [(set_attr "type" "vlsegdx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_load" +(define_insn "@pred_indexed_load" [(set (match_operand:V16T 0 "register_operand" "=&vr, &vr") (if_then_else:V16T (unspec: @@ -8579,14 +8779,14 @@ (unspec:V16T [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ") (mem:BLK (scratch)) - (match_operand:V16I 4 "register_operand" " vr, vr")] ORDER) + (match_operand:RATIO4I 4 "register_operand" " vr, vr")] ORDER) (match_operand:V16T 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" - "vlxsegei.v\t%0,(%z3),%4%p1" + "vlxsegei.v\t%0,(%z3),%4%p1" [(set_attr "type" "vlsegdx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_load" +(define_insn "@pred_indexed_load" [(set (match_operand:V32T 0 "register_operand" "=&vr, &vr") (if_then_else:V32T (unspec: @@ -8600,35 +8800,14 @@ (unspec:V32T [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ") (mem:BLK (scratch)) - (match_operand:V32I 4 "register_operand" " vr, vr")] ORDER) + (match_operand:RATIO2I 4 "register_operand" " vr, vr")] ORDER) (match_operand:V32T 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" - "vlxsegei.v\t%0,(%z3),%4%p1" + "vlxsegei.v\t%0,(%z3),%4%p1" [(set_attr "type" "vlsegdx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_load" - [(set (match_operand:V64T 0 "register_operand" "=&vr, &vr") - (if_then_else:V64T - (unspec: - [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (match_operand 8 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (unspec:V64T - [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ") - (mem:BLK (scratch)) - (match_operand:V64I 4 "register_operand" " vr, vr")] ORDER) - (match_operand:V64T 2 "vector_merge_operand" " vu, 0")))] - "TARGET_VECTOR" - "vlxsegei.v\t%0,(%z3),%4%p1" - [(set_attr "type" "vlsegdx") - (set_attr "mode" "")]) - -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -8638,14 +8817,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:V1I 2 "register_operand" " vr") + (match_operand:RATIO64I 2 "register_operand" " vr") (match_operand:V1T 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxsegei.v\t%3,(%z1),%2%p0" + "vsxsegei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vssegtx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -8655,14 +8834,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:V2I 2 "register_operand" " vr") + (match_operand:RATIO32I 2 "register_operand" " vr") (match_operand:V2T 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxsegei.v\t%3,(%z1),%2%p0" + "vsxsegei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vssegtx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -8672,14 +8851,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:V4I 2 "register_operand" " vr") + (match_operand:RATIO16I 2 "register_operand" " vr") (match_operand:V4T 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxsegei.v\t%3,(%z1),%2%p0" + "vsxsegei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vssegtx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -8689,14 +8868,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:V8I 2 "register_operand" " vr") + (match_operand:RATIO8I 2 "register_operand" " vr") (match_operand:V8T 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxsegei.v\t%3,(%z1),%2%p0" + "vsxsegei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vssegtx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -8706,14 +8885,14 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:V16I 2 "register_operand" " vr") + (match_operand:RATIO4I 2 "register_operand" " vr") (match_operand:V16T 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxsegei.v\t%3,(%z1),%2%p0" + "vsxsegei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vssegtx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" +(define_insn "@pred_indexed_store" [(set (mem:BLK (scratch)) (unspec:BLK [(unspec: @@ -8723,29 +8902,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:V32I 2 "register_operand" " vr") + (match_operand:RATIO2I 2 "register_operand" " vr") (match_operand:V32T 3 "register_operand" " vr")] ORDER))] "TARGET_VECTOR" - "vsxsegei.v\t%3,(%z1),%2%p0" + "vsxsegei.v\t%3,(%z1),%2%p0" [(set_attr "type" "vssegtx") (set_attr "mode" "")]) -(define_insn "@pred_indexed_store" - [(set (mem:BLK (scratch)) - (unspec:BLK - [(unspec: - [(match_operand: 0 "vector_mask_operand" "vmWc1") - (match_operand 4 "vector_length_operand" " rK") - (match_operand 5 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand 1 "pmode_reg_or_0_operand" " rJ") - (match_operand:V64I 2 "register_operand" " vr") - (match_operand:V64T 3 "register_operand" " vr")] ORDER))] - "TARGET_VECTOR" - "vsxsegei.v\t%3,(%z1),%2%p0" - [(set_attr "type" "vssegtx") - (set_attr "mode" "")]) - (include "autovec.md") (include "autovec-opt.md") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c index c162879..3f7ffbd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c @@ -1,5 +1,9 @@ /* { dg-do run { target { riscv_vector } } } */ - +/* For some reason we exceed + the default code model's +-2 GiB limits. We should investigate why and + add a proper description here. For now just make sure the test case + compiles properly. */ +/* { dg-additional-options "-mcmodel=medany" } */ #include "gather_load-7.c" #include diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c index e1744f6..1bcab84 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c @@ -1,5 +1,9 @@ /* { dg-do run { target { riscv_vector } } } */ - +/* For some reason we exceed + the default code model's +-2 GiB limits. We should investigate why and + add a proper description here. For now just make sure the test case + compiles properly. */ +/* { dg-additional-options "-mcmodel=medany" } */ #include "gather_load-8.c" #include diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c index 77a9af9..a21ccd5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c @@ -1,5 +1,10 @@ /* { dg-do compile } */ /* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d -fdump-tree-vect-details" } */ +/* For some reason we exceed + the default code model's +-2 GiB limits. We should investigate why and + add a proper description here. For now just make sure the test case + compiles properly. */ +/* { dg-additional-options "-mcmodel=medany" } */ #include diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c index 8ee35d2..da688f3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c @@ -1,5 +1,9 @@ /* { dg-do run { target { riscv_vector } } } */ - +/* For some reason we exceed + the default code model's +-2 GiB limits. We should investigate why and + add a proper description here. For now just make sure the test case + compiles properly. */ +/* { dg-additional-options "-mcmodel=medany" } */ #include "mask_scatter_store-8.c" #include diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c index 080c9b8..f74b96e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c @@ -1,5 +1,9 @@ /* { dg-do run { target { riscv_vector } } } */ - +/* For some reason we exceed + the default code model's +-2 GiB limits. We should investigate why and + add a proper description here. For now just make sure the test case + compiles properly. */ +/* { dg-additional-options "-mcmodel=medany" } */ #include "scatter_store-8.c" #include -- cgit v1.1 From 38daaaa91438d3f635a10bf5d5181c3b29f07df9 Mon Sep 17 00:00:00 2001 From: Haochen Jiang Date: Thu, 20 Jul 2023 10:47:18 +0800 Subject: Correct Granite Rapids{, D} documentation gcc/Changelog: * doc/invoke.texi: Remove AVX512VP2INTERSECT in Granite Rapids{, D} from documentation. --- gcc/doc/invoke.texi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 88e3c62..d3c821e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -32697,9 +32697,9 @@ RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB, -MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, -SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, -AVX512BF16, AMX-FP16 and PREFETCHI instruction set support. +MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, +UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, AVX512BF16, AMX-FP16 +and PREFETCHI instruction set support. @item graniterapids-d Intel graniterapids D CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, @@ -32708,9 +32708,9 @@ RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB, -MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, -SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, -AVX512BF16, AMX-FP16, PREFETCHI and AMX-COMPLEX instruction set support. +MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, +UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, AVX512BF16, AMX-FP16, +PREFETCHI and AMX-COMPLEX instruction set support. @item k6 AMD K6 CPU with MMX instruction set support. -- cgit v1.1 From b2cfe5233e682fc04a9b6fc91f3d30685515630b Mon Sep 17 00:00:00 2001 From: Lewis Hyatt Date: Wed, 19 Jul 2023 22:07:54 -0400 Subject: testsuite: Fix C++ UDL tests failing on 32-bit arch [PR103902] These tests need to use "size_t" rather than "unsigned long" for the user-defined literal function arguments. gcc/testsuite/ChangeLog: PR preprocessor/103902 * g++.dg/cpp0x/udlit-extended-id-1.C: Change "unsigned long" to "size_t" throughout. * g++.dg/cpp0x/udlit-extended-id-3.C: Likewise. --- gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C | 9 +++++---- gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C | 6 ++++-- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C index 5ea5ef0..c7091e9 100644 --- a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C @@ -1,6 +1,7 @@ // { dg-do run { target c++11 } } // { dg-additional-options "-Wno-error=normalized" } #include +#include using namespace std; constexpr unsigned long long operator "" _π (unsigned long long x) @@ -21,22 +22,22 @@ char x2[2_Π2]; static_assert (sizeof x1 == 3, "test1"); static_assert (sizeof x2 == 8, "test2"); -const char * operator "" _1σ (const char *s, unsigned long) +const char * operator "" _1σ (const char *s, size_t) { return s + 1; } -const char * operator ""_Σ2 (const char *s, unsigned long) +const char * operator ""_Σ2 (const char *s, size_t) { return s + 2; } -const char * operator "" _\U000000e61 (const char *s, unsigned long) +const char * operator "" _\U000000e61 (const char *s, size_t) { return "ae"; } -const char* operator ""_\u01532 (const char *s, unsigned long) +const char* operator ""_\u01532 (const char *s, size_t) { return "oe"; } diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C index 11292e4..cb8a957 100644 --- a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C @@ -1,9 +1,11 @@ // { dg-do compile { target c++11 } } +#include +using namespace std; // Check that we do not look for poisoned identifier when it is a suffix. int _ħ; #pragma GCC poison _ħ -const char * operator ""_ħ (const char *, unsigned long); // { dg-bogus "poisoned" } +const char * operator ""_ħ (const char *, size_t); // { dg-bogus "poisoned" } bool operator ""_ħ (unsigned long long x); // { dg-bogus "poisoned" } bool b = 1_ħ; // { dg-bogus "poisoned" } const char *x = "hbar"_ħ; // { dg-bogus "poisoned" } @@ -11,5 +13,5 @@ const char *x = "hbar"_ħ; // { dg-bogus "poisoned" } /* Ideally, we should not warn here either, but this is not implemented yet. This syntax has been deprecated for C++23. */ #pragma GCC poison _ħ2 -const char * operator "" _ħ2 (const char *, unsigned long); // { dg-bogus "poisoned" "" { xfail *-*-*} } +const char * operator "" _ħ2 (const char *, size_t); // { dg-bogus "poisoned" "" { xfail *-*-*} } const char *x2 = "hbar2"_ħ2; // { dg-bogus "poisoned" } -- cgit v1.1 From bb0da4542df887a530d5a75e08abf5cbb821fe6b Mon Sep 17 00:00:00 2001 From: Pan Li Date: Thu, 20 Jul 2023 14:29:47 +0800 Subject: RISC-V: Align the pattern format in vector.md There are some format-unaligned pattern in vector.md, this patch would like to align the format for these patterns. Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/vector.md: Align pattern format. --- gcc/config/riscv/vector.md | 850 ++++++++++++++++----------------------------- 1 file changed, 297 insertions(+), 553 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 69680de..fcff3ee3 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -669,61 +669,45 @@ ;; Defines rounding mode of an fixed-point operation. (define_attr "vxrm_mode" "rnu,rne,rdn,rod,none" - (cond - [ - (eq_attr "type" "vsalu,vaalu,vsmul,vsshift,vnclip") - (cond - [ - (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RNU") - (const_string "rnu") - - (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RNE") - (const_string "rne") - - (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RDN") - (const_string "rdn") - - (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_ROD") - (const_string "rod") - ] - (const_string "none") - ) - ] - (const_string "none") - ) -) + (cond [(eq_attr "type" "vsalu,vaalu,vsmul,vsshift,vnclip") + (cond + [(match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RNU") + (const_string "rnu") + + (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RNE") + (const_string "rne") + + (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_RDN") + (const_string "rdn") + + (match_test "INTVAL (operands[9]) == riscv_vector::VXRM_ROD") + (const_string "rod")] + (const_string "none"))] + (const_string "none"))) ;; Defines rounding mode of an floating-point operation. (define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,dyn_exit,none" - (cond - [ - (eq_attr "type" "vfalu") - (cond - [ - (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RNE") - (const_string "rne") - - (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RTZ") - (const_string "rtz") - - (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RDN") - (const_string "rdn") - - (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RUP") - (const_string "rup") - - (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RMM") - (const_string "rmm") - - (match_test "INTVAL (operands[9]) == riscv_vector::FRM_DYN") - (const_string "dyn") - ] - (const_string "none") - ) - ] - (const_string "none") - ) -) + (cond [(eq_attr "type" "vfalu") + (cond + [(match_test "INTVAL (operands[9]) == riscv_vector::FRM_RNE") + (const_string "rne") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RTZ") + (const_string "rtz") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RDN") + (const_string "rdn") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RUP") + (const_string "rup") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RMM") + (const_string "rmm") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_DYN") + (const_string "dyn")] + (const_string "none"))] + (const_string "none"))) ;; ----------------------------------------------------------------- ;; ---- Miscellaneous Operations @@ -7631,583 +7615,343 @@ ;; Integer Reduction for QI (define_insn "@pred_reduc_" - [ - (set - (match_operand:VQI_LMUL1 0 "register_operand" "=vr, vr") - (unspec:VQI_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (any_reduc:VQI - (vec_duplicate:VQI - (vec_select: - (match_operand:VQI_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VQI 3 "register_operand" " vr, vr") - ) - (match_operand:VQI_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ) - ] + [(set (match_operand:VQI_LMUL1 0 "register_operand" "=vr, vr") + (unspec:VQI_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_reduc:VQI + (vec_duplicate:VQI + (vec_select: + (match_operand:VQI_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VQI 3 "register_operand" " vr, vr")) + (match_operand:VQI_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC))] "TARGET_VECTOR" "vred.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vired") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vired") + (set_attr "mode" "")]) ;; Integer Reduction for HI (define_insn "@pred_reduc_" - [ - (set - (match_operand:VHI_LMUL1 0 "register_operand" "=vr, vr") - (unspec:VHI_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (any_reduc:VHI - (vec_duplicate:VHI - (vec_select: - (match_operand:VHI_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VHI 3 "register_operand" " vr, vr") - ) - (match_operand:VHI_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ) - ] + [(set (match_operand:VHI_LMUL1 0 "register_operand" "=vr, vr") + (unspec:VHI_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_reduc:VHI + (vec_duplicate:VHI + (vec_select: + (match_operand:VHI_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VHI 3 "register_operand" " vr, vr")) + (match_operand:VHI_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC))] "TARGET_VECTOR" "vred.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vired") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vired") + (set_attr "mode" "")]) ;; Integer Reduction for SI (define_insn "@pred_reduc_" - [ - (set - (match_operand:VSI_LMUL1 0 "register_operand" "=vr, vr") - (unspec:VSI_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (any_reduc:VSI - (vec_duplicate:VSI - (vec_select: - (match_operand:VSI_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VSI 3 "register_operand" " vr, vr") - ) - (match_operand:VSI_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ) - ] + [(set (match_operand:VSI_LMUL1 0 "register_operand" "=vr, vr") + (unspec:VSI_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_reduc:VSI + (vec_duplicate:VSI + (vec_select: + (match_operand:VSI_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VSI 3 "register_operand" " vr, vr")) + (match_operand:VSI_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC))] "TARGET_VECTOR" "vred.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vired") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vired") + (set_attr "mode" "")]) ;; Integer Reduction for DI (define_insn "@pred_reduc_" - [ - (set - (match_operand:VDI_LMUL1 0 "register_operand" "=vr, vr") - (unspec:VDI_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (any_reduc:VDI - (vec_duplicate:VDI - (vec_select: - (match_operand:VDI_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VDI 3 "register_operand" " vr, vr") - ) - (match_operand:VDI_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ) - ] + [(set (match_operand:VDI_LMUL1 0 "register_operand" "=vr, vr") + (unspec:VDI_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_reduc:VDI + (vec_duplicate:VDI + (vec_select: + (match_operand:VDI_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VDI 3 "register_operand" " vr, vr")) + (match_operand:VDI_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC))] "TARGET_VECTOR" "vred.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vired") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vired") + (set_attr "mode" "")]) ;; Integer Reduction Widen for QI, HI = QI op HI (define_insn "@pred_widen_reduc_plus" - [ - (set - (match_operand:VHI_LMUL1 0 "register_operand" "=&vr,&vr") - (unspec:VHI_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (match_operand:VQI 3 "register_operand" " vr, vr") - (match_operand:VHI_LMUL1 4 "register_operand" " vr, vr") - (match_operand:VHI_LMUL1 2 "vector_merge_operand" " vu, 0") - ] WREDUC - ) - ) - ] + [(set (match_operand:VHI_LMUL1 0 "register_operand" "=&vr,&vr") + (unspec:VHI_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:VQI 3 "register_operand" " vr, vr") + (match_operand:VHI_LMUL1 4 "register_operand" " vr, vr") + (match_operand:VHI_LMUL1 2 "vector_merge_operand" " vu, 0")] WREDUC))] "TARGET_VECTOR" "vwredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "viwred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "viwred") + (set_attr "mode" "")]) ;; Integer Reduction Widen for HI, SI = HI op SI (define_insn "@pred_widen_reduc_plus" - [ - (set - (match_operand:VSI_LMUL1 0 "register_operand" "=&vr,&vr") - (unspec:VSI_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (match_operand:VHI 3 "register_operand" " vr, vr") - (match_operand:VSI_LMUL1 4 "register_operand" " vr, vr") - (match_operand:VSI_LMUL1 2 "vector_merge_operand" " vu, 0") - ] WREDUC - ) - ) - ] + [(set (match_operand:VSI_LMUL1 0 "register_operand" "=&vr,&vr") + (unspec:VSI_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:VHI 3 "register_operand" " vr, vr") + (match_operand:VSI_LMUL1 4 "register_operand" " vr, vr") + (match_operand:VSI_LMUL1 2 "vector_merge_operand" " vu, 0")] WREDUC))] "TARGET_VECTOR" "vwredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "viwred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "viwred") + (set_attr "mode" "")]) ;; Integer Reduction Widen for SI, DI = SI op DI (define_insn "@pred_widen_reduc_plus" - [ - (set - (match_operand:VDI_LMUL1 0 "register_operand" "=&vr,&vr") - (unspec:VDI_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (match_operand:VSI 3 "register_operand" " vr, vr") - (match_operand:VDI_LMUL1 4 "register_operand" " vr, vr") - (match_operand:VDI_LMUL1 2 "vector_merge_operand" " vu, 0") - ] WREDUC - ) - ) - ] + [(set (match_operand:VDI_LMUL1 0 "register_operand" "=&vr,&vr") + (unspec:VDI_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:VSI 3 "register_operand" " vr, vr") + (match_operand:VDI_LMUL1 4 "register_operand" " vr, vr") + (match_operand:VDI_LMUL1 2 "vector_merge_operand" " vu, 0")] WREDUC))] "TARGET_VECTOR" "vwredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "viwred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "viwred") + (set_attr "mode" "")]) ;; Float Reduction for HF (define_insn "@pred_reduc_" - [ - (set - (match_operand:VHF_LMUL1 0 "register_operand" "=vr, vr") - (unspec:VHF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (any_reduc:VHF - (vec_duplicate:VHF - (vec_select: - (match_operand:VHF_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VHF 3 "register_operand" " vr, vr") - ) - (match_operand:VHF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ) - ] + [(set (match_operand:VHF_LMUL1 0 "register_operand" "=vr, vr") + (unspec:VHF_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_reduc:VHF + (vec_duplicate:VHF + (vec_select: + (match_operand:VHF_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VHF 3 "register_operand" " vr, vr")) + (match_operand:VHF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC))] "TARGET_VECTOR" "vfred.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfredu") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfredu") + (set_attr "mode" "")]) ;; Float Reduction for SF (define_insn "@pred_reduc_" - [ - (set - (match_operand:VSF_LMUL1 0 "register_operand" "=vr, vr") + [(set (match_operand:VSF_LMUL1 0 "register_operand" "=vr, vr") (unspec:VSF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (any_reduc:VSF + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_reduc:VSF (vec_duplicate:VSF (vec_select: (match_operand:VSF_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VSF 3 "register_operand" " vr, vr") - ) - (match_operand:VSF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ) - ] + (parallel [(const_int 0)]))) + (match_operand:VSF 3 "register_operand" " vr, vr")) + (match_operand:VSF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC))] "TARGET_VECTOR" "vfred.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfredu") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfredu") + (set_attr "mode" "")]) ;; Float Reduction for DF (define_insn "@pred_reduc_" - [ - (set - (match_operand:VDF_LMUL1 0 "register_operand" "=vr, vr") - (unspec:VDF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - ] UNSPEC_VPREDICATE - ) - (any_reduc:VDF - (vec_duplicate:VDF - (vec_select: - (match_operand:VDF_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VDF 3 "register_operand" " vr, vr") - ) - (match_operand:VDF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ) - ] + [(set (match_operand:VDF_LMUL1 0 "register_operand" "=vr, vr") + (unspec:VDF_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_reduc:VDF + (vec_duplicate:VDF + (vec_select: + (match_operand:VDF_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VDF 3 "register_operand" " vr, vr")) + (match_operand:VDF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC))] "TARGET_VECTOR" "vfred.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfredu") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfredu") + (set_attr "mode" "")]) ;; Float Ordered Reduction Sum for HF (define_insn "@pred_reduc_plus" - [ - (set - (match_operand:VHF_LMUL1 0 "register_operand" "=vr,vr") - (unspec:VHF_LMUL1 - [ - (unspec:VHF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (match_operand 8 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM) - ] UNSPEC_VPREDICATE - ) - (plus:VHF - (vec_duplicate:VHF - (vec_select: - (match_operand:VHF_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VHF 3 "register_operand" " vr, vr") - ) - (match_operand:VHF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ] ORDER - ) - ) - ] + [(set (match_operand:VHF_LMUL1 0 "register_operand" "=vr,vr") + (unspec:VHF_LMUL1 + [(unspec:VHF_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (plus:VHF + (vec_duplicate:VHF + (vec_select: + (match_operand:VHF_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VHF 3 "register_operand" " vr, vr")) + (match_operand:VHF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC)] ORDER))] "TARGET_VECTOR" "vfredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfred") + (set_attr "mode" "")]) ;; Float Ordered Reduction Sum for SF (define_insn "@pred_reduc_plus" - [ - (set - (match_operand:VSF_LMUL1 0 "register_operand" "=vr,vr") - (unspec:VSF_LMUL1 - [ - (unspec:VSF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (match_operand 8 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM) - ] UNSPEC_VPREDICATE - ) - (plus:VSF - (vec_duplicate:VSF - (vec_select: - (match_operand:VSF_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VSF 3 "register_operand" " vr, vr") - ) - (match_operand:VSF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ] ORDER - ) - ) - ] + [(set (match_operand:VSF_LMUL1 0 "register_operand" "=vr,vr") + (unspec:VSF_LMUL1 + [(unspec:VSF_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (plus:VSF + (vec_duplicate:VSF + (vec_select: + (match_operand:VSF_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VSF 3 "register_operand" " vr, vr")) + (match_operand:VSF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC)] ORDER))] "TARGET_VECTOR" "vfredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfred") + (set_attr "mode" "")]) ;; Float Ordered Reduction Sum for DF (define_insn "@pred_reduc_plus" - [ - (set - (match_operand:VDF_LMUL1 0 "register_operand" "=vr,vr") - (unspec:VDF_LMUL1 - [ - (unspec:VDF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (match_operand 8 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM) - ] UNSPEC_VPREDICATE - ) - (plus:VDF - (vec_duplicate:VDF - (vec_select: - (match_operand:VDF_LMUL1 4 "register_operand" " vr, vr") - (parallel [(const_int 0)]) - ) - ) - (match_operand:VDF 3 "register_operand" " vr, vr") - ) - (match_operand:VDF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_REDUC - ) - ] ORDER - ) - ) - ] + [(set (match_operand:VDF_LMUL1 0 "register_operand" "=vr,vr") + (unspec:VDF_LMUL1 + [(unspec:VDF_LMUL1 + [(unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (plus:VDF + (vec_duplicate:VDF + (vec_select: + (match_operand:VDF_LMUL1 4 "register_operand" " vr, vr") + (parallel [(const_int 0)]))) + (match_operand:VDF 3 "register_operand" " vr, vr")) + (match_operand:VDF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_REDUC)] ORDER))] "TARGET_VECTOR" "vfredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfred") + (set_attr "mode" "")]) ;; Float Widen Reduction for HF, aka SF = HF op SF (define_insn "@pred_widen_reduc_plus" - [ - (set - (match_operand:VSF_LMUL1 0 "register_operand" "=&vr, &vr") - (unspec:VSF_LMUL1 - [ - (unspec:VSF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_merge_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (match_operand 8 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM) - ] UNSPEC_VPREDICATE - ) - (match_operand:VHF 3 "register_operand" " vr, vr") - (match_operand:VSF_LMUL1 4 "register_operand" " vr, vr") - (match_operand:VSF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_WREDUC_SUM - ) - ] ORDER - ) - ) - ] + [(set (match_operand:VSF_LMUL1 0 "register_operand" "=&vr, &vr") + (unspec:VSF_LMUL1 + [(unspec:VSF_LMUL1 + [(unspec: + [(match_operand: 1 "vector_merge_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:VHF 3 "register_operand" " vr, vr") + (match_operand:VSF_LMUL1 4 "register_operand" " vr, vr") + (match_operand:VSF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_WREDUC_SUM)] ORDER))] "TARGET_VECTOR" "vfwredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfwred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfwred") + (set_attr "mode" "")]) ;; Float Widen Reduction for SF, aka DF = SF * DF (define_insn "@pred_widen_reduc_plus" - [ - (set - (match_operand:VDF_LMUL1 0 "register_operand" "=&vr, &vr") - (unspec:VDF_LMUL1 - [ - (unspec:VDF_LMUL1 - [ - (unspec: - [ - (match_operand: 1 "vector_merge_operand" "vmWc1,vmWc1") - (match_operand 5 "vector_length_operand" " rK, rK") - (match_operand 6 "const_int_operand" " i, i") - (match_operand 7 "const_int_operand" " i, i") - (match_operand 8 "const_int_operand" " i, i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM) - ] UNSPEC_VPREDICATE - ) - (match_operand:VSF 3 "register_operand" " vr, vr") - (match_operand:VDF_LMUL1 4 "register_operand" " vr, vr") - (match_operand:VDF_LMUL1 2 "vector_merge_operand" " vu, 0") - ] UNSPEC_WREDUC_SUM - ) - ] ORDER - ) - ) - ] + [(set (match_operand:VDF_LMUL1 0 "register_operand" "=&vr, &vr") + (unspec:VDF_LMUL1 + [(unspec:VDF_LMUL1 + [(unspec: + [(match_operand: 1 "vector_merge_operand" "vmWc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:VSF 3 "register_operand" " vr, vr") + (match_operand:VDF_LMUL1 4 "register_operand" " vr, vr") + (match_operand:VDF_LMUL1 2 "vector_merge_operand" " vu, 0")] UNSPEC_WREDUC_SUM)] ORDER))] "TARGET_VECTOR" "vfwredsum.vs\t%0,%3,%4%p1" - [ - (set_attr "type" "vfwred") - (set_attr "mode" "") - ] -) + [(set_attr "type" "vfwred") + (set_attr "mode" "")]) ;; ------------------------------------------------------------------------------- ;; ---- Predicated permutation operations -- cgit v1.1 From ceae1400cf24f329393e96dd9720b0391afe858d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 18 Jul 2023 13:19:11 +0200 Subject: middle-end/61747 - conditional move expansion and constants When expanding a COND_EXPR or a VEC_COND_EXPR the x86 backend for example tries to match FP min/max instructions. But this only works when it can see the equality of the comparison and selected operands. This breaks in both prepare_cmp_insn and vector_compare_rtx where the former forces expensive constants to a register and the latter performs legitimization. The patch below fixes this in the caller preserving former equalities. PR middle-end/61747 * internal-fn.cc (expand_vec_cond_optab_fn): When the value operands are equal to the original comparison operands preserve that equality by re-using the comparison expansion. * optabs.cc (emit_conditional_move): When the value operands are equal to the comparison operands and would be forced to a register by prepare_cmp_insn do so earlier, preserving the equality. * g++.target/i386/pr61747.C: New testcase. --- gcc/internal-fn.cc | 17 +++++++++++-- gcc/optabs.cc | 30 ++++++++++++++++++++++- gcc/testsuite/g++.target/i386/pr61747.C | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/pr61747.C (limited to 'gcc') diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 2bf4fc4..1b34d4d 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -3020,8 +3020,21 @@ expand_vec_cond_optab_fn (internal_fn, gcall *stmt, convert_optab optab) icode = convert_optab_handler (optab, mode, cmp_op_mode); rtx comparison = vector_compare_rtx (VOIDmode, tcode, op0a, op0b, unsignedp, icode, 4); - rtx rtx_op1 = expand_normal (op1); - rtx rtx_op2 = expand_normal (op2); + /* vector_compare_rtx legitimizes operands, preserve equality when + expanding op1/op2. */ + rtx rtx_op1, rtx_op2; + if (operand_equal_p (op1, op0a)) + rtx_op1 = XEXP (comparison, 0); + else if (operand_equal_p (op1, op0b)) + rtx_op1 = XEXP (comparison, 1); + else + rtx_op1 = expand_normal (op1); + if (operand_equal_p (op2, op0a)) + rtx_op2 = XEXP (comparison, 0); + else if (operand_equal_p (op2, op0b)) + rtx_op2 = XEXP (comparison, 1); + else + rtx_op2 = expand_normal (op2); rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); create_output_operand (&ops[0], target, mode); diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 4e9f58f..32ff379 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -5119,13 +5119,41 @@ emit_conditional_move (rtx target, struct rtx_comparison comp, last = get_last_insn (); do_pending_stack_adjust (); machine_mode cmpmode = comp.mode; + rtx orig_op0 = XEXP (comparison, 0); + rtx orig_op1 = XEXP (comparison, 1); + rtx op2p = op2; + rtx op3p = op3; + /* If we are optimizing, force expensive constants into a register + but preserve an eventual equality with op2/op3. */ + if (CONSTANT_P (orig_op0) && optimize + && (rtx_cost (orig_op0, mode, COMPARE, 0, + optimize_insn_for_speed_p ()) + > COSTS_N_INSNS (1)) + && can_create_pseudo_p ()) + { + if (rtx_equal_p (orig_op0, op2)) + op2p = XEXP (comparison, 0) = force_reg (cmpmode, orig_op0); + else if (rtx_equal_p (orig_op0, op3)) + op3p = XEXP (comparison, 0) = force_reg (cmpmode, orig_op0); + } + if (CONSTANT_P (orig_op1) && optimize + && (rtx_cost (orig_op1, mode, COMPARE, 0, + optimize_insn_for_speed_p ()) + > COSTS_N_INSNS (1)) + && can_create_pseudo_p ()) + { + if (rtx_equal_p (orig_op1, op2)) + op2p = XEXP (comparison, 1) = force_reg (cmpmode, orig_op1); + else if (rtx_equal_p (orig_op1, op3)) + op3p = XEXP (comparison, 1) = force_reg (cmpmode, orig_op1); + } prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN, &comparison, &cmpmode); if (comparison) { rtx res = emit_conditional_move_1 (target, comparison, - op2, op3, mode); + op2p, op3p, mode); if (res != NULL_RTX) return res; } diff --git a/gcc/testsuite/g++.target/i386/pr61747.C b/gcc/testsuite/g++.target/i386/pr61747.C new file mode 100644 index 0000000..024ef40 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr61747.C @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target c++11 } */ +/* { dg-options "-O2 -msse4.1 -mfpmath=sse" } */ + +typedef float __attribute__( ( vector_size( 16 ) ) ) float32x4_t; + +template +V1 vmax(V1 a, V1 b) { + return (a>b) ? a : b; +} + +template +V1 vmin(V1 a, V1 b) { + return (a +Float bart(Float a) { + constexpr Float zero{0.f}; + constexpr Float it = zero+4.f; + constexpr Float zt = zero-3.f; + return vmin(vmax(a,zt),it); +} + +float bar(float a) { + return bart(a); +} + +float32x4_t bar(float32x4_t a) { + return bart(a); +} + +/* { dg-final { scan-assembler-times "min" 4 } } */ +/* { dg-final { scan-assembler-times "max" 4 } } */ -- cgit v1.1 From 097106972f243ddcbddbbddd9a6bcc076f58b453 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Thu, 20 Jul 2023 09:23:11 +0100 Subject: i386: More TImode parameter passing improvements. This patch is the next piece of a solution to the x86_64 ABI issues in PR 88873. This splits the *concat3_3 define_insn_and_split into two patterns, a TARGET_64BIT *concatditi3_3 and a !TARGET_64BIT *concatsidi3_3. This allows us to add an additional alternative to the the 64-bit version, enabling the register allocator to perform this operation using SSE registers, which is implemented/split after reload using vec_concatv2di. To demonstrate the improvement, the test case from PR88873: typedef struct { double x, y; } s_t; s_t foo (s_t a, s_t b, s_t c) { return (s_t){ __builtin_fma(a.x, b.x, c.x), __builtin_fma (a.y, b.y, c.y) }; } when compiled with -O2 -march=cascadelake, currently generates: foo: vmovq %xmm2, -56(%rsp) movq -56(%rsp), %rax vmovq %xmm3, -48(%rsp) vmovq %xmm4, -40(%rsp) movq -48(%rsp), %rcx vmovq %xmm5, -32(%rsp) vmovq %rax, %xmm6 movq -40(%rsp), %rax movq -32(%rsp), %rsi vpinsrq $1, %rcx, %xmm6, %xmm6 vmovq %xmm0, -24(%rsp) vmovq %rax, %xmm7 vmovq %xmm1, -16(%rsp) vmovapd %xmm6, %xmm2 vpinsrq $1, %rsi, %xmm7, %xmm7 vfmadd132pd -24(%rsp), %xmm7, %xmm2 vmovapd %xmm2, -56(%rsp) vmovsd -48(%rsp), %xmm1 vmovsd -56(%rsp), %xmm0 ret with this change, we avoid many of the reloads via memory, foo: vpunpcklqdq %xmm3, %xmm2, %xmm7 vpunpcklqdq %xmm1, %xmm0, %xmm6 vpunpcklqdq %xmm5, %xmm4, %xmm2 vmovdqa %xmm7, -24(%rsp) vmovdqa %xmm6, %xmm1 movq -16(%rsp), %rax vpinsrq $1, %rax, %xmm7, %xmm4 vmovapd %xmm4, %xmm6 vfmadd132pd %xmm1, %xmm2, %xmm6 vmovapd %xmm6, -24(%rsp) vmovsd -16(%rsp), %xmm1 vmovsd -24(%rsp), %xmm0 ret 2023-07-20 Roger Sayle gcc/ChangeLog * config/i386/i386-expand.cc (ix86_expand_move): Don't call force_reg, to use SUBREG rather than create a new pseudo when inserting DFmode fields into TImode with insvti_{high,low}part. * config/i386/i386.md (*concat3_3): Split into two define_insn_and_split... (*concatditi3_3): 64-bit implementation. Provide alternative that allows register allocation to use SSE registers that is split into vec_concatv2di after reload. (*concatsidi3_3): 32-bit implementation. gcc/testsuite/ChangeLog * gcc.target/i386/pr88873.c: New test case. --- gcc/config/i386/i386-expand.cc | 4 +-- gcc/config/i386/i386.md | 46 ++++++++++++++++++++++++++------- gcc/testsuite/gcc.target/i386/pr88873.c | 11 ++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr88873.c (limited to 'gcc') diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index a82c2bd..a5c000f 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -558,7 +558,7 @@ ix86_expand_move (machine_mode mode, rtx operands[]) op0 = SUBREG_REG (op0); tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp); if (mode == DFmode) - op1 = force_reg (DImode, gen_lowpart (DImode, op1)); + op1 = gen_lowpart (DImode, op1); op1 = gen_rtx_ZERO_EXTEND (TImode, op1); op1 = gen_rtx_IOR (TImode, tmp, op1); } @@ -570,7 +570,7 @@ ix86_expand_move (machine_mode mode, rtx operands[]) op0 = SUBREG_REG (op0); tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp); if (mode == DFmode) - op1 = force_reg (DImode, gen_lowpart (DImode, op1)); + op1 = gen_lowpart (DImode, op1); op1 = gen_rtx_ZERO_EXTEND (TImode, op1); op1 = gen_rtx_ASHIFT (TImode, op1, GEN_INT (64)); op1 = gen_rtx_IOR (TImode, tmp, op1); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 47ea050..8c54aa5 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12408,21 +12408,47 @@ DONE; }) -(define_insn_and_split "*concat3_3" - [(set (match_operand: 0 "nonimmediate_operand" "=ro,r,r,&r") - (any_or_plus: - (ashift: - (zero_extend: - (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m")) +(define_insn_and_split "*concatditi3_3" + [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r,x") + (any_or_plus:TI + (ashift:TI + (zero_extend:TI + (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m,x")) (match_operand:QI 2 "const_int_operand")) - (zero_extend: - (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m"))))] - "INTVAL (operands[2]) == * BITS_PER_UNIT" + (zero_extend:TI + (match_operand:DI 3 "nonimmediate_operand" "r,r,m,m,0"))))] + "TARGET_64BIT + && INTVAL (operands[2]) == 64" + "#" + "&& reload_completed" + [(const_int 0)] +{ + if (SSE_REG_P (operands[0])) + { + rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0])); + emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1])); + } + else + split_double_concat (TImode, operands[0], operands[3], operands[1]); + DONE; +}) + +(define_insn_and_split "*concatsidi3_3" + [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r") + (any_or_plus:DI + (ashift:DI + (zero_extend:DI + (match_operand:SI 1 "nonimmediate_operand" "r,m,r,m")) + (match_operand:QI 2 "const_int_operand")) + (zero_extend:DI + (match_operand:SI 3 "nonimmediate_operand" "r,r,m,m"))))] + "!TARGET_64BIT + && INTVAL (operands[2]) == 32" "#" "&& reload_completed" [(const_int 0)] { - split_double_concat (mode, operands[0], operands[3], operands[1]); + split_double_concat (DImode, operands[0], operands[3], operands[1]); DONE; }) diff --git a/gcc/testsuite/gcc.target/i386/pr88873.c b/gcc/testsuite/gcc.target/i386/pr88873.c new file mode 100644 index 0000000..d893aac --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr88873.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -march=cascadelake" } */ + +typedef struct { double x, y; } s_t; + +s_t foo (s_t a, s_t b, s_t c) +{ + return (s_t) { __builtin_fma(a.x, b.x, c.x), __builtin_fma (a.y, b.y, c.y) }; +} + +/* { dg-final { scan-assembler-times "vpunpcklqdq" 3 } } */ -- cgit v1.1 From bb42f05d0738bddc721e838ebe9993df39ff2e0f Mon Sep 17 00:00:00 2001 From: Pan Li Date: Thu, 20 Jul 2023 16:31:10 +0800 Subject: RISC-V: Fix one incorrect match operand for RVV reduction There are 2 of the RVV reduction pattern mask operand takes vector_merge_operand instead of vector_mask_operand by mistake. This patch would like to fix this. Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/vector.md: Fix incorrect match_operand. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/pr110299-1.c: Adjust tests. * gcc.target/riscv/rvv/base/pr110299-2.c: Ditto. --- gcc/config/riscv/vector.md | 4 ++-- gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c | 4 ++-- gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index fcff3ee3..f745888 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -7915,7 +7915,7 @@ (unspec:VSF_LMUL1 [(unspec:VSF_LMUL1 [(unspec: - [(match_operand: 1 "vector_merge_operand" "vmWc1,vmWc1") + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") (match_operand 5 "vector_length_operand" " rK, rK") (match_operand 6 "const_int_operand" " i, i") (match_operand 7 "const_int_operand" " i, i") @@ -7937,7 +7937,7 @@ (unspec:VDF_LMUL1 [(unspec:VDF_LMUL1 [(unspec: - [(match_operand: 1 "vector_merge_operand" "vmWc1,vmWc1") + [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") (match_operand 5 "vector_length_operand" " rK, rK") (match_operand 6 "const_int_operand" " i, i") (match_operand 7 "const_int_operand" " i, i") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c index d83eea9..a903dde 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c @@ -3,5 +3,5 @@ #include "pr110299-1.h" -/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */ -/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */ +/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c index cdcde1b..1254ace 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c @@ -4,5 +4,5 @@ #include "pr110299-1.h" #include "pr110299-2.h" -/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */ -/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */ +/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ -- cgit v1.1 From 34cf27a64e7af949538e65bc266963c24f8da458 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Thu, 1 Sep 2022 22:49:49 +0200 Subject: Add __builtin_iseqsig() iseqsig() is a C2x library function, for signaling floating-point equality checks. Provide a GCC-builtin for it, which is folded to a series of comparisons. 2022-09-01 Francois-Xavier Coudert PR middle-end/77928 gcc/ * doc/extend.texi: Document iseqsig builtin. * builtins.cc (fold_builtin_iseqsig): New function. (fold_builtin_2): Handle BUILT_IN_ISEQSIG. (is_inexpensive_builtin): Handle BUILT_IN_ISEQSIG. * builtins.def (BUILT_IN_ISEQSIG): New built-in. gcc/c-family/ * c-common.cc (check_builtin_function_arguments): Handle BUILT_IN_ISEQSIG. gcc/testsuite/ * gcc.dg/torture/builtin-iseqsig-1.c: New test. * gcc.dg/torture/builtin-iseqsig-2.c: New test. * gcc.dg/torture/builtin-iseqsig-3.c: New test. --- gcc/builtins.cc | 41 ++++++++ gcc/builtins.def | 1 + gcc/c-family/c-common.cc | 1 + gcc/doc/extend.texi | 7 +- gcc/testsuite/gcc.dg/torture/builtin-iseqsig-1.c | 113 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/builtin-iseqsig-2.c | 113 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/builtin-iseqsig-3.c | 113 +++++++++++++++++++++++ 7 files changed, 386 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/builtin-iseqsig-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/builtin-iseqsig-2.c create mode 100644 gcc/testsuite/gcc.dg/torture/builtin-iseqsig-3.c (limited to 'gcc') diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 6dff521..e2e99d6 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -171,6 +171,7 @@ static tree fold_builtin_fabs (location_t, tree, tree); static tree fold_builtin_abs (location_t, tree, tree); static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code, enum tree_code); +static tree fold_builtin_iseqsig (location_t, tree, tree); static tree fold_builtin_varargs (location_t, tree, tree*, int); static tree fold_builtin_strpbrk (location_t, tree, tree, tree, tree); @@ -9445,6 +9446,42 @@ fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1, fold_build2_loc (loc, code, type, arg0, arg1)); } +/* Fold a call to __builtin_iseqsig(). ARG0 and ARG1 are the arguments. + After choosing the wider floating-point type for the comparison, + the code is folded to: + SAVE_EXPR >= SAVE_EXPR && SAVE_EXPR <= SAVE_EXPR */ + +static tree +fold_builtin_iseqsig (location_t loc, tree arg0, tree arg1) +{ + tree type0, type1; + enum tree_code code0, code1; + tree cmp1, cmp2, cmp_type = NULL_TREE; + + type0 = TREE_TYPE (arg0); + type1 = TREE_TYPE (arg1); + + code0 = TREE_CODE (type0); + code1 = TREE_CODE (type1); + + if (code0 == REAL_TYPE && code1 == REAL_TYPE) + /* Choose the wider of two real types. */ + cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) + ? type0 : type1; + else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE) + cmp_type = type0; + else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE) + cmp_type = type1; + + arg0 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg0)); + arg1 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg1)); + + cmp1 = fold_build2_loc (loc, GE_EXPR, integer_type_node, arg0, arg1); + cmp2 = fold_build2_loc (loc, LE_EXPR, integer_type_node, arg0, arg1); + + return fold_build2_loc (loc, TRUTH_AND_EXPR, integer_type_node, cmp1, cmp2); +} + /* Fold __builtin_{,s,u}{add,sub,mul}{,l,ll}_overflow, either into normal arithmetics if it can never overflow, or into internal functions that return both result of arithmetics and overflowed boolean flag in @@ -9878,6 +9915,9 @@ fold_builtin_2 (location_t loc, tree expr, tree fndecl, tree arg0, tree arg1) arg0, arg1, UNORDERED_EXPR, NOP_EXPR); + case BUILT_IN_ISEQSIG: + return fold_builtin_iseqsig (loc, arg0, arg1); + /* We do the folding for va_start in the expander. */ case BUILT_IN_VA_START: break; @@ -11396,6 +11436,7 @@ is_inexpensive_builtin (tree decl) case BUILT_IN_ISLESSEQUAL: case BUILT_IN_ISLESSGREATER: case BUILT_IN_ISUNORDERED: + case BUILT_IN_ISEQSIG: case BUILT_IN_VA_ARG_PACK: case BUILT_IN_VA_ARG_PACK_LEN: case BUILT_IN_VA_COPY: diff --git a/gcc/builtins.def b/gcc/builtins.def index 76e7200..5953266 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -1029,6 +1029,7 @@ DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOT DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISEQSIG, "iseqsig", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) DEF_GCC_BUILTIN (BUILT_IN_ISSIGNALING, "issignaling", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 6ab63da..9fbaeb4 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -6334,6 +6334,7 @@ check_builtin_function_arguments (location_t loc, vec arg_loc, case BUILT_IN_ISLESSEQUAL: case BUILT_IN_ISLESSGREATER: case BUILT_IN_ISUNORDERED: + case BUILT_IN_ISEQSIG: if (builtin_function_validate_nargs (loc, fndecl, nargs, 2)) { enum tree_code code0, code1; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index ec9ffa3..97eaacf 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13187,6 +13187,7 @@ is called and the @var{flag} argument passed to it. @node Other Builtins @section Other Built-in Functions Provided by GCC @cindex built-in functions +@findex __builtin_iseqsig @findex __builtin_isfinite @findex __builtin_isnormal @findex __builtin_isgreater @@ -13738,9 +13739,9 @@ the same names as the standard macros ( @code{isgreater}, @code{islessgreater}, and @code{isunordered}) , with @code{__builtin_} prefixed. We intend for a library implementor to be able to simply @code{#define} each standard macro to its built-in equivalent. -In the same fashion, GCC provides @code{fpclassify}, @code{isfinite}, -@code{isinf_sign}, @code{isnormal} and @code{signbit} built-ins used with -@code{__builtin_} prefixed. The @code{isinf} and @code{isnan} +In the same fashion, GCC provides @code{fpclassify}, @code{iseqsig}, +@code{isfinite}, @code{isinf_sign}, @code{isnormal} and @code{signbit} built-ins +used with @code{__builtin_} prefixed. The @code{isinf} and @code{isnan} built-in functions appear both with and without the @code{__builtin_} prefix. With @code{-ffinite-math-only} option the @code{isinf} and @code{isnan} built-in functions will always return 0. diff --git a/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-1.c b/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-1.c new file mode 100644 index 0000000..c66431f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-1.c @@ -0,0 +1,113 @@ +/* { dg-do run { xfail powerpc*-*-* } } */ +/* remove the xfail for powerpc when pr58684 is fixed */ +/* { dg-add-options ieee } */ +/* { dg-additional-options "-fsignaling-nans" } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include + +void +ftrue (float x, float y) +{ + if (!__builtin_iseqsig (x, y)) + __builtin_abort (); +} + +void +ffalse (float x, float y) +{ + if (__builtin_iseqsig (x, y)) + __builtin_abort (); +} + +int +main () +{ + volatile float f1, f2; + + f1 = 0.f; f2 = 0.f; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.f; f2 = -0.f; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.f; f2 = 1.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = -0.f; f2 = 1.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.f; f2 = __builtin_inff(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = -0.f; f2 = __builtin_inff(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.f; f2 = __builtin_nanf(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = -0.f; f2 = __builtin_nanf(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = 1.f; f2 = 1.f; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.f; f2 = 0.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.f; f2 = -0.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.f; f2 = __builtin_inff(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.f; f2 = __builtin_nanf(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_inff(); f2 = __builtin_inff(); + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = __builtin_inff(); f2 = __builtin_nanf(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nanf(""); f2 = __builtin_nanf(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nansf(""); f2 = 1.f; + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = 1.f; f2 = __builtin_nansf(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nansf(""); f2 = __builtin_nansf(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-2.c b/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-2.c new file mode 100644 index 0000000..03625b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-2.c @@ -0,0 +1,113 @@ +/* { dg-do run { xfail powerpc*-*-* } } */ +/* remove the xfail for powerpc when pr58684 is fixed */ +/* { dg-add-options ieee } */ +/* { dg-additional-options "-fsignaling-nans" } */ +/* { dg-require-effective-target fenv_exceptions_double } */ + +#include + +void +ftrue (double x, double y) +{ + if (!__builtin_iseqsig (x, y)) + __builtin_abort (); +} + +void +ffalse (double x, double y) +{ + if (__builtin_iseqsig (x, y)) + __builtin_abort (); +} + +int +main () +{ + volatile double f1, f2; + + f1 = 0.; f2 = 0.; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.; f2 = -0.; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.; f2 = 1.; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = -0.; f2 = 1.; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.; f2 = __builtin_inf(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = -0.; f2 = __builtin_inf(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.; f2 = __builtin_nan(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = -0.; f2 = __builtin_nan(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = 1.; f2 = 1.; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.; f2 = 0.; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.; f2 = -0.; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.; f2 = __builtin_inf(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.; f2 = __builtin_nan(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_inf(); f2 = __builtin_inf(); + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = __builtin_inf(); f2 = __builtin_nan(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nan(""); f2 = __builtin_nan(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nans(""); f2 = 1.; + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = 1.; f2 = __builtin_nans(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nans(""); f2 = __builtin_nans(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-3.c b/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-3.c new file mode 100644 index 0000000..ed24035 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-iseqsig-3.c @@ -0,0 +1,113 @@ +/* { dg-do run { xfail powerpc*-*-* } } */ +/* remove the xfail for powerpc when pr58684 is fixed */ +/* { dg-add-options ieee } */ +/* { dg-additional-options "-fsignaling-nans" } */ +/* { dg-require-effective-target fenv_exceptions_long_double } */ + +#include + +void +ftrue (long double x, long double y) +{ + if (!__builtin_iseqsig (x, y)) + __builtin_abort (); +} + +void +ffalse (long double x, long double y) +{ + if (__builtin_iseqsig (x, y)) + __builtin_abort (); +} + +int +main () +{ + volatile long double f1, f2; + + f1 = 0.L; f2 = 0.f; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.L; f2 = -0.f; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.L; f2 = 1.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = -0.L; f2 = 1.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.L; f2 = __builtin_infl(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = -0.L; f2 = __builtin_infl(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 0.L; f2 = __builtin_nanl(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = -0.L; f2 = __builtin_nanl(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = 1.L; f2 = 1.f; + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.L; f2 = 0.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.L; f2 = -0.f; + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.L; f2 = __builtin_infl(); + ffalse (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = 1.L; f2 = __builtin_nanl(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_infl(); f2 = __builtin_infl(); + ftrue (f1, f2); + if (fetestexcept (FE_INVALID)) __builtin_abort (); + + f1 = __builtin_infl(); f2 = __builtin_nanl(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nanl(""); f2 = __builtin_nanl(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nansl(""); f2 = 1.L; + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = 1.L; f2 = __builtin_nansl(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + f1 = __builtin_nansl(""); f2 = __builtin_nansl(""); + ffalse (f1, f2); + if (!fetestexcept (FE_INVALID)) __builtin_abort (); + feclearexcept (FE_INVALID); + + return 0; +} -- cgit v1.1 From dca2874897ec58ea1c22a9c2161f112fff07cfb2 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Fri, 2 Sep 2022 13:27:38 +0200 Subject: Fortran: add IEEE_QUIET_* and IEEE_SIGNALING_* comparisons Those operations were added to Fortran 2018, and correspond to well-defined IEEE comparison operations, with defined signaling semantics for NaNs. All are implemented in terms of GCC expressions and built-ins, with no library support needed. gcc/fortran/ * f95-lang.cc (gfc_init_builtin_functions): Add __builtin_iseqsig. * trans-intrinsic.cc (conv_intrinsic_ieee_comparison): New function. (gfc_conv_ieee_arithmetic_function): Handle IEEE comparisons. gcc/testsuite/ * gfortran.dg/ieee/comparisons_1.f90: New test. * gfortran.dg/ieee/comparisons_2.f90: New test. * gfortran.dg/ieee/comparisons_3.F90: New test. libgfortran/ * ieee/ieee_arithmetic.F90: Add IEEE_QUIET_* and IEEE_SIGNALING_* functions. --- gcc/fortran/f95-lang.cc | 2 + gcc/fortran/trans-intrinsic.cc | 176 ++++++++ gcc/testsuite/gfortran.dg/ieee/comparisons_1.f90 | 282 +++++++++++++ gcc/testsuite/gfortran.dg/ieee/comparisons_2.f90 | 282 +++++++++++++ gcc/testsuite/gfortran.dg/ieee/comparisons_3.F90 | 487 +++++++++++++++++++++++ 5 files changed, 1229 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/ieee/comparisons_1.f90 create mode 100644 gcc/testsuite/gfortran.dg/ieee/comparisons_2.f90 create mode 100644 gcc/testsuite/gfortran.dg/ieee/comparisons_3.F90 (limited to 'gcc') diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc index 89944f4..350e6e3 100644 --- a/gcc/fortran/f95-lang.cc +++ b/gcc/fortran/f95-lang.cc @@ -1047,6 +1047,8 @@ gfc_init_builtin_functions (void) ATTR_CONST_NOTHROW_LEAF_LIST); gfc_define_builtin ("__builtin_isunordered", ftype, BUILT_IN_ISUNORDERED, "__builtin_isunordered", ATTR_CONST_NOTHROW_LEAF_LIST); + gfc_define_builtin ("__builtin_iseqsig", ftype, BUILT_IN_ISEQSIG, + "__builtin_iseqsig", ATTR_CONST_NOTHROW_LEAF_LIST); #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \ diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index b6ea26e..e0f86b1 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -10376,6 +10376,178 @@ conv_intrinsic_ieee_minmax (gfc_se * se, gfc_expr * expr, int max, } +/* Generate code for comparison functions IEEE_QUIET_* and + IEEE_SIGNALING_*. */ + +static void +conv_intrinsic_ieee_comparison (gfc_se * se, gfc_expr * expr, int signaling, + const char *name) +{ + tree args[2]; + tree arg1, arg2, res; + + /* Evaluate arguments only once. */ + conv_ieee_function_args (se, expr, args, 2); + arg1 = gfc_evaluate_now (args[0], &se->pre); + arg2 = gfc_evaluate_now (args[1], &se->pre); + + if (startswith (name, "eq")) + { + if (signaling) + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISEQSIG), + 2, arg1, arg2); + else + res = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, + arg1, arg2); + } + else if (startswith (name, "ne")) + { + if (signaling) + { + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISEQSIG), + 2, arg1, arg2); + res = fold_build1_loc (input_location, TRUTH_NOT_EXPR, + logical_type_node, res); + } + else + res = fold_build2_loc (input_location, NE_EXPR, logical_type_node, + arg1, arg2); + } + else if (startswith (name, "ge")) + { + if (signaling) + res = fold_build2_loc (input_location, GE_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL), + 2, arg1, arg2); + } + else if (startswith (name, "gt")) + { + if (signaling) + res = fold_build2_loc (input_location, GT_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISGREATER), + 2, arg1, arg2); + } + else if (startswith (name, "le")) + { + if (signaling) + res = fold_build2_loc (input_location, LE_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISLESSEQUAL), + 2, arg1, arg2); + } + else if (startswith (name, "lt")) + { + if (signaling) + res = fold_build2_loc (input_location, LT_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISLESS), + 2, arg1, arg2); + } + else + gcc_unreachable (); + + se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), res); +} + + +/* Generate code for comparison functions IEEE_QUIET_* and + IEEE_SIGNALING_*. */ + +static void +conv_intrinsic_ieee_comparison (gfc_se * se, gfc_expr * expr, int signaling, + const char *name) +{ + tree args[2]; + tree arg1, arg2, res; + + /* Evaluate arguments only once. */ + conv_ieee_function_args (se, expr, args, 2); + arg1 = gfc_evaluate_now (args[0], &se->pre); + arg2 = gfc_evaluate_now (args[1], &se->pre); + + if (startswith (name, "eq")) + { + if (signaling) + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISEQSIG), + 2, arg1, arg2); + else + res = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, + arg1, arg2); + } + else if (startswith (name, "ne")) + { + if (signaling) + { + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISEQSIG), + 2, arg1, arg2); + res = fold_build1_loc (input_location, TRUTH_NOT_EXPR, + logical_type_node, res); + } + else + res = fold_build2_loc (input_location, NE_EXPR, logical_type_node, + arg1, arg2); + } + else if (startswith (name, "ge")) + { + if (signaling) + res = fold_build2_loc (input_location, GE_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL), + 2, arg1, arg2); + } + else if (startswith (name, "gt")) + { + if (signaling) + res = fold_build2_loc (input_location, GT_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISGREATER), + 2, arg1, arg2); + } + else if (startswith (name, "le")) + { + if (signaling) + res = fold_build2_loc (input_location, LE_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISLESSEQUAL), + 2, arg1, arg2); + } + else if (startswith (name, "lt")) + { + if (signaling) + res = fold_build2_loc (input_location, LT_EXPR, logical_type_node, + arg1, arg2); + else + res = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISLESS), + 2, arg1, arg2); + } + else + gcc_unreachable (); + + se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), res); +} + + /* Generate code for an intrinsic function from the IEEE_ARITHMETIC module. */ @@ -10418,6 +10590,10 @@ gfc_conv_ieee_arithmetic_function (gfc_se * se, gfc_expr * expr) conv_intrinsic_ieee_minmax (se, expr, 0, name + 23); else if (startswith (name, "_gfortran_ieee_max_num_")) conv_intrinsic_ieee_minmax (se, expr, 1, name + 23); + else if (startswith (name, "_gfortran_ieee_quiet_")) + conv_intrinsic_ieee_comparison (se, expr, 0, name + 21); + else if (startswith (name, "_gfortran_ieee_signaling_")) + conv_intrinsic_ieee_comparison (se, expr, 1, name + 25); else /* It is not among the functions we translate directly. We return false, so a library function call is emitted. */ diff --git a/gcc/testsuite/gfortran.dg/ieee/comparisons_1.f90 b/gcc/testsuite/gfortran.dg/ieee/comparisons_1.f90 new file mode 100644 index 0000000..39a8abd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/ieee/comparisons_1.f90 @@ -0,0 +1,282 @@ +! { dg-do run } +program foo + use ieee_arithmetic + use iso_fortran_env + implicit none + + ! This allows us to test REAL128 if it exists, and still compile + ! on platforms were it is not present + ! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89639 + integer, parameter :: large = merge(real128, real64, real128 > 0) + + real, volatile :: rnan, rinf + double precision, volatile :: dnan, dinf + real(kind=large), volatile :: lnan, linf + + rinf = ieee_value(0., ieee_positive_inf) + rnan = ieee_value(0., ieee_quiet_nan) + + dinf = ieee_value(0.d0, ieee_positive_inf) + dnan = ieee_value(0.d0, ieee_quiet_nan) + + linf = ieee_value(0._large, ieee_positive_inf) + lnan = ieee_value(0._large, ieee_quiet_nan) + + if (.not. ieee_quiet_eq (0., 0.)) stop 1 + if (.not. ieee_quiet_eq (0., -0.)) stop 2 + if (.not. ieee_quiet_eq (1., 1.)) stop 3 + if (.not. ieee_quiet_eq (rinf, rinf)) stop 4 + if (.not. ieee_quiet_eq (-rinf, -rinf)) stop 5 + if (ieee_quiet_eq (rnan, rnan)) stop 6 + if (ieee_quiet_eq (0., 1.)) stop 7 + if (ieee_quiet_eq (0., -1.)) stop 8 + if (ieee_quiet_eq (0., rnan)) stop 9 + if (ieee_quiet_eq (1., rnan)) stop 10 + if (ieee_quiet_eq (0., rinf)) stop 11 + if (ieee_quiet_eq (1., rinf)) stop 12 + if (ieee_quiet_eq (rinf, rnan)) stop 13 + + if (.not. ieee_quiet_eq (0.d0, 0.d0)) stop 14 + if (.not. ieee_quiet_eq (0.d0, -0.d0)) stop 15 + if (.not. ieee_quiet_eq (1.d0, 1.d0)) stop 16 + if (.not. ieee_quiet_eq (dinf, dinf)) stop 17 + if (.not. ieee_quiet_eq (-dinf, -dinf)) stop 18 + if (ieee_quiet_eq (dnan, dnan)) stop 19 + if (ieee_quiet_eq (0.d0, 1.d0)) stop 20 + if (ieee_quiet_eq (0.d0, -1.d0)) stop 21 + if (ieee_quiet_eq (0.d0, dnan)) stop 22 + if (ieee_quiet_eq (1.d0, dnan)) stop 23 + if (ieee_quiet_eq (0.d0, dinf)) stop 24 + if (ieee_quiet_eq (1.d0, dinf)) stop 25 + if (ieee_quiet_eq (dinf, dnan)) stop 26 + + if (.not. ieee_quiet_eq (0._large, 0._large)) stop 27 + if (.not. ieee_quiet_eq (0._large, -0._large)) stop 28 + if (.not. ieee_quiet_eq (1._large, 1._large)) stop 29 + if (.not. ieee_quiet_eq (linf, linf)) stop 30 + if (.not. ieee_quiet_eq (-linf, -linf)) stop 31 + if (ieee_quiet_eq (lnan, lnan)) stop 32 + if (ieee_quiet_eq (0._large, 1._large)) stop 33 + if (ieee_quiet_eq (0._large, -1._large)) stop 34 + if (ieee_quiet_eq (0._large, lnan)) stop 35 + if (ieee_quiet_eq (1._large, lnan)) stop 36 + if (ieee_quiet_eq (0._large, linf)) stop 37 + if (ieee_quiet_eq (1._large, linf)) stop 38 + if (ieee_quiet_eq (linf, lnan)) stop 39 + + + if (ieee_quiet_ne (0., 0.)) stop 40 + if (ieee_quiet_ne (0., -0.)) stop 41 + if (ieee_quiet_ne (1., 1.)) stop 42 + if (ieee_quiet_ne (rinf, rinf)) stop 43 + if (ieee_quiet_ne (-rinf, -rinf)) stop 44 + if (.not. ieee_quiet_ne (rnan, rnan)) stop 45 + if (.not. ieee_quiet_ne (0., 1.)) stop 46 + if (.not. ieee_quiet_ne (0., -1.)) stop 47 + if (.not. ieee_quiet_ne (0., rnan)) stop 48 + if (.not. ieee_quiet_ne (1., rnan)) stop 49 + if (.not. ieee_quiet_ne (0., rinf)) stop 50 + if (.not. ieee_quiet_ne (1., rinf)) stop 51 + if (.not. ieee_quiet_ne (rinf, rnan)) stop 52 + + if (ieee_quiet_ne (0.d0, 0.d0)) stop 53 + if (ieee_quiet_ne (0.d0, -0.d0)) stop 54 + if (ieee_quiet_ne (1.d0, 1.d0)) stop 55 + if (ieee_quiet_ne (dinf, dinf)) stop 56 + if (ieee_quiet_ne (-dinf, -dinf)) stop 57 + if (.not. ieee_quiet_ne (dnan, dnan)) stop 58 + if (.not. ieee_quiet_ne (0.d0, 1.d0)) stop 59 + if (.not. ieee_quiet_ne (0.d0, -1.d0)) stop 60 + if (.not. ieee_quiet_ne (0.d0, dnan)) stop 61 + if (.not. ieee_quiet_ne (1.d0, dnan)) stop 62 + if (.not. ieee_quiet_ne (0.d0, dinf)) stop 63 + if (.not. ieee_quiet_ne (1.d0, dinf)) stop 64 + if (.not. ieee_quiet_ne (dinf, dnan)) stop 65 + + if (ieee_quiet_ne (0._large, 0._large)) stop 66 + if (ieee_quiet_ne (0._large, -0._large)) stop 67 + if (ieee_quiet_ne (1._large, 1._large)) stop 68 + if (ieee_quiet_ne (linf, linf)) stop 69 + if (ieee_quiet_ne (-linf, -linf)) stop 70 + if (.not. ieee_quiet_ne (lnan, lnan)) stop 71 + if (.not. ieee_quiet_ne (0._large, 1._large)) stop 72 + if (.not. ieee_quiet_ne (0._large, -1._large)) stop 73 + if (.not. ieee_quiet_ne (0._large, lnan)) stop 74 + if (.not. ieee_quiet_ne (1._large, lnan)) stop 75 + if (.not. ieee_quiet_ne (0._large, linf)) stop 76 + if (.not. ieee_quiet_ne (1._large, linf)) stop 77 + if (.not. ieee_quiet_ne (linf, lnan)) stop 78 + + + if (.not. ieee_quiet_le (0., 0.)) stop 79 + if (.not. ieee_quiet_le (0., -0.)) stop 80 + if (.not. ieee_quiet_le (1., 1.)) stop 81 + if (.not. ieee_quiet_le (rinf, rinf)) stop 82 + if (.not. ieee_quiet_le (-rinf, -rinf)) stop 83 + if (ieee_quiet_le (rnan, rnan)) stop 84 + if (.not. ieee_quiet_le (0., 1.)) stop 85 + if (ieee_quiet_le (0., -1.)) stop 86 + if (ieee_quiet_le (0., rnan)) stop 87 + if (ieee_quiet_le (1., rnan)) stop 88 + if (.not. ieee_quiet_le (0., rinf)) stop 89 + if (.not. ieee_quiet_le (1., rinf)) stop 90 + if (ieee_quiet_le (rinf, rnan)) stop 91 + + if (.not. ieee_quiet_le (0.d0, 0.d0)) stop 92 + if (.not. ieee_quiet_le (0.d0, -0.d0)) stop 93 + if (.not. ieee_quiet_le (1.d0, 1.d0)) stop 94 + if (.not. ieee_quiet_le (dinf, dinf)) stop 95 + if (.not. ieee_quiet_le (-dinf, -dinf)) stop 96 + if (ieee_quiet_le (dnan, dnan)) stop 97 + if (.not. ieee_quiet_le (0.d0, 1.d0)) stop 98 + if (ieee_quiet_le (0.d0, -1.d0)) stop 99 + if (ieee_quiet_le (0.d0, dnan)) stop 100 + if (ieee_quiet_le (1.d0, dnan)) stop 101 + if (.not. ieee_quiet_le (0.d0, dinf)) stop 102 + if (.not. ieee_quiet_le (1.d0, dinf)) stop 103 + if (ieee_quiet_le (dinf, dnan)) stop 104 + + if (.not. ieee_quiet_le (0._large, 0._large)) stop 105 + if (.not. ieee_quiet_le (0._large, -0._large)) stop 106 + if (.not. ieee_quiet_le (1._large, 1._large)) stop 107 + if (.not. ieee_quiet_le (linf, linf)) stop 108 + if (.not. ieee_quiet_le (-linf, -linf)) stop 109 + if (ieee_quiet_le (lnan, lnan)) stop 110 + if (.not. ieee_quiet_le (0._large, 1._large)) stop 111 + if (ieee_quiet_le (0._large, -1._large)) stop 112 + if (ieee_quiet_le (0._large, lnan)) stop 113 + if (ieee_quiet_le (1._large, lnan)) stop 114 + if (.not. ieee_quiet_le (0._large, linf)) stop 115 + if (.not. ieee_quiet_le (1._large, linf)) stop 116 + if (ieee_quiet_le (linf, lnan)) stop 117 + + + if (.not. ieee_quiet_ge (0., 0.)) stop 118 + if (.not. ieee_quiet_ge (0., -0.)) stop 119 + if (.not. ieee_quiet_ge (1., 1.)) stop 120 + if (.not. ieee_quiet_ge (rinf, rinf)) stop 121 + if (.not. ieee_quiet_ge (-rinf, -rinf)) stop 122 + if (ieee_quiet_ge (rnan, rnan)) stop 123 + if (ieee_quiet_ge (0., 1.)) stop 124 + if (.not. ieee_quiet_ge (0., -1.)) stop 125 + if (ieee_quiet_ge (0., rnan)) stop 126 + if (ieee_quiet_ge (1., rnan)) stop 127 + if (ieee_quiet_ge (0., rinf)) stop 128 + if (ieee_quiet_ge (1., rinf)) stop 129 + if (ieee_quiet_ge (rinf, rnan)) stop 130 + + if (.not. ieee_quiet_ge (0.d0, 0.d0)) stop 131 + if (.not. ieee_quiet_ge (0.d0, -0.d0)) stop 132 + if (.not. ieee_quiet_ge (1.d0, 1.d0)) stop 133 + if (.not. ieee_quiet_ge (dinf, dinf)) stop 134 + if (.not. ieee_quiet_ge (-dinf, -dinf)) stop 135 + if (ieee_quiet_ge (dnan, dnan)) stop 136 + if (ieee_quiet_ge (0.d0, 1.d0)) stop 137 + if (.not. ieee_quiet_ge (0.d0, -1.d0)) stop 138 + if (ieee_quiet_ge (0.d0, dnan)) stop 139 + if (ieee_quiet_ge (1.d0, dnan)) stop 140 + if (ieee_quiet_ge (0.d0, dinf)) stop 141 + if (ieee_quiet_ge (1.d0, dinf)) stop 142 + if (ieee_quiet_ge (dinf, dnan)) stop 143 + + if (.not. ieee_quiet_ge (0._large, 0._large)) stop 144 + if (.not. ieee_quiet_ge (0._large, -0._large)) stop 145 + if (.not. ieee_quiet_ge (1._large, 1._large)) stop 146 + if (.not. ieee_quiet_ge (linf, linf)) stop 147 + if (.not. ieee_quiet_ge (-linf, -linf)) stop 148 + if (ieee_quiet_ge (lnan, lnan)) stop 149 + if (ieee_quiet_ge (0._large, 1._large)) stop 150 + if (.not. ieee_quiet_ge (0._large, -1._large)) stop 151 + if (ieee_quiet_ge (0._large, lnan)) stop 152 + if (ieee_quiet_ge (1._large, lnan)) stop 153 + if (ieee_quiet_ge (0._large, linf)) stop 154 + if (ieee_quiet_ge (1._large, linf)) stop 155 + if (ieee_quiet_ge (linf, lnan)) stop 156 + + + if (ieee_quiet_lt (0., 0.)) stop 157 + if (ieee_quiet_lt (0., -0.)) stop 158 + if (ieee_quiet_lt (1., 1.)) stop 159 + if (ieee_quiet_lt (rinf, rinf)) stop 160 + if (ieee_quiet_lt (-rinf, -rinf)) stop 161 + if (ieee_quiet_lt (rnan, rnan)) stop 162 + if (.not. ieee_quiet_lt (0., 1.)) stop 163 + if (ieee_quiet_lt (0., -1.)) stop 164 + if (ieee_quiet_lt (0., rnan)) stop 165 + if (ieee_quiet_lt (1., rnan)) stop 166 + if (.not. ieee_quiet_lt (0., rinf)) stop 167 + if (.not. ieee_quiet_lt (1., rinf)) stop 168 + if (ieee_quiet_lt (rinf, rnan)) stop 169 + + if (ieee_quiet_lt (0.d0, 0.d0)) stop 170 + if (ieee_quiet_lt (0.d0, -0.d0)) stop 171 + if (ieee_quiet_lt (1.d0, 1.d0)) stop 172 + if (ieee_quiet_lt (dinf, dinf)) stop 173 + if (ieee_quiet_lt (-dinf, -dinf)) stop 174 + if (ieee_quiet_lt (dnan, dnan)) stop 175 + if (.not. ieee_quiet_lt (0.d0, 1.d0)) stop 176 + if (ieee_quiet_lt (0.d0, -1.d0)) stop 177 + if (ieee_quiet_lt (0.d0, dnan)) stop 178 + if (ieee_quiet_lt (1.d0, dnan)) stop 179 + if (.not. ieee_quiet_lt (0.d0, dinf)) stop 180 + if (.not. ieee_quiet_lt (1.d0, dinf)) stop 181 + if (ieee_quiet_lt (dinf, dnan)) stop 182 + + if (ieee_quiet_lt (0._large, 0._large)) stop 183 + if (ieee_quiet_lt (0._large, -0._large)) stop 184 + if (ieee_quiet_lt (1._large, 1._large)) stop 185 + if (ieee_quiet_lt (linf, linf)) stop 186 + if (ieee_quiet_lt (-linf, -linf)) stop 187 + if (ieee_quiet_lt (lnan, lnan)) stop 188 + if (.not. ieee_quiet_lt (0._large, 1._large)) stop 189 + if (ieee_quiet_lt (0._large, -1._large)) stop 190 + if (ieee_quiet_lt (0._large, lnan)) stop 191 + if (ieee_quiet_lt (1._large, lnan)) stop 192 + if (.not. ieee_quiet_lt (0._large, linf)) stop 193 + if (.not. ieee_quiet_lt (1._large, linf)) stop 194 + if (ieee_quiet_lt (linf, lnan)) stop 195 + + + if (ieee_quiet_gt (0., 0.)) stop 196 + if (ieee_quiet_gt (0., -0.)) stop 197 + if (ieee_quiet_gt (1., 1.)) stop 198 + if (ieee_quiet_gt (rinf, rinf)) stop 199 + if (ieee_quiet_gt (-rinf, -rinf)) stop 200 + if (ieee_quiet_gt (rnan, rnan)) stop 201 + if (ieee_quiet_gt (0., 1.)) stop 202 + if (.not. ieee_quiet_gt (0., -1.)) stop 203 + if (ieee_quiet_gt (0., rnan)) stop 204 + if (ieee_quiet_gt (1., rnan)) stop 205 + if (ieee_quiet_gt (0., rinf)) stop 206 + if (ieee_quiet_gt (1., rinf)) stop 207 + if (ieee_quiet_gt (rinf, rnan)) stop 208 + + if (ieee_quiet_gt (0.d0, 0.d0)) stop 209 + if (ieee_quiet_gt (0.d0, -0.d0)) stop 210 + if (ieee_quiet_gt (1.d0, 1.d0)) stop 211 + if (ieee_quiet_gt (dinf, dinf)) stop 212 + if (ieee_quiet_gt (-dinf, -dinf)) stop 213 + if (ieee_quiet_gt (dnan, dnan)) stop 214 + if (ieee_quiet_gt (0.d0, 1.d0)) stop 215 + if (.not. ieee_quiet_gt (0.d0, -1.d0)) stop 216 + if (ieee_quiet_gt (0.d0, dnan)) stop 217 + if (ieee_quiet_gt (1.d0, dnan)) stop 218 + if (ieee_quiet_gt (0.d0, dinf)) stop 219 + if (ieee_quiet_gt (1.d0, dinf)) stop 220 + if (ieee_quiet_gt (dinf, dnan)) stop 221 + + if (ieee_quiet_gt (0._large, 0._large)) stop 222 + if (ieee_quiet_gt (0._large, -0._large)) stop 223 + if (ieee_quiet_gt (1._large, 1._large)) stop 224 + if (ieee_quiet_gt (linf, linf)) stop 225 + if (ieee_quiet_gt (-linf, -linf)) stop 226 + if (ieee_quiet_gt (lnan, lnan)) stop 227 + if (ieee_quiet_gt (0._large, 1._large)) stop 228 + if (.not. ieee_quiet_gt (0._large, -1._large)) stop 229 + if (ieee_quiet_gt (0._large, lnan)) stop 230 + if (ieee_quiet_gt (1._large, lnan)) stop 231 + if (ieee_quiet_gt (0._large, linf)) stop 232 + if (ieee_quiet_gt (1._large, linf)) stop 233 + if (ieee_quiet_gt (linf, lnan)) stop 234 + +end program foo diff --git a/gcc/testsuite/gfortran.dg/ieee/comparisons_2.f90 b/gcc/testsuite/gfortran.dg/ieee/comparisons_2.f90 new file mode 100644 index 0000000..35aa1fc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/ieee/comparisons_2.f90 @@ -0,0 +1,282 @@ +! { dg-do run } +program foo + use ieee_arithmetic + use iso_fortran_env + implicit none + + ! This allows us to test REAL128 if it exists, and still compile + ! on platforms were it is not present + ! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89639 + integer, parameter :: large = merge(real128, real64, real128 > 0) + + real, volatile :: rnan, rinf + double precision, volatile :: dnan, dinf + real(kind=large), volatile :: lnan, linf + + rinf = ieee_value(0., ieee_positive_inf) + rnan = ieee_value(0., ieee_quiet_nan) + + dinf = ieee_value(0.d0, ieee_positive_inf) + dnan = ieee_value(0.d0, ieee_quiet_nan) + + linf = ieee_value(0._large, ieee_positive_inf) + lnan = ieee_value(0._large, ieee_quiet_nan) + + if (.not. ieee_signaling_eq (0., 0.)) stop 1 + if (.not. ieee_signaling_eq (0., -0.)) stop 2 + if (.not. ieee_signaling_eq (1., 1.)) stop 3 + if (.not. ieee_signaling_eq (rinf, rinf)) stop 4 + if (.not. ieee_signaling_eq (-rinf, -rinf)) stop 5 + if (ieee_signaling_eq (rnan, rnan)) stop 6 + if (ieee_signaling_eq (0., 1.)) stop 7 + if (ieee_signaling_eq (0., -1.)) stop 8 + if (ieee_signaling_eq (0., rnan)) stop 9 + if (ieee_signaling_eq (1., rnan)) stop 10 + if (ieee_signaling_eq (0., rinf)) stop 11 + if (ieee_signaling_eq (1., rinf)) stop 12 + if (ieee_signaling_eq (rinf, rnan)) stop 13 + + if (.not. ieee_signaling_eq (0.d0, 0.d0)) stop 14 + if (.not. ieee_signaling_eq (0.d0, -0.d0)) stop 15 + if (.not. ieee_signaling_eq (1.d0, 1.d0)) stop 16 + if (.not. ieee_signaling_eq (dinf, dinf)) stop 17 + if (.not. ieee_signaling_eq (-dinf, -dinf)) stop 18 + if (ieee_signaling_eq (dnan, dnan)) stop 19 + if (ieee_signaling_eq (0.d0, 1.d0)) stop 20 + if (ieee_signaling_eq (0.d0, -1.d0)) stop 21 + if (ieee_signaling_eq (0.d0, dnan)) stop 22 + if (ieee_signaling_eq (1.d0, dnan)) stop 23 + if (ieee_signaling_eq (0.d0, dinf)) stop 24 + if (ieee_signaling_eq (1.d0, dinf)) stop 25 + if (ieee_signaling_eq (dinf, dnan)) stop 26 + + if (.not. ieee_signaling_eq (0._large, 0._large)) stop 27 + if (.not. ieee_signaling_eq (0._large, -0._large)) stop 28 + if (.not. ieee_signaling_eq (1._large, 1._large)) stop 29 + if (.not. ieee_signaling_eq (linf, linf)) stop 30 + if (.not. ieee_signaling_eq (-linf, -linf)) stop 31 + if (ieee_signaling_eq (lnan, lnan)) stop 32 + if (ieee_signaling_eq (0._large, 1._large)) stop 33 + if (ieee_signaling_eq (0._large, -1._large)) stop 34 + if (ieee_signaling_eq (0._large, lnan)) stop 35 + if (ieee_signaling_eq (1._large, lnan)) stop 36 + if (ieee_signaling_eq (0._large, linf)) stop 37 + if (ieee_signaling_eq (1._large, linf)) stop 38 + if (ieee_signaling_eq (linf, lnan)) stop 39 + + + if (ieee_signaling_ne (0., 0.)) stop 40 + if (ieee_signaling_ne (0., -0.)) stop 41 + if (ieee_signaling_ne (1., 1.)) stop 42 + if (ieee_signaling_ne (rinf, rinf)) stop 43 + if (ieee_signaling_ne (-rinf, -rinf)) stop 44 + if (.not. ieee_signaling_ne (rnan, rnan)) stop 45 + if (.not. ieee_signaling_ne (0., 1.)) stop 46 + if (.not. ieee_signaling_ne (0., -1.)) stop 47 + if (.not. ieee_signaling_ne (0., rnan)) stop 48 + if (.not. ieee_signaling_ne (1., rnan)) stop 49 + if (.not. ieee_signaling_ne (0., rinf)) stop 50 + if (.not. ieee_signaling_ne (1., rinf)) stop 51 + if (.not. ieee_signaling_ne (rinf, rnan)) stop 52 + + if (ieee_signaling_ne (0.d0, 0.d0)) stop 53 + if (ieee_signaling_ne (0.d0, -0.d0)) stop 54 + if (ieee_signaling_ne (1.d0, 1.d0)) stop 55 + if (ieee_signaling_ne (dinf, dinf)) stop 56 + if (ieee_signaling_ne (-dinf, -dinf)) stop 57 + if (.not. ieee_signaling_ne (dnan, dnan)) stop 58 + if (.not. ieee_signaling_ne (0.d0, 1.d0)) stop 59 + if (.not. ieee_signaling_ne (0.d0, -1.d0)) stop 60 + if (.not. ieee_signaling_ne (0.d0, dnan)) stop 61 + if (.not. ieee_signaling_ne (1.d0, dnan)) stop 62 + if (.not. ieee_signaling_ne (0.d0, dinf)) stop 63 + if (.not. ieee_signaling_ne (1.d0, dinf)) stop 64 + if (.not. ieee_signaling_ne (dinf, dnan)) stop 65 + + if (ieee_signaling_ne (0._large, 0._large)) stop 66 + if (ieee_signaling_ne (0._large, -0._large)) stop 67 + if (ieee_signaling_ne (1._large, 1._large)) stop 68 + if (ieee_signaling_ne (linf, linf)) stop 69 + if (ieee_signaling_ne (-linf, -linf)) stop 70 + if (.not. ieee_signaling_ne (lnan, lnan)) stop 71 + if (.not. ieee_signaling_ne (0._large, 1._large)) stop 72 + if (.not. ieee_signaling_ne (0._large, -1._large)) stop 73 + if (.not. ieee_signaling_ne (0._large, lnan)) stop 74 + if (.not. ieee_signaling_ne (1._large, lnan)) stop 75 + if (.not. ieee_signaling_ne (0._large, linf)) stop 76 + if (.not. ieee_signaling_ne (1._large, linf)) stop 77 + if (.not. ieee_signaling_ne (linf, lnan)) stop 78 + + + if (.not. ieee_signaling_le (0., 0.)) stop 79 + if (.not. ieee_signaling_le (0., -0.)) stop 80 + if (.not. ieee_signaling_le (1., 1.)) stop 81 + if (.not. ieee_signaling_le (rinf, rinf)) stop 82 + if (.not. ieee_signaling_le (-rinf, -rinf)) stop 83 + if (ieee_signaling_le (rnan, rnan)) stop 84 + if (.not. ieee_signaling_le (0., 1.)) stop 85 + if (ieee_signaling_le (0., -1.)) stop 86 + if (ieee_signaling_le (0., rnan)) stop 87 + if (ieee_signaling_le (1., rnan)) stop 88 + if (.not. ieee_signaling_le (0., rinf)) stop 89 + if (.not. ieee_signaling_le (1., rinf)) stop 90 + if (ieee_signaling_le (rinf, rnan)) stop 91 + + if (.not. ieee_signaling_le (0.d0, 0.d0)) stop 92 + if (.not. ieee_signaling_le (0.d0, -0.d0)) stop 93 + if (.not. ieee_signaling_le (1.d0, 1.d0)) stop 94 + if (.not. ieee_signaling_le (dinf, dinf)) stop 95 + if (.not. ieee_signaling_le (-dinf, -dinf)) stop 96 + if (ieee_signaling_le (dnan, dnan)) stop 97 + if (.not. ieee_signaling_le (0.d0, 1.d0)) stop 98 + if (ieee_signaling_le (0.d0, -1.d0)) stop 99 + if (ieee_signaling_le (0.d0, dnan)) stop 100 + if (ieee_signaling_le (1.d0, dnan)) stop 101 + if (.not. ieee_signaling_le (0.d0, dinf)) stop 102 + if (.not. ieee_signaling_le (1.d0, dinf)) stop 103 + if (ieee_signaling_le (dinf, dnan)) stop 104 + + if (.not. ieee_signaling_le (0._large, 0._large)) stop 105 + if (.not. ieee_signaling_le (0._large, -0._large)) stop 106 + if (.not. ieee_signaling_le (1._large, 1._large)) stop 107 + if (.not. ieee_signaling_le (linf, linf)) stop 108 + if (.not. ieee_signaling_le (-linf, -linf)) stop 109 + if (ieee_signaling_le (lnan, lnan)) stop 110 + if (.not. ieee_signaling_le (0._large, 1._large)) stop 111 + if (ieee_signaling_le (0._large, -1._large)) stop 112 + if (ieee_signaling_le (0._large, lnan)) stop 113 + if (ieee_signaling_le (1._large, lnan)) stop 114 + if (.not. ieee_signaling_le (0._large, linf)) stop 115 + if (.not. ieee_signaling_le (1._large, linf)) stop 116 + if (ieee_signaling_le (linf, lnan)) stop 117 + + + if (.not. ieee_signaling_ge (0., 0.)) stop 118 + if (.not. ieee_signaling_ge (0., -0.)) stop 119 + if (.not. ieee_signaling_ge (1., 1.)) stop 120 + if (.not. ieee_signaling_ge (rinf, rinf)) stop 121 + if (.not. ieee_signaling_ge (-rinf, -rinf)) stop 122 + if (ieee_signaling_ge (rnan, rnan)) stop 123 + if (ieee_signaling_ge (0., 1.)) stop 124 + if (.not. ieee_signaling_ge (0., -1.)) stop 125 + if (ieee_signaling_ge (0., rnan)) stop 126 + if (ieee_signaling_ge (1., rnan)) stop 127 + if (ieee_signaling_ge (0., rinf)) stop 128 + if (ieee_signaling_ge (1., rinf)) stop 129 + if (ieee_signaling_ge (rinf, rnan)) stop 130 + + if (.not. ieee_signaling_ge (0.d0, 0.d0)) stop 131 + if (.not. ieee_signaling_ge (0.d0, -0.d0)) stop 132 + if (.not. ieee_signaling_ge (1.d0, 1.d0)) stop 133 + if (.not. ieee_signaling_ge (dinf, dinf)) stop 134 + if (.not. ieee_signaling_ge (-dinf, -dinf)) stop 135 + if (ieee_signaling_ge (dnan, dnan)) stop 136 + if (ieee_signaling_ge (0.d0, 1.d0)) stop 137 + if (.not. ieee_signaling_ge (0.d0, -1.d0)) stop 138 + if (ieee_signaling_ge (0.d0, dnan)) stop 139 + if (ieee_signaling_ge (1.d0, dnan)) stop 140 + if (ieee_signaling_ge (0.d0, dinf)) stop 141 + if (ieee_signaling_ge (1.d0, dinf)) stop 142 + if (ieee_signaling_ge (dinf, dnan)) stop 143 + + if (.not. ieee_signaling_ge (0._large, 0._large)) stop 144 + if (.not. ieee_signaling_ge (0._large, -0._large)) stop 145 + if (.not. ieee_signaling_ge (1._large, 1._large)) stop 146 + if (.not. ieee_signaling_ge (linf, linf)) stop 147 + if (.not. ieee_signaling_ge (-linf, -linf)) stop 148 + if (ieee_signaling_ge (lnan, lnan)) stop 149 + if (ieee_signaling_ge (0._large, 1._large)) stop 150 + if (.not. ieee_signaling_ge (0._large, -1._large)) stop 151 + if (ieee_signaling_ge (0._large, lnan)) stop 152 + if (ieee_signaling_ge (1._large, lnan)) stop 153 + if (ieee_signaling_ge (0._large, linf)) stop 154 + if (ieee_signaling_ge (1._large, linf)) stop 155 + if (ieee_signaling_ge (linf, lnan)) stop 156 + + + if (ieee_signaling_lt (0., 0.)) stop 157 + if (ieee_signaling_lt (0., -0.)) stop 158 + if (ieee_signaling_lt (1., 1.)) stop 159 + if (ieee_signaling_lt (rinf, rinf)) stop 160 + if (ieee_signaling_lt (-rinf, -rinf)) stop 161 + if (ieee_signaling_lt (rnan, rnan)) stop 162 + if (.not. ieee_signaling_lt (0., 1.)) stop 163 + if (ieee_signaling_lt (0., -1.)) stop 164 + if (ieee_signaling_lt (0., rnan)) stop 165 + if (ieee_signaling_lt (1., rnan)) stop 166 + if (.not. ieee_signaling_lt (0., rinf)) stop 167 + if (.not. ieee_signaling_lt (1., rinf)) stop 168 + if (ieee_signaling_lt (rinf, rnan)) stop 169 + + if (ieee_signaling_lt (0.d0, 0.d0)) stop 170 + if (ieee_signaling_lt (0.d0, -0.d0)) stop 171 + if (ieee_signaling_lt (1.d0, 1.d0)) stop 172 + if (ieee_signaling_lt (dinf, dinf)) stop 173 + if (ieee_signaling_lt (-dinf, -dinf)) stop 174 + if (ieee_signaling_lt (dnan, dnan)) stop 175 + if (.not. ieee_signaling_lt (0.d0, 1.d0)) stop 176 + if (ieee_signaling_lt (0.d0, -1.d0)) stop 177 + if (ieee_signaling_lt (0.d0, dnan)) stop 178 + if (ieee_signaling_lt (1.d0, dnan)) stop 179 + if (.not. ieee_signaling_lt (0.d0, dinf)) stop 180 + if (.not. ieee_signaling_lt (1.d0, dinf)) stop 181 + if (ieee_signaling_lt (dinf, dnan)) stop 182 + + if (ieee_signaling_lt (0._large, 0._large)) stop 183 + if (ieee_signaling_lt (0._large, -0._large)) stop 184 + if (ieee_signaling_lt (1._large, 1._large)) stop 185 + if (ieee_signaling_lt (linf, linf)) stop 186 + if (ieee_signaling_lt (-linf, -linf)) stop 187 + if (ieee_signaling_lt (lnan, lnan)) stop 188 + if (.not. ieee_signaling_lt (0._large, 1._large)) stop 189 + if (ieee_signaling_lt (0._large, -1._large)) stop 190 + if (ieee_signaling_lt (0._large, lnan)) stop 191 + if (ieee_signaling_lt (1._large, lnan)) stop 192 + if (.not. ieee_signaling_lt (0._large, linf)) stop 193 + if (.not. ieee_signaling_lt (1._large, linf)) stop 194 + if (ieee_signaling_lt (linf, lnan)) stop 195 + + + if (ieee_signaling_gt (0., 0.)) stop 196 + if (ieee_signaling_gt (0., -0.)) stop 197 + if (ieee_signaling_gt (1., 1.)) stop 198 + if (ieee_signaling_gt (rinf, rinf)) stop 199 + if (ieee_signaling_gt (-rinf, -rinf)) stop 200 + if (ieee_signaling_gt (rnan, rnan)) stop 201 + if (ieee_signaling_gt (0., 1.)) stop 202 + if (.not. ieee_signaling_gt (0., -1.)) stop 203 + if (ieee_signaling_gt (0., rnan)) stop 204 + if (ieee_signaling_gt (1., rnan)) stop 205 + if (ieee_signaling_gt (0., rinf)) stop 206 + if (ieee_signaling_gt (1., rinf)) stop 207 + if (ieee_signaling_gt (rinf, rnan)) stop 208 + + if (ieee_signaling_gt (0.d0, 0.d0)) stop 209 + if (ieee_signaling_gt (0.d0, -0.d0)) stop 210 + if (ieee_signaling_gt (1.d0, 1.d0)) stop 211 + if (ieee_signaling_gt (dinf, dinf)) stop 212 + if (ieee_signaling_gt (-dinf, -dinf)) stop 213 + if (ieee_signaling_gt (dnan, dnan)) stop 214 + if (ieee_signaling_gt (0.d0, 1.d0)) stop 215 + if (.not. ieee_signaling_gt (0.d0, -1.d0)) stop 216 + if (ieee_signaling_gt (0.d0, dnan)) stop 217 + if (ieee_signaling_gt (1.d0, dnan)) stop 218 + if (ieee_signaling_gt (0.d0, dinf)) stop 219 + if (ieee_signaling_gt (1.d0, dinf)) stop 220 + if (ieee_signaling_gt (dinf, dnan)) stop 221 + + if (ieee_signaling_gt (0._large, 0._large)) stop 222 + if (ieee_signaling_gt (0._large, -0._large)) stop 223 + if (ieee_signaling_gt (1._large, 1._large)) stop 224 + if (ieee_signaling_gt (linf, linf)) stop 225 + if (ieee_signaling_gt (-linf, -linf)) stop 226 + if (ieee_signaling_gt (lnan, lnan)) stop 227 + if (ieee_signaling_gt (0._large, 1._large)) stop 228 + if (.not. ieee_signaling_gt (0._large, -1._large)) stop 229 + if (ieee_signaling_gt (0._large, lnan)) stop 230 + if (ieee_signaling_gt (1._large, lnan)) stop 231 + if (ieee_signaling_gt (0._large, linf)) stop 232 + if (ieee_signaling_gt (1._large, linf)) stop 233 + if (ieee_signaling_gt (linf, lnan)) stop 234 + +end program foo diff --git a/gcc/testsuite/gfortran.dg/ieee/comparisons_3.F90 b/gcc/testsuite/gfortran.dg/ieee/comparisons_3.F90 new file mode 100644 index 0000000..c15678f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/ieee/comparisons_3.F90 @@ -0,0 +1,487 @@ +! { dg-do run } +! { dg-options "-ffree-line-length-none" } +program foo + use ieee_arithmetic + use iso_fortran_env + implicit none + + ! This allows us to test REAL128 if it exists, and still compile + ! on platforms were it is not present + ! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89639 + integer, parameter :: large = merge(real128, real64, real128 > 0) + + real, volatile :: rnan, rinf + double precision, volatile :: dnan, dinf + real(kind=large), volatile :: lnan, linf + + logical :: flag + + rinf = ieee_value(0., ieee_positive_inf) + rnan = ieee_value(0., ieee_quiet_nan) + + dinf = ieee_value(0.d0, ieee_positive_inf) + dnan = ieee_value(0.d0, ieee_quiet_nan) + + linf = ieee_value(0._large, ieee_positive_inf) + lnan = ieee_value(0._large, ieee_quiet_nan) + +#define CHECK_INVALID(expected) \ + call ieee_get_flag(ieee_invalid, flag) ; \ + if (flag .neqv. expected) then ; \ + write (*,*) "Check failed at ", __LINE__ ; \ + stop 1; \ + end if ; \ + call ieee_set_flag(ieee_invalid, .false.) + + !! REAL + + ! Signaling versions + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_eq (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_eq (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_eq (0., rnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_eq (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_eq (rnan, rnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_ne (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_ne (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ne (0., rnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_ne (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ne (rnan, rnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_le (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_le (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_le (0., rnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_le (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_le (rnan, rnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0., rnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_lt (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (rnan, rnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ge (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ge (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_ge (0., rnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_ge (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_ge (rnan, rnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0., rnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_gt (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (rnan, rnan)) stop 15 + CHECK_INVALID(.true.) + + ! Quiet versions + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_eq (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_eq (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (0., rnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (rnan, rnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_ne (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_ne (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (0., rnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (rnan, rnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_le (0., rnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_le (rnan, rnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0., rnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_lt (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (rnan, rnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ge (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ge (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (0., rnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (rnan, rnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0., 0.)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0., -0.)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0., rnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0., rinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (rnan, rnan)) stop 15 + CHECK_INVALID(.false.) + + !! DOUBLE PRECISION + + ! Signaling versions + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_eq (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_eq (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_eq (0.d0, dnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_eq (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_eq (dnan, dnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_ne (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_ne (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ne (0.d0, dnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_ne (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ne (dnan, dnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_le (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_le (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_le (0.d0, dnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_le (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_le (dnan, dnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0.d0, dnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_lt (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (dnan, dnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ge (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ge (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_ge (0.d0, dnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_ge (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_ge (dnan, dnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0.d0, dnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_gt (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (dnan, dnan)) stop 15 + CHECK_INVALID(.true.) + + ! Quiet versions + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_eq (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_eq (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (0.d0, dnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (dnan, dnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_ne (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_ne (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (0.d0, dnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (dnan, dnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_le (0.d0, dnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_le (dnan, dnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0.d0, dnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_lt (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (dnan, dnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ge (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ge (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (0.d0, dnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (dnan, dnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0.d0, 0.d0)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0.d0, -0.d0)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0.d0, dnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0.d0, dinf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (dnan, dnan)) stop 15 + CHECK_INVALID(.false.) + + !! LARGE KIND + + ! Signaling versions + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_eq (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_eq (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_eq (0._large, lnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_eq (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_eq (lnan, lnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_ne (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_ne (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ne (0._large, lnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_ne (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ne (lnan, lnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_le (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_le (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_le (0._large, lnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_le (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_le (lnan, lnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (0._large, lnan)) stop 13 + CHECK_INVALID(.true.) + if (.not. ieee_signaling_lt (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_lt (lnan, lnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ge (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_signaling_ge (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_ge (0._large, lnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_ge (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_ge (lnan, lnan)) stop 15 + CHECK_INVALID(.true.) + + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (0._large, lnan)) stop 13 + CHECK_INVALID(.true.) + if (ieee_signaling_gt (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_signaling_gt (lnan, lnan)) stop 15 + CHECK_INVALID(.true.) + + ! Quiet versions + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_eq (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_eq (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (0._large, lnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_eq (lnan, lnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_ne (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_ne (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (0._large, lnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ne (lnan, lnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_le (0._large, lnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_le (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_le (lnan, lnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (0._large, lnan)) stop 13 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_lt (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_lt (lnan, lnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ge (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (.not. ieee_quiet_ge (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (0._large, lnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_ge (lnan, lnan)) stop 15 + CHECK_INVALID(.false.) + + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0._large, 0._large)) stop 11 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0._large, -0._large)) stop 12 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0._large, lnan)) stop 13 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (0._large, linf)) stop 14 + CHECK_INVALID(.false.) + if (ieee_quiet_gt (lnan, lnan)) stop 15 + CHECK_INVALID(.false.) + + +end program foo -- cgit v1.1 From 23ad5ed7432bea7c5d00837f12d8334f53c43cb4 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Thu, 20 Jul 2023 11:55:59 +0200 Subject: Fortran: fix wrong rebase that broke bootstrap Sorry... gcc/fortran/ * trans-intrinsic.cc (conv_intrinsic_ieee_comparison): Only define it once. --- gcc/fortran/trans-intrinsic.cc | 86 ------------------------------------------ 1 file changed, 86 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index e0f86b1..2893091 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -10462,92 +10462,6 @@ conv_intrinsic_ieee_comparison (gfc_se * se, gfc_expr * expr, int signaling, } -/* Generate code for comparison functions IEEE_QUIET_* and - IEEE_SIGNALING_*. */ - -static void -conv_intrinsic_ieee_comparison (gfc_se * se, gfc_expr * expr, int signaling, - const char *name) -{ - tree args[2]; - tree arg1, arg2, res; - - /* Evaluate arguments only once. */ - conv_ieee_function_args (se, expr, args, 2); - arg1 = gfc_evaluate_now (args[0], &se->pre); - arg2 = gfc_evaluate_now (args[1], &se->pre); - - if (startswith (name, "eq")) - { - if (signaling) - res = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_ISEQSIG), - 2, arg1, arg2); - else - res = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, - arg1, arg2); - } - else if (startswith (name, "ne")) - { - if (signaling) - { - res = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_ISEQSIG), - 2, arg1, arg2); - res = fold_build1_loc (input_location, TRUTH_NOT_EXPR, - logical_type_node, res); - } - else - res = fold_build2_loc (input_location, NE_EXPR, logical_type_node, - arg1, arg2); - } - else if (startswith (name, "ge")) - { - if (signaling) - res = fold_build2_loc (input_location, GE_EXPR, logical_type_node, - arg1, arg2); - else - res = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL), - 2, arg1, arg2); - } - else if (startswith (name, "gt")) - { - if (signaling) - res = fold_build2_loc (input_location, GT_EXPR, logical_type_node, - arg1, arg2); - else - res = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_ISGREATER), - 2, arg1, arg2); - } - else if (startswith (name, "le")) - { - if (signaling) - res = fold_build2_loc (input_location, LE_EXPR, logical_type_node, - arg1, arg2); - else - res = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_ISLESSEQUAL), - 2, arg1, arg2); - } - else if (startswith (name, "lt")) - { - if (signaling) - res = fold_build2_loc (input_location, LT_EXPR, logical_type_node, - arg1, arg2); - else - res = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_ISLESS), - 2, arg1, arg2); - } - else - gcc_unreachable (); - - se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), res); -} - - /* Generate code for an intrinsic function from the IEEE_ARITHMETIC module. */ -- cgit v1.1 From c5bd0e5870aed178b7f82e7b94f59a383e7c5b4f Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Thu, 20 Jul 2023 11:43:12 +0100 Subject: vectorizer: Avoid an OOB access from vectorization Our checks for whether the vectorization of a given loop would make an out of bounds access miss the case when the vector we load is so large as to span multiple iterations worth of data (while only being there to implement a single iteration). This patch adds a check for such an access. Example where this was going wrong (smaller version of testcase added): ``` extern unsigned short multi_array[5][16][16]; extern void initialise_s(int *); extern int get_sval(); void foo() { int s0 = get_sval(); int s[31]; int i,j; initialise_s(&s[0]); s0 = get_sval(); for (j=0; j < 16; j++) for (i=0; i < 16; i++) multi_array[1][j][i]=s[j*2]; } ``` With the above loop we would load the `s[j*2]` integer into a 4 element vector, which reads 3 extra elements than the scalar loop would. `get_group_load_store_type` identifies that the loop requires a scalar epilogue due to gaps. However we do not identify that the above code requires *two* scalar loops to be peeled due to the fact that each iteration loads an amount of data from the *next* iteration (while not using it). Bootstrapped and regtested on aarch64-none-linux-gnu. N.b. out of interest we came across this working with Morello. gcc/ChangeLog: * tree-vect-stmts.cc (get_group_load_store_type): Account for `gap` when checking if need to peel twice. gcc/testsuite/ChangeLog: * gcc.dg/vect/vect-multi-peel-gaps.c: New test. --- gcc/testsuite/gcc.dg/vect/vect-multi-peel-gaps.c | 61 ++++++++++++++++++++++++ gcc/tree-vect-stmts.cc | 6 ++- 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-multi-peel-gaps.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/vect-multi-peel-gaps.c b/gcc/testsuite/gcc.dg/vect/vect-multi-peel-gaps.c new file mode 100644 index 0000000..1aab4c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multi-peel-gaps.c @@ -0,0 +1,61 @@ +/* For some targets we end up vectorizing the below loop such that the `sp` + single integer is loaded into a 4 integer vector. + While the writes are all safe, without 2 scalar loops being peeled into the + epilogue we would read past the end of the 31 integer array. This happens + because we load a 4 integer chunk to only use the first integer and + increment by 2 integers at a time, hence the last load needs s[30-33] and + the penultimate load needs s[28-31]. + This testcase ensures that we do not crash due to that behaviour. */ +/* { dg-require-effective-target mmap } */ +#include +#include + +#define MMAP_SIZE 0x20000 +#define ADDRESS 0x1122000000 + +#define MB_BLOCK_SIZE 16 +#define VERT_PRED_16 0 +#define HOR_PRED_16 1 +#define DC_PRED_16 2 +int *sptr; +extern void intrapred_luma_16x16(); +unsigned short mprr_2[5][16][16]; +void initialise_s(int *s) { } +int main() { + void *s_mapping; + void *end_s; + s_mapping = mmap ((void *)ADDRESS, MMAP_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (s_mapping == MAP_FAILED) + { + perror ("mmap"); + return 1; + } + end_s = (s_mapping + MMAP_SIZE); + sptr = (int*)(end_s - sizeof(int[31])); + intrapred_luma_16x16(sptr); + return 0; +} + +void intrapred_luma_16x16(int * restrict sp) { + for (int j=0; j < MB_BLOCK_SIZE; j++) + { + mprr_2[VERT_PRED_16][j][0]=sp[j*2]; + mprr_2[VERT_PRED_16][j][1]=sp[j*2]; + mprr_2[VERT_PRED_16][j][2]=sp[j*2]; + mprr_2[VERT_PRED_16][j][3]=sp[j*2]; + mprr_2[VERT_PRED_16][j][4]=sp[j*2]; + mprr_2[VERT_PRED_16][j][5]=sp[j*2]; + mprr_2[VERT_PRED_16][j][6]=sp[j*2]; + mprr_2[VERT_PRED_16][j][7]=sp[j*2]; + mprr_2[VERT_PRED_16][j][8]=sp[j*2]; + mprr_2[VERT_PRED_16][j][9]=sp[j*2]; + mprr_2[VERT_PRED_16][j][10]=sp[j*2]; + mprr_2[VERT_PRED_16][j][11]=sp[j*2]; + mprr_2[VERT_PRED_16][j][12]=sp[j*2]; + mprr_2[VERT_PRED_16][j][13]=sp[j*2]; + mprr_2[VERT_PRED_16][j][14]=sp[j*2]; + mprr_2[VERT_PRED_16][j][15]=sp[j*2]; + } +} +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" {target vect_int } } } */ diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index cb86d54..60de650 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -2217,7 +2217,9 @@ get_group_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, but the access in the loop doesn't cover the full vector we can end up with no gap recorded but still excess elements accessed, see PR103116. Make sure we peel for - gaps if necessary and sufficient and give up if not. */ + gaps if necessary and sufficient and give up if not. + If there is a combination of the access not covering the full vector and + a gap recorded then we may need to peel twice. */ if (loop_vinfo && *memory_access_type == VMAT_CONTIGUOUS && SLP_TREE_LOAD_PERMUTATION (slp_node).exists () @@ -2233,7 +2235,7 @@ get_group_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, access excess elements. ??? Enhancements include peeling multiple iterations or using masked loads with a static mask. */ - || (group_size * cvf) % cnunits + group_size < cnunits) + || (group_size * cvf) % cnunits + group_size - gap < cnunits) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, -- cgit v1.1 From d0de3bf9175877d6c51c94fe04662c6e031876e1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 17 Jul 2023 12:15:29 +0200 Subject: tree-optimization/110204 - second level redundancy and simplification When PRE discovers a full redundancy during insertion it cannot unite the two value sets. Instead it inserts a copy old-val = new-val where new-val can also be a constant. The following looks through such copies during elimination, providing one extra level of constant and copy propagation. For the PR this helps avoiding a bogus diagnostic that's emitted on unreachable code during loop optimization. PR tree-optimization/110204 * tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_avail): Look through copies generated by PRE. --- gcc/tree-ssa-sccvn.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 11061a3..a0b98c1 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -6594,7 +6594,22 @@ eliminate_dom_walker::eliminate_avail (basic_block, tree op) if (SSA_NAME_IS_DEFAULT_DEF (valnum)) return valnum; if (avail.length () > SSA_NAME_VERSION (valnum)) - return avail[SSA_NAME_VERSION (valnum)]; + { + tree av = avail[SSA_NAME_VERSION (valnum)]; + /* When PRE discovers a new redundancy there's no way to unite + the value classes so it instead inserts a copy old-val = new-val. + Look through such copies here, providing one more level of + simplification at elimination time. */ + gassign *ass; + if (av && (ass = dyn_cast (SSA_NAME_DEF_STMT (av)))) + if (gimple_assign_rhs_class (ass) == GIMPLE_SINGLE_RHS) + { + tree rhs1 = gimple_assign_rhs1 (ass); + if (CONSTANT_CLASS_P (rhs1) || TREE_CODE (rhs1) == SSA_NAME) + av = rhs1; + } + return av; + } } else if (is_gimple_min_invariant (valnum)) return valnum; -- cgit v1.1 From ef28aadad6e5cff3d7494f3c97d435a6579a2e2d Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 20 Jul 2023 15:41:39 +0200 Subject: loop-ch improvements, part 3 Make tree-ssa-loop-ch understand if-combined conditionals (which are quite common) and remove the IV-derived heuristics. That heuristics is quite dubious because every variable with PHI in header of integral or pointer type is seen as IV, so in the first basic block we match all loop invariants as invariants and everything that chagnes in loop as IV-like. I think the heuristics was mostly there to make header duplication happen when the exit conditional is constant false in the first iteration and with ranger we can work this out in good enough precision. The patch adds notion of "combined exit" which has conditional that is and/or/xor of loop invariant exit and exit known to be false in first iteration. Copying these is a win since the loop conditional will simplify in both copies. It seems that those are usual bit or/and/xor and the code size accounting is true only when the values have at most one bit set or when the static constant and invariant versions are simple (such as all zeros). I am not testing this, so the code may be optimistic here. I think it is not common enough to matter and I can not think of correct condition that is not quite complex. I also improved code size estimate not accounting non-conditionals that are know to be constant in peeled copy and improved debug output. This requires testsuite compensaiton. uninit-pred-loop-1.c.C does: /* { dg-do compile } */ /* { dg-options "-Wuninitialized -O2 -std=c++98" } */ extern int bar(); int foo(int n, int m) { for (;;) { int err = ({int _err; for (int i = 0; i < 16; ++i) { if (m+i > n) break; _err = 17; _err = bar(); } _err; }); if (err == 0) return 17; } Before path we duplicate if (m+i > n) which makes maybe-uninitialized warning to not be output. I do not quite see why copying this out would be a win, since it won't simlify. Also I think the warning is correct. if m>n the loop will bail out before initializing _err and it will be used unitialized. I think it is bug elsewhere that header duplication supresses this. copy headers does: int is_sorted(int *a, int n, int m, int k) { for (int i = 0; i < n - 1 && m && k > i; i++) if (a[i] > a[i + 1]) return 0; return 1; } it tests that all three for statement conditionals are duplicaed. With patch we no longer do k>i since it is not going to simplify. So I added test ensuring that k is positive. Also the tests requires disabling if-combining and vrp to avoid conditionals becoming combined ones. So I aded new version of test that we now behave correctly aslo with if-combine. ivopt_mult_2.c and ivopt_mult_1.c seems to require loop header duplication for ivopts to behave particular way, so I also ensured by value range that the header is duplicated. Bootstrapped/regtested x86_64-linux, OK? gcc/ChangeLog: * tree-ssa-loop-ch.cc (edge_range_query): Rename to ... (get_range_query): ... this one; do (static_loop_exit): Add query parametr, turn ranger to reference. (loop_static_stmt_p): New function. (loop_static_op_p): New function. (loop_iv_derived_p): Remove. (loop_combined_static_and_iv_p): New function. (should_duplicate_loop_header_p): Discover combined onditionals; do not track iv derived; improve dumps. (pass_ch::execute): Fix whitespace. gcc/testsuite/ChangeLog: * g++.dg/uninit-pred-loop-1_c.C: Allow warning. * gcc.dg/tree-ssa/copy-headers-7.c: Add tests so exit conditition is static; update template. * gcc.dg/tree-ssa/ivopt_mult_1.c: Add test so exit condition is static. * gcc.dg/tree-ssa/ivopt_mult_2.c: Add test so exit condition is static. * gcc.dg/tree-ssa/copy-headers-8.c: New test. --- gcc/testsuite/g++.dg/uninit-pred-loop-1_c.C | 2 +- gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c | 11 +- gcc/testsuite/gcc.dg/tree-ssa/copy-headers-8.c | 18 ++ gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_1.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_2.c | 19 +- gcc/tree-ssa-loop-ch.cc | 278 ++++++++++++++++++------- 6 files changed, 241 insertions(+), 88 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/copy-headers-8.c (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/uninit-pred-loop-1_c.C b/gcc/testsuite/g++.dg/uninit-pred-loop-1_c.C index 711812a..1ee1615 100644 --- a/gcc/testsuite/g++.dg/uninit-pred-loop-1_c.C +++ b/gcc/testsuite/g++.dg/uninit-pred-loop-1_c.C @@ -15,7 +15,7 @@ int foo(int n, int m) _err; }); - if (err == 0) return 17; + if (err == 0) return 17; /* { dg-warning "uninitialized" "warning" } */ } return 18; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c index 3c9b380..e2a6c75 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c @@ -3,9 +3,10 @@ int is_sorted(int *a, int n, int m, int k) { - for (int i = 0; i < n - 1 && m && k > i; i++) - if (a[i] > a[i + 1]) - return 0; + if (k > 0) + for (int i = 0; i < n - 1 && m && k > i; i++) + if (a[i] > a[i + 1]) + return 0; return 1; } @@ -13,4 +14,8 @@ int is_sorted(int *a, int n, int m, int k) the invariant test, not the alternate exit test. */ /* { dg-final { scan-tree-dump "is now do-while loop" "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Conditional combines static and invariant" 0 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Will elliminate invariant exit" 1 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Will eliminate peeled conditional" 1 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Not duplicating bb .: condition based on non-IV loop variant." 1 "ch2" } } */ /* { dg-final { scan-tree-dump-times "Will duplicate bb" 3 "ch2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-8.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-8.c new file mode 100644 index 0000000..8b4b5e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-8.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ch2-details" } */ + +int is_sorted(int *a, int n, int m, int k) +{ + if (k > 0) + for (int i = 0; i < n - 1 && m && k > i; i++) + if (a[i] > a[i + 1]) + return 0; + return 1; +} + +/* Verify we apply loop header copying but only copy the IV tests and + the invariant test, not the alternate exit test. */ + +/* { dg-final { scan-tree-dump "is now do-while loop" "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Conditional combines static and invariant" 1 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Will duplicate bb" 2 "ch2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_1.c b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_1.c index adfe371..faed911 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_1.c @@ -9,6 +9,7 @@ long foo(long* p, long* p2, int N1, int N2) long* p_limit = p + N1; long* p_limit2 = p2 + N2; long s = 0; + if (p2 <= p_limit2) while (p <= p_limit) { p++; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_2.c b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_2.c index 50d0cc5..6a82aeb 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_2.c @@ -8,15 +8,16 @@ long foo(long* p, long* p2, int N1, int N2) int i = 0; long* p_limit2 = p2 + N2; long s = 0; - while (i < N1) - { - p++; - p2++; - i++; - if (p2 > p_limit2) - break; - s += (*p); - } + if (p2 <= p_limit2) + while (i < N1) + { + p++; + p2++; + i++; + if (p2 > p_limit2) + break; + s += (*p); + } return s; } diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index e0139cb..3e6d167 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -38,34 +38,33 @@ along with GCC; see the file COPYING3. If not see #include "value-range.h" #include "gimple-range.h" #include "gimple-range-path.h" +#include "gimple-pretty-print.h" #include "cfganal.h" -/* Duplicates headers of loops if they are small enough, so that the statements - in the loop body are always executed when the loop is entered. This - increases effectiveness of code motion optimizations, and reduces the need - for loop preconditioning. */ +/* Return path query insteance for testing ranges of statements + in headers of LOOP contained in basic block BB. + Use RANGER instance. */ -/* Given a path through edge E, whose last statement is COND, return - the range of the solved conditional in R. */ - -static void -edge_range_query (irange &r, class loop *loop, gcond *cond, gimple_ranger &ranger) +static path_range_query * +get_range_query (class loop *loop, + basic_block bb, + gimple_ranger &ranger) { auto_vec path; - for (basic_block bb = gimple_bb (cond); bb != loop->header; bb = single_pred_edge (bb)->src) + for (; bb != loop->header; bb = single_pred_edge (bb)->src) path.safe_push (bb); path.safe_push (loop->header); path.safe_push (loop_preheader_edge (loop)->src); - path_range_query query (ranger, path); - if (!query.range_of_stmt (r, cond)) - r.set_varying (boolean_type_node); + return new path_range_query (ranger, path); } /* Return edge that is true in the first iteration of the loop - and NULL otherwise. */ + and NULL otherwise. + Formulate corrent ranger query to RANGER. */ static edge -static_loop_exit (class loop *l, basic_block bb, gimple_ranger *ranger) +static_loop_exit (class loop *l, basic_block bb, gimple_ranger &ranger, + path_range_query *&query) { gcond *last = safe_dyn_cast (*gsi_last_bb (bb)); edge ret_e; @@ -83,21 +82,48 @@ static_loop_exit (class loop *l, basic_block bb, gimple_ranger *ranger) int_range<1> desired_static_range; if (loop_exit_edge_p (l, true_e)) - { + { desired_static_range = range_false (); ret_e = true_e; - } + } else - { - desired_static_range = range_true (); - ret_e = false_e; - } + { + desired_static_range = range_true (); + ret_e = false_e; + } + + if (!query) + query = get_range_query (l, gimple_bb (last), ranger); int_range<2> r; - edge_range_query (r, l, last, *ranger); + if (!query->range_of_stmt (r, last)) + return NULL; return r == desired_static_range ? ret_e : NULL; } +/* Return true if STMT is static in LOOP. This means that its value + is constant in the first iteration. + Use RANGER and formulate query cached in QUERY. */ + +static bool +loop_static_stmt_p (class loop *loop, + gimple_ranger &ranger, + path_range_query *&query, + gimple *stmt) +{ + tree type = gimple_range_type (stmt); + if (!type || !Value_Range::supports_type_p (type)) + return false; + + if (!query) + query = get_range_query (loop, gimple_bb (stmt), ranger); + + Value_Range r (gimple_range_type (stmt)); + if (!query->range_of_stmt (r, stmt)) + return false; + return r.singleton_p (); +} + /* Return true if OP is invariant. */ static bool @@ -109,21 +135,37 @@ loop_invariant_op_p (class loop *loop, if (SSA_NAME_IS_DEFAULT_DEF (op) || !flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (op)))) return true; + return gimple_uid (SSA_NAME_DEF_STMT (op)) & 1; +} + +/* Return true if OP combines outcome of static and + loop invariant conditional. */ + +static bool +loop_static_op_p (class loop *loop, tree op) +{ + /* Always check for invariant first. */ + gcc_checking_assert (!is_gimple_min_invariant (op) + && !SSA_NAME_IS_DEFAULT_DEF (op) + && flow_bb_inside_loop_p (loop, + gimple_bb (SSA_NAME_DEF_STMT (op)))); return gimple_uid (SSA_NAME_DEF_STMT (op)) & 2; } -/* Return true if OP looks like it is derived from IV. */ + +/* Return true if OP combines outcome of static and + loop invariant conditional. */ static bool -loop_iv_derived_p (class loop *loop, - tree op) +loop_combined_static_and_iv_p (class loop *loop, + tree op) { /* Always check for invariant first. */ gcc_checking_assert (!is_gimple_min_invariant (op) && !SSA_NAME_IS_DEFAULT_DEF (op) && flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (op)))); - return gimple_uid (SSA_NAME_DEF_STMT (op)) & 1; + return gimple_uid (SSA_NAME_DEF_STMT (op)) & 4; } /* Check whether we should duplicate HEADER of LOOP. At most *LIMIT @@ -182,25 +224,18 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, return false; } + path_range_query *query = NULL; for (gphi_iterator psi = gsi_start_phis (header); !gsi_end_p (psi); gsi_next (&psi)) - /* If this is actual loop header PHIs indicate that the SSA_NAME - may be IV. Otherwise just give up. */ - if (header == loop->header) + if (!virtual_operand_p (gimple_phi_result (psi.phi ()))) { - gphi *phi = psi.phi (); - tree res = gimple_phi_result (phi); - if (INTEGRAL_TYPE_P (TREE_TYPE (res)) - || POINTER_TYPE_P (TREE_TYPE (res))) - gimple_set_uid (phi, 1 /* IV */); - else - gimple_set_uid (phi, 0); + bool static_p = loop_static_stmt_p (loop, *ranger, + query, psi.phi ()); + gimple_set_uid (psi.phi (), static_p ? 2 : 0); } - else - gimple_set_uid (psi.phi (), 0); /* Count number of instructions and punt on calls. - Populate stmts INV/IV flag to later apply heuristics to the + Populate stmts INV flag to later apply heuristics to the kind of conditions we want to copy. */ for (bsi = gsi_start_bb (header); !gsi_end_p (bsi); gsi_next (&bsi)) { @@ -215,6 +250,12 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, if (gimple_code (last) == GIMPLE_COND) break; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " Analyzing: "); + print_gimple_stmt (dump_file, last, 0, TDF_SLIM); + } + if (gimple_code (last) == GIMPLE_CALL && (!gimple_inexpensive_call_p (as_a (last)) /* IFN_LOOP_DIST_ALIAS means that inner loop is distributed @@ -225,53 +266,149 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, fprintf (dump_file, " Not duplicating bb %i: it contains call.\n", header->index); + if (query) + delete query; return false; } - /* Classify the stmt based on whether its computation is based - on a IV or whether it is invariant in the loop. */ + /* Classify the stmt is invariant in the loop. */ gimple_set_uid (last, 0); if (!gimple_vuse (last) && gimple_code (last) != GIMPLE_ASM && (gimple_code (last) != GIMPLE_CALL || gimple_call_flags (last) & ECF_CONST)) { - bool inv = true; - bool iv = true; + bool inv = true, static_p = false; ssa_op_iter i; tree op; FOR_EACH_SSA_TREE_OPERAND (op, last, i, SSA_OP_USE) if (!loop_invariant_op_p (loop, op)) - { - if (!loop_iv_derived_p (loop, op)) - { - inv = false; - iv = false; - break; - } - else - inv = false; - } - gimple_set_uid (last, (iv ? 1 : 0) | (inv ? 2 : 0)); + inv = false; + /* Assume that code is reasonably optimized and invariant + constants are already identified. */ + if (!inv) + static_p = loop_static_stmt_p (loop, *ranger, query, last); + gimple_set_uid (last, (inv ? 1 : 0) | (static_p ? 2 : 0)); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + if (inv) + fprintf (dump_file, " Stmt is loop invariant\n"); + if (static_p) + fprintf (dump_file, " Stmt is static " + "(constant in the first iteration)\n"); + } /* Loop invariants will be optimized out in loop body after duplication; do not account invariant computation in code - size costs. */ - if (inv) + size costs. + + Similarly static computations will be optimized out in the + duplicatd header. */ + if (inv || static_p) continue; + + /* Match the following: + _1 = i_1 < 10 <- static condtion + _2 = n != 0 <- loop invariant condition + _3 = _1 & _2 <- combined static and iv statement. */ + tree_code code; + if (gimple_code (last) == GIMPLE_ASSIGN + && ((code = gimple_assign_rhs_code (last)) == TRUTH_AND_EXPR + || code == TRUTH_OR_EXPR || code == TRUTH_XOR_EXPR)) + { + tree op1 = gimple_assign_rhs1 (last); + tree op2 = gimple_assign_rhs2 (last); + + if ((loop_invariant_op_p (loop, op1) + || loop_combined_static_and_iv_p (loop, op1) + || loop_static_op_p (loop, op1)) + && (loop_invariant_op_p (loop, op2) + || loop_combined_static_and_iv_p (loop, op2) + || loop_static_op_p (loop, op2))) + { + /* Duplicating loop header with combned conditional will + remove this statement in each copy. But we account for + that later when seeing that condition. + + Note that this may be overly optimistic for bit operations + where the static parameter may still result in non-trivial + bit operation. */ + gimple_set_uid (last, 4); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Stmt combines static and invariant op\n"); + continue; + } + } } - *limit -= estimate_num_insns (last, &eni_size_weights); + int insns = estimate_num_insns (last, &eni_size_weights); + *limit -= insns; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Acconting stmt as %i insns\n", insns); if (*limit < 0) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Not duplicating bb %i contains too many insns.\n", header->index); + if (query) + delete query; return false; } } - edge static_exit = static_loop_exit (loop, header, ranger); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " Analyzing: "); + print_gimple_stmt (dump_file, last, 0, TDF_SLIM); + } + + /* If the condition tests a non-IV loop variant we do not want to rotate + the loop further. Unless this is the original loop header. */ + tree lhs = gimple_cond_lhs (last); + tree rhs = gimple_cond_rhs (last); + bool lhs_invariant = loop_invariant_op_p (loop, lhs); + bool rhs_invariant = loop_invariant_op_p (loop, rhs); + + /* Combined conditional is a result of if combining: + + _1 = i_1 < 10 <- static condtion + _2 = n != 0 <- loop invariant condition + _3 = _1 & _2 <- combined static and iv statement + if (_3 != 0) <- combined conditional + + Combined conditionals will not be optimized out in either copy. + However duplicaed header simplifies to: + + if (n < 10) + + while loop body to + + if (i_1 < 10) + + So effectively the resulting code sequence will be of same length as + the original code. + + Combined conditionals are never static or invariant, so save some work + below. */ + if (lhs_invariant != rhs_invariant + && (lhs_invariant + || loop_combined_static_and_iv_p (loop, lhs)) + && (rhs_invariant + || loop_combined_static_and_iv_p (loop, rhs))) + { + if (query) + delete query; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Conditional combines static and invariant op.\n"); + return true; + } + + edge static_exit = static_loop_exit (loop, header, *ranger, query); + if (query) + delete query; if (static_exit && static_exits) { @@ -282,13 +419,6 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, static_exit->src->index); /* Still look for invariant exits; exit may be both. */ } - - /* If the condition tests a non-IV loop variant we do not want to rotate - the loop further. Unless this is the original loop header. */ - tree lhs = gimple_cond_lhs (last); - tree rhs = gimple_cond_rhs (last); - bool lhs_invariant = loop_invariant_op_p (loop, lhs); - bool rhs_invariant = loop_invariant_op_p (loop, rhs); if (lhs_invariant && rhs_invariant) { if (invariant_exits) @@ -312,7 +442,11 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, return true; /* We was not able to prove that conditional will be eliminated. */ - *limit -= estimate_num_insns (last, &eni_size_weights); + int insns = estimate_num_insns (last, &eni_size_weights); + *limit -= insns; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Acconting stmt as %i insns\n", insns); if (*limit < 0) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -322,12 +456,6 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, return false; } - /* TODO: This is heuristics that claims that IV based ocnditionals will - likely be optimized out in duplicated header. We could use ranger - query instead to tell this more precisely. */ - if ((lhs_invariant || loop_iv_derived_p (loop, lhs)) - && (rhs_invariant || loop_iv_derived_p (loop, rhs))) - return true; if (header != loop->header) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -550,7 +678,7 @@ public: /* opt_pass methods: */ bool gate (function *) final override { return flag_tree_ch != 0; } - + /* Initialize and finalize loop structures, copying headers inbetween. */ unsigned int execute (function *) final override; @@ -590,7 +718,7 @@ public: return flag_tree_ch != 0 && (flag_tree_loop_vectorize != 0 || fun->has_force_vectorize_loops); } - + /* Just copy headers, no initialization/finalization of loop structures. */ unsigned int execute (function *) final override; @@ -973,7 +1101,7 @@ pass_ch::execute (function *fun) /* Assume an earlier phase has already initialized all the loop structures that we need here (and perhaps others too), and that these will be finalized by a later phase. */ - + unsigned int pass_ch_vect::execute (function *fun) { -- cgit v1.1 From b6b72562d116bd0a589dce39437f9d2b3c34491f Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Thu, 20 Jul 2023 16:06:29 +0800 Subject: CODE STRUCTURE: Refine codes in Vectorizer Hi, Richard and Richi. I plan to refine the codes that I recently support for RVV auto-vectorization. This patch is inspired last review comments from Richard: https://patchwork.sourceware.org/project/gcc/patch/20230712042124.111818-1-juzhe.zhong@rivai.ai/ Richard said he prefer the the code structure as follows: Please instead switch the if condition so that the structure is: if (...) vect_record_loop_mask (...) else if (...) vect_record_loop_len (...) else can't use partial vectors This is his last comments. So, I come back to refine this piece of codes. Does it look reasonable ? This next refine patch is change all names of "LEN_MASK" into "MASK_LEN" but should come after this patch. gcc/ChangeLog: * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Refine code structure. --- gcc/tree-vect-stmts.cc | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 60de650..cc9a200 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1605,6 +1605,7 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype, nvectors = vect_get_num_copies (loop_vinfo, vectype); vec_loop_masks *masks = &LOOP_VINFO_MASKS (loop_vinfo); + vec_loop_lens *lens = &LOOP_VINFO_LENS (loop_vinfo); machine_mode vecmode = TYPE_MODE (vectype); bool is_load = (vls_type == VLS_LOAD); if (memory_access_type == VMAT_LOAD_STORE_LANES) @@ -1631,33 +1632,29 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype, internal_fn ifn = (is_load ? IFN_MASK_GATHER_LOAD : IFN_MASK_SCATTER_STORE); - if (!internal_gather_scatter_fn_supported_p (ifn, vectype, - gs_info->memory_type, - gs_info->offset_vectype, - gs_info->scale)) - { - ifn = (is_load - ? IFN_LEN_MASK_GATHER_LOAD - : IFN_LEN_MASK_SCATTER_STORE); - if (internal_gather_scatter_fn_supported_p (ifn, vectype, - gs_info->memory_type, - gs_info->offset_vectype, - gs_info->scale)) - { - vec_loop_lens *lens = &LOOP_VINFO_LENS (loop_vinfo); - vect_record_loop_len (loop_vinfo, lens, nvectors, vectype, 1); - return; - } + internal_fn len_ifn = (is_load + ? IFN_LEN_MASK_GATHER_LOAD + : IFN_LEN_MASK_SCATTER_STORE); + if (internal_gather_scatter_fn_supported_p (ifn, vectype, + gs_info->memory_type, + gs_info->offset_vectype, + gs_info->scale)) + vect_record_loop_mask (loop_vinfo, masks, nvectors, vectype, + scalar_mask); + else if (internal_gather_scatter_fn_supported_p (len_ifn, vectype, + gs_info->memory_type, + gs_info->offset_vectype, + gs_info->scale)) + vect_record_loop_len (loop_vinfo, lens, nvectors, vectype, 1); + else + { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "can't operate on partial vectors because" " the target doesn't have an appropriate" " gather load or scatter store instruction.\n"); LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; - return; } - vect_record_loop_mask (loop_vinfo, masks, nvectors, vectype, - scalar_mask); return; } @@ -1703,7 +1700,6 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype, if (get_len_load_store_mode (vecmode, is_load).exists (&vmode)) { nvectors = group_memory_nvectors (group_size * vf, nunits); - vec_loop_lens *lens = &LOOP_VINFO_LENS (loop_vinfo); unsigned factor = (vecmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vecmode); vect_record_loop_len (loop_vinfo, lens, nvectors, vectype, factor); using_partial_vectors_p = true; -- cgit v1.1 From 2cb0dc866e8f95151df5d759157708108e850dd9 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 19 Jul 2023 08:47:29 -0400 Subject: c++: fix ICE with designated initializer [PR110114] r13-1227 added an assert checking that the index in a CONSTRUCTOR is a FIELD_DECL. That's a reasonable assumption but in this case we never called reshape_init due to the type being incomplete, and so the index remained an identifier node: get_class_binding never got around to looking up the FIELD_DECL. We can avoid the crash by returning early in implicit_conversion_1; we'd return NULL anyway due to: if (i < CONSTRUCTOR_NELTS (ctor)) return NULL; in build_aggr_conv. PR c++/110114 gcc/cp/ChangeLog: * call.cc (implicit_conversion_1): Return early if the type isn't complete. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist100.C: Adjust expected diagnostic. * g++.dg/cpp2a/desig28.C: New test. * g++.dg/cpp2a/desig29.C: New test. --- gcc/cp/call.cc | 19 +++++++++++-------- gcc/testsuite/g++.dg/cpp0x/initlist100.C | 4 ++-- gcc/testsuite/g++.dg/cpp2a/desig28.C | 17 +++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/desig29.C | 10 ++++++++++ 4 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/desig28.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/desig29.C (limited to 'gcc') diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index b55230d..673ec91 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -2059,15 +2059,18 @@ implicit_conversion_1 (tree to, tree from, tree expr, bool c_cast_p, complain &= ~tf_error; /* Call reshape_init early to remove redundant braces. */ - if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr) - && CLASS_TYPE_P (to) - && COMPLETE_TYPE_P (complete_type (to)) - && !CLASSTYPE_NON_AGGREGATE (to)) + if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr) && CLASS_TYPE_P (to)) { - expr = reshape_init (to, expr, complain); - if (expr == error_mark_node) - return NULL; - from = TREE_TYPE (expr); + to = complete_type (to); + if (!COMPLETE_TYPE_P (to)) + return nullptr; + if (!CLASSTYPE_NON_AGGREGATE (to)) + { + expr = reshape_init (to, expr, complain); + if (expr == error_mark_node) + return nullptr; + from = TREE_TYPE (expr); + } } if (TYPE_REF_P (to)) diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist100.C b/gcc/testsuite/g++.dg/cpp0x/initlist100.C index 9d80a00..6865d34 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist100.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist100.C @@ -2,9 +2,9 @@ // { dg-do compile { target c++11 } } namespace std { -template class initializer_list; // { dg-message "declaration" } +template class initializer_list; } template struct B { B (std::initializer_list); }; struct C { virtual int foo (); }; -struct D : C {} d { B { D {} } }; // { dg-error "incomplete|no matching" } +struct D : C {} d { B { D {} } }; // { dg-error "no matching" } diff --git a/gcc/testsuite/g++.dg/cpp2a/desig28.C b/gcc/testsuite/g++.dg/cpp2a/desig28.C new file mode 100644 index 0000000..b63265f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/desig28.C @@ -0,0 +1,17 @@ +// PR c++/110114 +// { dg-do compile { target c++20 } } + +struct A { + int a,b; +}; + +struct B; + +void foo(const A &) {} +void foo(const B &) {} + +int +main () +{ + foo({.a=0}); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/desig29.C b/gcc/testsuite/g++.dg/cpp2a/desig29.C new file mode 100644 index 0000000..bd1a82b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/desig29.C @@ -0,0 +1,10 @@ +// PR c++/110114 +// { dg-do compile { target c++20 } } + +struct B; + +void foo(const B &) {} + +int main() { + foo({.a=0}); // { dg-error "invalid" } +} -- cgit v1.1 From c0c5a57bff5cf2b6f3d6c55e70c0dc7d4e1fe1aa Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Thu, 20 Jul 2023 16:43:36 +0200 Subject: Document new analyzer parameters This patch documents the analyzer parameters introduced in r14-2029-g0e466e978c7286 also in gcc/doc/invoke.texi. 2023-07-20 Martin Jambor * doc/invoke.texi (analyzer-text-art-string-ellipsis-threshold): New. (analyzer-text-art-ideal-canvas-width): Likewise. (analyzer-text-art-string-ellipsis-head-len): Likewise. (analyzer-text-art-string-ellipsis-tail-len): Likewise. --- gcc/doc/invoke.texi | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d3c821e..5628c08 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -16324,6 +16324,18 @@ The parameter is used only in GIMPLE FE. The maximum number of 'after supernode' exploded nodes within the analyzer per supernode, before terminating analysis. +@item analyzer-text-art-string-ellipsis-threshold +The number of bytes at which to ellipsize string literals in analyzer text art diagrams. + +@item analyzer-text-art-ideal-canvas-width +The ideal width in characters of text art diagrams generated by the analyzer. + +@item analyzer-text-art-string-ellipsis-head-len +The number of literal bytes to show at the head of a string literal in text art when ellipsizing it. + +@item analyzer-text-art-string-ellipsis-tail-len +The number of literal bytes to show at the tail of a string literal in text art when ellipsizing it. + @item ranger-logical-depth Maximum depth of logical expression evaluation ranger will look through when evaluating outgoing edge ranges. -- cgit v1.1 From 70e46073910f2df3bd43decbfc530e16e59b3509 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 20 Jul 2023 17:53:31 +0200 Subject: Fix last-minute change to previs tree-ssa-loop-ch.cc patch gcc/ChangeLog: * tree-ssa-loop-ch.cc (should_duplicate_loop_header_p): Use BIT instead of TRUTH logical ops. --- gcc/tree-ssa-loop-ch.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 3e6d167..a87ebc5 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -312,8 +312,8 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, _3 = _1 & _2 <- combined static and iv statement. */ tree_code code; if (gimple_code (last) == GIMPLE_ASSIGN - && ((code = gimple_assign_rhs_code (last)) == TRUTH_AND_EXPR - || code == TRUTH_OR_EXPR || code == TRUTH_XOR_EXPR)) + && ((code = gimple_assign_rhs_code (last)) == BIT_AND_EXPR + || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)) { tree op1 = gimple_assign_rhs1 (last); tree op2 = gimple_assign_rhs2 (last); -- cgit v1.1 From 85a4e4f93ff251f206e9df3a0d47d5734ed328fc Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 21 Sep 2019 01:27:34 +0000 Subject: Move combine over to statistics_counter_event. Since we have statistics_counter_event now, combine should use that instead of it is own custom printing of statistics. The only thing that is not done any more after this patch is printing out the total stats for the whole TU. Note you need to use -fdump-rtl-combine-stats to get the stats in the combine dump unlike before where the stats was dumped directly into the file. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: * combine.cc (dump_combine_stats): Remove. (dump_combine_total_stats): Remove. (total_attempts, total_merges, total_extras, total_successes): Remove. (combine_instructions): Don't increment total stats instead use statistics_counter_event. * dumpfile.cc (print_combine_total_stats): Remove. * dumpfile.h (print_combine_total_stats): Remove. (dump_combine_total_stats): Remove. * passes.cc (finish_optimization_passes): Don't call print_combine_total_stats. * rtl.h (dump_combine_total_stats): Remove. (dump_combine_stats): Remove. --- gcc/combine.cc | 30 ++++-------------------------- gcc/dumpfile.cc | 9 --------- gcc/dumpfile.h | 3 --- gcc/passes.cc | 7 ------- gcc/rtl.h | 2 -- 5 files changed, 4 insertions(+), 47 deletions(-) (limited to 'gcc') diff --git a/gcc/combine.cc b/gcc/combine.cc index d9161b2..4bf867d 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -108,10 +108,6 @@ static int combine_extras; static int combine_successes; -/* Totals over entire compilation. */ - -static int total_attempts, total_merges, total_extras, total_successes; - /* combine_instructions may try to replace the right hand side of the second instruction with the value of an associated REG_EQUAL note before throwing it at try_combine. That is problematic when there @@ -1456,10 +1452,10 @@ retry: undobuf.frees = 0; } - total_attempts += combine_attempts; - total_merges += combine_merges; - total_extras += combine_extras; - total_successes += combine_successes; + statistics_counter_event (cfun, "attempts", combine_attempts); + statistics_counter_event (cfun, "merges", combine_merges); + statistics_counter_event (cfun, "extras", combine_extras); + statistics_counter_event (cfun, "successes", combine_successes); nonzero_sign_valid = 0; rtl_hooks = general_rtl_hooks; @@ -14936,24 +14932,6 @@ unmentioned_reg_p (rtx equiv, rtx expr) return false; } -DEBUG_FUNCTION void -dump_combine_stats (FILE *file) -{ - fprintf - (file, - ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n", - combine_attempts, combine_merges, combine_extras, combine_successes); -} - -void -dump_combine_total_stats (FILE *file) -{ - fprintf - (file, - "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n", - total_attempts, total_merges, total_extras, total_successes); -} - /* Make pseudo-to-pseudo copies after every hard-reg-to-pseudo-copy, because the reg-to-reg copy can usefully combine with later instructions, but we do not want to combine the hard reg into later instructions, for that diff --git a/gcc/dumpfile.cc b/gcc/dumpfile.cc index 51f68c8..a2050d1 100644 --- a/gcc/dumpfile.cc +++ b/gcc/dumpfile.cc @@ -2074,15 +2074,6 @@ dump_function (int phase, tree fn) } } -/* Print information from the combine pass on dump_file. */ - -void -print_combine_total_stats (void) -{ - if (dump_file) - dump_combine_total_stats (dump_file); -} - /* Enable RTL dump for all the RTL passes. */ bool diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h index 7d5eca8..c419406 100644 --- a/gcc/dumpfile.h +++ b/gcc/dumpfile.h @@ -647,14 +647,11 @@ class auto_dump_scope auto_dump_scope scope (NAME, USER_LOC) extern void dump_function (int phase, tree fn); -extern void print_combine_total_stats (void); extern bool enable_rtl_dump_file (void); /* In tree-dump.cc */ extern void dump_node (const_tree, dump_flags_t, FILE *); -/* In combine.cc */ -extern void dump_combine_total_stats (FILE *); /* In cfghooks.cc */ extern void dump_bb (FILE *, basic_block, int, dump_flags_t); diff --git a/gcc/passes.cc b/gcc/passes.cc index d7b0ad2..6f894a4 100644 --- a/gcc/passes.cc +++ b/gcc/passes.cc @@ -359,13 +359,6 @@ finish_optimization_passes (void) dumps->dump_finish (pass_profile_1->static_pass_number); } - if (optimize > 0) - { - dumps->dump_start (pass_combine_1->static_pass_number, NULL); - print_combine_total_stats (); - dumps->dump_finish (pass_combine_1->static_pass_number); - } - /* Do whatever is necessary to finish printing the graphs. */ for (i = TDI_end; (dfi = dumps->get_dump_file_info (i)) != NULL; ++i) if (dfi->graph_dump_initialized) diff --git a/gcc/rtl.h b/gcc/rtl.h index 098dc4c..03b7d05 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -4216,8 +4216,6 @@ extern bool validate_subreg (machine_mode, machine_mode, /* In combine.cc */ extern unsigned int extended_count (const_rtx, machine_mode, int); extern rtx remove_death (unsigned int, rtx_insn *); -extern void dump_combine_stats (FILE *); -extern void dump_combine_total_stats (FILE *); extern rtx make_compound_operation (rtx, enum rtx_code); /* In sched-rgn.cc. */ -- cgit v1.1 From bdda084bc4604467587447fbc4be1c8da0a12665 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Mon, 10 Jul 2023 16:21:58 -0400 Subject: testsuite: fix allocator-opt1.C FAIL with old ABI Running $ make check-g++ RUNTESTFLAGS='--target_board=unix\{-D_GLIBCXX_USE_CXX11_ABI=0,\} dg.exp=allocator-opt1.C' yields: FAIL: g++.dg/tree-ssa/allocator-opt1.C -std=c++98 scan-tree-dump-times gimple "struct allocator D" 1 FAIL: g++.dg/tree-ssa/allocator-opt1.C -std=c++14 scan-tree-dump-times gimple "struct allocator D" 1 FAIL: g++.dg/tree-ssa/allocator-opt1.C -std=c++17 scan-tree-dump-times gimple "struct allocator D" 1 FAIL: g++.dg/tree-ssa/allocator-opt1.C -std=c++20 scan-tree-dump-times gimple "struct allocator D" 1 === g++ Summary for unix/-D_GLIBCXX_USE_CXX11_ABI=0 === === g++ Summary for unix === because in the old ABI we get two "struct allocator D". This patch follows r14-658 although I'm not quite sure I follow the logic there. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/allocator-opt1.C: Force _GLIBCXX_USE_CXX11_ABI to 1. --- gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C b/gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C index e8394c7..51c470d 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C +++ b/gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C @@ -5,8 +5,20 @@ // Currently the dump doesn't print the allocator template arg in this context. // { dg-final { scan-tree-dump-times "struct allocator D" 1 "gimple" } } +// In the pre-C++11 ABI we get two allocator variables. +#undef _GLIBCXX_USE_CXX11_ABI +#define _GLIBCXX_USE_CXX11_ABI 1 + #include + +// When the library is not dual-ABI and defaults to old just compile +// an empty TU. NB: We test _GLIBCXX_USE_CXX11_ABI again because the +// #include above might have undef'd _GLIBCXX_USE_CXX11_ABI. +#if _GLIBCXX_USE_CXX11_ABI + void f (const char *p) { std::string lst[] = { p, p, p, p }; } + +#endif -- cgit v1.1 From 4b8878fbf7b74ea5c3405c9f558df0517036f131 Mon Sep 17 00:00:00 2001 From: "Vladimir N. Makarov" Date: Thu, 20 Jul 2023 14:34:26 -0400 Subject: [LRA]: Exclude reloading of frame pointer in subreg for some cases LRA for avr port reloads frame pointer in subreg although we can just simplify the subreg. It results in generation of bad performance code. The following patch fixes this. gcc/ChangeLog: * lra-constraints.cc (simplify_operand_subreg): Check frame pointer simplification. --- gcc/lra-constraints.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'gcc') diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 76a155e..f3784cf 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -1797,6 +1797,16 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) alter_subreg (curr_id->operand_loc[nop], false); return true; } + auto fp_subreg_can_be_simplified_after_reload_p = [] (machine_mode innermode, + poly_uint64 offset, + machine_mode mode) { + reload_completed = 1; + bool res = simplify_subreg_regno (FRAME_POINTER_REGNUM, + innermode, + offset, mode) >= 0; + reload_completed = 0; + return res; + }; /* Force a reload of the SUBREG_REG if this is a constant or PLUS or if there may be a problem accessing OPERAND in the outer mode. */ @@ -1809,6 +1819,12 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) >= hard_regno_nregs (hard_regno, mode)) && simplify_subreg_regno (hard_regno, innermode, SUBREG_BYTE (operand), mode) < 0 + /* Exclude reloading of frame pointer in subreg if frame pointer can not + be simplified here only because the reload is not finished yet. */ + && (hard_regno != FRAME_POINTER_REGNUM + || !fp_subreg_can_be_simplified_after_reload_p (innermode, + SUBREG_BYTE (operand), + mode)) /* Don't reload subreg for matching reload. It is actually valid subreg in LRA. */ && ! LRA_SUBREG_P (operand)) -- cgit v1.1 From b50a851eef4b70aabf28fa875d9b2a302d17b66a Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 20 Jul 2023 20:54:51 +0200 Subject: i386: Double-word sign-extension missed-optimization [PR110717] When sign-extending the value in a double-word register pair using shift and ashiftrt sequence with the same count immediate value less than word width, there is no need to shift the lower word of the value. The sign-extension could be limited to the upper word, but we uselessly shift the lower word with it as well: movq %rdi, %rax movq %rsi, %rdx shldq $59, %rdi, %rdx salq $59, %rax shrdq $59, %rdx, %rax sarq $59, %rdx ret for -m64 and movl 4(%esp), %eax movl 8(%esp), %edx shldl $27, %eax, %edx sall $27, %eax shrdl $27, %edx, %eax sarl $27, %edx ret for -m32. The patch introduces a new post-reload splitter to provide the combined ASHIFTRT/SHIFT instruction pattern. The instruction is split to a sequence of SAL and SAR insns with the same count immediate operand: movq %rsi, %rdx movq %rdi, %rax salq $59, %rdx sarq $59, %rdx ret Some complication is required to properly handle STV transform, where we emit a sequence with DImode PSLLQ and PSRAQ insns for 32-bit AVX512VL targets when profitable. The patch also fixes a small oversight and enables STV transform of SImode ASHIFTRT to PSRAD also for SSE2 targets. PR target/110717 gcc/ChangeLog: * config/i386/i386-features.cc (general_scalar_chain::compute_convert_gain): Calculate gain for extend higpart case. (general_scalar_chain::convert_op): Handle ASHIFTRT/ASHIFT combined RTX. (general_scalar_to_vector_candidate_p): Enable ASHIFTRT for SImode for SSE2 targets. Handle ASHIFTRT/ASHIFT combined RTX. * config/i386/i386.md (*extend2_doubleword_highpart): New define_insn_and_split pattern. (*extendv2di2_highpart_stv): Ditto. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110717.c: New test. --- gcc/config/i386/i386-features.cc | 16 +++++++++++++-- gcc/config/i386/i386.md | 35 ++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr110717.c | 21 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr110717.c (limited to 'gcc') diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index 4d69251..f801a8f 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -572,6 +572,9 @@ general_scalar_chain::compute_convert_gain () { if (INTVAL (XEXP (src, 1)) >= 32) igain += ix86_cost->add; + /* Gain for extend highpart case. */ + else if (GET_CODE (XEXP (src, 0)) == ASHIFT) + igain += ix86_cost->shift_const - ix86_cost->sse_op; else igain += ix86_cost->shift_const; } @@ -951,7 +954,8 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) { *op = copy_rtx_if_shared (*op); - if (GET_CODE (*op) == NOT) + if (GET_CODE (*op) == NOT + || GET_CODE (*op) == ASHIFT) { convert_op (&XEXP (*op, 0), insn); PUT_MODE (*op, vmode); @@ -2120,7 +2124,7 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode) switch (GET_CODE (src)) { case ASHIFTRT: - if (!TARGET_AVX512VL) + if (mode == DImode && !TARGET_AVX512VL) return false; /* FALLTHRU */ @@ -2131,6 +2135,14 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode) if (!CONST_INT_P (XEXP (src, 1)) || !IN_RANGE (INTVAL (XEXP (src, 1)), 0, GET_MODE_BITSIZE (mode)-1)) return false; + + /* Check for extend highpart case. */ + if (mode != DImode + || GET_CODE (src) != ASHIFTRT + || GET_CODE (XEXP (src, 0)) != ASHIFT) + break; + + src = XEXP (src, 0); break; case SMAX: diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 8c54aa5..4db210c 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -15292,6 +15292,41 @@ (const_string "0") (const_string "*"))) (set_attr "mode" "QI")]) + +(define_insn_and_split "*extend2_doubleword_highpart" + [(set (match_operand: 0 "register_operand" "=r") + (ashiftrt: + (ashift: (match_operand: 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "const_int_operand")) + (match_operand:QI 3 "const_int_operand"))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[2]) == INTVAL (operands[3]) + && UINTVAL (operands[2]) < * BITS_PER_UNIT" + "#" + "&& reload_completed" + [(parallel [(set (match_dup 4) + (ashift:DWIH (match_dup 4) (match_dup 2))) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 4) + (ashiftrt:DWIH (match_dup 4) (match_dup 2))) + (clobber (reg:CC FLAGS_REG))])] + "split_double_mode (mode, &operands[0], 1, &operands[0], &operands[4]);") + +(define_insn_and_split "*extendv2di2_highpart_stv" + [(set (match_operand:V2DI 0 "register_operand" "=v") + (ashiftrt:V2DI + (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm") + (match_operand:QI 2 "const_int_operand")) + (match_operand:QI 3 "const_int_operand")))] + "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL + && INTVAL (operands[2]) == INTVAL (operands[3]) + && UINTVAL (operands[2]) < 32" + "#" + "&& reload_completed" + [(set (match_dup 0) + (ashift:V2DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (ashiftrt:V2DI (match_dup 0) (match_dup 2)))]) ;; Rotate instructions diff --git a/gcc/testsuite/gcc.target/i386/pr110717.c b/gcc/testsuite/gcc.target/i386/pr110717.c new file mode 100644 index 0000000..233f0ea --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110717.c @@ -0,0 +1,21 @@ +/* PR target/110717 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#ifdef __SIZEOF_INT128__ +unsigned __int128 +foo (unsigned __int128 x) +{ + x <<= 59; + return ((__int128) x) >> 59; +} +#else +unsigned long long +foo (unsigned long long x) +{ + x <<= 27; + return ((long long) x) >> 27; +} +#endif + +/* { dg-final { scan-assembler-not "sh\[lr\]d" } } */ -- cgit v1.1 From 4e9ed68ee7ef2c80dcfd038c54e937646cc0ece2 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 20 Jul 2023 11:21:13 -0700 Subject: cmd/go: don't collect package CGOLDFLAGS when using gccgo They are already collected via cmd/cgo. The gccgo_link_c test is tweaked to do real linking as with this change the cgo ldflags are not fully reflected in go build -n output, since they now only come from the built archive. This is a backport of https://go.dev/cl/497117 from the main repo. For golang/go#60287 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/511675 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index c44cdc2..83ab3e2 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -92152c88ea8e2dd9e8c67e91bf4ae5e3edf1b506 +d04b024021bb7dbaa434a6d902bd12beb08e315f The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 083e7857a9ebf187b9116c74f6acf161f593bad9 Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Thu, 20 Jul 2023 22:32:22 +0100 Subject: [modula2] Implement limited VAR parameter static analysis This patch implements limited VAR parameter static analysis for pointer parameters. gcc/m2/ChangeLog: * gm2-compiler/M2SymInit.mod (IsExempt): Remove parameter exemption. (CheckIndrX): Call SetupLAlias between lhs and content. (trashParam): Re-write. (SetVarLRInitialized): Indicate shadow and heap are initialized. Call SetupIndr between shadow and heap. * gm2-compiler/P2SymBuild.mod: Import PutProcedureParameterHeapVars. (EndBuildProcedure): Call PutProcedureParameterHeapVars. * gm2-compiler/SymbolTable.def (GetParameterHeapVar): New procedure function. (PutProcedureParameterHeapVars): New procedure function. * gm2-compiler/SymbolTable.mod (MakeParameterHeapVar): New procedure function. (GetParameterHeapVar): New procedure function. (PuttParameterHeapVar): New procedure function. (PutProcedureParameterHeapVars): New procedure. (VarParam): HeapVar new record field. (PutVarParam): HeapVar assigned to NulSym. gcc/testsuite/ChangeLog: * gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod: New test. * gm2/switches/uninit-variable-checking/procedures/fail/testdispose4.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testdispose3.mod: New test. * gm2/switches/uninit-variable-checking/procedures/pass/testdispose4.mod: New test. Signed-off-by: Gaius Mulley --- gcc/m2/gm2-compiler/M2SymInit.mod | 94 ++++++++++++++-------- gcc/m2/gm2-compiler/P2SymBuild.mod | 2 + gcc/m2/gm2-compiler/SymbolTable.def | 18 ++++- gcc/m2/gm2-compiler/SymbolTable.mod | 85 ++++++++++++++++++- .../procedures/fail/testdispose3.mod | 24 ++++++ .../procedures/fail/testdispose4.mod | 22 +++++ .../procedures/pass/testdispose3.mod | 23 ++++++ .../procedures/pass/testdispose4.mod | 22 +++++ 8 files changed, 252 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose4.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose3.mod create mode 100644 gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose4.mod (limited to 'gcc') diff --git a/gcc/m2/gm2-compiler/M2SymInit.mod b/gcc/m2/gm2-compiler/M2SymInit.mod index 81d1e6b..b629ed8 100644 --- a/gcc/m2/gm2-compiler/M2SymInit.mod +++ b/gcc/m2/gm2-compiler/M2SymInit.mod @@ -60,7 +60,8 @@ FROM SymbolTable IMPORT NulSym, ModeOfAddr, IsVar, IsRecord, GetSType, IsVarient, IsFieldVarient, GetVarient, IsVarArrayRef, GetSymName, IsType, IsPointer, - GetParameterShadowVar, IsParameter, GetLType ; + GetParameterShadowVar, IsParameter, GetLType, + GetParameterHeapVar ; FROM M2Quads IMPORT QuadOperator, GetQuadOtok, GetQuad, GetNextQuad, IsNewLocalVar, IsReturn, IsKillLocalVar, IsConditional, @@ -1052,7 +1053,7 @@ PROCEDURE IsExempt (sym: CARDINAL) : BOOLEAN ; BEGIN RETURN (sym # NulSym) AND IsVar (sym) AND (IsGlobalVar (sym) OR - (IsVarAParam (sym) AND (GetMode (sym) = LeftValue)) OR + (* (IsVarAParam (sym) AND (GetMode (sym) = LeftValue)) OR *) ContainsVariant (sym) OR IsArray (GetSType (sym)) OR IsSet (GetSType (sym)) OR IsUnbounded (GetSType (sym)) OR IsVarArrayRef (sym) OR @@ -1098,23 +1099,27 @@ PROCEDURE CheckXIndr (procSym, lhstok, lhs, type, rhstok, rhs: CARDINAL; warning: BOOLEAN; bblst: List; i: CARDINAL) ; VAR - lst : List ; - vsym: CARDINAL ; + lst : List ; + content: CARDINAL ; BEGIN CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, bblst, i) ; CheckDeferredRecordAccess (procSym, lhstok, lhs, FALSE, warning, bblst, i) ; (* Now see if we know what lhs is pointing to and set fields if necessary. *) - vsym := getContent (getLAlias (lhs), lhs, lhstok) ; - IF (vsym # NulSym) AND (vsym # lhs) AND (GetSType (vsym) = type) + content := getContent (getLAlias (lhs), lhs, lhstok) ; + IF (content # NulSym) AND (content # lhs) AND (GetSType (content) = type) THEN + IF IsReallyPointer (rhs) + THEN + SetupLAlias (content, rhs) + END ; IF IsRecord (type) THEN - (* Set all fields of vsym as initialized. *) - SetVarInitialized (vsym, FALSE, lhstok) + (* Set all fields of content as initialized. *) + SetVarInitialized (content, FALSE, lhstok) ELSE (* Set only the field assigned in vsym as initialized. *) lst := ComponentCreateFieldList (rhs) ; - IF PutVarFieldInitialized (vsym, RightValue, lst) + IF PutVarFieldInitialized (content, RightValue, lst) THEN END ; KillList (lst) @@ -1140,9 +1145,11 @@ BEGIN IncludeItemIntoList (ignoreList, lhs) ELSE CheckDeferredRecordAccess (procSym, rhstok, content, TRUE, warning, lst, i) ; - (* SetVarInitialized (lhs, IsVarAParam (rhs)) -- was -- *) - (* SetVarInitialized (lhs, FALSE) -- was -- *) - SetVarInitialized (lhs, VarCheckReadInit (content, RightValue), lhstok) + SetVarInitialized (lhs, VarCheckReadInit (content, RightValue), lhstok) ; + IF IsReallyPointer (content) + THEN + SetupLAlias (lhs, content) + END END END CheckIndrX ; @@ -1527,34 +1534,36 @@ END DumpBBSequence ; PROCEDURE trashParam (trashQuad: CARDINAL) ; VAR - op : QuadOperator ; - op1, op2, op3 : CARDINAL ; - op1tok, op2tok, op3tok, qtok: CARDINAL ; - overflowChecking : BOOLEAN ; - heapSym, ptr : CARDINAL ; + op : QuadOperator ; + op1, proc, param, paramValue : CARDINAL ; + op1tok, op2tok, paramtok, qtok: CARDINAL ; + overflowChecking : BOOLEAN ; + heapValue, ptrToHeap : CARDINAL ; BEGIN IF trashQuad # 0 THEN - GetQuadOtok (trashQuad, qtok, op, op1, op2, op3, overflowChecking, - op1tok, op2tok, op3tok) ; - heapSym := GetQuadTrash (trashQuad) ; + GetQuadOtok (trashQuad, qtok, op, op1, proc, param, overflowChecking, + op1tok, op2tok, paramtok) ; + heapValue := GetQuadTrash (trashQuad) ; IF Debugging THEN - printf1 ("heapSym = %d\n", heapSym) + printf1 ("heapValue = %d\n", heapValue) END ; - IF heapSym # NulSym + IF heapValue # NulSym THEN - SetVarInitialized (op3, FALSE, op3tok) ; - ptr := getContent (getLAlias (op3), op3, op3tok) ; - IF ptr # NulSym + SetVarInitialized (param, FALSE, paramtok) ; + paramValue := getLAlias (param) ; + ptrToHeap := getContent (paramValue, param, paramtok) ; + IF ptrToHeap # NulSym THEN - IF IsDeallocate (op2) + IF IsDeallocate (proc) THEN - SetupLAlias (ptr, Nil) + SetupLAlias (ptrToHeap, Nil) ; + SetVarInitialized (ptrToHeap, FALSE, paramtok) ELSE - SetupIndr (ptr, heapSym) - END ; - SetVarInitialized (ptr, FALSE, op3tok) + SetupIndr (ptrToHeap, heapValue) ; + SetVarInitialized (ptrToHeap, TRUE, paramtok) + END END END END ; @@ -1563,18 +1572,33 @@ END trashParam ; (* - SetVarLRInitialized - + SetVarLRInitialized - this sets up an alias between the parameter + value and the pointer for the case: + + procedure foo (var shadow: PtrToType) ; + + which allows shadow to be statically analyzed + once it is re-assigned. *) PROCEDURE SetVarLRInitialized (param: CARDINAL) ; VAR - sym: CARDINAL ; + heap, + shadow: CARDINAL ; BEGIN Assert (IsParameter (param)) ; - sym := GetParameterShadowVar (param) ; - IF sym # NulSym + shadow := GetParameterShadowVar (param) ; + IF shadow # NulSym + THEN + IncludeItemIntoList (ignoreList, shadow) + END ; + heap := GetParameterHeapVar (param) ; + IF (shadow # NulSym) AND (heap # NulSym) THEN - IncludeItemIntoList (ignoreList, sym) + PutVarInitialized (shadow, GetMode (shadow)) ; + PutVarInitialized (heap, GetMode (heap)) ; + SetupIndr (shadow, heap) ; + IncludeItemIntoList (ignoreList, heap) END END SetVarLRInitialized ; diff --git a/gcc/m2/gm2-compiler/P2SymBuild.mod b/gcc/m2/gm2-compiler/P2SymBuild.mod index 98a51ea..71f6b1c 100644 --- a/gcc/m2/gm2-compiler/P2SymBuild.mod +++ b/gcc/m2/gm2-compiler/P2SymBuild.mod @@ -109,6 +109,7 @@ FROM SymbolTable IMPORT NulSym, ParametersDefinedInImplementation, ProcedureParametersDefined, PutProcedureNoReturn, + PutProcedureParameterHeapVars, CheckForUnImplementedExports, CheckForUndeclaredExports, IsHiddenTypeDeclared, @@ -1377,6 +1378,7 @@ BEGIN THEN WriteFormat2('end procedure name does not match beginning %a name %a', NameStart, NameEnd) END ; + PutProcedureParameterHeapVars (ProcSym) ; EndScope ; M2Error.LeaveErrorScope END EndBuildProcedure ; diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def index 2cfa0d4..9579a42 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.def +++ b/gcc/m2/gm2-compiler/SymbolTable.def @@ -362,7 +362,8 @@ EXPORT QUALIFIED NulSym, DebugLineNumbers, VarCheckReadInit, VarInitState, PutVarInitialized, PutVarFieldInitialized, GetVarFieldInitialized, - PrintInitialized ; + PrintInitialized, + GetParameterHeapVar, PutProcedureParameterHeapVars ; (* @@ -3648,4 +3649,19 @@ PROCEDURE GetVarFieldInitialized (sym: CARDINAL; mode: ModeOfAddr; PROCEDURE PrintInitialized (sym: CARDINAL) ; +(* + GetParameterHeapVar - return the heap variable associated with the + parameter or NulSym. +*) + +PROCEDURE GetParameterHeapVar (ParSym: CARDINAL) : CARDINAL ; + + +(* + PutProcedureParameterHeapVars - creates heap variables for parameter sym. +*) + +PROCEDURE PutProcedureParameterHeapVars (sym: CARDINAL) ; + + END SymbolTable. diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod index 1768966..aabaef4 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.mod +++ b/gcc/m2/gm2-compiler/SymbolTable.mod @@ -443,7 +443,7 @@ TYPE name : Name ; (* Index into name array, name *) (* of param. *) Type : CARDINAL ; (* Index to the type of param. *) - IsUnbounded : BOOLEAN ; (* ARRAY OF Type? *) + IsUnbounded : BOOLEAN ; (* Is it an ARRAY OF Type? *) ShadowVar : CARDINAL ; (* The local variable used to *) (* shadow this parameter. *) At : Where ; (* Where was sym declared/used *) @@ -453,7 +453,10 @@ TYPE name : Name ; (* Index into name array, name *) (* of param. *) Type : CARDINAL ;(* Index to the type of param. *) - IsUnbounded : BOOLEAN ; (* ARRAY OF Type? *) + IsUnbounded : BOOLEAN ; (* Is it an ARRAY OF Type? *) + HeapVar : CARDINAL ;(* The pointer value on heap. *) + (* Only used by static *) + (* analysis. *) ShadowVar : CARDINAL ;(* The local variable used to *) (* shadow this parameter. *) At : Where ; (* Where was sym declared/used *) @@ -10296,6 +10299,7 @@ BEGIN Type := ParamType ; IsUnbounded := isUnbounded ; ShadowVar := NulSym ; + HeapVar := NulSym ; (* Will contain a pointer value. *) InitWhereDeclaredTok(tok, At) END END ; @@ -10659,6 +10663,83 @@ END GetOptArgInit ; (* + MakeParameterHeapVar - create a heap variable if sym is a pointer. +*) + +PROCEDURE MakeParameterHeapVar (tok: CARDINAL; type: CARDINAL; mode: ModeOfAddr) : CARDINAL ; +VAR + heapvar: CARDINAL ; +BEGIN + heapvar := NulSym ; + type := SkipType (type) ; + IF IsPointer (type) + THEN + heapvar := MakeTemporary (tok, mode) ; + PutVar (heapvar, type) ; + PutVarHeap (heapvar, TRUE) + END ; + RETURN heapvar +END MakeParameterHeapVar ; + + +(* + GetParameterHeapVar - return the heap variable associated with the + parameter or NulSym. +*) + +PROCEDURE GetParameterHeapVar (ParSym: CARDINAL) : CARDINAL ; +VAR + pSym: PtrToSymbol ; +BEGIN + pSym := GetPsym (ParSym) ; + WITH pSym^ DO + CASE SymbolType OF + + ParamSym : RETURN NulSym | (* Only VarParam has the pointer. *) + VarParamSym: RETURN VarParam.HeapVar + + ELSE + InternalError ('expecting Param or VarParam symbol') + END + END +END GetParameterHeapVar ; + + +(* + PutParameterHeapVar - creates a heap variable associated with parameter sym. +*) + +PROCEDURE PutParameterHeapVar (sym: CARDINAL) ; +VAR + pSym : PtrToSymbol ; +BEGIN + pSym := GetPsym (sym) ; + WITH pSym^ DO + CASE SymbolType OF + + ParamSym : | (* Nothing to do for the non var parameter. *) + VarParamSym: VarParam.HeapVar := MakeParameterHeapVar (GetDeclaredMod (sym), + VarParam.Type, LeftValue) + + ELSE + InternalError ('Param or VarParam symbol expected') + END + END +END PutParameterHeapVar ; + + +(* + PutProcedureParameterHeapVars - creates heap variables for parameter sym. +*) + +PROCEDURE PutProcedureParameterHeapVars (sym: CARDINAL) ; +BEGIN + Assert (IsProcedure (sym)) ; + ForeachParamSymDo (sym, PutParameterHeapVar) +END PutProcedureParameterHeapVars ; + + +(* NoOfVariables - returns the number of variables in scope. The scope maybe a procedure, module or defimp scope. *) diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod new file mode 100644 index 0000000..5463344 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod @@ -0,0 +1,24 @@ +MODULE testdispose3 ; + +FROM Storage IMPORT DEALLOCATE ; + +TYPE + PtrToVec = POINTER TO RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test (VAR ptr: PtrToVec) ; +BEGIN + DISPOSE (ptr) ; + IF ptr^.x = 1 + THEN + END +END test ; + + +VAR + p: PtrToVec ; +BEGIN + test (p) +END testdispose3. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose4.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose4.mod new file mode 100644 index 0000000..c0b36d6 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose4.mod @@ -0,0 +1,22 @@ +MODULE testdispose4 ; + +FROM Storage IMPORT DEALLOCATE ; + +TYPE + PtrToCard = POINTER TO CARDINAL ; + + +PROCEDURE test (VAR ptr: PtrToCard) ; +BEGIN + DISPOSE (ptr) ; + IF ptr^ = 1 + THEN + END +END test ; + + +VAR + p: PtrToCard ; +BEGIN + test (p) +END testdispose4. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose3.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose3.mod new file mode 100644 index 0000000..f826457 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose3.mod @@ -0,0 +1,23 @@ +MODULE testdispose3 ; + +FROM Storage IMPORT DEALLOCATE ; + +TYPE + PtrToVec = POINTER TO RECORD + x, y: INTEGER ; + END ; + + +PROCEDURE test (VAR ptr: PtrToVec) ; +BEGIN + IF ptr^.x = 1 + THEN + END +END test ; + + +VAR + p: PtrToVec ; +BEGIN + test (p) +END testdispose3. diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose4.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose4.mod new file mode 100644 index 0000000..70bc3f5 --- /dev/null +++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/pass/testdispose4.mod @@ -0,0 +1,22 @@ +MODULE testdispose4 ; + +FROM Storage IMPORT ALLOCATE ; + +TYPE + PtrToCard = POINTER TO CARDINAL ; + + +PROCEDURE test (VAR ptr: PtrToCard) ; +BEGIN + IF ptr^ = 1 + THEN + END +END test ; + + +VAR + p: PtrToCard ; +BEGIN + NEW (p) ; + test (p) +END testdispose4. -- cgit v1.1 From e2bf82d510378a4cc195622f6bbf281a5d9a4124 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 21 Jul 2023 00:17:07 +0000 Subject: Daily bump. --- gcc/ChangeLog | 276 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/c-family/ChangeLog | 6 ++ gcc/cp/ChangeLog | 6 ++ gcc/fortran/ChangeLog | 12 +++ gcc/m2/ChangeLog | 21 ++++ gcc/testsuite/ChangeLog | 83 +++++++++++++++ 7 files changed, 405 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47b872b..4bbcc03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,279 @@ +2023-07-20 Uros Bizjak + + PR target/110717 + * config/i386/i386-features.cc + (general_scalar_chain::compute_convert_gain): Calculate gain + for extend higpart case. + (general_scalar_chain::convert_op): Handle + ASHIFTRT/ASHIFT combined RTX. + (general_scalar_to_vector_candidate_p): Enable ASHIFTRT for + SImode for SSE2 targets. Handle ASHIFTRT/ASHIFT combined RTX. + * config/i386/i386.md (*extend2_doubleword_highpart): + New define_insn_and_split pattern. + (*extendv2di2_highpart_stv): Ditto. + +2023-07-20 Vladimir N. Makarov + + * lra-constraints.cc (simplify_operand_subreg): Check frame pointer + simplification. + +2023-07-20 Andrew Pinski + + * combine.cc (dump_combine_stats): Remove. + (dump_combine_total_stats): Remove. + (total_attempts, total_merges, total_extras, + total_successes): Remove. + (combine_instructions): Don't increment total stats + instead use statistics_counter_event. + * dumpfile.cc (print_combine_total_stats): Remove. + * dumpfile.h (print_combine_total_stats): Remove. + (dump_combine_total_stats): Remove. + * passes.cc (finish_optimization_passes): + Don't call print_combine_total_stats. + * rtl.h (dump_combine_total_stats): Remove. + (dump_combine_stats): Remove. + +2023-07-20 Jan Hubicka + + * tree-ssa-loop-ch.cc (should_duplicate_loop_header_p): Use BIT instead of TRUTH + logical ops. + +2023-07-20 Martin Jambor + + * doc/invoke.texi (analyzer-text-art-string-ellipsis-threshold): New. + (analyzer-text-art-ideal-canvas-width): Likewise. + (analyzer-text-art-string-ellipsis-head-len): Likewise. + (analyzer-text-art-string-ellipsis-tail-len): Likewise. + +2023-07-20 Ju-Zhe Zhong + + * tree-vect-stmts.cc (check_load_store_for_partial_vectors): + Refine code structure. + +2023-07-20 Jan Hubicka + + * tree-ssa-loop-ch.cc (edge_range_query): Rename to ... + (get_range_query): ... this one; do + (static_loop_exit): Add query parametr, turn ranger to reference. + (loop_static_stmt_p): New function. + (loop_static_op_p): New function. + (loop_iv_derived_p): Remove. + (loop_combined_static_and_iv_p): New function. + (should_duplicate_loop_header_p): Discover combined onditionals; + do not track iv derived; improve dumps. + (pass_ch::execute): Fix whitespace. + +2023-07-20 Richard Biener + + PR tree-optimization/110204 + * tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_avail): + Look through copies generated by PRE. + +2023-07-20 Matthew Malcomson + + * tree-vect-stmts.cc (get_group_load_store_type): Account for + `gap` when checking if need to peel twice. + +2023-07-20 Francois-Xavier Coudert + + PR middle-end/77928 + * doc/extend.texi: Document iseqsig builtin. + * builtins.cc (fold_builtin_iseqsig): New function. + (fold_builtin_2): Handle BUILT_IN_ISEQSIG. + (is_inexpensive_builtin): Handle BUILT_IN_ISEQSIG. + * builtins.def (BUILT_IN_ISEQSIG): New built-in. + +2023-07-20 Pan Li + + * config/riscv/vector.md: Fix incorrect match_operand. + +2023-07-20 Roger Sayle + + * config/i386/i386-expand.cc (ix86_expand_move): Don't call + force_reg, to use SUBREG rather than create a new pseudo when + inserting DFmode fields into TImode with insvti_{high,low}part. + * config/i386/i386.md (*concat3_3): Split into two + define_insn_and_split... + (*concatditi3_3): 64-bit implementation. Provide alternative + that allows register allocation to use SSE registers that is + split into vec_concatv2di after reload. + (*concatsidi3_3): 32-bit implementation. + +2023-07-20 Richard Biener + + PR middle-end/61747 + * internal-fn.cc (expand_vec_cond_optab_fn): When the + value operands are equal to the original comparison operands + preserve that equality by re-using the comparison expansion. + * optabs.cc (emit_conditional_move): When the value operands + are equal to the comparison operands and would be forced to + a register by prepare_cmp_insn do so earlier, preserving the + equality. + +2023-07-20 Pan Li + + * config/riscv/vector.md: Align pattern format. + +2023-07-20 Haochen Jiang + + * doc/invoke.texi: Remove AVX512VP2INTERSECT in + Granite Rapids{, D} from documentation. + +2023-07-20 Juzhe-Zhong + + * config/riscv/autovec.md + (len_mask_gather_load): + Refactor RVV machine modes. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + * config/riscv/riscv-modes.def (VECTOR_BOOL_MODE): Ditto. + (ADJUST_NUNITS): Ditto. + (ADJUST_ALIGNMENT): Ditto. + (ADJUST_BYTESIZE): Ditto. + (ADJUST_PRECISION): Ditto. + (RVV_MODES): Ditto. + (RVV_WHOLE_MODES): Ditto. + (RVV_FRACT_MODE): Ditto. + (RVV_NF8_MODES): Ditto. + (RVV_NF4_MODES): Ditto. + (VECTOR_MODES_WITH_PREFIX): Ditto. + (VECTOR_MODE_WITH_PREFIX): Ditto. + (RVV_TUPLE_MODES): Ditto. + (RVV_NF2_MODES): Ditto. + (RVV_TUPLE_PARTIAL_MODES): Ditto. + * config/riscv/riscv-v.cc (struct mode_vtype_group): Ditto. + (ENTRY): Ditto. + (TUPLE_ENTRY): Ditto. + (get_vlmul): Ditto. + (get_nf): Ditto. + (get_ratio): Ditto. + (preferred_simd_mode): Ditto. + (autovectorize_vector_modes): Ditto. + * config/riscv/riscv-vector-builtins.cc (DEF_RVV_TYPE): Ditto. + * config/riscv/riscv-vector-builtins.def (DEF_RVV_TYPE): Ditto. + (vbool64_t): Ditto. + (vbool32_t): Ditto. + (vbool16_t): Ditto. + (vbool8_t): Ditto. + (vbool4_t): Ditto. + (vbool2_t): Ditto. + (vbool1_t): Ditto. + (vint8mf8_t): Ditto. + (vuint8mf8_t): Ditto. + (vint8mf4_t): Ditto. + (vuint8mf4_t): Ditto. + (vint8mf2_t): Ditto. + (vuint8mf2_t): Ditto. + (vint8m1_t): Ditto. + (vuint8m1_t): Ditto. + (vint8m2_t): Ditto. + (vuint8m2_t): Ditto. + (vint8m4_t): Ditto. + (vuint8m4_t): Ditto. + (vint8m8_t): Ditto. + (vuint8m8_t): Ditto. + (vint16mf4_t): Ditto. + (vuint16mf4_t): Ditto. + (vint16mf2_t): Ditto. + (vuint16mf2_t): Ditto. + (vint16m1_t): Ditto. + (vuint16m1_t): Ditto. + (vint16m2_t): Ditto. + (vuint16m2_t): Ditto. + (vint16m4_t): Ditto. + (vuint16m4_t): Ditto. + (vint16m8_t): Ditto. + (vuint16m8_t): Ditto. + (vint32mf2_t): Ditto. + (vuint32mf2_t): Ditto. + (vint32m1_t): Ditto. + (vuint32m1_t): Ditto. + (vint32m2_t): Ditto. + (vuint32m2_t): Ditto. + (vint32m4_t): Ditto. + (vuint32m4_t): Ditto. + (vint32m8_t): Ditto. + (vuint32m8_t): Ditto. + (vint64m1_t): Ditto. + (vuint64m1_t): Ditto. + (vint64m2_t): Ditto. + (vuint64m2_t): Ditto. + (vint64m4_t): Ditto. + (vuint64m4_t): Ditto. + (vint64m8_t): Ditto. + (vuint64m8_t): Ditto. + (vfloat16mf4_t): Ditto. + (vfloat16mf2_t): Ditto. + (vfloat16m1_t): Ditto. + (vfloat16m2_t): Ditto. + (vfloat16m4_t): Ditto. + (vfloat16m8_t): Ditto. + (vfloat32mf2_t): Ditto. + (vfloat32m1_t): Ditto. + (vfloat32m2_t): Ditto. + (vfloat32m4_t): Ditto. + (vfloat32m8_t): Ditto. + (vfloat64m1_t): Ditto. + (vfloat64m2_t): Ditto. + (vfloat64m4_t): Ditto. + (vfloat64m8_t): Ditto. + * config/riscv/riscv-vector-switch.def (ENTRY): Ditto. + (TUPLE_ENTRY): Ditto. + * config/riscv/riscv-vsetvl.cc (change_insn): Ditto. + * config/riscv/riscv.cc (riscv_valid_lo_sum_p): Ditto. + (riscv_v_adjust_nunits): Ditto. + (riscv_v_adjust_bytesize): Ditto. + (riscv_v_adjust_precision): Ditto. + (riscv_convert_vector_bits): Ditto. + * config/riscv/riscv.h (riscv_v_adjust_nunits): Ditto. + * config/riscv/riscv.md: Ditto. + * config/riscv/vector-iterators.md: Ditto. + * config/riscv/vector.md + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_load): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + (@pred_indexed_store): Ditto. + 2023-07-19 Vladimir N. Makarov * lra-int.h (lra_update_fp2sp_elimination): New prototype. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4b8414a..0e7d73c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230720 +20230721 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2533274..119adee 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2023-07-20 Francois-Xavier Coudert + + PR middle-end/77928 + * c-common.cc (check_builtin_function_arguments): + Handle BUILT_IN_ISEQSIG. + 2023-07-05 Robin Dapp Juzhe-Zhong diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 59491e5..db9ce60 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2023-07-20 Marek Polacek + + PR c++/110114 + * call.cc (implicit_conversion_1): Return early if the type isn't + complete. + 2023-07-19 Marek Polacek PR c++/110745 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 3663a74b..fba7799 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2023-07-20 Francois-Xavier Coudert + + * trans-intrinsic.cc (conv_intrinsic_ieee_comparison): Only + define it once. + +2023-07-20 Francois-Xavier Coudert + + * f95-lang.cc (gfc_init_builtin_functions): Add __builtin_iseqsig. + * trans-intrinsic.cc (conv_intrinsic_ieee_comparison): New + function. + (gfc_conv_ieee_arithmetic_function): Handle IEEE comparisons. + 2023-07-19 Tobias Burnus PR fortran/107424 diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 718c6f5..5197a00 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,24 @@ +2023-07-20 Gaius Mulley + + * gm2-compiler/M2SymInit.mod (IsExempt): Remove parameter exemption. + (CheckIndrX): Call SetupLAlias between lhs and content. + (trashParam): Re-write. + (SetVarLRInitialized): Indicate shadow and heap are initialized. + Call SetupIndr between shadow and heap. + * gm2-compiler/P2SymBuild.mod: Import + PutProcedureParameterHeapVars. + (EndBuildProcedure): Call PutProcedureParameterHeapVars. + * gm2-compiler/SymbolTable.def (GetParameterHeapVar): New + procedure function. + (PutProcedureParameterHeapVars): New procedure function. + * gm2-compiler/SymbolTable.mod (MakeParameterHeapVar): New + procedure function. + (GetParameterHeapVar): New procedure function. + (PuttParameterHeapVar): New procedure function. + (PutProcedureParameterHeapVars): New procedure. + (VarParam): HeapVar new record field. + (PutVarParam): HeapVar assigned to NulSym. + 2023-07-19 Gaius Mulley PR modula2/110284 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4345065..c52e8ae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,86 @@ +2023-07-20 Gaius Mulley + + * gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/fail/testdispose4.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testdispose3.mod: New test. + * gm2/switches/uninit-variable-checking/procedures/pass/testdispose4.mod: New test. + +2023-07-20 Uros Bizjak + + PR target/110717 + * gcc.target/i386/pr110717.c: New test. + +2023-07-20 Marek Polacek + + * g++.dg/tree-ssa/allocator-opt1.C: Force _GLIBCXX_USE_CXX11_ABI to 1. + +2023-07-20 Marek Polacek + + PR c++/110114 + * g++.dg/cpp0x/initlist100.C: Adjust expected diagnostic. + * g++.dg/cpp2a/desig28.C: New test. + * g++.dg/cpp2a/desig29.C: New test. + +2023-07-20 Jan Hubicka + + * g++.dg/uninit-pred-loop-1_c.C: Allow warning. + * gcc.dg/tree-ssa/copy-headers-7.c: Add tests so exit conditition is + static; update template. + * gcc.dg/tree-ssa/ivopt_mult_1.c: Add test so exit condition is static. + * gcc.dg/tree-ssa/ivopt_mult_2.c: Add test so exit condition is static. + * gcc.dg/tree-ssa/copy-headers-8.c: New test. + +2023-07-20 Matthew Malcomson + + * gcc.dg/vect/vect-multi-peel-gaps.c: New test. + +2023-07-20 Francois-Xavier Coudert + + * gfortran.dg/ieee/comparisons_1.f90: New test. + * gfortran.dg/ieee/comparisons_2.f90: New test. + * gfortran.dg/ieee/comparisons_3.F90: New test. + +2023-07-20 Francois-Xavier Coudert + + PR middle-end/77928 + * gcc.dg/torture/builtin-iseqsig-1.c: New test. + * gcc.dg/torture/builtin-iseqsig-2.c: New test. + * gcc.dg/torture/builtin-iseqsig-3.c: New test. + +2023-07-20 Pan Li + + * gcc.target/riscv/rvv/base/pr110299-1.c: Adjust tests. + * gcc.target/riscv/rvv/base/pr110299-2.c: Ditto. + +2023-07-20 Roger Sayle + + * gcc.target/i386/pr88873.c: New test case. + +2023-07-20 Richard Biener + + PR middle-end/61747 + * g++.target/i386/pr61747.C: New testcase. + +2023-07-20 Lewis Hyatt + + PR preprocessor/103902 + * g++.dg/cpp0x/udlit-extended-id-1.C: Change "unsigned long" to + "size_t" throughout. + * g++.dg/cpp0x/udlit-extended-id-3.C: Likewise. + +2023-07-20 Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-7.c: + Adapt test. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load_run-8.c: + Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c: + Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store_run-8.c + : Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store_run-8.c: + Ditto. + 2023-07-19 Marek Polacek PR c++/110745 -- cgit v1.1 From 5a0aff76a9980488a760ece72323e7ed1f2c0e5e Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 20 Jul 2023 20:24:01 -0400 Subject: analyzer: fix ICE on certain pointer subtractions [PR110387] gcc/analyzer/ChangeLog: PR analyzer/110387 * region.h (struct cast_region::key_t): Support "m_type" being null by using "m_original_region" for empty/deleted slots. gcc/testsuite/ChangeLog: PR analyzer/110387 * gcc.dg/analyzer/out-of-bounds-pr110387.c: New test. Signed-off-by: David Malcolm --- gcc/analyzer/region.h | 16 +++++++++++----- .../gcc.dg/analyzer/out-of-bounds-pr110387.c | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c (limited to 'gcc') diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h index 0c79490..2cbb923 100644 --- a/gcc/analyzer/region.h +++ b/gcc/analyzer/region.h @@ -1107,7 +1107,7 @@ public: key_t (const region *original_region, tree type) : m_original_region (original_region), m_type (type) { - gcc_assert (type); + gcc_assert (original_region); } hashval_t hash () const @@ -1124,10 +1124,16 @@ public: && m_type == other.m_type); } - void mark_deleted () { m_type = reinterpret_cast (1); } - void mark_empty () { m_type = NULL_TREE; } - bool is_deleted () const { return m_type == reinterpret_cast (1); } - bool is_empty () const { return m_type == NULL_TREE; } + void mark_deleted () + { + m_original_region = reinterpret_cast (1); + } + void mark_empty () { m_original_region = nullptr; } + bool is_deleted () const + { + return m_original_region == reinterpret_cast (1); + } + bool is_empty () const { return m_original_region == nullptr; } const region *m_original_region; tree m_type; diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c new file mode 100644 index 0000000..a046659 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c @@ -0,0 +1,19 @@ +char a, b, c, d; +long x; + +void +_S_copy (long __n) +{ + __builtin_memcpy (&a, &d, __n); /* { dg-prune-output "-Wanalyzer-out-of-bounds" } */ + /* This only warns on some targets; the purpose of the test is to verify that + we don't ICE. */ +} + +void +_M_construct () +{ + x = &c - &b; + unsigned long __dnew = x; + if (__dnew > 1) + _S_copy (&c - &b); +} -- cgit v1.1 From 7006f02bbc3f1d0b7ed7fe2122abc0896aa848d2 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 20 Jul 2023 20:24:06 -0400 Subject: analyzer/text-art: fix clang warnings [PR110433,PR110612] gcc/analyzer/ChangeLog: PR analyzer/110433 PR middle-end/110612 * access-diagram.cc (class spatial_item): Add virtual dtor. gcc/ChangeLog: PR middle-end/110612 * text-art/table.cc (table_geometry::table_geometry): Drop m_table field. (table_geometry::table_x_to_canvas_x): Add cast to comparison. (table_geometry::table_y_to_canvas_y): Likewise. * text-art/table.h (table_geometry::m_table): Drop unused field. * text-art/widget.h (wrapper_widget::update_child_alloc_rects): Add "override". Signed-off-by: David Malcolm --- gcc/analyzer/access-diagram.cc | 1 + gcc/text-art/table.cc | 7 +++---- gcc/text-art/table.h | 1 - gcc/text-art/widget.h | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc index 467c9bd..d7b669a 100644 --- a/gcc/analyzer/access-diagram.cc +++ b/gcc/analyzer/access-diagram.cc @@ -1125,6 +1125,7 @@ private: class spatial_item { public: + virtual ~spatial_item () {} virtual void add_boundaries (boundaries &out, logger *) const = 0; virtual table make_table (const bit_to_table_map &btm, diff --git a/gcc/text-art/table.cc b/gcc/text-art/table.cc index 71a1024..2f857a0 100644 --- a/gcc/text-art/table.cc +++ b/gcc/text-art/table.cc @@ -507,8 +507,7 @@ table_cell_sizes::get_canvas_size (const table::rect_t &rect) const /* class text_art::table_geometry. */ table_geometry::table_geometry (const table &table, table_cell_sizes &cell_sizes) -: m_table (table), - m_cell_sizes (cell_sizes), +: m_cell_sizes (cell_sizes), m_canvas_size (canvas::size_t (0, 0)), m_col_start_x (table.get_size ().w), m_row_start_y (table.get_size ().h) @@ -558,7 +557,7 @@ int table_geometry::table_x_to_canvas_x (int table_x) const { /* Allow one beyond the end, for the right-hand border of the table. */ - if (table_x == m_col_start_x.size ()) + if (table_x == (int)m_col_start_x.size ()) return m_canvas_size.w - 1; return m_col_start_x[table_x]; } @@ -570,7 +569,7 @@ int table_geometry::table_y_to_canvas_y (int table_y) const { /* Allow one beyond the end, for the right-hand border of the table. */ - if (table_y == m_row_start_y.size ()) + if (table_y == (int)m_row_start_y.size ()) return m_canvas_size.h - 1; return m_row_start_y[table_y]; } diff --git a/gcc/text-art/table.h b/gcc/text-art/table.h index 2dc5c3c..17eda91 100644 --- a/gcc/text-art/table.h +++ b/gcc/text-art/table.h @@ -232,7 +232,6 @@ class table_geometry } private: - const table &m_table; table_cell_sizes &m_cell_sizes; canvas::size_t m_canvas_size; diff --git a/gcc/text-art/widget.h b/gcc/text-art/widget.h index 8798e43..5156a7e 100644 --- a/gcc/text-art/widget.h +++ b/gcc/text-art/widget.h @@ -148,7 +148,7 @@ class wrapper_widget : public widget { return m_child->get_req_size (); } - void update_child_alloc_rects () + void update_child_alloc_rects () override { m_child->set_alloc_rect (get_alloc_rect ()); } -- cgit v1.1 From a4913a19d24a794c97f38d9c65c47c1fb9f2140c Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 20 Jul 2023 20:24:10 -0400 Subject: analyzer: avoid usage of TYPE_PRECISION on vector types [PR110455] gcc/analyzer/ChangeLog: PR analyzer/110455 * region-model.cc (region_model::get_gassign_result): Only check for bad shift counts when dealing with an integral type. gcc/testsuite/ChangeLog: PR analyzer/110455 * gcc.dg/analyzer/pr110455.c: New test. Signed-off-by: David Malcolm --- gcc/analyzer/region-model.cc | 3 ++- gcc/testsuite/gcc.dg/analyzer/pr110455.c | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr110455.c (limited to 'gcc') diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 187013a..e01b1c8 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -860,7 +860,8 @@ region_model::get_gassign_result (const gassign *assign, or by greater than or equal to the number of bits that exist in the operand." */ if (const tree rhs2_cst = rhs2_sval->maybe_get_constant ()) - if (TREE_CODE (rhs2_cst) == INTEGER_CST) + if (TREE_CODE (rhs2_cst) == INTEGER_CST + && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))) { if (tree_int_cst_sgn (rhs2_cst) < 0) ctxt->warn diff --git a/gcc/testsuite/gcc.dg/analyzer/pr110455.c b/gcc/testsuite/gcc.dg/analyzer/pr110455.c new file mode 100644 index 0000000..7f97943 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr110455.c @@ -0,0 +1,7 @@ +int __attribute__((__vector_size__ (4))) v; + +void +foo (void) +{ + v | v << 1; +} -- cgit v1.1 From 629ad1cfdaf542c454536d56ba9de19bd0a4b046 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Thu, 20 Jul 2023 12:44:03 +0800 Subject: Fix fp16 related testcase failure for i686. > I see some regressions most likely with this change on i686-linux, > in particular: > +FAIL: gcc.dg/pr107547.c (test for excess errors) > +FAIL: gcc.dg/torture/floatn-convert.c -O0 (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O0 compilation failed to produce executable > +FAIL: gcc.dg/torture/floatn-convert.c -O1 (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O1 compilation failed to produce executable > +FAIL: gcc.dg/torture/floatn-convert.c -O2 (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O2 compilation failed to produce executable > +FAIL: gcc.dg/torture/floatn-convert.c -O2 -flto (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O2 -flto compilation failed to produce executable > +FAIL: gcc.dg/torture/floatn-convert.c -O2 -flto -flto-partition=none (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O2 -flto -flto-partition=none compilation failed to produce executable > +FAIL: gcc.dg/torture/floatn-convert.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions compilation failed to produce executable > +FAIL: gcc.dg/torture/floatn-convert.c -O3 -g (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O3 -g compilation failed to produce executable > +FAIL: gcc.dg/torture/floatn-convert.c -Os (test for excess errors) > +UNRESOLVED: gcc.dg/torture/floatn-convert.c -Os compilation failed to produce executable > +FAIL: gcc.target/i386/float16-7.c (test for errors, line 7) > > Perhaps we need to tweak > gcc/testsuite/lib/target-supports.exp (add_options_for_float16) > so that it adds -msse2 for i?86-*-* x86_64-*-* (that would likely > fix up floatn-convert) and for the others perhaps > /* { dg-add-options float16 } */ > ? gcc/testsuite/ChangeLog: * gcc.dg/pr107547.c: Add { dg-add-options float16 }. * gcc.target/i386/float16-7.c: Add -msse2 to dg-options. * lib/target-supports.exp (add_options_for_float16): Add -msse2 for i?86-*-* || x86_64-*-*. --- gcc/testsuite/gcc.dg/pr107547.c | 1 + gcc/testsuite/gcc.target/i386/float16-7.c | 2 +- gcc/testsuite/lib/target-supports.exp | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/pr107547.c b/gcc/testsuite/gcc.dg/pr107547.c index c6992c8..7cd68af 100644 --- a/gcc/testsuite/gcc.dg/pr107547.c +++ b/gcc/testsuite/gcc.dg/pr107547.c @@ -1,6 +1,7 @@ /* PR tree-optimization/107547 */ /* { dg-do compile } */ /* { dg-options "-O2" } */ +/* { dg-add-options float16 } */ int x; diff --git a/gcc/testsuite/gcc.target/i386/float16-7.c b/gcc/testsuite/gcc.target/i386/float16-7.c index 86641af..660021b 100644 --- a/gcc/testsuite/gcc.target/i386/float16-7.c +++ b/gcc/testsuite/gcc.target/i386/float16-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=16" } */ +/* { dg-options "-O2 -msse2 -mfpmath=387 -fexcess-precision=16" } */ /* { dg-excess-errors "'-fexcess-precision=16' is not compatible with '-mfpmath=387'" } */ _Float16 foo (_Float16 a, _Float16 b) diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 8ea0d9f..4202447 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3487,6 +3487,9 @@ proc add_options_for_float16 { flags } { if { [istarget arm*-*-*] } { return "$flags -mfp16-format=ieee" } + if { [istarget i?86-*-*] || [istarget x86_64-*-*] } { + return "$flags -msse2" + } return "$flags" } -- cgit v1.1 From 1c6231c05bdccab3a21abcbb75e2094ea3e98782 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Fri, 12 May 2023 15:15:08 +0800 Subject: Provide -fcf-protection=branch,return. Use EnumSet instead of EnumBitSet since CF_FULL is not power of 2. It is a bit tricky for sets classification, cf_branch and cf_return should be in different sets, but they both "conflicts" cf_full, cf_none. And current EnumSet don't handle this well. So in the current implementation, only cf_full,cf_none are exclusive to each other, but they can be combined with any cf_branch, cf_return, cf_check. It's not perfect, but still an improvement than original one. gcc/ChangeLog: PR target/89701 * common.opt: (fcf-protection=): Add EnumSet attribute to support combination of params. gcc/testsuite/ChangeLog: * c-c++-common/fcf-protection-10.c: New test. * c-c++-common/fcf-protection-11.c: New test. * c-c++-common/fcf-protection-12.c: New test. * c-c++-common/fcf-protection-8.c: New test. * c-c++-common/fcf-protection-9.c: New test. * gcc.target/i386/pr89701-1.c: New test. * gcc.target/i386/pr89701-2.c: New test. * gcc.target/i386/pr89701-3.c: New test. --- gcc/common.opt | 12 ++++++------ gcc/testsuite/c-c++-common/fcf-protection-10.c | 2 ++ gcc/testsuite/c-c++-common/fcf-protection-11.c | 2 ++ gcc/testsuite/c-c++-common/fcf-protection-12.c | 2 ++ gcc/testsuite/c-c++-common/fcf-protection-8.c | 2 ++ gcc/testsuite/c-c++-common/fcf-protection-9.c | 2 ++ gcc/testsuite/gcc.target/i386/pr89701-1.c | 4 ++++ gcc/testsuite/gcc.target/i386/pr89701-2.c | 4 ++++ gcc/testsuite/gcc.target/i386/pr89701-3.c | 4 ++++ 9 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/fcf-protection-10.c create mode 100644 gcc/testsuite/c-c++-common/fcf-protection-11.c create mode 100644 gcc/testsuite/c-c++-common/fcf-protection-12.c create mode 100644 gcc/testsuite/c-c++-common/fcf-protection-8.c create mode 100644 gcc/testsuite/c-c++-common/fcf-protection-9.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89701-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89701-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89701-3.c (limited to 'gcc') diff --git a/gcc/common.opt b/gcc/common.opt index 25f650e..0888c15 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1908,7 +1908,7 @@ fcf-protection Common RejectNegative Alias(fcf-protection=,full) fcf-protection= -Common Joined RejectNegative Enum(cf_protection_level) Var(flag_cf_protection) Init(CF_NONE) +Common Joined RejectNegative Enum(cf_protection_level) EnumSet Var(flag_cf_protection) Init(CF_NONE) -fcf-protection=[full|branch|return|none|check] Instrument functions with checks to verify jump/call/return control-flow transfer instructions have valid targets. @@ -1916,19 +1916,19 @@ Enum Name(cf_protection_level) Type(enum cf_protection_level) UnknownError(unknown Control-Flow Protection Level %qs) EnumValue -Enum(cf_protection_level) String(full) Value(CF_FULL) +Enum(cf_protection_level) String(full) Value(CF_FULL) Set(1) EnumValue -Enum(cf_protection_level) String(branch) Value(CF_BRANCH) +Enum(cf_protection_level) String(branch) Value(CF_BRANCH) Set(2) EnumValue -Enum(cf_protection_level) String(return) Value(CF_RETURN) +Enum(cf_protection_level) String(return) Value(CF_RETURN) Set(3) EnumValue -Enum(cf_protection_level) String(check) Value(CF_CHECK) +Enum(cf_protection_level) String(check) Value(CF_CHECK) Set(4) EnumValue -Enum(cf_protection_level) String(none) Value(CF_NONE) +Enum(cf_protection_level) String(none) Value(CF_NONE) Set(1) finstrument-functions Common Var(flag_instrument_function_entry_exit,1) diff --git a/gcc/testsuite/c-c++-common/fcf-protection-10.c b/gcc/testsuite/c-c++-common/fcf-protection-10.c new file mode 100644 index 0000000..b271d13 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fcf-protection-10.c @@ -0,0 +1,2 @@ +/* { dg-do compile { target { "i?86-*-* x86_64-*-*" } } } */ +/* { dg-options "-fcf-protection=branch,check" } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-11.c b/gcc/testsuite/c-c++-common/fcf-protection-11.c new file mode 100644 index 0000000..2e56635 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fcf-protection-11.c @@ -0,0 +1,2 @@ +/* { dg-do compile { target { "i?86-*-* x86_64-*-*" } } } */ +/* { dg-options "-fcf-protection=branch,return" } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-12.c b/gcc/testsuite/c-c++-common/fcf-protection-12.c new file mode 100644 index 0000000..b39c2f8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fcf-protection-12.c @@ -0,0 +1,2 @@ +/* { dg-do compile { target { "i?86-*-* x86_64-*-*" } } } */ +/* { dg-options "-fcf-protection=return,branch" } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-8.c b/gcc/testsuite/c-c++-common/fcf-protection-8.c new file mode 100644 index 0000000..3b97095 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fcf-protection-8.c @@ -0,0 +1,2 @@ +/* { dg-do compile { target { "i?86-*-* x86_64-*-*" } } } */ +/* { dg-options "-fcf-protection=branch,none" } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-9.c b/gcc/testsuite/c-c++-common/fcf-protection-9.c new file mode 100644 index 0000000..6a37e74 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fcf-protection-9.c @@ -0,0 +1,2 @@ +/* { dg-do compile { target { "i?86-*-* x86_64-*-*" } } } */ +/* { dg-options "-fcf-protection=branch,full" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr89701-1.c b/gcc/testsuite/gcc.target/i386/pr89701-1.c new file mode 100644 index 0000000..1879c9a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89701-1.c @@ -0,0 +1,4 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-fcf-protection=branch,return" } */ +/* { dg-final { scan-assembler-times ".note.gnu.property" 1 } } */ +/* { dg-final { scan-assembler-times ".long 0x3" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr89701-2.c b/gcc/testsuite/gcc.target/i386/pr89701-2.c new file mode 100644 index 0000000..d510057 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89701-2.c @@ -0,0 +1,4 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-fcf-protection=return,branch" } */ +/* { dg-final { scan-assembler-times ".note.gnu.property" 1 } } */ +/* { dg-final { scan-assembler-times ".long 0x3" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr89701-3.c b/gcc/testsuite/gcc.target/i386/pr89701-3.c new file mode 100644 index 0000000..88afb54 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89701-3.c @@ -0,0 +1,4 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-fcf-protection=return,none" } */ +/* { dg-final { scan-assembler-times ".note.gnu.property" 1 } } */ +/* { dg-final { scan-assembler-times ".long 0x2" 1 } } */ -- cgit v1.1 From 6894581ac453361e3fb4e1ffd54f9499acb87466 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Fri, 21 Jul 2023 00:16:29 -0500 Subject: testsuite: Add a test case for PR110729 [PR110729] As PR110729 reported, there was one issue for .section __patchable_function_entries with -ffunction-sections, that is we put the same symbol as link_to section symbol for all functions wrongly. The commit r13-4294 for PR99889 has fixed this with the corresponding label LPFE* which sits in the function_section. As Fangrui suggested [1], this patch is to add a bit more test coverage. I didn't find a good way to check all linked_to symbols are different, so I checked for LPFE[012]. [1] https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624866.html PR testsuite/110729 gcc/testsuite/ChangeLog: * gcc.dg/pr110729.c: New test. --- gcc/testsuite/gcc.dg/pr110729.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr110729.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/pr110729.c b/gcc/testsuite/gcc.dg/pr110729.c new file mode 100644 index 0000000..29b8c1c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110729.c @@ -0,0 +1,29 @@ +/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */ +/* { dg-require-effective-target o_flag_in_section } */ +/* { dg-options "-ffunction-sections -fpatchable-function-entry=2" } */ +/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */ + +/* Verify there are three different link_to symbols for three + .section __patchable_function_entries respectively. */ + +int +f () +{ + return 1; +} + +int +g () +{ + return 2; +} + +int +h () +{ + return 3; +} + +/* { dg-final { scan-assembler-times {.section[\t ]*__patchable_function_entries,.*,\.LPFE0} 1 } } */ +/* { dg-final { scan-assembler-times {.section[\t ]*__patchable_function_entries,.*,\.LPFE1} 1 } } */ +/* { dg-final { scan-assembler-times {.section[\t ]*__patchable_function_entries,.*,\.LPFE2} 1 } } */ -- cgit v1.1 From a6654c08fde11890d621fa7831180d410054568a Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Fri, 21 Jul 2023 00:18:19 -0500 Subject: sccvn: Correct the index of bias for IFN_LEN_STORE [PR110744] Commit r14-2267-gb8806f6ffbe72e adjusts the arguments order of LEN_STORE from {len,vector,bias} to {len,bias,vector}, in order to make them consistent with LEN_MASK_STORE and MASK_STORE. But it missed to update the related handlings in tree-ssa-sccvn.cc, it caused the failure shown in PR 110744. This patch is to fix the related handlings with the correct index. PR tree-optimization/110744 gcc/ChangeLog: * tree-ssa-sccvn.cc (vn_reference_lookup_3): Correct the index of bias operand for ifn IFN_LEN_STORE. --- gcc/tree-ssa-sccvn.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index a0b98c1..ebe8006 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -3299,11 +3299,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, return (void *)-1; break; case IFN_LEN_STORE: - len = gimple_call_arg (call, 2); - bias = gimple_call_arg (call, 4); - if (!tree_fits_uhwi_p (len) || !tree_fits_shwi_p (bias)) - return (void *)-1; - break; + { + int len_index = internal_fn_len_index (fn); + len = gimple_call_arg (call, len_index); + bias = gimple_call_arg (call, len_index + 1); + if (!tree_fits_uhwi_p (len) || !tree_fits_shwi_p (bias)) + return (void *) -1; + break; + } default: return (void *)-1; } -- cgit v1.1 From 89619f87697a0e0b54be4627f0f811f6c486ffe5 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 08:52:00 +0200 Subject: Cleanup expected_loop_iterations this patch cleanups API for determining expected loop iteraitons from profile. We started with having expected_loop_iterations and only source was the integer represented BB counts. It did some work on guessing number of iteration if profile was absent or bogus. Later we introduced loop_info and added get_estimated_loop_iterations which made expected_loop_iterations useful mostly when doing profile updates and not for loop optimization heuristics. The naming is bit ambiguous so this difference is not clear. Even later we introduced precision tracking to profile and exended the API to return reliablity of result but did not update all uses to do reasonable stuff with it. There is also some cofusion about +-1s concering latch execution counts versus header execution counts. This patch aims to obsolette expected_loop_iterations and expected_loop_iterations_unbounded (and "suceeds" modulo 1 use of each of two). It adds expected_loop_iterations_by_profile which computes sreal and does correct precision/presence tracking. Unlike old code, it is based on CFG profile only and does not attempt to provide fake answer when info is missing and does not check sanity with loop_info. We now define iterations consistently as lath execution in loop_info so I use that here too. I converted almost all calls to new API: dumps, code produing loop_info from CFG profile and profile updating. Remaining uses are in loop unrolling and prefetching that needs more TLC I will do incrementally. There are some improvements possible which I can play with incrementally. - for simple loops with one exit dominating latch we can use exit probability for easier to preserve info in loop itraionts. THis is probably not too critical since all esitmates should be recorded in loop_info and would help mostly if new loop is constructed or old loop is lost and redicovered. - We may want to avoid trusting the profile if it is obviously inconsistent on header. gcc/ChangeLog: * cfgloop.cc: Include sreal.h. (flow_loop_dump): Dump sreal iteration exsitmate. (get_estimated_loop_iterations): Update. * cfgloop.h (expected_loop_iterations_by_profile): Declare. * cfgloopanal.cc (expected_loop_iterations_by_profile): New function. (expected_loop_iterations_unbounded): Use new API. * cfgloopmanip.cc (scale_loop_profile): Use expected_loop_iterations_by_profile * predict.cc (pass_profile::execute): Likewise. * profile.cc (branch_prob): Likewise. * tree-ssa-loop-niter.cc: Include sreal.h. (estimate_numbers_of_iterations): Likewise --- gcc/cfgloop.cc | 22 ++++---- gcc/cfgloop.h | 5 +- gcc/cfgloopanal.cc | 138 ++++++++++++++++++++++++++------------------- gcc/cfgloopmanip.cc | 9 +-- gcc/predict.cc | 8 +-- gcc/profile.cc | 9 ++- gcc/tree-ssa-loop-niter.cc | 10 +++- 7 files changed, 117 insertions(+), 84 deletions(-) (limited to 'gcc') diff --git a/gcc/cfgloop.cc b/gcc/cfgloop.cc index ccda741..020e573 100644 --- a/gcc/cfgloop.cc +++ b/gcc/cfgloop.cc @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "dumpfile.h" #include "tree-ssa.h" #include "tree-pretty-print.h" +#include "sreal.h" static void flow_loops_cfg_dump (FILE *); @@ -138,14 +139,11 @@ flow_loop_dump (const class loop *loop, FILE *file, loop_depth (loop), (long) (loop_outer (loop) ? loop_outer (loop)->num : -1)); - if (loop->latch) - { - bool read_profile_p; - gcov_type nit = expected_loop_iterations_unbounded (loop, &read_profile_p); - if (read_profile_p && !loop->any_estimate) - fprintf (file, ";; profile-based iteration count: %" PRIu64 "\n", - (uint64_t) nit); - } + bool reliable; + sreal iterations; + if (loop->num && expected_loop_iterations_by_profile (loop, &iterations, &reliable)) + fprintf (file, ";; profile-based iteration count: %f %s\n", + iterations.to_double (), reliable ? "(reliable)" : "(unreliable)"); fprintf (file, ";; nodes:"); bbs = get_loop_body (loop); @@ -2014,10 +2012,12 @@ get_estimated_loop_iterations (class loop *loop, widest_int *nit) profile. */ if (!loop->any_estimate) { - if (loop->header->count.reliable_p ()) + sreal snit; + bool reliable; + if (expected_loop_iterations_by_profile (loop, &snit, &reliable) + && reliable) { - *nit = gcov_type_to_wide_int - (expected_loop_iterations_unbounded (loop) + 1); + *nit = (snit + 0.5).to_int (); return true; } return false; diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index e7ac2b5..4d2fd4b6 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -403,7 +403,10 @@ extern void verify_loop_structure (void); /* Loop analysis. */ extern bool just_once_each_iteration_p (const class loop *, const_basic_block); gcov_type expected_loop_iterations_unbounded (const class loop *, - bool *read_profile_p = NULL, bool by_profile_only = false); + bool *read_profile_p = NULL); +extern bool expected_loop_iterations_by_profile (const class loop *loop, + sreal *ret, + bool *reliable = NULL); extern unsigned expected_loop_iterations (class loop *); extern rtx doloop_condition_get (rtx_insn *); diff --git a/gcc/cfgloopanal.cc b/gcc/cfgloopanal.cc index fd86744..2bf2eb0 100644 --- a/gcc/cfgloopanal.cc +++ b/gcc/cfgloopanal.cc @@ -233,79 +233,101 @@ average_num_loop_insns (const class loop *loop) return ret; } -/* Returns expected number of iterations of LOOP, according to - measured or guessed profile. +/* Return true if BB profile can be used to determine the expected number of + iterations (that is number of executions of latch edge(s) for each + entry of the loop. If this is the case initialize RET with the number + of iterations. - This functions attempts to return "sane" value even if profile - information is not good enough to derive osmething. - If BY_PROFILE_ONLY is set, this logic is bypassed and function - return -1 in those scenarios. */ + RELIABLE is set if profile indiates that the returned value should be + realistic estimate. (This is the case if we read profile and did not + messed it up yet and not the case of guessed profiles.) -gcov_type -expected_loop_iterations_unbounded (const class loop *loop, - bool *read_profile_p, - bool by_profile_only) + This function uses only CFG profile. We track more reliable info in + loop_info structure and for loop optimization heuristics more relevant + is get_estimated_loop_iterations API. */ + +bool +expected_loop_iterations_by_profile (const class loop *loop, sreal *ret, + bool *reliable) { + profile_count header_count = loop->header->count; + if (reliable) + *reliable = false; + + /* TODO: For single exit loops we can use loop exit edge probability. + It also may be reliable while loop itself was adjusted. */ + if (!header_count.initialized_p () + || !header_count.nonzero_p ()) + return false; + + profile_count count_in = profile_count::zero (); edge e; edge_iterator ei; - gcov_type expected = -1; - - if (read_profile_p) - *read_profile_p = false; - /* If we have no profile at all, use AVG_LOOP_NITER. */ - if (profile_status_for_fn (cfun) == PROFILE_ABSENT) - { - if (by_profile_only) - return -1; - expected = param_avg_loop_niter; - } - else if (loop->latch && (loop->latch->count.initialized_p () - || loop->header->count.initialized_p ())) + /* For single-latch loops avoid querying dominators. */ + if (loop->latch) { - profile_count count_in = profile_count::zero (), - count_latch = profile_count::zero (); - + bool found = false; FOR_EACH_EDGE (e, ei, loop->header->preds) - if (e->src == loop->latch) - count_latch = e->count (); - else + if (e->src != loop->latch) count_in += e->count (); - - if (!count_latch.initialized_p ()) - { - if (by_profile_only) - return -1; - expected = param_avg_loop_niter; - } - else if (!count_in.nonzero_p ()) + else + found = true; + /* If latch is not found, loop is inconsistent. */ + gcc_checking_assert (found); + } + else + FOR_EACH_EDGE (e, ei, loop->header->preds) + if (!dominated_by_p (CDI_DOMINATORS, e->src, loop->header)) + count_in += e->count (); + + bool known; + /* Number of iterations is number of executions of latch edge. */ + *ret = (header_count - count_in).to_sreal_scale (count_in, &known); + if (!known) + return false; + if (reliable) + { + /* Header should have at least count_in many executions. + Give up on clearly inconsistent profile. */ + if (header_count < count_in && header_count.differs_from_p (count_in)) { - if (by_profile_only) - return -1; - expected = count_latch.to_gcov_type () * 2; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Inconsistent bb profile of loop %i\n", + loop->num); + *reliable = false; } else - { - expected = (count_latch.to_gcov_type () + count_in.to_gcov_type () - - 1) / count_in.to_gcov_type (); - if (read_profile_p - && count_latch.reliable_p () && count_in.reliable_p ()) - *read_profile_p = true; - } + *reliable = count_in.reliable_p () && header_count.reliable_p (); } + return true; +} + +/* Returns expected number of iterations of LOOP, according to + measured or guessed profile. + + This functions attempts to return "sane" value even if profile + information is not good enough to derive osmething. */ + +gcov_type +expected_loop_iterations_unbounded (const class loop *loop, + bool *read_profile_p) +{ + gcov_type expected = -1; + + if (read_profile_p) + *read_profile_p = false; + + sreal sreal_expected; + if (expected_loop_iterations_by_profile + (loop, &sreal_expected, read_profile_p)) + expected = (sreal_expected + 0.5).to_int (); else - { - if (by_profile_only) - return -1; - expected = param_avg_loop_niter; - } + expected = param_avg_loop_niter; - if (!by_profile_only) - { - HOST_WIDE_INT max = get_max_loop_iterations_int (loop); - if (max != -1 && max < expected) - return max; - } + HOST_WIDE_INT max = get_max_loop_iterations_int (loop); + if (max != -1 && max < expected) + return max; return expected; } diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 5c0065b..3012a8d 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify-me.h" #include "tree-ssa-loop-manip.h" #include "dumpfile.h" +#include "sreal.h" static void copy_loops_to (class loop **, int, class loop *); @@ -527,16 +528,16 @@ scale_loop_profile (class loop *loop, profile_probability p, if (iteration_bound == -1) return; - gcov_type iterations = expected_loop_iterations_unbounded (loop, NULL, true); - if (iterations == -1) + sreal iterations; + if (!expected_loop_iterations_by_profile (loop, &iterations)) return; if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, - ";; guessed iterations of loop %i:%i new upper bound %i:\n", + ";; guessed iterations of loop %i:%f new upper bound %i:\n", loop->num, - (int)iterations, + iterations.to_double (), (int)iteration_bound); } diff --git a/gcc/predict.cc b/gcc/predict.cc index 26f9f3f..8f44f5b 100644 --- a/gcc/predict.cc +++ b/gcc/predict.cc @@ -4142,11 +4142,11 @@ pass_profile::execute (function *fun) profile_status_for_fn (fun) = PROFILE_GUESSED; if (dump_file && (dump_flags & TDF_DETAILS)) { + sreal iterations; for (auto loop : loops_list (cfun, LI_FROM_INNERMOST)) - if (loop->header->count.initialized_p ()) - fprintf (dump_file, "Loop got predicted %d to iterate %i times.\n", - loop->num, - (int)expected_loop_iterations_unbounded (loop)); + if (expected_loop_iterations_by_profile (loop, &iterations)) + fprintf (dump_file, "Loop got predicted %d to iterate %f times.\n", + loop->num, iterations.to_double ()); } return 0; } diff --git a/gcc/profile.cc b/gcc/profile.cc index a71800d..84d47b3 100644 --- a/gcc/profile.cc +++ b/gcc/profile.cc @@ -1543,14 +1543,17 @@ branch_prob (bool thunk) { if (dump_file && (dump_flags & TDF_DETAILS)) report_predictor_hitrates (); + sreal nit; + bool reliable; /* At this moment we have precise loop iteration count estimates. Record them to loop structure before the profile gets out of date. */ for (auto loop : loops_list (cfun, 0)) - if (loop->header->count > 0 && loop->header->count.reliable_p ()) + if (loop->header->count.ipa ().nonzero_p () + && expected_loop_iterations_by_profile (loop, &nit, &reliable) + && reliable) { - gcov_type nit = expected_loop_iterations_unbounded (loop); - widest_int bound = gcov_type_to_wide_int (nit); + widest_int bound = (nit + 0.5).to_int (); loop->any_estimate = false; record_niter_bound (loop, bound, true, false); } diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 5d398b6..3c4e662 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-dfa.h" #include "internal-fn.h" #include "gimple-range.h" +#include "sreal.h" /* The maximum number of dominator BBs we search for conditions @@ -4775,6 +4776,9 @@ estimate_numbers_of_iterations (class loop *loop) loop->estimate_state = EST_AVAILABLE; + sreal nit; + bool reliable; + /* If we have a measured profile, use it to estimate the number of iterations. Normally this is recorded by branch_prob right after reading the profile. In case we however found a new loop, record the @@ -4787,10 +4791,10 @@ estimate_numbers_of_iterations (class loop *loop) recomputing iteration bounds later in the compilation process will just introduce random roundoff errors. */ if (!loop->any_estimate - && loop->header->count.reliable_p ()) + && expected_loop_iterations_by_profile (loop, &nit, &reliable) + && reliable) { - gcov_type nit = expected_loop_iterations_unbounded (loop); - bound = gcov_type_to_wide_int (nit); + bound = (nit + 0.5).to_int (); record_niter_bound (loop, bound, true, false); } -- cgit v1.1 From 9a8782e63790842d1bfa03e12eecf73c4aaeb1f8 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 20 Jul 2023 13:09:17 +0200 Subject: tree-optimization/110742 - fix latent issue with permuting existing vectors When we materialize a layout we push edge permutes to constant/external defs without checking we can actually do so. For externals defined by vector stmts rather than scalar components we can't. PR tree-optimization/110742 * tree-vect-slp.cc (vect_optimize_slp_pass::get_result_with_layout): Do not materialize an edge permutation in an external node with vector defs. (vect_slp_analyze_node_operations_1): Guard purely internal nodes better. * g++.dg/torture/pr110742.C: New testcase. --- gcc/testsuite/g++.dg/torture/pr110742.C | 47 +++++++++++++++++++++++++++++++++ gcc/tree-vect-slp.cc | 7 +++-- 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr110742.C (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/torture/pr110742.C b/gcc/testsuite/g++.dg/torture/pr110742.C new file mode 100644 index 0000000..d41ac04 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr110742.C @@ -0,0 +1,47 @@ +// { dg-do compile } + +struct HARD_REG_SET { + HARD_REG_SET operator~() const { + HARD_REG_SET res; + for (unsigned int i = 0; i < (sizeof(elts) / sizeof((elts)[0])); ++i) + res.elts[i] = ~elts[i]; + return res; + } + HARD_REG_SET operator&(const HARD_REG_SET &other) const { + HARD_REG_SET res; + for (unsigned int i = 0; i < (sizeof(elts) / sizeof((elts)[0])); ++i) + res.elts[i] = elts[i] & other.elts[i]; + return res; + } + unsigned long elts[4]; +}; +typedef const HARD_REG_SET &const_hard_reg_set; +inline bool hard_reg_set_subset_p(const_hard_reg_set x, const_hard_reg_set y) { + unsigned long bad = 0; + for (unsigned int i = 0; i < (sizeof(x.elts) / sizeof((x.elts)[0])); ++i) + bad |= (x.elts[i] & ~y.elts[i]); + return bad == 0; +} +inline bool hard_reg_set_empty_p(const_hard_reg_set x) { + unsigned long bad = 0; + for (unsigned int i = 0; i < (sizeof(x.elts) / sizeof((x.elts)[0])); ++i) + bad |= x.elts[i]; + return bad == 0; +} +extern HARD_REG_SET rr[2]; +extern int t[2]; +extern HARD_REG_SET nn; +static HARD_REG_SET mm; +void setup_reg_class_relations(void) { + HARD_REG_SET intersection_set, union_set, temp_set2; + for (int cl2 = 0; cl2 < 2; cl2++) { + temp_set2 = rr[cl2] & ~nn; + if (hard_reg_set_empty_p(mm) && hard_reg_set_empty_p(temp_set2)) { + mm = rr[0] & nn; + if (hard_reg_set_subset_p(mm, intersection_set)) + if (!hard_reg_set_subset_p(mm, temp_set2) || + hard_reg_set_subset_p(rr[0], rr[t[cl2]])) + t[cl2] = 0; + } + } +} diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 693621c..f4adbb2 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -5198,7 +5198,9 @@ vect_optimize_slp_pass::get_result_with_layout (slp_tree node, return result; if (SLP_TREE_DEF_TYPE (node) == vect_constant_def - || SLP_TREE_DEF_TYPE (node) == vect_external_def) + || (SLP_TREE_DEF_TYPE (node) == vect_external_def + /* We can't permute vector defs in place. */ + && SLP_TREE_VEC_DEFS (node).is_empty ())) { /* If the vector is uniform or unchanged, there's nothing to do. */ if (to_layout_i == 0 || vect_slp_tree_uniform_p (node)) @@ -5944,7 +5946,8 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node, calculated by the recursive call). Otherwise it is the number of scalar elements in one scalar iteration (DR_GROUP_SIZE) multiplied by VF divided by the number of elements in a vector. */ - if (!STMT_VINFO_DATA_REF (stmt_info) + if (SLP_TREE_CODE (node) != VEC_PERM_EXPR + && !STMT_VINFO_DATA_REF (stmt_info) && REDUC_GROUP_FIRST_ELEMENT (stmt_info)) { for (unsigned i = 0; i < SLP_TREE_CHILDREN (node).length (); ++i) -- cgit v1.1 From 6d449531a60b56ed0f4aeb640aa9e46e4ec35208 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Thu, 20 Jul 2023 17:36:29 -0700 Subject: MATCH: Add Max,a> -> Max simplifcation This adds a simple match pattern to simplify `max,a>` to `max`. Reassociation handles this already (r0-77700-ge969dbde29bfd396259357) but seems like we should be able to handle this even before reassociation. This fixes part of PR tree-optimization/80574 but more work is needed fix it the rest of the way. The original testcase there is fixed but the RTL level is what fixes it the rest of the way. OK? Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: * match.pd (minmax,a>->minmax): New transformation. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/reassoc-12.c: Disable all of the passes that enables match-and-simplify. * gcc.dg/tree-ssa/minmax-23.c: New test. --- gcc/match.pd | 6 +++++- gcc/testsuite/gcc.dg/tree-ssa/minmax-23.c | 22 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/reassoc-12.c | 3 ++- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-23.c (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index 4dfe926..bfd15d6 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3503,7 +3503,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for minmax (min max) (simplify (minmax @0 @0) - @0)) + @0) +/* max(max(x,y),x) -> max(x,y) */ + (simplify + (minmax:c (minmax:c@2 @0 @1) @0) + @2)) /* For fmin() and fmax(), skip folding when both are sNaN. */ (for minmax (FMIN_ALL FMAX_ALL) (simplify diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-23.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-23.c new file mode 100644 index 0000000..0b7e51b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-23.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-tree-reassoc -fdump-tree-optimized" } */ + + +#define MAX(a,b) (a)>=(b) ? (a) : (b) + +#define MIN(a,b) (a)<=(b) ? (a) : (b) + +int test1(int a, int b) +{ + int d = MAX(a,b); + return MAX(a,d); +} +int test2(int a, int b) +{ + int d = MIN(a,b); + return MIN(a,d); +} + +/* We should be optimize these two functions even without reassociation. */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR " 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "MIN_EXPR " 1 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-12.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-12.c index 9a138eb..2238147 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-12.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-reassoc1-details" } */ +/* Match-and-simplify can handle now MAX,a>->MAX, disable all of the passes that uses that. */ +/* { dg-options "-O1 -fdump-tree-reassoc1-details -fno-tree-ccp -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre" } */ int f(int a, int b) { /* MAX_EXPR should cause it to be equivalent to a. */ -- cgit v1.1 From 9f8f37f5490076b10436993fb90d18092a960922 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 13 Jul 2023 08:58:58 +0200 Subject: tree-optimization/88540 - FP x > y ? x : y if-conversion without -ffast-math The following makes sure that FP x > y ? x : y style max/min operations are if-converted at the GIMPLE level. While we can neither match it to MAX_EXPR nor .FMAX as both have different semantics with IEEE than the ternary ?: operation we can make sure to maintain this form as a COND_EXPR so backends have the chance to match this to instructions their ISA offers. The patch does this in phiopt where we recognize min/max and instead of giving up when we have to honor NaNs we alter the generated code to a COND_EXPR. This resolves PR88540 and we can then SLP vectorize the min operation for its testcase. It also resolves part of the regressions observed with the change matching bit-inserts of bit-field-refs to vec_perm. Expansion from a COND_EXPR rather than from compare-and-branch gcc.target/i386/pr54855-9.c by producing extra moves while the corresponding min/max operations are now already synthesized by RTL expansion, register selection isn't optimal. This can be also provoked without this change by altering the operand order in the source. I have XFAILed that part of the test. PR tree-optimization/88540 * tree-ssa-phiopt.cc (minmax_replacement): Do not give up with NaNs but handle the simple case by if-converting to a COND_EXPR. * gcc.target/i386/pr88540.c: New testcase. * gcc.target/i386/pr54855-9.c: XFAIL check for redundant moves. * gcc.target/i386/pr54855-12.c: Adjust. * gcc.target/i386/pr54855-13.c: Likewise. * gcc.target/i386/pr110170.c: Likewise. * gcc.dg/tree-ssa/split-path-12.c: Likewise. --- gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c | 4 +++- gcc/testsuite/gcc.target/i386/pr110170.c | 7 ++----- gcc/testsuite/gcc.target/i386/pr54855-12.c | 2 +- gcc/testsuite/gcc.target/i386/pr54855-13.c | 2 +- gcc/testsuite/gcc.target/i386/pr54855-9.c | 4 ++-- gcc/testsuite/gcc.target/i386/pr88540.c | 10 ++++++++++ gcc/tree-ssa-phiopt.cc | 21 ++++++++++++++++----- 7 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr88540.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c index 19a130d..da00f79 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c @@ -16,4 +16,6 @@ foo(double *d1, double *d2, double *d3, int num, double *ip) return dmax[0] + dmax[1] + dmax[2]; } -/* { dg-final { scan-tree-dump "appears to be optimized to a join point for if-convertable half-diamond" "split-paths" } } */ +/* Split-paths shouldn't do anything here, if there's a diamond it would + be if-convertible. */ +/* { dg-final { scan-tree-dump-not "Duplicating join block" "split-paths" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr110170.c b/gcc/testsuite/gcc.target/i386/pr110170.c index c72f733..9edbf05 100644 --- a/gcc/testsuite/gcc.target/i386/pr110170.c +++ b/gcc/testsuite/gcc.target/i386/pr110170.c @@ -1,10 +1,7 @@ /* { dg-do compile } */ /* { dg-options " -O2 -msse4.1 -mfpmath=sse" } */ -/* { dg-final { scan-assembler-times {(?n)mins[sd]} 2 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times {(?n)maxs[sd]} 2 { target { ! ia32 } } } } */ -/* Ideally cond_swap_df is also optimized to minsd/maxsd. */ -/* { dg-final { scan-assembler-times {(?n)mins[sd]} 1 { target ia32 } } } */ -/* { dg-final { scan-assembler-times {(?n)maxs[sd]} 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times {(?n)mins[sd]} 2 } } */ +/* { dg-final { scan-assembler-times {(?n)maxs[sd]} 2 } } */ void __cond_swap_df(double* __x, double* __y) { _Bool __r = (*__x < *__y); diff --git a/gcc/testsuite/gcc.target/i386/pr54855-12.c b/gcc/testsuite/gcc.target/i386/pr54855-12.c index 2f8af39..09e8ab8 100644 --- a/gcc/testsuite/gcc.target/i386/pr54855-12.c +++ b/gcc/testsuite/gcc.target/i386/pr54855-12.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -mavx512fp16" } */ -/* { dg-final { scan-assembler-times "vmaxsh\[ \\t\]" 1 } } */ +/* { dg-final { scan-assembler-times "vm\[ai\]\[nx\]sh\[ \\t\]" 1 } } */ /* { dg-final { scan-assembler-not "vcomish\[ \\t\]" } } */ /* { dg-final { scan-assembler-not "vmovsh\[ \\t\]" { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr54855-13.c b/gcc/testsuite/gcc.target/i386/pr54855-13.c index 87b4f45..a4f2506 100644 --- a/gcc/testsuite/gcc.target/i386/pr54855-13.c +++ b/gcc/testsuite/gcc.target/i386/pr54855-13.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -mavx512fp16" } */ -/* { dg-final { scan-assembler-times "vmaxsh\[ \\t\]" 1 } } */ +/* { dg-final { scan-assembler-times "vm\[ai\]\[nx\]sh\[ \\t\]" 1 } } */ /* { dg-final { scan-assembler-not "vcomish\[ \\t\]" } } */ /* { dg-final { scan-assembler-not "vmovsh\[ \\t\]" { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr54855-9.c b/gcc/testsuite/gcc.target/i386/pr54855-9.c index 40add5f..fe9302e 100644 --- a/gcc/testsuite/gcc.target/i386/pr54855-9.c +++ b/gcc/testsuite/gcc.target/i386/pr54855-9.c @@ -1,8 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2 -msse2 -mfpmath=sse" } */ /* { dg-final { scan-assembler-times "minss" 1 } } */ -/* { dg-final { scan-assembler-not "movaps" } } */ -/* { dg-final { scan-assembler-not "movss" } } */ +/* { dg-final { scan-assembler-not "movaps" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not "movss" { xfail *-*-* } } } */ typedef float vec __attribute__((vector_size(16))); diff --git a/gcc/testsuite/gcc.target/i386/pr88540.c b/gcc/testsuite/gcc.target/i386/pr88540.c new file mode 100644 index 0000000..b927d0c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr88540.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2" } */ + +void test(double* __restrict d1, double* __restrict d2, double* __restrict d3) +{ + for (int n = 0; n < 2; ++n) + d3[n] = d1[n] < d2[n] ? d1[n] : d2[n]; +} + +/* { dg-final { scan-assembler "minpd" } } */ diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 9d542fd..cb4e2da 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -1625,10 +1625,6 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_ tree type = TREE_TYPE (PHI_RESULT (phi)); - /* The optimization may be unsafe due to NaNs. */ - if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type)) - return false; - gcond *cond = as_a (*gsi_last_bb (cond_bb)); enum tree_code cmp = gimple_cond_code (cond); tree rhs = gimple_cond_rhs (cond); @@ -1815,6 +1811,9 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_ else return false; } + else if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type)) + /* The optimization may be unsafe due to NaNs. */ + return false; else if (middle_bb != alt_middle_bb && threeway_p) { /* Recognize the following case: @@ -2148,7 +2147,19 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_ /* Emit the statement to compute min/max. */ gimple_seq stmts = NULL; tree phi_result = PHI_RESULT (phi); - result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, arg1); + + /* When we can't use a MIN/MAX_EXPR still make sure the expression + stays in a form to be recognized by ISA that map to IEEE x > y ? x : y + semantics (that's not IEEE max semantics). */ + if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type)) + { + result = gimple_build (&stmts, cmp, boolean_type_node, + gimple_cond_lhs (cond), rhs); + result = gimple_build (&stmts, COND_EXPR, TREE_TYPE (phi_result), + result, arg_true, arg_false); + } + else + result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, arg1); gsi = gsi_last_bb (cond_bb); gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); -- cgit v1.1 From 1ec65c2bc076b2909ee2ac0667757201d8b3c757 Mon Sep 17 00:00:00 2001 From: Haochen Jiang Date: Fri, 21 Jul 2023 15:43:30 +0800 Subject: Fix a typo Hi all, This patch fix a typo which will not cause any behavior difference. Commited as obvious change. Thx, Haochen gcc/ChangeLog: * config/i386/i386.opt: Fix a typo. --- gcc/config/i386/i386.opt | 5 ----- 1 file changed, 5 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index db99568..1cc8563 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1289,11 +1289,6 @@ Target Mask(ISA2_SM3) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and SM3 built-in functions and code generation. -mvpinsrvpextr -Target Mask(ISA2_VPINSRVPEXTR) Var(ix86_isa_flags2) Save -Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, -AVX512VL and VPINSRVPEXTR built-in functions and code generation. - msha512 Target Mask(ISA2_SHA512) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and -- cgit v1.1 From bd68b33f80ae4726393dbd6e12025f99dc269c12 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Fri, 21 Jul 2023 07:20:04 +0800 Subject: cleanup: Change LEN_MASK into MASK_LEN Hi. Since start from LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE, COND_LEN_* patterns, the order of len and mask is {mask,len,bias}. The reason we make "mask" argument comes before "len" is because we want to keep the "mask" location same as mask_* or cond_* patterns to make use of current codes flow of mask_* and cond_*. Otherwise, we will need to change codes much more and make codes hard to maintain. Now, we already have COND_LEN_*, it's naturally that we should rename "LEN_MASK" into "MASK_LEN" to keep name scheme consistent. This patch only changes the name "LEN_MASK" into "MASK_LEN". No codes functionality change. gcc/ChangeLog: * config/riscv/autovec.md (len_maskload): Change LEN_MASK into MASK_LEN. (mask_len_load): Ditto. (len_maskstore): Ditto. (mask_len_store): Ditto. (len_mask_gather_load): Ditto. (mask_len_gather_load): Ditto. (len_mask_gather_load): Ditto. (mask_len_gather_load): Ditto. (len_mask_gather_load): Ditto. (mask_len_gather_load): Ditto. (len_mask_gather_load): Ditto. (mask_len_gather_load): Ditto. (len_mask_gather_load): Ditto. (mask_len_gather_load): Ditto. (len_mask_gather_load): Ditto. (mask_len_gather_load): Ditto. (len_mask_gather_load): Ditto. (mask_len_gather_load): Ditto. (len_mask_scatter_store): Ditto. (mask_len_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (mask_len_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (mask_len_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (mask_len_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (mask_len_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (mask_len_scatter_store): Ditto. (len_mask_scatter_store): Ditto. (mask_len_scatter_store): Ditto. * doc/md.texi: Ditto. * genopinit.cc (main): Ditto. (CMP_NAME): Ditto. Ditto. * gimple-fold.cc (arith_overflowed_p): Ditto. (gimple_fold_partial_load_store_mem_ref): Ditto. (gimple_fold_call): Ditto. * internal-fn.cc (len_maskload_direct): Ditto. (mask_len_load_direct): Ditto. (len_maskstore_direct): Ditto. (mask_len_store_direct): Ditto. (expand_call_mem_ref): Ditto. (expand_len_maskload_optab_fn): Ditto. (expand_mask_len_load_optab_fn): Ditto. (expand_len_maskstore_optab_fn): Ditto. (expand_mask_len_store_optab_fn): Ditto. (direct_len_maskload_optab_supported_p): Ditto. (direct_mask_len_load_optab_supported_p): Ditto. (direct_len_maskstore_optab_supported_p): Ditto. (direct_mask_len_store_optab_supported_p): Ditto. (internal_load_fn_p): Ditto. (internal_store_fn_p): Ditto. (internal_gather_scatter_fn_p): Ditto. (internal_fn_len_index): Ditto. (internal_fn_mask_index): Ditto. (internal_fn_stored_value_index): Ditto. (internal_len_load_store_bias): Ditto. * internal-fn.def (LEN_MASK_GATHER_LOAD): Ditto. (MASK_LEN_GATHER_LOAD): Ditto. (LEN_MASK_LOAD): Ditto. (MASK_LEN_LOAD): Ditto. (LEN_MASK_SCATTER_STORE): Ditto. (MASK_LEN_SCATTER_STORE): Ditto. (LEN_MASK_STORE): Ditto. (MASK_LEN_STORE): Ditto. * optabs-query.cc (supports_vec_gather_load_p): Ditto. (supports_vec_scatter_store_p): Ditto. * optabs-tree.cc (target_supports_mask_load_store_p): Ditto. (target_supports_len_load_store_p): Ditto. * optabs.def (OPTAB_CD): Ditto. * tree-ssa-alias.cc (ref_maybe_used_by_call_p_1): Ditto. (call_may_clobber_ref_p_1): Ditto. * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Ditto. (dse_optimize_stmt): Ditto. * tree-ssa-loop-ivopts.cc (get_mem_type_for_internal_fn): Ditto. (get_alias_ptr_type_for_ptr_address): Ditto. * tree-vect-data-refs.cc (vect_gather_scatter_fn_p): Ditto. * tree-vect-patterns.cc (vect_recog_gather_scatter_pattern): Ditto. * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Ditto. (vect_get_strided_load_store_ops): Ditto. (vectorizable_store): Ditto. (vectorizable_load): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c: Ditto. * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c: Ditto. --- gcc/config/riscv/autovec.md | 32 ++++++------- gcc/doc/md.texi | 18 +++---- gcc/genopinit.cc | 6 +-- gcc/gimple-fold.cc | 12 ++--- gcc/internal-fn.cc | 56 +++++++++++----------- gcc/internal-fn.def | 20 ++++---- gcc/optabs-query.cc | 4 +- gcc/optabs-tree.cc | 20 ++++---- gcc/optabs.def | 8 ++-- .../rvv/autovec/gather-scatter/gather_load-1.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-10.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-11.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-12.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-2.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-3.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-4.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-5.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-6.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-7.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-8.c | 2 +- .../rvv/autovec/gather-scatter/gather_load-9.c | 2 +- .../autovec/gather-scatter/mask_gather_load-1.c | 2 +- .../autovec/gather-scatter/mask_gather_load-10.c | 2 +- .../autovec/gather-scatter/mask_gather_load-11.c | 2 +- .../autovec/gather-scatter/mask_gather_load-2.c | 2 +- .../autovec/gather-scatter/mask_gather_load-3.c | 2 +- .../autovec/gather-scatter/mask_gather_load-4.c | 2 +- .../autovec/gather-scatter/mask_gather_load-5.c | 2 +- .../autovec/gather-scatter/mask_gather_load-6.c | 2 +- .../autovec/gather-scatter/mask_gather_load-7.c | 2 +- .../autovec/gather-scatter/mask_gather_load-8.c | 2 +- .../autovec/gather-scatter/mask_gather_load-9.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-1.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-10.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-2.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-3.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-4.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-5.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-6.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-7.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-8.c | 2 +- .../autovec/gather-scatter/mask_scatter_store-9.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-1.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-10.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-2.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-3.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-4.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-5.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-6.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-7.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-8.c | 2 +- .../rvv/autovec/gather-scatter/scatter_store-9.c | 2 +- .../rvv/autovec/gather-scatter/strided_load-1.c | 2 +- .../rvv/autovec/gather-scatter/strided_load-2.c | 2 +- .../rvv/autovec/gather-scatter/strided_store-1.c | 2 +- .../rvv/autovec/gather-scatter/strided_store-2.c | 2 +- .../riscv/rvv/autovec/partial/gimple_fold-1.c | 2 +- gcc/tree-ssa-alias.cc | 6 +-- gcc/tree-ssa-dse.cc | 4 +- gcc/tree-ssa-loop-ivopts.cc | 8 ++-- gcc/tree-vect-data-refs.cc | 12 ++--- gcc/tree-vect-patterns.cc | 4 +- gcc/tree-vect-stmts.cc | 34 ++++++------- 63 files changed, 170 insertions(+), 170 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 0094720..f06aff7 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -22,7 +22,7 @@ ;; == Loads/Stores ;; ========================================================================= -(define_expand "len_maskload" +(define_expand "mask_len_load" [(match_operand:V 0 "register_operand") (match_operand:V 1 "memory_operand") (match_operand 2 "autovec_length_operand") @@ -34,7 +34,7 @@ DONE; }) -(define_expand "len_maskstore" +(define_expand "mask_len_store" [(match_operand:V 0 "memory_operand") (match_operand:V 1 "register_operand") (match_operand 2 "autovec_length_operand") @@ -61,7 +61,7 @@ ;; == Gather Load ;; ========================================================================= -(define_expand "len_mask_gather_load" +(define_expand "mask_len_gather_load" [(match_operand:RATIO64 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") (match_operand:RATIO64I 2 "register_operand") @@ -76,7 +76,7 @@ DONE; }) -(define_expand "len_mask_gather_load" +(define_expand "mask_len_gather_load" [(match_operand:RATIO32 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") (match_operand:RATIO32I 2 "register_operand") @@ -91,7 +91,7 @@ DONE; }) -(define_expand "len_mask_gather_load" +(define_expand "mask_len_gather_load" [(match_operand:RATIO16 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") (match_operand:RATIO16I 2 "register_operand") @@ -106,7 +106,7 @@ DONE; }) -(define_expand "len_mask_gather_load" +(define_expand "mask_len_gather_load" [(match_operand:RATIO8 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") (match_operand:RATIO8I 2 "register_operand") @@ -121,7 +121,7 @@ DONE; }) -(define_expand "len_mask_gather_load" +(define_expand "mask_len_gather_load" [(match_operand:RATIO4 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") (match_operand:RATIO4I 2 "register_operand") @@ -136,7 +136,7 @@ DONE; }) -(define_expand "len_mask_gather_load" +(define_expand "mask_len_gather_load" [(match_operand:RATIO2 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") (match_operand:RATIO2I 2 "register_operand") @@ -155,7 +155,7 @@ ;; larger SEW. Since RVV indexed load/store support zero extend ;; implicitly and not support scaling, we should only allow ;; operands[3] and operands[4] to be const_1_operand. -(define_expand "len_mask_gather_load" +(define_expand "mask_len_gather_load" [(match_operand:RATIO1 0 "register_operand") (match_operand 1 "pmode_reg_or_0_operand") (match_operand:RATIO1 2 "register_operand") @@ -174,7 +174,7 @@ ;; == Scatter Store ;; ========================================================================= -(define_expand "len_mask_scatter_store" +(define_expand "mask_len_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") (match_operand:RATIO64I 1 "register_operand") (match_operand 2 "") @@ -189,7 +189,7 @@ DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "mask_len_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") (match_operand:RATIO32I 1 "register_operand") (match_operand 2 "") @@ -204,7 +204,7 @@ DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "mask_len_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") (match_operand:RATIO16I 1 "register_operand") (match_operand 2 "") @@ -219,7 +219,7 @@ DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "mask_len_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") (match_operand:RATIO8I 1 "register_operand") (match_operand 2 "") @@ -234,7 +234,7 @@ DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "mask_len_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") (match_operand:RATIO4I 1 "register_operand") (match_operand 2 "") @@ -249,7 +249,7 @@ DONE; }) -(define_expand "len_mask_scatter_store" +(define_expand "mask_len_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") (match_operand:RATIO2I 1 "register_operand") (match_operand 2 "") @@ -268,7 +268,7 @@ ;; larger SEW. Since RVV indexed load/store support zero extend ;; implicitly and not support scaling, we should only allow ;; operands[3] and operands[4] to be const_1_operand. -(define_expand "len_mask_scatter_store" +(define_expand "mask_len_scatter_store" [(match_operand 0 "pmode_reg_or_0_operand") (match_operand:RATIO1 1 "register_operand") (match_operand 2 "") diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 6f44e66..f864936 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5040,10 +5040,10 @@ operand 5. Bit @var{i} of the mask is set if element @var{i} of the result should be loaded from memory and clear if element @var{i} of the result should be set to zero. -@cindex @code{len_mask_gather_load@var{m}@var{n}} instruction pattern -@item @samp{len_mask_gather_load@var{m}@var{n}} +@cindex @code{mask_len_gather_load@var{m}@var{n}} instruction pattern +@item @samp{mask_len_gather_load@var{m}@var{n}} Like @samp{gather_load@var{m}@var{n}}, but takes an extra length operand (operand 5), -a bias operand (operand 6) as well as a mask operand (operand 7). Similar to len_maskload, +a bias operand (operand 6) as well as a mask operand (operand 7). Similar to mask_len_load, the instruction loads at most (operand 5 + operand 6) elements from memory. Bit @var{i} of the mask is set if element @var{i} of the result should be loaded from memory and clear if element @var{i} of the result should be undefined. @@ -5078,8 +5078,8 @@ Like @samp{scatter_store@var{m}@var{n}}, but takes an extra mask operand as operand 5. Bit @var{i} of the mask is set if element @var{i} of the result should be stored to memory. -@cindex @code{len_mask_scatter_store@var{m}@var{n}} instruction pattern -@item @samp{len_mask_scatter_store@var{m}@var{n}} +@cindex @code{mask_len_scatter_store@var{m}@var{n}} instruction pattern +@item @samp{mask_len_scatter_store@var{m}@var{n}} Like @samp{scatter_store@var{m}@var{n}}, but takes an extra length operand (operand 5), a bias operand (operand 6) as well as a mask operand (operand 7). The instruction stores at most (operand 5 + operand 6) elements of (operand 4) to memory. @@ -5321,8 +5321,8 @@ of @code{QI} elements. This pattern is not allowed to @code{FAIL}. -@cindex @code{len_maskload@var{m}@var{n}} instruction pattern -@item @samp{len_maskload@var{m}@var{n}} +@cindex @code{mask_len_load@var{m}@var{n}} instruction pattern +@item @samp{mask_len_load@var{m}@var{n}} Perform a masked load from the memory location pointed to by operand 1 into register operand 0. (operand 2 + operand 3) elements are loaded from memory and other elements in operand 0 are set to undefined values. @@ -5348,8 +5348,8 @@ of @code{QI} elements. This pattern is not allowed to @code{FAIL}. -@cindex @code{len_maskstore@var{m}@var{n}} instruction pattern -@item @samp{len_maskstore@var{m}@var{n}} +@cindex @code{mask_len_store@var{m}@var{n}} instruction pattern +@item @samp{mask_len_store@var{m}@var{n}} Perform a masked store from vector register operand 1 into memory operand 0. (operand 2 + operand 3) elements are stored to memory and leave the other elements of operand 0 unchanged. diff --git a/gcc/genopinit.cc b/gcc/genopinit.cc index 2a84100..a4ba233 100644 --- a/gcc/genopinit.cc +++ b/gcc/genopinit.cc @@ -376,7 +376,7 @@ main (int argc, const char **argv) fprintf (s_file, "/* Returns TRUE if the target supports any of the partial vector\n" " optabs: while_ult_optab, len_load_optab, len_store_optab,\n" - " len_maskload_optab or len_maskstore_optab,\n" + " mask_len_load_optab or mask_len_store_optab,\n" " for any mode. */\n" "bool\npartial_vectors_supported_p (void)\n{\n"); bool any_match = false; @@ -386,8 +386,8 @@ main (int argc, const char **argv) { #define CMP_NAME(N) !strncmp (p->name, (N), strlen ((N))) if (CMP_NAME("while_ult") || CMP_NAME ("len_load") - || CMP_NAME ("len_store")|| CMP_NAME ("len_maskload") - || CMP_NAME ("len_maskstore")) + || CMP_NAME ("len_store")|| CMP_NAME ("mask_len_load") + || CMP_NAME ("mask_len_store")) { if (first) fprintf (s_file, " HAVE_%s", p->name); diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index de94efb..86b8347 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -5370,7 +5370,7 @@ arith_overflowed_p (enum tree_code code, const_tree type, return wi::min_precision (wres, sign) > TYPE_PRECISION (type); } -/* If IFN_{MASK,LEN,LEN_MASK}_LOAD/STORE call CALL is unconditional, +/* If IFN_{MASK,LEN,MASK_LEN}_LOAD/STORE call CALL is unconditional, return a MEM_REF for the memory it references, otherwise return null. VECTYPE is the type of the memory vector. MASK_P indicates it's for MASK if true, otherwise it's for LEN. */ @@ -5398,15 +5398,15 @@ gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype, bool mask_p) return NULL_TREE; tree bias = gimple_call_arg (call, len_index + 1); gcc_assert (TREE_CODE (bias) == INTEGER_CST); - /* For LEN_LOAD/LEN_STORE/LEN_MASK_LOAD/LEN_MASK_STORE, + /* For LEN_LOAD/LEN_STORE/MASK_LEN_LOAD/MASK_LEN_STORE, we don't fold when (bias + len) != VF. */ if (maybe_ne (wi::to_poly_widest (basic_len) + wi::to_widest (bias), GET_MODE_NUNITS (TYPE_MODE (vectype)))) return NULL_TREE; - /* For LEN_MASK_{LOAD,STORE}, we should also check whether + /* For MASK_LEN_{LOAD,STORE}, we should also check whether the mask is all ones mask. */ - if (ifn == IFN_LEN_MASK_LOAD || ifn == IFN_LEN_MASK_STORE) + if (ifn == IFN_MASK_LEN_LOAD || ifn == IFN_MASK_LEN_STORE) { tree mask = gimple_call_arg (call, internal_fn_mask_index (ifn)); if (!integer_all_onesp (mask)) @@ -5689,11 +5689,11 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) changed |= gimple_fold_partial_store (gsi, stmt, true); break; case IFN_LEN_LOAD: - case IFN_LEN_MASK_LOAD: + case IFN_MASK_LEN_LOAD: changed |= gimple_fold_partial_load (gsi, stmt, false); break; case IFN_LEN_STORE: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: changed |= gimple_fold_partial_store (gsi, stmt, false); break; default: diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 1b34d4d..ad14960 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -165,7 +165,7 @@ init_internal_fns () #define mask_load_lanes_direct { -1, -1, false } #define gather_load_direct { 3, 1, false } #define len_load_direct { -1, -1, false } -#define len_maskload_direct { -1, 4, false } +#define mask_len_load_direct { -1, 4, false } #define mask_store_direct { 3, 2, false } #define store_lanes_direct { 0, 0, false } #define mask_store_lanes_direct { 0, 0, false } @@ -173,7 +173,7 @@ init_internal_fns () #define vec_cond_direct { 2, 0, false } #define scatter_store_direct { 3, 1, false } #define len_store_direct { 3, 3, false } -#define len_maskstore_direct { 4, 5, false } +#define mask_len_store_direct { 4, 5, false } #define vec_set_direct { 3, 3, false } #define vec_extract_direct { 3, 3, false } #define unary_direct { 0, 0, true } @@ -2912,7 +2912,7 @@ expand_call_mem_ref (tree type, gcall *stmt, int index) return fold_build2 (MEM_REF, type, addr, build_int_cst (alias_ptr_type, 0)); } -/* Expand MASK_LOAD{,_LANES}, LEN_MASK_LOAD or LEN_LOAD call STMT using optab +/* Expand MASK_LOAD{,_LANES}, MASK_LEN_LOAD or LEN_LOAD call STMT using optab * OPTAB. */ static void @@ -2954,9 +2954,9 @@ expand_partial_load_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab) #define expand_mask_load_optab_fn expand_partial_load_optab_fn #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn #define expand_len_load_optab_fn expand_partial_load_optab_fn -#define expand_len_maskload_optab_fn expand_partial_load_optab_fn +#define expand_mask_len_load_optab_fn expand_partial_load_optab_fn -/* Expand MASK_STORE{,_LANES}, LEN_MASK_STORE or LEN_STORE call STMT using optab +/* Expand MASK_STORE{,_LANES}, MASK_LEN_STORE or LEN_STORE call STMT using optab * OPTAB. */ static void @@ -2993,7 +2993,7 @@ expand_partial_store_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab #define expand_mask_store_optab_fn expand_partial_store_optab_fn #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn #define expand_len_store_optab_fn expand_partial_store_optab_fn -#define expand_len_maskstore_optab_fn expand_partial_store_optab_fn +#define expand_mask_len_store_optab_fn expand_partial_store_optab_fn /* Expand VCOND, VCONDU and VCONDEQ optab internal functions. The expansion of STMT happens based on OPTAB table associated. */ @@ -4001,7 +4001,7 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types, #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p #define direct_gather_load_optab_supported_p convert_optab_supported_p #define direct_len_load_optab_supported_p direct_optab_supported_p -#define direct_len_maskload_optab_supported_p convert_optab_supported_p +#define direct_mask_len_load_optab_supported_p convert_optab_supported_p #define direct_mask_store_optab_supported_p convert_optab_supported_p #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p @@ -4009,7 +4009,7 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types, #define direct_vec_cond_optab_supported_p convert_optab_supported_p #define direct_scatter_store_optab_supported_p convert_optab_supported_p #define direct_len_store_optab_supported_p direct_optab_supported_p -#define direct_len_maskstore_optab_supported_p convert_optab_supported_p +#define direct_mask_len_store_optab_supported_p convert_optab_supported_p #define direct_while_optab_supported_p convert_optab_supported_p #define direct_fold_extract_optab_supported_p direct_optab_supported_p #define direct_fold_left_optab_supported_p direct_optab_supported_p @@ -4554,9 +4554,9 @@ internal_load_fn_p (internal_fn fn) case IFN_MASK_LOAD_LANES: case IFN_GATHER_LOAD: case IFN_MASK_GATHER_LOAD: - case IFN_LEN_MASK_GATHER_LOAD: + case IFN_MASK_LEN_GATHER_LOAD: case IFN_LEN_LOAD: - case IFN_LEN_MASK_LOAD: + case IFN_MASK_LEN_LOAD: return true; default: @@ -4576,9 +4576,9 @@ internal_store_fn_p (internal_fn fn) case IFN_MASK_STORE_LANES: case IFN_SCATTER_STORE: case IFN_MASK_SCATTER_STORE: - case IFN_LEN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: case IFN_LEN_STORE: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: return true; default: @@ -4595,10 +4595,10 @@ internal_gather_scatter_fn_p (internal_fn fn) { case IFN_GATHER_LOAD: case IFN_MASK_GATHER_LOAD: - case IFN_LEN_MASK_GATHER_LOAD: + case IFN_MASK_LEN_GATHER_LOAD: case IFN_SCATTER_STORE: case IFN_MASK_SCATTER_STORE: - case IFN_LEN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: return true; default: @@ -4616,12 +4616,12 @@ internal_fn_len_index (internal_fn fn) { case IFN_LEN_LOAD: case IFN_LEN_STORE: - case IFN_LEN_MASK_LOAD: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_LOAD: + case IFN_MASK_LEN_STORE: return 2; - case IFN_LEN_MASK_GATHER_LOAD: - case IFN_LEN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_GATHER_LOAD: + case IFN_MASK_LEN_SCATTER_STORE: case IFN_COND_LEN_FMA: case IFN_COND_LEN_FMS: case IFN_COND_LEN_FNMA: @@ -4669,10 +4669,10 @@ internal_fn_mask_index (internal_fn fn) case IFN_MASK_GATHER_LOAD: case IFN_MASK_SCATTER_STORE: - case IFN_LEN_MASK_LOAD: - case IFN_LEN_MASK_STORE: - case IFN_LEN_MASK_GATHER_LOAD: - case IFN_LEN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_LOAD: + case IFN_MASK_LEN_STORE: + case IFN_MASK_LEN_GATHER_LOAD: + case IFN_MASK_LEN_SCATTER_STORE: return 4; default: @@ -4693,13 +4693,13 @@ internal_fn_stored_value_index (internal_fn fn) case IFN_MASK_STORE_LANES: case IFN_SCATTER_STORE: case IFN_MASK_SCATTER_STORE: - case IFN_LEN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: return 3; case IFN_LEN_STORE: return 4; - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: return 5; default: @@ -4774,13 +4774,13 @@ internal_len_load_store_bias (internal_fn ifn, machine_mode mode) return VECT_PARTIAL_BIAS_UNSUPPORTED; if (ifn == IFN_LEN_LOAD) { - /* Try LEN_MASK_LOAD. */ - optab = direct_internal_fn_optab (IFN_LEN_MASK_LOAD); + /* Try MASK_LEN_LOAD. */ + optab = direct_internal_fn_optab (IFN_MASK_LEN_LOAD); } else { - /* Try LEN_MASK_STORE. */ - optab = direct_internal_fn_optab (IFN_LEN_MASK_STORE); + /* Try MASK_LEN_STORE. */ + optab = direct_internal_fn_optab (IFN_MASK_LEN_STORE); } icode = convert_optab_handler (optab, mode, mask_mode); } diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index d3aec51..04f3812 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -48,16 +48,16 @@ along with GCC; see the file COPYING3. If not see - mask_load: currently just maskload - load_lanes: currently just vec_load_lanes - mask_load_lanes: currently just vec_mask_load_lanes - - gather_load: used for {mask_,len_mask,}gather_load + - gather_load: used for {mask_,mask_len_,}gather_load - len_load: currently just len_load - - len_maskload: currently just len_maskload + - mask_len_load: currently just mask_len_load - mask_store: currently just maskstore - store_lanes: currently just vec_store_lanes - mask_store_lanes: currently just vec_mask_store_lanes - - scatter_store: used for {mask_,len_mask,}scatter_store + - scatter_store: used for {mask_,mask_len_,}scatter_store - len_store: currently just len_store - - len_maskstore: currently just len_maskstore + - mask_len_store: currently just mask_len_store - unary: a normal unary optab, such as vec_reverse_ - binary: a normal binary optab, such as vec_interleave_lo_ @@ -161,17 +161,17 @@ DEF_INTERNAL_OPTAB_FN (MASK_LOAD_LANES, ECF_PURE, DEF_INTERNAL_OPTAB_FN (GATHER_LOAD, ECF_PURE, gather_load, gather_load) DEF_INTERNAL_OPTAB_FN (MASK_GATHER_LOAD, ECF_PURE, mask_gather_load, gather_load) -DEF_INTERNAL_OPTAB_FN (LEN_MASK_GATHER_LOAD, ECF_PURE, - len_mask_gather_load, gather_load) +DEF_INTERNAL_OPTAB_FN (MASK_LEN_GATHER_LOAD, ECF_PURE, + mask_len_gather_load, gather_load) DEF_INTERNAL_OPTAB_FN (LEN_LOAD, ECF_PURE, len_load, len_load) -DEF_INTERNAL_OPTAB_FN (LEN_MASK_LOAD, ECF_PURE, len_maskload, len_maskload) +DEF_INTERNAL_OPTAB_FN (MASK_LEN_LOAD, ECF_PURE, mask_len_load, mask_len_load) DEF_INTERNAL_OPTAB_FN (SCATTER_STORE, 0, scatter_store, scatter_store) DEF_INTERNAL_OPTAB_FN (MASK_SCATTER_STORE, 0, mask_scatter_store, scatter_store) -DEF_INTERNAL_OPTAB_FN (LEN_MASK_SCATTER_STORE, 0, - len_mask_scatter_store, scatter_store) +DEF_INTERNAL_OPTAB_FN (MASK_LEN_SCATTER_STORE, 0, + mask_len_scatter_store, scatter_store) DEF_INTERNAL_OPTAB_FN (MASK_STORE, 0, maskstore, mask_store) DEF_INTERNAL_OPTAB_FN (STORE_LANES, ECF_CONST, vec_store_lanes, store_lanes) @@ -187,7 +187,7 @@ DEF_INTERNAL_OPTAB_FN (VEC_SET, 0, vec_set, vec_set) DEF_INTERNAL_OPTAB_FN (VEC_EXTRACT, 0, vec_extract, vec_extract) DEF_INTERNAL_OPTAB_FN (LEN_STORE, 0, len_store, len_store) -DEF_INTERNAL_OPTAB_FN (LEN_MASK_STORE, 0, len_maskstore, len_maskstore) +DEF_INTERNAL_OPTAB_FN (MASK_LEN_STORE, 0, mask_len_store, mask_len_store) DEF_INTERNAL_OPTAB_FN (WHILE_ULT, ECF_CONST | ECF_NOTHROW, while_ult, while) DEF_INTERNAL_OPTAB_FN (SELECT_VL, ECF_CONST | ECF_NOTHROW, select_vl, binary) diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc index bf1f484..947ccef 100644 --- a/gcc/optabs-query.cc +++ b/gcc/optabs-query.cc @@ -676,7 +676,7 @@ supports_vec_gather_load_p (machine_mode mode) this_fn_optabs->supports_vec_gather_load[mode] = (supports_vec_convert_optab_p (gather_load_optab, mode) || supports_vec_convert_optab_p (mask_gather_load_optab, mode) - || supports_vec_convert_optab_p (len_mask_gather_load_optab, mode) + || supports_vec_convert_optab_p (mask_len_gather_load_optab, mode) ? 1 : -1); return this_fn_optabs->supports_vec_gather_load[mode] > 0; @@ -693,7 +693,7 @@ supports_vec_scatter_store_p (machine_mode mode) this_fn_optabs->supports_vec_scatter_store[mode] = (supports_vec_convert_optab_p (scatter_store_optab, mode) || supports_vec_convert_optab_p (mask_scatter_store_optab, mode) - || supports_vec_convert_optab_p (len_mask_scatter_store_optab, mode) + || supports_vec_convert_optab_p (mask_len_scatter_store_optab, mode) ? 1 : -1); return this_fn_optabs->supports_vec_scatter_store[mode] > 0; diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc index e6ae159..40bfbb1 100644 --- a/gcc/optabs-tree.cc +++ b/gcc/optabs-tree.cc @@ -545,17 +545,17 @@ target_supports_op_p (tree type, enum tree_code code, /* Return true if the target has support for masked load/store. We can support masked load/store by either mask{load,store} - or len_mask{load,store}. + or mask_len_{load,store}. This helper function checks whether target supports masked load/store and return corresponding IFN in the last argument - (IFN_MASK_{LOAD,STORE} or IFN_LEN_MASK_{LOAD,STORE}). */ + (IFN_MASK_{LOAD,STORE} or IFN_MASK_LEN_{LOAD,STORE}). */ static bool target_supports_mask_load_store_p (machine_mode mode, machine_mode mask_mode, bool is_load, internal_fn *ifn) { optab op = is_load ? maskload_optab : maskstore_optab; - optab len_op = is_load ? len_maskload_optab : len_maskstore_optab; + optab len_op = is_load ? mask_len_load_optab : mask_len_store_optab; if (convert_optab_handler (op, mode, mask_mode) != CODE_FOR_nothing) { if (ifn) @@ -565,7 +565,7 @@ target_supports_mask_load_store_p (machine_mode mode, machine_mode mask_mode, else if (convert_optab_handler (len_op, mode, mask_mode) != CODE_FOR_nothing) { if (ifn) - *ifn = is_load ? IFN_LEN_MASK_LOAD : IFN_LEN_MASK_STORE; + *ifn = is_load ? IFN_MASK_LEN_LOAD : IFN_MASK_LEN_STORE; return true; } return false; @@ -573,7 +573,7 @@ target_supports_mask_load_store_p (machine_mode mode, machine_mode mask_mode, /* Return true if target supports vector masked load/store for mode. An additional output in the last argument which is the IFN pointer. - We set IFN as MASK_{LOAD,STORE} or LEN_MASK_{LOAD,STORE} according + We set IFN as MASK_{LOAD,STORE} or MASK_LEN_{LOAD,STORE} according which optab is supported in the target. */ bool @@ -615,17 +615,17 @@ can_vec_mask_load_store_p (machine_mode mode, /* Return true if the target has support for len load/store. We can support len load/store by either len_{load,store} - or len_mask{load,store}. + or mask_len_{load,store}. This helper function checks whether target supports len load/store and return corresponding IFN in the last argument - (IFN_LEN_{LOAD,STORE} or IFN_LEN_MASK_{LOAD,STORE}). */ + (IFN_LEN_{LOAD,STORE} or IFN_MASK_LEN_{LOAD,STORE}). */ static bool target_supports_len_load_store_p (machine_mode mode, bool is_load, internal_fn *ifn) { optab op = is_load ? len_load_optab : len_store_optab; - optab masked_op = is_load ? len_maskload_optab : len_maskstore_optab; + optab masked_op = is_load ? mask_len_load_optab : mask_len_store_optab; if (direct_optab_handler (op, mode)) { @@ -638,7 +638,7 @@ target_supports_len_load_store_p (machine_mode mode, bool is_load, && convert_optab_handler (masked_op, mode, mask_mode) != CODE_FOR_nothing) { if (ifn) - *ifn = is_load ? IFN_LEN_MASK_LOAD : IFN_LEN_MASK_STORE; + *ifn = is_load ? IFN_MASK_LEN_LOAD : IFN_MASK_LEN_STORE; return true; } return false; @@ -651,7 +651,7 @@ target_supports_len_load_store_p (machine_mode mode, bool is_load, As len_{load,store} optabs point out, for the flavor with bytes, we use VnQI to wrap the other supportable same size vector modes. An additional output in the last argument which is the IFN pointer. - We set IFN as LEN_{LOAD,STORE} or LEN_MASK_{LOAD,STORE} according + We set IFN as LEN_{LOAD,STORE} or MASK_LEN_{LOAD,STORE} according which optab is supported in the target. */ opt_machine_mode diff --git a/gcc/optabs.def b/gcc/optabs.def index 7023392..1ea1947 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -91,14 +91,14 @@ OPTAB_CD(vec_cmpu_optab, "vec_cmpu$a$b") OPTAB_CD(vec_cmpeq_optab, "vec_cmpeq$a$b") OPTAB_CD(maskload_optab, "maskload$a$b") OPTAB_CD(maskstore_optab, "maskstore$a$b") -OPTAB_CD(len_maskload_optab, "len_maskload$a$b") -OPTAB_CD(len_maskstore_optab, "len_maskstore$a$b") +OPTAB_CD(mask_len_load_optab, "mask_len_load$a$b") +OPTAB_CD(mask_len_store_optab, "mask_len_store$a$b") OPTAB_CD(gather_load_optab, "gather_load$a$b") OPTAB_CD(mask_gather_load_optab, "mask_gather_load$a$b") -OPTAB_CD(len_mask_gather_load_optab, "len_mask_gather_load$a$b") +OPTAB_CD(mask_len_gather_load_optab, "mask_len_gather_load$a$b") OPTAB_CD(scatter_store_optab, "scatter_store$a$b") OPTAB_CD(mask_scatter_store_optab, "mask_scatter_store$a$b") -OPTAB_CD(len_mask_scatter_store_optab, "len_mask_scatter_store$a$b") +OPTAB_CD(mask_len_scatter_store_optab, "mask_len_scatter_store$a$b") OPTAB_CD(vec_extract_optab, "vec_extract$a$b") OPTAB_CD(vec_init_optab, "vec_init$a$b") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c index dffe13f..3b26bf1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c @@ -33,6 +33,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c index a622e51..63949cb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c index 4692380..8dc1da3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c @@ -27,6 +27,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c index 71a3dd4..6277682 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c @@ -105,7 +105,7 @@ TEST_LOOP (float, uint64_t) TEST_LOOP (double, uint64_t) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 88 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not "vluxei64\.v" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c index 785550c..89e4b40 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c @@ -33,6 +33,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c index 22aeb88..02fd37c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c index d74a834..af6a76a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c index 2b6c0a8..bd9a449 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c index 407cc8a..6d776af 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c index 81b31ef..040300a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c index 0bfdb8f..9223bf0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c index 46f7911..2e06fe6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c index a5de0de..abab3b9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c @@ -34,6 +34,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c index 74a0d05..61ab1fb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c index 98c5b46..e574181 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c @@ -108,7 +108,7 @@ TEST_LOOP (float, uint64_t) TEST_LOOP (double, uint64_t) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 88 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-assembler-not "vluxei64\.v" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c index 03f84ce..cc5f52e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c @@ -34,6 +34,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c index 8578001..311e25e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c index b273caa..9223df9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c index 5055d88..9ec7e60 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c index 2a4ae585..ff18009 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c index 31d9414..fd05df7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c index 73ed230..a58c1c2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c index 2f64e80..36947db 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_GATHER_LOAD" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c index 623de41..0099ed3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c @@ -34,6 +34,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c index 55112b0..089ec48 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c index 32a572d..57a1ace 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c @@ -34,6 +34,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c index fbaaa9d..ba89eb3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c index 9b08661..2d6499f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c index dd26635..f55db71 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c index fa0206a..a7ec279 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c index 325e86c..b7bd3f4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c index b4b84e9..f2ab865 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c @@ -31,6 +31,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c index a21ccd5..42ce1c5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c @@ -36,6 +36,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c index 6a39026..28c4bae 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c @@ -33,6 +33,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c index feb58d7..2cd3e72 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c index e4c587f..ee44f41 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c @@ -33,6 +33,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c index 33ad256..899b05f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c index 48d3056..ff6d90c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c index 83ddc44..212bd2d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c index 11eb68b..4b6b39d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c index 2e32347..2415c69 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c index e6732fe..4c2fcb1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c index 766a52b..0f4f94c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c @@ -30,6 +30,6 @@ TEST_ALL (TEST_LOOP) /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 11 "vect" } } */ -/* { dg-final { scan-tree-dump " \.LEN_MASK_SCATTER_STORE" "vect" } } */ +/* { dg-final { scan-tree-dump " \.MASK_LEN_SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "vect" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c index 0c64f3e..b1e6a17 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c @@ -40,6 +40,6 @@ TEST_ALL (TEST_LOOP) -/* { dg-final { scan-tree-dump-times " \.LEN_MASK_GATHER_LOAD" 66 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \.MASK_LEN_GATHER_LOAD" 66 "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c index 0f23420..ee5f509 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c @@ -40,6 +40,6 @@ TEST_ALL (TEST_LOOP) -/* { dg-final { scan-tree-dump-times " \.LEN_MASK_GATHER_LOAD" 46 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \.MASK_LEN_GATHER_LOAD" 46 "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c index 2418a0d..3e6a340 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c @@ -40,6 +40,6 @@ TEST_ALL (TEST_LOOP) -/* { dg-final { scan-tree-dump-times " \.LEN_MASK_SCATTER_STORE" 66 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \.MASK_LEN_SCATTER_STORE" 66 "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c index 83e101d..6906af1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c @@ -40,6 +40,6 @@ TEST_ALL (TEST_LOOP) -/* { dg-final { scan-tree-dump-times " \.LEN_MASK_SCATTER_STORE" 44 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \.MASK_LEN_SCATTER_STORE" 44 "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.SCATTER_STORE" "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_SCATTER_STORE" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c index 23407a2..7021182 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c @@ -40,4 +40,4 @@ main () RUN_ALL () } -/* { dg-final { scan-tree-dump-times "\.LEN_MASK_STORE" 6 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.MASK_LEN_STORE" 6 "optimized" } } */ diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc index f31fd04..cf38fe5 100644 --- a/gcc/tree-ssa-alias.cc +++ b/gcc/tree-ssa-alias.cc @@ -2815,13 +2815,13 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref, bool tbaa_p) case IFN_SCATTER_STORE: case IFN_MASK_SCATTER_STORE: case IFN_LEN_STORE: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: return false; case IFN_MASK_STORE_LANES: goto process_args; case IFN_MASK_LOAD: case IFN_LEN_LOAD: - case IFN_LEN_MASK_LOAD: + case IFN_MASK_LEN_LOAD: case IFN_MASK_LOAD_LANES: { ao_ref rhs_ref; @@ -3070,7 +3070,7 @@ call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref, bool tbaa_p) return false; case IFN_MASK_STORE: case IFN_LEN_STORE: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: case IFN_MASK_STORE_LANES: { tree rhs = gimple_call_arg (call, diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc index 9c6004c..baf72bf 100644 --- a/gcc/tree-ssa-dse.cc +++ b/gcc/tree-ssa-dse.cc @@ -159,7 +159,7 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write, bool may_def_ok = false) { case IFN_LEN_STORE: case IFN_MASK_STORE: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: { internal_fn ifn = gimple_call_internal_fn (stmt); int stored_value_index = internal_fn_stored_value_index (ifn); @@ -1517,7 +1517,7 @@ dse_optimize_stmt (function *fun, gimple_stmt_iterator *gsi, sbitmap live_bytes) { case IFN_LEN_STORE: case IFN_MASK_STORE: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: { enum dse_store_status store_status; store_status = dse_classify_store (&ref, stmt, false, live_bytes); diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc index 243ce86..92fc1c7 100644 --- a/gcc/tree-ssa-loop-ivopts.cc +++ b/gcc/tree-ssa-loop-ivopts.cc @@ -2442,7 +2442,7 @@ get_mem_type_for_internal_fn (gcall *call, tree *op_p) case IFN_MASK_LOAD: case IFN_MASK_LOAD_LANES: case IFN_LEN_LOAD: - case IFN_LEN_MASK_LOAD: + case IFN_MASK_LEN_LOAD: if (op_p == gimple_call_arg_ptr (call, 0)) return TREE_TYPE (gimple_call_lhs (call)); return NULL_TREE; @@ -2450,7 +2450,7 @@ get_mem_type_for_internal_fn (gcall *call, tree *op_p) case IFN_MASK_STORE: case IFN_MASK_STORE_LANES: case IFN_LEN_STORE: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_STORE: { if (op_p == gimple_call_arg_ptr (call, 0)) { @@ -7567,8 +7567,8 @@ get_alias_ptr_type_for_ptr_address (iv_use *use) case IFN_MASK_STORE_LANES: case IFN_LEN_LOAD: case IFN_LEN_STORE: - case IFN_LEN_MASK_LOAD: - case IFN_LEN_MASK_STORE: + case IFN_MASK_LEN_LOAD: + case IFN_MASK_LEN_STORE: /* The second argument contains the correct alias type. */ gcc_assert (use->op_p = gimple_call_arg_ptr (call, 0)); return TREE_TYPE (gimple_call_arg (call, 1)); diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index 9edc898..a3570c4 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -3878,19 +3878,19 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p, bool masked_p, { ifn = masked_p ? IFN_MASK_GATHER_LOAD : IFN_GATHER_LOAD; alt_ifn = IFN_MASK_GATHER_LOAD; - /* When target supports LEN_MASK_GATHER_LOAD, we always - use LEN_MASK_GATHER_LOAD regardless whether len and + /* When target supports MASK_LEN_GATHER_LOAD, we always + use MASK_LEN_GATHER_LOAD regardless whether len and mask are valid or not. */ - alt_ifn2 = IFN_LEN_MASK_GATHER_LOAD; + alt_ifn2 = IFN_MASK_LEN_GATHER_LOAD; } else { ifn = masked_p ? IFN_MASK_SCATTER_STORE : IFN_SCATTER_STORE; alt_ifn = IFN_MASK_SCATTER_STORE; - /* When target supports LEN_MASK_SCATTER_STORE, we always - use LEN_MASK_SCATTER_STORE regardless whether len and + /* When target supports MASK_LEN_SCATTER_STORE, we always + use MASK_LEN_SCATTER_STORE regardless whether len and mask are valid or not. */ - alt_ifn2 = IFN_LEN_MASK_SCATTER_STORE; + alt_ifn2 = IFN_MASK_LEN_SCATTER_STORE; } for (;;) diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index c0832e8..ef806e2 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -6106,8 +6106,8 @@ vect_recog_gather_scatter_pattern (vec_info *vinfo, loop_vinfo); else if (gs_info.ifn == IFN_MASK_SCATTER_STORE || gs_info.ifn == IFN_MASK_GATHER_LOAD - || gs_info.ifn == IFN_LEN_MASK_SCATTER_STORE - || gs_info.ifn == IFN_LEN_MASK_GATHER_LOAD) + || gs_info.ifn == IFN_MASK_LEN_SCATTER_STORE + || gs_info.ifn == IFN_MASK_LEN_GATHER_LOAD) mask = build_int_cst (TREE_TYPE (truth_type_for (gs_vectype)), -1); /* Get the invariant base and non-invariant offset, converting the diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index cc9a200..cebddd4 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1633,8 +1633,8 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype, ? IFN_MASK_GATHER_LOAD : IFN_MASK_SCATTER_STORE); internal_fn len_ifn = (is_load - ? IFN_LEN_MASK_GATHER_LOAD - : IFN_LEN_MASK_SCATTER_STORE); + ? IFN_MASK_LEN_GATHER_LOAD + : IFN_MASK_LEN_SCATTER_STORE); if (internal_gather_scatter_fn_supported_p (ifn, vectype, gs_info->memory_type, gs_info->offset_vectype, @@ -3034,7 +3034,7 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info, { /* _31 = .SELECT_VL (ivtmp_29, POLY_INT_CST [4, 4]); ivtmp_8 = _31 * 16 (step in bytes); - .LEN_MASK_SCATTER_STORE (vectp_a.9_7, ... ); + .MASK_LEN_SCATTER_STORE (vectp_a.9_7, ... ); vectp_a.9_26 = vectp_a.9_7 + ivtmp_8; */ tree loop_len = vect_get_loop_len (loop_vinfo, gsi, loop_lens, 1, vectype, 0, 0); @@ -8872,7 +8872,7 @@ vectorizable_store (vec_info *vinfo, vec_offset = vec_offsets[vec_num * j + i]; tree scale = size_int (gs_info.scale); - if (gs_info.ifn == IFN_LEN_MASK_SCATTER_STORE) + if (gs_info.ifn == IFN_MASK_LEN_SCATTER_STORE) { if (loop_lens) final_len @@ -8896,7 +8896,7 @@ vectorizable_store (vec_info *vinfo, gcall *call; if (final_len && final_mask) call - = gimple_build_call_internal (IFN_LEN_MASK_SCATTER_STORE, + = gimple_build_call_internal (IFN_MASK_LEN_SCATTER_STORE, 7, dataref_ptr, vec_offset, scale, vec_oprnd, final_mask, final_len, bias); @@ -9036,12 +9036,12 @@ vectorizable_store (vec_info *vinfo, gcc_unreachable (); } - if (partial_ifn == IFN_LEN_MASK_STORE) + if (partial_ifn == IFN_MASK_LEN_STORE) { if (!final_len) { /* Pass VF value to 'len' argument of - LEN_MASK_STORE if LOOP_LENS is invalid. */ + MASK_LEN_STORE if LOOP_LENS is invalid. */ tree iv_type = LOOP_VINFO_RGROUP_IV_TYPE (loop_vinfo); final_len = build_int_cst (iv_type, @@ -9050,7 +9050,7 @@ vectorizable_store (vec_info *vinfo, if (!final_mask) { /* Pass all ones value to 'mask' argument of - LEN_MASK_STORE if final_mask is invalid. */ + MASK_LEN_STORE if final_mask is invalid. */ mask_vectype = truth_type_for (vectype); final_mask = build_minus_one_cst (mask_vectype); } @@ -9086,8 +9086,8 @@ vectorizable_store (vec_info *vinfo, vec_oprnd = var; } - if (partial_ifn == IFN_LEN_MASK_STORE) - call = gimple_build_call_internal (IFN_LEN_MASK_STORE, 6, + if (partial_ifn == IFN_MASK_LEN_STORE) + call = gimple_build_call_internal (IFN_MASK_LEN_STORE, 6, dataref_ptr, ptr, final_len, bias, final_mask, vec_oprnd); @@ -10456,7 +10456,7 @@ vectorizable_load (vec_info *vinfo, tree zero = build_zero_cst (vectype); tree scale = size_int (gs_info.scale); - if (gs_info.ifn == IFN_LEN_MASK_GATHER_LOAD) + if (gs_info.ifn == IFN_MASK_LEN_GATHER_LOAD) { if (loop_lens) final_len @@ -10480,7 +10480,7 @@ vectorizable_load (vec_info *vinfo, gcall *call; if (final_len && final_mask) call = gimple_build_call_internal ( - IFN_LEN_MASK_GATHER_LOAD, 7, dataref_ptr, + IFN_MASK_LEN_GATHER_LOAD, 7, dataref_ptr, vec_offset, scale, zero, final_mask, final_len, bias); else if (final_mask) @@ -10620,12 +10620,12 @@ vectorizable_load (vec_info *vinfo, gcc_unreachable (); } - if (partial_ifn == IFN_LEN_MASK_LOAD) + if (partial_ifn == IFN_MASK_LEN_LOAD) { if (!final_len) { /* Pass VF value to 'len' argument of - LEN_MASK_LOAD if LOOP_LENS is invalid. */ + MASK_LEN_LOAD if LOOP_LENS is invalid. */ tree iv_type = LOOP_VINFO_RGROUP_IV_TYPE (loop_vinfo); final_len @@ -10635,7 +10635,7 @@ vectorizable_load (vec_info *vinfo, if (!final_mask) { /* Pass all ones value to 'mask' argument of - LEN_MASK_LOAD if final_mask is invalid. */ + MASK_LEN_LOAD if final_mask is invalid. */ mask_vectype = truth_type_for (vectype); final_mask = build_minus_one_cst (mask_vectype); } @@ -10653,8 +10653,8 @@ vectorizable_load (vec_info *vinfo, tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); gcall *call; - if (partial_ifn == IFN_LEN_MASK_LOAD) - call = gimple_build_call_internal (IFN_LEN_MASK_LOAD, + if (partial_ifn == IFN_MASK_LEN_LOAD) + call = gimple_build_call_internal (IFN_MASK_LEN_LOAD, 5, dataref_ptr, ptr, final_len, bias, final_mask); -- cgit v1.1 From 363bb3dca429e885ce3d134fc50f8ab05aacda0f Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Fri, 21 Jul 2023 10:09:00 +0800 Subject: cleanup: make all cond_len_* and mask_len_* consistent on the order of mask and len This patch is depending on: https://gcc.gnu.org/pipermail/gcc-patches/2023-July/625121.html Hi, Richard and Richi. This patch is to align the order of mask and len. Currently, According to this piece code: if (final_len && final_mask) call = gimple_build_call_internal ( IFN_LEN_MASK_GATHER_LOAD, 7, dataref_ptr, vec_offset, scale, zero, final_mask, final_len, bias); You can see the order of mask and len, is {mask,len,bias}. "mask" comes before "len". The reason of this order is that we want to reuse the current codes of MASK_GATHER_LOAD/MASK_SCATTER_STORE. Same situation for COND_LEN_*, we want to reuse the codes of COND_*. Reusing codes from the existing MASK_* or COND_* can allow us not to change the codes too much and make the codes elegant and easy to maintain && read. To avoid any confusions of auto-vectorization patterns that includes both mask and len, this patch align the order of mask and len for both Gimple IR and RTL pattern into {mask, len, bias} to make everything cleaner and more elegant. Bootstrap and Regression is on the way. gcc/ChangeLog: * config/riscv/autovec.md: Align order of mask and len. * config/riscv/riscv-v.cc (expand_load_store): Ditto. (expand_gather_scatter): Ditto. * doc/md.texi: Ditto. * internal-fn.cc (add_len_and_mask_args): Ditto. (add_mask_and_len_args): Ditto. (expand_partial_load_optab_fn): Ditto. (expand_partial_store_optab_fn): Ditto. (expand_scatter_store_optab_fn): Ditto. (expand_gather_load_optab_fn): Ditto. (internal_fn_len_index): Ditto. (internal_fn_mask_index): Ditto. (internal_len_load_store_bias): Ditto. * tree-vect-stmts.cc (vectorizable_store): Ditto. (vectorizable_load): Ditto. --- gcc/config/riscv/autovec.md | 96 ++++++++++++++++++++++----------------------- gcc/config/riscv/riscv-v.cc | 12 +++--- gcc/doc/md.texi | 36 ++++++++--------- gcc/internal-fn.cc | 50 +++++++++++------------ gcc/tree-vect-stmts.cc | 8 ++-- 5 files changed, 101 insertions(+), 101 deletions(-) (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index f06aff7..c9ea731 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -25,9 +25,9 @@ (define_expand "mask_len_load" [(match_operand:V 0 "register_operand") (match_operand:V 1 "memory_operand") - (match_operand 2 "autovec_length_operand") - (match_operand 3 "const_0_operand") - (match_operand: 4 "vector_mask_operand")] + (match_operand: 2 "vector_mask_operand") + (match_operand 3 "autovec_length_operand") + (match_operand 4 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_load_store (operands, true); @@ -37,9 +37,9 @@ (define_expand "mask_len_store" [(match_operand:V 0 "memory_operand") (match_operand:V 1 "register_operand") - (match_operand 2 "autovec_length_operand") - (match_operand 3 "const_0_operand") - (match_operand: 4 "vector_mask_operand")] + (match_operand: 2 "vector_mask_operand") + (match_operand 3 "autovec_length_operand") + (match_operand 4 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_load_store (operands, false); @@ -67,9 +67,9 @@ (match_operand:RATIO64I 2 "register_operand") (match_operand 3 "") (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -82,9 +82,9 @@ (match_operand:RATIO32I 2 "register_operand") (match_operand 3 "") (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -97,9 +97,9 @@ (match_operand:RATIO16I 2 "register_operand") (match_operand 3 "") (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -112,9 +112,9 @@ (match_operand:RATIO8I 2 "register_operand") (match_operand 3 "") (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -127,9 +127,9 @@ (match_operand:RATIO4I 2 "register_operand") (match_operand 3 "") (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -142,9 +142,9 @@ (match_operand:RATIO2I 2 "register_operand") (match_operand 3 "") (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -161,9 +161,9 @@ (match_operand:RATIO1 2 "register_operand") (match_operand 3 "") (match_operand 4 "") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -180,9 +180,9 @@ (match_operand 2 "") (match_operand 3 "") (match_operand:RATIO64 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); @@ -195,9 +195,9 @@ (match_operand 2 "") (match_operand 3 "") (match_operand:RATIO32 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); @@ -210,9 +210,9 @@ (match_operand 2 "") (match_operand 3 "") (match_operand:RATIO16 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); @@ -225,9 +225,9 @@ (match_operand 2 "") (match_operand 3 "") (match_operand:RATIO8 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); @@ -240,9 +240,9 @@ (match_operand 2 "") (match_operand 3 "") (match_operand:RATIO4 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); @@ -255,9 +255,9 @@ (match_operand 2 "") (match_operand 3 "") (match_operand:RATIO2 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); @@ -274,9 +274,9 @@ (match_operand 2 "") (match_operand 3 "") (match_operand:RATIO1 4 "register_operand") - (match_operand 5 "autovec_length_operand") - (match_operand 6 "const_0_operand") - (match_operand: 7 "vector_mask_operand")] + (match_operand: 5 "vector_mask_operand") + (match_operand 6 "autovec_length_operand") + (match_operand 7 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, false); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 53088ed..eb92451 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -3073,13 +3073,13 @@ expand_select_vl (rtx *ops) emit_insn (gen_no_side_effects_vsetvl_rtx (rvv_mode, ops[0], ops[1])); } -/* Expand LEN_MASK_{LOAD,STORE}. */ +/* Expand MASK_LEN_{LOAD,STORE}. */ void expand_load_store (rtx *ops, bool is_load) { poly_int64 value; - rtx len = ops[2]; - rtx mask = ops[4]; + rtx mask = ops[2]; + rtx len = ops[3]; machine_mode mode = GET_MODE (ops[0]); if (poly_int_rtx_p (len, &value) && known_eq (value, GET_MODE_NUNITS (mode))) @@ -3215,6 +3215,8 @@ expand_gather_scatter (rtx *ops, bool is_load) rtx ptr, vec_offset, vec_reg, len, mask; bool zero_extend_p; int scale_log2; + rtx mask = ops[5]; + rtx len = ops[6]; if (is_load) { vec_reg = ops[0]; @@ -3222,8 +3224,6 @@ expand_gather_scatter (rtx *ops, bool is_load) vec_offset = ops[2]; zero_extend_p = INTVAL (ops[3]); scale_log2 = exact_log2 (INTVAL (ops[4])); - len = ops[5]; - mask = ops[7]; } else { @@ -3232,8 +3232,6 @@ expand_gather_scatter (rtx *ops, bool is_load) vec_offset = ops[1]; zero_extend_p = INTVAL (ops[2]); scale_log2 = exact_log2 (INTVAL (ops[3])); - len = ops[5]; - mask = ops[7]; } machine_mode vec_mode = GET_MODE (vec_reg); diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index f864936..9693b6b 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5042,12 +5042,12 @@ of the result should be set to zero. @cindex @code{mask_len_gather_load@var{m}@var{n}} instruction pattern @item @samp{mask_len_gather_load@var{m}@var{n}} -Like @samp{gather_load@var{m}@var{n}}, but takes an extra length operand (operand 5), -a bias operand (operand 6) as well as a mask operand (operand 7). Similar to mask_len_load, -the instruction loads at most (operand 5 + operand 6) elements from memory. +Like @samp{gather_load@var{m}@var{n}}, but takes an extra mask operand (operand 5), +a len operand (operand 6) as well as a bias operand (operand 7). Similar to mask_len_load, +the instruction loads at most (operand 6 + operand 7) elements from memory. Bit @var{i} of the mask is set if element @var{i} of the result should be loaded from memory and clear if element @var{i} of the result should be undefined. -Mask elements @var{i} with @var{i} > (operand 5 + operand 6) are ignored. +Mask elements @var{i} with @var{i} > (operand 6 + operand 7) are ignored. @cindex @code{scatter_store@var{m}@var{n}} instruction pattern @item @samp{scatter_store@var{m}@var{n}} @@ -5080,11 +5080,11 @@ of the result should be stored to memory. @cindex @code{mask_len_scatter_store@var{m}@var{n}} instruction pattern @item @samp{mask_len_scatter_store@var{m}@var{n}} -Like @samp{scatter_store@var{m}@var{n}}, but takes an extra length operand (operand 5), -a bias operand (operand 6) as well as a mask operand (operand 7). The instruction stores -at most (operand 5 + operand 6) elements of (operand 4) to memory. +Like @samp{scatter_store@var{m}@var{n}}, but takes an extra mask operand (operand 5), +a len operand (operand 6) as well as a bias operand (operand 7). The instruction stores +at most (operand 6 + operand 7) elements of (operand 4) to memory. Bit @var{i} of the mask is set if element @var{i} of (operand 4) should be stored. -Mask elements @var{i} with @var{i} > (operand 5 + operand 6) are ignored. +Mask elements @var{i} with @var{i} > (operand 6 + operand 7) are ignored. @cindex @code{vec_set@var{m}} instruction pattern @item @samp{vec_set@var{m}} @@ -5324,15 +5324,15 @@ This pattern is not allowed to @code{FAIL}. @cindex @code{mask_len_load@var{m}@var{n}} instruction pattern @item @samp{mask_len_load@var{m}@var{n}} Perform a masked load from the memory location pointed to by operand 1 -into register operand 0. (operand 2 + operand 3) elements are loaded from +into register operand 0. (operand 3 + operand 4) elements are loaded from memory and other elements in operand 0 are set to undefined values. This is a combination of len_load and maskload. -Operands 0 and 1 have mode @var{m}, which must be a vector mode. Operand 2 +Operands 0 and 1 have mode @var{m}, which must be a vector mode. Operand 3 has whichever integer mode the target prefers. A mask is specified in -operand 4 which must be of type @var{n}. The mask has lower precedence than +operand 2 which must be of type @var{n}. The mask has lower precedence than the length and is itself subject to length masking, -i.e. only mask indices < (operand 2 + operand 3) are used. -Operand 3 conceptually has mode @code{QI}. +i.e. only mask indices < (operand 3 + operand 4) are used. +Operand 4 conceptually has mode @code{QI}. Operand 2 can be a variable or a constant amount. Operand 4 specifies a constant bias: it is either a constant 0 or a constant -1. The predicate on @@ -5351,14 +5351,14 @@ This pattern is not allowed to @code{FAIL}. @cindex @code{mask_len_store@var{m}@var{n}} instruction pattern @item @samp{mask_len_store@var{m}@var{n}} Perform a masked store from vector register operand 1 into memory operand 0. -(operand 2 + operand 3) elements are stored to memory +(operand 3 + operand 4) elements are stored to memory and leave the other elements of operand 0 unchanged. This is a combination of len_store and maskstore. -Operands 0 and 1 have mode @var{m}, which must be a vector mode. Operand 2 has whichever -integer mode the target prefers. A mask is specified in operand 4 which must be +Operands 0 and 1 have mode @var{m}, which must be a vector mode. Operand 3 has whichever +integer mode the target prefers. A mask is specified in operand 2 which must be of type @var{n}. The mask has lower precedence than the length and is itself subject to -length masking, i.e. only mask indices < (operand 2 + operand 3) are used. -Operand 3 conceptually has mode @code{QI}. +length masking, i.e. only mask indices < (operand 3 + operand 4) are used. +Operand 4 conceptually has mode @code{QI}. Operand 2 can be a variable or a constant amount. Operand 3 specifies a constant bias: it is either a constant 0 or a constant -1. The predicate on diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index ad14960..8e29428 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -298,10 +298,10 @@ get_multi_vector_move (tree array_type, convert_optab optab) return convert_optab_handler (optab, imode, vmode); } -/* Add len and mask arguments according to the STMT. */ +/* Add mask and len arguments according to the STMT. */ static unsigned int -add_len_and_mask_args (expand_operand *ops, unsigned int opno, gcall *stmt) +add_mask_and_len_args (expand_operand *ops, unsigned int opno, gcall *stmt) { internal_fn ifn = gimple_call_internal_fn (stmt); int len_index = internal_fn_len_index (ifn); @@ -309,6 +309,13 @@ add_len_and_mask_args (expand_operand *ops, unsigned int opno, gcall *stmt) int bias_index = len_index + 1; int mask_index = internal_fn_mask_index (ifn); /* The order of arguments are always {len,bias,mask}. */ + if (mask_index >= 0) + { + tree mask = gimple_call_arg (stmt, mask_index); + rtx mask_rtx = expand_normal (mask); + create_input_operand (&ops[opno++], mask_rtx, + TYPE_MODE (TREE_TYPE (mask))); + } if (len_index >= 0) { tree len = gimple_call_arg (stmt, len_index); @@ -320,13 +327,6 @@ add_len_and_mask_args (expand_operand *ops, unsigned int opno, gcall *stmt) rtx bias = expand_normal (biast); create_input_operand (&ops[opno++], bias, QImode); } - if (mask_index >= 0) - { - tree mask = gimple_call_arg (stmt, mask_index); - rtx mask_rtx = expand_normal (mask); - create_input_operand (&ops[opno++], mask_rtx, - TYPE_MODE (TREE_TYPE (mask))); - } return opno; } @@ -2944,7 +2944,7 @@ expand_partial_load_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab) target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); create_output_operand (&ops[i++], target, TYPE_MODE (type)); create_fixed_operand (&ops[i++], mem); - i = add_len_and_mask_args (ops, i, stmt); + i = add_mask_and_len_args (ops, i, stmt); expand_insn (icode, i, ops); if (!rtx_equal_p (target, ops[0].value)) @@ -2986,7 +2986,7 @@ expand_partial_store_optab_fn (internal_fn ifn, gcall *stmt, convert_optab optab reg = expand_normal (rhs); create_fixed_operand (&ops[i++], mem); create_input_operand (&ops[i++], reg, TYPE_MODE (type)); - i = add_len_and_mask_args (ops, i, stmt); + i = add_mask_and_len_args (ops, i, stmt); expand_insn (icode, i, ops); } @@ -3579,7 +3579,7 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab) create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset))); create_integer_operand (&ops[i++], scale_int); create_input_operand (&ops[i++], rhs_rtx, TYPE_MODE (TREE_TYPE (rhs))); - i = add_len_and_mask_args (ops, i, stmt); + i = add_mask_and_len_args (ops, i, stmt); insn_code icode = convert_optab_handler (optab, TYPE_MODE (TREE_TYPE (rhs)), TYPE_MODE (TREE_TYPE (offset))); @@ -3608,7 +3608,7 @@ expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab) create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset))); create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset))); create_integer_operand (&ops[i++], scale_int); - i = add_len_and_mask_args (ops, i, stmt); + i = add_mask_and_len_args (ops, i, stmt); insn_code icode = convert_optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs)), TYPE_MODE (TREE_TYPE (offset))); expand_insn (icode, i, ops); @@ -4616,8 +4616,6 @@ internal_fn_len_index (internal_fn fn) { case IFN_LEN_LOAD: case IFN_LEN_STORE: - case IFN_MASK_LEN_LOAD: - case IFN_MASK_LEN_STORE: return 2; case IFN_MASK_LEN_GATHER_LOAD: @@ -4646,6 +4644,8 @@ internal_fn_len_index (internal_fn fn) return 4; case IFN_COND_LEN_NEG: + case IFN_MASK_LEN_LOAD: + case IFN_MASK_LEN_STORE: return 3; default: @@ -4665,12 +4665,12 @@ internal_fn_mask_index (internal_fn fn) case IFN_MASK_LOAD_LANES: case IFN_MASK_STORE: case IFN_MASK_STORE_LANES: + case IFN_MASK_LEN_LOAD: + case IFN_MASK_LEN_STORE: return 2; case IFN_MASK_GATHER_LOAD: case IFN_MASK_SCATTER_STORE: - case IFN_MASK_LEN_LOAD: - case IFN_MASK_LEN_STORE: case IFN_MASK_LEN_GATHER_LOAD: case IFN_MASK_LEN_SCATTER_STORE: return 4; @@ -4755,17 +4755,18 @@ internal_check_ptrs_fn_supported_p (internal_fn ifn, tree type, && insn_operand_matches (icode, 4, GEN_INT (align))); } -/* Return the supported bias for IFN which is either IFN_LEN_LOAD - or IFN_LEN_STORE. For now we only support the biases of 0 and -1 - (in case 0 is not an allowable length for len_load or len_store). - If none of the biases match what the backend provides, return - VECT_PARTIAL_BIAS_UNSUPPORTED. */ +/* Return the supported bias for IFN which is either IFN_{LEN_,MASK_LEN_,}LOAD + or IFN_{LEN_,MASK_LEN_,}STORE. For now we only support the biases of 0 and + -1 (in case 0 is not an allowable length for {len_,mask_len_}load or + {len_,mask_len_}store). If none of the biases match what the backend + provides, return VECT_PARTIAL_BIAS_UNSUPPORTED. */ signed char internal_len_load_store_bias (internal_fn ifn, machine_mode mode) { optab optab = direct_internal_fn_optab (ifn); insn_code icode = direct_optab_handler (optab, mode); + int bias_no = 3; if (icode == CODE_FOR_nothing) { @@ -4783,14 +4784,15 @@ internal_len_load_store_bias (internal_fn ifn, machine_mode mode) optab = direct_internal_fn_optab (IFN_MASK_LEN_STORE); } icode = convert_optab_handler (optab, mode, mask_mode); + bias_no = 4; } if (icode != CODE_FOR_nothing) { /* For now we only support biases of 0 or -1. Try both of them. */ - if (insn_operand_matches (icode, 3, GEN_INT (0))) + if (insn_operand_matches (icode, bias_no, GEN_INT (0))) return 0; - if (insn_operand_matches (icode, 3, GEN_INT (-1))) + if (insn_operand_matches (icode, bias_no, GEN_INT (-1))) return -1; } diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index cebddd4..2555958 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -9089,8 +9089,8 @@ vectorizable_store (vec_info *vinfo, if (partial_ifn == IFN_MASK_LEN_STORE) call = gimple_build_call_internal (IFN_MASK_LEN_STORE, 6, dataref_ptr, ptr, - final_len, bias, - final_mask, vec_oprnd); + final_mask, final_len, + bias, vec_oprnd); else call = gimple_build_call_internal (IFN_LEN_STORE, 5, @@ -10656,8 +10656,8 @@ vectorizable_load (vec_info *vinfo, if (partial_ifn == IFN_MASK_LEN_LOAD) call = gimple_build_call_internal (IFN_MASK_LEN_LOAD, 5, dataref_ptr, - ptr, final_len, - bias, final_mask); + ptr, final_mask, + final_len, bias); else call = gimple_build_call_internal (IFN_LEN_LOAD, 4, dataref_ptr, ptr, -- cgit v1.1 From 3e76bdd5fd289ac38326060bba91b0e264c50ccf Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Fri, 21 Jul 2023 10:23:43 +0800 Subject: cleanup: Change condition order Hi, Richard and Richi. I have double check the recent codes for len && mask support again. Some places code structure: if (len_mask_fn) ... else if (mask_fn) ... some places code structure: if (mask_len_fn) ... else if (mask) Base on previous review comment from Richi: https://gcc.gnu.org/pipermail/gcc-patches/2023-July/625067.html len mask stuff should be checked before mask. So I reorder all condition order to check LEN MASK stuff before MASK. This is the last clean up patch. Boostrap and Regression is on the way. gcc/ChangeLog: * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Change condition order. (vectorizable_operation): Ditto. --- gcc/tree-vect-stmts.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 2555958..ed28fbd 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1635,17 +1635,17 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype, internal_fn len_ifn = (is_load ? IFN_MASK_LEN_GATHER_LOAD : IFN_MASK_LEN_SCATTER_STORE); - if (internal_gather_scatter_fn_supported_p (ifn, vectype, + if (internal_gather_scatter_fn_supported_p (len_ifn, vectype, gs_info->memory_type, gs_info->offset_vectype, gs_info->scale)) - vect_record_loop_mask (loop_vinfo, masks, nvectors, vectype, - scalar_mask); - else if (internal_gather_scatter_fn_supported_p (len_ifn, vectype, + vect_record_loop_len (loop_vinfo, lens, nvectors, vectype, 1); + else if (internal_gather_scatter_fn_supported_p (ifn, vectype, gs_info->memory_type, gs_info->offset_vectype, gs_info->scale)) - vect_record_loop_len (loop_vinfo, lens, nvectors, vectype, 1); + vect_record_loop_mask (loop_vinfo, masks, nvectors, vectype, + scalar_mask); else { if (dump_enabled_p ()) @@ -6598,16 +6598,16 @@ vectorizable_operation (vec_info *vinfo, && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) && mask_out_inactive) { - if (cond_fn != IFN_LAST - && direct_internal_fn_supported_p (cond_fn, vectype, + if (cond_len_fn != IFN_LAST + && direct_internal_fn_supported_p (cond_len_fn, vectype, OPTIMIZE_FOR_SPEED)) - vect_record_loop_mask (loop_vinfo, masks, ncopies * vec_num, - vectype, NULL); - else if (cond_len_fn != IFN_LAST - && direct_internal_fn_supported_p (cond_len_fn, vectype, - OPTIMIZE_FOR_SPEED)) vect_record_loop_len (loop_vinfo, lens, ncopies * vec_num, vectype, 1); + else if (cond_fn != IFN_LAST + && direct_internal_fn_supported_p (cond_fn, vectype, + OPTIMIZE_FOR_SPEED)) + vect_record_loop_mask (loop_vinfo, masks, ncopies * vec_num, + vectype, NULL); else { if (dump_enabled_p ()) -- cgit v1.1 From 1d96b11e4aef1727b3bd3215d0d8140a504d8eb7 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Fri, 21 Jul 2023 17:57:27 +0800 Subject: RISC-V: Fix redundant variable declaration. Notice there is mistake for RISC-V I made in the last patch. Fix it. Sorry about that. gcc/ChangeLog: * config/riscv/riscv-v.cc (expand_gather_scatter): Remove redundant variables. --- gcc/config/riscv/riscv-v.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index eb92451..3157542 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -3212,7 +3212,7 @@ prepare_gather_scatter (machine_mode vec_mode, machine_mode idx_mode, void expand_gather_scatter (rtx *ops, bool is_load) { - rtx ptr, vec_offset, vec_reg, len, mask; + rtx ptr, vec_offset, vec_reg; bool zero_extend_p; int scale_log2; rtx mask = ops[5]; -- cgit v1.1 From 15ec8d5ab5f21997cfa34cdba9f4b2daea40e710 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 13:38:29 +0200 Subject: improfe loop dumps we have flow_loop_dump and print_loop. While print_loop was extended to dump stuff from loop structure we added over years (loop info), flow_loop_dump was not. -fdump-tree-all files contains flow_loop_dump which makes it hard to see what metadata we have attached to loop. This patch unifies dumping of these fields from both functions. For example for: int a[100]; main() { for (int i = 0; i < 10; i++) a[i]=i; } we now print: ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 3 4 5 ;; ;; Loop 1 ;; header 4, latch 3 ;; depth 1, outer 0, finite_p ;; upper_bound 10 ;; likely_upper_bound 10 ;; estimate 10 ;; iterations by profile: 10.001101 (unreliable) finite_p, upper_boud, likely_upper_bound estimate and iterations by profile is new. Bootstrap/regtest on x86_64 in progress. OK if it passes? Honza gcc/ChangeLog: * cfgloop.cc (flow_loop_dump): Use print_loop_info. * cfgloop.h (print_loop_info): Declare. * tree-cfg.cc (print_loop_info): Break out from ...; add printing of missing fields and profile (print_loop): ... here. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/dce-1.c: Update for new loop dumps. --- gcc/cfgloop.cc | 11 ++---- gcc/cfgloop.h | 1 + gcc/testsuite/gcc.dg/tree-ssa/dce-1.c | 4 +- gcc/tree-cfg.cc | 71 ++++++++++++++++++++++++----------- 4 files changed, 56 insertions(+), 31 deletions(-) (limited to 'gcc') diff --git a/gcc/cfgloop.cc b/gcc/cfgloop.cc index 020e573..9ca85e6 100644 --- a/gcc/cfgloop.cc +++ b/gcc/cfgloop.cc @@ -135,17 +135,12 @@ flow_loop_dump (const class loop *loop, FILE *file, fprintf (file, "\n"); } - fprintf (file, ";; depth %d, outer %ld\n", + fprintf (file, ";; depth %d, outer %ld", loop_depth (loop), (long) (loop_outer (loop) ? loop_outer (loop)->num : -1)); + print_loop_info (file, loop, ";; "); - bool reliable; - sreal iterations; - if (loop->num && expected_loop_iterations_by_profile (loop, &iterations, &reliable)) - fprintf (file, ";; profile-based iteration count: %f %s\n", - iterations.to_double (), reliable ? "(reliable)" : "(unreliable)"); - - fprintf (file, ";; nodes:"); + fprintf (file, "\n;; nodes:"); bbs = get_loop_body (loop); for (i = 0; i < loop->num_nodes; i++) fprintf (file, " %d", bbs[i]->index); diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 4d2fd4b6..269694c 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -411,6 +411,7 @@ extern unsigned expected_loop_iterations (class loop *); extern rtx doloop_condition_get (rtx_insn *); void mark_loop_for_removal (loop_p); +void print_loop_info (FILE *file, const class loop *loop, const char *); /* Induction variable analysis. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c b/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c index 42d9407..91c3bcd 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c @@ -13,6 +13,6 @@ int foo (int b, int j) } /* Check that empty loop is eliminated in this case. We should no longer have the exit condition after the loop. */ -/* { dg-final { scan-tree-dump-not "999" "cddce1"} } */ -/* { dg-final { scan-tree-dump-not "1000" "cddce1"} } */ +/* { dg-final { scan-tree-dump-not "999)" "cddce1"} } */ +/* { dg-final { scan-tree-dump-not "1000)" "cddce1"} } */ diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 7ccc2a5..a6c97a0 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -8479,6 +8479,55 @@ print_loops_bb (FILE *file, basic_block bb, int indent, int verbosity) } } +/* Print loop information. */ + +void +print_loop_info (FILE *file, const class loop *loop, const char *prefix) +{ + if (loop->can_be_parallel) + fprintf (file, ", can_be_parallel"); + if (loop->warned_aggressive_loop_optimizations) + fprintf (file, ", warned_aggressive_loop_optimizations"); + if (loop->dont_vectorize) + fprintf (file, ", dont_vectorize"); + if (loop->force_vectorize) + fprintf (file, ", force_vectorize"); + if (loop->in_oacc_kernels_region) + fprintf (file, ", in_oacc_kernels_region"); + if (loop->finite_p) + fprintf (file, ", finite_p"); + if (loop->unroll) + fprintf (file, "\n%sunroll %d", prefix, loop->unroll); + if (loop->nb_iterations) + { + fprintf (file, "\n%sniter ", prefix); + print_generic_expr (file, loop->nb_iterations); + } + + if (loop->any_upper_bound) + { + fprintf (file, "\n%supper_bound ", prefix); + print_decu (loop->nb_iterations_upper_bound, file); + } + if (loop->any_likely_upper_bound) + { + fprintf (file, "\n%slikely_upper_bound ", prefix); + print_decu (loop->nb_iterations_likely_upper_bound, file); + } + + if (loop->any_estimate) + { + fprintf (file, "\n%sestimate ", prefix); + print_decu (loop->nb_iterations_estimate, file); + } + bool reliable; + sreal iterations; + if (loop->num && expected_loop_iterations_by_profile (loop, &iterations, &reliable)) + fprintf (file, "\n%siterations by profile: %f %s", prefix, + iterations.to_double (), reliable ? "(reliable)" : "(unreliable)"); + +} + static void print_loop_and_siblings (FILE *, class loop *, int, int); /* Pretty print LOOP on FILE, indented INDENT spaces. Following @@ -8511,27 +8560,7 @@ print_loop (FILE *file, class loop *loop, int indent, int verbosity) fprintf (file, ", latch = %d", loop->latch->index); else fprintf (file, ", multiple latches"); - fprintf (file, ", niter = "); - print_generic_expr (file, loop->nb_iterations); - - if (loop->any_upper_bound) - { - fprintf (file, ", upper_bound = "); - print_decu (loop->nb_iterations_upper_bound, file); - } - if (loop->any_likely_upper_bound) - { - fprintf (file, ", likely_upper_bound = "); - print_decu (loop->nb_iterations_likely_upper_bound, file); - } - - if (loop->any_estimate) - { - fprintf (file, ", estimate = "); - print_decu (loop->nb_iterations_estimate, file); - } - if (loop->unroll) - fprintf (file, ", unroll = %d", loop->unroll); + print_loop_info (file, loop, s_indent); fprintf (file, ")\n"); /* Print loop's body. */ -- cgit v1.1 From 3038d598529d612391728b1895c21954ddb24306 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 13:57:34 +0200 Subject: finite_loop_p tweak We have finite_p flag in loop structure. finite_loop_p already know to use it, but we also may set the flag when we prove loop to be finite by SCEV analysis to avoid duplicated work. Bootstrapped/regtested x86_64-linux, OK? gcc/ChangeLog: * tree-ssa-loop-niter.cc (finite_loop_p): Reorder to do cheap tests first; update finite_p flag. --- gcc/tree-ssa-loop-niter.cc | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 3c4e662..a806801 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -3338,24 +3338,6 @@ finite_loop_p (class loop *loop) widest_int nit; int flags; - flags = flags_from_decl_or_type (current_function_decl); - if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Found loop %i to be finite: it is within pure or const function.\n", - loop->num); - return true; - } - - if (loop->any_upper_bound - || max_loop_iterations (loop, &nit)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Found loop %i to be finite: upper bound found.\n", - loop->num); - return true; - } - if (loop->finite_p) { unsigned i; @@ -3368,11 +3350,36 @@ finite_loop_p (class loop *loop) { if (dump_file) fprintf (dump_file, "Assume loop %i to be finite: it has an exit " - "and -ffinite-loops is on.\n", loop->num); + "and -ffinite-loops is on or loop was " + "previously finite.\n", + loop->num); return true; } } + flags = flags_from_decl_or_type (current_function_decl); + if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Found loop %i to be finite: it is within " + "pure or const function.\n", + loop->num); + loop->finite_p = true; + return true; + } + + if (loop->any_upper_bound + /* Loop with no normal exit will not pass max_loop_iterations. */ + || (!loop->finite_p && max_loop_iterations (loop, &nit))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Found loop %i to be finite: upper bound found.\n", + loop->num); + loop->finite_p = true; + return true; + } + return false; } -- cgit v1.1 From 8cbdb2e4d64461d8a19e033bd33b585187059d8a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 21 Jul 2023 13:55:43 +0200 Subject: tree-optimization/41320 - remove bogus XFAILed testcase gcc.dg/tree-ssa/forwprop-12.c looks for reconstruction of an ARRAY_REF from pointer arithmetic and dereference. That's not safe because ARRAY_REFs carry special semantics we later exploit during data dependence analysis. The following removes the testcase, closing the bug as WONTFIX. PR tree-optimization/41320 * gcc.dg/tree-ssa/forwprop-12.c: Remove. --- gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c deleted file mode 100644 index de16c68..0000000 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c +++ /dev/null @@ -1,21 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O -fdump-tree-forwprop1" } */ - -struct X { int a[256]; }; - -int foo(struct X *p, __SIZE_TYPE__ i) -{ - int *q = &p->a[0]; - int *q2 = (int *)((void *)q + i*4 + 32); - return *q2; -} - -int bar(struct X *p, int i) -{ - return *((int *)p + i + 8); -} - -/* We should have propagated the base array address through the - address arithmetic into the memory access as an array access. */ - -/* { dg-final { scan-tree-dump-times "->a\\\[D\\\." 2 "forwprop1" { xfail *-*-* } } } */ -- cgit v1.1 From 65ff4a45b11b5ab13ef849bd5721ab28ff316202 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 14:54:23 +0200 Subject: loop-ch improvements, part 5 Currently loop-ch skips all do-while loops. But when loop is not do-while in addition to original goal of turining it to do-while it can do additional things: 1) move out loop invariant computations 2) duplicate loop invariant conditionals and eliminate them in loop body. 3) prove that some exits are always true in first iteration and can be skipped Most of time 1 can be done by lim (exception is when the invariant computation is conditional). For 2 we however don't really have other place doing it except for loop unswitching that is more expensive (it will duplicate the loop and then optimize out one path to non-loop). 3 can be done by loop peeling but it is also more expensive by duplicating full loop body. This patch improves heuristics by not giving up on do-while loops and trying to find sequence of BBs to duplicate to obtain one of goals: - turn loop to do-while - eliminate invariant conditional in loop body - do partial "peeling" as long as code optimizes enough so this does not increase code size. Bootstrapped/regtested x86_64-linux, OK? gcc/ChangeLog: * tree-ssa-loop-ch.cc (enum ch_decision): New enum. (should_duplicate_loop_header_p): Return info on profitability. (do_while_loop_p): Watch for constant conditionals. (update_profile_after_ch): Do not sanity check that all static exits are taken. (ch_base::copy_headers): Run on all loops. (pass_ch::process_loop_p): Improve heuristics by handling also do_while loop and duplicating shortest sequence containing all winning blocks. gcc/testsuite/ChangeLog: * gcc.dg/loop-unswitch-17.c: Disable ch. * gcc.dg/pr103079.c: Disable ch. * gcc.dg/tree-ssa/copy-headers-7.c: Update so ch behaves as expected. * gcc.dg/tree-ssa/copy-headers.c: Update template. * gcc.dg/tree-ssa/copy-headers-9.c: New test. --- gcc/testsuite/gcc.dg/loop-unswitch-17.c | 2 +- gcc/testsuite/gcc.dg/pr103079.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c | 3 +- gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c | 20 ++++ gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c | 2 +- gcc/tree-ssa-loop-ch.cc | 147 +++++++++++++++++++------ 6 files changed, 136 insertions(+), 40 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-17.c b/gcc/testsuite/gcc.dg/loop-unswitch-17.c index 8655e09..4b806c4 100644 --- a/gcc/testsuite/gcc.dg/loop-unswitch-17.c +++ b/gcc/testsuite/gcc.dg/loop-unswitch-17.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized -fno-tree-ch" } */ int foo (int a) { diff --git a/gcc/testsuite/gcc.dg/pr103079.c b/gcc/testsuite/gcc.dg/pr103079.c index 7f6632f..7b10754 100644 --- a/gcc/testsuite/gcc.dg/pr103079.c +++ b/gcc/testsuite/gcc.dg/pr103079.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Os -fdump-tree-vrp2" } */ +/* { dg-options "-Os -fdump-tree-vrp2 -fno-tree-ch" } */ int a, b = -2; int main() { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c index e2a6c75..b3df3b6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c @@ -4,7 +4,7 @@ int is_sorted(int *a, int n, int m, int k) { if (k > 0) - for (int i = 0; i < n - 1 && m && k > i; i++) + for (int i = 0; k > i && m && i < n - 1 ; i++) if (a[i] > a[i + 1]) return 0; return 1; @@ -17,5 +17,4 @@ int is_sorted(int *a, int n, int m, int k) /* { dg-final { scan-tree-dump-times "Conditional combines static and invariant" 0 "ch2" } } */ /* { dg-final { scan-tree-dump-times "Will elliminate invariant exit" 1 "ch2" } } */ /* { dg-final { scan-tree-dump-times "Will eliminate peeled conditional" 1 "ch2" } } */ -/* { dg-final { scan-tree-dump-times "Not duplicating bb .: condition based on non-IV loop variant." 1 "ch2" } } */ /* { dg-final { scan-tree-dump-times "Will duplicate bb" 3 "ch2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c new file mode 100644 index 0000000..7cc162c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ch-details" } */ +int a[100]; +void test (int m, int n) +{ + int i = 0; + do + { + if (m) + break; + i++; + a[i]=0; + } + while (i<10); +} +/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win" 1 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "May duplicate bb" 1 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Duplicating additional BB to obtain do-while loop" 1 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Will duplicate bb" 2 "ch2" } } */ +/* { dg-final { scan-tree-dump "is now do-while loop" "ch2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c index a5a8212..f4f2b2a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c @@ -12,4 +12,4 @@ void bla (void) } /* There should be a header duplicated. */ -/* { dg-final { scan-tree-dump-times "Duplicating header" 1 "ch2"} } */ +/* { dg-final { scan-tree-dump-times "Duplicating header of the" 1 "ch2"} } */ diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index a87ebc5..6cdb87a 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -168,11 +168,28 @@ loop_combined_static_and_iv_p (class loop *loop, return gimple_uid (SSA_NAME_DEF_STMT (op)) & 4; } +/* Decision about posibility of copying a given header. */ + +enum ch_decision +{ + /* We do not want to copy this header. */ + ch_impossible, + /* We can copy it if it enables wins. */ + ch_possible, + /* We can "cop" it if it enables wins and doing + so will introduce no new code. */ + ch_possible_zero_cost, + /* We want to copy. */ + ch_win, + /* We want to copy and we will eliminate loop exit. */ + ch_win_invariant_exit +}; + /* Check whether we should duplicate HEADER of LOOP. At most *LIMIT instructions should be duplicated, limit is decreased by the actual amount. */ -static bool +static ch_decision should_duplicate_loop_header_p (basic_block header, class loop *loop, gimple_ranger *ranger, int *limit, @@ -190,7 +207,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, fprintf (dump_file, " Not duplicating bb %i: it is single succ.\n", header->index); - return false; + return ch_impossible; } if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest) @@ -200,7 +217,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, fprintf (dump_file, " Not duplicating bb %i: both successors are in loop.\n", loop->num); - return false; + return ch_impossible; } /* If this is not the original loop header, we want it to have just @@ -211,7 +228,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, fprintf (dump_file, " Not duplicating bb %i: it has mutiple predecestors.\n", header->index); - return false; + return ch_impossible; } gcond *last = safe_dyn_cast (*gsi_last_bb (header)); @@ -221,7 +238,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, fprintf (dump_file, " Not duplicating bb %i: it does not end by conditional.\n", header->index); - return false; + return ch_impossible; } path_range_query *query = NULL; @@ -233,6 +250,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, query, psi.phi ()); gimple_set_uid (psi.phi (), static_p ? 2 : 0); } + bool code_size_cost = false; /* Count number of instructions and punt on calls. Populate stmts INV flag to later apply heuristics to the @@ -268,7 +286,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, header->index); if (query) delete query; - return false; + return ch_impossible; } /* Classify the stmt is invariant in the loop. */ @@ -343,6 +361,8 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, int insns = estimate_num_insns (last, &eni_size_weights); *limit -= insns; + if (insns) + code_size_cost = true; if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Acconting stmt as %i insns\n", insns); @@ -354,7 +374,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, header->index); if (query) delete query; - return false; + return ch_impossible; } } @@ -403,7 +423,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Conditional combines static and invariant op.\n"); - return true; + return ch_win; } edge static_exit = static_loop_exit (loop, header, *ranger, query); @@ -435,11 +455,16 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, invariant_exits->add (e); } } - return true; + return ch_win_invariant_exit; } + /* If the static exit fully optimize out, it is win to "duplicate" + it. + + TODO: Even if duplication costs some size we may opt to do so in case + exit probability is significant enough (do partial peeling). */ if (static_exit) - return true; + return code_size_cost ? ch_possible_zero_cost : ch_win; /* We was not able to prove that conditional will be eliminated. */ int insns = estimate_num_insns (last, &eni_size_weights); @@ -453,19 +478,10 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, fprintf (dump_file, " Not duplicating bb %i contains too many insns.\n", header->index); - return false; - } - - if (header != loop->header) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " Not duplicating bb %i: condition based on non-IV loop" - " variant.\n", header->index); - return false; + return ch_impossible; } - return true; + return ch_possible; } /* Checks whether LOOP is a do-while style loop. */ @@ -496,10 +512,11 @@ do_while_loop_p (class loop *loop) "predecessors.\n", loop->num); return false; } + basic_block pred = single_pred (loop->latch); /* If the latch predecessor doesn't exit the loop, it is not a do-while loop. */ - if (!loop_exits_from_bb_p (loop, single_pred (loop->latch))) + if (!loop_exits_from_bb_p (loop, pred)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, @@ -507,6 +524,18 @@ do_while_loop_p (class loop *loop) "does not exit loop.\n", loop->num); return false; } + gcond *last = safe_dyn_cast (*gsi_last_bb (pred)); + if (last + && (gimple_cond_lhs (last) == boolean_false_node + || gimple_cond_lhs (last) == boolean_true_node) + && gimple_cond_rhs (last) == boolean_false_node) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Loop %i is not do-while loop: latch predecessor " + "contains exit we optimized out.\n", loop->num); + return false; + } if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Loop %i is do-while loop\n", loop->num); @@ -634,9 +663,9 @@ update_profile_after_ch (class loop *loop, } entry_count = e_copy->count (); } - /* Be sure that we seen all edges we are supposed to update. */ - gcc_checking_assert (static_exits->is_empty () - && invariant_exits->is_empty ()); + /* Be sure that we seen all invariant exit edges we are supposed to update. + We may have recorded some static exists we decided to not duplicate. */ + gcc_checking_assert (invariant_exits->is_empty ()); } namespace { @@ -792,16 +821,43 @@ ch_base::copy_headers (function *fun) the header to have just a single successor and copying up to postdominator. */ int nheaders = 0; + int last_win_nheaders = 0; + bool last_win_invariant_exit = false; + ch_decision ret; hash_set *invariant_exits = new hash_set ; hash_set *static_exits = new hash_set ; - while (should_duplicate_loop_header_p (header, loop, ranger, - &remaining_limit, - invariant_exits, - static_exits)) + while ((ret = should_duplicate_loop_header_p (header, loop, ranger, + &remaining_limit, + invariant_exits, + static_exits)) + != ch_impossible) { nheaders++; - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Will duplicate bb %i\n", header->index); + if (ret >= ch_win) + { + last_win_nheaders = nheaders; + last_win_invariant_exit = (ret == ch_win_invariant_exit); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Duplicating bb %i is a win\n", + header->index); + } + /* Duplicate BB if has zero cost but be sure it will not + imply duplication of other BBs. */ + else if (ret == ch_possible_zero_cost + && (last_win_nheaders == nheaders - 1 + || (last_win_nheaders == nheaders - 2 + && last_win_invariant_exit))) + { + last_win_nheaders = nheaders; + last_win_invariant_exit = false; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Duplicating bb %i is a win; it has zero cost\n", + header->index); + } + else + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " May duplicate bb %i\n", header->index); /* Find a successor of header that is inside a loop; i.e. the new header after the condition is copied. */ @@ -811,8 +867,27 @@ ch_base::copy_headers (function *fun) header = EDGE_SUCC (header, 1)->dest; } - if (nheaders) - candidates.safe_push ({loop, nheaders, invariant_exits, static_exits}); + /* Try to turn loop into do-while. This means ensuring that + last duplicated header will not have loop invariant exit. */ + if (last_win_nheaders && last_win_invariant_exit + && nheaders > last_win_nheaders) + { + last_win_nheaders++; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Duplicating additional BB to obtain do-while loop\n"); + } + else if (!last_win_nheaders && nheaders && !do_while_loop_p (loop)) + { + last_win_nheaders = 1; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Duplicating header BB to obtain do-while loop\n"); + } + + if (last_win_nheaders) + candidates.safe_push ({loop, last_win_nheaders, + invariant_exits, static_exits}); else { delete invariant_exits; @@ -844,6 +919,8 @@ ch_base::copy_headers (function *fun) entry_count += e->count (); while (n_bbs < candidate.nheaders) { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Will duplicate bb %i\n", header->index); /* Find a successor of header that is inside a loop; i.e. the new header after the condition is copied. */ if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)) @@ -1111,9 +1188,9 @@ pass_ch_vect::execute (function *fun) /* Apply header copying according to a very simple test of do-while shape. */ bool -pass_ch::process_loop_p (class loop *loop) +pass_ch::process_loop_p (class loop *) { - return !do_while_loop_p (loop); + return true; } /* Apply header-copying to loops where we might enable vectorization. */ -- cgit v1.1 From e35d297fc9a625f11d861b6feacb228810e4e6bd Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 16:44:01 +0200 Subject: Fix sreal::to_int and implement sreal::to_nearest_int while exploring new loop estimate dumps, I noticed that loop iterating 1.8 times by profile is etimated as iterating once instead of 2 by nb_estimate. While nb_estimate should really be a sreal and I will convert it incrementally, I found problem is in previous patch doing: + *nit = (snit + 0.5).to_int (); this does not work for sreal because it has only constructor from integer, so first 0.5 is rounded to 0 and then added to snit. Some code uses sreal(1, -1) which produces 0.5, but it reuqires unnecessary addition, so I decided to add to_nearest_int. Testing it I noticed that to_int is buggy: (sreal(3)/2).to_int () == 1 while (sreal(-3)/2).to_int () == -2 Fix is easy, we need to correctly shift in positive values. This patch fixes it and adds the to_nearest_int alternative. gcc/ChangeLog: * sreal.cc (sreal::to_nearest_int): New. (sreal_verify_basics): Verify also to_nearest_int. (verify_aritmetics): Likewise. (sreal_verify_conversions): New. (sreal_cc_tests): Call sreal_verify_conversions. * sreal.h: (sreal::to_nearest_int): Declare --- gcc/sreal.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- gcc/sreal.h | 1 + 2 files changed, 55 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/sreal.cc b/gcc/sreal.cc index 8e99d87..606a571 100644 --- a/gcc/sreal.cc +++ b/gcc/sreal.cc @@ -116,7 +116,26 @@ sreal::to_int () const if (m_exp > 0) return sign * (SREAL_ABS ((int64_t)m_sig) << m_exp); if (m_exp < 0) - return m_sig >> -m_exp; + return sign * (SREAL_ABS ((int64_t)m_sig) >> -m_exp); + return m_sig; +} + +/* Return nearest integer value of *this. */ + +int64_t +sreal::to_nearest_int () const +{ + int64_t sign = SREAL_SIGN (m_sig); + + if (m_exp <= -SREAL_BITS) + return 0; + if (m_exp >= SREAL_PART_BITS) + return sign * INTTYPE_MAXIMUM (int64_t); + if (m_exp > 0) + return sign * (SREAL_ABS ((int64_t)m_sig) << m_exp); + if (m_exp < 0) + return sign * ((SREAL_ABS ((int64_t)m_sig) >> -m_exp) + + ((SREAL_ABS (m_sig) >> (-m_exp - 1)) & 1)); return m_sig; } @@ -286,6 +305,8 @@ sreal_verify_basics (void) ASSERT_EQ (INT_MIN/2, minimum.to_int ()); ASSERT_EQ (INT_MAX/2, maximum.to_int ()); + ASSERT_EQ (INT_MIN/2, minimum.to_nearest_int ()); + ASSERT_EQ (INT_MAX/2, maximum.to_nearest_int ()); ASSERT_FALSE (minus_two < minus_two); ASSERT_FALSE (seven < seven); @@ -315,6 +336,10 @@ verify_aritmetics (int64_t a, int64_t b) ASSERT_EQ (a - b, (sreal (a) - sreal (b)).to_int ()); ASSERT_EQ (b + a, (sreal (b) + sreal (a)).to_int ()); ASSERT_EQ (b - a, (sreal (b) - sreal (a)).to_int ()); + ASSERT_EQ (a + b, (sreal (a) + sreal (b)).to_nearest_int ()); + ASSERT_EQ (a - b, (sreal (a) - sreal (b)).to_nearest_int ()); + ASSERT_EQ (b + a, (sreal (b) + sreal (a)).to_nearest_int ()); + ASSERT_EQ (b - a, (sreal (b) - sreal (a)).to_nearest_int ()); } /* Verify arithmetics for interesting numbers. */ @@ -377,6 +402,33 @@ sreal_verify_negative_division (void) ASSERT_EQ (sreal (1234567) / sreal (-1234567), sreal (-1)); } +static void +sreal_verify_conversions (void) +{ + ASSERT_EQ ((sreal (11) / sreal (3)).to_int (), 3); + ASSERT_EQ ((sreal (11) / sreal (3)).to_nearest_int (), 4); + ASSERT_EQ ((sreal (10) / sreal (3)).to_int (), 3); + ASSERT_EQ ((sreal (10) / sreal (3)).to_nearest_int (), 3); + ASSERT_EQ ((sreal (9) / sreal (3)).to_int (), 3); + ASSERT_EQ ((sreal (9) / sreal (3)).to_nearest_int (), 3); + ASSERT_EQ ((sreal (-11) / sreal (3)).to_int (), -3); + ASSERT_EQ ((sreal (-11) / sreal (3)).to_nearest_int (), -4); + ASSERT_EQ ((sreal (-10) / sreal (3)).to_int (), -3); + ASSERT_EQ ((sreal (-10) / sreal (3)).to_nearest_int (), -3); + ASSERT_EQ ((sreal (-3)).to_int (), -3); + ASSERT_EQ ((sreal (-3)).to_nearest_int (), -3); + for (int i = -100000 ; i < 100000; i += 123) + for (int j = -10000 ; j < 100000; j += 71) + if (j != 0) + { + sreal sval = ((sreal)i) / (sreal)j; + double val = (double)i / (double)j; + ASSERT_EQ ((fabs (sval.to_double () - val) < 0.00001), true); + ASSERT_EQ (sval.to_int (), (int)val); + ASSERT_EQ (sval.to_nearest_int (), lround (val)); + } +} + /* Run all of the selftests within this file. */ void sreal_cc_tests () @@ -385,6 +437,7 @@ void sreal_cc_tests () sreal_verify_arithmetics (); sreal_verify_shifting (); sreal_verify_negative_division (); + sreal_verify_conversions (); } } // namespace selftest diff --git a/gcc/sreal.h b/gcc/sreal.h index 8700807..4dbb83c 100644 --- a/gcc/sreal.h +++ b/gcc/sreal.h @@ -51,6 +51,7 @@ public: void dump (FILE *) const; int64_t to_int () const; + int64_t to_nearest_int () const; double to_double () const; void stream_out (struct output_block *); static sreal stream_in (class lto_input_block *); -- cgit v1.1 From fc92f5811e77b091d65045f2daa0f83c31d00797 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Thu, 20 Jul 2023 16:37:21 +0100 Subject: Darwin: Handle linker '-demangle' option. Most of the Darwin linkers in use support this option which we will now pass by default (matching the Xcode clang impl.)> Signed-off-by: Iain Sandoe gcc/ChangeLog: * config.in: Regenerate. * config/darwin.h (DARWIN_LD_DEMANGLE): New. (LINK_COMMAND_SPEC_A): Add demangle handling. * configure: Regenerate. * configure.ac: Detect linker support for '-demangle'. --- gcc/config.in | 9 ++++++++- gcc/config/darwin.h | 7 +++++++ gcc/configure | 19 +++++++++++++++++++ gcc/configure.ac | 14 ++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config.in b/gcc/config.in index 0e62b9f..5cf51bc 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -2178,6 +2178,12 @@ #endif +/* Define to 1 if ld64 supports '-demangle'. */ +#ifndef USED_FOR_TARGET +#undef LD64_HAS_DEMANGLE +#endif + + /* Define to 1 if ld64 supports '-export_dynamic'. */ #ifndef USED_FOR_TARGET #undef LD64_HAS_EXPORT_DYNAMIC @@ -2239,7 +2245,8 @@ #endif -/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ #ifndef USED_FOR_TARGET #undef LT_OBJDIR #endif diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index 1b538c7..e0e8672 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -270,6 +270,12 @@ extern GTY(()) int darwin_ms_struct; "%&6; } gcc_cv_ld64_major=`echo "$gcc_cv_ld64_version" | sed -e 's/\..*//'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_major" >&5 $as_echo "$gcc_cv_ld64_major" >&6; } + if test "$gcc_cv_ld64_major" -ge 97; then + gcc_cv_ld64_demangle=1 + fi if test "$gcc_cv_ld64_major" -ge 236; then gcc_cv_ld64_export_dynamic=1 fi @@ -30517,6 +30521,15 @@ $as_echo_n "checking linker version... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_version" >&5 $as_echo "$gcc_cv_ld64_version" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for -demangle support" >&5 +$as_echo_n "checking linker for -demangle support... " >&6; } + gcc_cv_ld64_demangle=1 + if $gcc_cv_ld -demangle < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then + gcc_cv_ld64_demangle=0 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_demangle" >&5 +$as_echo "$gcc_cv_ld64_demangle" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for -export_dynamic support" >&5 $as_echo_n "checking linker for -export_dynamic support... " >&6; } gcc_cv_ld64_export_dynamic=1 @@ -30546,6 +30559,12 @@ _ACEOF cat >>confdefs.h <<_ACEOF +#define LD64_HAS_DEMANGLE $gcc_cv_ld64_demangle +_ACEOF + + + +cat >>confdefs.h <<_ACEOF #define LD64_HAS_EXPORT_DYNAMIC $gcc_cv_ld64_export_dynamic _ACEOF diff --git a/gcc/configure.ac b/gcc/configure.ac index e91073b..46e58a2 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -6211,6 +6211,7 @@ if test x"$ld64_flag" = x"yes"; then # Set defaults for possibly untestable items. gcc_cv_ld64_export_dynamic=0 gcc_cv_ld64_platform_version=0 + gcc_cv_ld64_demangle=0 if test "$build" = "$host"; then darwin_try_test=1 @@ -6232,6 +6233,9 @@ if test x"$ld64_flag" = x"yes"; then AC_MSG_CHECKING(ld64 specified version) gcc_cv_ld64_major=`echo "$gcc_cv_ld64_version" | sed -e 's/\..*//'` AC_MSG_RESULT($gcc_cv_ld64_major) + if test "$gcc_cv_ld64_major" -ge 97; then + gcc_cv_ld64_demangle=1 + fi if test "$gcc_cv_ld64_major" -ge 236; then gcc_cv_ld64_export_dynamic=1 fi @@ -6246,6 +6250,13 @@ if test x"$ld64_flag" = x"yes"; then fi AC_MSG_RESULT($gcc_cv_ld64_version) + AC_MSG_CHECKING(linker for -demangle support) + gcc_cv_ld64_demangle=1 + if $gcc_cv_ld -demangle < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then + gcc_cv_ld64_demangle=0 + fi + AC_MSG_RESULT($gcc_cv_ld64_demangle) + AC_MSG_CHECKING(linker for -export_dynamic support) gcc_cv_ld64_export_dynamic=1 if $gcc_cv_ld -export_dynamic < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then @@ -6266,6 +6277,9 @@ if test x"$ld64_flag" = x"yes"; then [Define to ld64 version.]) fi + AC_DEFINE_UNQUOTED(LD64_HAS_DEMANGLE, $gcc_cv_ld64_demangle, + [Define to 1 if ld64 supports '-demangle'.]) + AC_DEFINE_UNQUOTED(LD64_HAS_EXPORT_DYNAMIC, $gcc_cv_ld64_export_dynamic, [Define to 1 if ld64 supports '-export_dynamic'.]) -- cgit v1.1 From feeee84079ee165f13f9fb8cdcf5dcea98d394e0 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 16:50:49 +0200 Subject: Use sreal::nearest_int Fix conversions from sreal to nearest integer. gcc/ChangeLog: * cfgloop.cc (get_estimated_loop_iterations): Use sreal::to_nearest_int * cfgloopanal.cc (expected_loop_iterations_unbounded): Likewise. * predict.cc (estimate_bb_frequencies): Likewise. * profile.cc (branch_prob): Likewise. * tree-ssa-loop-niter.cc (estimate_numbers_of_iterations): Likewise --- gcc/cfgloop.cc | 2 +- gcc/cfgloopanal.cc | 2 +- gcc/predict.cc | 4 ++-- gcc/profile.cc | 2 +- gcc/tree-ssa-loop-niter.cc | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/cfgloop.cc b/gcc/cfgloop.cc index 9ca85e6..6d46b5b 100644 --- a/gcc/cfgloop.cc +++ b/gcc/cfgloop.cc @@ -2012,7 +2012,7 @@ get_estimated_loop_iterations (class loop *loop, widest_int *nit) if (expected_loop_iterations_by_profile (loop, &snit, &reliable) && reliable) { - *nit = (snit + 0.5).to_int (); + *nit = snit.to_nearest_int (); return true; } return false; diff --git a/gcc/cfgloopanal.cc b/gcc/cfgloopanal.cc index 2bf2eb0..c86a537 100644 --- a/gcc/cfgloopanal.cc +++ b/gcc/cfgloopanal.cc @@ -321,7 +321,7 @@ expected_loop_iterations_unbounded (const class loop *loop, sreal sreal_expected; if (expected_loop_iterations_by_profile (loop, &sreal_expected, read_profile_p)) - expected = (sreal_expected + 0.5).to_int (); + expected = sreal_expected.to_nearest_int (); else expected = param_avg_loop_niter; diff --git a/gcc/predict.cc b/gcc/predict.cc index 8f44f5b..6777e6c 100644 --- a/gcc/predict.cc +++ b/gcc/predict.cc @@ -4003,8 +4003,8 @@ estimate_bb_frequencies () break; } } - tmp = tmp * freq_max + sreal (1, -1); - profile_count count = profile_count::from_gcov_type (tmp.to_int ()); + tmp = tmp * freq_max; + profile_count count = profile_count::from_gcov_type (tmp.to_nearest_int ()); /* If we have profile feedback in which this function was never executed, then preserve this info. */ diff --git a/gcc/profile.cc b/gcc/profile.cc index 84d47b3..fc59326 100644 --- a/gcc/profile.cc +++ b/gcc/profile.cc @@ -1553,7 +1553,7 @@ branch_prob (bool thunk) && expected_loop_iterations_by_profile (loop, &nit, &reliable) && reliable) { - widest_int bound = (nit + 0.5).to_int (); + widest_int bound = nit.to_nearest_int (); loop->any_estimate = false; record_niter_bound (loop, bound, true, false); } diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index a806801..705bcc0 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -4801,7 +4801,7 @@ estimate_numbers_of_iterations (class loop *loop) && expected_loop_iterations_by_profile (loop, &nit, &reliable) && reliable) { - bound = (nit + 0.5).to_int (); + bound = nit.to_nearest_int (); record_niter_bound (loop, bound, true, false); } -- cgit v1.1 From 3291f9e6cba2ea6a170ba4fc7ddbb57218d3f9f6 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 17:31:34 +0200 Subject: Fix gcc.dg/tree-ssa/copy-headers-9.c and gcc.dg/tree-ssa/dce-1.c failures This patch fixes template in the two testcases so it matches the output correctly. I did not re-test after last changes in the previous patch, sorry for that. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/copy-headers-9.c: Fix template for tree-ssa-loop-ch.cc changes. * gcc.dg/tree-ssa/dce-1.c: Likewise. --- gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c | 5 ++--- gcc/testsuite/gcc.dg/tree-ssa/dce-1.c | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c index 7cc162c..b49d1fc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c @@ -13,8 +13,7 @@ void test (int m, int n) } while (i<10); } -/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win" 1 "ch2" } } */ -/* { dg-final { scan-tree-dump-times "May duplicate bb" 1 "ch2" } } */ -/* { dg-final { scan-tree-dump-times "Duplicating additional BB to obtain do-while loop" 1 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win" 2 "ch2" } } */ +/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win. it has zero" 1 "ch2" } } */ /* { dg-final { scan-tree-dump-times "Will duplicate bb" 2 "ch2" } } */ /* { dg-final { scan-tree-dump "is now do-while loop" "ch2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c b/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c index 91c3bcd..3ebfa98 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/dce-1.c @@ -13,6 +13,6 @@ int foo (int b, int j) } /* Check that empty loop is eliminated in this case. We should no longer have the exit condition after the loop. */ -/* { dg-final { scan-tree-dump-not "999)" "cddce1"} } */ -/* { dg-final { scan-tree-dump-not "1000)" "cddce1"} } */ +/* { dg-final { scan-tree-dump-not "999\\)" "cddce1"} } */ +/* { dg-final { scan-tree-dump-not "1000\\)" "cddce1"} } */ -- cgit v1.1 From ea272814c23d2b88dc846b225c041594ae6be3e3 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 17:34:31 +0200 Subject: Implement flat loop profile detection This patch adds maybe_flat_loop_profile which can be used in loop profile udpate to detect situation where the profile may be unrealistically flat and should not be dwonscalled after vectorizing, unrolling and other transforms that assume that loop has high iteration count even if the CFG profile says otherwise. Profile is flat if it was statically detected and at that time we had no idea about actual number of iterations or we artificially capped them. So the function considers flat all profiles that have guessed or lower reliability in their count and there is no nb_iteration_bounds/estimate which would prove that the profile iteration count is high enough. gcc/ChangeLog: * cfgloop.h (maybe_flat_loop_profile): Declare * cfgloopanal.cc (maybe_flat_loop_profile): New function. * tree-cfg.cc (print_loop_info): Print info about flat profiles. --- gcc/cfgloop.h | 1 + gcc/cfgloopanal.cc | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree-cfg.cc | 7 +++++-- 3 files changed, 67 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 269694c..22293e1 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -407,6 +407,7 @@ gcov_type expected_loop_iterations_unbounded (const class loop *, extern bool expected_loop_iterations_by_profile (const class loop *loop, sreal *ret, bool *reliable = NULL); +extern bool maybe_flat_loop_profile (const class loop *); extern unsigned expected_loop_iterations (class loop *); extern rtx doloop_condition_get (rtx_insn *); diff --git a/gcc/cfgloopanal.cc b/gcc/cfgloopanal.cc index c86a537..d8923b2 100644 --- a/gcc/cfgloopanal.cc +++ b/gcc/cfgloopanal.cc @@ -303,6 +303,67 @@ expected_loop_iterations_by_profile (const class loop *loop, sreal *ret, return true; } +/* Return true if loop CFG profile may be unrealistically flat. + This is a common case, since average loops iterate only about 5 times. + In the case we do not have profile feedback or do not know real number of + iterations during profile estimation, we are likely going to predict it with + similar low iteration count. For static loop profiles we also artificially + cap profile of loops with known large iteration count so they do not appear + significantly more hot than other loops with unknown iteration counts. + + For loop optimization heuristics we ignore CFG profile and instead + use get_estimated_loop_iterations API which returns estimate + only when it is realistic. For unknown counts some optimizations, + like vectorizer or unroller make guess that iteration count will + be large. In this case we need to avoid scaling down the profile + after the loop transform. */ + +bool +maybe_flat_loop_profile (const class loop *loop) +{ + bool reliable; + sreal ret; + + if (!expected_loop_iterations_by_profile (loop, &ret, &reliable)) + return true; + + /* Reliable CFG estimates ought never be flat. Sanity check with + nb_iterations_estimate. If those differ, it is a but in profile + updating code */ + if (reliable) + { + int64_t intret = ret.to_nearest_int (); + if (loop->any_estimate + && (wi::ltu_p (intret * 2, loop->nb_iterations_estimate) + || wi::gtu_p (intret, loop->nb_iterations_estimate * 2))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Loop %i has inconsistent iterations estimates: " + "reliable CFG based iteration estimate is %f " + "while nb_iterations_estimate is %i\n", + loop->num, + ret.to_double (), + (int)loop->nb_iterations_estimate.to_shwi ()); + return true; + } + return false; + } + + /* Allow some margin of error and see if we are close to known bounds. + sreal (9,-3) is 9/8 */ + int64_t intret = (ret * sreal (9, -3)).to_nearest_int (); + if (loop->any_upper_bound && wi::geu_p (intret, loop->nb_iterations_upper_bound)) + return false; + if (loop->any_likely_upper_bound + && wi::geu_p (intret, loop->nb_iterations_likely_upper_bound)) + return false; + if (loop->any_estimate + && wi::geu_p (intret, loop->nb_iterations_estimate)) + return false; + return true; +} + /* Returns expected number of iterations of LOOP, according to measured or guessed profile. diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index a6c97a0..c65af8c 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -8523,8 +8523,11 @@ print_loop_info (FILE *file, const class loop *loop, const char *prefix) bool reliable; sreal iterations; if (loop->num && expected_loop_iterations_by_profile (loop, &iterations, &reliable)) - fprintf (file, "\n%siterations by profile: %f %s", prefix, - iterations.to_double (), reliable ? "(reliable)" : "(unreliable)"); + { + fprintf (file, "\n%siterations by profile: %f (%s%s)", prefix, + iterations.to_double (), reliable ? "reliable" : "unreliable", + maybe_flat_loop_profile (loop) ? ", maybe flat" : ""); + } } -- cgit v1.1 From 54da3d249ea60c14e71b13935e5e846c8b490b7d Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Fri, 21 Jul 2023 16:59:54 +0000 Subject: Update gcc hr.po * hr.po: Update. --- gcc/po/hr.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/po/hr.po b/gcc/po/hr.po index cd6c8eb..5c1335b 100644 --- a/gcc/po/hr.po +++ b/gcc/po/hr.po @@ -1802,7 +1802,7 @@ msgstr "" #: c-family/c.opt:703 #, no-c-format msgid "Warn about function calls with format strings that write past the end of the destination region. Same as -Wformat-overflow=1." -msgstr "Upozori na pozive funkcija s format stingovima koji pišu iza kraja područja odredišta. Isto kao -Wformat-overflow=1." +msgstr "Upozori na pozive funkcija s format stringovima koji pišu iza kraja područja odredišta. Isto kao -Wformat-overflow=1." #: c-family/c.opt:708 #, no-c-format @@ -12963,7 +12963,7 @@ msgstr "Pokaže ove informacije." #: common.opt:299 #, no-c-format msgid "--help=\tDisplay descriptions of a specific class of options. is one or more of optimizers, target, warnings, undocumented, params." -msgstr "--help=\tPokaže opise specične klase opcija. je jedan ili više elemenata iz optimizers, target, warnings, undocumented, params." +msgstr "--help=\tPokaže opise specifične klase opcija. je jedan ili više elemenata iz optimizers, target, warnings, undocumented, params." #: common.opt:420 #, no-c-format @@ -13183,7 +13183,7 @@ msgstr "" #: common.opt:716 #, no-c-format msgid "Warn when one variable shadows another. Same as -Wshadow=global." -msgstr "Upozori na jedna varijabla zasijeni neku drugu varijablu. Isko kao -Wshadow=global." +msgstr "Upozori na jedna varijabla zasijeni neku drugu varijablu. Isto kao -Wshadow=global." #: common.opt:720 #, no-c-format @@ -13403,7 +13403,7 @@ msgstr "poravna početak funkcija" #: common.opt:1035 #, no-c-format msgid "Align labels which are only reached by jumping." -msgstr "oravna one oznake do kojih se može doći samo sa skakanjem" +msgstr "poravna one oznake do kojih se može doći samo sa skakanjem" #: common.opt:1042 #, no-c-format @@ -18721,7 +18721,7 @@ msgstr "" #: c-family/c-format.cc:695 msgid "field width in strfmon format" -msgstr "širina poljau u strfmon formatu" +msgstr "širina polja u strfmon formatu" #: c-family/c-format.cc:696 msgid "left precision" @@ -18981,7 +18981,7 @@ msgstr "neprepoznata pretpostavljena konstanta" #: config/arm/arm.cc:21053 config/arm/arm.cc:21062 #, c-format msgid "invalid shift operand" -msgstr "nevaljai operand pomaka (shift)" +msgstr "nevaljani operand pomaka (shift)" #: config/arm/arm.cc:23971 config/arm/arm.cc:23989 #, c-format @@ -19693,7 +19693,7 @@ msgstr "" #: config/msp430/msp430.cc:4376 #, c-format msgid "invalid zero extract" -msgstr "nevaljani nulo ekstrakt" +msgstr "nevaljani nula ekstrakt" #: config/or1k/or1k.cc:1154 config/or1k/or1k.cc:1162 #, c-format @@ -27837,7 +27837,7 @@ msgstr "" #: lto-streamer-in.cc:1230 #, gcc-internal-format msgid "Reference statement index out of range" -msgstr "Index referente izjave je izvan granica" +msgstr "Index referentne izjave je izvan granica" #: lto-streamer-in.cc:1234 #, gcc-internal-format @@ -60571,7 +60571,7 @@ msgstr "" #: cp/pt.cc:6373 #, gcc-internal-format msgid "redeclared here" -msgstr "ponovn deklarirano ovdje" +msgstr "ponovno deklarirano ovdje" #: cp/pt.cc:6384 #, gcc-internal-format -- cgit v1.1 From a31ef26b056d0c4f0a9f08b6eb81456ea257298e Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 19:38:26 +0200 Subject: Avoid scaling flat loop profiles of vectorized loops As discussed, when vectorizing loop with static profile, it is not always good idea to divide the header frequency by vectorization factor because the profile may not realistically represent the expected number of iterations. Since in such cases we default to relatively low iteration counts (based on average for spec2k17), this will make vectorized loop body look cold. This patch makes vectorizer to look for flat profiles and only possibly reduce the profile by known upper bound on iteration counts. gcc/ChangeLog: PR target/110727 * tree-vect-loop.cc (scale_profile_for_vect_loop): Avoid scaling flat profiles by vectorization factor. (vect_transform_loop): Check for flat profiles. --- gcc/tree-vect-loop.cc | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index b44fb9c..d036a7d 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -10837,11 +10837,25 @@ vect_get_loop_len (loop_vec_info loop_vinfo, gimple_stmt_iterator *gsi, } /* Scale profiling counters by estimation for LOOP which is vectorized - by factor VF. */ + by factor VF. + If FLAT is true, the loop we started with had unrealistically flat + profile. */ static void -scale_profile_for_vect_loop (class loop *loop, unsigned vf) +scale_profile_for_vect_loop (class loop *loop, unsigned vf, bool flat) { + /* For flat profiles do not scale down proportionally by VF and only + cap by known iteration count bounds. */ + if (flat) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Vectorized loop profile seems flat; not scaling iteration " + "count down by the vectorization factor %i\n", vf); + scale_loop_profile (loop, profile_probability::always (), + get_likely_max_loop_iterations_int (loop)); + return; + } /* Loop body executes VF fewer times and exit increases VF times. */ edge exit_e = single_exit (loop); profile_count entry_count = loop_preheader_edge (loop)->count (); @@ -10852,7 +10866,13 @@ scale_profile_for_vect_loop (class loop *loop, unsigned vf) while (vf > 1 && loop->header->count > entry_count && loop->header->count < entry_count * vf) - vf /= 2; + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Vectorization factor %i seems too large for profile " + "prevoiusly believed to be consistent; reducing.\n", vf); + vf /= 2; + } if (entry_count.nonzero_p ()) set_edge_probability_and_rescale_others @@ -11184,6 +11204,7 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) gimple *stmt; bool check_profitability = false; unsigned int th; + bool flat = maybe_flat_loop_profile (loop); DUMP_VECT_SCOPE ("vec_transform_loop"); @@ -11252,7 +11273,6 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) &step_vector, &niters_vector_mult_vf, th, check_profitability, niters_no_overflow, &advance); - if (LOOP_VINFO_SCALAR_LOOP (loop_vinfo) && LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo).initialized_p ()) scale_loop_frequencies (LOOP_VINFO_SCALAR_LOOP (loop_vinfo), @@ -11545,7 +11565,7 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) assumed_vf) - 1 : wi::udiv_floor (loop->nb_iterations_estimate + bias_for_assumed, assumed_vf) - 1); - scale_profile_for_vect_loop (loop, assumed_vf); + scale_profile_for_vect_loop (loop, assumed_vf, flat); if (dump_enabled_p ()) { -- cgit v1.1 From e36d1994051122fc6e1f8c728fbd109a59e0a822 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 18 Jul 2023 16:02:21 -0400 Subject: c++: fix ICE with is_really_empty_class [PR110106] is_really_empty_class is liable to crash when it gets an incomplete or dependent type. Since r11-557, we pass the yet-uninstantiated class type S<0> of the PARM_DECL s to is_really_empty_class -- because of the potential_rvalue_constant_expression -> is_rvalue_constant_expression change in cp_parser_constant_expression. Here we're not parsing a template so we did not check COMPLETE_TYPE_P as we should. It should work to complete the type before checking COMPLETE_TYPE_P. PR c++/110106 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1): Try to complete the type when !processing_template_decl. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept80.C: New test. --- gcc/cp/constexpr.cc | 5 +++-- gcc/testsuite/g++.dg/cpp0x/noexcept80.C | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept80.C (limited to 'gcc') diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 6e8f1c2..fb94f3c 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -9116,8 +9116,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, if (now && want_rval) { tree type = TREE_TYPE (t); - if ((processing_template_decl && !COMPLETE_TYPE_P (type)) - || dependent_type_p (type) + if (dependent_type_p (type) + || !COMPLETE_TYPE_P (processing_template_decl + ? type : complete_type (type)) || is_really_empty_class (type, /*ignore_vptr*/false)) /* An empty class has no data to read. */ return true; diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept80.C b/gcc/testsuite/g++.dg/cpp0x/noexcept80.C new file mode 100644 index 0000000..3e90af7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept80.C @@ -0,0 +1,12 @@ +// PR c++/110106 +// { dg-do compile { target c++11 } } + +template struct S +{ +}; + +struct G { + G(S<0>); +}; + +void y(S<0> s) noexcept(noexcept(G{s})); -- cgit v1.1 From 13ed106723c7c01cddd769b0bac14c81399e6b40 Mon Sep 17 00:00:00 2001 From: Cupertino Miranda Date: Fri, 21 Jul 2023 17:40:07 +0100 Subject: bpf: fixed template for neg (added second operand) This patch fixes define_insn for "neg" to support 2 operands. Initial implementation assumed the format "neg %0" while the instruction allows both a destination and source operands. The second operand can either be a register or an immediate value. gcc/ChangeLog: * config/bpf/bpf.md: fixed template for neg instruction. --- gcc/config/bpf/bpf.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index 329f62f..adf11e1 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -139,10 +139,10 @@ ;;; Negation (define_insn "neg2" - [(set (match_operand:AM 0 "register_operand" "=r") - (neg:AM (match_operand:AM 1 "register_operand" " 0")))] + [(set (match_operand:AM 0 "register_operand" "=r,r") + (neg:AM (match_operand:AM 1 "register_operand" " r,I")))] "" - "neg\t%0" + "neg\t%0,%1" [(set_attr "type" "")]) ;;; Multiplication -- cgit v1.1 From 77d0f9ec3809b4d2e32c36069b6b9239d301c030 Mon Sep 17 00:00:00 2001 From: Cupertino Miranda Date: Mon, 17 Jul 2023 17:42:42 +0100 Subject: bpf: pseudo-c assembly dialect support New pseudo-c BPF assembly dialect already supported by clang and widely used in the linux kernel. gcc/ChangeLog: PR target/110770 * config/bpf/bpf.opt: Added option -masm=. * config/bpf/bpf-opts.h (enum bpf_asm_dialect): New type. * config/bpf/bpf.cc (bpf_print_register): New function. (bpf_print_register): Support pseudo-c syntax for registers. (bpf_print_operand_address): Likewise. * config/bpf/bpf.h (ASM_SPEC): handle -msasm. (ASSEMBLER_DIALECT): Define. * config/bpf/bpf.md: Added pseudo-c templates. * doc/invoke.texi (-masm=): New eBPF option item. --- gcc/config/bpf/bpf-opts.h | 6 +++ gcc/config/bpf/bpf.cc | 46 +++++++++++++++++++--- gcc/config/bpf/bpf.h | 5 ++- gcc/config/bpf/bpf.md | 97 ++++++++++++++++++++++++----------------------- gcc/config/bpf/bpf.opt | 14 +++++++ gcc/doc/invoke.texi | 21 +++++++++- 6 files changed, 133 insertions(+), 56 deletions(-) (limited to 'gcc') diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h index 8282351..92db01e 100644 --- a/gcc/config/bpf/bpf-opts.h +++ b/gcc/config/bpf/bpf-opts.h @@ -60,4 +60,10 @@ enum bpf_isa_version ISA_V3, }; +enum bpf_asm_dialect +{ + ASM_NORMAL, + ASM_PSEUDOC +}; + #endif /* ! BPF_OPTS_H */ diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index e0324e1..1d39368 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -873,16 +873,47 @@ bpf_output_call (rtx target) return ""; } +/* Print register name according to assembly dialect. + In normal syntax registers are printed like %rN where N is the + register number. + In pseudoc syntax, the register names do not feature a '%' prefix. + Additionally, the code 'w' denotes that the register should be printed + as wN instead of rN, where N is the register number, but only when the + value stored in the operand OP is 32-bit wide. */ +static void +bpf_print_register (FILE *file, rtx op, int code) +{ + if(asm_dialect == ASM_NORMAL) + fprintf (file, "%s", reg_names[REGNO (op)]); + else + { + if (code == 'w' && GET_MODE (op) == SImode) + { + if (REGNO (op) == BPF_FP) + fprintf (file, "w10"); + else + fprintf (file, "w%s", reg_names[REGNO (op)]+2); + } + else + { + if (REGNO (op) == BPF_FP) + fprintf (file, "r10"); + else + fprintf (file, "%s", reg_names[REGNO (op)]+1); + } + } +} + /* Print an instruction operand. This function is called in the macro PRINT_OPERAND defined in bpf.h */ void -bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED) +bpf_print_operand (FILE *file, rtx op, int code) { switch (GET_CODE (op)) { case REG: - fprintf (file, "%s", reg_names[REGNO (op)]); + bpf_print_register (file, op, code); break; case MEM: output_address (GET_MODE (op), XEXP (op, 0)); @@ -936,7 +967,9 @@ bpf_print_operand_address (FILE *file, rtx addr) switch (GET_CODE (addr)) { case REG: - fprintf (file, "[%s+0]", reg_names[REGNO (addr)]); + fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "("); + bpf_print_register (file, addr, 0); + fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)"); break; case PLUS: { @@ -945,9 +978,11 @@ bpf_print_operand_address (FILE *file, rtx addr) if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT) { - fprintf (file, "[%s+", reg_names[REGNO (op0)]); + fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "("); + bpf_print_register (file, op0, 0); + fprintf (file, "+"); output_addr_const (file, op1); - fputs ("]", file); + fprintf (file, asm_dialect == ASM_NORMAL ? "]" : ")"); } else fatal_insn ("invalid address in operand", addr); @@ -1816,7 +1851,6 @@ handle_attr_preserve (function *fn) } } - /* This pass finds accesses to structures marked with the BPF target attribute __attribute__((preserve_access_index)). For every such access, a CO-RE relocation record is generated, to be output in the .BTF.ext section. */ diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h index 344aca0..9561bf5 100644 --- a/gcc/config/bpf/bpf.h +++ b/gcc/config/bpf/bpf.h @@ -22,7 +22,8 @@ /**** Controlling the Compilation Driver. */ -#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf}" +#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf} " \ + "%{masm=pseudoc:-mdialect=pseudoc}" #define LINK_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}" #define LIB_SPEC "" #define STARTFILE_SPEC "" @@ -503,4 +504,6 @@ enum reg_class #define DO_GLOBAL_DTORS_BODY \ do { } while (0) +#define ASSEMBLER_DIALECT ((int) asm_dialect) + #endif /* ! GCC_BPF_H */ diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index adf11e1..80220f2 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -88,6 +88,8 @@ (define_mode_attr mop [(QI "b") (HI "h") (SI "w") (DI "dw") (SF "w") (DF "dw")]) +(define_mode_attr smop [(QI "u8") (HI "u16") (SI "u32") (DI "u64") + (SF "u32") (DF "u64")]) (define_mode_attr mtype [(SI "alu32") (DI "alu")]) (define_mode_attr msuffix [(SI "32") (DI "")]) @@ -121,7 +123,7 @@ (plus:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" " r,I")))] "1" - "add\t%0,%2" + "{add\t%0,%2|%w0 += %w1}" [(set_attr "type" "")]) ;;; Subtraction @@ -134,15 +136,15 @@ (minus:AM (match_operand:AM 1 "register_operand" " 0") (match_operand:AM 2 "register_operand" " r")))] "" - "sub\t%0,%2" + "{sub\t%0,%2|%w0 -= %w1}" [(set_attr "type" "")]) ;;; Negation (define_insn "neg2" - [(set (match_operand:AM 0 "register_operand" "=r,r") - (neg:AM (match_operand:AM 1 "register_operand" " r,I")))] + [(set (match_operand:AM 0 "register_operand" "=r,r") + (neg:AM (match_operand:AM 1 "reg_or_imm_operand" " r,I")))] "" - "neg\t%0,%1" + "{neg\t%0,%1|%w0 = -%w1}" [(set_attr "type" "")]) ;;; Multiplication @@ -151,7 +153,7 @@ (mult:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" " r,I")))] "" - "mul\t%0,%2" + "{mul\t%0,%2|%w0 *= %w2}" [(set_attr "type" "")]) (define_insn "*mulsidi3_zeroextend" @@ -160,7 +162,7 @@ (mult:SI (match_operand:SI 1 "register_operand" "0,0") (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))] "" - "mul32\t%0,%2" + "{mul32\t%0,%2|%w0 *= %w2}" [(set_attr "type" "alu32")]) ;;; Division @@ -173,7 +175,7 @@ (udiv:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] "" - "div\t%0,%2" + "{div\t%0,%2|%w0 /= %w2}" [(set_attr "type" "")]) ;; However, xBPF does provide a signed division operator, sdiv. @@ -183,7 +185,7 @@ (div:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] "TARGET_XBPF" - "sdiv\t%0,%2" + "{sdiv\t%0,%2|%w0 s/= %w2}" [(set_attr "type" "")]) ;;; Modulus @@ -196,7 +198,7 @@ (umod:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] "" - "mod\t%0,%2" + "{mod\t%0,%2|%w0 %%= %w2}" [(set_attr "type" "")]) ;; Again, xBPF provides a signed version, smod. @@ -206,7 +208,7 @@ (mod:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] "TARGET_XBPF" - "smod\t%0,%2" + "{smod\t%0,%2|%w0 s%%= %w2}" [(set_attr "type" "")]) ;;; Logical AND @@ -215,7 +217,7 @@ (and:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] "" - "and\t%0,%2" + "{and\t%0,%2|%w0 &= %w2}" [(set_attr "type" "")]) ;;; Logical inclusive-OR @@ -224,7 +226,7 @@ (ior:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] "" - "or\t%0,%2" + "{or\t%0,%2|%w0 %|= %w2}" [(set_attr "type" "")]) ;;; Logical exclusive-OR @@ -233,7 +235,7 @@ (xor:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] "" - "xor\t%0,%2" + "{xor\t%0,%2|%w0 ^= %w2}" [(set_attr "type" "")]) ;;;; Conversions @@ -256,9 +258,9 @@ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "0,r,q")))] "" "@ - and\t%0,0xffff - mov\t%0,%1\;and\t%0,0xffff - ldxh\t%0,%1" + {and\t%0,0xffff|%0 &= 0xffff} + {mov\t%0,%1\;and\t%0,0xffff|%0 = %1;%0 &= 0xffff} + {ldxh\t%0,%1|%0 = *(u16 *) %1}" [(set_attr "type" "alu,alu,ldx")]) (define_insn "zero_extendqidi2" @@ -266,9 +268,9 @@ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "0,r,q")))] "" "@ - and\t%0,0xff - mov\t%0,%1\;and\t%0,0xff - ldxb\t%0,%1" + {and\t%0,0xff|%0 &= 0xff} + {mov\t%0,%1\;and\t%0,0xff|%0 = %1;%0 &= 0xff} + {ldxh\t%0,%1|%0 = *(u8 *) %1}" [(set_attr "type" "alu,alu,ldx")]) (define_insn "zero_extendsidi2" @@ -277,8 +279,8 @@ (match_operand:SI 1 "nonimmediate_operand" "r,q")))] "" "@ - * return bpf_has_alu32 ? \"mov32\t%0,%1\" : \"mov\t%0,%1\;and\t%0,0xffffffff\"; - ldxw\t%0,%1" + * return bpf_has_alu32 ? \"{mov32\t%0,%1|%0 = %1}\" : \"{mov\t%0,%1\;and\t%0,0xffffffff|%0 = %1;%0 &= 0xffffffff}\"; + {ldxw\t%0,%1|%0 = *(u32 *) %1}" [(set_attr "type" "alu,ldx")]) ;;; Sign-extension @@ -317,11 +319,11 @@ (match_operand:MM 1 "mov_src_operand" " q,rI,B,r,I"))] "" "@ - ldx\t%0,%1 - mov\t%0,%1 - lddw\t%0,%1 - stx\t%0,%1 - st\t%0,%1" + {ldx\t%0,%1|%0 = *( *) %1} + {mov\t%0,%1|%0 = %1} + {lddw\t%0,%1|%0 = %1 ll} + {stx\t%0,%1|*( *) %0 = %1} + {st\t%0,%1|*( *) %0 = %1}" [(set_attr "type" "ldx,alu,alu,stx,st")]) ;;;; Shifts @@ -333,7 +335,7 @@ (ashiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0") (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] "" - "arsh\t%0,%2" + "{arsh\t%0,%2|%w0 s>>= %w2}" [(set_attr "type" "")]) (define_insn "ashl3" @@ -341,7 +343,7 @@ (ashift:SIM (match_operand:SIM 1 "register_operand" " 0,0") (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] "" - "lsh\t%0,%2" + "{lsh\t%0,%2|%w0 <<= %w2}" [(set_attr "type" "")]) (define_insn "lshr3" @@ -349,7 +351,7 @@ (lshiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0") (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] "" - "rsh\t%0,%2" + "{rsh\t%0,%2|%w0 >>= %w2}" [(set_attr "type" "")]) ;;;; Endianness conversion @@ -363,9 +365,9 @@ "" { if (TARGET_BIG_ENDIAN) - return "endle\t%0, "; + return "{endle\t%0, |%0 = le %0}"; else - return "endbe\t%0, "; + return "{endbe\t%0, |%0 = be %0}"; } [(set_attr "type" "end")]) @@ -404,16 +406,16 @@ switch (code) { - case EQ: return "jeq\t%0,%1,%2"; break; - case NE: return "jne\t%0,%1,%2"; break; - case LT: return "jslt\t%0,%1,%2"; break; - case LE: return "jsle\t%0,%1,%2"; break; - case GT: return "jsgt\t%0,%1,%2"; break; - case GE: return "jsge\t%0,%1,%2"; break; - case LTU: return "jlt\t%0,%1,%2"; break; - case LEU: return "jle\t%0,%1,%2"; break; - case GTU: return "jgt\t%0,%1,%2"; break; - case GEU: return "jge\t%0,%1,%2"; break; + case EQ: return "{jeq\t%0,%1,%2|if %w0 == %w1 goto %2}"; break; + case NE: return "{jne\t%0,%1,%2|if %w0 != %w1 goto %2}"; break; + case LT: return "{jslt\t%0,%1,%2|if %w0 s< %w1 goto %2}"; break; + case LE: return "{jsle\t%0,%1,%2|if %w0 s<= %w1 goto %2}"; break; + case GT: return "{jsgt\t%0,%1,%2|if %w0 s> %w1 goto %2}"; break; + case GE: return "{jsge\t%0,%1,%2|if %w0 s>= %w1 goto %2}"; break; + case LTU: return "{jlt\t%0,%1,%2|if %w0 < %w1 goto %2}"; break; + case LEU: return "{jle\t%0,%1,%2|if %w0 <= %w1 goto %2}"; break; + case GTU: return "{jgt\t%0,%1,%2|if %w0 > %w1 goto %2}"; break; + case GEU: return "{jge\t%0,%1,%2|if %w0 >= %w1 goto %2}"; break; default: gcc_unreachable (); return ""; @@ -427,7 +429,7 @@ [(set (pc) (label_ref (match_operand 0 "" "")))] "" - "ja\t%0" + "{ja\t%0|goto %0}" [(set_attr "type" "jmp")]) ;;;; Function prologue/epilogue @@ -506,13 +508,14 @@ ;; operands[2] is next_arg_register ;; operands[3] is struct_value_size_rtx. "" - "ja\t%0" + "{ja\t%0|goto %0}" [(set_attr "type" "jmp")]) ;;;; Non-generic load instructions (define_mode_iterator LDM [QI HI SI DI]) (define_mode_attr ldop [(QI "b") (HI "h") (SI "w") (DI "dw")]) +(define_mode_attr pldop [(QI "u8") (HI "u16") (SI "u32") (DI "u64")]) (define_insn "ldind" [(set (reg:LDM R0_REGNUM) @@ -524,7 +527,7 @@ (clobber (reg:DI R3_REGNUM)) (clobber (reg:DI R4_REGNUM))] "" - "ldind\t%0,%1" + "{ldind\t%0,%1|r0 = *( *) skb[%0 + %1]}" [(set_attr "type" "ld")]) (define_insn "ldabs" @@ -537,7 +540,7 @@ (clobber (reg:DI R3_REGNUM)) (clobber (reg:DI R4_REGNUM))] "" - "ldabs\t%0" + "{ldabs\t%0|r0 = *( *) skb[%0]}" [(set_attr "type" "ld")]) ;;;; Atomic increments @@ -552,5 +555,5 @@ (match_operand:SI 2 "const_int_operand")] ;; Memory model. UNSPEC_XADD))] "" - "xadd\t%0,%1" + "{xadd\t%0,%1|*( *) %0 += %1}" [(set_attr "type" "xadd")]) diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index fe3ad35..ff805f9 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -160,3 +160,17 @@ Enum(bpf_isa) String(v2) Value(ISA_V2) EnumValue Enum(bpf_isa) String(v3) Value(ISA_V3) + +masm= +Target RejectNegative Joined Var(asm_dialect) Enum(asm_dialect) Init(ASM_NORMAL) +Use given assembler dialect. + +Enum +Name(asm_dialect) Type(enum bpf_asm_dialect) +Known assembler dialects (for use with the -masm= option) + +EnumValue +Enum(asm_dialect) String(normal) Value(ASM_NORMAL) + +EnumValue +Enum(asm_dialect) String(pseudoc) Value(ASM_PSEUDOC) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5628c08..efd356e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -946,8 +946,8 @@ Objective-C and Objective-C++ Dialects}. @emph{eBPF Options} @gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version} --mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re --mjmpext -mjmp32 -malu32 -mcpu=@var{version}} +-mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -mjmpext +-mjmp32 -malu32 -mcpu=@var{version} -masm=@var{dialect}} @emph{FR30 Options} @gccoptlist{-msmall-model -mno-lsim} @@ -24748,6 +24748,23 @@ the restrictions imposed by the BPF architecture: @item Save and restore callee-saved registers at function entry and exit, respectively. @end itemize + +@opindex masm=@var{dialect} +@item -masm=@var{dialect} +Outputs assembly instructions using eBPF selected @var{dialect}. The default +is @samp{normal}. + +Supported values for @var{dialect} are: + +@table @samp +@item normal +Outputs normal assembly dialect. + +@item pseudoc +Outputs pseudo-c assembly dialect. + +@end table + @end table @node FR30 Options -- cgit v1.1 From cfe53af09364d94fb86013f85ef598a1d47e0657 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Fri, 21 Jul 2023 20:37:59 +0100 Subject: PR c/110699: Defend against error_mark_node in gimplify.cc. This patch resolves PR c/110669, an ICE-after-error regression, by adding a check that the array type isn't error_mark_node in gimplify_compound_lval. 2023-07-21 Roger Sayle Richard Biener gcc/ChangeLog PR c/110699 * gimplify.cc (gimplify_compound_lval): If the array's type is error_mark_node then return GS_ERROR. gcc/testsuite/ChangeLog PR c/110699 * gcc.dg/pr110699.c: New test case. --- gcc/gimplify.cc | 3 +++ gcc/testsuite/gcc.dg/pr110699.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr110699.c (limited to 'gcc') diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 36e5df0..320920e 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -3209,6 +3209,9 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { tree t = expr_stack[i]; + if (error_operand_p (TREE_OPERAND (t, 0))) + return GS_ERROR; + if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) { /* Deal with the low bound and element type size and put them into diff --git a/gcc/testsuite/gcc.dg/pr110699.c b/gcc/testsuite/gcc.dg/pr110699.c new file mode 100644 index 0000000..be77613 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110699.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef __attribute__((__vector_size__(64))) int T; + +void f(void) { + extern char a[64], b[64]; /* { dg-message "previous" "note" } */ + void *p = a; + T q = *(T *)&b[0]; +} + +void g() { + extern char b; /* { dg-error "conflicting types" } */ +} -- cgit v1.1 From 87516efcbe28884c39a8c68e600d11cc91ed96c7 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 21 Jul 2023 19:47:35 +0000 Subject: Require target lra in gcc.c-torture/compile/asmgoto-6.c 2023-07-21 John David Anglin gcc/testsuite/ChangeLog: * gcc.c-torture/compile/asmgoto-6.c: Require target lra. --- gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c b/gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c index 0652bd4..6799b83 100644 --- a/gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c +++ b/gcc/testsuite/gcc.c-torture/compile/asmgoto-6.c @@ -1,5 +1,5 @@ -/* { dg-do compile } */ +/* { dg-do compile { target lra } } */ /* PR middle-end/110420 */ /* PR middle-end/103979 */ /* PR middle-end/98619 */ -- cgit v1.1 From 0ce6353046ec3fccc16bb6465f8a7f3eb00547fa Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 22 Jul 2023 00:17:44 +0000 Subject: Daily bump. --- gcc/ChangeLog | 263 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/analyzer/ChangeLog | 18 ++++ gcc/cp/ChangeLog | 6 ++ gcc/po/ChangeLog | 4 + gcc/testsuite/ChangeLog | 143 ++++++++++++++++++++++++++ 6 files changed, 435 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bbcc03..835fec3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,266 @@ +2023-07-21 Roger Sayle + Richard Biener + + PR c/110699 + * gimplify.cc (gimplify_compound_lval): If the array's type + is error_mark_node then return GS_ERROR. + +2023-07-21 Cupertino Miranda + + PR target/110770 + * config/bpf/bpf.opt: Added option -masm=. + * config/bpf/bpf-opts.h (enum bpf_asm_dialect): New type. + * config/bpf/bpf.cc (bpf_print_register): New function. + (bpf_print_register): Support pseudo-c syntax for registers. + (bpf_print_operand_address): Likewise. + * config/bpf/bpf.h (ASM_SPEC): handle -msasm. + (ASSEMBLER_DIALECT): Define. + * config/bpf/bpf.md: Added pseudo-c templates. + * doc/invoke.texi (-masm=): New eBPF option item. + +2023-07-21 Cupertino Miranda + + * config/bpf/bpf.md: fixed template for neg instruction. + +2023-07-21 Jan Hubicka + + PR target/110727 + * tree-vect-loop.cc (scale_profile_for_vect_loop): Avoid scaling flat + profiles by vectorization factor. + (vect_transform_loop): Check for flat profiles. + +2023-07-21 Jan Hubicka + + * cfgloop.h (maybe_flat_loop_profile): Declare + * cfgloopanal.cc (maybe_flat_loop_profile): New function. + * tree-cfg.cc (print_loop_info): Print info about flat profiles. + +2023-07-21 Jan Hubicka + + * cfgloop.cc (get_estimated_loop_iterations): Use sreal::to_nearest_int + * cfgloopanal.cc (expected_loop_iterations_unbounded): Likewise. + * predict.cc (estimate_bb_frequencies): Likewise. + * profile.cc (branch_prob): Likewise. + * tree-ssa-loop-niter.cc (estimate_numbers_of_iterations): Likewise + +2023-07-21 Iain Sandoe + + * config.in: Regenerate. + * config/darwin.h (DARWIN_LD_DEMANGLE): New. + (LINK_COMMAND_SPEC_A): Add demangle handling. + * configure: Regenerate. + * configure.ac: Detect linker support for '-demangle'. + +2023-07-21 Jan Hubicka + + * sreal.cc (sreal::to_nearest_int): New. + (sreal_verify_basics): Verify also to_nearest_int. + (verify_aritmetics): Likewise. + (sreal_verify_conversions): New. + (sreal_cc_tests): Call sreal_verify_conversions. + * sreal.h: (sreal::to_nearest_int): Declare + +2023-07-21 Jan Hubicka + + * tree-ssa-loop-ch.cc (enum ch_decision): New enum. + (should_duplicate_loop_header_p): Return info on profitability. + (do_while_loop_p): Watch for constant conditionals. + (update_profile_after_ch): Do not sanity check that all + static exits are taken. + (ch_base::copy_headers): Run on all loops. + (pass_ch::process_loop_p): Improve heuristics by handling also + do_while loop and duplicating shortest sequence containing all + winning blocks. + +2023-07-21 Jan Hubicka + + * tree-ssa-loop-niter.cc (finite_loop_p): Reorder to do cheap + tests first; update finite_p flag. + +2023-07-21 Jan Hubicka + + * cfgloop.cc (flow_loop_dump): Use print_loop_info. + * cfgloop.h (print_loop_info): Declare. + * tree-cfg.cc (print_loop_info): Break out from ...; add + printing of missing fields and profile + (print_loop): ... here. + +2023-07-21 Juzhe-Zhong + + * config/riscv/riscv-v.cc (expand_gather_scatter): Remove redundant variables. + +2023-07-21 Juzhe-Zhong + + * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Change condition order. + (vectorizable_operation): Ditto. + +2023-07-21 Juzhe-Zhong + + * config/riscv/autovec.md: Align order of mask and len. + * config/riscv/riscv-v.cc (expand_load_store): Ditto. + (expand_gather_scatter): Ditto. + * doc/md.texi: Ditto. + * internal-fn.cc (add_len_and_mask_args): Ditto. + (add_mask_and_len_args): Ditto. + (expand_partial_load_optab_fn): Ditto. + (expand_partial_store_optab_fn): Ditto. + (expand_scatter_store_optab_fn): Ditto. + (expand_gather_load_optab_fn): Ditto. + (internal_fn_len_index): Ditto. + (internal_fn_mask_index): Ditto. + (internal_len_load_store_bias): Ditto. + * tree-vect-stmts.cc (vectorizable_store): Ditto. + (vectorizable_load): Ditto. + +2023-07-21 Juzhe-Zhong + + * config/riscv/autovec.md (len_maskload): Change LEN_MASK into MASK_LEN. + (mask_len_load): Ditto. + (len_maskstore): Ditto. + (mask_len_store): Ditto. + (len_mask_gather_load): Ditto. + (mask_len_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (mask_len_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (mask_len_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (mask_len_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (mask_len_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (mask_len_gather_load): Ditto. + (len_mask_gather_load): Ditto. + (mask_len_gather_load): Ditto. + (len_mask_scatter_store): Ditto. + (mask_len_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (mask_len_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (mask_len_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (mask_len_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (mask_len_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (mask_len_scatter_store): Ditto. + (len_mask_scatter_store): Ditto. + (mask_len_scatter_store): Ditto. + * doc/md.texi: Ditto. + * genopinit.cc (main): Ditto. + (CMP_NAME): Ditto. Ditto. + * gimple-fold.cc (arith_overflowed_p): Ditto. + (gimple_fold_partial_load_store_mem_ref): Ditto. + (gimple_fold_call): Ditto. + * internal-fn.cc (len_maskload_direct): Ditto. + (mask_len_load_direct): Ditto. + (len_maskstore_direct): Ditto. + (mask_len_store_direct): Ditto. + (expand_call_mem_ref): Ditto. + (expand_len_maskload_optab_fn): Ditto. + (expand_mask_len_load_optab_fn): Ditto. + (expand_len_maskstore_optab_fn): Ditto. + (expand_mask_len_store_optab_fn): Ditto. + (direct_len_maskload_optab_supported_p): Ditto. + (direct_mask_len_load_optab_supported_p): Ditto. + (direct_len_maskstore_optab_supported_p): Ditto. + (direct_mask_len_store_optab_supported_p): Ditto. + (internal_load_fn_p): Ditto. + (internal_store_fn_p): Ditto. + (internal_gather_scatter_fn_p): Ditto. + (internal_fn_len_index): Ditto. + (internal_fn_mask_index): Ditto. + (internal_fn_stored_value_index): Ditto. + (internal_len_load_store_bias): Ditto. + * internal-fn.def (LEN_MASK_GATHER_LOAD): Ditto. + (MASK_LEN_GATHER_LOAD): Ditto. + (LEN_MASK_LOAD): Ditto. + (MASK_LEN_LOAD): Ditto. + (LEN_MASK_SCATTER_STORE): Ditto. + (MASK_LEN_SCATTER_STORE): Ditto. + (LEN_MASK_STORE): Ditto. + (MASK_LEN_STORE): Ditto. + * optabs-query.cc (supports_vec_gather_load_p): Ditto. + (supports_vec_scatter_store_p): Ditto. + * optabs-tree.cc (target_supports_mask_load_store_p): Ditto. + (target_supports_len_load_store_p): Ditto. + * optabs.def (OPTAB_CD): Ditto. + * tree-ssa-alias.cc (ref_maybe_used_by_call_p_1): Ditto. + (call_may_clobber_ref_p_1): Ditto. + * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Ditto. + (dse_optimize_stmt): Ditto. + * tree-ssa-loop-ivopts.cc (get_mem_type_for_internal_fn): Ditto. + (get_alias_ptr_type_for_ptr_address): Ditto. + * tree-vect-data-refs.cc (vect_gather_scatter_fn_p): Ditto. + * tree-vect-patterns.cc (vect_recog_gather_scatter_pattern): Ditto. + * tree-vect-stmts.cc (check_load_store_for_partial_vectors): Ditto. + (vect_get_strided_load_store_ops): Ditto. + (vectorizable_store): Ditto. + (vectorizable_load): Ditto. + +2023-07-21 Haochen Jiang + + * config/i386/i386.opt: Fix a typo. + +2023-07-21 Richard Biener + + PR tree-optimization/88540 + * tree-ssa-phiopt.cc (minmax_replacement): Do not give up + with NaNs but handle the simple case by if-converting to a + COND_EXPR. + +2023-07-21 Andrew Pinski + + * match.pd (minmax,a>->minmax): New + transformation. + +2023-07-21 Richard Biener + + PR tree-optimization/110742 + * tree-vect-slp.cc (vect_optimize_slp_pass::get_result_with_layout): + Do not materialize an edge permutation in an external node with + vector defs. + (vect_slp_analyze_node_operations_1): Guard purely internal + nodes better. + +2023-07-21 Jan Hubicka + + * cfgloop.cc: Include sreal.h. + (flow_loop_dump): Dump sreal iteration exsitmate. + (get_estimated_loop_iterations): Update. + * cfgloop.h (expected_loop_iterations_by_profile): Declare. + * cfgloopanal.cc (expected_loop_iterations_by_profile): New function. + (expected_loop_iterations_unbounded): Use new API. + * cfgloopmanip.cc (scale_loop_profile): Use + expected_loop_iterations_by_profile + * predict.cc (pass_profile::execute): Likewise. + * profile.cc (branch_prob): Likewise. + * tree-ssa-loop-niter.cc: Include sreal.h. + (estimate_numbers_of_iterations): Likewise + +2023-07-21 Kewen Lin + + PR tree-optimization/110744 + * tree-ssa-sccvn.cc (vn_reference_lookup_3): Correct the index of bias + operand for ifn IFN_LEN_STORE. + +2023-07-21 liuhongt + + PR target/89701 + * common.opt: (fcf-protection=): Add EnumSet attribute to + support combination of params. + +2023-07-21 David Malcolm + + PR middle-end/110612 + * text-art/table.cc (table_geometry::table_geometry): Drop m_table + field. + (table_geometry::table_x_to_canvas_x): Add cast to comparison. + (table_geometry::table_y_to_canvas_y): Likewise. + * text-art/table.h (table_geometry::m_table): Drop unused field. + * text-art/widget.h (wrapper_widget::update_child_alloc_rects): + Add "override". + 2023-07-20 Uros Bizjak PR target/110717 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 0e7d73c..05e1afb 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230721 +20230722 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index e7565685..fe0c628 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,21 @@ +2023-07-21 David Malcolm + + PR analyzer/110455 + * region-model.cc (region_model::get_gassign_result): Only check + for bad shift counts when dealing with an integral type. + +2023-07-21 David Malcolm + + PR analyzer/110433 + PR middle-end/110612 + * access-diagram.cc (class spatial_item): Add virtual dtor. + +2023-07-21 David Malcolm + + PR analyzer/110387 + * region.h (struct cast_region::key_t): Support "m_type" being + null by using "m_original_region" for empty/deleted slots. + 2023-07-19 David Malcolm PR analyzer/110700 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index db9ce60..107456d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2023-07-21 Marek Polacek + + PR c++/110106 + * constexpr.cc (potential_constant_expression_1): Try to complete the + type when !processing_template_decl. + 2023-07-20 Marek Polacek PR c++/110114 diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index 6c3c001..571af08 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2023-07-21 Joseph Myers + + * hr.po: Update. + 2023-05-09 Joseph Myers * hr.po: Update. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c52e8ae..3a9d390 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,146 @@ +2023-07-21 John David Anglin + + * gcc.c-torture/compile/asmgoto-6.c: Require target lra. + +2023-07-21 Roger Sayle + Richard Biener + + PR c/110699 + * gcc.dg/pr110699.c: New test case. + +2023-07-21 Marek Polacek + + PR c++/110106 + * g++.dg/cpp0x/noexcept80.C: New test. + +2023-07-21 Jan Hubicka + + * gcc.dg/tree-ssa/copy-headers-9.c: Fix template for tree-ssa-loop-ch.cc changes. + * gcc.dg/tree-ssa/dce-1.c: Likewise. + +2023-07-21 Jan Hubicka + + * gcc.dg/loop-unswitch-17.c: Disable ch. + * gcc.dg/pr103079.c: Disable ch. + * gcc.dg/tree-ssa/copy-headers-7.c: Update so ch behaves + as expected. + * gcc.dg/tree-ssa/copy-headers.c: Update template. + * gcc.dg/tree-ssa/copy-headers-9.c: New test. + +2023-07-21 Richard Biener + + PR tree-optimization/41320 + * gcc.dg/tree-ssa/forwprop-12.c: Remove. + +2023-07-21 Jan Hubicka + + * gcc.dg/tree-ssa/dce-1.c: Update for new loop dumps. + +2023-07-21 Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-12.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/gather_load-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_gather_load-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/mask_scatter_store-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/scatter_store-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/gather-scatter/strided_store-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/partial/gimple_fold-1.c: Ditto. + +2023-07-21 Richard Biener + + PR tree-optimization/88540 + * gcc.target/i386/pr88540.c: New testcase. + * gcc.target/i386/pr54855-9.c: XFAIL check for redundant moves. + * gcc.target/i386/pr54855-12.c: Adjust. + * gcc.target/i386/pr54855-13.c: Likewise. + * gcc.target/i386/pr110170.c: Likewise. + * gcc.dg/tree-ssa/split-path-12.c: Likewise. + +2023-07-21 Andrew Pinski + + * gcc.dg/tree-ssa/reassoc-12.c: Disable all of + the passes that enables match-and-simplify. + * gcc.dg/tree-ssa/minmax-23.c: New test. + +2023-07-21 Richard Biener + + PR tree-optimization/110742 + * g++.dg/torture/pr110742.C: New testcase. + +2023-07-21 Kewen Lin + + PR testsuite/110729 + * gcc.dg/pr110729.c: New test. + +2023-07-21 liuhongt + + * c-c++-common/fcf-protection-10.c: New test. + * c-c++-common/fcf-protection-11.c: New test. + * c-c++-common/fcf-protection-12.c: New test. + * c-c++-common/fcf-protection-8.c: New test. + * c-c++-common/fcf-protection-9.c: New test. + * gcc.target/i386/pr89701-1.c: New test. + * gcc.target/i386/pr89701-2.c: New test. + * gcc.target/i386/pr89701-3.c: New test. + +2023-07-21 liuhongt + + * gcc.dg/pr107547.c: Add { dg-add-options float16 }. + * gcc.target/i386/float16-7.c: Add -msse2 to dg-options. + * lib/target-supports.exp (add_options_for_float16): Add + -msse2 for i?86-*-* || x86_64-*-*. + +2023-07-21 David Malcolm + + PR analyzer/110455 + * gcc.dg/analyzer/pr110455.c: New test. + +2023-07-21 David Malcolm + + PR analyzer/110387 + * gcc.dg/analyzer/out-of-bounds-pr110387.c: New test. + 2023-07-20 Gaius Mulley * gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod: New test. -- cgit v1.1 From 16894253cd152dd8e02ba48708ec8ec0a9f99e24 Mon Sep 17 00:00:00 2001 From: "Vladimir N. Makarov" Date: Fri, 21 Jul 2023 20:28:50 -0400 Subject: [LRA]: Fix sparc bootstrap after recent patch for fp elimination for avr LRA port The recent patch for fp elimination for avr LRA port modified an assert which can be wrong for targets using hard frame pointer different from frame pointer. Also for such ports spilling pseudos assigned to fp was wrong too in the new code. Although this code is not used for any target currently using LRA except for avr. Given patch fixes the issues. gcc/ChangeLog: * lra-eliminations.cc (update_reg_eliminate): Fix the assert. (lra_update_fp2sp_elimination): Use HARD_FRAME_POINTER_REGNUM instead of FRAME_POINTER_REGNUM to spill pseudos. --- gcc/lra-eliminations.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index cf0aa94..1f4e3fe 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -1179,8 +1179,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) gcc_assert (ep->to_rtx != stack_pointer_rtx || (ep->from == FRAME_POINTER_REGNUM && !elimination_fp2sp_occured_p) - || (ep->from != FRAME_POINTER_REGNUM - && ep->from < FIRST_PSEUDO_REGISTER + || (ep->from < FIRST_PSEUDO_REGISTER && fixed_regs [ep->from])); /* Mark that is not eliminable anymore. */ @@ -1398,7 +1397,7 @@ lra_update_fp2sp_elimination (void) " Frame pointer can not be eliminated anymore\n"); frame_pointer_needed = true; CLEAR_HARD_REG_SET (set); - add_to_hard_reg_set (&set, Pmode, FRAME_POINTER_REGNUM); + add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM); spill_pseudos (set); for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) -- cgit v1.1 From 73cc6ce1294ec35e9322b1bbc91009cfc76f732b Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Sat, 22 Jul 2023 10:01:02 +0100 Subject: PR modula2/110631 Bugfix to FIO WriteCardinal FIO.WriteCardinal fails to write binary data. This patch fixes two bugs in FIO.mod and provides a testcase which writes and reads binary cardinals. There was an off by one error when using HIGH (a) to determine the number of bytes and the dest/src pointers were switched when calling memcpy. gcc/m2/ChangeLog: PR modula2/110631 * gm2-libs/FIO.def (ReadAny): Correct comment as HIGH (a) + 1 is number of bytes. (WriteAny): Correct comment as HIGH (a) + 1 is number of bytes. * gm2-libs/FIO.mod (ReadAny): Correct comment as HIGH (a) + 1 is number of bytes. Also pass HIGH (a) + 1 to BufferedRead. (WriteAny): Correct comment as HIGH (a) + 1 is number of bytes. Also pass HIGH (a) + 1 to BufferedWrite. (BufferedWrite): Rename parameter a to src, rename variable t to dest. Correct parameter order to memcpy. gcc/testsuite/ChangeLog: PR modula2/110631 * gm2/pimlib/run/pass/testfiobinary.mod: New test. Signed-off-by: Gaius Mulley --- gcc/m2/gm2-libs/FIO.def | 4 +- gcc/m2/gm2-libs/FIO.mod | 56 +++++++------- .../gm2/pimlib/run/pass/testfiobinary.mod | 89 ++++++++++++++++++++++ 3 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gm2/pimlib/run/pass/testfiobinary.mod (limited to 'gcc') diff --git a/gcc/m2/gm2-libs/FIO.def b/gcc/m2/gm2-libs/FIO.def index f521ef6..f4c201f 100644 --- a/gcc/m2/gm2-libs/FIO.def +++ b/gcc/m2/gm2-libs/FIO.def @@ -159,7 +159,7 @@ PROCEDURE ReadNBytes (f: File; nBytes: CARDINAL; (* - ReadAny - reads HIGH(a) bytes into, a. All input + ReadAny - reads HIGH (a) + 1 bytes into, a. All input is fully buffered, unlike ReadNBytes and thus is more suited to small reads. *) @@ -180,7 +180,7 @@ PROCEDURE WriteNBytes (f: File; nBytes: CARDINAL; (* - WriteAny - writes HIGH(a) bytes onto, file, f. All output + WriteAny - writes HIGH (a) + 1 bytes onto, file, f. All output is fully buffered, unlike WriteNBytes and thus is more suited to small writes. *) diff --git a/gcc/m2/gm2-libs/FIO.mod b/gcc/m2/gm2-libs/FIO.mod index 1f3e22e..dd6f48c 100644 --- a/gcc/m2/gm2-libs/FIO.mod +++ b/gcc/m2/gm2-libs/FIO.mod @@ -1083,7 +1083,7 @@ END UnReadChar ; (* - ReadAny - reads HIGH(a) bytes into, a. All input + ReadAny - reads HIGH (a) + 1 bytes into, a. All input is fully buffered, unlike ReadNBytes and thus is more suited to small reads. *) @@ -1091,9 +1091,9 @@ END UnReadChar ; PROCEDURE ReadAny (f: File; VAR a: ARRAY OF BYTE) ; BEGIN CheckAccess(f, openedforread, FALSE) ; - IF BufferedRead (f, HIGH (a), ADR (a)) = VAL (INTEGER, HIGH (a)) + IF BufferedRead (f, HIGH (a) + 1, ADR (a)) = VAL (INTEGER, HIGH (a) + 1) THEN - SetEndOfLine(f, a[HIGH(a)]) + SetEndOfLine (f, a[HIGH(a)]) END END ReadAny ; @@ -1232,51 +1232,51 @@ END WriteNBytes ; Useful when performing small writes. *) -PROCEDURE BufferedWrite (f: File; nBytes: CARDINAL; a: ADDRESS) : INTEGER ; +PROCEDURE BufferedWrite (f: File; nBytes: CARDINAL; src: ADDRESS) : INTEGER ; VAR - t : ADDRESS ; + dest : ADDRESS ; total, n : INTEGER ; p : POINTER TO BYTE ; fd : FileDescriptor ; BEGIN - IF f#Error + IF f # Error THEN - fd := GetIndice(FileInfo, f) ; + fd := GetIndice (FileInfo, f) ; IF fd#NIL THEN total := 0 ; (* how many bytes have we read *) WITH fd^ DO - IF buffer#NIL + IF buffer # NIL THEN WITH buffer^ DO - WHILE nBytes>0 DO + WHILE nBytes > 0 DO (* place into the buffer first *) - IF left>0 + IF left > 0 THEN - IF nBytes=1 + IF nBytes = 1 THEN (* too expensive to call memcpy for 1 character *) - p := a ; + p := src ; contents^[position] := p^ ; - DEC(left) ; (* reduce space *) - INC(position) ; (* move onwards n byte *) - INC(total) ; + DEC (left) ; (* reduce space *) + INC (position) ; (* move onwards n byte *) + INC (total) ; RETURN( total ) ELSE - n := Min(left, nBytes) ; - t := address ; - INC(t, position) ; - p := memcpy(a, t, CARDINAL(n)) ; - DEC(left, n) ; (* remove consumed bytes *) - INC(position, n) ; (* move onwards n bytes *) - (* move ready for further writes *) - INC(a, n) ; - DEC(nBytes, n) ; (* reduce the amount for future writes *) - INC(total, n) + n := Min (left, nBytes) ; + dest := address ; + INC (dest, position) ; + p := memcpy (dest, src, CARDINAL (n)) ; + DEC (left, n) ; (* remove consumed bytes *) + INC (position, n) ; (* move onwards n bytes *) + (* move ready for further writes *) + INC (src, n) ; + DEC (nBytes, n) ; (* reduce the amount for future writes *) + INC (total, n) END ELSE - FlushBuffer(f) ; + FlushBuffer (f) ; IF (state#successful) AND (state#endofline) THEN nBytes := 0 @@ -1329,7 +1329,7 @@ END FlushBuffer ; (* - WriteAny - writes HIGH(a) bytes onto, file, f. All output + WriteAny - writes HIGH (a) + 1 bytes onto, file, f. All output is fully buffered, unlike WriteNBytes and thus is more suited to small writes. *) @@ -1337,7 +1337,7 @@ END FlushBuffer ; PROCEDURE WriteAny (f: File; VAR a: ARRAY OF BYTE) ; BEGIN CheckAccess (f, openedforwrite, TRUE) ; - IF BufferedWrite (f, HIGH (a), ADR (a)) = VAL (INTEGER, HIGH (a)) + IF BufferedWrite (f, HIGH (a) + 1, ADR (a)) = VAL (INTEGER, HIGH (a) + 1) THEN END END WriteAny ; diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testfiobinary.mod b/gcc/testsuite/gm2/pimlib/run/pass/testfiobinary.mod new file mode 100644 index 0000000..06feb84 --- /dev/null +++ b/gcc/testsuite/gm2/pimlib/run/pass/testfiobinary.mod @@ -0,0 +1,89 @@ +MODULE testfiobinary ; + +(* Simple test to stress FIO.WriteCardinal. *) + +FROM FIO IMPORT WriteCardinal, File, OpenToRead, OpenToWrite, Close, ReadNBytes, IsNoError, ReadCardinal ; +FROM libc IMPORT exit, printf ; + + +CONST + OutputName = "binary.bin" ; + Debugging = TRUE ; + + +PROCEDURE Check (bool: BOOLEAN) ; +BEGIN + IF NOT bool + THEN + printf ("check assert failed\n"); + exit (1) + END +END Check ; + + +PROCEDURE Write (f: File; card: CARDINAL) ; +BEGIN + WriteCardinal (f, card) +END Write ; + + +PROCEDURE Read (f: File; card: CARDINAL) ; +VAR + value: CARDINAL ; +BEGIN + value := ReadCardinal (f) ; + IF value # card + THEN + printf ("Read failed to read cardinal value, expecting %d and read %d\n", + card, value) ; + exit (2) + END +END Read ; + + +PROCEDURE CreateBinary ; +VAR + f: File ; +BEGIN + f := OpenToWrite (OutputName) ; + Check (IsNoError (f)) ; + IF SIZE (CARDINAL) >= 4 + THEN + Write (f, 012345678H) + END ; + Write (f, 0) ; + Write (f, 1) ; + Write (f, 2) ; + Write (f, 3) ; + Write (f, 1000) ; + Write (f, 1024) ; + Write (f, 32767) ; + Close (f) +END CreateBinary ; + + +PROCEDURE CheckBinary ; +VAR + f: File ; +BEGIN + f := OpenToRead (OutputName) ; + Check (IsNoError (f)) ; + IF SIZE (CARDINAL) >= 4 + THEN + Read (f, 012345678H) + END ; + Read (f, 0) ; + Read (f, 1) ; + Read (f, 2) ; + Read (f, 3) ; + Read (f, 1000) ; + Read (f, 1024) ; + Read (f, 32767) ; + Close (f) +END CheckBinary ; + + +BEGIN + CreateBinary ; + CheckBinary +END testfiobinary. -- cgit v1.1 From bb095e8a343db043a0cd0b0da9b2ab1186d1a1ed Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Sat, 22 Jul 2023 09:47:21 -0600 Subject: [committed] Fix length computation bug in bfin port The tester seemed to occasionally ping-pong a compilation failure on the builtin-bitops-1.c test. I long suspected it was something like length computations. I finally got a few minutes to dig into it, and sure enough the blackfin port was claiming the "ones" operation was 2 bytes when it is in fact 4 bytes. This fixes the compilation failure for the builtin-bitops-1.c test. Sadly, it doesn't fix any of the other failures on the bfin port. Committed to the trunk. gcc/ * config/bfin/bfin.md (ones): Fix length computation. --- gcc/config/bfin/bfin.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md index 9b5ab07..c6b174d 100644 --- a/gcc/config/bfin/bfin.md +++ b/gcc/config/bfin/bfin.md @@ -1401,7 +1401,8 @@ (popcount:SI (match_operand:SI 1 "register_operand" "d"))))] "" "%h0 = ONES %1;" - [(set_attr "type" "alu0")]) + [(set_attr "type" "alu0") + (set_attr "length" "4")]) (define_expand "popcountsi2" [(set (match_dup 2) -- cgit v1.1 From 6ed43713e4c894c196ee07991aa25e09322f8ab4 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 22 Jul 2023 17:48:09 +0100 Subject: testsuite: Limit bb-slp-pr95839-v8.c to 64-bit vector targets Only run bb-slp-pr95839-v8.c with targets that support vectors of 64 bits, removing regressions with 32-bit x86 targets: FAIL: gcc.dg/vect/bb-slp-pr95839-v8.c scan-tree-dump slp2 "optimized: basic block" FAIL: gcc.dg/vect/bb-slp-pr95839-v8.c -flto -ffat-lto-objects scan-tree-dump slp2 "optimized: basic block" gcc/testsuite/ * gcc.dg/vect/bb-slp-pr95839-v8.c: Limit to `vect64' targets. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c index 9a02107..fea7f00 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-v8.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect64 } */ /* { dg-additional-options "-w -Wno-psabi" } */ typedef float __attribute__((vector_size(8))) v2f32; -- cgit v1.1 From 59c38ddfe052a409a690380d0378169f4a3936ad Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sat, 22 Jul 2023 21:50:06 +0100 Subject: i386: Use QImode for offsets in zero_extract/sign_extract in i386.md As suggested by Uros, this patch changes the ZERO_EXTRACTs and SIGN_EXTRACTs in i386.md to consistently use QImode for bit offsets (i.e. third and fourth operands), matching the use of QImode for bit counts in shifts and rotates. There's no change in functionality, and the new patterns simply ensure that we continue to generate the same code (match revised patterns) as before. 2023-07-22 Roger Sayle gcc/ChangeLog * config/i386/i386.md (extv): Use QImode for offsets. (extzv): Likewise. (insv): Likewise. (*testqi_ext_3): Likewise. (*btr_2): Likewise. (define_split): Likewise. (*btsq_imm): Likewise. (*btrq_imm): Likewise. (*btcq_imm): Likewise. (define_peephole2 x3): Likewise. (*bt): Likewise (*bt_mask): New define_insn_and_split. (*jcc_bt): Use QImode for offsets. (*jcc_bt_1): Delete obsolete pattern. (*jcc_bt_mask): Use QImode offsets. (*jcc_bt_mask_1): Likewise. (define_split): Likewise. (*bt_setcqi): Likewise. (*bt_setncqi): Likewise. (*bt_setnc): Likewise. (*bt_setncqi_2): Likewise. (*bt_setc_mask): New define_insn_and_split. (bmi2_bzhi_3): Use QImode offsets. (*bmi2_bzhi_3): Likewise. (*bmi2_bzhi_3_1): Likewise. (*bmi2_bzhi_3_1_ccz): Likewise. (@tbm_bextri_): Likewise. --- gcc/config/i386/i386.md | 212 +++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 109 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4db210c..2ce8e95 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3312,8 +3312,8 @@ (define_expand "extv" [(set (match_operand:SWI24 0 "register_operand") (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand") - (match_operand:SI 2 "const_int_operand") - (match_operand:SI 3 "const_int_operand")))] + (match_operand:QI 2 "const_int_operand") + (match_operand:QI 3 "const_int_operand")))] "" { /* Handle extractions from %ah et al. */ @@ -3340,8 +3340,8 @@ (define_expand "extzv" [(set (match_operand:SWI248 0 "register_operand") (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand") - (match_operand:SI 2 "const_int_operand") - (match_operand:SI 3 "const_int_operand")))] + (match_operand:QI 2 "const_int_operand") + (match_operand:QI 3 "const_int_operand")))] "" { if (ix86_expand_pextr (operands)) @@ -3428,8 +3428,8 @@ (define_expand "insv" [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand") - (match_operand:SI 1 "const_int_operand") - (match_operand:SI 2 "const_int_operand")) + (match_operand:QI 1 "const_int_operand") + (match_operand:QI 2 "const_int_operand")) (match_operand:SWI248 3 "register_operand"))] "" { @@ -10788,8 +10788,8 @@ (match_operator 1 "compare_operator" [(zero_extract:SWI248 (match_operand 2 "int_nonimmediate_operand" "rm") - (match_operand 3 "const_int_operand") - (match_operand 4 "const_int_operand")) + (match_operand:QI 3 "const_int_operand") + (match_operand:QI 4 "const_int_operand")) (const_int 0)]))] "/* Ensure that resulting mask is zero or sign extended operand. */ INTVAL (operands[4]) >= 0 @@ -15965,7 +15965,7 @@ [(set (zero_extract:HI (match_operand:SWI12 0 "nonimmediate_operand") (const_int 1) - (zero_extend:SI (match_operand:QI 1 "register_operand"))) + (match_operand:QI 1 "register_operand")) (const_int 0)) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" @@ -15989,7 +15989,7 @@ [(set (zero_extract:HI (match_operand:SWI12 0 "register_operand") (const_int 1) - (zero_extend:SI (match_operand:QI 1 "register_operand"))) + (match_operand:QI 1 "register_operand")) (const_int 0)) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" @@ -16016,7 +16016,7 @@ (define_insn "*btsq_imm" [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") (const_int 1) - (match_operand 1 "const_0_to_63_operand")) + (match_operand:QI 1 "const_0_to_63_operand")) (const_int 1)) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -16029,7 +16029,7 @@ (define_insn "*btrq_imm" [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") (const_int 1) - (match_operand 1 "const_0_to_63_operand")) + (match_operand:QI 1 "const_0_to_63_operand")) (const_int 0)) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -16042,7 +16042,7 @@ (define_insn "*btcq_imm" [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") (const_int 1) - (match_operand 1 "const_0_to_63_operand")) + (match_operand:QI 1 "const_0_to_63_operand")) (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -16059,7 +16059,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand") (const_int 1) - (match_operand 1 "const_0_to_63_operand")) + (match_operand:QI 1 "const_0_to_63_operand")) (const_int 1)) (clobber (reg:CC FLAGS_REG))])] "TARGET_64BIT && !TARGET_USE_BT" @@ -16083,7 +16083,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand") (const_int 1) - (match_operand 1 "const_0_to_63_operand")) + (match_operand:QI 1 "const_0_to_63_operand")) (const_int 0)) (clobber (reg:CC FLAGS_REG))])] "TARGET_64BIT && !TARGET_USE_BT" @@ -16107,7 +16107,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand") (const_int 1) - (match_operand 1 "const_0_to_63_operand")) + (match_operand:QI 1 "const_0_to_63_operand")) (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))])] @@ -16135,14 +16135,14 @@ (zero_extract:SWI48 (match_operand:SWI48 0 "nonimmediate_operand" "r,m") (const_int 1) - (match_operand:SI 1 "nonmemory_operand" "r,")) + (match_operand:QI 1 "nonmemory_operand" "q,")) (const_int 0)))] "" { switch (get_attr_mode (insn)) { case MODE_SI: - return "bt{l}\t{%1, %k0|%k0, %1}"; + return "bt{l}\t{%k1, %k0|%k0, %k1}"; case MODE_DI: return "bt{q}\t{%q1, %0|%0, %q1}"; @@ -16160,13 +16160,36 @@ (const_string "SI") (const_string "")))]) +(define_insn_and_split "*bt_mask" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 + (match_operand:SWI48 0 "nonimmediate_operand" "r,m") + (const_int 1) + (subreg:QI + (and:SWI248 + (match_operand:SWI248 1 "register_operand") + (match_operand 2 "const_int_operand")) 0)) + (const_int 0)))] + "TARGET_USE_BT + && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode)-1)) + == GET_MODE_BITSIZE (mode)-1 + && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1)) + (const_int 0)))] + "operands[1] = gen_lowpart (QImode, operands[1]);") + (define_insn_and_split "*jcc_bt" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" [(zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") (const_int 1) - (match_operand:SI 2 "nonmemory_operand")) + (match_operand:QI 2 "nonmemory_operand")) (const_int 0)]) (label_ref (match_operand 3)) (pc))) @@ -16196,39 +16219,6 @@ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) -(define_insn_and_split "*jcc_bt_1" - [(set (pc) - (if_then_else (match_operator 0 "bt_comparison_operator" - [(zero_extract:SWI48 - (match_operand:SWI48 1 "register_operand") - (const_int 1) - (zero_extend:SI - (match_operand:QI 2 "register_operand"))) - (const_int 0)]) - (label_ref (match_operand 3)) - (pc))) - (clobber (reg:CC FLAGS_REG))] - "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) - && ix86_pre_reload_split ()" - "#" - "&& 1" - [(set (reg:CCC FLAGS_REG) - (compare:CCC - (zero_extract:SWI48 - (match_dup 1) - (const_int 1) - (match_dup 2)) - (const_int 0))) - (set (pc) - (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) - (label_ref (match_dup 3)) - (pc)))] -{ - operands[2] = lowpart_subreg (SImode, operands[2], QImode); - operands[0] = shallow_copy_rtx (operands[0]); - PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); -}) - ;; Avoid useless masking of bit offset operand. (define_insn_and_split "*jcc_bt_mask" [(set (pc) @@ -16236,8 +16226,8 @@ [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (and:SI - (match_operand:SI 2 "register_operand") + (and:QI + (match_operand:QI 2 "register_operand") (match_operand 3 "const_int_operand")))]) (label_ref (match_operand 4)) (pc))) @@ -16264,23 +16254,23 @@ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) -(define_insn_and_split "*jcc_bt_mask_1" +;; Avoid useless masking of bit offset operand. +(define_insn_and_split "*jcc_bt_mask_1" [(set (pc) - (if_then_else (match_operator 0 "bt_comparison_operator" + (if_then_else (match_operator 0 "bt_comparison_operator" [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (zero_extend:SI - (subreg:QI - (and - (match_operand 2 "int248_register_operand") - (match_operand 3 "const_int_operand")) 0)))]) + (subreg:QI + (and:SWI248 + (match_operand:SWI248 2 "register_operand") + (match_operand 3 "const_int_operand")) 0))]) (label_ref (match_operand 4)) (pc))) (clobber (reg:CC FLAGS_REG))] "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) - && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1)) - == GET_MODE_BITSIZE (mode)-1 + && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1)) + == GET_MODE_BITSIZE (mode)-1 && ix86_pre_reload_split ()" "#" "&& 1" @@ -16296,10 +16286,9 @@ (label_ref (match_dup 4)) (pc)))] { - operands[2] = force_reg (GET_MODE (operands[2]), operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); + operands[2] = gen_lowpart (QImode, operands[2]); }) ;; Help combine recognize bt followed by cmov @@ -16310,7 +16299,7 @@ [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (zero_extend:SI (match_operand:QI 2 "register_operand"))) + (match_operand:QI 2 "register_operand")) (const_int 0)]) (match_operand:SWI248 3 "nonimmediate_operand") (match_operand:SWI248 4 "nonimmediate_operand")))] @@ -16328,7 +16317,6 @@ { if (GET_CODE (operands[5]) == EQ) std::swap (operands[3], operands[4]); - operands[2] = lowpart_subreg (SImode, operands[2], QImode); }) ;; Help combine recognize bt followed by setc @@ -16337,7 +16325,7 @@ (zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (zero_extend:SI (match_operand:QI 2 "register_operand")))) + (match_operand:QI 2 "register_operand"))) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" "#" @@ -16347,8 +16335,7 @@ (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) - (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] - "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") + (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]) ;; Help combine recognize bt followed by setnc (define_insn_and_split "*bt_setncqi" @@ -16368,8 +16355,7 @@ (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) - (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] - "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") + (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]) (define_insn_and_split "*bt_setnc" [(set (match_operand:SWI48 0 "register_operand") @@ -16389,10 +16375,7 @@ (set (match_dup 3) (ne:QI (reg:CCC FLAGS_REG) (const_int 0))) (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))] -{ - operands[2] = lowpart_subreg (SImode, operands[2], QImode); - operands[3] = gen_reg_rtx (QImode); -}) + "operands[3] = gen_reg_rtx (QImode);") ;; Help combine recognize bt followed by setnc (PR target/110588) (define_insn_and_split "*bt_setncqi_2" @@ -16401,7 +16384,7 @@ (zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (zero_extend:SI (match_operand:QI 2 "register_operand"))) + (match_operand:QI 2 "register_operand")) (const_int 0))) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" @@ -16412,8 +16395,36 @@ (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) - (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] - "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") + (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]) + +;; Help combine recognize bt followed by setc +(define_insn_and_split "*bt_setc_mask" + [(set (match_operand:SWI48 0 "register_operand") + (zero_extract:SWI48 + (match_operand:SWI48 1 "register_operand") + (const_int 1) + (subreg:QI + (and:SWI48 + (match_operand:SWI48 2 "register_operand") + (match_operand 3 "const_int_operand")) 0))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_USE_BT + && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1)) + == GET_MODE_BITSIZE (mode)-1 + && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) + (const_int 0))) + (set (match_dup 3) + (ne:QI (reg:CCC FLAGS_REG) (const_int 0))) + (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))] +{ + operands[2] = gen_lowpart (QImode, operands[2]); + operands[3] = gen_reg_rtx (QImode); +}) ;; Store-flag instructions. @@ -18708,46 +18719,29 @@ [(parallel [(set (match_operand:SWI48 0 "register_operand") (if_then_else:SWI48 - (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand") - (const_int 255)) + (ne:QI (match_operand:QI 2 "register_operand") (const_int 0)) (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") - (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255)) - (match_dup 3)) + (umin:QI (match_dup 2) (match_dup 3)) (const_int 0)) (const_int 0))) (clobber (reg:CC FLAGS_REG))])] "TARGET_BMI2" - "operands[3] = GEN_INT ( * BITS_PER_UNIT);") +{ + operands[2] = gen_lowpart (QImode, operands[2]); + operands[3] = GEN_INT ( * BITS_PER_UNIT); +}) (define_insn "*bmi2_bzhi_3" [(set (match_operand:SWI48 0 "register_operand" "=r") (if_then_else:SWI48 - (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r") - (const_int 255)) + (ne:QI (match_operand:QI 2 "register_operand" "q") (const_int 0)) (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255)) - (match_operand:SWI48 3 "const_int_operand")) - (const_int 0)) - (const_int 0))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_BMI2 && INTVAL (operands[3]) == * BITS_PER_UNIT" - "bzhi\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "type" "bitmanip") - (set_attr "prefix" "vex") - (set_attr "mode" "")]) - -(define_insn "*bmi2_bzhi_3_1" - [(set (match_operand:SWI48 0 "register_operand" "=r") - (if_then_else:SWI48 - (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0)) - (zero_extract:SWI48 - (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (umin:SWI48 (zero_extend:SWI48 (match_dup 2)) - (match_operand:SWI48 3 "const_int_operand")) + (umin:QI (match_dup 2) + (match_operand:QI 3 "const_int_operand")) (const_int 0)) (const_int 0))) (clobber (reg:CC FLAGS_REG))] @@ -18764,8 +18758,8 @@ (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0)) (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (umin:SWI48 (zero_extend:SWI48 (match_dup 2)) - (match_operand:SWI48 3 "const_int_operand")) + (umin:QI (match_dup 2) + (match_operand:QI 3 "const_int_operand")) (const_int 0)) (const_int 0)) (const_int 0))) @@ -18864,8 +18858,8 @@ [(set (match_operand:SWI48 0 "register_operand" "=r") (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (match_operand 2 "const_0_to_255_operand") - (match_operand 3 "const_0_to_255_operand"))) + (match_operand:QI 2 "const_0_to_255_operand") + (match_operand:QI 3 "const_0_to_255_operand"))) (clobber (reg:CC FLAGS_REG))] "TARGET_TBM" { -- cgit v1.1 From 659d856e1d424ea8ef634844a7bd08b86ec7344b Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 22 Jul 2023 20:34:41 +0000 Subject: Fix alpha building The problem is after r14-2587-gd8105b10fff951, the definition of extended_count now takes a bool as its last argument but we only have a declaration for the version which takes an int as the last argument. This fixes the problem by changing the declaration to be a bool too. Committed as obvious after building a cross to alpha-linux-gnu. gcc/ChangeLog: PR target/110778 * rtl.h (extended_count): Change last argument type to bool. --- gcc/rtl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/rtl.h b/gcc/rtl.h index 03b7d05..e1c5115 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -4214,7 +4214,7 @@ extern bool validate_subreg (machine_mode, machine_mode, const_rtx, poly_uint64); /* In combine.cc */ -extern unsigned int extended_count (const_rtx, machine_mode, int); +extern unsigned int extended_count (const_rtx, machine_mode, bool); extern rtx remove_death (unsigned int, rtx_insn *); extern rtx make_compound_operation (rtx, enum rtx_code); -- cgit v1.1 From 8125b12f846b41f26e58c0fe3b218d654f65d1c8 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sat, 22 Jul 2023 21:52:55 +0100 Subject: i386: Don't use insvti_{high,low}part with -O0 (for compile-time). This patch attempts to help with PR rtl-optimization/110587, a regression of -O0 compile time for the pathological pr28071.c. My recent patch helps a bit, but hasn't returned -O0 compile-time to where it was before my ix86_expand_move changes. The obvious solution/workaround is to guard these new TImode parameter passing optimizations with "&& optimize", so they don't trigger when compiling with -O0. The very minor complication is that "&& optimize" alone leads to the regression of pr110533.c, where our improved TImode parameter passing fixes a wrong-code issue with naked functions, importantly, when compiling with -O0. This should explain the one line fix below "&& (optimize || ix86_function_naked (cfun))". I've an additional fix/tweak or two for this compile-time issue, but this change eliminates the part of the regression that I've caused. 2023-07-22 Roger Sayle gcc/ChangeLog * config/i386/i386-expand.cc (ix86_expand_move): Disable the 64-bit insertions into TImode optimizations with -O0, unless the function has the "naked" attribute (for PR target/110533). --- gcc/config/i386/i386-expand.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index a5c000f..0421909 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -544,6 +544,8 @@ ix86_expand_move (machine_mode mode, rtx operands[]) /* Special case inserting 64-bit values into a TImode register. */ if (TARGET_64BIT + /* Disable for -O0 (see PR110587) unless naked (PR110533). */ + && (optimize || ix86_function_naked (current_function_decl)) && (mode == DImode || mode == DFmode) && SUBREG_P (op0) && GET_MODE (SUBREG_REG (op0)) == TImode -- cgit v1.1 From ecfa870ff29d979bd2c3d411643b551f2b6915b0 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 20 Jul 2023 11:15:37 -0700 Subject: RISC-V: optim const DF +0.0 store to mem [PR/110748] Fixes: ef85d150b5963 ("RISC-V: Enable TARGET_SUPPORTS_WIDE_INT") DF +0.0 is bitwise all zeros so int x0 store to mem can be used to optimize it. void zd(double *) { *d = 0.0; } currently: | fmv.d.x fa5,zero | fsd fa5,0(a0) | ret With patch | sd zero,0(a0) | ret The fix updates predicate const_0_operand() so reg_or_0_operand () now includes const_double, enabling movdf expander -> riscv_legitimize_move () to generate below vs. an intermediate set (reg:DF) const_double:DF | (insn 6 3 0 2 (set (mem:DF (reg/v/f:DI 134 [ d ]) | (const_double:DF 0.0 [0x0.0p+0])) This change also enables such insns to be recog() by later passes. The md pattern "*movdf_hardfloat_rv64" despite already supporting the needed constraints {"m","G"} mem/const 0.0 was failing to match because the additional condition check reg_or_0_operand() was failing due to missing const_double. This failure to recog() was triggering an ICE when testing the in-flight f-m-o patches and is how all of this started, but then was deemed to be an independent optimization of it's own [1]. [1] https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624857.html Its worthwhile to note all the set peices were already there and working up until my own commit mentioned at top regressed the whole thing. Ran thru full multilib testsuite and no surprises. There was 1 false failure due to random string "lw" appearing in lto build assembler output, which is also fixed here. gcc/ChangeLog: PR target/110748 * config/riscv/predicates.md (const_0_operand): Add back const_double. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr110748-1.c: New Test. * gcc.target/riscv/xtheadfmv-fmv.c: Add '\t' around test patterns to avoid random string matches. Signed-off-by: Vineet Gupta --- gcc/config/riscv/predicates.md | 2 +- gcc/testsuite/gcc.target/riscv/pr110748-1.c | 10 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c | 8 ++++---- 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/pr110748-1.c (limited to 'gcc') diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 5a22c77..9db28c2 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -58,7 +58,7 @@ (match_test "INTVAL (op) + 1 != 0"))) (define_predicate "const_0_operand" - (and (match_code "const_int,const_wide_int,const_vector") + (and (match_code "const_int,const_wide_int,const_double,const_vector") (match_test "op == CONST0_RTX (GET_MODE (op))"))) (define_predicate "const_1_operand" diff --git a/gcc/testsuite/gcc.target/riscv/pr110748-1.c b/gcc/testsuite/gcc.target/riscv/pr110748-1.c new file mode 100644 index 0000000..2f5bc08a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr110748-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target hard_float } */ +/* { dg-options "-march=rv64g -mabi=lp64d -O2" } */ + + +void zd(double *d) { *d = 0.0; } +void zf(float *f) { *f = 0.0; } + +/* { dg-final { scan-assembler-not "\tfmv\\.d\\.x\t" } } */ +/* { dg-final { scan-assembler-not "\tfmv\\.s\\.x\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c b/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c index 1036044..89eb48b 100644 --- a/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c @@ -18,7 +18,7 @@ d2ll (double d) /* { dg-final { scan-assembler "th.fmv.hw.x" } } */ /* { dg-final { scan-assembler "fmv.x.w" } } */ /* { dg-final { scan-assembler "th.fmv.x.hw" } } */ -/* { dg-final { scan-assembler-not "sw" } } */ -/* { dg-final { scan-assembler-not "fld" } } */ -/* { dg-final { scan-assembler-not "fsd" } } */ -/* { dg-final { scan-assembler-not "lw" } } */ +/* { dg-final { scan-assembler-not "\tsw\t" } } */ +/* { dg-final { scan-assembler-not "\tfld\t" } } */ +/* { dg-final { scan-assembler-not "\tfsd\t" } } */ +/* { dg-final { scan-assembler-not "\tlw\t" } } */ -- cgit v1.1 From f33fdf9e7c0386397576330db880c2ba85314a9c Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 23 Jul 2023 00:17:30 +0000 Subject: Daily bump. --- gcc/ChangeLog | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/m2/ChangeLog | 15 +++++++++++++ gcc/testsuite/ChangeLog | 15 +++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 835fec3..2eab466 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,61 @@ +2023-07-22 Vineet Gupta + + PR target/110748 + * config/riscv/predicates.md (const_0_operand): Add back + const_double. + +2023-07-22 Roger Sayle + + * config/i386/i386-expand.cc (ix86_expand_move): Disable the + 64-bit insertions into TImode optimizations with -O0, unless + the function has the "naked" attribute (for PR target/110533). + +2023-07-22 Andrew Pinski + + PR target/110778 + * rtl.h (extended_count): Change last argument type + to bool. + +2023-07-22 Roger Sayle + + * config/i386/i386.md (extv): Use QImode for offsets. + (extzv): Likewise. + (insv): Likewise. + (*testqi_ext_3): Likewise. + (*btr_2): Likewise. + (define_split): Likewise. + (*btsq_imm): Likewise. + (*btrq_imm): Likewise. + (*btcq_imm): Likewise. + (define_peephole2 x3): Likewise. + (*bt): Likewise + (*bt_mask): New define_insn_and_split. + (*jcc_bt): Use QImode for offsets. + (*jcc_bt_1): Delete obsolete pattern. + (*jcc_bt_mask): Use QImode offsets. + (*jcc_bt_mask_1): Likewise. + (define_split): Likewise. + (*bt_setcqi): Likewise. + (*bt_setncqi): Likewise. + (*bt_setnc): Likewise. + (*bt_setncqi_2): Likewise. + (*bt_setc_mask): New define_insn_and_split. + (bmi2_bzhi_3): Use QImode offsets. + (*bmi2_bzhi_3): Likewise. + (*bmi2_bzhi_3_1): Likewise. + (*bmi2_bzhi_3_1_ccz): Likewise. + (@tbm_bextri_): Likewise. + +2023-07-22 Jeff Law + + * config/bfin/bfin.md (ones): Fix length computation. + +2023-07-22 Vladimir N. Makarov + + * lra-eliminations.cc (update_reg_eliminate): Fix the assert. + (lra_update_fp2sp_elimination): Use HARD_FRAME_POINTER_REGNUM + instead of FRAME_POINTER_REGNUM to spill pseudos. + 2023-07-21 Roger Sayle Richard Biener diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 05e1afb..15985d1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230722 +20230723 diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 5197a00..519353a 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,18 @@ +2023-07-22 Gaius Mulley + + PR modula2/110631 + * gm2-libs/FIO.def (ReadAny): Correct comment as + HIGH (a) + 1 is number of bytes. + (WriteAny): Correct comment as HIGH (a) + 1 is number of + bytes. + * gm2-libs/FIO.mod (ReadAny): Correct comment as + HIGH (a) + 1 is number of bytes. Also pass HIGH (a) + 1 + to BufferedRead. + (WriteAny): Correct comment as HIGH (a) + 1 is number of + bytes. Also pass HIGH (a) + 1 to BufferedWrite. + (BufferedWrite): Rename parameter a to src, rename variable + t to dest. Correct parameter order to memcpy. + 2023-07-20 Gaius Mulley * gm2-compiler/M2SymInit.mod (IsExempt): Remove parameter exemption. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a9d390..b11b463 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2023-07-22 Vineet Gupta + + * gcc.target/riscv/pr110748-1.c: New Test. + * gcc.target/riscv/xtheadfmv-fmv.c: Add '\t' around test + patterns to avoid random string matches. + +2023-07-22 Maciej W. Rozycki + + * gcc.dg/vect/bb-slp-pr95839-v8.c: Limit to `vect64' targets. + +2023-07-22 Gaius Mulley + + PR modula2/110631 + * gm2/pimlib/run/pass/testfiobinary.mod: New test. + 2023-07-21 John David Anglin * gcc.c-torture/compile/asmgoto-6.c: Require target lra. -- cgit v1.1 From 82c2a34b2f2c1a06eff672eba2e447b53f35d7b0 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 24 Jul 2023 00:16:51 +0000 Subject: Daily bump. --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 15985d1..03f4ad7 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230723 +20230724 -- cgit v1.1 From 73ff915a169bf3f4b15c75fa3b6e658f7fe86b46 Mon Sep 17 00:00:00 2001 From: Pan Li Date: Fri, 21 Jul 2023 16:50:08 +0800 Subject: RISC-V: Bugfix for allowing incorrect dyn for static rounding According to the spec, dyn rounding mode is invalid for RVV floating-point, this patch would like to fix this. Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/riscv-vector-builtins-shapes.cc (struct alu_frm_def): Take range check. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-error.c: Update cases. * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: Removed. --- gcc/config/riscv/riscv-vector-builtins-shapes.cc | 3 +- .../riscv/rvv/base/float-point-frm-error.c | 6 ++-- .../riscv/rvv/base/float-point-frm-insert-6.c | 33 ---------------------- 3 files changed, 4 insertions(+), 38 deletions(-) delete mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c (limited to 'gcc') diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index 69a6710..22b5fe2 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -285,8 +285,7 @@ struct alu_frm_def : public build_base { unsigned int frm_num = c.arg_num () - 2; - return c.require_immediate_range_or (frm_num, FRM_STATIC_MIN, - FRM_STATIC_MAX, FRM_DYN); + return c.require_immediate (frm_num, FRM_STATIC_MIN, FRM_STATIC_MAX); } return true; diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c index 4ebaa15..01d82d4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-error.c @@ -7,9 +7,9 @@ typedef float float32_t; void test_float_point_frm_error (float32_t *out, vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { - vfloat32m1_t v1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 5, vl); /* { dg-error {passing 5 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\] or 7} } */ - vfloat32m1_t v2 = __riscv_vfadd_vv_f32m1_rm (v1, v1, 6, vl); /* { dg-error {passing 6 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\] or 7} } */ - vfloat32m1_t v3 = __riscv_vfadd_vv_f32m1_rm (v2, v2, 8, vl); /* { dg-error {passing 8 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\] or 7} } */ + vfloat32m1_t v1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 5, vl); /* { dg-error {passing 5 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\]} } */ + vfloat32m1_t v2 = __riscv_vfadd_vv_f32m1_rm (v1, v1, 6, vl); /* { dg-error {passing 6 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\]} } */ + vfloat32m1_t v3 = __riscv_vfadd_vv_f32m1_rm (v2, v2, 8, vl); /* { dg-error {passing 8 to argument 3 of '__riscv_vfadd_vv_f32m1_rm', which expects a value in the range \[0, 4\]} } */ __riscv_vse32_v_f32m1 (out, v3, vl); } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c deleted file mode 100644 index 1ef0e01..0000000 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c +++ /dev/null @@ -1,33 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ - -#include "riscv_vector.h" - -typedef float float32_t; - -vfloat32m1_t -test_riscv_vfadd_vv_f32m1_rm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { - return __riscv_vfadd_vv_f32m1_rm (op1, op2, 7, vl); -} - -vfloat32m1_t -test_vfadd_vv_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, vfloat32m1_t op2, - size_t vl) { - return __riscv_vfadd_vv_f32m1_m_rm(mask, op1, op2, 7, vl); -} - -vfloat32m1_t -test_vfadd_vf_f32m1_rm(vfloat32m1_t op1, float32_t op2, size_t vl) { - return __riscv_vfadd_vf_f32m1_rm(op1, op2, 7, vl); -} - -vfloat32m1_t -test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2, - size_t vl) { - return __riscv_vfadd_vf_f32m1_m_rm(mask, op1, op2, 7, vl); -} - -/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */ -/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */ -/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */ -/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */ -- cgit v1.1 From d07504725973ccdec78929a09dc13e5ebd9472f6 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Mon, 24 Jul 2023 01:20:30 -0500 Subject: vect: Don't vectorize a single scalar iteration loop [PR110740] The function vect_update_epilogue_niters which has been removed by r14-2281 has some code taking care of that if there is only one scalar iteration left for epilogue then we won't try to vectorize it any more. Although costing should be able to care about it eventually, I think we still want this special casing without costing enabled, so this patch is to add it back in function vect_analyze_loop_costing, and make it more general for both main and epilogue loops as Richi suggested, it can fix some exposed failures on Power10: - gcc.target/powerpc/p9-vec-length-epil-{1,8}.c - gcc.dg/vect/slp-perm-{1,5,6,7}.c PR tree-optimization/110740 gcc/ChangeLog: * tree-vect-loop.cc (vect_analyze_loop_costing): Do not vectorize a loop with a single scalar iteration. --- gcc/tree-vect-loop.cc | 55 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index d036a7d..71589b2 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -2158,8 +2158,7 @@ vect_analyze_loop_costing (loop_vec_info loop_vinfo, epilogue we can also decide whether the main loop leaves us with enough iterations, prefering a smaller vector epilog then also possibly used for the case we skip the vector loop. */ - if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) - && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) + if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) { widest_int scalar_niters = wi::to_widest (LOOP_VINFO_NITERSM1 (loop_vinfo)) + 1; @@ -2182,32 +2181,46 @@ vect_analyze_loop_costing (loop_vec_info loop_vinfo, % lowest_vf + gap); } } - - /* Check that the loop processes at least one full vector. */ - poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); - if (known_lt (scalar_niters, vf)) + /* Reject vectorizing for a single scalar iteration, even if + we could in principle implement that using partial vectors. */ + unsigned peeling_gap = LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo); + if (scalar_niters <= peeling_gap + 1) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "loop does not have enough iterations " - "to support vectorization.\n"); + "not vectorized: loop only has a single " + "scalar iteration.\n"); return 0; } - /* If we need to peel an extra epilogue iteration to handle data - accesses with gaps, check that there are enough scalar iterations - available. - - The check above is redundant with this one when peeling for gaps, - but the distinction is useful for diagnostics. */ - if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) - && known_le (scalar_niters, vf)) + if (!LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "loop does not have enough iterations " - "to support peeling for gaps.\n"); - return 0; + /* Check that the loop processes at least one full vector. */ + poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); + if (known_lt (scalar_niters, vf)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "loop does not have enough iterations " + "to support vectorization.\n"); + return 0; + } + + /* If we need to peel an extra epilogue iteration to handle data + accesses with gaps, check that there are enough scalar iterations + available. + + The check above is redundant with this one when peeling for gaps, + but the distinction is useful for diagnostics. */ + if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) + && known_le (scalar_niters, vf)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "loop does not have enough iterations " + "to support peeling for gaps.\n"); + return 0; + } } } -- cgit v1.1 From fb132cdfb204bc12851eb1d5852eef6f03c13af3 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 24 Jul 2023 08:40:19 +0200 Subject: tree-optimization/110766 - missing PHI location check The following adds a missing PHI location check before querying the loop latch PHI arg from it. PR tree-optimization/110766 * tree-scalar-evolution.cc (analyze_and_compute_bitwise_induction_effect): Check the PHI is defined in the loop header. * gcc.dg/torture/pr110766.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr110766.c | 17 +++++++++++++++++ gcc/tree-scalar-evolution.cc | 1 + 2 files changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr110766.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/torture/pr110766.c b/gcc/testsuite/gcc.dg/torture/pr110766.c new file mode 100644 index 0000000..97dcacf --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110766.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +int a, b, c, e; +short d, f; +int g(int h) { return h > a ? h : h << a; } +int main() { + while (e) { + b = 0; + for (; b < 3; b++) + if (c) { + e = g(1); + f = e | d; + } + d = 0; + } + return 0; +} diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc index 2abe8fa..3fb6951 100644 --- a/gcc/tree-scalar-evolution.cc +++ b/gcc/tree-scalar-evolution.cc @@ -3519,6 +3519,7 @@ analyze_and_compute_bitwise_induction_effect (class loop* loop, if (!gimple_bitwise_induction_p (phidef, &match_op[0], NULL) || TREE_CODE (match_op[2]) != SSA_NAME || !(header_phi = dyn_cast (SSA_NAME_DEF_STMT (match_op[2]))) + || gimple_bb (header_phi) != loop->header || gimple_phi_num_args (header_phi) != 2) return NULL_TREE; -- cgit v1.1 From 50b5feaa94c26d01fed13f1119f025ae2bc75d2b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 24 Jul 2023 08:55:11 +0200 Subject: tree-optimization/110777 - abnormals and recent PRE optimization The following avoids propagating abnormals with the recent tweak to look through PRE introduced copies between equal values. PR tree-optimization/110777 * tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_avail): Avoid propagating abnormals. * gcc.dg/pr110777.c: New testcase. --- gcc/testsuite/gcc.dg/pr110777.c | 22 ++++++++++++++++++++++ gcc/tree-ssa-sccvn.cc | 4 +++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/pr110777.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/pr110777.c b/gcc/testsuite/gcc.dg/pr110777.c new file mode 100644 index 0000000..253c2a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110777.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -w" } */ + +void pm_message (int); +int *findOrAddBackgroundInPalette_palette_pnm; +static void findOrAddBackgroundInPalette(unsigned *paletteSizeP, + int *backgroundIndexP) { + if (*paletteSizeP) { + *backgroundIndexP = (*paletteSizeP)++; + pm_message(0); + } + pm_message(findOrAddBackgroundInPalette_palette_pnm[*backgroundIndexP]); +} +void computeColorMap(int *backgroundIndexP) { + unsigned paletteSize; + findOrAddBackgroundInPalette(&paletteSize, backgroundIndexP); +} +int main() { + unsigned backgroundIndex; + _setjmp(); + computeColorMap(&backgroundIndex); +} diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index ebe8006..32e06fa 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -6608,7 +6608,9 @@ eliminate_dom_walker::eliminate_avail (basic_block, tree op) if (gimple_assign_rhs_class (ass) == GIMPLE_SINGLE_RHS) { tree rhs1 = gimple_assign_rhs1 (ass); - if (CONSTANT_CLASS_P (rhs1) || TREE_CODE (rhs1) == SSA_NAME) + if (CONSTANT_CLASS_P (rhs1) + || (TREE_CODE (rhs1) == SSA_NAME + && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))) av = rhs1; } return av; -- cgit v1.1 From 42b17d00c33dd9994dee973c001d85dc09b79b24 Mon Sep 17 00:00:00 2001 From: Ju-Zhe Zhong Date: Sun, 23 Jul 2023 12:23:33 +0800 Subject: VECT: Support floating-point in-order reduction for length loop control Hi, Richard and Richi. This patch support floating-point in-order reduction for loop length control. Consider this following case: float foo (float *__restrict a, int n) { float result = 1.0; for (int i = 0; i < n; i++) result += a[i]; return result; } When compile with **NO** -ffast-math on ARM SVE, we will end up with: loop_mask = WHILE_ULT result = MASK_FOLD_LEFT_PLUS (...loop_mask...) For RVV, we don't use length loop control instead of mask: So, with this patch, we expect to see: loop_len = SELECT_VL result = MASK_LEN_FOLD_LEFT_PLUS (...loop_len...) gcc/ChangeLog: * tree-vect-loop.cc (get_masked_reduction_fn): Add mask_len_fold_left_plus. (vectorize_fold_left_reduction): Ditto. (vectorizable_reduction): Ditto. (vect_transform_reduction): Ditto. --- gcc/tree-vect-loop.cc | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 71589b2..ac86b09 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -6813,11 +6813,13 @@ static internal_fn get_masked_reduction_fn (internal_fn reduc_fn, tree vectype_in) { internal_fn mask_reduc_fn; + internal_fn mask_len_reduc_fn; switch (reduc_fn) { case IFN_FOLD_LEFT_PLUS: mask_reduc_fn = IFN_MASK_FOLD_LEFT_PLUS; + mask_len_reduc_fn = IFN_MASK_LEN_FOLD_LEFT_PLUS; break; default: @@ -6827,6 +6829,9 @@ get_masked_reduction_fn (internal_fn reduc_fn, tree vectype_in) if (direct_internal_fn_supported_p (mask_reduc_fn, vectype_in, OPTIMIZE_FOR_SPEED)) return mask_reduc_fn; + if (direct_internal_fn_supported_p (mask_len_reduc_fn, vectype_in, + OPTIMIZE_FOR_SPEED)) + return mask_len_reduc_fn; return IFN_LAST; } @@ -6847,7 +6852,8 @@ vectorize_fold_left_reduction (loop_vec_info loop_vinfo, gimple *reduc_def_stmt, tree_code code, internal_fn reduc_fn, tree ops[3], tree vectype_in, - int reduc_index, vec_loop_masks *masks) + int reduc_index, vec_loop_masks *masks, + vec_loop_lens *lens) { class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); tree vectype_out = STMT_VINFO_VECTYPE (stmt_info); @@ -6909,8 +6915,18 @@ vectorize_fold_left_reduction (loop_vec_info loop_vinfo, { gimple *new_stmt; tree mask = NULL_TREE; + tree len = NULL_TREE; + tree bias = NULL_TREE; if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)) mask = vect_get_loop_mask (loop_vinfo, gsi, masks, vec_num, vectype_in, i); + if (LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo)) + { + len = vect_get_loop_len (loop_vinfo, gsi, lens, vec_num, vectype_in, + i, 1); + signed char biasval = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); + bias = build_int_cst (intQI_type_node, biasval); + mask = build_minus_one_cst (truth_type_for (vectype_in)); + } /* Handle MINUS by adding the negative. */ if (reduc_fn != IFN_LAST && code == MINUS_EXPR) @@ -6930,7 +6946,10 @@ vectorize_fold_left_reduction (loop_vec_info loop_vinfo, the preceding operation. */ if (reduc_fn != IFN_LAST || (mask && mask_reduc_fn != IFN_LAST)) { - if (mask && mask_reduc_fn != IFN_LAST) + if (mask && len && mask_reduc_fn == IFN_MASK_LEN_FOLD_LEFT_PLUS) + new_stmt = gimple_build_call_internal (mask_reduc_fn, 5, reduc_var, + def0, mask, len, bias); + else if (mask && mask_reduc_fn == IFN_MASK_FOLD_LEFT_PLUS) new_stmt = gimple_build_call_internal (mask_reduc_fn, 3, reduc_var, def0, mask); else @@ -7992,6 +8011,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, else if (loop_vinfo && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) { vec_loop_masks *masks = &LOOP_VINFO_MASKS (loop_vinfo); + vec_loop_lens *lens = &LOOP_VINFO_LENS (loop_vinfo); internal_fn cond_fn = get_conditional_internal_fn (op.code, op.type); if (reduction_type != FOLD_LEFT_REDUCTION @@ -8019,8 +8039,17 @@ vectorizable_reduction (loop_vec_info loop_vinfo, LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; } else - vect_record_loop_mask (loop_vinfo, masks, ncopies * vec_num, - vectype_in, NULL); + { + internal_fn mask_reduc_fn + = get_masked_reduction_fn (reduc_fn, vectype_in); + + if (mask_reduc_fn == IFN_MASK_LEN_FOLD_LEFT_PLUS) + vect_record_loop_len (loop_vinfo, lens, ncopies * vec_num, + vectype_in, 1); + else + vect_record_loop_mask (loop_vinfo, masks, ncopies * vec_num, + vectype_in, NULL); + } } return true; } @@ -8150,6 +8179,7 @@ vect_transform_reduction (loop_vec_info loop_vinfo, code_helper code = canonicalize_code (op.code, op.type); internal_fn cond_fn = get_conditional_internal_fn (code, op.type); vec_loop_masks *masks = &LOOP_VINFO_MASKS (loop_vinfo); + vec_loop_lens *lens = &LOOP_VINFO_LENS (loop_vinfo); bool mask_by_cond_expr = use_mask_by_cond_expr_p (code, cond_fn, vectype_in); /* Transform. */ @@ -8175,7 +8205,8 @@ vect_transform_reduction (loop_vec_info loop_vinfo, gcc_assert (code.is_tree_code ()); return vectorize_fold_left_reduction (loop_vinfo, stmt_info, gsi, vec_stmt, slp_node, reduc_def_phi, - tree_code (code), reduc_fn, op.ops, vectype_in, reduc_index, masks); + tree_code (code), reduc_fn, op.ops, vectype_in, reduc_index, masks, + lens); } bool single_defuse_cycle = STMT_VINFO_FORCE_SINGLE_CYCLE (reduc_info); -- cgit v1.1 From 8390a2af1397ba86ea2cf80d58007b8b69a9a6eb Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Thu, 20 Jul 2023 16:51:03 +0800 Subject: RISC-V: Support in-order floating-point reduction This patch is depending on: https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624995.html Consider this following case: float foo (float *__restrict a, int n) { float result = 1.0; for (int i = 0; i < n; i++) result += a[i]; return result; } Compile with **NO** -ffast-math: Before this patch: :4:21: missed: couldn't vectorize loop :1:7: missed: not vectorized: relevant phi not supported: result_14 = PHI After this patch: foo: lui a5,%hi(.LC0) flw fa0,%lo(.LC0)(a5) ble a1,zero,.L4 .L3: vsetvli a5,a1,e32,m1,ta,ma vle32.v v1,0(a0) slli a4,a5,2 sub a1,a1,a5 vfmv.s.f v2,fa0 add a0,a0,a4 vfredosum.vs v1,v1,v2 ----------> FOLD_LEFT_PLUS vfmv.f.s fa0,v1 bne a1,zero,.L3 ret .L4: ret gcc/ChangeLog: * config/riscv/autovec.md (fold_left_plus_): New pattern. (mask_len_fold_left_plus_): Ditto. * config/riscv/riscv-protos.h (enum insn_type): New enum. (enum reduction_type): Ditto. (expand_reduction): Add in-order reduction. * config/riscv/riscv-v.cc (emit_nonvlmax_fp_reduction_insn): New function. (expand_reduction): Add in-order reduction. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-1.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-2.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-3.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-4.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-5.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-6.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-7.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-1.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-2.c: New test. --- gcc/config/riscv/autovec.md | 39 ++++++++++++++++ gcc/config/riscv/riscv-protos.h | 13 +++++- gcc/config/riscv/riscv-v.cc | 53 ++++++++++++++++++---- .../riscv/rvv/autovec/reduc/reduc_strict-1.c | 28 ++++++++++++ .../riscv/rvv/autovec/reduc/reduc_strict-2.c | 26 +++++++++++ .../riscv/rvv/autovec/reduc/reduc_strict-3.c | 18 ++++++++ .../riscv/rvv/autovec/reduc/reduc_strict-4.c | 24 ++++++++++ .../riscv/rvv/autovec/reduc/reduc_strict-5.c | 28 ++++++++++++ .../riscv/rvv/autovec/reduc/reduc_strict-6.c | 18 ++++++++ .../riscv/rvv/autovec/reduc/reduc_strict-7.c | 21 +++++++++ .../riscv/rvv/autovec/reduc/reduc_strict_run-1.c | 29 ++++++++++++ .../riscv/rvv/autovec/reduc/reduc_strict_run-2.c | 31 +++++++++++++ 12 files changed, 317 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-2.c (limited to 'gcc') diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index c9ea731..d899922 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1687,3 +1687,42 @@ riscv_vector::expand_reduction (SMIN, operands, f); DONE; }) + +;; ------------------------------------------------------------------------- +;; ---- [FP] Left-to-right reductions +;; ------------------------------------------------------------------------- +;; Includes: +;; - vfredosum.vs +;; ------------------------------------------------------------------------- + +;; Unpredicated in-order FP reductions. +(define_expand "fold_left_plus_" + [(match_operand: 0 "register_operand") + (match_operand: 1 "register_operand") + (match_operand:VF 2 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_reduction (PLUS, operands, + operands[1], + riscv_vector::reduction_type::FOLD_LEFT); + DONE; +}) + +;; Predicated in-order FP reductions. +(define_expand "mask_len_fold_left_plus_" + [(match_operand: 0 "register_operand") + (match_operand: 1 "register_operand") + (match_operand:VF 2 "register_operand") + (match_operand: 3 "vector_mask_operand") + (match_operand 4 "autovec_length_operand") + (match_operand 5 "const_0_operand")] + "TARGET_VECTOR" +{ + if (rtx_equal_p (operands[4], const0_rtx)) + emit_move_insn (operands[0], operands[1]); + else + riscv_vector::expand_reduction (PLUS, operands, + operands[1], + riscv_vector::reduction_type::MASK_LEN_FOLD_LEFT); + DONE; +}) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 16fb8da..c9520f68 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -199,6 +199,7 @@ enum insn_type RVV_GATHER_M_OP = 5, RVV_SCATTER_M_OP = 4, RVV_REDUCTION_OP = 3, + RVV_REDUCTION_TU_OP = RVV_REDUCTION_OP + 2, }; enum vlmul_type { @@ -247,7 +248,7 @@ void emit_vlmax_merge_insn (unsigned, int, rtx *); void emit_vlmax_cmp_insn (unsigned, rtx *); void emit_vlmax_cmp_mu_insn (unsigned, rtx *); void emit_vlmax_masked_mu_insn (unsigned, int, rtx *); -void emit_scalar_move_insn (unsigned, rtx *); +void emit_scalar_move_insn (unsigned, rtx *, rtx = 0); void emit_nonvlmax_integer_move_insn (unsigned, rtx *, rtx); enum vlmul_type get_vlmul (machine_mode); unsigned int get_ratio (machine_mode); @@ -270,6 +271,13 @@ enum mask_policy MASK_AGNOSTIC = 1, MASK_ANY = 2, }; + +enum class reduction_type +{ + UNORDERED, + FOLD_LEFT, + MASK_LEN_FOLD_LEFT, +}; enum tail_policy get_prefer_tail_policy (); enum mask_policy get_prefer_mask_policy (); rtx get_avl_type_rtx (enum avl_type); @@ -282,7 +290,8 @@ bool has_vi_variant_p (rtx_code, rtx); void expand_vec_cmp (rtx, rtx_code, rtx, rtx); bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); void expand_cond_len_binop (rtx_code, rtx *); -void expand_reduction (rtx_code, rtx *, rtx); +void expand_reduction (rtx_code, rtx *, rtx, + reduction_type = reduction_type::UNORDERED); #endif bool sew64_scalar_helper (rtx *, rtx *, rtx, machine_mode, bool, void (*)(rtx *, rtx)); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 3157542..a080268 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1023,11 +1023,11 @@ emit_nonvlmax_fp_tu_insn (unsigned icode, int op_num, rtx *ops, rtx avl) /* Emit vmv.s.x instruction. */ void -emit_scalar_move_insn (unsigned icode, rtx *ops) +emit_scalar_move_insn (unsigned icode, rtx *ops, rtx len) { machine_mode dest_mode = GET_MODE (ops[0]); machine_mode mask_mode = get_mask_mode (dest_mode).require (); - insn_expander e (riscv_vector::RVV_SCALAR_MOV_OP, + insn_expander e (RVV_SCALAR_MOV_OP, /* HAS_DEST_P */ true, /* FULLY_UNMASKED_P */ false, /* USE_REAL_MERGE_P */ true, @@ -1038,7 +1038,7 @@ emit_scalar_move_insn (unsigned icode, rtx *ops) e.set_policy (TAIL_ANY); e.set_policy (MASK_ANY); - e.set_vl (CONST1_RTX (Pmode)); + e.set_vl (len ? len : CONST1_RTX (Pmode)); e.emit_insn ((enum insn_code) icode, ops); } @@ -1196,6 +1196,26 @@ emit_vlmax_fp_reduction_insn (unsigned icode, int op_num, rtx *ops) e.emit_insn ((enum insn_code) icode, ops); } +/* Emit reduction instruction. */ +static void +emit_nonvlmax_fp_reduction_insn (unsigned icode, int op_num, rtx *ops, rtx vl) +{ + machine_mode dest_mode = GET_MODE (ops[0]); + machine_mode mask_mode = get_mask_mode (GET_MODE (ops[1])).require (); + insn_expander e (op_num, + /* HAS_DEST_P */ true, + /* FULLY_UNMASKED_P */ false, + /* USE_REAL_MERGE_P */ true, + /* HAS_AVL_P */ true, + /* VLMAX_P */ false, dest_mode, + mask_mode); + + e.set_policy (TAIL_ANY); + e.set_rounding_mode (FRM_DYN); + e.set_vl (vl); + e.emit_insn ((enum insn_code) icode, ops); +} + /* Emit merge instruction. */ static machine_mode @@ -3341,9 +3361,10 @@ expand_cond_len_ternop (unsigned icode, rtx *ops) /* Expand reduction operations. */ void -expand_reduction (rtx_code code, rtx *ops, rtx init) +expand_reduction (rtx_code code, rtx *ops, rtx init, reduction_type type) { - machine_mode vmode = GET_MODE (ops[1]); + rtx vector = type == reduction_type::UNORDERED ? ops[1] : ops[2]; + machine_mode vmode = GET_MODE (vector); machine_mode m1_mode = get_m1_mode (vmode).require (); machine_mode m1_mmode = get_mask_mode (m1_mode).require (); @@ -3351,16 +3372,30 @@ expand_reduction (rtx_code code, rtx *ops, rtx init) rtx m1_mask = gen_scalar_move_mask (m1_mmode); rtx m1_undef = RVV_VUNDEF (m1_mode); rtx scalar_move_ops[] = {m1_tmp, m1_mask, m1_undef, init}; - emit_scalar_move_insn (code_for_pred_broadcast (m1_mode), scalar_move_ops); + rtx len = type == reduction_type::MASK_LEN_FOLD_LEFT ? ops[4] : NULL_RTX; + emit_scalar_move_insn (code_for_pred_broadcast (m1_mode), scalar_move_ops, + len); rtx m1_tmp2 = gen_reg_rtx (m1_mode); - rtx reduc_ops[] = {m1_tmp2, ops[1], m1_tmp}; + rtx reduc_ops[] = {m1_tmp2, vector, m1_tmp}; if (FLOAT_MODE_P (vmode) && code == PLUS) { insn_code icode - = code_for_pred_reduc_plus (UNSPEC_UNORDERED, vmode, m1_mode); - emit_vlmax_fp_reduction_insn (icode, RVV_REDUCTION_OP, reduc_ops); + = code_for_pred_reduc_plus (type == reduction_type::UNORDERED + ? UNSPEC_UNORDERED + : UNSPEC_ORDERED, + vmode, m1_mode); + if (type == reduction_type::MASK_LEN_FOLD_LEFT) + { + rtx mask = ops[3]; + rtx mask_len_reduc_ops[] + = {m1_tmp2, mask, RVV_VUNDEF (m1_mode), vector, m1_tmp}; + emit_nonvlmax_fp_reduction_insn (icode, RVV_REDUCTION_TU_OP, + mask_len_reduc_ops, len); + } + else + emit_vlmax_fp_reduction_insn (icode, RVV_REDUCTION_OP, reduc_ops); } else { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-1.c new file mode 100644 index 0000000..c293e9a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-1.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define NUM_ELEMS(TYPE) ((int)(5 * (256 / sizeof (TYPE)) + 3)) + +#define DEF_REDUC_PLUS(TYPE) \ + TYPE __attribute__ ((noinline, noclone)) \ + reduc_plus_##TYPE (TYPE *a, TYPE *b) \ + { \ + TYPE r = 0, q = 3; \ + for (int i = 0; i < NUM_ELEMS (TYPE); i++) \ + { \ + r += a[i]; \ + q -= b[i]; \ + } \ + return r * q; \ + } + +#define TEST_ALL(T) \ + T (_Float16) \ + T (float) \ + T (double) + +TEST_ALL (DEF_REDUC_PLUS) + +/* { dg-final { scan-assembler-times {vfredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-2.c new file mode 100644 index 0000000..2e1e7ab --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define NUM_ELEMS(TYPE) ((int) (5 * (256 / sizeof (TYPE)) + 3)) + +#define DEF_REDUC_PLUS(TYPE) \ +void __attribute__ ((noinline, noclone)) \ +reduc_plus_##TYPE (TYPE (*restrict a)[NUM_ELEMS (TYPE)], \ + TYPE *restrict r, int n) \ +{ \ + for (int i = 0; i < n; i++) \ + { \ + r[i] = 0; \ + for (int j = 0; j < NUM_ELEMS (TYPE); j++) \ + r[i] += a[i][j]; \ + } \ +} + +#define TEST_ALL(T) \ + T (_Float16) \ + T (float) \ + T (double) + +TEST_ALL (DEF_REDUC_PLUS) + +/* { dg-final { scan-assembler-times {vfredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-3.c new file mode 100644 index 0000000..f559d40 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +double mat[100][2]; + +double +slp_reduc_plus (int n) +{ + double tmp = 0.0; + for (int i = 0; i < n; i++) + { + tmp = tmp + mat[i][0]; + tmp = tmp + mat[i][1]; + } + return tmp; +} + +/* { dg-final { scan-assembler-times {vfredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-4.c new file mode 100644 index 0000000..428d371 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-4.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +double mat[100][8]; + +double +slp_reduc_plus (int n) +{ + double tmp = 0.0; + for (int i = 0; i < n; i++) + { + tmp = tmp + mat[i][0]; + tmp = tmp + mat[i][1]; + tmp = tmp + mat[i][2]; + tmp = tmp + mat[i][3]; + tmp = tmp + mat[i][4]; + tmp = tmp + mat[i][5]; + tmp = tmp + mat[i][6]; + tmp = tmp + mat[i][7]; + } + return tmp; +} + +/* { dg-final { scan-assembler {vfredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-5.c new file mode 100644 index 0000000..24add22 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-5.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +double mat[100][12]; + +double +slp_reduc_plus (int n) +{ + double tmp = 0.0; + for (int i = 0; i < n; i++) + { + tmp = tmp + mat[i][0]; + tmp = tmp + mat[i][1]; + tmp = tmp + mat[i][2]; + tmp = tmp + mat[i][3]; + tmp = tmp + mat[i][4]; + tmp = tmp + mat[i][5]; + tmp = tmp + mat[i][6]; + tmp = tmp + mat[i][7]; + tmp = tmp + mat[i][8]; + tmp = tmp + mat[i][9]; + tmp = tmp + mat[i][10]; + tmp = tmp + mat[i][11]; + } + return tmp; +} + +/* { dg-final { scan-assembler {vfredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-6.c new file mode 100644 index 0000000..c1567b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-6.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */ + +float +double_reduc (float (*i)[16]) +{ + float l = 0; + +#pragma GCC unroll 0 + for (int a = 0; a < 8; a++) + for (int b = 0; b < 100; b++) + l += i[b][a]; + return l; +} + +/* { dg-final { scan-assembler-times {vfredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */ +/* { dg-final { scan-tree-dump "Detected double reduction" "vect" } } */ +/* { dg-final { scan-tree-dump-not "OUTER LOOP VECTORIZED" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-7.c new file mode 100644 index 0000000..f742a82 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict-7.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */ + +float +double_reduc (float *i, float *j) +{ + float k = 0, l = 0; + + for (int a = 0; a < 8; a++) + for (int b = 0; b < 100; b++) + { + k += i[b]; + l += j[b]; + } + return l * k; +} + +/* { dg-final { scan-assembler-times {vle32\.v} 2 } } */ +/* { dg-final { scan-assembler-times {vfredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */ +/* { dg-final { scan-tree-dump "Detected double reduction" "vect" } } */ +/* { dg-final { scan-tree-dump-not "OUTER LOOP VECTORIZED" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-1.c new file mode 100644 index 0000000..516be97 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-1.c @@ -0,0 +1,29 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "reduc_strict-1.c" + +#define TEST_REDUC_PLUS(TYPE) \ + { \ + TYPE a[NUM_ELEMS (TYPE)]; \ + TYPE b[NUM_ELEMS (TYPE)]; \ + TYPE r = 0, q = 3; \ + for (int i = 0; i < NUM_ELEMS (TYPE); i++) \ + { \ + a[i] = (i * 0.1) * (i & 1 ? 1 : -1); \ + b[i] = (i * 0.3) * (i & 1 ? 1 : -1); \ + r += a[i]; \ + q -= b[i]; \ + asm volatile ("" ::: "memory"); \ + } \ + TYPE res = reduc_plus_##TYPE (a, b); \ + if (res != r * q) \ + __builtin_abort (); \ + } + +int __attribute__ ((optimize (1))) +main () +{ + TEST_ALL (TEST_REDUC_PLUS); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-2.c new file mode 100644 index 0000000..0a4238d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-2.c @@ -0,0 +1,31 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "reduc_strict-2.c" + +#define NROWS 5 + +#define TEST_REDUC_PLUS(TYPE) \ + { \ + TYPE a[NROWS][NUM_ELEMS (TYPE)]; \ + TYPE r[NROWS]; \ + TYPE expected[NROWS] = {}; \ + for (int i = 0; i < NROWS; ++i) \ + for (int j = 0; j < NUM_ELEMS (TYPE); ++j) \ + { \ + a[i][j] = (i * 0.1 + j * 0.6) * (j & 1 ? 1 : -1); \ + expected[i] += a[i][j]; \ + asm volatile ("" ::: "memory"); \ + } \ + reduc_plus_##TYPE (a, r, NROWS); \ + for (int i = 0; i < NROWS; ++i) \ + if (r[i] != expected[i]) \ + __builtin_abort (); \ + } + +int __attribute__ ((optimize (1))) +main () +{ + TEST_ALL (TEST_REDUC_PLUS); + return 0; +} -- cgit v1.1 From f1e34551e4d6e259ab3bd0c9aba4fa1f0c448214 Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 24 Jul 2023 10:56:27 +0200 Subject: bpf: make use of the bswap{16,32,64} V4 BPF instruction This patch makes the BPF backend to use the new V4 bswap{16,32,64} instructions in order to implement the __builtin_bswap{16,32,64} built-ins. It also adds support for -mcpu=v4 and -m[no]bswap command-line options. Tests and doc updates are includes. Tested in bpf-unknown-none. gcc/ChangeLog PR target/110786 * config/bpf/bpf.opt (mcpu): Add ISA_V4 and make it the default. (mbswap): New option. * config/bpf/bpf-opts.h (enum bpf_isa_version): New value ISA_V4. * config/bpf/bpf.cc (bpf_option_override): Set bpf_has_bswap. * config/bpf/bpf.md: Use bswap instructions if available for bswap* insn, and fix constraint. * doc/invoke.texi (eBPF Options): Document -mcpu=v4 and -mbswap. gcc/testsuite/ChangeLog PR target/110786 * gcc.target/bpf/bswap-1.c: Pass -mcpu=v3 to build test. * gcc.target/bpf/bswap-2.c: New test. --- gcc/config/bpf/bpf-opts.h | 1 + gcc/config/bpf/bpf.cc | 3 +++ gcc/config/bpf/bpf.md | 17 +++++++++++------ gcc/config/bpf/bpf.opt | 9 ++++++++- gcc/doc/invoke.texi | 11 ++++++++++- gcc/testsuite/gcc.target/bpf/bswap-1.c | 2 +- gcc/testsuite/gcc.target/bpf/bswap-2.c | 23 +++++++++++++++++++++++ 7 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/bpf/bswap-2.c (limited to 'gcc') diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h index 92db01e..e0be591 100644 --- a/gcc/config/bpf/bpf-opts.h +++ b/gcc/config/bpf/bpf-opts.h @@ -58,6 +58,7 @@ enum bpf_isa_version ISA_V1, ISA_V2, ISA_V3, + ISA_V4 }; enum bpf_asm_dialect diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index 1d39368..6bc7154 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -253,6 +253,9 @@ bpf_option_override (void) if (bpf_has_jmp32 == -1) bpf_has_jmp32 = (bpf_isa >= ISA_V3); + if (bpf_has_bswap == -1) + bpf_has_bswap = (bpf_isa >= ISA_V4); + /* Disable -fstack-protector as it is not supported in BPF. */ if (flag_stack_protect) { diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index 80220f2..81e2268 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -60,7 +60,7 @@ ;; Instruction classes. ;; alu 64-bit arithmetic. ;; alu32 32-bit arithmetic. -;; end endianness conversion instructions. +;; end endianness conversion or byte swap instructions. ;; ld load instructions. ;; lddx load 64-bit immediate instruction. ;; ldx generic load instructions. @@ -354,20 +354,25 @@ "{rsh\t%0,%2|%w0 >>= %w2}" [(set_attr "type" "")]) -;;;; Endianness conversion +;;;; Byte swapping (define_mode_iterator BSM [HI SI DI]) (define_mode_attr endmode [(HI "16") (SI "32") (DI "64")]) (define_insn "bswap2" [(set (match_operand:BSM 0 "register_operand" "=r") - (bswap:BSM (match_operand:BSM 1 "register_operand" " r")))] + (bswap:BSM (match_operand:BSM 1 "register_operand" " 0")))] "" { - if (TARGET_BIG_ENDIAN) - return "{endle\t%0, |%0 = le %0}"; + if (bpf_has_bswap) + return "{bswap\t%0, |%0 = bswap %1}"; else - return "{endbe\t%0, |%0 = be %0}"; + { + if (TARGET_BIG_ENDIAN) + return "{endle\t%0, |%0 = le %1}"; + else + return "{endbe\t%0, |%0 = be %1}"; + } } [(set_attr "type" "end")]) diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index ff805f9..1e4dcc8 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -146,8 +146,12 @@ mjmp32 Target Var(bpf_has_jmp32) Init(-1) Enable 32-bit jump instructions. +mbswap +Target Var(bpf_has_bswap) Init(-1) +Enable byte swap instructions. + mcpu= -Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V3) +Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V4) Enum Name(bpf_isa) Type(enum bpf_isa_version) @@ -161,6 +165,9 @@ Enum(bpf_isa) String(v2) Value(ISA_V2) EnumValue Enum(bpf_isa) String(v3) Value(ISA_V3) +EnumValue +Enum(bpf_isa) String(v4) Value(ISA_V4) + masm= Target RejectNegative Joined Var(asm_dialect) Enum(asm_dialect) Init(ASM_NORMAL) Use given assembler dialect. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index efd356e..a977a34 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -24707,10 +24707,14 @@ Enable 32-bit jump instructions. Enabled for CPU v3 and above. @item -malu32 Enable 32-bit ALU instructions. Enabled for CPU v3 and above. +@opindex mbswap +@item -mbswap +Enable byte swap instructions. Enabled for CPU v4 and above. + @opindex mcpu @item -mcpu=@var{version} This specifies which version of the eBPF ISA to target. Newer versions -may not be supported by all kernels. The default is @samp{v3}. +may not be supported by all kernels. The default is @samp{v4}. Supported values for @var{version} are: @@ -24728,6 +24732,11 @@ All features of v2, plus: @item 32-bit ALU operations, as in @option{-malu32} @end itemize +@item v4 +All features of v3, plus: +@itemize @minus +@item Byte swap instructions, as in @option{-mbswap} +@end itemize @end table @opindex mco-re diff --git a/gcc/testsuite/gcc.target/bpf/bswap-1.c b/gcc/testsuite/gcc.target/bpf/bswap-1.c index 4748143..ba19eb6 100644 --- a/gcc/testsuite/gcc.target/bpf/bswap-1.c +++ b/gcc/testsuite/gcc.target/bpf/bswap-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mlittle-endian" } */ +/* { dg-options "-mlittle-endian -mcpu=v3" } */ unsigned short in16 = 0x1234U; unsigned int in32 = 0x12345678U; diff --git a/gcc/testsuite/gcc.target/bpf/bswap-2.c b/gcc/testsuite/gcc.target/bpf/bswap-2.c new file mode 100644 index 0000000..e5aef38 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/bswap-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-mlittle-endian -mcpu=v4" } */ + +unsigned short in16 = 0x1234U; +unsigned int in32 = 0x12345678U; +unsigned long in64 = 0x123456789abcdef0ULL; + +unsigned short out16 = 0; +unsigned int out32 = 0; +unsigned long out64 = 0; + +int foo (void) +{ + out16 = __builtin_bswap16 (in16); + out32 = __builtin_bswap32 (in32); + out64 = __builtin_bswap64 (in64); + + return 0; +} + +/* { dg-final { scan-assembler "bswap\t%r., 16" } } */ +/* { dg-final { scan-assembler "bswap\t%r., 32" } } */ +/* { dg-final { scan-assembler "bswap\t%r., 64" } } */ -- cgit v1.1 From da445a5858299ed2a72af1089c225a438ab93ce2 Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 24 Jul 2023 11:52:30 +0200 Subject: bpf: remove -mkernel option and BPF_KERNEL_VERSION_CODE Having the ability of specifying a target kernel version when building a BPF program is one of these things that sound pretty good in theory, but simply don't work in practice: kernels in practice contain backports, etc. Also, the addition of CO-RE to BPF has made this uneccessary. This patch removes the -mkernel command line option and also the associated BPF_KERNEL_VERSION_CODE pre-processor constant. Tested in bpf-unknown-none. gcc/ChangeLog * config/bpf/bpf-opts.h (enum bpf_kernel_version): Remove enum. * config/bpf/bpf.opt (mkernel): Remove option. * config/bpf/bpf.cc (bpf_target_macros): Do not define BPF_KERNEL_VERSION_CODE. --- gcc/config/bpf/bpf-opts.h | 33 ------------------ gcc/config/bpf/bpf.cc | 40 ---------------------- gcc/config/bpf/bpf.opt | 87 ----------------------------------------------- 3 files changed, 160 deletions(-) (limited to 'gcc') diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h index e0be591..5c9441c 100644 --- a/gcc/config/bpf/bpf-opts.h +++ b/gcc/config/bpf/bpf-opts.h @@ -20,39 +20,6 @@ #ifndef BPF_OPTS_H #define BPF_OPTS_H -/* Supported versions of the Linux kernel. */ -enum bpf_kernel_version -{ - /* Linux 4.x */ - LINUX_V4_0, - LINUX_V4_1, - LINUX_V4_2, - LINUX_V4_3, - LINUX_V4_4, - LINUX_V4_5, - LINUX_V4_6, - LINUX_V4_7, - LINUX_V4_8, - LINUX_V4_9, - LINUX_V4_10, - LINUX_V4_11, - LINUX_V4_12, - LINUX_V4_13, - LINUX_V4_14, - LINUX_V4_15, - LINUX_V4_16, - LINUX_V4_17, - LINUX_V4_18, - LINUX_V4_19, - LINUX_V4_20, - /* Linux 5.x */ - LINUX_V5_0, - LINUX_V5_1, - LINUX_V5_2, - LINUX_LATEST = LINUX_V5_2, - LINUX_NATIVE, -}; - enum bpf_isa_version { ISA_V1, diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index 6bc7154..18d3b5f 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -308,46 +308,6 @@ bpf_target_macros (cpp_reader *pfile) builtin_define ("__BPF_BIG_ENDIAN__"); else builtin_define ("__BPF_LITTLE_ENDIAN__"); - - /* Define BPF_KERNEL_VERSION_CODE */ - { - const char *version_code; - char *kernel_version_code; - - switch (bpf_kernel) - { - case LINUX_V4_0: version_code = "0x40000"; break; - case LINUX_V4_1: version_code = "0x40100"; break; - case LINUX_V4_2: version_code = "0x40200"; break; - case LINUX_V4_3: version_code = "0x40300"; break; - case LINUX_V4_4: version_code = "0x40400"; break; - case LINUX_V4_5: version_code = "0x40500"; break; - case LINUX_V4_6: version_code = "0x40600"; break; - case LINUX_V4_7: version_code = "0x40700"; break; - case LINUX_V4_8: version_code = "0x40800"; break; - case LINUX_V4_9: version_code = "0x40900"; break; - case LINUX_V4_10: version_code = "0x40a00"; break; - case LINUX_V4_11: version_code = "0x40b00"; break; - case LINUX_V4_12: version_code = "0x40c00"; break; - case LINUX_V4_13: version_code = "0x40d00"; break; - case LINUX_V4_14: version_code = "0x40e00"; break; - case LINUX_V4_15: version_code = "0x40f00"; break; - case LINUX_V4_16: version_code = "0x41000"; break; - case LINUX_V4_17: version_code = "0x42000"; break; - case LINUX_V4_18: version_code = "0x43000"; break; - case LINUX_V4_19: version_code = "0x44000"; break; - case LINUX_V4_20: version_code = "0x45000"; break; - case LINUX_V5_0: version_code = "0x50000"; break; - case LINUX_V5_1: version_code = "0x50100"; break; - case LINUX_V5_2: version_code = "0x50200"; break; - default: - gcc_unreachable (); - } - - kernel_version_code = ACONCAT (("__BPF_KERNEL_VERSION_CODE__=", - version_code, NULL)); - builtin_define (kernel_version_code); - } } /* Return an RTX representing the place where a function returns or diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index 1e4dcc8..3bf9033 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -21,93 +21,6 @@ HeaderInclude config/bpf/bpf-opts.h -; Selecting the kind of kernel the eBPF will be running on. - -mkernel= -Target RejectNegative Joined Var(bpf_kernel) Enum(bpf_kernel) Init(LINUX_LATEST) -Generate eBPF for the given Linux kernel version. - -Enum -Name(bpf_kernel) Type(enum bpf_kernel_version) - -EnumValue -Enum(bpf_kernel) String(native) Value(LINUX_NATIVE) DriverOnly - -EnumValue -Enum(bpf_kernel) String(latest) Value(LINUX_LATEST) DriverOnly - -EnumValue -Enum(bpf_kernel) String(4.0) Value(LINUX_V4_0) - -EnumValue -Enum(bpf_kernel) String(4.1) Value(LINUX_V4_1) - -EnumValue -Enum(bpf_kernel) String(4.2) Value(LINUX_V4_2) - -EnumValue -Enum(bpf_kernel) String(4.3) Value(LINUX_V4_3) - -EnumValue -Enum(bpf_kernel) String(4.4) Value(LINUX_V4_4) - -EnumValue -Enum(bpf_kernel) String(4.5) Value(LINUX_V4_5) - -EnumValue -Enum(bpf_kernel) String(4.6) Value(LINUX_V4_6) - -EnumValue -Enum(bpf_kernel) String(4.7) Value(LINUX_V4_7) - -EnumValue -Enum(bpf_kernel) String(4.8) Value(LINUX_V4_8) - -EnumValue -Enum(bpf_kernel) String(4.9) Value(LINUX_V4_9) - -EnumValue -Enum(bpf_kernel) String(4.10) Value(LINUX_V4_10) - -EnumValue -Enum(bpf_kernel) String(4.11) Value(LINUX_V4_11) - -EnumValue -Enum(bpf_kernel) String(4.12) Value(LINUX_V4_12) - -EnumValue -Enum(bpf_kernel) String(4.13) Value(LINUX_V4_13) - -EnumValue -Enum(bpf_kernel) String(4.14) Value(LINUX_V4_14) - -EnumValue -Enum(bpf_kernel) String(4.15) Value(LINUX_V4_15) - -EnumValue -Enum(bpf_kernel) String(4.16) Value(LINUX_V4_16) - -EnumValue -Enum(bpf_kernel) String(4.17) Value(LINUX_V4_17) - -EnumValue -Enum(bpf_kernel) String(4.18) Value(LINUX_V4_18) - -EnumValue -Enum(bpf_kernel) String(4.19) Value(LINUX_V4_19) - -EnumValue -Enum(bpf_kernel) String(4.20) Value(LINUX_V4_20) - -EnumValue -Enum(bpf_kernel) String(5.0) Value(LINUX_V5_0) - -EnumValue -Enum(bpf_kernel) String(5.1) Value(LINUX_V5_1) - -EnumValue -Enum(bpf_kernel) String(5.2) Value(LINUX_V5_2) - ; Use xBPF extensions. mxbpf -- cgit v1.1 From 9f66753ef48f37729a88735ae1a2bf2d2558e69f Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 24 Jul 2023 12:34:23 +0100 Subject: [Committed] PR target/110787: Revert QImode offsets in {zero,sign}_extract. My recent patch to use QImode for bit offsets in ZERO_EXTRACTs and SIGN_EXTRACTs in the i386 backend shouldn't have resulted in any change behaviour, but as reported by Rainer it produces a bootstrap failure in gm2. This reverts the problematic patch whilst we investigate the underlying cause. Committed as obvious. 2023-07-23 Roger Sayle gcc/ChangeLog PR target/110787 PR target/110790 Revert patch. * config/i386/i386.md (extv): Use QImode for offsets. (extzv): Likewise. (insv): Likewise. (*testqi_ext_3): Likewise. (*btr_2): Likewise. (define_split): Likewise. (*btsq_imm): Likewise. (*btrq_imm): Likewise. (*btcq_imm): Likewise. (define_peephole2 x3): Likewise. (*bt): Likewise (*bt_mask): New define_insn_and_split. (*jcc_bt): Use QImode for offsets. (*jcc_bt_1): Delete obsolete pattern. (*jcc_bt_mask): Use QImode offsets. (*jcc_bt_mask_1): Likewise. (define_split): Likewise. (*bt_setcqi): Likewise. (*bt_setncqi): Likewise. (*bt_setnc): Likewise. (*bt_setncqi_2): Likewise. (*bt_setc_mask): New define_insn_and_split. (bmi2_bzhi_3): Use QImode offsets. (*bmi2_bzhi_3): Likewise. (*bmi2_bzhi_3_1): Likewise. (*bmi2_bzhi_3_1_ccz): Likewise. (@tbm_bextri_): Likewise. --- gcc/config/i386/i386.md | 212 +++++++++++++++++++++++++----------------------- 1 file changed, 109 insertions(+), 103 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2ce8e95..4db210c 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3312,8 +3312,8 @@ (define_expand "extv" [(set (match_operand:SWI24 0 "register_operand") (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand") - (match_operand:QI 2 "const_int_operand") - (match_operand:QI 3 "const_int_operand")))] + (match_operand:SI 2 "const_int_operand") + (match_operand:SI 3 "const_int_operand")))] "" { /* Handle extractions from %ah et al. */ @@ -3340,8 +3340,8 @@ (define_expand "extzv" [(set (match_operand:SWI248 0 "register_operand") (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand") - (match_operand:QI 2 "const_int_operand") - (match_operand:QI 3 "const_int_operand")))] + (match_operand:SI 2 "const_int_operand") + (match_operand:SI 3 "const_int_operand")))] "" { if (ix86_expand_pextr (operands)) @@ -3428,8 +3428,8 @@ (define_expand "insv" [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand") - (match_operand:QI 1 "const_int_operand") - (match_operand:QI 2 "const_int_operand")) + (match_operand:SI 1 "const_int_operand") + (match_operand:SI 2 "const_int_operand")) (match_operand:SWI248 3 "register_operand"))] "" { @@ -10788,8 +10788,8 @@ (match_operator 1 "compare_operator" [(zero_extract:SWI248 (match_operand 2 "int_nonimmediate_operand" "rm") - (match_operand:QI 3 "const_int_operand") - (match_operand:QI 4 "const_int_operand")) + (match_operand 3 "const_int_operand") + (match_operand 4 "const_int_operand")) (const_int 0)]))] "/* Ensure that resulting mask is zero or sign extended operand. */ INTVAL (operands[4]) >= 0 @@ -15965,7 +15965,7 @@ [(set (zero_extract:HI (match_operand:SWI12 0 "nonimmediate_operand") (const_int 1) - (match_operand:QI 1 "register_operand")) + (zero_extend:SI (match_operand:QI 1 "register_operand"))) (const_int 0)) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" @@ -15989,7 +15989,7 @@ [(set (zero_extract:HI (match_operand:SWI12 0 "register_operand") (const_int 1) - (match_operand:QI 1 "register_operand")) + (zero_extend:SI (match_operand:QI 1 "register_operand"))) (const_int 0)) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" @@ -16016,7 +16016,7 @@ (define_insn "*btsq_imm" [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") (const_int 1) - (match_operand:QI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (const_int 1)) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -16029,7 +16029,7 @@ (define_insn "*btrq_imm" [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") (const_int 1) - (match_operand:QI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (const_int 0)) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -16042,7 +16042,7 @@ (define_insn "*btcq_imm" [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") (const_int 1) - (match_operand:QI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -16059,7 +16059,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand") (const_int 1) - (match_operand:QI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (const_int 1)) (clobber (reg:CC FLAGS_REG))])] "TARGET_64BIT && !TARGET_USE_BT" @@ -16083,7 +16083,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand") (const_int 1) - (match_operand:QI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (const_int 0)) (clobber (reg:CC FLAGS_REG))])] "TARGET_64BIT && !TARGET_USE_BT" @@ -16107,7 +16107,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand") (const_int 1) - (match_operand:QI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))])] @@ -16135,14 +16135,14 @@ (zero_extract:SWI48 (match_operand:SWI48 0 "nonimmediate_operand" "r,m") (const_int 1) - (match_operand:QI 1 "nonmemory_operand" "q,")) + (match_operand:SI 1 "nonmemory_operand" "r,")) (const_int 0)))] "" { switch (get_attr_mode (insn)) { case MODE_SI: - return "bt{l}\t{%k1, %k0|%k0, %k1}"; + return "bt{l}\t{%1, %k0|%k0, %1}"; case MODE_DI: return "bt{q}\t{%q1, %0|%0, %q1}"; @@ -16160,36 +16160,13 @@ (const_string "SI") (const_string "")))]) -(define_insn_and_split "*bt_mask" - [(set (reg:CCC FLAGS_REG) - (compare:CCC - (zero_extract:SWI48 - (match_operand:SWI48 0 "nonimmediate_operand" "r,m") - (const_int 1) - (subreg:QI - (and:SWI248 - (match_operand:SWI248 1 "register_operand") - (match_operand 2 "const_int_operand")) 0)) - (const_int 0)))] - "TARGET_USE_BT - && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode)-1)) - == GET_MODE_BITSIZE (mode)-1 - && ix86_pre_reload_split ()" - "#" - "&& 1" - [(set (reg:CCC FLAGS_REG) - (compare:CCC - (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1)) - (const_int 0)))] - "operands[1] = gen_lowpart (QImode, operands[1]);") - (define_insn_and_split "*jcc_bt" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" [(zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") (const_int 1) - (match_operand:QI 2 "nonmemory_operand")) + (match_operand:SI 2 "nonmemory_operand")) (const_int 0)]) (label_ref (match_operand 3)) (pc))) @@ -16219,6 +16196,39 @@ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) +(define_insn_and_split "*jcc_bt_1" + [(set (pc) + (if_then_else (match_operator 0 "bt_comparison_operator" + [(zero_extract:SWI48 + (match_operand:SWI48 1 "register_operand") + (const_int 1) + (zero_extend:SI + (match_operand:QI 2 "register_operand"))) + (const_int 0)]) + (label_ref (match_operand 3)) + (pc))) + (clobber (reg:CC FLAGS_REG))] + "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) + && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 + (match_dup 1) + (const_int 1) + (match_dup 2)) + (const_int 0))) + (set (pc) + (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) + (label_ref (match_dup 3)) + (pc)))] +{ + operands[2] = lowpart_subreg (SImode, operands[2], QImode); + operands[0] = shallow_copy_rtx (operands[0]); + PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); +}) + ;; Avoid useless masking of bit offset operand. (define_insn_and_split "*jcc_bt_mask" [(set (pc) @@ -16226,8 +16236,8 @@ [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (and:QI - (match_operand:QI 2 "register_operand") + (and:SI + (match_operand:SI 2 "register_operand") (match_operand 3 "const_int_operand")))]) (label_ref (match_operand 4)) (pc))) @@ -16254,23 +16264,23 @@ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) -;; Avoid useless masking of bit offset operand. -(define_insn_and_split "*jcc_bt_mask_1" +(define_insn_and_split "*jcc_bt_mask_1" [(set (pc) - (if_then_else (match_operator 0 "bt_comparison_operator" + (if_then_else (match_operator 0 "bt_comparison_operator" [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (subreg:QI - (and:SWI248 - (match_operand:SWI248 2 "register_operand") - (match_operand 3 "const_int_operand")) 0))]) + (zero_extend:SI + (subreg:QI + (and + (match_operand 2 "int248_register_operand") + (match_operand 3 "const_int_operand")) 0)))]) (label_ref (match_operand 4)) (pc))) (clobber (reg:CC FLAGS_REG))] "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) - && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1)) - == GET_MODE_BITSIZE (mode)-1 + && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1)) + == GET_MODE_BITSIZE (mode)-1 && ix86_pre_reload_split ()" "#" "&& 1" @@ -16286,9 +16296,10 @@ (label_ref (match_dup 4)) (pc)))] { + operands[2] = force_reg (GET_MODE (operands[2]), operands[2]); + operands[2] = gen_lowpart (SImode, operands[2]); operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); - operands[2] = gen_lowpart (QImode, operands[2]); }) ;; Help combine recognize bt followed by cmov @@ -16299,7 +16310,7 @@ [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (match_operand:QI 2 "register_operand")) + (zero_extend:SI (match_operand:QI 2 "register_operand"))) (const_int 0)]) (match_operand:SWI248 3 "nonimmediate_operand") (match_operand:SWI248 4 "nonimmediate_operand")))] @@ -16317,6 +16328,7 @@ { if (GET_CODE (operands[5]) == EQ) std::swap (operands[3], operands[4]); + operands[2] = lowpart_subreg (SImode, operands[2], QImode); }) ;; Help combine recognize bt followed by setc @@ -16325,7 +16337,7 @@ (zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (match_operand:QI 2 "register_operand"))) + (zero_extend:SI (match_operand:QI 2 "register_operand")))) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" "#" @@ -16335,7 +16347,8 @@ (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) - (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]) + (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") ;; Help combine recognize bt followed by setnc (define_insn_and_split "*bt_setncqi" @@ -16355,7 +16368,8 @@ (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) - (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]) + (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") (define_insn_and_split "*bt_setnc" [(set (match_operand:SWI48 0 "register_operand") @@ -16375,7 +16389,10 @@ (set (match_dup 3) (ne:QI (reg:CCC FLAGS_REG) (const_int 0))) (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))] - "operands[3] = gen_reg_rtx (QImode);") +{ + operands[2] = lowpart_subreg (SImode, operands[2], QImode); + operands[3] = gen_reg_rtx (QImode); +}) ;; Help combine recognize bt followed by setnc (PR target/110588) (define_insn_and_split "*bt_setncqi_2" @@ -16384,7 +16401,7 @@ (zero_extract:SWI48 (match_operand:SWI48 1 "register_operand") (const_int 1) - (match_operand:QI 2 "register_operand")) + (zero_extend:SI (match_operand:QI 2 "register_operand"))) (const_int 0))) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_BT && ix86_pre_reload_split ()" @@ -16395,36 +16412,8 @@ (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) - (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]) - -;; Help combine recognize bt followed by setc -(define_insn_and_split "*bt_setc_mask" - [(set (match_operand:SWI48 0 "register_operand") - (zero_extract:SWI48 - (match_operand:SWI48 1 "register_operand") - (const_int 1) - (subreg:QI - (and:SWI48 - (match_operand:SWI48 2 "register_operand") - (match_operand 3 "const_int_operand")) 0))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_BT - && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (mode)-1)) - == GET_MODE_BITSIZE (mode)-1 - && ix86_pre_reload_split ()" - "#" - "&& 1" - [(set (reg:CCC FLAGS_REG) - (compare:CCC - (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) - (const_int 0))) - (set (match_dup 3) - (ne:QI (reg:CCC FLAGS_REG) (const_int 0))) - (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))] -{ - operands[2] = gen_lowpart (QImode, operands[2]); - operands[3] = gen_reg_rtx (QImode); -}) + (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") ;; Store-flag instructions. @@ -18719,29 +18708,46 @@ [(parallel [(set (match_operand:SWI48 0 "register_operand") (if_then_else:SWI48 - (ne:QI (match_operand:QI 2 "register_operand") + (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand") + (const_int 255)) (const_int 0)) (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") - (umin:QI (match_dup 2) (match_dup 3)) + (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255)) + (match_dup 3)) (const_int 0)) (const_int 0))) (clobber (reg:CC FLAGS_REG))])] "TARGET_BMI2" -{ - operands[2] = gen_lowpart (QImode, operands[2]); - operands[3] = GEN_INT ( * BITS_PER_UNIT); -}) + "operands[3] = GEN_INT ( * BITS_PER_UNIT);") (define_insn "*bmi2_bzhi_3" [(set (match_operand:SWI48 0 "register_operand" "=r") (if_then_else:SWI48 - (ne:QI (match_operand:QI 2 "register_operand" "q") + (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r") + (const_int 255)) (const_int 0)) (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (umin:QI (match_dup 2) - (match_operand:QI 3 "const_int_operand")) + (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255)) + (match_operand:SWI48 3 "const_int_operand")) + (const_int 0)) + (const_int 0))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_BMI2 && INTVAL (operands[3]) == * BITS_PER_UNIT" + "bzhi\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "bitmanip") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "*bmi2_bzhi_3_1" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (if_then_else:SWI48 + (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0)) + (zero_extract:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (umin:SWI48 (zero_extend:SWI48 (match_dup 2)) + (match_operand:SWI48 3 "const_int_operand")) (const_int 0)) (const_int 0))) (clobber (reg:CC FLAGS_REG))] @@ -18758,8 +18764,8 @@ (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0)) (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (umin:QI (match_dup 2) - (match_operand:QI 3 "const_int_operand")) + (umin:SWI48 (zero_extend:SWI48 (match_dup 2)) + (match_operand:SWI48 3 "const_int_operand")) (const_int 0)) (const_int 0)) (const_int 0))) @@ -18858,8 +18864,8 @@ [(set (match_operand:SWI48 0 "register_operand" "=r") (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (match_operand:QI 2 "const_0_to_255_operand") - (match_operand:QI 3 "const_0_to_255_operand"))) + (match_operand 2 "const_0_to_255_operand") + (match_operand 3 "const_0_to_255_operand"))) (clobber (reg:CC FLAGS_REG))] "TARGET_TBM" { -- cgit v1.1 From fe39eca4136bf2f9dc740c05e7957027736fc11b Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Thu, 13 Jul 2023 09:10:06 +0200 Subject: vect: Handle demoting FLOAT and promoting FIX_TRUNC. The recent changes that allowed multi-step conversions for "non-packing/unpacking", i.e. modifier == NONE targets included promoting to-float and demoting to-int variants. This patch adds the missing demoting to-float and promoting to-int handling. gcc/ChangeLog: * tree-vect-stmts.cc (vectorizable_conversion): Handle more demotion/promotion for modifier == NONE. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/conversions/vec-narrow-int64-float16.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vec-widen-float16-int64.c: New test. --- .../autovec/conversions/vec-narrow-int64-float16.c | 15 +++++ .../autovec/conversions/vec-widen-float16-int64.c | 15 +++++ gcc/tree-vect-stmts.cc | 69 ++++++++++++++++------ 3 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-narrow-int64-float16.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-widen-float16-int64.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-narrow-int64-float16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-narrow-int64-float16.c new file mode 100644 index 0000000..c24d66a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-narrow-int64-float16.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fdump-tree-vect-details" } */ + +/* This test ensures that we vectorize the conversion by having the vectorizer + create an intermediate type. */ + +#include + +void convert (_Float16 *restrict dst, int64_t *restrict a, int n) +{ + for (int i = 0; i < n; i++) + dst[i] = (_Float16) (a[i] & 0x7fffffff); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-widen-float16-int64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-widen-float16-int64.c new file mode 100644 index 0000000..3fd1260 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vec-widen-float16-int64.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-trapping-math -fdump-tree-vect-details" } */ + +/* This test ensures that we vectorize the conversion by having the vectorizer + create an intermediate type. */ + +#include + +void convert (int64_t *restrict dst, _Float16 *restrict a, int n) +{ + for (int i = 0; i < n; i++) + dst[i] = (int64_t) a[i]; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index ed28fbd..15e12f2 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -5190,31 +5190,66 @@ vectorizable_conversion (vec_info *vinfo, break; } - /* For conversions between float and smaller integer types try whether we - can use intermediate signed integer types to support the + /* For conversions between float and integer types try whether + we can use intermediate signed integer types to support the conversion. */ - if ((code == FLOAT_EXPR - && GET_MODE_SIZE (lhs_mode) > GET_MODE_SIZE (rhs_mode)) - || (code == FIX_TRUNC_EXPR - && GET_MODE_SIZE (rhs_mode) > GET_MODE_SIZE (lhs_mode) - && !flag_trapping_math)) + if (GET_MODE_SIZE (lhs_mode) != GET_MODE_SIZE (rhs_mode) + && (code == FLOAT_EXPR || + (code == FIX_TRUNC_EXPR && !flag_trapping_math))) { + bool demotion = GET_MODE_SIZE (rhs_mode) > GET_MODE_SIZE (lhs_mode); bool float_expr_p = code == FLOAT_EXPR; - scalar_mode imode = float_expr_p ? rhs_mode : lhs_mode; - fltsz = GET_MODE_SIZE (float_expr_p ? lhs_mode : rhs_mode); + unsigned short target_size; + scalar_mode intermediate_mode; + if (demotion) + { + intermediate_mode = lhs_mode; + target_size = GET_MODE_SIZE (rhs_mode); + } + else + { + target_size = GET_MODE_SIZE (lhs_mode); + if (!int_mode_for_size + (GET_MODE_BITSIZE (rhs_mode), 0).exists (&intermediate_mode)) + goto unsupported; + } code1 = float_expr_p ? code : NOP_EXPR; codecvt1 = float_expr_p ? NOP_EXPR : code; - FOR_EACH_2XWIDER_MODE (rhs_mode_iter, imode) + opt_scalar_mode mode_iter; + FOR_EACH_2XWIDER_MODE (mode_iter, intermediate_mode) { - imode = rhs_mode_iter.require (); - if (GET_MODE_SIZE (imode) > fltsz) + intermediate_mode = mode_iter.require (); + + if (GET_MODE_SIZE (intermediate_mode) > target_size) break; - cvt_type - = build_nonstandard_integer_type (GET_MODE_BITSIZE (imode), - 0); - cvt_type = get_vectype_for_scalar_type (vinfo, cvt_type, - slp_node); + scalar_mode cvt_mode; + if (!int_mode_for_size + (GET_MODE_BITSIZE (intermediate_mode), 0).exists (&cvt_mode)) + break; + + cvt_type = build_nonstandard_integer_type + (GET_MODE_BITSIZE (cvt_mode), 0); + + /* Check if the intermediate type can hold OP0's range. + When converting from float to integer this is not necessary + because values that do not fit the (smaller) target type are + unspecified anyway. */ + if (demotion && float_expr_p) + { + wide_int op_min_value, op_max_value; + if (!vect_get_range_info (op0, &op_min_value, &op_max_value)) + break; + + if (cvt_type == NULL_TREE + || (wi::min_precision (op_max_value, SIGNED) + > TYPE_PRECISION (cvt_type)) + || (wi::min_precision (op_min_value, SIGNED) + > TYPE_PRECISION (cvt_type))) + continue; + } + + cvt_type = get_vectype_for_scalar_type (vinfo, cvt_type, slp_node); /* This should only happened for SLP as long as loop vectorizer only supports same-sized vector. */ if (cvt_type == NULL_TREE -- cgit v1.1 From 2c820da28e9139569357f016c2da193ba1f6ad75 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 24 Jul 2023 12:12:00 +0200 Subject: [i386] remove unused tree-vectorizer.h includes * config/i386/i386-builtins.cc: Remove tree-vectorizer.h include. * config/i386/i386-expand.cc: Likewise. * config/i386/i386-features.cc: Likewise. * config/i386/i386-options.cc: Likewise. --- gcc/config/i386/i386-builtins.cc | 1 - gcc/config/i386/i386-expand.cc | 1 - gcc/config/i386/i386-features.cc | 1 - gcc/config/i386/i386-options.cc | 1 - 4 files changed, 4 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc index 6c90334..356b6df 100644 --- a/gcc/config/i386/i386-builtins.cc +++ b/gcc/config/i386/i386-builtins.cc @@ -66,7 +66,6 @@ along with GCC; see the file COPYING3. If not see #include "pass_manager.h" #include "target-globals.h" #include "gimple-iterator.h" -#include "tree-vectorizer.h" #include "shrink-wrap.h" #include "builtins.h" #include "rtl-iter.h" diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 0421909..e9dc0bc 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -66,7 +66,6 @@ along with GCC; see the file COPYING3. If not see #include "pass_manager.h" #include "target-globals.h" #include "gimple-iterator.h" -#include "tree-vectorizer.h" #include "shrink-wrap.h" #include "builtins.h" #include "rtl-iter.h" diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index f801a8f..6da8395 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -66,7 +66,6 @@ along with GCC; see the file COPYING3. If not see #include "pass_manager.h" #include "target-globals.h" #include "gimple-iterator.h" -#include "tree-vectorizer.h" #include "shrink-wrap.h" #include "builtins.h" #include "rtl-iter.h" diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index edbb927..127ee24 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -66,7 +66,6 @@ along with GCC; see the file COPYING3. If not see #include "pass_manager.h" #include "target-globals.h" #include "gimple-iterator.h" -#include "tree-vectorizer.h" #include "shrink-wrap.h" #include "builtins.h" #include "rtl-iter.h" -- cgit v1.1 From 8547c451aac1c1f0178cf0914243b20fa0dde0c3 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 24 Jul 2023 12:13:35 +0200 Subject: Remove unused tree-vectorizer.h include * tree-ssa-loop.cc: Remove unused tree-vectorizer.h include. --- gcc/tree-ssa-loop.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-loop.cc b/gcc/tree-ssa-loop.cc index ab398c3..f465fb8 100644 --- a/gcc/tree-ssa-loop.cc +++ b/gcc/tree-ssa-loop.cc @@ -35,7 +35,6 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "tree-inline.h" #include "tree-scalar-evolution.h" -#include "tree-vectorizer.h" #include "omp-general.h" #include "diagnostic-core.h" #include "stringpool.h" -- cgit v1.1 From 2b074dc7bdf4402c1e3e44f247e27f3ef51bd8e4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 24 Jul 2023 12:14:26 +0200 Subject: Remove SLP_TREE_VEC_STMTS in favor of SLP_TREE_VEC_DEFS The following unifies SLP_TREE_VEC_STMTS into SLP_TREE_VEC_DEFS which can handle all cases we need. * tree-vectorizer.h (_slp_tree::push_vec_def): Add. (_slp_tree::vec_stmts): Remove. (SLP_TREE_VEC_STMTS): Remove. * tree-vect-slp.cc (_slp_tree::push_vec_def): Define. (_slp_tree::_slp_tree): Adjust. (_slp_tree::~_slp_tree): Likewise. (vect_get_slp_vect_def): Simplify. (vect_get_slp_defs): Likewise. (vect_transform_slp_perm_load_1): Adjust. (vect_add_slp_permutation): Likewise. (vect_schedule_slp_node): Likewise. (vectorize_slp_instance_root_stmt): Likewise. (vect_schedule_scc): Likewise. * tree-vect-stmts.cc (vectorizable_bswap): Use push_vec_def. (vectorizable_call): Likewise. (vectorizable_call): Likewise. (vect_create_vectorized_demotion_stmts): Likewise. (vectorizable_conversion): Likewise. (vectorizable_assignment): Likewise. (vectorizable_shift): Likewise. (vectorizable_operation): Likewise. (vectorizable_load): Likewise. (vectorizable_condition): Likewise. (vectorizable_comparison): Likewise. * tree-vect-loop.cc (vect_create_epilog_for_reduction): Adjust. (vectorize_fold_left_reduction): Use push_vec_def. (vect_transform_reduction): Likewise. (vect_transform_cycle_phi): Likewise. (vectorizable_lc_phi): Likewise. (vectorizable_phi): Likewise. (vectorizable_recurr): Likewise. (vectorizable_induction): Likewise. (vectorizable_live_operation): Likewise. --- gcc/tree-vect-loop.cc | 31 +++++++++-------- gcc/tree-vect-slp.cc | 91 +++++++++++++++++++++++++++----------------------- gcc/tree-vect-stmts.cc | 32 +++++++++--------- gcc/tree-vectorizer.h | 7 ++-- 4 files changed, 84 insertions(+), 77 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index ac86b09..2561552 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -5847,7 +5847,7 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, int ncopies; if (slp_node) { - vec_num = SLP_TREE_VEC_STMTS (slp_node_instance->reduc_phis).length (); + vec_num = SLP_TREE_VEC_DEFS (slp_node_instance->reduc_phis).length (); ncopies = 1; } else @@ -6990,7 +6990,7 @@ vectorize_fold_left_reduction (loop_vec_info loop_vinfo, new_stmt, gsi); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else { STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); @@ -8292,7 +8292,7 @@ vect_transform_reduction (loop_vec_info loop_vinfo, } if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else if (single_defuse_cycle && i < ncopies - 1) { @@ -8578,7 +8578,7 @@ vect_transform_cycle_phi (loop_vec_info loop_vinfo, /* The loop-latch arg is set in epilogue processing. */ if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_phi); + slp_node->push_vec_def (new_phi); else { if (j == 0) @@ -8639,7 +8639,7 @@ vectorizable_lc_phi (loop_vec_info loop_vinfo, gphi *new_phi = create_phi_node (vec_dest, bb); add_phi_arg (new_phi, vec_oprnds[i], e, UNKNOWN_LOCATION); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_phi); + slp_node->push_vec_def (new_phi); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_phi); } @@ -8719,7 +8719,7 @@ vectorizable_phi (vec_info *, /* Skip not yet vectorized defs. */ if (SLP_TREE_DEF_TYPE (child) == vect_internal_def - && SLP_TREE_VEC_STMTS (child).is_empty ()) + && SLP_TREE_VEC_DEFS (child).is_empty ()) continue; auto_vec vec_oprnds; @@ -8731,7 +8731,7 @@ vectorizable_phi (vec_info *, { /* Create the vectorized LC PHI node. */ new_phis.quick_push (create_phi_node (vec_dest, bb)); - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_phis[j]); + slp_node->push_vec_def (new_phis[j]); } } edge e = gimple_phi_arg_edge (as_a (stmt_info->stmt), i); @@ -8912,7 +8912,7 @@ vectorizable_recurr (loop_vec_info loop_vinfo, stmt_vec_info stmt_info, vect_finish_stmt_generation (loop_vinfo, stmt_info, vperm, &gsi2); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (vperm); + slp_node->push_vec_def (vperm); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (vperm); } @@ -9868,7 +9868,7 @@ vectorizable_induction (loop_vec_info loop_vinfo, /* Set the arguments of the phi node: */ add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION); - SLP_TREE_VEC_STMTS (slp_node).quick_push (induction_phi); + slp_node->push_vec_def (induction_phi); } if (!nested_in_vect_loop) { @@ -9878,8 +9878,7 @@ vectorizable_induction (loop_vec_info loop_vinfo, vec_steps.reserve (nivs-ivn); for (; ivn < nivs; ++ivn) { - SLP_TREE_VEC_STMTS (slp_node) - .quick_push (SLP_TREE_VEC_STMTS (slp_node)[0]); + slp_node->push_vec_def (SLP_TREE_VEC_DEFS (slp_node)[0]); vec_steps.quick_push (vec_steps[0]); } } @@ -9898,7 +9897,8 @@ vectorizable_induction (loop_vec_info loop_vinfo, : build_int_cstu (stept, vfp)); for (; ivn < nvects; ++ivn) { - gimple *iv = SLP_TREE_VEC_STMTS (slp_node)[ivn - nivs]; + gimple *iv + = SSA_NAME_DEF_STMT (SLP_TREE_VEC_DEFS (slp_node)[ivn - nivs]); tree def = gimple_get_lhs (iv); if (ivn < 2*nivs) vec_steps[ivn - nivs] @@ -9916,8 +9916,7 @@ vectorizable_induction (loop_vec_info loop_vinfo, gimple_stmt_iterator tgsi = gsi_for_stmt (iv); gsi_insert_seq_after (&tgsi, stmts, GSI_CONTINUE_LINKING); } - SLP_TREE_VEC_STMTS (slp_node) - .quick_push (SSA_NAME_DEF_STMT (def)); + slp_node->push_vec_def (def); } } @@ -10343,8 +10342,8 @@ vectorizable_live_operation (vec_info *vinfo, gcc_assert (!loop_vinfo || !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)); /* Get the correct slp vectorized stmt. */ - vec_stmt = SLP_TREE_VEC_STMTS (slp_node)[vec_entry]; - vec_lhs = gimple_get_lhs (vec_stmt); + vec_lhs = SLP_TREE_VEC_DEFS (slp_node)[vec_entry]; + vec_stmt = SSA_NAME_DEF_STMT (vec_lhs); /* Get entry to use. */ bitstart = bitsize_int (vec_index); diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index f4adbb2..e443024 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -112,7 +112,6 @@ _slp_tree::_slp_tree () slp_first_node = this; SLP_TREE_SCALAR_STMTS (this) = vNULL; SLP_TREE_SCALAR_OPS (this) = vNULL; - SLP_TREE_VEC_STMTS (this) = vNULL; SLP_TREE_VEC_DEFS (this) = vNULL; SLP_TREE_NUMBER_OF_VEC_STMTS (this) = 0; SLP_TREE_CHILDREN (this) = vNULL; @@ -141,7 +140,6 @@ _slp_tree::~_slp_tree () SLP_TREE_CHILDREN (this).release (); SLP_TREE_SCALAR_STMTS (this).release (); SLP_TREE_SCALAR_OPS (this).release (); - SLP_TREE_VEC_STMTS (this).release (); SLP_TREE_VEC_DEFS (this).release (); SLP_TREE_LOAD_PERMUTATION (this).release (); SLP_TREE_LANE_PERMUTATION (this).release (); @@ -149,6 +147,20 @@ _slp_tree::~_slp_tree () free (failed); } +/* Push the single SSA definition in DEF to the vector of vector defs. */ + +void +_slp_tree::push_vec_def (gimple *def) +{ + if (gphi *phi = dyn_cast (def)) + vec_defs.quick_push (gimple_phi_result (phi)); + else + { + def_operand_p defop = single_ssa_def_operand (def, SSA_OP_ALL_DEFS); + vec_defs.quick_push (get_def_from_ptr (defop)); + } +} + /* Recursively free the memory allocated for the SLP tree rooted at NODE. */ void @@ -8092,10 +8104,7 @@ vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node) tree vect_get_slp_vect_def (slp_tree slp_node, unsigned i) { - if (SLP_TREE_VEC_STMTS (slp_node).exists ()) - return gimple_get_lhs (SLP_TREE_VEC_STMTS (slp_node)[i]); - else - return SLP_TREE_VEC_DEFS (slp_node)[i]; + return SLP_TREE_VEC_DEFS (slp_node)[i]; } /* Get the vectorized definitions of SLP_NODE in *VEC_DEFS. */ @@ -8104,15 +8113,7 @@ void vect_get_slp_defs (slp_tree slp_node, vec *vec_defs) { vec_defs->create (SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node)); - if (SLP_TREE_DEF_TYPE (slp_node) == vect_internal_def) - { - unsigned j; - gimple *vec_def_stmt; - FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (slp_node), j, vec_def_stmt) - vec_defs->quick_push (gimple_get_lhs (vec_def_stmt)); - } - else - vec_defs->splice (SLP_TREE_VEC_DEFS (slp_node)); + vec_defs->splice (SLP_TREE_VEC_DEFS (slp_node)); } /* Get N vectorized definitions for SLP_NODE. */ @@ -8170,8 +8171,8 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node, /* Initialize the vect stmts of NODE to properly insert the generated stmts later. */ if (! analyze_only) - for (unsigned i = SLP_TREE_VEC_STMTS (node).length (); i < nstmts; i++) - SLP_TREE_VEC_STMTS (node).quick_push (NULL); + for (unsigned i = SLP_TREE_VEC_DEFS (node).length (); i < nstmts; i++) + SLP_TREE_VEC_DEFS (node).quick_push (NULL_TREE); /* Generate permutation masks for every NODE. Number of masks for each NODE is equal to GROUP_SIZE. @@ -8337,7 +8338,7 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node, } /* Store the vector statement in NODE. */ - SLP_TREE_VEC_STMTS (node)[vect_stmts_counter++] = perm_stmt; + SLP_TREE_VEC_DEFS (node)[vect_stmts_counter++] = perm_dest; } } else if (!analyze_only) @@ -8347,12 +8348,11 @@ vect_transform_slp_perm_load_1 (vec_info *vinfo, slp_tree node, tree first_vec = dr_chain[first_vec_index + ri]; /* If mask was NULL_TREE generate the requested identity transform. */ - gimple *perm_stmt = SSA_NAME_DEF_STMT (first_vec); if (dce_chain) bitmap_set_bit (used_defs, first_vec_index + ri); /* Store the vector statement in NODE. */ - SLP_TREE_VEC_STMTS (node)[vect_stmts_counter++] = perm_stmt; + SLP_TREE_VEC_DEFS (node)[vect_stmts_counter++] = first_vec; } } @@ -8503,7 +8503,7 @@ vect_add_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi, } vect_finish_stmt_generation (vinfo, NULL, perm_stmt, gsi); /* Store the vector statement in NODE. */ - SLP_TREE_VEC_STMTS (node).quick_push (perm_stmt); + node->push_vec_def (perm_stmt); } /* Subroutine of vectorizable_slp_permutation. Check whether the target @@ -8822,10 +8822,11 @@ vect_schedule_slp_node (vec_info *vinfo, slp_tree child; /* For existing vectors there's nothing to do. */ - if (SLP_TREE_VEC_DEFS (node).exists ()) + if (SLP_TREE_DEF_TYPE (node) == vect_external_def + && SLP_TREE_VEC_DEFS (node).exists ()) return; - gcc_assert (SLP_TREE_VEC_STMTS (node).is_empty ()); + gcc_assert (SLP_TREE_VEC_DEFS (node).is_empty ()); /* Vectorize externals and constants. */ if (SLP_TREE_DEF_TYPE (node) == vect_constant_def @@ -8844,7 +8845,7 @@ vect_schedule_slp_node (vec_info *vinfo, stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); gcc_assert (SLP_TREE_NUMBER_OF_VEC_STMTS (node) != 0); - SLP_TREE_VEC_STMTS (node).create (SLP_TREE_NUMBER_OF_VEC_STMTS (node)); + SLP_TREE_VEC_DEFS (node).create (SLP_TREE_NUMBER_OF_VEC_STMTS (node)); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, @@ -8885,7 +8886,7 @@ vect_schedule_slp_node (vec_info *vinfo, reduction PHI but we still have SLP_TREE_NUM_VEC_STMTS set so the representation isn't perfect. Resort to the last scalar def here. */ - if (SLP_TREE_VEC_STMTS (child).is_empty ()) + if (SLP_TREE_VEC_DEFS (child).is_empty ()) { gcc_assert (STMT_VINFO_TYPE (SLP_TREE_REPRESENTATIVE (child)) == cycle_phi_info_type); @@ -8900,11 +8901,14 @@ vect_schedule_slp_node (vec_info *vinfo, ??? Unless we have a load permutation applied and that figures to re-use an earlier generated load. */ unsigned j; - gimple *vstmt; - FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (child), j, vstmt) - if (!last_stmt - || vect_stmt_dominates_stmt_p (last_stmt, vstmt)) - last_stmt = vstmt; + tree vdef; + FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (child), j, vdef) + { + gimple *vstmt = SSA_NAME_DEF_STMT (vdef); + if (!last_stmt + || vect_stmt_dominates_stmt_p (last_stmt, vstmt)) + last_stmt = vstmt; + } } else if (!SLP_TREE_VECTYPE (child)) { @@ -9069,8 +9073,7 @@ vectorize_slp_instance_root_stmt (slp_tree node, slp_instance instance) { if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) == 1) { - gimple *child_stmt = SLP_TREE_VEC_STMTS (node)[0]; - tree vect_lhs = gimple_get_lhs (child_stmt); + tree vect_lhs = SLP_TREE_VEC_DEFS (node)[0]; tree root_lhs = gimple_get_lhs (instance->root_stmts[0]->stmt); if (!useless_type_conversion_p (TREE_TYPE (root_lhs), TREE_TYPE (vect_lhs))) @@ -9081,7 +9084,7 @@ vectorize_slp_instance_root_stmt (slp_tree node, slp_instance instance) else if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) > 1) { int nelts = SLP_TREE_NUMBER_OF_VEC_STMTS (node); - gimple *child_stmt; + tree child_def; int j; vec *v; vec_alloc (v, nelts); @@ -9089,9 +9092,8 @@ vectorize_slp_instance_root_stmt (slp_tree node, slp_instance instance) /* A CTOR can handle V16HI composition from VNx8HI so we do not need to convert vector elements if the types do not match. */ - FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (node), j, child_stmt) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - gimple_get_lhs (child_stmt)); + FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (node), j, child_def) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, child_def); tree lhs = gimple_get_lhs (instance->root_stmts[0]->stmt); tree rtype = TREE_TYPE (gimple_assign_rhs1 (instance->root_stmts[0]->stmt)); @@ -9282,26 +9284,31 @@ vect_schedule_scc (vec_info *vinfo, slp_tree node, slp_instance instance, child = SLP_TREE_CHILDREN (phi_node)[dest_idx]; if (!child || SLP_TREE_DEF_TYPE (child) != vect_internal_def) continue; - unsigned n = SLP_TREE_VEC_STMTS (phi_node).length (); + unsigned n = SLP_TREE_VEC_DEFS (phi_node).length (); /* Simply fill all args. */ if (STMT_VINFO_DEF_TYPE (SLP_TREE_REPRESENTATIVE (phi_node)) != vect_first_order_recurrence) for (unsigned i = 0; i < n; ++i) - add_phi_arg (as_a (SLP_TREE_VEC_STMTS (phi_node)[i]), - vect_get_slp_vect_def (child, i), - e, gimple_phi_arg_location (phi, dest_idx)); + { + tree phidef = SLP_TREE_VEC_DEFS (phi_node)[i]; + gphi *phi = as_a (SSA_NAME_DEF_STMT (phidef)); + add_phi_arg (phi, vect_get_slp_vect_def (child, i), + e, gimple_phi_arg_location (phi, dest_idx)); + } else { /* Unless it is a first order recurrence which needs args filled in for both the PHI node and the permutes. */ - gimple *perm = SLP_TREE_VEC_STMTS (phi_node)[0]; + gimple *perm + = SSA_NAME_DEF_STMT (SLP_TREE_VEC_DEFS (phi_node)[0]); gimple *rphi = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (perm)); add_phi_arg (as_a (rphi), vect_get_slp_vect_def (child, n - 1), e, gimple_phi_arg_location (phi, dest_idx)); for (unsigned i = 0; i < n; ++i) { - gimple *perm = SLP_TREE_VEC_STMTS (phi_node)[i]; + gimple *perm + = SSA_NAME_DEF_STMT (SLP_TREE_VEC_DEFS (phi_node)[i]); if (i > 0) gimple_assign_set_rhs1 (perm, vect_get_slp_vect_def (child, i - 1)); diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 15e12f2..99e61f8 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -3237,7 +3237,7 @@ vectorizable_bswap (vec_info *vinfo, vectype, tem2)); vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -3694,7 +3694,7 @@ vectorizable_call (vec_info *vinfo, vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); new_stmt = call; } - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); } continue; } @@ -3823,7 +3823,7 @@ vectorizable_call (vec_info *vinfo, gimple_call_set_lhs (call, new_temp); gimple_call_set_nothrow (call, true); vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); - SLP_TREE_VEC_STMTS (slp_node).quick_push (call); + slp_node->push_vec_def (call); } continue; } @@ -4827,7 +4827,7 @@ vect_create_vectorized_demotion_stmts (vec_info *vinfo, vec *vec_oprnds, vectors in SLP_NODE or in vector info of the scalar statement (or in STMT_VINFO_RELATED_STMT chain). */ if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -5564,7 +5564,7 @@ vectorizable_conversion (vec_info *vinfo, vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -5620,7 +5620,7 @@ vectorizable_conversion (vec_info *vinfo, new_stmt = SSA_NAME_DEF_STMT (vop0); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -5666,7 +5666,7 @@ vectorizable_conversion (vec_info *vinfo, vectors in SLP_NODE or in vector info of the scalar statement (or in STMT_VINFO_RELATED_STMT chain). */ if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -5865,7 +5865,7 @@ vectorizable_assignment (vec_info *vinfo, gimple_assign_set_lhs (new_stmt, new_temp); vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -6323,7 +6323,7 @@ vectorizable_shift (vec_info *vinfo, gimple_assign_set_lhs (new_stmt, new_temp); vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -6985,7 +6985,7 @@ vectorizable_operation (vec_info *vinfo, } if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -9708,7 +9708,7 @@ vectorizable_load (vec_info *vinfo, gimple *new_stmt = SSA_NAME_DEF_STMT (new_temp); if (slp) for (j = 0; j < (int) SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); ++j) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else { for (j = 0; j < ncopies; ++j) @@ -9947,7 +9947,7 @@ vectorizable_load (vec_info *vinfo, if (slp_perm) dr_chain.quick_push (gimple_assign_lhs (new_stmt)); else - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); } else { @@ -10011,7 +10011,7 @@ vectorizable_load (vec_info *vinfo, /* Check if the chain of loads is already vectorized. */ if (STMT_VINFO_VEC_STMTS (first_stmt_info).exists () - /* For SLP we would need to copy over SLP_TREE_VEC_STMTS. + /* For SLP we would need to copy over SLP_TREE_VEC_DEFS. ??? But we can only do so if there is exactly one as we have no way to get at the rest. Leave the CSE opportunity alone. @@ -10997,7 +10997,7 @@ vectorizable_load (vec_info *vinfo, /* Store vector loads in the corresponding SLP_NODE. */ if (!costing_p && slp && !slp_perm) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); /* With SLP permutation we load the gaps as well, without we need to skip the gaps after we manage to fully load @@ -11705,7 +11705,7 @@ vectorizable_condition (vec_info *vinfo, vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); } if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } @@ -11942,7 +11942,7 @@ vectorizable_comparison (vec_info *vinfo, } } if (slp_node) - SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); + slp_node->push_vec_def (new_stmt); else STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 6b1cf6d..a651614 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -174,6 +174,9 @@ struct _slp_tree { _slp_tree (); ~_slp_tree (); + void push_vec_def (gimple *def); + void push_vec_def (tree def) { vec_defs.quick_push (def); } + /* Nodes that contain def-stmts of this node statements operands. */ vec children; @@ -194,8 +197,7 @@ struct _slp_tree { lane_permutation_t lane_permutation; tree vectype; - /* Vectorized stmt/s. */ - vec vec_stmts; + /* Vectorized defs. */ vec vec_defs; /* Number of vector stmts that are created to replace the group of scalar stmts. It is calculated during the transformation phase as the number of @@ -289,7 +291,6 @@ public: #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts #define SLP_TREE_SCALAR_OPS(S) (S)->ops #define SLP_TREE_REF_COUNT(S) (S)->refcnt -#define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts #define SLP_TREE_VEC_DEFS(S) (S)->vec_defs #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size #define SLP_TREE_LOAD_PERMUTATION(S) (S)->load_permutation -- cgit v1.1 From aa1e2d543869a07580f9b2112f2d7367f83a6753 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 24 Jul 2023 07:56:36 -0600 Subject: [committed][RISC-V] Fix minor issues in diagnostic message This fixes two minor issues with the recently adding warning about too large VLEN in the RISC-V backend. These prevent the RISC-V port from bootstrapping as both Andreas and I have found. Specifically we'll get warnings for the use of '>' in the recently added message as well as using "can not" vs "cannot". While these warnings may seem annoying, they're in place to make it easier for the translators. This patch fixes the message in the fairly obvious way. Spells out the greater than and uses cannot. There's a similar issue in another recently added diagnostic that I'll push momentarily. gcc/ * config/riscv/riscv.cc (riscv_option_override): Spell out greater than and use cannot in diagnostic string. --- gcc/config/riscv/riscv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 332fa72..941ea25 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6713,7 +6713,7 @@ riscv_option_override (void) We can only allow TARGET_MIN_VLEN * 8 (LMUL) < 65535. */ if (TARGET_MIN_VLEN > 4096) sorry ( - "Current RISC-V GCC can not support VLEN > 4096bit for 'V' Extension"); + "Current RISC-V GCC cannot support VLEN greater than 4096bit for 'V' Extension"); /* Convert -march to a chunks count. */ riscv_vector_chunks = riscv_convert_vector_bits (); -- cgit v1.1 From 4be3919fb75e3d2a4d2bb80ba33c14e0973bc08f Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 24 Jul 2023 15:57:05 +0200 Subject: bpf: sdiv/smod are now part of BPF V4 We used to support signed division and signed modulus instructions in the XBPF GCC-specific extensions to BPF. However, BPF catched up by adding these instructions in the V4 of the ISA. This patch changes GCC in order to use sdiv/smod instructions when -mcpu=v4 or higher. The testsuite and the manual have been updated accordingly. Tested in bpf-unknown-none. gcc/ChangeLog PR target/110783 * config/bpf/bpf.opt: New command-line option -msdiv. * config/bpf/bpf.md: Conditionalize sdiv/smod on bpf_has_sdiv. * config/bpf/bpf.cc (bpf_option_override): Initialize bpf_has_sdiv. * doc/invoke.texi (eBPF Options): Document -msdiv. gcc/testsuite/ChangeLog PR target/110783 * gcc.target/bpf/xbpf-sdiv-1.c: Renamed to sdiv-1.c * gcc.target/bpf/xbpf-smod-1.c: Renamed to smod-1.c * gcc.target/bpf/sdiv-1.c: Renamed from xbpf-sdiv-1.c, use -mcpu=v4. * gcc.target/bpf/smod-1.c: Renamed from xbpf-smod-1.c, use -mcpu=v4. * gcc.target/bpf/diag-sdiv.c: Use -mcpu=v3. * gcc.target/bpf/diag-smod.c: Likewise. --- gcc/config/bpf/bpf.cc | 3 +++ gcc/config/bpf/bpf.md | 16 ++++++++-------- gcc/config/bpf/bpf.opt | 4 ++++ gcc/doc/invoke.texi | 5 +++++ gcc/testsuite/gcc.target/bpf/diag-sdiv.c | 2 +- gcc/testsuite/gcc.target/bpf/diag-smod.c | 2 +- gcc/testsuite/gcc.target/bpf/sdiv-1.c | 14 ++++++++++++++ gcc/testsuite/gcc.target/bpf/smod-1.c | 14 ++++++++++++++ gcc/testsuite/gcc.target/bpf/xbpf-sdiv-1.c | 14 -------------- gcc/testsuite/gcc.target/bpf/xbpf-smod-1.c | 14 -------------- 10 files changed, 50 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/gcc.target/bpf/sdiv-1.c create mode 100644 gcc/testsuite/gcc.target/bpf/smod-1.c delete mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-sdiv-1.c delete mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-smod-1.c (limited to 'gcc') diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index 18d3b5f..55b6927 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -256,6 +256,9 @@ bpf_option_override (void) if (bpf_has_bswap == -1) bpf_has_bswap = (bpf_isa >= ISA_V4); + if (bpf_has_sdiv == -1) + bpf_has_sdiv = (bpf_isa >= ISA_V4); + /* Disable -fstack-protector as it is not supported in BPF. */ if (flag_stack_protect) { diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index 81e2268..3e2d760 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -167,8 +167,8 @@ ;;; Division -;; Note that eBPF doesn't provide instructions for signed integer -;; division. +;; Note that eBPF <= V3 doesn't provide instructions for signed +;; integer division. (define_insn "udiv3" [(set (match_operand:AM 0 "register_operand" "=r,r") @@ -178,20 +178,20 @@ "{div\t%0,%2|%w0 /= %w2}" [(set_attr "type" "")]) -;; However, xBPF does provide a signed division operator, sdiv. +;; However, BPF V4 does provide a signed division operator, sdiv. (define_insn "div3" [(set (match_operand:AM 0 "register_operand" "=r,r") (div:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] - "TARGET_XBPF" + "bpf_has_sdiv" "{sdiv\t%0,%2|%w0 s/= %w2}" [(set_attr "type" "")]) ;;; Modulus -;; Note that eBPF doesn't provide instructions for signed integer -;; remainder. +;; Note that eBPF <= V3 doesn't provide instructions for signed +;; integer remainder. (define_insn "umod3" [(set (match_operand:AM 0 "register_operand" "=r,r") @@ -201,13 +201,13 @@ "{mod\t%0,%2|%w0 %%= %w2}" [(set_attr "type" "")]) -;; Again, xBPF provides a signed version, smod. +;; However, BPF V4 does provide a signed modulus operator, smod. (define_insn "mod3" [(set (match_operand:AM 0 "register_operand" "=r,r") (mod:AM (match_operand:AM 1 "register_operand" " 0,0") (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] - "TARGET_XBPF" + "bpf_has_sdiv" "{smod\t%0,%2|%w0 s%%= %w2}" [(set_attr "type" "")]) diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index 3bf9033..bd35f8d 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -63,6 +63,10 @@ mbswap Target Var(bpf_has_bswap) Init(-1) Enable byte swap instructions. +msdiv +Target Var(bpf_has_sdiv) Init(-1) +Enable signed division and modulus instructions. + mcpu= Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V4) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a977a34..fa765d5 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -24711,6 +24711,11 @@ Enable 32-bit ALU instructions. Enabled for CPU v3 and above. @item -mbswap Enable byte swap instructions. Enabled for CPU v4 and above. +@opindex msdiv +@item -msdiv +Enable signed division and modulus instructions. Enabled for CPU v4 +and above. + @opindex mcpu @item -mcpu=@var{version} This specifies which version of the eBPF ISA to target. Newer versions diff --git a/gcc/testsuite/gcc.target/bpf/diag-sdiv.c b/gcc/testsuite/gcc.target/bpf/diag-sdiv.c index db0c494..c48bbf0 100644 --- a/gcc/testsuite/gcc.target/bpf/diag-sdiv.c +++ b/gcc/testsuite/gcc.target/bpf/diag-sdiv.c @@ -1,6 +1,6 @@ /* Verify signed division does not produce 'sdiv' insn in eBPF. */ /* { dg-do compile } */ -/* { dg-options "-O0" } */ +/* { dg-options "-O0 -mcpu=v3" } */ void foo () diff --git a/gcc/testsuite/gcc.target/bpf/diag-smod.c b/gcc/testsuite/gcc.target/bpf/diag-smod.c index 20234ee..d3df308 100644 --- a/gcc/testsuite/gcc.target/bpf/diag-smod.c +++ b/gcc/testsuite/gcc.target/bpf/diag-smod.c @@ -1,6 +1,6 @@ /* Verify signed modulo does not produce 'smod' insn in eBPF. */ /* { dg-do compile } */ -/* { dg-options "-O0" } */ +/* { dg-options "-O0 -mcpu=v3" } */ void foo () diff --git a/gcc/testsuite/gcc.target/bpf/sdiv-1.c b/gcc/testsuite/gcc.target/bpf/sdiv-1.c new file mode 100644 index 0000000..ad75b04 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/sdiv-1.c @@ -0,0 +1,14 @@ +/* Verify that sdiv instruction is used for xBPF. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mcpu=v4" } */ + +void +foo () +{ + signed int x = 5; + signed int y = 2; + signed int z = x / y; + signed int w = x / 3; +} + +/* { dg-final { scan-assembler "sdiv(32)?\t%r" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/smod-1.c b/gcc/testsuite/gcc.target/bpf/smod-1.c new file mode 100644 index 0000000..c5fc6f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/smod-1.c @@ -0,0 +1,14 @@ +/* Verify that smod instruction is used for xBPF. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mcpu=v4" } */ + +void +foo () +{ + signed int x = 5; + signed int y = 2; + signed int z = x % y; + signed int w = x % 3; +} + +/* { dg-final { scan-assembler "smod(32)?\t%r" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/xbpf-sdiv-1.c b/gcc/testsuite/gcc.target/bpf/xbpf-sdiv-1.c deleted file mode 100644 index f6c5c9e..0000000 --- a/gcc/testsuite/gcc.target/bpf/xbpf-sdiv-1.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Verify that sdiv instruction is used for xBPF. */ -/* { dg-do compile } */ -/* { dg-options "-O0 -mxbpf" } */ - -void -foo () -{ - signed int x = 5; - signed int y = 2; - signed int z = x / y; - signed int w = x / 3; -} - -/* { dg-final { scan-assembler "sdiv(32)?\t%r" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/xbpf-smod-1.c b/gcc/testsuite/gcc.target/bpf/xbpf-smod-1.c deleted file mode 100644 index b3e5816..0000000 --- a/gcc/testsuite/gcc.target/bpf/xbpf-smod-1.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Verify that smod instruction is used for xBPF. */ -/* { dg-do compile } */ -/* { dg-options "-O0 -mxbpf" } */ - -void -foo () -{ - signed int x = 5; - signed int y = 2; - signed int z = x % y; - signed int w = x % 3; -} - -/* { dg-final { scan-assembler "smod(32)?\t%r" } } */ -- cgit v1.1 From d90e81af8052e96ae3262ed3ac42682537fc42c6 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 24 Jul 2023 08:10:21 -0600 Subject: [committed] Use single quote rather than backquote in RISC-V diagnostic Similar to the other patch this morning, this fixes a warning that was causing the RISC-V bootstrap to fail. In this case the diagnostic used a backquote. This changes it to a simple single quote which the diagnostic framework won't complain about. Committed to the trunk. gcc/ * common/config/riscv/riscv-common.cc (riscv_subset_list::add): Use single quote rather than backquote in diagnostic. --- gcc/common/config/riscv/riscv-common.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 884d81c..5238877 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -573,7 +573,7 @@ riscv_subset_list::add (const char *subset, int major_version, else if (subset[0] == 'z' && !standard_extensions_p (subset)) { error_at (m_loc, - "%<-march=%s%>: extension %qs starts with `z` but is " + "%<-march=%s%>: extension %qs starts with 'z' but is " "unsupported standard extension", m_arch, subset); return; @@ -581,7 +581,7 @@ riscv_subset_list::add (const char *subset, int major_version, else if (subset[0] == 's' && !standard_extensions_p (subset)) { error_at (m_loc, - "%<-march=%s%>: extension %qs starts with `s` but is " + "%<-march=%s%>: extension %qs starts with 's' but is " "unsupported standard supervisor extension", m_arch, subset); return; @@ -589,7 +589,7 @@ riscv_subset_list::add (const char *subset, int major_version, else if (subset[0] == 'x' && !standard_extensions_p (subset)) { error_at (m_loc, - "%<-march=%s%>: extension %qs starts with `x` but is " + "%<-march=%s%>: extension %qs starts with 'x' but is " "unsupported non-standard extension", m_arch, subset); return; -- cgit v1.1 From 2a3556376c69a1fb588dcf25225950575e42784f Mon Sep 17 00:00:00 2001 From: Drew Ross Date: Mon, 24 Jul 2023 17:51:28 +0200 Subject: match.pd: Implement missed optimization (~X | Y) ^ X -> ~(X & Y) [PR109986] Adds a simplification for (~X | Y) ^ X to be folded into ~(X & Y). Also adds the macro bitwise_equal_p for generic and gimple which returns true iff EXPR1 and EXPR2 have the same value. This helps to reduce the number of nop_converts necessary to match the pattern. PR middle-end/109986 gcc/ChangeLog: * generic-match-head.cc (bitwise_equal_p): New macro. * gimple-match-head.cc (bitwise_equal_p): New macro. (gimple_nop_convert): Declare. (gimple_bitwise_equal_p): Helper for bitwise_equal_p. * match.pd ((~X | Y) ^ X -> ~(X & Y)): New simplification. gcc/testsuite/ChangeLog: * gcc.c-torture/execute/pr109986.c: New test. * gcc.dg/tree-ssa/pr109986.c: New test. Co-authored-by: Jakub Jelinek --- gcc/generic-match-head.cc | 17 +++ gcc/gimple-match-head.cc | 37 ++++++ gcc/match.pd | 6 + gcc/testsuite/gcc.c-torture/execute/pr109986.c | 41 ++++++ gcc/testsuite/gcc.dg/tree-ssa/pr109986.c | 177 +++++++++++++++++++++++++ 5 files changed, 278 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr109986.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr109986.c (limited to 'gcc') diff --git a/gcc/generic-match-head.cc b/gcc/generic-match-head.cc index f011204..b4b5bc8 100644 --- a/gcc/generic-match-head.cc +++ b/gcc/generic-match-head.cc @@ -102,3 +102,20 @@ optimize_successive_divisions_p (tree, tree) { return false; } + +/* Return true if EXPR1 and EXPR2 have the same value, but not necessarily + same type. The types can differ through nop conversions. */ + +static inline bool +bitwise_equal_p (tree expr1, tree expr2) +{ + STRIP_NOPS (expr1); + STRIP_NOPS (expr2); + if (expr1 == expr2) + return true; + if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2))) + return false; + if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST) + return wi::to_wide (expr1) == wi::to_wide (expr2); + return operand_equal_p (expr1, expr2, 0); +} diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc index b08cd89..d795066 100644 --- a/gcc/gimple-match-head.cc +++ b/gcc/gimple-match-head.cc @@ -224,3 +224,40 @@ optimize_successive_divisions_p (tree divisor, tree inner_div) } return true; } + +/* Return true if EXPR1 and EXPR2 have the same value, but not necessarily + same type. The types can differ through nop conversions. */ +#define bitwise_equal_p(expr1, expr2) \ + gimple_bitwise_equal_p (expr1, expr2, valueize) + +bool gimple_nop_convert (tree, tree *, tree (*) (tree)); + +/* Helper function for bitwise_equal_p macro. */ + +static inline bool +gimple_bitwise_equal_p (tree expr1, tree expr2, tree (*valueize) (tree)) +{ + if (expr1 == expr2) + return true; + if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2))) + return false; + if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST) + return wi::to_wide (expr1) == wi::to_wide (expr2); + if (operand_equal_p (expr1, expr2, 0)) + return true; + tree expr3, expr4; + if (!gimple_nop_convert (expr1, &expr3, valueize)) + expr3 = expr1; + if (!gimple_nop_convert (expr2, &expr4, valueize)) + expr4 = expr2; + if (expr1 != expr3) + { + if (operand_equal_p (expr3, expr2, 0)) + return true; + if (expr2 != expr4 && operand_equal_p (expr3, expr4, 0)) + return true; + } + if (expr2 != expr4 && operand_equal_p (expr1, expr4, 0)) + return true; + return false; +} diff --git a/gcc/match.pd b/gcc/match.pd index bfd15d6..ab7622b 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1648,6 +1648,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (convert (bit_and @1 (bit_not @0))))) +/* (~X | Y) ^ X -> ~(X & Y). */ +(simplify + (bit_xor:c (nop_convert1? (bit_ior:c (nop_convert2? (bit_not @0)) @1)) @2) + (if (bitwise_equal_p (@0, @2)) + (convert (bit_not (bit_and @0 (convert @1)))))) + /* Convert ~X ^ ~Y to X ^ Y. */ (simplify (bit_xor (convert1? (bit_not @0)) (convert2? (bit_not @1))) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr109986.c b/gcc/testsuite/gcc.c-torture/execute/pr109986.c new file mode 100644 index 0000000..00ee988 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr109986.c @@ -0,0 +1,41 @@ +/* PR middle-end/109986 */ + +#include "../../gcc.dg/tree-ssa/pr109986.c" + +int +main () +{ + if (t1 (29789, 29477) != -28678) __builtin_abort (); + if (t2 (20196, -18743) != 4294965567) __builtin_abort (); + if (t3 (127, 99) != -100) __builtin_abort (); + if (t4 (100, 53) != 219) __builtin_abort (); + if (t5 (20100, 1283) != -1025) __builtin_abort (); + if (t6 (20100, 10283) != 63487) __builtin_abort (); + if (t7 (2136614690L, 1136698390L) != -1128276995L) __builtin_abort (); + if (t8 (1136698390L, 2136614690L) != -1128276995UL) __builtin_abort (); + if (t9 (9176690219839792930LL, 3176690219839721234LL) != -3175044472123688707LL) + __builtin_abort (); + if (t10 (9176690219839792930LL, 3176690219839721234LL) != 15271699601585862909ULL) + __builtin_abort (); + if (t11 (29789, 29477) != -28678) __builtin_abort (); + if (t12 (20196, -18743) != 4294965567) __builtin_abort (); + if (t13 (127, 99) != -100) __builtin_abort (); + if (t14 (100, 53) != 219) __builtin_abort (); + if (t15 (20100, 1283) != -1025) __builtin_abort (); + if (t16 (20100, 10283) != 63487) __builtin_abort (); + if (t17 (2136614690, 1136698390) != -1128276995) __builtin_abort (); + if (t18 (1136698390L, 2136614690L) != -1128276995UL) __builtin_abort (); + if (t19 (9176690219839792930LL, 3176690219839721234LL) != -3175044472123688707LL) + __builtin_abort (); + if (t20 (9176690219839792930LL, 3176690219839721234LL) != 15271699601585862909ULL) + __builtin_abort (); + v4si a1 = {1, 2, 3, 4}; + v4si a2 = {6, 7, 8, 9}; + v4si r1 = {-1, -3, -1, -1}; + v4si b1 = t21 (a1, a2); + v4si b2 = t22 (a1, a2); + if (__builtin_memcmp (&b1, &r1, sizeof (b1) != 0)) __builtin_abort(); + if (__builtin_memcmp (&b2, &r1, sizeof (b2) != 0)) __builtin_abort(); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109986.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109986.c new file mode 100644 index 0000000..45f099b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109986.c @@ -0,0 +1,177 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dse1 -Wno-psabi" } */ + +typedef int v4si __attribute__((vector_size(16))); + +/* Generic */ +__attribute__((noipa)) int +t1 (int a, int b) +{ + return (~a | b) ^ a; +} + +__attribute__((noipa)) unsigned int +t2 (int a, int b) +{ + return a ^ (~a | (unsigned int) b); +} + +__attribute__((noipa)) char +t3 (char a, char b) +{ + return (b | ~a) ^ a; +} + +__attribute__((noipa)) unsigned char +t4 (char a, char b) +{ + return ((unsigned char) a) ^ (b | ~a); +} + +__attribute__((noipa)) short +t5 (short a, short b) +{ + return a ^ (b | ~a); +} + +__attribute__((noipa)) unsigned short +t6 (short a, short b) +{ + return ((unsigned short) a) ^ (b | ~a); +} + +__attribute__((noipa)) long +t7 (long a, long b) +{ + return a ^ (b | ~a); +} + +__attribute__((noipa)) unsigned long +t8 (long a, long b) +{ + return ((unsigned long) a) ^ (b | ~a); +} + +__attribute__((noipa)) long long +t9 (long long a, long long b) +{ + return a ^ (b | ~a); +} + +__attribute__((noipa)) unsigned long long +t10 (long long a, long long b) +{ + return ((unsigned long long) a) ^ (b | ~a); +} + +__attribute__((noipa)) v4si +t21 (v4si a, v4si b) +{ + return a ^ (b | ~a); +} + +/* Gimple */ +__attribute__((noipa)) int +t11 (int a, int b) +{ + int t1 = ~a; + int t2 = t1 | b; + int t3 = t2 ^ a; + return t3; +} + +__attribute__((noipa)) unsigned int +t12 (int a, unsigned int b) +{ + int t1 = ~a; + unsigned int t2 = t1 | b; + unsigned int t3 = a ^ t2; + return t3; +} + +__attribute__((noipa)) char +t13 (char a, char b) +{ + char t1 = ~a; + char t2 = b | t1; + char t3 = t2 ^ a; + return t3; +} + +__attribute__((noipa)) unsigned char +t14 (unsigned char a, char b) +{ + unsigned char t1 = ~a; + char t2 = b | t1; + unsigned char t3 = a ^ t2; + return t3; +} + +__attribute__((noipa)) short +t15 (short a, short b) +{ + short t1 = ~a; + short t2 = t1 | b; + short t3 = t2 ^ a; + return t3; +} + +__attribute__((noipa)) unsigned short +t16 (unsigned short a, short b) +{ + short t1 = ~a; + short t2 = t1 | b; + unsigned short t3 = t2 ^ a; + return t3; +} + +__attribute__((noipa)) long +t17 (long a, long b) +{ + long t1 = ~a; + long t2 = t1 | b; + long t3 = t2 ^ a; + return t3; +} + +__attribute__((noipa)) unsigned long +t18 (long a, unsigned long b) +{ + long t1 = ~a; + unsigned long t2 = t1 | b; + unsigned long t3 = t2 ^ a; + return t3; +} + +__attribute__((noipa)) long long +t19 (long long a, long long b) +{ + long long t1 = ~a; + long long t2 = t1 | b; + long long t3 = t2 ^ a; + return t3; +} + +__attribute__((noipa)) unsigned long long +t20 (long long a, long long b) +{ + long long t1 = ~a; + long long t2 = t1 | b; + unsigned long long t3 = a ^ t2; + return t3; +} + +__attribute__((noipa)) v4si +t22 (v4si a, v4si b) +{ + v4si t1 = ~a; + v4si t2 = t1 | b; + v4si t3 = a ^ t2; + return t3; +} + +/* { dg-final { scan-tree-dump-not " \\\| " "dse1" } } */ +/* { dg-final { scan-tree-dump-not " \\\^ " "dse1" } } */ +/* { dg-final { scan-tree-dump-times " ~" 22 "dse1" } } */ +/* { dg-final { scan-tree-dump-times " & " 22 "dse1" } } */ + -- cgit v1.1 From be16bb885ef141dc497f6e7358ac82e9bed4f34d Mon Sep 17 00:00:00 2001 From: David Faust Date: Mon, 24 Jul 2023 11:40:57 -0700 Subject: bpf: add pseudo-c asm dialect for "nop" The define_insn "nop" was missing a template for the pseudo-c dialect, so the normal syntax was unconditionally emitted. gcc/ * config/bpf/bpf.md (nop): Add pseudo-c asm dialect template. --- gcc/config/bpf/bpf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index 3e2d760..64342ea 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -103,7 +103,7 @@ (define_insn "nop" [(const_int 0)] "" - "ja\t0" + "{ja\t0|goto 0}" [(set_attr "type" "alu")]) ;;;; Arithmetic/Logical -- cgit v1.1 From 2e31fe431b08b0302e1fa8a1c18ee51adafd41df Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Mon, 24 Jul 2023 22:57:07 +0200 Subject: OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065] OpenMP requires: "If a teams region is nested inside a target region, the corresponding target construct must not contain any statements, declarations or directives outside of the corresponding teams construct." This commit checks now for this restriction. PR fortran/110725 PR middle-end/71065 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_clauses): Add contains_teams_construct. * openmp.cc (resolve_omp_target): New; check for teams nesting. (gfc_resolve_omp_directive): Call it. * parse.cc (decode_omp_directive): Set contains_teams_construct on enclosing ST_OMP_TARGET. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/pr99226.f90: Update dg-error. * gfortran.dg/gomp/teams-5.f90: New test. --- gcc/fortran/gfortran.h | 1 + gcc/fortran/openmp.cc | 39 +++++++- gcc/fortran/parse.cc | 33 +++++++ gcc/testsuite/gfortran.dg/gomp/pr99226.f90 | 2 +- gcc/testsuite/gfortran.dg/gomp/teams-5.f90 | 150 +++++++++++++++++++++++++++++ 5 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/gomp/teams-5.f90 (limited to 'gcc') diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 6482a88..577ef80 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1575,6 +1575,7 @@ typedef struct gfc_omp_clauses unsigned order_unconstrained:1, order_reproducible:1, capture:1; unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1; unsigned non_rectangular:1, order_concurrent:1; + unsigned contains_teams_construct:1; ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3; ENUM_BITFIELD (gfc_omp_device_type) device_type:2; ENUM_BITFIELD (gfc_omp_memorder) memorder:3; diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 05a697d..675011a 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -10653,6 +10653,41 @@ gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED) } +static void +resolve_omp_target (gfc_code *code) +{ +#define GFC_IS_TEAMS_CONSTRUCT(op) \ + (op == EXEC_OMP_TEAMS \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE_SIMD \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD \ + || op == EXEC_OMP_TEAMS_LOOP) + + if (!code->ext.omp_clauses->contains_teams_construct) + return; + if ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op) + && code->block->next->next == NULL) + || (code->block->next->op == EXEC_BLOCK + && code->block->next->next + && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op) + && code->block->next->next->next == NULL)) + return; + gfc_code *c = code->block->next; + while (c && !GFC_IS_TEAMS_CONSTRUCT (c->op)) + c = c->next; + if (c) + gfc_error ("!$OMP TARGET region at %L with a nested TEAMS at %L may not " + "contain any other statement, declaration or directive outside " + "of the single TEAMS construct", &c->loc, &code->loc); + else + gfc_error ("!$OMP TARGET region at %L with a nested TEAMS may not " + "contain any other statement, declaration or directive outside " + "of the single TEAMS construct", &code->loc); +#undef GFC_IS_TEAMS_CONSTRUCT +} + + /* Resolve OpenMP directive clauses and check various requirements of each directive. */ @@ -10703,6 +10738,9 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_TEAMS_LOOP: resolve_omp_do (code); break; + case EXEC_OMP_TARGET: + resolve_omp_target (code); + gcc_fallthrough (); case EXEC_OMP_ALLOCATE: case EXEC_OMP_ALLOCATORS: case EXEC_OMP_ASSUME: @@ -10718,7 +10756,6 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_SCOPE: case EXEC_OMP_SECTIONS: case EXEC_OMP_SINGLE: - case EXEC_OMP_TARGET: case EXEC_OMP_TARGET_DATA: case EXEC_OMP_TARGET_ENTER_DATA: case EXEC_OMP_TARGET_EXIT_DATA: diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index e53b7a4..011a39c 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -1312,6 +1312,39 @@ decode_omp_directive (void) prog_unit->omp_target_seen = true; break; } + case ST_OMP_TEAMS: + case ST_OMP_TEAMS_DISTRIBUTE: + case ST_OMP_TEAMS_DISTRIBUTE_SIMD: + case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO: + case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case ST_OMP_TEAMS_LOOP: + if (gfc_state_stack->previous && gfc_state_stack->previous->tail) + { + gfc_state_data *stk = gfc_state_stack; + do { + stk = stk->previous; + } while (stk && stk->tail && stk->tail->op == EXEC_BLOCK); + if (stk && stk->tail) + switch (stk->tail->op) + { + case EXEC_OMP_TARGET: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case EXEC_OMP_TARGET_TEAMS_LOOP: + case EXEC_OMP_TARGET_PARALLEL: + case EXEC_OMP_TARGET_PARALLEL_DO: + case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: + case EXEC_OMP_TARGET_PARALLEL_LOOP: + case EXEC_OMP_TARGET_SIMD: + stk->tail->ext.omp_clauses->contains_teams_construct = 1; + break; + default: + break; + } + } + break; case ST_OMP_ERROR: if (new_st.ext.omp_clauses->at != OMP_AT_EXECUTION) return ST_NONE; diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 index 72dbdde..2aea0c1 100644 --- a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 @@ -2,7 +2,7 @@ subroutine sub (n) integer :: n, i - !$omp target ! { dg-error "construct with nested 'teams' construct contains directives outside of the 'teams' construct" } + !$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } !$omp teams distribute dist_schedule (static,n+4) do i = 1, 8 end do diff --git a/gcc/testsuite/gfortran.dg/gomp/teams-5.f90 b/gcc/testsuite/gfortran.dg/gomp/teams-5.f90 new file mode 100644 index 0000000..00377b6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/teams-5.f90 @@ -0,0 +1,150 @@ +! { dg-do compile } + +! PR fortran/110725 +! PR middle-end/71065 + +implicit none +integer :: x +!$omp target device(1) + block + !$omp teams num_teams(f()) + !$omp end teams + end block +!!$omp end target + +!$omp target device(1) + !$omp teams num_teams(f()) + !$omp end teams +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + x = 5 + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams + x = 5 +!$omp end target + +!$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + block + !$omp teams num_teams(f()) + !$omp end teams + end block + end block +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + x = 5 + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams + end block +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams + x = 5 + end block +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams + x = 5 + end block +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams + block; end block +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + block; end block; + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams + end block +!$omp end target + +!$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + !$omp teams num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp end teams + block; end block; + end block +!!$omp end target + + +contains + +function f() + !$omp declare target + integer, allocatable :: f + f = 5 +end +end + +subroutine sub1 + implicit none + integer :: x,i + + !$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + !$omp teams distribute num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + do i = 1, 5 + end do + x = 7 + end block + !$omp end target + + !$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + !$omp teams loop num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + do i = 1, 5 + end do + x = 7 + end block + !$omp end target + + !$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp teams distribute simd num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + do i = 1, 5 + end do + x = 7 + !$omp end target + + !$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + !$omp teams distribute parallel do num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + do i = 1, 5 + end do + x = 7 + !$omp end target + + !$omp target device(1) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + block + x = 7 + !$omp teams distribute parallel do simd num_teams(f()) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + do i = 1, 5 + end do + end block + !$omp end target + +contains + +function f() + !$omp declare target + integer, allocatable :: f + f = 5 +end + +end -- cgit v1.1 From 87d4356cab02a2a137eb49e4082cd82fd6132c91 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 25 Jul 2023 00:18:54 +0000 Subject: Daily bump. --- gcc/ChangeLog | 177 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/fortran/ChangeLog | 10 +++ gcc/testsuite/ChangeLog | 62 +++++++++++++++++ 4 files changed, 250 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2eab466..2ccde3f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,180 @@ +2023-07-24 David Faust + + * config/bpf/bpf.md (nop): Add pseudo-c asm dialect template. + +2023-07-24 Drew Ross + Jakub Jelinek + + PR middle-end/109986 + * generic-match-head.cc (bitwise_equal_p): New macro. + * gimple-match-head.cc (bitwise_equal_p): New macro. + (gimple_nop_convert): Declare. + (gimple_bitwise_equal_p): Helper for bitwise_equal_p. + * match.pd ((~X | Y) ^ X -> ~(X & Y)): New simplification. + +2023-07-24 Jeff Law + + * common/config/riscv/riscv-common.cc (riscv_subset_list::add): Use + single quote rather than backquote in diagnostic. + +2023-07-24 Jose E. Marchesi + + PR target/110783 + * config/bpf/bpf.opt: New command-line option -msdiv. + * config/bpf/bpf.md: Conditionalize sdiv/smod on bpf_has_sdiv. + * config/bpf/bpf.cc (bpf_option_override): Initialize + bpf_has_sdiv. + * doc/invoke.texi (eBPF Options): Document -msdiv. + +2023-07-24 Jeff Law + + * config/riscv/riscv.cc (riscv_option_override): Spell out + greater than and use cannot in diagnostic string. + +2023-07-24 Richard Biener + + * tree-vectorizer.h (_slp_tree::push_vec_def): Add. + (_slp_tree::vec_stmts): Remove. + (SLP_TREE_VEC_STMTS): Remove. + * tree-vect-slp.cc (_slp_tree::push_vec_def): Define. + (_slp_tree::_slp_tree): Adjust. + (_slp_tree::~_slp_tree): Likewise. + (vect_get_slp_vect_def): Simplify. + (vect_get_slp_defs): Likewise. + (vect_transform_slp_perm_load_1): Adjust. + (vect_add_slp_permutation): Likewise. + (vect_schedule_slp_node): Likewise. + (vectorize_slp_instance_root_stmt): Likewise. + (vect_schedule_scc): Likewise. + * tree-vect-stmts.cc (vectorizable_bswap): Use push_vec_def. + (vectorizable_call): Likewise. + (vectorizable_call): Likewise. + (vect_create_vectorized_demotion_stmts): Likewise. + (vectorizable_conversion): Likewise. + (vectorizable_assignment): Likewise. + (vectorizable_shift): Likewise. + (vectorizable_operation): Likewise. + (vectorizable_load): Likewise. + (vectorizable_condition): Likewise. + (vectorizable_comparison): Likewise. + * tree-vect-loop.cc (vect_create_epilog_for_reduction): Adjust. + (vectorize_fold_left_reduction): Use push_vec_def. + (vect_transform_reduction): Likewise. + (vect_transform_cycle_phi): Likewise. + (vectorizable_lc_phi): Likewise. + (vectorizable_phi): Likewise. + (vectorizable_recurr): Likewise. + (vectorizable_induction): Likewise. + (vectorizable_live_operation): Likewise. + +2023-07-24 Richard Biener + + * tree-ssa-loop.cc: Remove unused tree-vectorizer.h include. + +2023-07-24 Richard Biener + + * config/i386/i386-builtins.cc: Remove tree-vectorizer.h include. + * config/i386/i386-expand.cc: Likewise. + * config/i386/i386-features.cc: Likewise. + * config/i386/i386-options.cc: Likewise. + +2023-07-24 Robin Dapp + + * tree-vect-stmts.cc (vectorizable_conversion): Handle + more demotion/promotion for modifier == NONE. + +2023-07-24 Roger Sayle + + PR target/110787 + PR target/110790 + Revert patch. + * config/i386/i386.md (extv): Use QImode for offsets. + (extzv): Likewise. + (insv): Likewise. + (*testqi_ext_3): Likewise. + (*btr_2): Likewise. + (define_split): Likewise. + (*btsq_imm): Likewise. + (*btrq_imm): Likewise. + (*btcq_imm): Likewise. + (define_peephole2 x3): Likewise. + (*bt): Likewise + (*bt_mask): New define_insn_and_split. + (*jcc_bt): Use QImode for offsets. + (*jcc_bt_1): Delete obsolete pattern. + (*jcc_bt_mask): Use QImode offsets. + (*jcc_bt_mask_1): Likewise. + (define_split): Likewise. + (*bt_setcqi): Likewise. + (*bt_setncqi): Likewise. + (*bt_setnc): Likewise. + (*bt_setncqi_2): Likewise. + (*bt_setc_mask): New define_insn_and_split. + (bmi2_bzhi_3): Use QImode offsets. + (*bmi2_bzhi_3): Likewise. + (*bmi2_bzhi_3_1): Likewise. + (*bmi2_bzhi_3_1_ccz): Likewise. + (@tbm_bextri_): Likewise. + +2023-07-24 Jose E. Marchesi + + * config/bpf/bpf-opts.h (enum bpf_kernel_version): Remove enum. + * config/bpf/bpf.opt (mkernel): Remove option. + * config/bpf/bpf.cc (bpf_target_macros): Do not define + BPF_KERNEL_VERSION_CODE. + +2023-07-24 Jose E. Marchesi + + PR target/110786 + * config/bpf/bpf.opt (mcpu): Add ISA_V4 and make it the default. + (mbswap): New option. + * config/bpf/bpf-opts.h (enum bpf_isa_version): New value ISA_V4. + * config/bpf/bpf.cc (bpf_option_override): Set bpf_has_bswap. + * config/bpf/bpf.md: Use bswap instructions if available for + bswap* insn, and fix constraint. + * doc/invoke.texi (eBPF Options): Document -mcpu=v4 and -mbswap. + +2023-07-24 Juzhe-Zhong + + * config/riscv/autovec.md (fold_left_plus_): New pattern. + (mask_len_fold_left_plus_): Ditto. + * config/riscv/riscv-protos.h (enum insn_type): New enum. + (enum reduction_type): Ditto. + (expand_reduction): Add in-order reduction. + * config/riscv/riscv-v.cc (emit_nonvlmax_fp_reduction_insn): New function. + (expand_reduction): Add in-order reduction. + +2023-07-24 Ju-Zhe Zhong + + * tree-vect-loop.cc (get_masked_reduction_fn): Add mask_len_fold_left_plus. + (vectorize_fold_left_reduction): Ditto. + (vectorizable_reduction): Ditto. + (vect_transform_reduction): Ditto. + +2023-07-24 Richard Biener + + PR tree-optimization/110777 + * tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_avail): + Avoid propagating abnormals. + +2023-07-24 Richard Biener + + PR tree-optimization/110766 + * tree-scalar-evolution.cc + (analyze_and_compute_bitwise_induction_effect): Check the PHI + is defined in the loop header. + +2023-07-24 Kewen Lin + + PR tree-optimization/110740 + * tree-vect-loop.cc (vect_analyze_loop_costing): Do not vectorize a + loop with a single scalar iteration. + +2023-07-24 Pan Li + + * config/riscv/riscv-vector-builtins-shapes.cc + (struct alu_frm_def): Take range check. + 2023-07-22 Vineet Gupta PR target/110748 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 03f4ad7..c2d3fa2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230724 +20230725 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index fba7799..4be1424 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2023-07-24 Tobias Burnus + + PR fortran/110725 + PR middle-end/71065 + * gfortran.h (gfc_omp_clauses): Add contains_teams_construct. + * openmp.cc (resolve_omp_target): New; check for teams nesting. + (gfc_resolve_omp_directive): Call it. + * parse.cc (decode_omp_directive): Set contains_teams_construct + on enclosing ST_OMP_TARGET. + 2023-07-20 Francois-Xavier Coudert * trans-intrinsic.cc (conv_intrinsic_ieee_comparison): Only diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b11b463..5d0627c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,65 @@ +2023-07-24 Tobias Burnus + + PR fortran/110725 + PR middle-end/71065 + * gfortran.dg/gomp/pr99226.f90: Update dg-error. + * gfortran.dg/gomp/teams-5.f90: New test. + +2023-07-24 Drew Ross + Jakub Jelinek + + PR middle-end/109986 + * gcc.c-torture/execute/pr109986.c: New test. + * gcc.dg/tree-ssa/pr109986.c: New test. + +2023-07-24 Jose E. Marchesi + + PR target/110783 + * gcc.target/bpf/xbpf-sdiv-1.c: Renamed to sdiv-1.c + * gcc.target/bpf/xbpf-smod-1.c: Renamed to smod-1.c + * gcc.target/bpf/sdiv-1.c: Renamed from xbpf-sdiv-1.c, use -mcpu=v4. + * gcc.target/bpf/smod-1.c: Renamed from xbpf-smod-1.c, use -mcpu=v4. + * gcc.target/bpf/diag-sdiv.c: Use -mcpu=v3. + * gcc.target/bpf/diag-smod.c: Likewise. + +2023-07-24 Robin Dapp + + * gcc.target/riscv/rvv/autovec/conversions/vec-narrow-int64-float16.c: New test. + * gcc.target/riscv/rvv/autovec/conversions/vec-widen-float16-int64.c: New test. + +2023-07-24 Jose E. Marchesi + + PR target/110786 + * gcc.target/bpf/bswap-1.c: Pass -mcpu=v3 to build test. + * gcc.target/bpf/bswap-2.c: New test. + +2023-07-24 Juzhe-Zhong + + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-1.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-2.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-3.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-4.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-5.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-6.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict-7.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-1.c: New test. + * gcc.target/riscv/rvv/autovec/reduc/reduc_strict_run-2.c: New test. + +2023-07-24 Richard Biener + + PR tree-optimization/110777 + * gcc.dg/pr110777.c: New testcase. + +2023-07-24 Richard Biener + + PR tree-optimization/110766 + * gcc.dg/torture/pr110766.c: New testcase. + +2023-07-24 Pan Li + + * gcc.target/riscv/rvv/base/float-point-frm-error.c: Update cases. + * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: Removed. + 2023-07-22 Vineet Gupta * gcc.target/riscv/pr110748-1.c: New Test. -- cgit v1.1 From c4637cbed3f23095b98962b41063380c4ab9eda9 Mon Sep 17 00:00:00 2001 From: Gaius Mulley Date: Tue, 25 Jul 2023 03:21:12 +0100 Subject: PR modula2/110174 Bugfixes to M2GenGCC.mod:CodeInline preventing an ICE This patch calls skip_const_decl before chaining parameter values and ensures that all strings passed to build_stmt (..., ASM_EXPR, ...) are nul terminated. It also improves the accuracy of locations in function calls and asm statements. gcc/m2/ PR modula2/110174 * gm2-compiler/M2GCCDeclare.def (PromoteToCString): New procedure function. * gm2-compiler/M2GCCDeclare.mod (PromoteToCString): New procedure function. * gm2-compiler/M2GenGCC.mod (BuildTreeFromInterface): Call skip_const_decl before chaining the parameter value. Use PromoteToCString to ensure the string is nul terminated. (CodeInline): Remove all parameters and replace with quad. Use GetQuadOtok to get operand token numbers. Remove call to DeclareConstant and replace it with PromoteToCString. * gm2-compiler/M2Quads.def (BuildInline): Rename into ... (BuildAsm): ... this. * gm2-compiler/M2Quads.mod: (BuildInline): Rename into ... (BuildAsm): ... this. (BuildAsmElement): Add debugging. * gm2-compiler/P1Build.bnf: Remove import of BuildInline. * gm2-compiler/P2Build.bnf: Remove import of BuildInline. * gm2-compiler/P3Build.bnf: Remove import of BuildInline and import BuildAsm. * gm2-compiler/PHBuild.bnf: Remove import of BuildInline. * gm2-libs-iso/SysClock.mod (foo): Remove. * gm2-libs/FIO.mod (BufferedRead): Rename parameter a to dest. Rename variable t to src. * m2pp.cc (pf): Correct block comment. (pe): Correct block comment. (m2pp_asm_expr): New function. (m2pp_statement): Call m2pp_asm_expr. gcc/testsuite/ PR modula2/110174 * gm2/pim/pass/program2.mod: Remove import of BuildInline. * gm2/extensions/asm/fail/extensions-asm-fail.exp: New test. * gm2/extensions/asm/fail/stressreturn.mod: New test. * gm2/extensions/asm/pass/extensions-asm-pass.exp: New test. * gm2/extensions/asm/pass/fooasm.mod: New test. Signed-off-by: Gaius Mulley --- gcc/m2/gm2-compiler/M2GCCDeclare.def | 23 ++++--- gcc/m2/gm2-compiler/M2GCCDeclare.mod | 27 ++++++++ gcc/m2/gm2-compiler/M2GenGCC.mod | 73 ++++++++++++++-------- gcc/m2/gm2-compiler/M2Quads.def | 20 +++--- gcc/m2/gm2-compiler/M2Quads.mod | 39 ++++++++---- gcc/m2/gm2-compiler/P1Build.bnf | 3 +- gcc/m2/gm2-compiler/P2Build.bnf | 1 - gcc/m2/gm2-compiler/P3Build.bnf | 38 +++++------ gcc/m2/gm2-compiler/PHBuild.bnf | 1 - gcc/m2/gm2-libs-iso/SysClock.mod | 10 --- gcc/m2/gm2-libs/FIO.mod | 48 +++++++------- gcc/m2/m2pp.cc | 39 ++++++++++-- .../extensions/asm/fail/extensions-asm-fail.exp | 37 +++++++++++ .../gm2/extensions/asm/fail/stressreturn.mod | 14 +++++ .../extensions/asm/pass/extensions-asm-pass.exp | 37 +++++++++++ gcc/testsuite/gm2/extensions/asm/pass/fooasm.mod | 13 ++++ gcc/testsuite/gm2/pim/pass/program2.mod | 3 +- 17 files changed, 302 insertions(+), 124 deletions(-) create mode 100644 gcc/testsuite/gm2/extensions/asm/fail/extensions-asm-fail.exp create mode 100644 gcc/testsuite/gm2/extensions/asm/fail/stressreturn.mod create mode 100644 gcc/testsuite/gm2/extensions/asm/pass/extensions-asm-pass.exp create mode 100644 gcc/testsuite/gm2/extensions/asm/pass/fooasm.mod (limited to 'gcc') diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.def b/gcc/m2/gm2-compiler/M2GCCDeclare.def index 38ca33f..91b66fab 100644 --- a/gcc/m2/gm2-compiler/M2GCCDeclare.def +++ b/gcc/m2/gm2-compiler/M2GCCDeclare.def @@ -32,18 +32,6 @@ DEFINITION MODULE M2GCCDeclare ; FROM SYSTEM IMPORT WORD ; FROM m2tree IMPORT Tree ; -EXPORT QUALIFIED FoldConstants, - DeclareConstant, TryDeclareConstant, - DeclareConstructor, TryDeclareConstructor, - DeclareLocalVariables, PromoteToString, DeclareLocalVariable, - InitDeclarations, StartDeclareScope, EndDeclareScope, - DeclareModuleVariables, IsProcedureGccNested, - DeclareProcedure, PoisonSymbols, DeclareParameters, - CompletelyResolved, MarkExported, PrintSym, - ConstantKnownAndUsed, - PutToBeSolvedByQuads, - GetTypeMin, GetTypeMax, - WalkAction, IsAction ; TYPE WalkAction = PROCEDURE (WORD) ; @@ -174,6 +162,17 @@ PROCEDURE PromoteToString (tokenno: CARDINAL; sym: CARDINAL) : Tree ; (* + PromoteToCString - declare, sym, and then promote it to a string. + Note that if sym is a single character we do + *not* record it as a string + but as a char however we always + return a string constant. +*) + +PROCEDURE PromoteToCString (tokenno: CARDINAL; sym: CARDINAL) : Tree ; + + +(* CompletelyResolved - returns TRUE if a symbol has been completely resolved and is not partially declared (such as a record, array or procedure type). diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod index 92de4b4..37235f0 100644 --- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod +++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod @@ -1584,6 +1584,33 @@ END PromoteToString ; (* + PromoteToCString - declare, sym, and then promote it to a string. + Note that if sym is a single character we do + *not* record it as a string + but as a char however we always + return a string constant. +*) + +PROCEDURE PromoteToCString (tokenno: CARDINAL; sym: CARDINAL) : Tree ; +VAR + size: CARDINAL ; + ch : CHAR ; +BEGIN + DeclareConstant (tokenno, sym) ; + IF IsConst (sym) AND (GetSType (sym) = Char) + THEN + PushValue (sym) ; + ch := PopChar (tokenno) ; + RETURN BuildCStringConstant (string (InitStringChar (ch)), 1) + ELSE + size := GetStringLength (sym) ; + RETURN BuildCStringConstant (KeyToCharStar (GetString (sym)), + size) + END +END PromoteToCString ; + + +(* WalkConstructor - walks all dependants of, sym. *) diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod index d701543..bcef4e7 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.mod +++ b/gcc/m2/gm2-compiler/M2GenGCC.mod @@ -150,7 +150,7 @@ FROM M2GCCDeclare IMPORT WalkAction, DeclareConstant, TryDeclareConstant, DeclareConstructor, TryDeclareConstructor, StartDeclareScope, EndDeclareScope, - PromoteToString, DeclareLocalVariable, + PromoteToString, PromoteToCString, DeclareLocalVariable, CompletelyResolved, PoisonSymbols, GetTypeMin, GetTypeMax, IsProcedureGccNested, DeclareParameters, @@ -208,10 +208,11 @@ FROM m2expr IMPORT GetIntegerZero, GetIntegerOne, BuildAddAddress, BuildIfInRangeGoto, BuildIfNotInRangeGoto ; -FROM m2tree IMPORT Tree, debug_tree ; +FROM m2tree IMPORT Tree, debug_tree, skip_const_decl ; FROM m2linemap IMPORT location_t ; -FROM m2decl IMPORT BuildStringConstant, DeclareKnownConstant, GetBitsPerBitset, +FROM m2decl IMPORT BuildStringConstant, BuildCStringConstant, + DeclareKnownConstant, GetBitsPerBitset, BuildIntegerConstant, BuildModuleCtor, DeclareModuleCtor ; @@ -530,7 +531,7 @@ BEGIN SavePriorityOp : CodeSavePriority (op1, op2, op3) | RestorePriorityOp : CodeRestorePriority (op1, op2, op3) | - InlineOp : CodeInline (location, CurrentQuadToken, op3) | + InlineOp : CodeInline (q) | StatementNoteOp : CodeStatementNote (op3) | CodeOnOp : | (* the following make no sense with gcc *) CodeOffOp : | @@ -702,6 +703,8 @@ END FindType ; *) PROCEDURE BuildTreeFromInterface (sym: CARDINAL) : Tree ; +CONST + DebugTokPos = FALSE ; VAR tok : CARDINAL ; i : CARDINAL ; @@ -717,7 +720,7 @@ BEGIN i := 1 ; REPEAT GetRegInterface (sym, i, tok, name, str, obj) ; - IF str#NulSym + IF str # NulSym THEN IF IsConstString (str) THEN @@ -726,11 +729,18 @@ BEGIN THEN gccName := NIL ELSE - gccName := BuildStringConstant (KeyToCharStar (name), LengthKey (name)) + gccName := BuildCStringConstant (KeyToCharStar (name), LengthKey (name)) END ; - tree := ChainOnParamValue (tree, gccName, PromoteToString (tok, str), Mod2Gcc (obj)) + tree := ChainOnParamValue (tree, gccName, PromoteToCString (tok, str), + skip_const_decl (Mod2Gcc (obj))) ; + IF DebugTokPos + THEN + WarnStringAt (InitString ('input expression'), tok) + END ELSE - WriteFormat0 ('a constraint to the GNU ASM statement must be a constant string') + MetaErrorT1 (tok, + 'a constraint to the GNU ASM statement must be a constant string and not a {%1Ed}', + str) END END ; INC(i) @@ -745,6 +755,8 @@ END BuildTreeFromInterface ; *) PROCEDURE BuildTrashTreeFromInterface (sym: CARDINAL) : Tree ; +CONST + DebugTokPos = FALSE ; VAR tok : CARDINAL ; i : CARDINAL ; @@ -763,9 +775,15 @@ BEGIN THEN IF IsConstString (str) THEN - tree := AddStringToTreeList (tree, PromoteToString (tok, str)) + tree := AddStringToTreeList (tree, PromoteToCString (tok, str)) ; + IF DebugTokPos + THEN + WarnStringAt (InitString ('trash expression'), tok) + END ELSE - WriteFormat0 ('a constraint to the GNU ASM statement must be a constant string') + MetaErrorT1 (tok, + 'a constraint to the GNU ASM statement must be a constant string and not a {%1Ed}', + str) END END ; (* @@ -785,33 +803,34 @@ END BuildTrashTreeFromInterface ; CodeInline - InlineOp is a quadruple which has the following format: InlineOp NulSym NulSym Sym - - The inline asm statement, Sym, is written to standard output. *) -PROCEDURE CodeInline (location: location_t; tokenno: CARDINAL; GnuAsm: CARDINAL) ; +PROCEDURE CodeInline (quad: CARDINAL) ; VAR - string : CARDINAL ; + overflowChecking: BOOLEAN ; + op : QuadOperator ; + op1, op2, GnuAsm: CARDINAL ; + op1pos, op2pos, + op3pos, asmpos : CARDINAL ; + string : CARDINAL ; inputs, outputs, trash, - labels : Tree ; + labels : Tree ; + location : location_t ; BEGIN - (* - no need to explicity flush the outstanding instructions as - per M2GenDyn486 and M2GenAPU. The GNU ASM statements in GCC - can handle the register dependency providing the user - specifies VOLATILE and input/output/trash sets correctly. - *) - inputs := BuildTreeFromInterface (GetGnuAsmInput(GnuAsm)) ; - outputs := BuildTreeFromInterface (GetGnuAsmOutput(GnuAsm)) ; - trash := BuildTrashTreeFromInterface (GetGnuAsmTrash(GnuAsm)) ; - labels := NIL ; (* at present it makes no sence for Modula-2 to jump to a label, + GetQuadOtok (quad, asmpos, op, op1, op2, GnuAsm, overflowChecking, + op1pos, op2pos, op3pos) ; + location := TokenToLocation (asmpos) ; + inputs := BuildTreeFromInterface (GetGnuAsmInput (GnuAsm)) ; + outputs := BuildTreeFromInterface (GetGnuAsmOutput (GnuAsm)) ; + trash := BuildTrashTreeFromInterface (GetGnuAsmTrash (GnuAsm)) ; + labels := NIL ; (* At present it makes no sence for Modula-2 to jump to a label, given that labels are not allowed in Modula-2. *) string := GetGnuAsm (GnuAsm) ; - DeclareConstant (tokenno, string) ; BuildAsm (location, - Mod2Gcc (string), IsGnuAsmVolatile (GnuAsm), IsGnuAsmSimple (GnuAsm), + PromoteToCString (GetDeclaredMod (string), string), + IsGnuAsmVolatile (GnuAsm), IsGnuAsmSimple (GnuAsm), inputs, outputs, trash, labels) END CodeInline ; diff --git a/gcc/m2/gm2-compiler/M2Quads.def b/gcc/m2/gm2-compiler/M2Quads.def index 3a40595..3fc9dfb 100644 --- a/gcc/m2/gm2-compiler/M2Quads.def +++ b/gcc/m2/gm2-compiler/M2Quads.def @@ -88,7 +88,7 @@ EXPORT QUALIFIED StartBuildDefFile, StartBuildModFile, EndBuildFile, BuildCodeOn, BuildCodeOff, BuildProfileOn, BuildProfileOff, BuildOptimizeOn, BuildOptimizeOff, - BuildInline, BuildStmtNote, BuildLineNo, PushLineNo, + BuildAsm, BuildStmtNote, BuildLineNo, PushLineNo, BuildConstructor, BuildConstructorStart, BuildConstructorEnd, @@ -2518,23 +2518,23 @@ PROCEDURE BuildOptimizeOff ; (* - BuildInline - builds an Inline pseudo quadruple operator. - The inline interface, Sym, is stored as the operand - to the operator InlineOp. + BuildAsm - builds an Inline pseudo quadruple operator. + The inline interface, Sym, is stored as the operand + to the operator InlineOp. - The stack is expected to contain: + The stack is expected to contain: Entry Exit ===== ==== - Ptr -> - +--------------+ - | Sym | Empty - |--------------| + Ptr -> + +--------------+ + | Sym | Empty + |--------------| *) -PROCEDURE BuildInline ; +PROCEDURE BuildAsm (tok: CARDINAL) ; (* diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod index 51c2835..44648de 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -14121,29 +14121,29 @@ END BuildOptimizeOff ; (* - BuildInline - builds an Inline pseudo quadruple operator. - The inline interface, Sym, is stored as the operand - to the operator InlineOp. + BuildAsm - builds an Inline pseudo quadruple operator. + The inline interface, Sym, is stored as the operand + to the operator InlineOp. - The stack is expected to contain: + The stack is expected to contain: Entry Exit ===== ==== - Ptr -> - +--------------+ - | Sym | Empty - |--------------| + Ptr -> + +--------------+ + | Sym | Empty + |--------------| *) -PROCEDURE BuildInline ; +PROCEDURE BuildAsm (tok: CARDINAL) ; VAR Sym: CARDINAL ; BEGIN PopT (Sym) ; - GenQuad (InlineOp, NulSym, NulSym, Sym) -END BuildInline ; + GenQuadO (tok, InlineOp, NulSym, NulSym, Sym, FALSE) +END BuildAsm ; (* @@ -14541,7 +14541,10 @@ END AddVarientEquality ; *) PROCEDURE BuildAsmElement (input, output: BOOLEAN) ; +CONST + DebugAsmTokPos = FALSE ; VAR + s : String ; n, str, expr, tokpos, CurrentInterface, CurrentAsm, name : CARDINAL ; @@ -14561,12 +14564,22 @@ BEGIN IF input THEN PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, - NextQuad, 0) + NextQuad, 0) ; + IF DebugAsmTokPos + THEN + s := InitString ('input expression') ; + WarnStringAt (s, tokpos) + END END ; IF output THEN PutRegInterface (tokpos, CurrentInterface, n, name, str, expr, - 0, NextQuad) + 0, NextQuad) ; + IF DebugAsmTokPos + THEN + s := InitString ('output expression') ; + WarnStringAt (s, tokpos) + END END ; PushT (n) ; PushT (CurrentAsm) ; diff --git a/gcc/m2/gm2-compiler/P1Build.bnf b/gcc/m2/gm2-compiler/P1Build.bnf index 5be6af4..a477275 100644 --- a/gcc/m2/gm2-compiler/P1Build.bnf +++ b/gcc/m2/gm2-compiler/P1Build.bnf @@ -64,8 +64,7 @@ FROM M2Quads IMPORT PushT, PopT, EndBuildInit, BuildProcedureStart, BuildProcedureEnd, - BuildAssignment, - BuildInline ; + BuildAssignment ; FROM P1SymBuild IMPORT P1StartBuildProgramModule, P1EndBuildProgramModule, diff --git a/gcc/m2/gm2-compiler/P2Build.bnf b/gcc/m2/gm2-compiler/P2Build.bnf index 0a82e6b..b5cdbfe 100644 --- a/gcc/m2/gm2-compiler/P2Build.bnf +++ b/gcc/m2/gm2-compiler/P2Build.bnf @@ -60,7 +60,6 @@ FROM M2Quads IMPORT PushT, PopT, PushTF, PopTF, PopNothing, OperandT, PushTFA, T BuildProcedureStart, BuildProcedureEnd, BuildAssignment, - BuildInline, AddRecordToList, AddVarientToList, IsAutoPushOn, PushAutoOff, PushAutoOn, PopAuto, DisplayStack ; diff --git a/gcc/m2/gm2-compiler/P3Build.bnf b/gcc/m2/gm2-compiler/P3Build.bnf index e50620e..bcff7579 100644 --- a/gcc/m2/gm2-compiler/P3Build.bnf +++ b/gcc/m2/gm2-compiler/P3Build.bnf @@ -98,7 +98,7 @@ FROM M2Quads IMPORT PushT, PopT, PushTF, PopTF, PopNothing, Annotate, BuildProcedureCall, BuildReturn, BuildNulExpression, CheckBuildFunction, StartBuildWith, EndBuildWith, - BuildInline, + BuildAsm, BuildCaseStart, BuildCaseOr, BuildCaseElse, @@ -1461,17 +1461,19 @@ Definition := "CONST" { ConstantDeclaration ";" } | "VAR" { VariableDeclaration ";" } | DefProcedureHeading ";" =: -AsmStatement := % VAR CurrentAsm: CARDINAL ; % +AsmStatement := % VAR CurrentAsm: CARDINAL ; + tok: CARDINAL ; % + % tok := GetTokenNo () % 'ASM' % PushAutoOn ; - PushT(0) ; (* operand count *) - PushT(MakeGnuAsm()) + PushT (0) ; (* operand count *) + PushT (MakeGnuAsm ()) % - [ 'VOLATILE' % PopT(CurrentAsm) ; - PutGnuAsmVolatile(CurrentAsm) ; - PushT(CurrentAsm) + [ 'VOLATILE' % PopT (CurrentAsm) ; + PutGnuAsmVolatile (CurrentAsm) ; + PushT (CurrentAsm) % ] '(' AsmOperands % PopNothing ; (* throw away interface sym *) - BuildInline ; + BuildAsm (tok) ; PopNothing ; (* throw away count *) PopAuto % @@ -1480,22 +1482,22 @@ AsmStatement := % VAR AsmOperands := % VAR CurrentAsm, count: CARDINAL ; str: CARDINAL ; % - ConstExpression % PopT(str) ; - PopT(CurrentAsm) ; - Assert(IsGnuAsm(CurrentAsm) OR IsGnuAsmVolatile(CurrentAsm)) ; - PopT(count) ; + ConstExpression % PopT (str) ; + PopT (CurrentAsm) ; + Assert (IsGnuAsm (CurrentAsm) OR IsGnuAsmVolatile (CurrentAsm)) ; + PopT (count) ; IF DebugAsm THEN - printf1('1: count of asm operands: %d\n', count) + printf1 ('1: count of asm operands: %d\n', count) END ; - PushT(count) ; + PushT (count) ; (* adds the name/instruction for this asm *) - PutGnuAsm(CurrentAsm, str) ; - PushT(CurrentAsm) ; - PushT(NulSym) (* the InterfaceSym *) + PutGnuAsm (CurrentAsm, str) ; + PushT (CurrentAsm) ; + PushT (NulSym) (* the InterfaceSym *) % ( AsmOperandSpec | % (* epsilon *) - PutGnuAsmSimple(CurrentAsm) + PutGnuAsmSimple (CurrentAsm) % ) =: diff --git a/gcc/m2/gm2-compiler/PHBuild.bnf b/gcc/m2/gm2-compiler/PHBuild.bnf index c829a6e..c1ab70d 100644 --- a/gcc/m2/gm2-compiler/PHBuild.bnf +++ b/gcc/m2/gm2-compiler/PHBuild.bnf @@ -79,7 +79,6 @@ FROM M2Quads IMPORT PushT, PopT, PushTF, PopTF, PopNothing, Annotate, BuildElsif1, BuildElsif2, BuildProcedureCall, BuildReturn, BuildNulExpression, StartBuildWith, EndBuildWith, - BuildInline, BuildCaseStart, BuildCaseOr, BuildCaseElse, diff --git a/gcc/m2/gm2-libs-iso/SysClock.mod b/gcc/m2/gm2-libs-iso/SysClock.mod index c5fd2eb..e894489 100644 --- a/gcc/m2/gm2-libs-iso/SysClock.mod +++ b/gcc/m2/gm2-libs-iso/SysClock.mod @@ -114,16 +114,6 @@ BEGIN END IsValidDateTime ; -(* - foo - -*) - -PROCEDURE foo () : CARDINAL ; -BEGIN - RETURN 1 -END foo ; - - PROCEDURE GetClock (VAR userData: DateTime) ; (* Assigns local date and time of the day to userData *) VAR diff --git a/gcc/m2/gm2-libs/FIO.mod b/gcc/m2/gm2-libs/FIO.mod index dd6f48c..b46d505 100644 --- a/gcc/m2/gm2-libs/FIO.mod +++ b/gcc/m2/gm2-libs/FIO.mod @@ -664,9 +664,9 @@ END ReadNBytes ; Useful when performing small reads. *) -PROCEDURE BufferedRead (f: File; nBytes: CARDINAL; a: ADDRESS) : INTEGER ; +PROCEDURE BufferedRead (f: File; nBytes: CARDINAL; dest: ADDRESS) : INTEGER ; VAR - t : ADDRESS ; + src : ADDRESS ; total, n : INTEGER ; p : POINTER TO BYTE ; @@ -674,52 +674,52 @@ VAR BEGIN IF f#Error THEN - fd := GetIndice(FileInfo, f) ; + fd := GetIndice (FileInfo, f) ; total := 0 ; (* how many bytes have we read *) IF fd#NIL THEN WITH fd^ DO (* extract from the buffer first *) - IF buffer#NIL + IF buffer # NIL THEN WITH buffer^ DO - WHILE nBytes>0 DO - IF (left>0) AND valid + WHILE nBytes > 0 DO + IF (left > 0) AND valid THEN - IF nBytes=1 + IF nBytes = 1 THEN (* too expensive to call memcpy for 1 character *) - p := a ; + p := dest ; p^ := contents^[position] ; - DEC(left) ; (* remove consumed byte *) - INC(position) ; (* move onwards n byte *) - INC(total) ; + DEC (left) ; (* remove consumed byte *) + INC (position) ; (* move onwards n byte *) + INC (total) ; RETURN( total ) ELSE - n := Min(left, nBytes) ; - t := address ; - INC(t, position) ; - p := memcpy(a, t, n) ; - DEC(left, n) ; (* remove consumed bytes *) - INC(position, n) ; (* move onwards n bytes *) + n := Min (left, nBytes) ; + src := address ; + INC (src, position) ; + p := memcpy (dest, src, n) ; + DEC (left, n) ; (* remove consumed bytes *) + INC (position, n) ; (* move onwards n bytes *) (* move onwards ready for direct reads *) - INC(a, n) ; - DEC(nBytes, n) ; (* reduce the amount for future direct *) + INC (dest, n) ; + DEC (nBytes, n) ; (* reduce the amount for future direct *) (* read *) - INC(total, n) + INC (total, n) END ELSE (* refill buffer *) - n := read(unixfd, address, size) ; - IF n>=0 + n := read (unixfd, address, size) ; + IF n >= 0 THEN valid := TRUE ; position := 0 ; left := n ; filled := n ; bufstart := abspos ; - INC(abspos, n) ; - IF n=0 + INC (abspos, n) ; + IF n = 0 THEN (* eof reached *) state := endoffile ; diff --git a/gcc/m2/m2pp.cc b/gcc/m2/m2pp.cc index 52a2938..d502c93 100644 --- a/gcc/m2/m2pp.cc +++ b/gcc/m2/m2pp.cc @@ -183,7 +183,7 @@ do_pf (tree t, int bits) } /* pf print function. Expected to be printed interactively from - the debugger: print pf(func), or to be called from code. */ + the debugger: print modula2::pf(func), or to be called from code. */ void pf (tree t) @@ -192,7 +192,7 @@ pf (tree t) } /* pe print expression. Expected to be printed interactively from - the debugger: print pe(expr), or to be called from code. */ + the debugger: print modula2::pe(expr), or to be called from code. */ void pe (tree t) @@ -206,8 +206,8 @@ pe (tree t) } /* pet print expression and its type. Expected to be printed - interactively from the debugger: print pet(expr), or to be called - from code. */ + interactively from the debugger: print modula2::pet(expr), or to + be called from code. */ void pet (tree t) @@ -2209,6 +2209,34 @@ m2pp_if_stmt (pretty *s, tree t) } #endif +static void +m2pp_asm_expr (pretty *state, tree node) +{ + m2pp_begin (state); + m2pp_print (state, "ASM"); + m2pp_needspace (state); + if (ASM_VOLATILE_P (node)) + { + m2pp_print (state, "VOLATILE"); + m2pp_needspace (state); + } + m2pp_print (state, "("); + m2pp_expression (state, ASM_STRING (node)); + m2pp_print (state, ":"); + m2pp_needspace (state); + m2pp_expression (state, ASM_OUTPUTS (node)); + m2pp_print (state, ":"); + m2pp_needspace (state); + m2pp_expression (state, ASM_INPUTS (node)); + if (ASM_CLOBBERS (node) != NULL) + { + m2pp_print (state, ":"); + m2pp_needspace (state); + m2pp_expression (state, ASM_CLOBBERS (node)); + } + m2pp_print (state, ");\n"); +} + /* m2pp_statement attempts to reconstruct a statement. */ static void @@ -2271,6 +2299,9 @@ m2pp_statement (pretty *s, tree t) case CATCH_EXPR: m2pp_catch_expr (s, t); break; + case ASM_EXPR: + m2pp_asm_expr (s, t); + break; #if defined(CPP) case IF_STMT: m2pp_if_stmt (s, t); diff --git a/gcc/testsuite/gm2/extensions/asm/fail/extensions-asm-fail.exp b/gcc/testsuite/gm2/extensions/asm/fail/extensions-asm-fail.exp new file mode 100644 index 0000000..6447c77 --- /dev/null +++ b/gcc/testsuite/gm2/extensions/asm/fail/extensions-asm-fail.exp @@ -0,0 +1,37 @@ +# Expect driver script for GCC Regression Tests +# Copyright (C) 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file was written by Gaius Mulley (gaius.mulley@southwales.ac.uk) +# for GNU Modula-2. + +if $tracelevel then { + strace $tracelevel +} + +# load support procs +load_lib gm2-torture.exp + +gm2_init_pim "${srcdir}/gm2/extensions/asm/fail" + +foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $testcase] then { + continue + } + + gm2-torture-fail $testcase +} diff --git a/gcc/testsuite/gm2/extensions/asm/fail/stressreturn.mod b/gcc/testsuite/gm2/extensions/asm/fail/stressreturn.mod new file mode 100644 index 0000000..79e2a6f --- /dev/null +++ b/gcc/testsuite/gm2/extensions/asm/fail/stressreturn.mod @@ -0,0 +1,14 @@ +MODULE stressreturn ; +FROM Builtins IMPORT return_address; +FROM SYSTEM IMPORT ADDRESS; + +VAR x: ADDRESS; + +PROCEDURE test; +BEGIN + ASM VOLATILE("" : "=m"(x) : "m"(return_address(0)) : ); +END test; + +BEGIN + test +END stressreturn. diff --git a/gcc/testsuite/gm2/extensions/asm/pass/extensions-asm-pass.exp b/gcc/testsuite/gm2/extensions/asm/pass/extensions-asm-pass.exp new file mode 100644 index 0000000..03bfbd0 --- /dev/null +++ b/gcc/testsuite/gm2/extensions/asm/pass/extensions-asm-pass.exp @@ -0,0 +1,37 @@ +# Expect driver script for GCC Regression Tests +# Copyright (C) 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# This file was written by Gaius Mulley (gaiusmod2@gmail.com) +# for GNU Modula-2. + +if $tracelevel then { + strace $tracelevel +} + +# load support procs +load_lib gm2-torture.exp + +gm2_init_pim "${srcdir}/gm2/extensions/asm/pass" + +foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $testcase] then { + continue + } + + gm2-torture $testcase +} diff --git a/gcc/testsuite/gm2/extensions/asm/pass/fooasm.mod b/gcc/testsuite/gm2/extensions/asm/pass/fooasm.mod new file mode 100644 index 0000000..da11114 --- /dev/null +++ b/gcc/testsuite/gm2/extensions/asm/pass/fooasm.mod @@ -0,0 +1,13 @@ +MODULE fooasm ; + +VAR + x: INTEGER ; + +PROCEDURE test ; +BEGIN + ASM("" : : "m"(x)) +END test ; + +BEGIN + test +END fooasm. diff --git a/gcc/testsuite/gm2/pim/pass/program2.mod b/gcc/testsuite/gm2/pim/pass/program2.mod index 6334589..4efe2d4 100644 --- a/gcc/testsuite/gm2/pim/pass/program2.mod +++ b/gcc/testsuite/gm2/pim/pass/program2.mod @@ -37,8 +37,7 @@ FROM M2Quads IMPORT PushT, PopT, EndBuildInit, BuildProcedureStart, BuildProcedureEnd, - BuildAssignment, - BuildInline ; + BuildAssignment ; FROM P1SymBuild IMPORT P1StartBuildProgramModule, P1EndBuildProgramModule, -- cgit v1.1 From 54ce3cbd285d453b954c281bb3ad38bee2f65330 Mon Sep 17 00:00:00 2001 From: Haochen Gui Date: Tue, 25 Jul 2023 10:40:37 +0800 Subject: rs6000: Implemented f[min/max]_optab by xs[min/max]dp gcc/ PR target/103605 * config/rs6000/rs6000-builtin.cc (rs6000_gimple_fold_builtin): Gimple fold RS6000_BIF_XSMINDP and RS6000_BIF_XSMAXDP when fast-math is set. * config/rs6000/rs6000.md (FMINMAX): New int iterator. (minmax_op): New int attribute. (UNSPEC_FMAX, UNSPEC_FMIN): New unspecs. (f3): New pattern by UNSPEC_FMAX and UNSPEC_FMIN. * config/rs6000/rs6000-builtins.def (__builtin_vsx_xsmaxdp): Set pattern to fmaxdf3. (__builtin_vsx_xsmindp): Set pattern to fmindf3. gcc/testsuite/ PR target/103605 * gcc.target/powerpc/pr103605.h: New. * gcc.target/powerpc/pr103605-1.c: New. * gcc.target/powerpc/pr103605-2.c: New. --- gcc/config/rs6000/rs6000-builtin.cc | 4 ++++ gcc/config/rs6000/rs6000-builtins.def | 4 ++-- gcc/config/rs6000/rs6000.md | 18 ++++++++++++++++ gcc/testsuite/gcc.target/powerpc/pr103605-1.c | 9 ++++++++ gcc/testsuite/gcc.target/powerpc/pr103605-2.c | 11 ++++++++++ gcc/testsuite/gcc.target/powerpc/pr103605.h | 31 +++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr103605-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr103605-2.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr103605.h (limited to 'gcc') diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index a8f291c..82cc3a1 100644 --- a/gcc/config/rs6000/rs6000-builtin.cc +++ b/gcc/config/rs6000/rs6000-builtin.cc @@ -1574,6 +1574,8 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) gimple_set_location (g, gimple_location (stmt)); gsi_replace (gsi, g, true); return true; + /* fold into MIN_EXPR when fast-math is set. */ + case RS6000_BIF_XSMINDP: /* flavors of vec_min. */ case RS6000_BIF_XVMINDP: case RS6000_BIF_XVMINSP: @@ -1600,6 +1602,8 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) gimple_set_location (g, gimple_location (stmt)); gsi_replace (gsi, g, true); return true; + /* fold into MAX_EXPR when fast-math is set. */ + case RS6000_BIF_XSMAXDP: /* flavors of vec_max. */ case RS6000_BIF_XVMAXDP: case RS6000_BIF_XVMAXSP: diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def index c0ef717..b71cce5 100644 --- a/gcc/config/rs6000/rs6000-builtins.def +++ b/gcc/config/rs6000/rs6000-builtins.def @@ -1614,10 +1614,10 @@ XSCVSPDP vsx_xscvspdp {} const double __builtin_vsx_xsmaxdp (double, double); - XSMAXDP smaxdf3 {} + XSMAXDP fmaxdf3 {} const double __builtin_vsx_xsmindp (double, double); - XSMINDP smindf3 {} + XSMINDP fmindf3 {} const double __builtin_vsx_xsrdpi (double); XSRDPI vsx_xsrdpi {} diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 783f9ff..1a9a7b1 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -158,6 +158,8 @@ UNSPEC_HASHCHK UNSPEC_XXSPLTIDP_CONST UNSPEC_XXSPLTIW_CONST + UNSPEC_FMAX + UNSPEC_FMIN ]) ;; @@ -5423,6 +5425,22 @@ DONE; }) + +(define_int_iterator FMINMAX [UNSPEC_FMAX UNSPEC_FMIN]) + +(define_int_attr minmax_op [(UNSPEC_FMAX "max") + (UNSPEC_FMIN "min")]) + +(define_insn "f3" + [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa") + (unspec:SFDF [(match_operand:SFDF 1 "vsx_register_operand" "wa") + (match_operand:SFDF 2 "vsx_register_operand" "wa")] + FMINMAX))] + "TARGET_VSX && !flag_finite_math_only" + "xsdp %x0,%x1,%x2" + [(set_attr "type" "fp")] +) + (define_expand "movcc" [(set (match_operand:GPR 0 "gpc_reg_operand") (if_then_else:GPR (match_operand 1 "comparison_operator") diff --git a/gcc/testsuite/gcc.target/powerpc/pr103605-1.c b/gcc/testsuite/gcc.target/powerpc/pr103605-1.c new file mode 100644 index 0000000..3f253a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr103605-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ +/* { dg-final { scan-assembler-times {\mxsmaxdp\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mxsmindp\M} 3 } } */ + +/* Verify that GCC generates expected min/max hw insns instead of fmin/fmax + calls. */ +#include "pr103605.h" diff --git a/gcc/testsuite/gcc.target/powerpc/pr103605-2.c b/gcc/testsuite/gcc.target/powerpc/pr103605-2.c new file mode 100644 index 0000000..9e531e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr103605-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx -ffast-math" } */ +/* { dg-final { scan-assembler-times {\mxsmaxcdp\M} 3 { target has_arch_pwr9 } } } */ +/* { dg-final { scan-assembler-times {\mxsmincdp\M} 3 { target has_arch_pwr9 } } } */ +/* { dg-final { scan-assembler-times {\mxsmaxdp\M} 3 { target { ! has_arch_pwr9 } } } } */ +/* { dg-final { scan-assembler-times {\mxsmindp\M} 3 { target { ! has_arch_pwr9 } } } } */ + +/* Verify that GCC generates expected min/max hw insns instead of fmin/fmax + calls. */ +#include "pr103605.h" diff --git a/gcc/testsuite/gcc.target/powerpc/pr103605.h b/gcc/testsuite/gcc.target/powerpc/pr103605.h new file mode 100644 index 0000000..c99dfe6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr103605.h @@ -0,0 +1,31 @@ +#include + +double test1 (double d0, double d1) +{ + return fmin (d0, d1); +} + +float test2 (float d0, float d1) +{ + return fmin (d0, d1); +} + +double test3 (double d0, double d1) +{ + return fmax (d0, d1); +} + +float test4 (float d0, float d1) +{ + return fmax (d0, d1); +} + +double test5 (double d0, double d1) +{ + return __builtin_vsx_xsmindp (d0, d1); +} + +double test6 (double d0, double d1) +{ + return __builtin_vsx_xsmaxdp (d0, d1); +} -- cgit v1.1 From 50656980497d77ac12a5e7179013a6af09ba32f7 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 25 Jul 2023 09:28:43 +0200 Subject: gfortran.dg/gomp/pr99226.f90: Add missing dg-error Follow up to r14-2754-g2e31fe431b08b0302e1fa8a1c18ee51adafd41df which added a check that a target region with teams does not have anything anything else strictly nested in the target. When changing the dg-error for this PR, somehow the addition of a dg-error in a second line was lost (the message uses (1) and (2) as location, showing two lines, both need a dg-error with the same message). gcc/testsuite/ChangeLog: * gfortran.dg/gomp/pr99226.f90: Update dg-error. --- gcc/testsuite/gfortran.dg/gomp/pr99226.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 index 2aea0c1..d1b3507 100644 --- a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 @@ -3,7 +3,7 @@ subroutine sub (n) integer :: n, i !$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } - !$omp teams distribute dist_schedule (static,n+4) + !$omp teams distribute dist_schedule (static,n+4) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } do i = 1, 8 end do !$omp teams distribute dist_schedule (static,n+4) -- cgit v1.1 From d8dc61bb5ab99c3239ea93a37097f9419bee0211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= Date: Tue, 25 Jul 2023 14:11:54 +0200 Subject: Adjust one Ada test Recent change modified how the loops are created, with the first iteration being extracted out of the loops in the 2 test cases. Adjust the text to match from the unroll dump. gcc/testsuite/ChangeLog: * gnat.dg/unroll3.adb: Adjust. --- gcc/testsuite/gnat.dg/unroll3.adb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/gnat.dg/unroll3.adb b/gcc/testsuite/gnat.dg/unroll3.adb index 3bd06e7..86193d6 100644 --- a/gcc/testsuite/gnat.dg/unroll3.adb +++ b/gcc/testsuite/gnat.dg/unroll3.adb @@ -23,4 +23,4 @@ package body Unroll3 is end Unroll3; --- { dg-final { scan-tree-dump-times "loop with 3 iterations completely unrolled" 2 "cunroll" } } +-- { dg-final { scan-tree-dump-times "loop with 2 iterations completely unrolled" 2 "cunroll" } } -- cgit v1.1 From 09dda270380fe13e7b4722305cb1122df1f779a0 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 25 Jul 2023 15:43:58 +0200 Subject: OpenMP/Fortran: Reject declarations between target + teams While commit r14-2754-g2e31fe431b08b0302e1fa8a1c18ee51adafd41df detected executable statements, declarations do not show up as executable statements. Hence, we now check whether the first statement after TARGET is TEAMS - such that we can detect data statements like type or variable declarations. Fortran semantics ensures that only executable directives/statemens can come after '!$omp end teams' such that those can be detected with the previous check. Note that statements returning ST_NONE such as 'omp nothing' or 'omp error at(compilation)' will still slip through. PR fortran/110725 PR middle-end/71065 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_clauses): Add target_first_st_is_teams. * parse.cc (parse_omp_structured_block): Set it if the first statement in the structured block of a TARGET is TEAMS or a combined/composite starting with TEAMS. * openmp.cc (resolve_omp_target): Also show an error for contains_teams_construct without target_first_st_is_teams. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/teams-6.f90: New test. --- gcc/fortran/gfortran.h | 2 +- gcc/fortran/openmp.cc | 13 ++--- gcc/fortran/parse.cc | 25 ++++++++-- gcc/testsuite/gfortran.dg/gomp/teams-6.f90 | 78 ++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/gomp/teams-6.f90 (limited to 'gcc') diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 577ef80..9a00e6d 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1575,7 +1575,7 @@ typedef struct gfc_omp_clauses unsigned order_unconstrained:1, order_reproducible:1, capture:1; unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1; unsigned non_rectangular:1, order_concurrent:1; - unsigned contains_teams_construct:1; + unsigned contains_teams_construct:1, target_first_st_is_teams:1; ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3; ENUM_BITFIELD (gfc_omp_device_type) device_type:2; ENUM_BITFIELD (gfc_omp_memorder) memorder:3; diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 675011a..52eeaf2 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -10666,12 +10666,13 @@ resolve_omp_target (gfc_code *code) if (!code->ext.omp_clauses->contains_teams_construct) return; - if ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op) - && code->block->next->next == NULL) - || (code->block->next->op == EXEC_BLOCK - && code->block->next->next - && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op) - && code->block->next->next->next == NULL)) + if (code->ext.omp_clauses->target_first_st_is_teams + && ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op) + && code->block->next->next == NULL) + || (code->block->next->op == EXEC_BLOCK + && code->block->next->next + && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op) + && code->block->next->next->next == NULL))) return; gfc_code *c = code->block->next; while (c && !GFC_IS_TEAMS_CONSTRUCT (c->op)) diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index 011a39c..aa6bb66 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -5766,7 +5766,7 @@ parse_openmp_allocate_block (gfc_statement omp_st) static gfc_statement parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) { - gfc_statement st, omp_end_st; + gfc_statement st, omp_end_st, first_st; gfc_code *cp, *np; gfc_state_data s; @@ -5857,7 +5857,7 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) gfc_namespace *my_ns = NULL; gfc_namespace *my_parent = NULL; - st = next_statement (); + first_st = st = next_statement (); if (st == ST_BLOCK) { @@ -5876,9 +5876,28 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) new_st.ext.block.ns = my_ns; new_st.ext.block.assoc = NULL; accept_statement (ST_BLOCK); - st = parse_spec (ST_NONE); + first_st = next_statement (); + st = parse_spec (first_st); } + if (omp_end_st == ST_OMP_END_TARGET) + switch (first_st) + { + case ST_OMP_TEAMS: + case ST_OMP_TEAMS_DISTRIBUTE: + case ST_OMP_TEAMS_DISTRIBUTE_SIMD: + case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO: + case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case ST_OMP_TEAMS_LOOP: + { + gfc_state_data *stk = gfc_state_stack->previous; + stk->tail->ext.omp_clauses->target_first_st_is_teams = true; + break; + } + default: + break; + } + do { if (workshare_stmts_only) diff --git a/gcc/testsuite/gfortran.dg/gomp/teams-6.f90 b/gcc/testsuite/gfortran.dg/gomp/teams-6.f90 new file mode 100644 index 0000000..be453f2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/teams-6.f90 @@ -0,0 +1,78 @@ +! { dg-do compile } + +! PR fortran/110725 +! PR middle-end/71065 + + +subroutine one +!$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } +block + integer :: i ! <<< invalid: variable declaration + !$omp teams ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + i = 5 + !$omp end teams +end block + +!$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } +block + type t ! <<< invalid: type declaration + end type t + !$omp teams ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + i = 5 + !$omp end teams +end block + +!$omp target + ! The following is invalid - but not detected as ST_NONE is returned: + !$omp error at(compilation) severity(warning) ! { dg-warning "OMP ERROR encountered" } + !$omp teams + i = 5 + !$omp end teams +!$omp end target + +!$omp target + ! The following is invalid - but not detected as ST_NONE is returned: + !$omp nothing ! <<< invalid: directive + !$omp teams + i = 5 + !$omp end teams +!$omp end target +end + + +subroutine two +!$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } +block + integer :: i ! <<< invalid: variable declaration + !$omp teams distribute ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + do i = 1, 5 + end do + !$omp end teams distribute +end block + +!$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } +block + type t ! <<< invalid: type declaration + end type t + !$omp teams distribute parallel do ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } + do i = 1, 5 + end do +end block + +!$omp target + ! The following is invalid - but not detected as ST_NONE is returned: + !$omp error at(compilation) severity(warning) ! { dg-warning "OMP ERROR encountered" } + !$omp teams loop + do i = 5, 10 + end do +!$omp end target + +!$omp target + ! The following is invalid - but not detected as ST_NONE is returned: + !$omp nothing ! <<< invalid: directive + !$omp teams distribute simd + do i = -3, 5 + end do + !$omp end teams distribute simd +!$omp end target +end -- cgit v1.1 From 6e424febfbcb27c21a7fe3a137e614765f9cf9d2 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 21 Jul 2023 17:48:37 -0400 Subject: c++: fix ICE with constexpr ARRAY_REF [PR110382] This code in cxx_eval_array_reference has been hard to get right. In r12-2304 I added some code; in r13-5693 I removed some of it. Here the problematic line is "S s = arr[0];" which causes a crash on the assert in verify_ctor_sanity: gcc_assert (!ctx->object || !DECL_P (ctx->object) || ctx->global->get_value (ctx->object) == ctx->ctor); ctx->object is the VAR_DECL 's', which is correct here. The second line points to the problem: we replaced ctx->ctor in cxx_eval_array_reference: new_ctx.ctor = build_constructor (elem_type, NULL); // #1 which I think we shouldn't have; the CONSTRUCTOR we created in cxx_eval_constant_expression/DECL_EXPR new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL); had the right type. We still need #1 though. E.g., in constexpr-96241.C, we never set ctx.ctor/object before calling cxx_eval_array_reference, so we have to build a CONSTRUCTOR there. And in constexpr-101371-2.C we have a ctx.ctor, but it has the wrong type, so we need a new one. We can fix the problem by always clearing the object, and, as an optimization, only create/free a new ctor when actually needed. PR c++/110382 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_array_reference): Create a new constructor only when we don't already have a matching one. Clear the object when the type is non-scalar. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-110382.C: New test. --- gcc/cp/constexpr.cc | 13 +++++++++++-- gcc/testsuite/g++.dg/cpp1y/constexpr-110382.C | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-110382.C (limited to 'gcc') diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index fb94f3c..5e0fe93 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -4291,15 +4291,24 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, else val = build_value_init (elem_type, tf_warning_or_error); - if (!SCALAR_TYPE_P (elem_type)) + /* Create a new constructor only if we don't already have a suitable one. */ + const bool new_ctor = (!SCALAR_TYPE_P (elem_type) + && (!ctx->ctor + || !same_type_ignoring_top_level_qualifiers_p + (elem_type, TREE_TYPE (ctx->ctor)))); + if (new_ctor) { new_ctx = *ctx; + /* We clear the object here. We used to replace it with T, but that + caused problems (101371, 108158); and anyway, T is the initializer, + not the target object. */ + new_ctx.object = NULL_TREE; new_ctx.ctor = build_constructor (elem_type, NULL); ctx = &new_ctx; } t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p, overflow_p); - if (!SCALAR_TYPE_P (elem_type) && t != ctx->ctor) + if (new_ctor && t != ctx->ctor) free_constructor (ctx->ctor); return t; } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-110382.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-110382.C new file mode 100644 index 0000000..317c5ec --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-110382.C @@ -0,0 +1,17 @@ +// PR c++/110382 +// { dg-do compile { target c++14 } } + +struct S { + double a = 0; +}; + +constexpr double +g () +{ + S arr[1]; + S s = arr[0]; + (void) arr[0]; + return s.a; +} + +int main() { return g (); } -- cgit v1.1 From a8649d53d1359756b737915193e4684c7dddcaf4 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 25 Jul 2023 11:51:28 -0400 Subject: Make some functions in CCP static. gcc/ChangeLog: * tree-ssa-ccp.cc (value_mask_to_min_max): Make static. (bit_value_mult_const): Same. (get_individual_bits): Same. --- gcc/tree-ssa-ccp.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc index 64d5fa8..73fb7c1 100644 --- a/gcc/tree-ssa-ccp.cc +++ b/gcc/tree-ssa-ccp.cc @@ -1297,7 +1297,7 @@ ccp_fold (gimple *stmt) represented by the mask pair VAL and MASK with signedness SGN and precision PRECISION. */ -void +static void value_mask_to_min_max (widest_int *min, widest_int *max, const widest_int &val, const widest_int &mask, signop sgn, int precision) @@ -1391,7 +1391,7 @@ bit_value_unop (enum tree_code code, signop type_sgn, int type_precision, /* Determine the mask pair *VAL and *MASK from multiplying the argument mask pair RVAL, RMASK by the unsigned constant C. */ -void +static void bit_value_mult_const (signop sgn, int width, widest_int *val, widest_int *mask, const widest_int &rval, const widest_int &rmask, @@ -1453,7 +1453,7 @@ bit_value_mult_const (signop sgn, int width, bits in X (capped at the maximum value MAX). For example, an X value 11, places 1, 2 and 8 in BITS and returns the value 3. */ -unsigned int +static unsigned int get_individual_bits (widest_int *bits, widest_int x, unsigned int max) { unsigned int count = 0; -- cgit v1.1 From 39004608e79b68fe7615a026ce58dea646dba20e Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 25 Jul 2023 14:36:47 -0400 Subject: c++: clear tf_partial et al in instantiate_template [PR108960] In we concluded that we might clear all flags except tf_warning_or_error when performing instantiate_template. PR c++/108960 gcc/cp/ChangeLog: * pt.cc (lookup_and_finish_template_variable): Don't clear tf_partial here. (instantiate_template): Reset all complain flags except tf_warning_or_error. --- gcc/cp/pt.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 21b08a6..265e2a5 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10396,12 +10396,6 @@ lookup_and_finish_template_variable (tree templ, tree targs, tree var = lookup_template_variable (templ, targs, complain); if (var == error_mark_node) return error_mark_node; - /* We may be called while doing a partial substitution, but the - type of the variable template may be auto, in which case we - will call do_auto_deduction in mark_used (which clears tf_partial) - and the auto must be properly reduced at that time for the - deduction to work. */ - complain &= ~tf_partial; var = finish_template_variable (var, complain); mark_used (var); return var; @@ -22008,6 +22002,14 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) if (tmpl == error_mark_node) return error_mark_node; + /* The other flags are not relevant anymore here, especially tf_partial + shouldn't be set. For instance, we may be called while doing a partial + substitution of a template variable, but the type of the variable + template may be auto, in which case we will call do_auto_deduction + in mark_used (which clears tf_partial) and the auto must be properly + reduced at that time for the deduction to work. */ + complain &= tf_warning_or_error; + gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); if (modules_p ()) -- cgit v1.1 From 099d40ba776c0722888c3aa40c87c818892e04bb Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 25 Jul 2023 20:41:41 +0000 Subject: Update gcc uk.po * uk.po: Update. --- gcc/po/uk.po | 32405 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 16356 insertions(+), 16049 deletions(-) (limited to 'gcc') diff --git a/gcc/po/uk.po b/gcc/po/uk.po index 6e35bb1..8bb3240 100644 --- a/gcc/po/uk.po +++ b/gcc/po/uk.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the gcc package. # # Yuri Chornoivan , 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. +# Volodymyr M. Lisivka , 2023. msgid "" msgstr "" -"Project-Id-Version: gcc 12.1.0\n" +"Project-Id-Version: gcc 13.1.0\n" "Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n" "POT-Creation-Date: 2023-04-25 21:43+0000\n" -"PO-Revision-Date: 2022-05-08 14:31+0300\n" -"Last-Translator: Yuri Chornoivan \n" +"PO-Revision-Date: 2023-06-28 21:45+0300\n" +"Last-Translator: Volodymyr Lisivka \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" @@ -17,55 +18,54 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Bugs: Report translation errors to the Language-Team address.\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Lokalize 20.12.0\n" #: cif-code.def:39 msgid "function not considered for inlining" -msgstr "функція не буде включено для вбудовування" +msgstr "функція не розглядається для вбудовування" #: cif-code.def:43 msgid "caller is not optimized" -msgstr "джерело виклику не оптимізовано" +msgstr "викликач не оптимізований" #: cif-code.def:47 msgid "function body not available" -msgstr "вміст функції є недоступним" +msgstr "тіло функції недоступне" #: cif-code.def:51 msgid "redefined extern inline functions are not considered for inlining" -msgstr "" +msgstr "перевизначені зовнішні функції з ключовим словом inline не розглядаються для вбудовування" #: cif-code.def:56 msgid "function not inlinable" -msgstr "функція є непридатною до вбудовування" +msgstr "функцію не можна вбудувати" #: cif-code.def:60 msgid "function body can be overwritten at link time" -msgstr "вміст функцію може бути перезаписано під час компонування" +msgstr "тіло функції може бути перезаписане під час звʼязування" #: cif-code.def:64 msgid "function not inline candidate" -msgstr "функція не є кандидатом на вбудовування" +msgstr "функція не є кандидатом для вбудовування" #: cif-code.def:68 msgid "--param large-function-growth limit reached" -msgstr "" +msgstr "досягнуто обмеження --param large-function-growth" #: cif-code.def:70 msgid "--param large-stack-frame-growth limit reached" -msgstr "" +msgstr "досягнуто обмеження --param large-stack-frame-growth" #: cif-code.def:72 msgid "--param max-inline-insns-single limit reached" -msgstr "" +msgstr "досягнуто обмеження --param max-inline-insns-single" #: cif-code.def:74 msgid "--param max-inline-insns-auto limit reached" -msgstr "" +msgstr "досягнуто обмеження параметра --param max-inline-insns-auto" #: cif-code.def:76 msgid "--param inline-unit-growth limit reached" -msgstr "" +msgstr "досягнуто обмеження параметра --param inline-unit-growth" #: cif-code.def:80 msgid "recursive inlining" @@ -73,59 +73,59 @@ msgstr "рекурсивне вбудовування" #: cif-code.def:84 msgid "call is unlikely and code size would grow" -msgstr "виклик малоймовірний, а розмір коду збільшиться" +msgstr "виклик малоймовірний і розмір коду збільшиться" #: cif-code.def:88 msgid "call is considered never executed and code size would grow" -msgstr "виклик вважається таким, який ніколи не буде виконано, а розмір коду збільшиться" +msgstr "виклик вважається ніколи не виконуваним і розмір коду збільшиться" #: cif-code.def:92 msgid "function not declared inline and code size would grow" -msgstr "функцію не оголошено як вбудовувану, а розмір коду збільшиться" +msgstr "функція не оголошена як inline і розмір коду збільшиться" #: cif-code.def:96 msgid "mismatched declarations during linktime optimization" -msgstr "невідповідність оголошень під час оптимізації під час компонування" +msgstr "несумісні оголошення під час оптимізації на етапі звʼязування" #: cif-code.def:100 msgid "variadic thunk call" -msgstr "" +msgstr "виклик варіативного тунку" #: cif-code.def:104 msgid "originally indirect function call not considered for inlining" -msgstr "" +msgstr "початковий непрямий виклик функції не розглядається для вбудовування" #: cif-code.def:108 msgid "indirect function call with a yet undetermined callee" -msgstr "" +msgstr "непрямий виклик функції з ще невизначеним викликачем" #: cif-code.def:112 msgid "exception handling personality mismatch" -msgstr "" +msgstr "несумісність персоналітету обробки виключень" #: cif-code.def:117 msgid "non-call exception handling mismatch" -msgstr "" +msgstr "несумісність обробки виключень без виклику" #: cif-code.def:121 msgid "target specific option mismatch" -msgstr "" +msgstr "несумісність специфічної опції цілі" #: cif-code.def:125 msgid "optimization level attribute mismatch" -msgstr "невідповідність атрибутів рівня оптимізації" +msgstr "несумісність атрибуту рівня оптимізації" #: cif-code.def:129 msgid "callee refers to comdat-local symbols" -msgstr "" +msgstr "викликаюча функція посилається на локальні символи comdat" #: cif-code.def:134 msgid "sanitizer function attribute mismatch" -msgstr "невідповідність атрибутів функції-санітайзера" +msgstr "несумісність атрибуту функції санітазатора" #: cif-code.def:139 msgid "function has external linkage when the user requests only inlining static for live patching" -msgstr "" +msgstr "функція має зовнішнє звʼязування, тоді як користувач вимагає тільки вбудовування статичних функцій для живого латання" #: cif-code.def:144 msgid "unreachable" @@ -162,11 +162,11 @@ msgstr "анахронізм: " #: diagnostic.def:39 msgid "note: " -msgstr "зауваження: " +msgstr "примітка: " #: diagnostic.def:40 msgid "debug: " -msgstr "діагностика: " +msgstr "налагодження: " #. For use when using the diagnostic_show_locus machinery to show #. a range of events within a path. @@ -178,7 +178,7 @@ msgstr "шлях: " #. prefix does not matter. #: diagnostic.def:48 msgid "pedwarn: " -msgstr "педантичне попередження: " +msgstr "пед. попередження: " #: diagnostic.def:49 msgid "permerror: " @@ -187,7 +187,7 @@ msgstr "постійна помилка: " #: config/i386/djgpp.h:143 #, c-format msgid "-f%s ignored (not supported for DJGPP)\n" -msgstr "-f%s проігноровано (не передбачено підтримки для DJGPP)\n" +msgstr "-f%s ігнорується (не підтримується для DJGPP)\n" #. The remainder are real diagnostic types. #: fortran/gfc-diagnostic.def:33 @@ -218,17 +218,17 @@ msgstr "анахронізм" #: fortran/gfc-diagnostic.def:39 msgid "note" -msgstr "зауваження" +msgstr "примітка" #: fortran/gfc-diagnostic.def:40 msgid "debug" -msgstr "діагностика" +msgstr "налагодження" #. These two would be re-classified as DK_WARNING or DK_ERROR, so the #. prefix does not matter. #: fortran/gfc-diagnostic.def:43 msgid "pedwarn" -msgstr "педантичне попередження" +msgstr "пед. попередження" #: fortran/gfc-diagnostic.def:44 msgid "permerror" @@ -242,37 +242,35 @@ msgstr "помилка" #: gcc.cc:839 gcc.cc:896 msgid "-gz is not supported in this configuration" -msgstr "підтримки -gz на цій конфігурації не передбачено" +msgstr "-gz не підтримується в цій конфігурації" #: gcc.cc:845 -#, fuzzy -#| msgid "-gz is not supported in this configuration" msgid "-gz=zstd is not supported in this configuration" -msgstr "підтримки -gz на цій конфігурації не передбачено" +msgstr "-gz=zstd не підтримується в цій конфігурації" #: gcc.cc:1079 msgid "-fuse-linker-plugin is not supported in this configuration" -msgstr "підтримки -fuse-linker-plugin на цій конфігурації не передбачено" +msgstr "-fuse-linker-plugin не підтримується в цій конфігурації" #: gcc.cc:1095 msgid "cannot specify -static with -fsanitize=address" -msgstr "не можна вказувати -static у поєднанні із -fsanitize=address" +msgstr "не можна вказувати -static з -fsanitize=address" #: gcc.cc:1097 msgid "cannot specify -static with -fsanitize=hwaddress" -msgstr "" +msgstr "не можна вказувати -static з -fsanitize=hwaddress" #: gcc.cc:1099 msgid "cannot specify -static with -fsanitize=thread" -msgstr "" +msgstr "не можна вказувати -static з -fsanitize=thread" #: gcc.cc:1121 msgid "-fvtable-verify=std is not supported in this configuration" -msgstr "" +msgstr "-fvtable-verify=std не підтримується в цій конфігурації" #: gcc.cc:1123 msgid "-fvtable-verify=preinit is not supported in this configuration" -msgstr "" +msgstr "-fvtable-verify=preinit не підтримується в цій конфігурації" #: gcc.cc:1260 ada/gcc-interface/lang-specs.h:37 msgid "-pg and -fomit-frame-pointer are incompatible" @@ -280,119 +278,119 @@ msgstr "-pg і -fomit-frame-pointer є несумісними" #: gcc.cc:1435 msgid "GNU C no longer supports -traditional without -E" -msgstr "У GNU C припинено підтримку -traditional без -E" +msgstr "GNU C більше не підтримує -traditional без -E" #: gcc.cc:1444 msgid "-E or -x required when input is from standard input" -msgstr "якщо дані надходять зі стандартного вхідного джерела, слід вказувати -E або -x" +msgstr "-E або -x потрібні, коли вхідні дані отримані зі стандартного вводу" #: config/darwin.h:151 msgid "conflicting code generation switches" -msgstr "конфлікт перемикачів створення коду" +msgstr "конфліктують перемикачі генерації коду" #: config/darwin.h:156 msgid "-bundle_loader not allowed with -dynamiclib" -msgstr "" +msgstr "-bundle_loader не дозволяється з -dynamiclib" #: config/darwin.h:158 msgid "-client_name not allowed with -dynamiclib" -msgstr "" +msgstr "-client_name не дозволяється з -dynamiclib" #: config/darwin.h:167 msgid "-keep_private_externs not allowed with -dynamiclib" -msgstr "" +msgstr "-keep_private_externs не дозволяється з -dynamiclib" #: config/darwin.h:169 msgid "-private_bundle not allowed with -dynamiclib" -msgstr "" +msgstr "-private_bundle не дозволяється з -dynamiclib" #: config/darwin.h:177 msgid "-compatibility_version only allowed with -dynamiclib" -msgstr "" +msgstr "-compatibility_version дозволяється тільки з -dynamiclib" #: config/darwin.h:179 msgid "-current_version only allowed with -dynamiclib" -msgstr "" +msgstr "-current_version дозволяється тільки з -dynamiclib" #: config/darwin.h:181 msgid "-install_name only allowed with -dynamiclib" -msgstr "" +msgstr "-install_name дозволяється тільки з -dynamiclib" #: config/darwin.h:192 msgid "-bundle not allowed with -dynamiclib" -msgstr "" +msgstr "-bundle не дозволяється з -dynamiclib" #: config/darwin.h:208 msgid "-force_flat_namespace not allowed with -dynamiclib" -msgstr "" +msgstr "-force_flat_namespace не дозволяється з -dynamiclib" #: config/darwin.h:213 config/darwin.h:596 msgid "gsplit-dwarf is not supported on this platform" -msgstr "підтримки gsplit-dwarf на цій платформі не передбачено" +msgstr "gsplit-dwarf не підтримується на цій платформі" #: config/darwin.h:277 msgid "rdynamic is not supported" -msgstr "підтримки rdynamic не передбачено" +msgstr "rdynamic не підтримується" #: config/dragonfly.h:76 config/i386/freebsd.h:82 config/i386/freebsd64.h:35 #: config/ia64/freebsd.h:26 config/rs6000/sysv4.h:750 #: config/sparc/freebsd.h:45 msgid "consider using '-pg' instead of '-p' with gprof(1)" -msgstr "" +msgstr "розгляньте використання '-pg' замість '-p' з gprof(1)" #: config/lynx.h:69 msgid "cannot use mthreads and mlegacy-threads together" -msgstr "" +msgstr "не можна використовувати mthreads і mlegacy-threads одночасно" #: config/lynx.h:94 msgid "cannot use mshared and static together" -msgstr "" +msgstr "не можна використовувати mshared і static одночасно" #: config/sol2.h:349 config/sol2.h:354 msgid "does not support multilib" -msgstr "" +msgstr "не підтримує multilib" #: config/sol2.h:448 msgid "-pie is not supported in this configuration" -msgstr "" +msgstr "-pie не підтримується в цій конфігурації" #: config/vxworks.h:219 msgid "-Xbind-now and -Xbind-lazy are incompatible" -msgstr "" +msgstr "-Xbind-now і -Xbind-lazy несумісні" #: config/aarch64/aarch64-freebsd.h:37 config/arm/freebsd.h:49 #: config/riscv/freebsd.h:44 msgid "consider using `-pg' instead of `-p' with gprof (1)" -msgstr "" +msgstr "розгляньте використання `-pg' замість `-p' з gprof (1)" #: config/arc/arc.h:68 config/mips/mips.h:1477 msgid "may not use both -EB and -EL" -msgstr "" +msgstr "не можна використовувати одночасно -EB та -EL" #: config/avr/specs.h:71 config/pru/pru.h:58 msgid "shared is not supported" -msgstr "" +msgstr "shared не підтримується" #: config/bfin/elf.h:55 msgid "no processor type specified for linking" -msgstr "" +msgstr "не вказано тип процесора для звʼязування" #: config/cris/cris.h:168 msgid "do not specify both -march=... and -mcpu=..." -msgstr "" +msgstr "не вказуйте одночасно -march=... та -mcpu=..." #: config/i386/cygwin-w64.h:64 config/i386/cygwin.h:129 #: config/i386/mingw-w64.h:103 config/i386/mingw32.h:154 msgid "shared and mdll are not compatible" -msgstr "" +msgstr "shared та mdll несумісні" #: config/i386/darwin.h:93 msgid "Darwin is not an mx32 platform" -msgstr "" +msgstr "Darwin не є платформою mx32" #: config/i386/darwin.h:94 msgid "Darwin does not support -mfentry or associated options" -msgstr "" +msgstr "Darwin не підтримує -mfentry або повʼязані опції" #: config/i386/sol2.h:59 msgid "-mx32 is not supported on Solaris" @@ -400,150 +398,150 @@ msgstr "підтримки -mx32 у Solaris не передбачено" #: config/mcore/mcore.h:53 msgid "the m210 does not have little endian support" -msgstr "" +msgstr "m210 не підтримує little endian" #: config/mips/r3900.h:37 msgid "-mhard-float not supported" -msgstr "" +msgstr "-mhard-float не підтримується" #: config/mips/r3900.h:39 msgid "-msingle-float and -msoft-float cannot both be specified" -msgstr "" +msgstr "-msingle-float та -msoft-float не можуть бути вказані одночасно" #: config/moxie/moxiebox.h:43 msgid "this target is little-endian" -msgstr "" +msgstr "ця цільова архітектура має формат little endian" #: config/msp430/msp430.h:90 msgid "-mcode-region requires the large memory model (-mlarge)" -msgstr "" +msgstr "-mcode-region вимагає велику модель памʼяті (-mlarge)" #: config/msp430/msp430.h:92 msgid "-mdata-region requires the large memory model (-mlarge)" -msgstr "" +msgstr "-mdata-region вимагає велику модель памʼяті (-mlarge)" #: config/nios2/elf.h:44 msgid "You need a C startup file for -msys-crt0=" -msgstr "" +msgstr "Вам потрібен початковий файл C для -msys-crt0=" #: config/pa/pa-hpux11.h:134 config/pa/pa-hpux11.h:137 #: config/pa/pa64-hpux.h:29 config/pa/pa64-hpux.h:32 config/pa/pa64-hpux.h:41 #: config/pa/pa64-hpux.h:44 msgid "warning: consider linking with '-static' as system libraries with" -msgstr "" +msgstr "попередження: розгляньте звʼязування з '-static', оскільки системні бібліотеки з" #: config/pa/pa-hpux11.h:135 config/pa/pa-hpux11.h:138 #: config/pa/pa64-hpux.h:30 config/pa/pa64-hpux.h:33 config/pa/pa64-hpux.h:42 #: config/pa/pa64-hpux.h:45 msgid " profiling support are only provided in archive format" -msgstr "" +msgstr " підтримка профілювання надається тільки у форматі архіву" #: config/rs6000/darwin.h:123 msgid " conflicting code gen style switches are used" -msgstr "" +msgstr " використовуються конфліктуючі перемикачі стилю генерації коду" #: config/rs6000/freebsd64.h:114 msgid "consider using `-pg' instead of `-p' with gprof(1)" -msgstr "" +msgstr "розгляньте використання `-pg' замість `-p' з gprof(1)" #: config/rs6000/rs6000.h:170 msgid "Missing -mcpu option in ASM_CPU_SPEC?" -msgstr "" +msgstr "Відсутня опція -mcpu в ASM_CPU_SPEC?" #: config/rx/linux.h:53 config/rx/rx.h:82 msgid "rx200 cpu does not have FPU hardware" -msgstr "" +msgstr "процесор rx200 не має апаратного FPU" #: config/rx/rx.h:80 msgid "-mas100-syntax is incompatible with -gdwarf" -msgstr "" +msgstr "-mas100-syntax несумісний з -gdwarf" #: config/rx/rx.h:81 msgid "rx100 cpu does not have FPU hardware" -msgstr "" +msgstr "процесор rx100 не має апаратного FPU" #: config/s390/tpf.h:119 msgid "static is not supported on TPF-OS" -msgstr "" +msgstr "статичний не підтримується в TPF-OS" #: config/sh/sh.h:299 config/sh/sh.h:302 msgid "SH2a does not support little-endian" -msgstr "" +msgstr "SH2a не підтримує little-endian" #: config/sparc/linux64.h:142 msgid "-fsanitize=address is not supported in this configuration" -msgstr "підтримки -fsanitize=адреса на цій конфігурації не передбачено" +msgstr "-fsanitize=address не підтримується в цій конфігурації" #: config/sparc/linux64.h:156 config/sparc/linux64.h:162 #: config/sparc/netbsd-elf.h:103 config/sparc/netbsd-elf.h:112 #: config/sparc/sol2.h:237 config/sparc/sol2.h:243 msgid "may not use both -m32 and -m64" -msgstr "" +msgstr "не можна використовувати одночасно -m32 та -m64" #: config/vax/netbsd-elf.h:51 msgid "the -shared option is not currently supported for VAX ELF" -msgstr "" +msgstr "опція -shared наразі не підтримується для VAX ELF" #: config/vax/vax.h:46 config/vax/vax.h:47 msgid "profiling not supported with -mg" -msgstr "" +msgstr "профілювання не підтримується з -mg" #: ada/gcc-interface/lang-specs.h:38 msgid "-c or -S required for Ada" -msgstr "" +msgstr "-c або -S потрібно для Ada" #: ada/gcc-interface/lang-specs.h:56 msgid "-c required for gnat2why" -msgstr "" +msgstr "-c потрібно для gnat2why" #: ada/gcc-interface/lang-specs.h:67 msgid "-c required for gnat2scil" -msgstr "" +msgstr "-c потрібно для gnat2scil" #: fortran/lang-specs.h:60 fortran/lang-specs.h:74 msgid "gfortran does not support -E without -cpp" -msgstr "" +msgstr "gfortran не підтримує -E без -cpp" #: m2/lang-specs.h:48 msgid "to generate dependencies you must specify '-fcpp' " -msgstr "" +msgstr "для генерації залежностей потрібно вказати '-fcpp'" #: objc/lang-specs.h:30 objc/lang-specs.h:41 msgid "GNU Objective C no longer supports traditional compilation" -msgstr "" +msgstr "GNU Objective C більше не підтримує традиційну компіляцію" #: objc/lang-specs.h:55 msgid "objc-cpp-output is deprecated; please use objective-c-cpp-output instead" -msgstr "objc-cpp-output вважається застарілим; будь ласка, скористайтеся замість нього objective-c-cpp-output" +msgstr "objc-cpp-output застаріло; будь ласка, використовуйте objective-c-cpp-output замість цього" #: objcp/lang-specs.h:58 msgid "objc++-cpp-output is deprecated; please use objective-c++-cpp-output instead" -msgstr "objc++-cpp-output вважається застарілим; будь ласка, скористайтеся замість нього objective-c++-cpp-output" +msgstr "objc++-cpp-output застаріло; будь ласка, використовуйте objective-c++-cpp-output замість цього" #: fortran/lang.opt:146 #, no-c-format msgid "-J\tPut MODULE files in 'directory'." -msgstr "" +msgstr "-J<директорія>\tРозмістити файли MODULE у «директорії»." #: fortran/lang.opt:198 #, no-c-format msgid "Warn about possible aliasing of dummy arguments." -msgstr "" +msgstr "Попереджати про можливе псевдонімування фіктивних аргументів." #: fortran/lang.opt:202 #, no-c-format msgid "Warn about alignment of COMMON blocks." -msgstr "" +msgstr "Попереджати про вирівнювання блоків COMMON." #: fortran/lang.opt:206 #, no-c-format msgid "Warn about missing ampersand in continued character constants." -msgstr "" +msgstr "Попередження про відсутність символу «&» в продовжених символьних константах." #: fortran/lang.opt:210 #, no-c-format msgid "Warn about creation of array temporaries." -msgstr "Попереджати щодо створення тимчасових масивів." +msgstr "Попереджати про створення тимчасових масивів." #: fortran/lang.opt:214 fortran/lang.opt:535 c-family/c.opt:1529 #: config/alpha/alpha.opt:31 common.opt:681 common.opt:823 common.opt:1064 @@ -552,582 +550,582 @@ msgstr "Попереджати щодо створення тимчасових #: common.opt:2482 common.opt:3202 #, no-c-format msgid "Does nothing. Preserved for backward compatibility." -msgstr "" +msgstr "Нічого не робить. Зберігається для забезпечення сумісності з попередніми версіями." #: fortran/lang.opt:218 #, no-c-format msgid "Warn if the type of a variable might be not interoperable with C." -msgstr "" +msgstr "Попереджати, якщо тип змінної може бути несумісним з C." #: fortran/lang.opt:226 #, no-c-format msgid "Warn about truncated character expressions." -msgstr "" +msgstr "Попереджати про обрізання символьних виразів." #: fortran/lang.opt:230 #, no-c-format msgid "Warn about equality comparisons involving REAL or COMPLEX expressions." -msgstr "" +msgstr "Попередження про порівняння на рівність з використанням виразів REAL або COMPLEX." #: fortran/lang.opt:238 #, no-c-format msgid "Warn about most implicit conversions." -msgstr "" +msgstr "Попереджати про більшість неявних перетворень." #: fortran/lang.opt:242 #, no-c-format msgid "Warn about possibly incorrect subscripts in do loops." -msgstr "" +msgstr "Попередження про можливо неправильні підскрипти в циклах do." #: fortran/lang.opt:250 #, no-c-format msgid "Warn if loops have been interchanged." -msgstr "" +msgstr "Попереджати, якщо цикли були поміняні місцями." #: fortran/lang.opt:254 #, no-c-format msgid "Warn about function call elimination." -msgstr "" +msgstr "Попередження про видалення викликів функцій." #: fortran/lang.opt:258 #, no-c-format msgid "Warn about calls with implicit interface." -msgstr "" +msgstr "Попереджати про виклики з неявним інтерфейсом." #: fortran/lang.opt:262 #, no-c-format msgid "Warn about called procedures not explicitly declared." -msgstr "" +msgstr "Попереджати про виклики процедур, які не були явно оголошені." #: fortran/lang.opt:266 #, no-c-format msgid "Warn about constant integer divisions with truncated results." -msgstr "" +msgstr "Попереджати про константні цілочисельні ділення з обрізаними результатами." #: fortran/lang.opt:270 #, no-c-format msgid "Warn about truncated source lines." -msgstr "" +msgstr "Попередження про обрізані рядки вихідного коду." #: fortran/lang.opt:274 #, no-c-format msgid "Warn on intrinsics not part of the selected standard." -msgstr "" +msgstr "Попередження про використання вбудованих функцій, які не входять до обраного стандарту." #: fortran/lang.opt:286 #, no-c-format msgid "Warn about USE statements that have no ONLY qualifier." -msgstr "" +msgstr "Попередження про використання операторів USE без явного вказівника ONLY." #: fortran/lang.opt:298 #, no-c-format msgid "Warn that -fno-automatic may break recursion." -msgstr "" +msgstr "Попереджати, що -fno-automatic може порушити рекурсію." #: fortran/lang.opt:306 #, no-c-format msgid "Warn about real-literal-constants with 'q' exponent-letter." -msgstr "" +msgstr "Попередження про використання літералів-констант з дійсними числами з літерою-показником 'q'." #: fortran/lang.opt:310 #, no-c-format msgid "Warn when a left-hand-side array variable is reallocated." -msgstr "" +msgstr "Попереджати, коли змінна масиву з лівого боку перерозподіляється." #: fortran/lang.opt:314 #, no-c-format msgid "Warn when a left-hand-side variable is reallocated." -msgstr "" +msgstr "Попереджати, коли змінна з лівого боку перерозподіляється." #: fortran/lang.opt:318 #, no-c-format msgid "Warn if the pointer in a pointer assignment might outlive its target." -msgstr "" +msgstr "Попередження, якщо вказівник у присвоєнні вказівників може пережити свою ціль." #: fortran/lang.opt:326 #, no-c-format msgid "Warn about \"suspicious\" constructs." -msgstr "" +msgstr "Попереджати про «підозрілі» конструкції." #: fortran/lang.opt:330 #, no-c-format msgid "Permit nonconforming uses of the tab character." -msgstr "" +msgstr "Дозволити невідповідні використання символу табуляції." #: fortran/lang.opt:334 #, no-c-format msgid "Warn about an invalid DO loop." -msgstr "" +msgstr "Попереджати про недійсний цикл DO." #: fortran/lang.opt:338 #, no-c-format msgid "Warn about underflow of numerical constant expressions." -msgstr "" +msgstr "Попереджати про недостатність числових константних виразів." #: fortran/lang.opt:346 #, no-c-format msgid "Warn if a user-procedure has the same name as an intrinsic." -msgstr "" +msgstr "Попереджати, якщо користувацька процедура має ту саму назву, що і вбудована." #: fortran/lang.opt:354 #, no-c-format msgid "Warn about unused dummy arguments." -msgstr "" +msgstr "Попереджати про невикористані фіктивні аргументи." #: fortran/lang.opt:358 #, no-c-format msgid "Warn about zero-trip DO loops." -msgstr "" +msgstr "Попереджати про цикли DO з нульовою кількістю ітерацій." #: fortran/lang.opt:362 #, no-c-format msgid "Enable preprocessing." -msgstr "" +msgstr "Увімкнути попередню обробку." #: fortran/lang.opt:370 #, no-c-format msgid "Disable preprocessing." -msgstr "" +msgstr "Вимкнути попередню обробку." #: fortran/lang.opt:378 #, no-c-format msgid "Accept argument mismatches in procedure calls." -msgstr "" +msgstr "Приймати несумісність аргументів у викликах процедур." #: fortran/lang.opt:382 #, no-c-format msgid "Eliminate multiple function invocations also for impure functions." -msgstr "" +msgstr "Усунути кілька викликів функцій, навіть для незбалансованих функцій." #: fortran/lang.opt:386 #, no-c-format msgid "Enable alignment of COMMON blocks." -msgstr "" +msgstr "Увімкнути вирівнювання блоків COMMON." #: fortran/lang.opt:390 #, no-c-format msgid "All intrinsics procedures are available regardless of selected standard." -msgstr "" +msgstr "Всі вбудовані процедури доступні незалежно від вибраного стандарту." #: fortran/lang.opt:394 #, no-c-format msgid "Allow a BOZ literal constant to appear in an invalid context and with X instead of Z." -msgstr "" +msgstr "Дозволити появу літеральної константи BOZ в недійсному контексті та замість Z використовувати X." #: fortran/lang.opt:402 #, no-c-format msgid "Do not treat local variables and COMMON blocks as if they were named in SAVE statements." -msgstr "" +msgstr "Не розглядати локальні змінні та COMMON-блоки так, ніби вони були названі в SAVE-операторах." #: fortran/lang.opt:406 #, no-c-format msgid "Specify that backslash in string introduces an escape character." -msgstr "" +msgstr "Вказати, що зворотний слеш в рядку вводить символ екранування." #: fortran/lang.opt:410 #, no-c-format msgid "Produce a backtrace when a runtime error is encountered." -msgstr "" +msgstr "Створити трасування викликів при виникненні помилки під час виконання." #: fortran/lang.opt:414 #, no-c-format msgid "-fblas-matmul-limit=\tSize of the smallest matrix for which matmul will use BLAS." -msgstr "" +msgstr "-fblas-matmul-limit=\tРозмір найменшої матриці, для якої matmul буде використовувати BLAS." #: fortran/lang.opt:421 #, no-c-format msgid "Produce a warning at runtime if a array temporary has been created for a procedure argument." -msgstr "" +msgstr "Виробляти попередження під час виконання, якщо для аргументу процедури було створено тимчасовий масив." #: fortran/lang.opt:425 #, no-c-format msgid "-fconvert=\tThe endianness used for unformatted files." -msgstr "" +msgstr "-fconvert=\tПорядок байтів, що використовується для неформатованих файлів." #: fortran/lang.opt:450 #, no-c-format msgid "Use the Cray Pointer extension." -msgstr "" +msgstr "Використовувати розширення вказівників Cray." #: fortran/lang.opt:454 #, no-c-format msgid "Generate C prototypes from BIND(C) declarations." -msgstr "" +msgstr "Генерувати C-прототипи з декларацій BIND(C)." #: fortran/lang.opt:458 #, no-c-format msgid "Generate C prototypes from non-BIND(C) external procedure definitions." -msgstr "" +msgstr "Генерувати C-прототипи з зовнішніх визначень процедур, які не є BIND(C)." #: fortran/lang.opt:462 #, no-c-format msgid "Ignore 'D' in column one in fixed form." -msgstr "" +msgstr "Ігнорувати «D» в першому стовпчику у фіксованій формі." #: fortran/lang.opt:466 #, no-c-format msgid "Treat lines with 'D' in column one as comments." -msgstr "" +msgstr "Трактувати рядки з «D» в першому стовпчику як коментарі." #: fortran/lang.opt:470 #, no-c-format msgid "Issue debug information for compiler-generated auxiliary variables." -msgstr "" +msgstr "Виводити відлагоджувальну інформацію для допоміжних змінних, згенерованих компілятором." #: fortran/lang.opt:474 #, no-c-format msgid "Enable all DEC language extensions." -msgstr "" +msgstr "Увімкнути всі розширення мови DEC." #: fortran/lang.opt:478 #, no-c-format msgid "Enable the use of blank format items in format strings." -msgstr "" +msgstr "Увімкнути використання порожніх елементів формату в рядках форматування." #: fortran/lang.opt:482 #, no-c-format msgid "Enable the use of character literals in assignments and data statements for non-character variables." -msgstr "" +msgstr "Увімкнути використання літералів символів в присвоєннях та операторах даних для несимвольних змінних." #: fortran/lang.opt:487 #, no-c-format msgid "Enable legacy parsing of INCLUDE as statement." -msgstr "" +msgstr "Увімкнути старе розбирання INCLUDE як оператора." #: fortran/lang.opt:491 #, no-c-format msgid "Enable default widths for i, f and g format specifiers." -msgstr "" +msgstr "Увімкнути типові ширини для специфікаторів формату i, f та g." #: fortran/lang.opt:495 #, no-c-format msgid "Enable kind-specific variants of integer intrinsic functions." -msgstr "" +msgstr "Увімкнути види специфікацій для вбудованих цілочисельних функцій." #: fortran/lang.opt:499 #, no-c-format msgid "Enable legacy math intrinsics for compatibility." -msgstr "" +msgstr "Увімкнути спадкові математичні інтринси для сумісності." #: fortran/lang.opt:503 #, no-c-format msgid "Enable support for DEC STRUCTURE/RECORD." -msgstr "" +msgstr "Увімкнути підтримку DEC STRUCTURE/RECORD." #: fortran/lang.opt:507 #, no-c-format msgid "Enable DEC-style STATIC and AUTOMATIC attributes." -msgstr "" +msgstr "Увімкнути атрибути STATIC та AUTOMATIC у стилі DEC." #: fortran/lang.opt:511 #, no-c-format msgid "Set the default double precision kind to an 8 byte wide type." -msgstr "" +msgstr "Встановити тип за замовчуванням для подвійної точності як тип шириною 8 байт." #: fortran/lang.opt:515 #, no-c-format msgid "Set the default integer kind to an 8 byte wide type." -msgstr "" +msgstr "Встановити тип за замовчуванням для цілочисельних як тип шириною 8 байт." #: fortran/lang.opt:519 #, no-c-format msgid "Set the default real kind to an 8 byte wide type." -msgstr "" +msgstr "Встановити тип за замовчуванням для дійсних чисел як тип шириною 8 байт." #: fortran/lang.opt:523 #, no-c-format msgid "Set the default real kind to an 10 byte wide type." -msgstr "" +msgstr "Встановити тип за замовчуванням для дійсних чисел як тип шириною 10 байт." #: fortran/lang.opt:527 #, no-c-format msgid "Set the default real kind to an 16 byte wide type." -msgstr "" +msgstr "Встановити тип за замовчуванням для дійсних чисел як тип шириною 16 байт." #: fortran/lang.opt:531 #, no-c-format msgid "Allow dollar signs in entity names." -msgstr "" +msgstr "Дозволити знаки долара в назвах сутностей." #: fortran/lang.opt:539 #, no-c-format msgid "Display the code tree after parsing." -msgstr "" +msgstr "Показувати дерево коду після синтаксичного аналізу." #: fortran/lang.opt:543 #, no-c-format msgid "Display the code tree after front end optimization." -msgstr "" +msgstr "Показувати дерево коду після оптимізації передньої частини." #: fortran/lang.opt:547 #, no-c-format msgid "Display the global symbol table after parsing." -msgstr "" +msgstr "Показувати глобальну таблицю символів після синтаксичного аналізу." #: fortran/lang.opt:551 #, no-c-format msgid "Display the code tree after parsing; deprecated option." -msgstr "" +msgstr "Показувати дерево коду після синтаксичного аналізу; застаріла опція." #: fortran/lang.opt:555 #, no-c-format msgid "Specify that an external BLAS library should be used for matmul calls on large-size arrays." -msgstr "" +msgstr "Вказати, що для викликів matmul з великими масивами слід використовувати зовнішню бібліотеку BLAS." #: fortran/lang.opt:559 #, no-c-format msgid "Use f2c calling convention." -msgstr "" +msgstr "Використовувати конвенцію виклику f2c." #: fortran/lang.opt:563 #, no-c-format msgid "Assume that the source file is fixed form." -msgstr "" +msgstr "Припустити, що вихідний файл має фіксовану форму." #: fortran/lang.opt:567 #, no-c-format msgid "Force creation of temporary to test infrequently-executed forall code." -msgstr "" +msgstr "Примусове створення тимчасової змінної для тестування рідко виконуваного коду forall." #: fortran/lang.opt:571 #, no-c-format msgid "Interpret any INTEGER(4) as an INTEGER(8)." -msgstr "" +msgstr "Інтерпретувати будь-яке INTEGER(4) як INTEGER(8)." #: fortran/lang.opt:575 fortran/lang.opt:579 #, no-c-format msgid "Specify where to find the compiled intrinsic modules." -msgstr "" +msgstr "Вказати, де знаходяться скомпільовані вбудовані модулі." #: fortran/lang.opt:583 #, no-c-format msgid "Allow arbitrary character line width in fixed mode." -msgstr "" +msgstr "Дозволити довільну ширину символів у фіксованому режимі." #: fortran/lang.opt:587 #, no-c-format msgid "-ffixed-line-length-\tUse n as character line width in fixed mode." -msgstr "" +msgstr "-ffixed-line-length-\tВикористовувати n як ширину символів у фіксованому режимі." #: fortran/lang.opt:591 #, no-c-format msgid "Pad shorter fixed form lines to line width with spaces." -msgstr "" +msgstr "Додати пробіли до коротших рядків фіксованої форми до ширини рядка." #: fortran/lang.opt:595 #, no-c-format msgid "-ffpe-trap=[...]\tStop on following floating point exceptions." -msgstr "" +msgstr "-ffpe-trap=[...]\tЗупинитися на наступних винятках з плаваючою комою." #: fortran/lang.opt:599 #, no-c-format msgid "-ffpe-summary=[...]\tPrint summary of floating point exceptions." -msgstr "" +msgstr "-ffpe-summary=[...]\tНадрукувати підсумок винятків з плаваючою комою." #: fortran/lang.opt:603 #, no-c-format msgid "Assume that the source file is free form." -msgstr "" +msgstr "Припустити, що вихідний файл має вільну форму." #: fortran/lang.opt:607 #, no-c-format msgid "Allow arbitrary character line width in free mode." -msgstr "" +msgstr "Дозволити довільну ширину рядка символів у вільному режимі." #: fortran/lang.opt:611 #, no-c-format msgid "-ffree-line-length-\tUse n as character line width in free mode." -msgstr "" +msgstr "-ffree-line-length-\tВикористовувати n як ширину рядка символів у вільному режимі." #: fortran/lang.opt:615 #, no-c-format msgid "Try to interchange loops if profitable." -msgstr "" +msgstr "Спробувати обміняти цикли, якщо це прибутково." #: fortran/lang.opt:619 #, no-c-format msgid "Enable front end optimization." -msgstr "" +msgstr "Увімкнути оптимізацію передньої частини." #: fortran/lang.opt:623 #, no-c-format msgid "Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements." -msgstr "" +msgstr "Вказати, що не дозволяється неявне типізування, якщо його не перевизначено явними операторами IMPLICIT." #: fortran/lang.opt:627 #, no-c-format msgid "-finit-character=\tInitialize local character variables to ASCII value n." -msgstr "" +msgstr "-finit-character=\tІніціалізувати локальні змінні типу символу значенням ASCII n." #: fortran/lang.opt:631 #, no-c-format msgid "Initialize components of derived type variables according to other init flags." -msgstr "" +msgstr "Ініціалізувати компоненти змінних похідного типу відповідно до інших прапорців ініціалізації." #: fortran/lang.opt:635 #, no-c-format msgid "-finit-integer=\tInitialize local integer variables to n." -msgstr "" +msgstr "-finit-integer=\tІніціалізувати локальні змінні типу ціле значенням n." #: fortran/lang.opt:639 #, no-c-format msgid "Initialize local variables to zero (from g77)." -msgstr "" +msgstr "Ініціалізувати локальні змінні нулем (з g77)." #: fortran/lang.opt:643 #, no-c-format msgid "-finit-logical=\tInitialize local logical variables." -msgstr "" +msgstr "-finit-logical=\tІніціалізувати локальні логічні змінні." #: fortran/lang.opt:647 #, no-c-format msgid "-finit-real=\tInitialize local real variables." -msgstr "" +msgstr "-finit-real=\tІніціалізувати локальні змінні типу дійсне значенням." #: fortran/lang.opt:669 #, no-c-format msgid "-finline-arg-packing\tPerform argument packing inline." -msgstr "" +msgstr "-finline-arg-packing\tВиконувати компактизацію аргументів в рядку." #: fortran/lang.opt:673 #, no-c-format msgid "-finline-matmul-limit=\tSpecify the size of the largest matrix for which matmul will be inlined." -msgstr "" +msgstr "-finline-matmul-limit=\tВказати розмір найбільшої матриці, для якої matmul буде вбудовано." #: fortran/lang.opt:677 #, no-c-format msgid "-fmax-array-constructor=\tMaximum number of objects in an array constructor." -msgstr "" +msgstr "-fmax-array-constructor=\tМаксимальна кількість обʼєктів у конструкторі масиву." #: fortran/lang.opt:681 #, no-c-format msgid "-fmax-identifier-length=\tMaximum identifier length." -msgstr "" +msgstr "-fmax-identifier-length=\tМаксимальна довжина ідентифікатора." #: fortran/lang.opt:685 #, no-c-format msgid "-fmax-subrecord-length=\tMaximum length for subrecords." -msgstr "" +msgstr "-fmax-subrecord-length=\tМаксимальна довжина підзаписів." #: fortran/lang.opt:689 #, no-c-format msgid "-fmax-stack-var-size=\tSize in bytes of the largest array that will be put on the stack." -msgstr "" +msgstr "-fmax-stack-var-size=\tРозмір у байтах найбільшого масиву, який буде поміщений у стек." #: fortran/lang.opt:693 #, no-c-format msgid "Put all local arrays on stack." -msgstr "" +msgstr "Помістити всі локальні масиви у стек." #: fortran/lang.opt:697 #, no-c-format msgid "Set default accessibility of module entities to PRIVATE." -msgstr "" +msgstr "Встановити приватний доступ за замовчуванням для сутностей модуля." #: fortran/lang.opt:717 #, no-c-format msgid "Try to lay out derived types as compactly as possible." -msgstr "" +msgstr "Спробуйте розмістити похідні типи якомога компактніше." #: fortran/lang.opt:725 #, no-c-format msgid "Protect parentheses in expressions." -msgstr "" +msgstr "Захистити дужки в виразах." #: fortran/lang.opt:729 #, no-c-format msgid "Path to header file that should be pre-included before each compilation unit." -msgstr "" +msgstr "Шлях до файлу заголовка, який повинен бути попередньо включений перед кожною одиницею компіляції." #: fortran/lang.opt:733 #, no-c-format msgid "Enable range checking during compilation." -msgstr "" +msgstr "Увімкнути перевірку діапазону під час компіляції." #: fortran/lang.opt:737 #, no-c-format msgid "Interpret any REAL(4) as a REAL(8)." -msgstr "" +msgstr "Інтерпретувати будь-яке REAL(4) як REAL(8)." #: fortran/lang.opt:741 #, no-c-format msgid "Interpret any REAL(4) as a REAL(10)." -msgstr "" +msgstr "Інтерпретувати будь-яке REAL(4) як REAL(10)." #: fortran/lang.opt:745 #, no-c-format msgid "Interpret any REAL(4) as a REAL(16)." -msgstr "" +msgstr "Інтерпретувати будь-яке REAL(4) як REAL(16)." #: fortran/lang.opt:749 #, no-c-format msgid "Interpret any REAL(8) as a REAL(4)." -msgstr "" +msgstr "Інтерпретувати будь-яке REAL(8) як REAL(4)." #: fortran/lang.opt:753 #, no-c-format msgid "Interpret any REAL(8) as a REAL(10)." -msgstr "" +msgstr "Інтерпретувати будь-який REAL(8) як REAL(10)." #: fortran/lang.opt:757 #, no-c-format msgid "Interpret any REAL(8) as a REAL(16)." -msgstr "" +msgstr "Інтерпретувати будь-який REAL(8) як REAL(16)." #: fortran/lang.opt:761 #, no-c-format msgid "Reallocate the LHS in assignments." -msgstr "" +msgstr "Перерозподілити LHS в присвоєннях." #: fortran/lang.opt:765 #, no-c-format msgid "Use a 4-byte record marker for unformatted files." -msgstr "" +msgstr "Використовувати 4-байтовий маркер запису для неформатованих файлів." #: fortran/lang.opt:769 #, no-c-format msgid "Use an 8-byte record marker for unformatted files." -msgstr "" +msgstr "Використовувати 8-байтовий маркер запису для неформатованих файлів." #: fortran/lang.opt:773 #, no-c-format msgid "Allocate local variables on the stack to allow indirect recursion." -msgstr "" +msgstr "Виділяти локальні змінні в стеку для дозволу непрямої рекурсії." #: fortran/lang.opt:777 #, no-c-format msgid "Copy array sections into a contiguous block on procedure entry." -msgstr "" +msgstr "Копіювати секції масиву в послідовний блок при вході в процедуру." #: fortran/lang.opt:781 #, no-c-format msgid "-fcoarray=\tSpecify which coarray parallelization should be used." -msgstr "" +msgstr "-fcoarray=\tВказати, яку паралелізацію coarray слід використовувати." #: fortran/lang.opt:797 #, no-c-format msgid "-fcheck=[...]\tSpecify which runtime checks are to be performed." -msgstr "" +msgstr "-fcheck=[...]\tВказує, які перевірки часу виконання мають бути виконані." #: fortran/lang.opt:801 #, no-c-format msgid "Append a second underscore if the name already contains an underscore." -msgstr "" +msgstr "Додати другу підкреслювання, якщо імʼя вже містить підкреслювання." #: fortran/lang.opt:809 #, no-c-format msgid "Apply negative sign to zero values." -msgstr "" +msgstr "Застосувати відʼємний знак до значень нуля." #: fortran/lang.opt:816 #, no-c-format msgid "Disallow tail call optimization when a calling routine may have omitted character lengths." -msgstr "" +msgstr "Заборонити оптимізацію хвостового виклику, коли викликаюча процедура може пропустити довжини символів." #: fortran/lang.opt:820 #, no-c-format msgid "Append underscores to externally visible names." -msgstr "" +msgstr "Додати підкреслювання до зовнішньо видимих імен." #: fortran/lang.opt:824 c-family/c.opt:1664 c-family/c.opt:1741 #: c-family/c.opt:1749 c-family/c.opt:2068 config/pa/pa.opt:46 @@ -1143,437 +1141,437 @@ msgstr "" #: common.opt:3440 common.opt:3444 #, no-c-format msgid "Does nothing. Preserved for backward compatibility." -msgstr "" +msgstr "Нічого не робить. Зберігається для забезпечення сумісності з попередніми версіями." #: fortran/lang.opt:864 #, no-c-format msgid "Statically link the GNU Fortran helper library (libgfortran)." -msgstr "" +msgstr "Статично звʼязати допоміжну бібліотеку GNU Fortran (libgfortran)." #: fortran/lang.opt:868 #, no-c-format msgid "Statically link the GCC Quad-Precision Math Library (libquadmath)." -msgstr "" +msgstr "Статично звʼязати бібліотеку математики з подвійною точністю GCC (libquadmath)." #: fortran/lang.opt:872 #, no-c-format msgid "Conform to the ISO Fortran 2003 standard." -msgstr "" +msgstr "Відповідати стандарту ISO Fortran 2003." #: fortran/lang.opt:876 #, no-c-format msgid "Conform to the ISO Fortran 2008 standard." -msgstr "" +msgstr "Відповідати стандарту ISO Fortran 2008." #: fortran/lang.opt:880 #, no-c-format msgid "Conform to the ISO Fortran 2008 standard including TS 29113." -msgstr "" +msgstr "Відповідати стандарту ISO Fortran 2008, включаючи TS 29113." #: fortran/lang.opt:884 #, no-c-format msgid "Conform to the ISO Fortran 2018 standard." -msgstr "" +msgstr "Відповідати стандарту ISO Fortran 2018." #: fortran/lang.opt:888 #, no-c-format msgid "Conform to the ISO Fortran 95 standard." -msgstr "" +msgstr "Відповідати стандарту ISO Fortran 95." #: fortran/lang.opt:892 #, no-c-format msgid "Conform to nothing in particular." -msgstr "" +msgstr "Не відповідати нічому конкретному." #: fortran/lang.opt:896 #, no-c-format msgid "Accept extensions to support legacy code." -msgstr "" +msgstr "Приймати розширення для підтримки старого коду." #: rust/lang.opt:47 rust/lang.opt:51 c-family/c.opt:1407 c-family/c.opt:1411 #, no-c-format msgid "Warn when a const variable is unused." -msgstr "" +msgstr "Попереджати, коли невикористовується константна змінна." #: rust/lang.opt:55 c-family/c.opt:1399 #, no-c-format msgid "Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value." -msgstr "" +msgstr "Попереджати, якщо викликач функції, позначеної атрибутом warn_unused_result, не використовує її повернене значення." #: rust/lang.opt:59 #, no-c-format msgid "-frust-crate= Set the crate name for the compilation" -msgstr "" +msgstr "-frust-crate=<імʼя> Встановити назву криївки (crate) для компіляції" #: rust/lang.opt:63 #, no-c-format msgid "Dump various Rust front end internals." -msgstr "" +msgstr "Вивести різні внутрішні елементи передньої частини Rust." #: rust/lang.opt:67 #, no-c-format msgid "-frust-dump-\tDump Rust frontend internal information." -msgstr "" +msgstr "-frust-dump-<тип>\tВивести внутрішню інформацію передньої частини Rust." #: rust/lang.opt:71 #, no-c-format msgid "Enable experimental compilation of Rust files at your own risk" -msgstr "" +msgstr "Увімкнути експериментальну компіляцію файлів Rust на власний ризик" #: rust/lang.opt:75 #, no-c-format msgid "-frust-max-recursion-depth=integer" -msgstr "" +msgstr "-frust-max-recursion-depth=ціле" #: rust/lang.opt:79 #, no-c-format msgid "-frust-mangling=[legacy|v0] Choose which version to use for name mangling" -msgstr "" +msgstr "-frust-mangling=[legacy|v0] Виберіть, яку версію використовувати для декорування імен" #: rust/lang.opt:92 #, no-c-format msgid "-frust-cfg= Set a config expansion option" -msgstr "" +msgstr "-frust-cfg=<імʼя> Встановити параметр розширення конфігурації" #: rust/lang.opt:96 #, no-c-format msgid "-frust-edition=[2015|2018|2021] Choose which edition to use when compiling rust code" -msgstr "" +msgstr "-frust-edition=[2015|2018|2021] Виберіть, яку редакцію використовувати при компіляції коду rust" #: rust/lang.opt:112 #, no-c-format msgid "Flag to enable embeding metadata directly into object files" -msgstr "" +msgstr "Прапорець для включення метаданих безпосередньо в обʼєктні файли" #: rust/lang.opt:116 #, no-c-format msgid "-frust-metadata-output= Path to output crate metadata" -msgstr "" +msgstr "-frust-metadata-output=<шлях.rox> Шлях до вихідних метаданих ящика" #: rust/lang.opt:124 #, no-c-format msgid "-frust-compile-until=[ast|attributecheck|expansion|nameresolution|lowering|typecheck|privacy|unsafety|const|copimlation|end] When to stop in the pipeline when compiling Rust code" -msgstr "" +msgstr "-frust-compile-until=[ast|attributecheck|expansion|nameresolution|lowering|typecheck|privacy|unsafety|const|copimlation|end] Коли зупинитися в конвеєрі під час компіляції коду Rust" #: c-family/c.opt:182 #, no-c-format msgid "-A=\tAssert the to . Putting '-' before disables the to ." -msgstr "" +msgstr "-A<питання>=<відповідь>\tПеревірити <відповідь> на <питання>. Поставлення '-' перед <питання> вимикає <відповідь> на <питання>." #: c-family/c.opt:186 #, no-c-format msgid "Do not discard comments." -msgstr "" +msgstr "Не викидайте коментарі." #: c-family/c.opt:190 #, no-c-format msgid "Do not discard comments in macro expansions." -msgstr "" +msgstr "Не викидайте коментарі в розширеннях макросів." #: c-family/c.opt:194 #, no-c-format msgid "-D[=]\tDefine a with as its value. If just is given, is taken to be 1." -msgstr "" +msgstr "-D<макро>[=<значення>]\tВизначити <макро> зі значенням <значення>. Якщо задано лише <макро>, <значення> вважається 1." #: c-family/c.opt:201 #, no-c-format msgid "-F \tAdd to the end of the main framework include path." -msgstr "" +msgstr "-F <каталог>\tДодати <каталог> в кінець основного шляху включення фреймворку." #: c-family/c.opt:205 #, no-c-format msgid "Enable parsing GIMPLE." -msgstr "" +msgstr "Увімкнути аналіз GIMPLE." #: c-family/c.opt:209 #, no-c-format msgid "Print the name of header files as they are used." -msgstr "" +msgstr "Виводить назви файлів заголовків при їх використанні." #: c-family/c.opt:213 #, no-c-format msgid "-I \tAdd to the end of the main include path." -msgstr "" +msgstr "-I <каталог>\tДодати <каталог> в кінець основного шляху включення." #: c-family/c.opt:217 #, no-c-format msgid "Generate make dependencies." -msgstr "" +msgstr "Генерувати залежності для make." #: c-family/c.opt:221 #, no-c-format msgid "Generate make dependencies and compile." -msgstr "" +msgstr "Генерувати залежності для make та компілювати." #: c-family/c.opt:225 #, no-c-format msgid "-MF \tWrite dependency output to the given file." -msgstr "" +msgstr "-MF <файл>\tЗаписати вихідні дані залежностей у вказаний файл." #: c-family/c.opt:229 #, no-c-format msgid "Treat missing header files as generated files." -msgstr "" +msgstr "Трактувати відсутні файли заголовків як згенеровані файли." #: c-family/c.opt:233 #, no-c-format msgid "Like -M but ignore system header files." -msgstr "" +msgstr "Подібно до -M, але ігнорує системні файли заголовків." #: c-family/c.opt:237 #, no-c-format msgid "Like -MD but ignore system header files." -msgstr "" +msgstr "Подібно до -MD, але ігнорує системні файли заголовків." #: c-family/c.opt:241 #, no-c-format msgid "Generate C++ Module dependency information." -msgstr "" +msgstr "Генерувати інформацію про залежності модулів C++." #: c-family/c.opt:249 #, no-c-format msgid "Generate phony targets for all headers." -msgstr "" +msgstr "Генерувати фальшиві цілі для всіх заголовків." #: c-family/c.opt:253 #, no-c-format msgid "-MQ \tAdd a target that may require quoting." -msgstr "" +msgstr "-MQ <ціль>\tДодати ціль, яка може вимагати цитування." #: c-family/c.opt:257 #, no-c-format msgid "-MT \tAdd a target that does not require quoting." -msgstr "" +msgstr "-MT <ціль>\tДодати ціль, яка не вимагає цитування." #: c-family/c.opt:261 #, no-c-format msgid "Do not generate #line directives." -msgstr "" +msgstr "Не генерувати директиви #line." #: c-family/c.opt:265 #, no-c-format msgid "-U\tUndefine ." -msgstr "" +msgstr "-U<макро>\tСкасувати визначення <макро>." #: c-family/c.opt:269 #, no-c-format msgid "Warn if the NSObject attribute is applied to a non-typedef." -msgstr "" +msgstr "Попереджати, якщо атрибут NSObject застосовується до не typedef." #: c-family/c.opt:273 #, no-c-format msgid "Warn about things that will change when compiling with an ABI-compliant compiler." -msgstr "" +msgstr "Попереджати про зміни, які відбудуться при компіляції з сумісним з ABI компілятором." #: c-family/c.opt:277 #, no-c-format msgid "Warn about things that change between the current -fabi-version and the specified version." -msgstr "" +msgstr "Попереджати про зміни, які відбуваються між поточною -fabi-версією та вказаною версією." #: c-family/c.opt:281 #, no-c-format msgid "Warn if a subobject has an abi_tag attribute that the complete object type does not have." -msgstr "" +msgstr "Попереджати, якщо підобʼєкт має атрибут abi_tag, якого немає в повному типі обʼєкта." #: c-family/c.opt:288 #, no-c-format msgid "Warn on suspicious calls of standard functions computing absolute values." -msgstr "" +msgstr "Попереджати про підозрілі виклики стандартних функцій, що обчислюють абсолютні значення." #: c-family/c.opt:292 #, no-c-format msgid "Warn about suspicious uses of memory addresses." -msgstr "" +msgstr "Попереджати про підозріле використання адрес памʼяті." #: c-family/c.opt:308 #, no-c-format msgid "Warn about 'new' of type with extended alignment without -faligned-new." -msgstr "" +msgstr "Попереджати про «new» типу з розширеним вирівнюванням без -faligned-new." #: c-family/c.opt:312 #, no-c-format msgid "-Waligned-new=[none|global|all]\tWarn even if 'new' uses a class member allocation function." -msgstr "" +msgstr "-Waligned-new=[none|global|all]\tПопереджати навіть якщо «new» використовує функцію виділення члена класу." #: c-family/c.opt:316 ada/gcc-interface/lang.opt:57 #, no-c-format msgid "Enable most warning messages." -msgstr "Увімкнути якнайбільше повідомлень із попередженнями." +msgstr "Увімкнути більшість повідомлень про попередження." #: c-family/c.opt:320 #, no-c-format msgid "Warn on any use of alloca." -msgstr "Попереджати про усі використання alloca." +msgstr "Попереджати про будь-яке використання alloca." #: c-family/c.opt:324 #, no-c-format msgid "-Walloc-size-larger-than=\tWarn for calls to allocation functions that attempt to allocate objects larger than the specified number of bytes." -msgstr "" +msgstr "-Walloc-size-larger-than=<байтів>\tПопереджати про виклики функцій виділення памʼяті, які намагаються виділити обʼєкти, розмір яких більший за вказану кількість байтів." #: c-family/c.opt:329 #, no-c-format msgid "Disable Walloc-size-larger-than= warning. Equivalent to Walloc-size-larger-than= or larger." -msgstr "" +msgstr "Вимкнути попередження Walloc-size-larger-than=. Еквівалентно Walloc-size-larger-than= або більше." #: c-family/c.opt:333 #, no-c-format msgid "Warn for calls to allocation functions that specify zero bytes." -msgstr "" +msgstr "Попереджувати про виклики функцій виділення памʼяті, які вказують нульові байти." #: c-family/c.opt:337 #, no-c-format msgid "-Walloca-larger-than=\tWarn on unbounded uses of alloca, and on bounded uses of alloca whose bound can be larger than bytes." -msgstr "" +msgstr "-Walloca-larger-than=<число>\tПопереджувати про необмежене використання alloca та про обмежене використання alloca, обмеження якого може бути більше <число> байтів." #: c-family/c.opt:343 #, no-c-format msgid "Disable Walloca-larger-than= warning. Equivalent to Walloca-larger-than= or larger." -msgstr "" +msgstr "Вимкнути попередження Walloca-larger-than=. Еквівалентно Walloca-larger-than= або більше." #: c-family/c.opt:351 #, no-c-format msgid "Warn about comparisons between two operands of array type." -msgstr "Попереджати про порівняння між двома операндами типу масивів." +msgstr "Попереджати про порівняння між двома операндами типу масив." #: c-family/c.opt:355 c-family/c.opt:359 #, no-c-format msgid "Warn about mismatched declarations of array parameters and unsafe accesses to them." -msgstr "" +msgstr "Попереджувати про несумісні декларації параметрів масиву та небезпечний доступ до них." #: c-family/c.opt:363 #, no-c-format msgid "Warn about accesses to interior zero-length array members." -msgstr "" +msgstr "Попереджувати про доступ до внутрішніх елементів масиву нульової довжини." #: c-family/c.opt:367 #, no-c-format msgid "Warn whenever an Objective-C assignment is being intercepted by the garbage collector." -msgstr "" +msgstr "Попереджувати, коли присвоєння Objective-C перехоплюється збирачем сміття." #: c-family/c.opt:371 #, no-c-format msgid "Warn about casting functions to incompatible types." -msgstr "Попереджати про виклик функцій із несумісними типами параметрів." +msgstr "Попереджувати про приведення типів функцій до несумісних типів." #: c-family/c.opt:379 #, no-c-format msgid "-Wbidi-chars=[none|unpaired|any|ucn] Warn about UTF-8 bidirectional control characters." -msgstr "" +msgstr "-Wbidi-chars=[none|unpaired|any|ucn] Попереджувати про управляючі символи UTF-8 з бідирекційним керуванням." #: c-family/c.opt:402 #, no-c-format msgid "Warn about boolean expression compared with an integer value different from true/false." -msgstr "" +msgstr "Попереджати, коли булевий вираз порівнюється з цілочисельним значенням, відмінним від true/false." #: c-family/c.opt:406 #, no-c-format msgid "Warn about certain operations on boolean expressions." -msgstr "Попереджати щодо певних дій із булевими виразами." +msgstr "Попереджувати про певні операції над булевими виразами." #: c-family/c.opt:410 #, no-c-format msgid "Warn when __builtin_frame_address or __builtin_return_address is used unsafely." -msgstr "" +msgstr "Попереджувати, коли __builtin_frame_address або __builtin_return_address використовуються небезпечно." #: c-family/c.opt:414 #, no-c-format msgid "Warn when a built-in function is declared with the wrong signature." -msgstr "" +msgstr "Попереджувати, коли вбудована функція оголошується з неправильною сигнатурою." #: c-family/c.opt:418 #, no-c-format msgid "Warn when a built-in preprocessor macro is undefined or redefined." -msgstr "" +msgstr "Попереджувати, коли вбудований макрос препроцесора не визначений або перевизначений." #: c-family/c.opt:422 #, no-c-format msgid "Warn about features not present in ISO C11, but present in ISO C2X." -msgstr "" +msgstr "Попереджувати про функції, які відсутні в ISO C11, але присутні в ISO C2X." #: c-family/c.opt:426 #, no-c-format msgid "Warn about features not present in ISO C90, but present in ISO C99." -msgstr "" +msgstr "Попереджувати про функції, які відсутні в ISO C90, але присутні в ISO C99." #: c-family/c.opt:430 #, no-c-format msgid "Warn about features not present in ISO C99, but present in ISO C11." -msgstr "" +msgstr "Попереджувати про функції, які відсутні в ISO C99, але присутні в ISO C11." #: c-family/c.opt:434 #, no-c-format msgid "Warn about C constructs that are not in the common subset of C and C++." -msgstr "" +msgstr "Попереджувати про конструкції C, які не належать до спільної підмножини C і C++." #: c-family/c.opt:441 #, no-c-format msgid "Warn about C++ constructs whose meaning differs between ISO C++ 1998 and ISO C++ 2011." -msgstr "" +msgstr "Попереджувати про конструкції C++, значення яких відрізняється між ISO C++ 1998 і ISO C++ 2011." #: c-family/c.opt:445 #, no-c-format msgid "Warn about C++ constructs whose meaning differs between ISO C++ 2011 and ISO C++ 2014." -msgstr "" +msgstr "Попереджувати про конструкції C++, значення яких відрізняється між ISO C++ 2011 і ISO C++ 2014." #: c-family/c.opt:452 #, no-c-format msgid "Warn about C++ constructs whose meaning differs between ISO C++ 2014 and ISO C++ 2017." -msgstr "" +msgstr "Попереджувати про конструкції C++, значення яких відрізняється між ISO C++ 2014 і ISO C++ 2017." #: c-family/c.opt:459 #, no-c-format msgid "Warn about C++ constructs whose meaning differs between ISO C++ 2017 and ISO C++ 2020." -msgstr "" +msgstr "Попереджувати про конструкції C++, значення яких відрізняється між ISO C++ 2017 і ISO C++ 2020." #: c-family/c.opt:463 #, no-c-format msgid "Warn about C++11 constructs in code compiled with an older standard." -msgstr "" +msgstr "Попереджувати про конструкції C++11 у коді, скомпільованому застарілим стандартом." #: c-family/c.opt:467 #, no-c-format msgid "Warn about C++14 constructs in code compiled with an older standard." -msgstr "" +msgstr "Попереджувати про використання конструкцій C++14 у коді, скомпільованому зі старішим стандартом." #: c-family/c.opt:471 #, no-c-format msgid "Warn about C++17 constructs in code compiled with an older standard." -msgstr "" +msgstr "Попереджувати про використання конструкцій C++17 у коді, скомпільованому зі старішим стандартом." #: c-family/c.opt:475 #, no-c-format msgid "Warn about C++20 constructs in code compiled with an older standard." -msgstr "" +msgstr "Попереджувати про використання конструкцій C++20 у коді, скомпільованому зі старішим стандартом." #: c-family/c.opt:479 #, no-c-format msgid "Warn about C++23 constructs in code compiled with an older standard." -msgstr "" +msgstr "Попереджувати про використання конструкцій C++23 у коді, скомпільованому зі старішим стандартом." #: c-family/c.opt:483 #, no-c-format msgid "Warn about casts between incompatible function types." -msgstr "Попереджати про варіанти виклику функцій несумісних типів." +msgstr "Попереджувати про приведення між несумісними типами функцій." #: c-family/c.opt:487 #, no-c-format msgid "Warn about casts which discard qualifiers." -msgstr "" +msgstr "Попереджувати про приведення, які відкидають кваліфікатори." #: c-family/c.opt:491 c-family/c.opt:495 #, no-c-format msgid "Warn about catch handlers of non-reference type." -msgstr "Попереджати про обробники catch нееталонного типу." +msgstr "Попереджувати про обробники catch, які не є посиланнями." #: c-family/c.opt:499 #, no-c-format msgid "Complain about a name being declared as a class member after a previous use of the same name." -msgstr "" +msgstr "Скаржитися на те, що імʼя оголошено як член класу після попереднього використання того самого імені." #: c-family/c.opt:503 #, no-c-format msgid "Warn about subscripts whose type is \"char\"." -msgstr "" +msgstr "Попереджати про підскрипти, тип яких є «char»." #: c-family/c.opt:507 c-family/c.opt:1561 c-family/c.opt:1565 #: c-family/c.opt:1569 c-family/c.opt:1573 c-family/c.opt:1577 @@ -1585,243 +1583,242 @@ msgstr "" #: config/i386/i386.opt:999 #, no-c-format msgid "Removed in GCC 9. This switch has no effect." -msgstr "" +msgstr "Вилучено в GCC 9. Цей перемикач не має ефекту." #: c-family/c.opt:511 #, no-c-format msgid "Warn about variables that might be changed by \"longjmp\" or \"vfork\"." -msgstr "" +msgstr "Попереджувати про зміну змінних за допомогою «longjmp» або «vfork»." #: c-family/c.opt:515 #, no-c-format msgid "Warn about uses of a comma operator within a subscripting expression." -msgstr "" +msgstr "Попереджувати про використання оператора коми в межах виразу підскриптування." #: c-family/c.opt:519 #, no-c-format msgid "Warn about possibly nested block comments, and C++ comments spanning more than one physical line." -msgstr "" +msgstr "Попереджувати про можливі вкладені блокові коментарі та коментарі C++, що охоплюють більше однієї фізичної лінії." #: c-family/c.opt:523 #, no-c-format msgid "Synonym for -Wcomment." -msgstr "Синонім -Wcomment." +msgstr "Синонім для -Wcomment." #: c-family/c.opt:527 #, no-c-format msgid "Warn for conditionally-supported constructs." -msgstr "" +msgstr "Попереджувати про умовно підтримувані конструкції." #: c-family/c.opt:531 #, no-c-format msgid "Warn for implicit type conversions that may change a value." -msgstr "Попереджати про неявні перетворення типів, які можуть призвести до зміни значення." +msgstr "Попереджувати про неявні типові перетворення, які можуть змінити значення." #: c-family/c.opt:535 #, no-c-format msgid "Warn for converting NULL from/to a non-pointer type." -msgstr "" +msgstr "Попереджувати про перетворення NULL з/на тип, який не є вказівником." #: c-family/c.opt:543 #, no-c-format msgid "Warn when performing class template argument deduction on a type with no deduction guides." -msgstr "" +msgstr "Попереджувати, коли виконується виведення аргументів шаблону класу для типу без посібників з виведення." #: c-family/c.opt:548 #, no-c-format msgid "Warn when all constructors and destructors are private." -msgstr "Попереджати, якщо усі конструктори і деструктори є закритими (private)." +msgstr "Попереджати, коли всі конструктори та деструктори є приватними." #: c-family/c.opt:552 #, no-c-format msgid "Warn about dangling else." -msgstr "" +msgstr "Попереджати про незакріплене else." #: c-family/c.opt:556 c-family/c.opt:560 #, no-c-format msgid "Warn for uses of pointers to auto variables whose lifetime has ended." -msgstr "" +msgstr "Попереджати про використання вказівників на автоматичні змінні, чий термін життя завершився." #: c-family/c.opt:564 #, no-c-format msgid "Warn when a reference is bound to a temporary whose lifetime has ended." -msgstr "" +msgstr "Попереджати, коли посилання звʼязане з тимчасовим обʼєктом, чий термін життя завершився." #: c-family/c.opt:568 #, no-c-format msgid "Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage." -msgstr "" +msgstr "Попереджати про використання __TIME__, __DATE__ і __TIMESTAMP__." #: c-family/c.opt:572 #, no-c-format msgid "Warn when a declaration is found after a statement." -msgstr "Попереджати, якщо оголошення виявлено після інструкції." +msgstr "Попереджати, коли після оператора знайдено оголошення." #: c-family/c.opt:576 #, no-c-format msgid "Warn when deleting a pointer to incomplete type." -msgstr "Попереджати щодо вилучення вказівника на неповний тип." +msgstr "Попереджати, коли видаляється вказівник на неповний тип." #: c-family/c.opt:580 #, no-c-format msgid "Warn about deleting polymorphic objects with non-virtual destructors." -msgstr "" +msgstr "Попереджати про видалення поліморфних обʼєктів з невіртуальними деструкторами." #: c-family/c.opt:588 #, no-c-format msgid "Mark implicitly-declared copy operations as deprecated if the class has a user-provided copy operation." -msgstr "" +msgstr "Позначати неявно оголошені операції копіювання як застарілі, якщо клас має користувацьку операцію копіювання." #: c-family/c.opt:593 #, no-c-format msgid "Mark implicitly-declared copy operations as deprecated if the class has a user-provided copy operation or destructor." -msgstr "" +msgstr "Позначати неявно оголошені операції копіювання як застарілі, якщо у класі є користувацька операція копіювання або деструктор." #: c-family/c.opt:598 #, no-c-format msgid "Warn about deprecated arithmetic conversions on operands of enumeration types." -msgstr "Попереджати про застарілі арифметичні перетворення операндів нумерованих типів." +msgstr "Попереджати про застарілі арифметичні перетворення операндів перелічування." #: c-family/c.opt:602 #, no-c-format msgid "Warn about deprecated arithmetic conversions on operands where one is of enumeration type and the other is of a floating-point type." -msgstr "" +msgstr "Попереджувати про застарілі арифметичні перетворення операндів, де один є перелічуванням, а інший - числом з рухомою комою." #: c-family/c.opt:607 #, no-c-format msgid "Warn about positional initialization of structs requiring designated initializers." -msgstr "" +msgstr "Попереджувати про позиційну ініціалізацію структур, яка вимагає призначених ініціалізаторів." #: c-family/c.opt:611 #, no-c-format msgid "Warn if qualifiers on arrays which are pointer targets are discarded." -msgstr "" +msgstr "Попереджувати, якщо відкидаються кваліфікатори масивів, які є цілями вказівників." #: c-family/c.opt:615 #, no-c-format msgid "Warn if type qualifiers on pointers are discarded." -msgstr "" +msgstr "Попереджувати, якщо відкидаються кваліфікатори типу на вказівниках." #: c-family/c.opt:619 #, no-c-format msgid "Warn about compile-time integer division by zero." -msgstr "" +msgstr "Попереджати про цілочисельне ділення на нуль на етапі компіляції." #: c-family/c.opt:623 #, no-c-format msgid "Warn about duplicated branches in if-else statements." -msgstr "Попереджати про дублювання гілок у інструкціях if-else." +msgstr "Попереджувати про дубльовані гілки в умовних операторах if-else." #: c-family/c.opt:627 #, no-c-format msgid "Warn about duplicated conditions in an if-else-if chain." -msgstr "Попереджати про дублювання умов у ланцюжку if-else-if." +msgstr "Попереджувати про дубльовані умови в ланцюжку if-else-if." #: c-family/c.opt:631 #, no-c-format msgid "Warn about violations of Effective C++ style rules." -msgstr "Попереджати про порушення правил стилю Effective C++." +msgstr "Попереджувати про порушення правил стилю Effective C++." #: c-family/c.opt:635 #, no-c-format msgid "Warn about an empty body in an if or else statement." -msgstr "Попереджати щодо порожнього комплекту інструкцій у if або else." +msgstr "Попереджувати про порожнє тіло в операторі if або else." #: c-family/c.opt:639 #, no-c-format msgid "Warn about stray tokens after #else and #endif." -msgstr "" +msgstr "Попереджувати про зайві токени після #else та #endif." #: c-family/c.opt:643 #, no-c-format msgid "Warn about comparison of different enum types." -msgstr "Попереджати про порівняння різних типів числових даних." +msgstr "Попереджувати про порівняння різних типів перелічувань." #: c-family/c.opt:647 #, no-c-format msgid "Warn about implicit conversion of enum types." -msgstr "" +msgstr "Попереджувати про неявне перетворення типів перелічувань." #: c-family/c.opt:651 -#, fuzzy, no-c-format -#| msgid "Warn about using variadic macros." +#, no-c-format msgid "Warn about enum/integer type mismatches." -msgstr "Попереджати про використання варіативних макросів." +msgstr "Попереджувати про несумісність типів перелічувань/цілочисельних." #: c-family/c.opt:659 #, no-c-format msgid "This switch is deprecated; use -Werror=implicit-function-declaration instead." -msgstr "Цей перемикач вважається застарілим; скористайтеся замість нього перемикачем -Werror=implicit-function-declaration." +msgstr "Цей ключ застарів; використовуйте -Werror=implicit-function-declaration замість нього." #: c-family/c.opt:663 #, no-c-format msgid "Warn when an exception handler is shadowed by another handler." -msgstr "" +msgstr "Попереджувати, коли обробник виключення прихований іншим обробником." #: c-family/c.opt:671 #, no-c-format msgid "Warn about semicolon after in-class function definition." -msgstr "Попереджати про крапку з комою після визначення функції у класі." +msgstr "Попереджувати про крапку з комою після визначення функції в класі." #: c-family/c.opt:675 #, no-c-format msgid "Warn for implicit type conversions that cause loss of floating point precision." -msgstr "" +msgstr "Попереджувати про неявні типові перетворення, які призводять до втрати точності дробових чисел." #: c-family/c.opt:679 #, no-c-format msgid "Warn if testing floating point numbers for equality." -msgstr "Попереджати про перевірки на рівність чисел із рухомою крапкою." +msgstr "Попереджувати, якщо тестування дробових чисел на рівність." #: c-family/c.opt:683 c-family/c.opt:729 #, no-c-format msgid "Warn about printf/scanf/strftime/strfmon format string anomalies." -msgstr "Попереджати про некоректності у рядках форматування printf/scanf/strftime/strfmon." +msgstr "Попереджувати про аномалії у форматних рядках printf/scanf/strftime/strfmon." #: c-family/c.opt:687 #, no-c-format msgid "Warn about format strings that contain NUL bytes." -msgstr "Попереджати щодо рядків форматування, які містять байти NUL." +msgstr "Попереджувати про форматні рядки, що містять NUL-байти." #: c-family/c.opt:691 #, no-c-format msgid "Warn about GCC format strings with strings unsuitable for diagnostics." -msgstr "" +msgstr "Попереджувати про форматні рядки GCC з рядками, що не підходять для діагностики." #: c-family/c.opt:695 #, no-c-format msgid "Warn if passing too many arguments to a function for its format string." -msgstr "" +msgstr "Попереджати, якщо передається забагато аргументів у функцію для її рядка форматування." #: c-family/c.opt:699 #, no-c-format msgid "Warn about format strings that are not literals." -msgstr "Попереджати, якщо рядки форматування не є літералами." +msgstr "Попереджати про рядки форматування, які не є літералами." #: c-family/c.opt:703 #, no-c-format msgid "Warn about function calls with format strings that write past the end of the destination region. Same as -Wformat-overflow=1." -msgstr "" +msgstr "Попереджати про виклики функцій з рядками форматування, які записують за межі кінця цільової області. Те саме, що й -Wformat-overflow=1." #: c-family/c.opt:708 #, no-c-format msgid "Warn about possible security problems with format functions." -msgstr "" +msgstr "Попереджати про можливі проблеми безпеки з функціями форматування." #: c-family/c.opt:712 #, no-c-format msgid "Warn about sign differences with format functions." -msgstr "Попереджати про відмінності у знаку у функціях форматування." +msgstr "Попереджувати про різницю знаків у функціях форматування." #: c-family/c.opt:716 #, no-c-format msgid "Warn about calls to snprintf and similar functions that truncate output. Same as -Wformat-truncation=1." -msgstr "" +msgstr "Попереджати про виклики функцій snprintf та подібних, які обрізають вивід. Те саме, що й -Wformat-truncation=1." #: c-family/c.opt:721 #, no-c-format msgid "Warn about strftime formats yielding 2-digit years." -msgstr "" +msgstr "Попереджувати про формати strftime, які дають двозначні роки." #: c-family/c.opt:725 #, no-c-format @@ -1831,824 +1828,822 @@ msgstr "Попереджати про формати нульової довжи #: c-family/c.opt:733 #, no-c-format msgid "Warn about function calls with format strings that write past the end of the destination region." -msgstr "" +msgstr "Попереджати про виклики функцій з рядками формату, які записують за межі кінця цільової області." #: c-family/c.opt:738 #, no-c-format msgid "Warn about calls to snprintf and similar functions that truncate output." -msgstr "" +msgstr "Попереджувати про виклики функцій snprintf та подібних, які обрізають вивід." #: c-family/c.opt:742 #, no-c-format msgid "Warn when the field in a struct is not aligned." -msgstr "Попереджати про невирівняне поле у структурі." +msgstr "Попереджати, коли поле в структурі не вирівняне." #: c-family/c.opt:746 #, no-c-format msgid "Warn whenever type qualifiers are ignored." -msgstr "" +msgstr "Попереджати, коли ігноруються кваліфікатори типу." #: c-family/c.opt:750 #, no-c-format msgid "Warn whenever attributes are ignored." -msgstr "Попереджати про ігнорування атрибутів." +msgstr "Попереджати, коли ігноруються атрибути." #: c-family/c.opt:754 #, no-c-format msgid "Warn when a base is inaccessible in derived due to ambiguity." -msgstr "" +msgstr "Попереджувати, коли база недоступна в похідному класі через неоднозначність." #: c-family/c.opt:758 #, no-c-format msgid "Warn when there is a conversion between pointers that have incompatible types." -msgstr "" +msgstr "Попереджувати про конвертацію між вказівниками, які мають несумісні типи." #: c-family/c.opt:762 common.opt:650 #, no-c-format msgid "Warn for infinitely recursive calls." -msgstr "" +msgstr "Попереджувати про нескінченні рекурсивні виклики." #: c-family/c.opt:766 #, no-c-format msgid "Warn when the address of packed member of struct or union is taken." -msgstr "" +msgstr "Попереджувати, коли береться адреса упакованого члена структури або обʼєднання." #: c-family/c.opt:770 #, no-c-format msgid "Warn about variables which are initialized to themselves." -msgstr "Попереджати про самоініціалізацію змінних." +msgstr "Попереджувати про змінні, які ініціалізуються самими собою." #: c-family/c.opt:774 #, no-c-format msgid "Warn about uses of std::initializer_list that can result in dangling pointers." -msgstr "" +msgstr "Попереджувати про використання std::initializer_list, що може призвести до висячих вказівників." #: c-family/c.opt:778 #, no-c-format msgid "Warn about nonsensical values of --param destructive-interference-size or constructive-interference-size." -msgstr "" +msgstr "Попереджувати про нерозумні значення параметрів --param destructive-interference-size або constructive-interference-size." #: c-family/c.opt:783 #, no-c-format msgid "Warn about implicit declarations." -msgstr "Попереджати про неявні оголошення." +msgstr "Попереджувати про неявні оголошення." #: c-family/c.opt:791 #, no-c-format msgid "Warn about implicit conversions from \"float\" to \"double\"." -msgstr "Попереджати про неявні перетворення з float на double." +msgstr "Попереджувати про неявні перетворення з «float» на «double»." #: c-family/c.opt:795 #, no-c-format msgid "Warn if \"defined\" is used outside #if." -msgstr "Попереджати, якщо defined використано поза #if." +msgstr "Попереджувати, якщо «defined» використовується поза #if." #: c-family/c.opt:799 #, no-c-format msgid "Warn about implicit function declarations." -msgstr "Попереджати про неявні оголошення функцій." +msgstr "Попереджувати про неявні оголошення функцій." #: c-family/c.opt:803 #, no-c-format msgid "Warn when a declaration does not specify a type." -msgstr "Попереджати, якщо оголошення не визначає типу." +msgstr "Попереджувати, коли оголошення не вказує тип." #: c-family/c.opt:810 #, no-c-format msgid "Warn about C++11 inheriting constructors when the base has a variadic constructor." -msgstr "" +msgstr "Попереджувати про успадкування конструкторів C++11, коли базовий клас має варіативний конструктор." #: c-family/c.opt:814 #, no-c-format msgid "Warn about incompatible integer to pointer and pointer to integer conversions." -msgstr "" +msgstr "Попереджувати про несумісні перетворення між цілими числами та вказівниками." #: c-family/c.opt:818 #, no-c-format msgid "Warn for suspicious integer expressions in boolean context." -msgstr "" +msgstr "Попереджувати про підозрілі цілочисельні вирази в булевому контексті." #: c-family/c.opt:822 #, no-c-format msgid "Warn when there is a cast to a pointer from an integer of a different size." -msgstr "" +msgstr "Попереджувати, коли відбувається приведення до вказівника з цілого числа іншого розміру." #: c-family/c.opt:826 -#, fuzzy, no-c-format -#| msgid "statement is not a constant expression" +#, no-c-format msgid "Warn when a function never produces a constant expression." -msgstr "інструкція не є сталим виразом" +msgstr "Попереджувати, коли функція ніколи не повертає константний вираз." #: c-family/c.opt:830 #, no-c-format msgid "Warn about invalid uses of the \"offsetof\" macro." -msgstr "" +msgstr "Попереджувати про неправильне використання макросу «offsetof»." #: c-family/c.opt:834 #, no-c-format msgid "Warn about PCH files that are found but not used." -msgstr "" +msgstr "Попереджувати про PCH-файли, які знайдено, але не використовуються." #: c-family/c.opt:838 -#, fuzzy, no-c-format -#| msgid "Warn about using variadic macros." +#, no-c-format msgid "Warn about invalid UTF-8 characters." -msgstr "Попереджати про використання варіативних макросів." +msgstr "Попереджувати про неправильні символи UTF-8." #: c-family/c.opt:842 #, no-c-format msgid "Warn when a jump misses a variable initialization." -msgstr "" +msgstr "Попереджувати, коли при стрибку пропускається ініціалізація змінної." #: c-family/c.opt:846 #, no-c-format msgid "Warn when a string or character literal is followed by a ud-suffix which does not begin with an underscore." -msgstr "" +msgstr "Попереджувати, коли за рядком або символьним літералом слідує суфікс ud, який не починається з підкреслення." #: c-family/c.opt:850 #, no-c-format msgid "Warn when a logical operator is suspiciously always evaluating to true or false." -msgstr "" +msgstr "Попереджати, коли логічний оператор підозріло завжди оцінюється як true або false." #: c-family/c.opt:854 #, no-c-format msgid "Warn when logical not is used on the left hand side operand of a comparison." -msgstr "" +msgstr "Попереджувати, коли логічне заперечення використовується на лівому операнді порівняння." #: c-family/c.opt:858 #, no-c-format msgid "Do not warn about using \"long long\" when -pedantic." -msgstr "" +msgstr "Не попереджувати про використання «long long» при -pedantic." #: c-family/c.opt:862 #, no-c-format msgid "Warn about suspicious declarations of \"main\"." -msgstr "" +msgstr "Попереджувати про підозрілі оголошення «main»." #: c-family/c.opt:870 #, no-c-format msgid "Warn about suspicious calls to memset where the third argument is constant literal zero and the second is not." -msgstr "" +msgstr "Попереджувати про підозрілі виклики memset, де третій аргумент є константним літералом нуль, а другий - ні." #: c-family/c.opt:874 #, no-c-format msgid "Warn about suspicious calls to memset where the third argument contains the number of elements not multiplied by the element size." -msgstr "" +msgstr "Попереджувати про підозрілі виклики memset, де третій аргумент містить кількість елементів, не помножену на розмір елемента." #: c-family/c.opt:878 #, no-c-format msgid "Warn when the indentation of the code does not reflect the block structure." -msgstr "" +msgstr "Попереджувати, коли відступи в коді не показують структуру блоку." #: c-family/c.opt:882 #, no-c-format msgid "Warn for deallocation calls with arguments returned from mismatched allocation functions." -msgstr "" +msgstr "Попереджувати про виклики звільнення з аргументами, які повернулися з невідповідних функцій виділення памʼяті." #: c-family/c.opt:887 #, no-c-format msgid "Warn for mismatches between calls to operator new or delete and the corresponding call to the allocation or deallocation function." -msgstr "" +msgstr "Попереджувати про невідповідності між викликами операторів new або delete та відповідним викликом функції виділення або звільнення памʼяті." #: c-family/c.opt:892 #, no-c-format msgid "Warn when a class is redeclared or referenced using a mismatched class-key." -msgstr "" +msgstr "Попереджувати, коли клас повторно оголошується або посилається з використанням невідповідного ключа класу." #: c-family/c.opt:896 #, no-c-format msgid "Warn about possibly missing braces around initializers." -msgstr "" +msgstr "Попереджати про можливе відсутність фігурних дужок навколо ініціалізаторів." #: c-family/c.opt:900 #, no-c-format msgid "Warn about global functions without previous declarations." -msgstr "" +msgstr "Попереджати про глобальні функції без попередніх оголошень." #: c-family/c.opt:904 #, no-c-format msgid "Warn about missing fields in struct initializers." -msgstr "" +msgstr "Попереджувати про відсутні поля в ініціалізаторах структур." #: c-family/c.opt:908 #, no-c-format msgid "Warn about likely missing requires keyword." -msgstr "" +msgstr "Попереджувати про ймовірне відсутність ключового слова «requires»." #: c-family/c.opt:912 #, no-c-format msgid "Warn when the template keyword is missing after a member access token in a dependent member access expression if that member is a template." -msgstr "" +msgstr "Попереджувати, коли ключове слово «template» відсутнє після токена доступу до члена в залежному виразі доступу до члена, якщо цей член є шаблоном." #: c-family/c.opt:916 #, no-c-format msgid "Warn about unsafe macros expanding to multiple statements used as a body of a clause such as if, else, while, switch, or for." -msgstr "" +msgstr "Попереджувати про небезпечні макроси, які розширюються до кількох операторів, використовуваних як тіло замикання, такого як if, else, while, switch або for." #: c-family/c.opt:920 #, no-c-format msgid "Warn on direct multiple inheritance." -msgstr "" +msgstr "Попереджувати про пряму множинну спадковість." #: c-family/c.opt:924 #, no-c-format msgid "Warn on namespace definition." -msgstr "" +msgstr "Попереджувати про визначення простору імен." #: c-family/c.opt:928 #, no-c-format msgid "Warn when fields in a struct with the packed attribute are misaligned." -msgstr "" +msgstr "Попереджувати, коли поля в структурі з атрибутом packed мають неправильне вирівнювання." #: c-family/c.opt:932 #, no-c-format msgid "Warn when a range-based for-loop is creating unnecessary copies." -msgstr "" +msgstr "Попереджувати, коли цикл for заснований на діапазоні створює непотрібні копії." #: c-family/c.opt:936 #, no-c-format msgid "Warn when a class or enumerated type is referenced using a redundant class-key." -msgstr "" +msgstr "Попереджувати, коли на клас або перелічуваний тип посилаються за допомогою зайвого ключа класу." #: c-family/c.opt:940 #, no-c-format msgid "Warn about missing sized deallocation functions." -msgstr "" +msgstr "Попереджувати про відсутність функцій звільнення памʼяті з вказаною розмірністю." #: c-family/c.opt:944 #, no-c-format msgid "Warn about suspicious divisions of two sizeof expressions that don't work correctly with pointers." -msgstr "" +msgstr "Попереджувати про підозрілі ділення двох виразів sizeof, які не працюють правильно з вказівниками." #: c-family/c.opt:948 #, no-c-format msgid "Warn about divisions of two sizeof operators when the first one is applied to an array and the divisor does not equal the size of the array element." -msgstr "" +msgstr "Попереджувати про ділення двох операторів sizeof, коли перший застосовується до масиву, а дільник не дорівнює розміру елемента масиву." #: c-family/c.opt:953 #, no-c-format msgid "Warn about suspicious length parameters to certain string functions if the argument uses sizeof." -msgstr "" +msgstr "Попереджувати про підозрілі параметри довжини для деяких функцій рядків, якщо аргумент використовує sizeof." #: c-family/c.opt:957 #, no-c-format msgid "Warn when sizeof is applied on a parameter declared as an array." -msgstr "" +msgstr "Попереджувати, коли sizeof застосовується до параметра, оголошеного як масив." #: c-family/c.opt:961 #, no-c-format msgid "Warn about calls to strcmp and strncmp used in equality expressions that are necessarily true or false due to the length of one and size of the other argument." -msgstr "" +msgstr "Попереджувати про виклики strcmp і strncmp, які використовуються в рівності виразів, які обовʼязково є істинними або хибними через довжину одного і розмір іншого аргументу." #: c-family/c.opt:967 #, no-c-format msgid "Warn about buffer overflow in string manipulation functions like memcpy and strcpy." -msgstr "" +msgstr "Попереджувати про переповнення буфера в функціях маніпулювання рядками, таких як memcpy і strcpy." #: c-family/c.opt:972 #, no-c-format msgid "Under the control of Object Size type, warn about buffer overflow in string manipulation functions like memcpy and strcpy." -msgstr "" +msgstr "Під керівництвом типу розміру обʼєкта, попереджувати про переповнення буфера в функціях маніпуляції рядками, таких як memcpy і strcpy." #: c-family/c.opt:977 #, no-c-format msgid "Warn about reading past the end of a source array in string manipulation functions like memchr and memcpy." -msgstr "" +msgstr "Попереджувати про читання за межами джерелового масиву у функціях маніпуляції рядками, таких як memchr і memcpy." #: c-family/c.opt:981 #, no-c-format msgid "Warn about truncation in string manipulation functions like strncat and strncpy." -msgstr "" +msgstr "Попереджувати про обрізання у функціях маніпуляції рядками, таких як strncat і strncpy." #: c-family/c.opt:985 #, no-c-format msgid "Warn about inproper usages of flexible array members according to the level of -fstrict-flex-arrays." -msgstr "" +msgstr "Попереджувати про неправильне використання гнучких елементів масиву залежно від рівня -fstrict-flex-arrays." #: c-family/c.opt:990 #, no-c-format msgid "Warn about functions which might be candidates for format attributes." -msgstr "" +msgstr "Попереджувати про функції, які можуть бути кандидатами на отримання атрибутів формату." #: c-family/c.opt:994 #, no-c-format msgid "Suggest that the override keyword be used when the declaration of a virtual function overrides another." -msgstr "" +msgstr "Рекомендується використовувати ключове слово override, коли оголошення віртуальної функції перевизначає іншу." #: c-family/c.opt:999 #, no-c-format msgid "Warn about enumerated switches, with no default, missing a case." -msgstr "" +msgstr "Попереджати про перелічовані перемикачі, без значення за замовчуванням, які пропускають випадок." #: c-family/c.opt:1003 #, no-c-format msgid "Warn about enumerated switches missing a \"default:\" statement." -msgstr "" +msgstr "Попереджувати про перелічовані перемикачі, які пропускають вираз «default:»." #: c-family/c.opt:1007 #, no-c-format msgid "Warn about all enumerated switches missing a specific case." -msgstr "" +msgstr "Попереджувати про всі перелічовані перемикачі, які пропускають певний випадок." #: c-family/c.opt:1011 #, no-c-format msgid "Warn about switches with boolean controlling expression." -msgstr "" +msgstr "Попереджувати про перемикачі з булевим керуючим виразом." #: c-family/c.opt:1015 #, no-c-format msgid "Warn about switch values that are outside of the switch's type range." -msgstr "" +msgstr "Попереджувати про значення перемикача, які виходять за межі діапазону типу перемикача." #: c-family/c.opt:1019 #, no-c-format msgid "Warn on primary template declaration." -msgstr "" +msgstr "Попереджувати про основну декларацію шаблону." #: c-family/c.opt:1023 #, no-c-format msgid "Warn about declarations of entities that may be missing attributes that related entities have been declared with." -msgstr "" +msgstr "Попереджувати про декларації сутностей, які можуть бути без атрибутів, які були вказані в деклараціях повʼязаних сутностей." #: c-family/c.opt:1032 #, no-c-format msgid "Warn about user-specified include directories that do not exist." -msgstr "" +msgstr "Попереджати про вказані користувачем каталоги включення, які не існують." #: c-family/c.opt:1036 #, no-c-format msgid "Warn about function parameters declared without a type specifier in K&R-style functions." -msgstr "" +msgstr "Попереджати про параметри функцій, оголошених без вказівника типу в функціях стилю K&R." #: c-family/c.opt:1040 #, no-c-format msgid "Warn about global functions without prototypes." -msgstr "" +msgstr "Попереджати про глобальні функції без прототипів." #: c-family/c.opt:1047 #, no-c-format msgid "Warn about use of multi-character character constants." -msgstr "" +msgstr "Попереджати про використання констант символів з кількома символами." #: c-family/c.opt:1051 #, no-c-format msgid "Warn about narrowing conversions within { } that are ill-formed in C++11." -msgstr "" +msgstr "Попереджати про звужувальні перетворення всередині { }, які є некоректними в C++11." #: c-family/c.opt:1055 #, no-c-format msgid "Warn about \"extern\" declarations not at file scope." -msgstr "" +msgstr "Попереджувати про оголошення «extern», які не знаходяться на рівні файлу." #: c-family/c.opt:1059 #, no-c-format msgid "Warn when a noexcept expression evaluates to false even though the expression can't actually throw." -msgstr "" +msgstr "Попереджувати, коли вираз без-винятків оцінюється як false, навіть якщо вираз насправді не може кинути виняток." #: c-family/c.opt:1063 #, no-c-format msgid "Warn if C++17 noexcept function type will change the mangled name of a symbol." -msgstr "" +msgstr "Попереджувати, якщо тип функції noexcept C++17 змінить декороване імʼя символу." #: c-family/c.opt:1067 #, no-c-format msgid "Warn when non-templatized friend functions are declared within a template." -msgstr "" +msgstr "Попереджувати, коли в шаблоні оголошуються нешаблонні функції-друзі." #: c-family/c.opt:1071 #, no-c-format msgid "Warn when a conversion function will never be called due to the type it converts to." -msgstr "" +msgstr "Попереджати, коли функція перетворення ніколи не буде викликана через тип, до якого вона перетворює." #: c-family/c.opt:1075 #, no-c-format msgid "Warn for unsafe raw memory writes to objects of class types." -msgstr "" +msgstr "Попереджувати про небезпечні записи в сирі памʼять обʼєктів класів." #: c-family/c.opt:1079 #, no-c-format msgid "Warn about non-virtual destructors." -msgstr "" +msgstr "Попереджати про невіртуальні деструктори." #: c-family/c.opt:1083 #, no-c-format msgid "Warn about NULL being passed to argument slots marked as requiring non-NULL." -msgstr "" +msgstr "Попереджувати про передачу NULL у слоти аргументів, які вимагають ненульових значень." #: c-family/c.opt:1099 #, no-c-format msgid "-Wnormalized=[none|id|nfc|nfkc]\tWarn about non-normalized Unicode strings." -msgstr "" +msgstr "-Wnormalized=[none|id|nfc|nfkc]\tПопереджувати про ненормалізовані рядки Юнікоду." #: c-family/c.opt:1122 #, no-c-format msgid "Warn if a class interface has no superclass. Root classes may use an attribute to suppress this warning." -msgstr "" +msgstr "Попереджувати, якщо інтерфейс класу не має суперкласу. Кореневі класи можуть використовувати атрибут для пригнічення цього попередження." #: c-family/c.opt:1127 #, no-c-format msgid "Warn if a C-style cast is used in a program." -msgstr "" +msgstr "Попереджувати, якщо в програмі використовується приведення типу у стилі C." #: c-family/c.opt:1131 #, no-c-format msgid "Warn for obsolescent usage in a declaration." -msgstr "" +msgstr "Попереджувати про застаріле використання в декларації." #: c-family/c.opt:1135 #, no-c-format msgid "Warn if an old-style parameter definition is used." -msgstr "" +msgstr "Попереджувати, якщо використовується старомодне визначення параметра." #: c-family/c.opt:1139 #, no-c-format msgid "Warn about potentially suboptimal choices related to OpenACC parallelism." -msgstr "" +msgstr "Попереджувати про потенційно неоптимальні вибори, повʼязані з паралелізмом OpenACC." #: c-family/c.opt:1143 #, no-c-format msgid "Warn if a simd directive is overridden by the vectorizer cost model." -msgstr "" +msgstr "Попереджати, якщо директива simd перевизначається моделлю вартості векторизатора." #: c-family/c.opt:1147 #, no-c-format msgid "Warn if a string is longer than the maximum portable length specified by the standard." -msgstr "" +msgstr "Попереджати, якщо рядок довший за максимальну переносну довжину, визначену стандартом." #: c-family/c.opt:1151 c-family/c.opt:1155 #, no-c-format msgid "Warn about overloaded virtual function names." -msgstr "" +msgstr "Попереджати про перевантажені імена віртуальних функцій." #: c-family/c.opt:1159 #, no-c-format msgid "Warn about overriding initializers without side effects." -msgstr "" +msgstr "Попереджати про перевизначення ініціалізаторів без побічних ефектів." #: c-family/c.opt:1163 #, no-c-format msgid "Warn about overriding initializers with side effects." -msgstr "" +msgstr "Попереджати про перевизначення ініціалізаторів з побічними ефектами." #: c-family/c.opt:1167 #, no-c-format msgid "Warn about packed bit-fields whose offset changed in GCC 4.4." -msgstr "" +msgstr "Попереджати про упаковані бітові поля, чий зсув змінився в GCC 4.4." #: c-family/c.opt:1171 #, no-c-format msgid "Warn about possibly missing parentheses." -msgstr "" +msgstr "Попереджувати про можливе відсутність дужок." #: c-family/c.opt:1179 #, no-c-format msgid "Warn about calling std::move on a local object in a return statement preventing copy elision." -msgstr "" +msgstr "Попереджати про виклик std::move на локальному обʼєкті в операторі повернення, що запобігає уникненню копіювання." #: c-family/c.opt:1183 #, no-c-format msgid "Warn when converting the type of pointers to member functions." -msgstr "" +msgstr "Попереджати при перетворенні типу вказівників на член-функції." #: c-family/c.opt:1187 #, no-c-format msgid "Warn about function pointer arithmetic." -msgstr "" +msgstr "Попереджати про арифметику з вказівниками на функції." #: c-family/c.opt:1191 #, no-c-format msgid "Warn when a pointer differs in signedness in an assignment." -msgstr "" +msgstr "Попереджати, коли вказівник відрізняється за знаком у присвоєнні." #: c-family/c.opt:1195 #, no-c-format msgid "Warn when a pointer is compared with a zero character constant." -msgstr "" +msgstr "Попереджати, коли вказівник порівнюється з нульовою символьною константою." #: c-family/c.opt:1199 #, no-c-format msgid "Warn when a pointer is cast to an integer of a different size." -msgstr "" +msgstr "Попереджати, коли вказівник приводиться до цілого числа іншого розміру." #: c-family/c.opt:1203 #, no-c-format msgid "Warn about misuses of pragmas." -msgstr "" +msgstr "Попереджати про неправильне використання прагм." #: c-family/c.opt:1207 #, no-c-format msgid "Warn if constructor or destructors with priorities from 0 to 100 are used." -msgstr "" +msgstr "Попереджати, якщо використовуються конструктори або деструктори з пріоритетами від 0 до 100." #: c-family/c.opt:1211 #, no-c-format msgid "Warn if a property for an Objective-C object has no assign semantics specified." -msgstr "" +msgstr "Попереджати, якщо для властивості обʼєкта Objective-C не вказано семантику присвоєння." #: c-family/c.opt:1215 #, no-c-format msgid "Warn if inherited methods are unimplemented." -msgstr "" +msgstr "Попереджати, якщо не реалізовані успадковані методи." #: c-family/c.opt:1219 c-family/c.opt:1223 #, no-c-format msgid "Warn for placement new expressions with undefined behavior." -msgstr "" +msgstr "Попереджати про використання виразів placement new з невизначеним поведінкою." #: c-family/c.opt:1227 #, no-c-format msgid "Warn about multiple declarations of the same object." -msgstr "" +msgstr "Попереджати про множинні оголошення одного й того ж обʼєкта." #: c-family/c.opt:1231 #, no-c-format msgid "Warn about redundant calls to std::move." -msgstr "" +msgstr "Попереджати про зайві виклики std::move." #: c-family/c.opt:1235 #, no-c-format msgid "Warn about uses of register storage specifier." -msgstr "" +msgstr "Попереджати про використання специфікатора зберігання register." #: c-family/c.opt:1239 #, no-c-format msgid "Warn when the compiler reorders code." -msgstr "" +msgstr "Попереджати, коли компілятор переставляє код." #: c-family/c.opt:1243 #, no-c-format msgid "Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)." -msgstr "" +msgstr "Попереджувати, коли тип повернення функції за замовчуванням стає «int» (C), або про неузгоджені типи повернення (C++)." #: c-family/c.opt:1247 #, no-c-format msgid "Warn on suspicious constructs involving reverse scalar storage order." -msgstr "" +msgstr "Попереджувати про підозрілі конструкції, що включають зворотний порядок зберігання скалярних значень." #: c-family/c.opt:1251 #, no-c-format msgid "Warn if a selector has multiple methods." -msgstr "" +msgstr "Попереджувати, якщо селектор має кілька методів." #: c-family/c.opt:1255 #, no-c-format msgid "Warn when a value is moved to itself with std::move." -msgstr "" +msgstr "Попереджувати, коли значення переміщується в самого себе за допомогою std::move." #: c-family/c.opt:1259 #, no-c-format msgid "Warn about possible violations of sequence point rules." -msgstr "" +msgstr "Попереджувати про можливі порушення правил послідовності точок." #: c-family/c.opt:1263 #, no-c-format msgid "Warn if a local declaration hides an instance variable." -msgstr "" +msgstr "Попереджувати, якщо локальна декларація приховує змінну екземпляра." #: c-family/c.opt:1267 c-family/c.opt:1271 #, no-c-format msgid "Warn if left shift of a signed value overflows." -msgstr "" +msgstr "Попереджувати, якщо лівий зсув знакового значення переповнюється." #: c-family/c.opt:1275 #, no-c-format msgid "Warn if shift count is negative." -msgstr "" +msgstr "Попереджувати, якщо кількість зсуву відʼємна." #: c-family/c.opt:1279 #, no-c-format msgid "Warn if shift count >= width of type." -msgstr "" +msgstr "Попереджувати, якщо кількість зсуву >= ширини типу." #: c-family/c.opt:1283 #, no-c-format msgid "Warn if left shifting a negative value." -msgstr "" +msgstr "Попереджати, якщо виконується зсув вліво відʼємного значення." #: c-family/c.opt:1287 #, no-c-format msgid "Warn if conversion of the result of arithmetic might change the value even though converting the operands cannot." -msgstr "" +msgstr "Попереджати, якщо конвертація результату арифметичної операції може змінити значення, навіть якщо конвертація операндів неможлива." #: c-family/c.opt:1291 #, no-c-format msgid "Warn about signed-unsigned comparisons." -msgstr "" +msgstr "Попереджати про порівняння зі знаком-беззнаком." #: c-family/c.opt:1299 #, no-c-format msgid "Warn for implicit type conversions between signed and unsigned integers." -msgstr "" +msgstr "Попереджати про неявні типові конвертації між знаковими та беззнаковими цілими числами." #: c-family/c.opt:1303 #, no-c-format msgid "Warn when overload promotes from unsigned to signed." -msgstr "" +msgstr "Попереджати, коли перевантаження приводить від беззнакового до знакового." #: c-family/c.opt:1307 #, no-c-format msgid "Warn about uncasted NULL used as sentinel." -msgstr "" +msgstr "Попереджати про використання некастованого NULL як маркера." #: c-family/c.opt:1311 #, no-c-format msgid "Warn about unprototyped function declarations." -msgstr "" +msgstr "Попереджати про непрототиповані оголошення функцій." #: c-family/c.opt:1323 #, no-c-format msgid "Warn if type signatures of candidate methods do not match exactly." -msgstr "" +msgstr "Попереджати, якщо типові підписи кандидатських методів не збігаються точно." #: c-family/c.opt:1327 #, no-c-format msgid "Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used." -msgstr "" +msgstr "Попереджати, коли використовуються вбудовані функції __sync_fetch_and_nand та __sync_nand_and_fetch." #: c-family/c.opt:1331 #, no-c-format msgid "Deprecated. This switch has no effect." -msgstr "" +msgstr "Застарілий. Цей перемикач не має ефекту." #: c-family/c.opt:1339 #, no-c-format msgid "Warn if a comparison always evaluates to true or false." -msgstr "" +msgstr "Попереджати, якщо порівняння завжди оцінюється як true або false." #: c-family/c.opt:1343 #, no-c-format msgid "Warn if a throw expression will always result in a call to terminate()." -msgstr "" +msgstr "Попереджати, якщо вираз throw завжди призведе до виклику terminate()." #: c-family/c.opt:1347 #, no-c-format msgid "Warn about features not present in traditional C." -msgstr "" +msgstr "Попереджати про функції, які відсутні в традиційній мові C." #: c-family/c.opt:1351 #, no-c-format msgid "Warn of prototypes causing type conversions different from what would happen in the absence of prototype." -msgstr "" +msgstr "Попереджати про прототипи, які призводять до типових перетворень, відмінних від тих, що відбуваються відсутності прототипу." #: c-family/c.opt:1355 #, no-c-format msgid "Warn if trigraphs are encountered that might affect the meaning of the program." -msgstr "" +msgstr "Попереджати, якщо зустрічаються триграфи, які можуть вплинути на значення програми." #: c-family/c.opt:1359 #, no-c-format msgid "Warn about @selector()s without previously declared methods." -msgstr "" +msgstr "Попереджувати про @selector() без попередньо оголошених методів." #: c-family/c.opt:1363 #, no-c-format msgid "Warn if an undefined macro is used in an #if directive." -msgstr "" +msgstr "Попереджати, якщо в директиві #if використовується невизначений макрос." #: c-family/c.opt:1367 #, no-c-format msgid "Warn about invalid forms of delimited or named escape sequences." -msgstr "" +msgstr "Попереджувати про недійсні форми обмежених або іменованих послідовностей екранування." #: c-family/c.opt:1379 #, no-c-format msgid "Warn about unrecognized pragmas." -msgstr "" +msgstr "Попереджувати про нерозпізнані pragma-інструкції." #: c-family/c.opt:1383 #, no-c-format msgid "Warn about unsuffixed float constants." -msgstr "" +msgstr "Попереджувати про використання несуфіксованих констант з плаваючою точкою." #: c-family/c.opt:1391 #, no-c-format msgid "Warn when typedefs locally defined in a function are not used." -msgstr "" +msgstr "Попереджувати, коли typedef, що визначається локально в функції, не використовується." #: c-family/c.opt:1395 #, no-c-format msgid "Warn about macros defined in the main file that are not used." -msgstr "" +msgstr "Попереджувати про невикористані макроси, що визначаються в головному файлі." #: c-family/c.opt:1423 #, no-c-format msgid "Warn about using variadic macros." -msgstr "Попереджати про використання варіативних макросів." +msgstr "Попереджувати про використання варіативних макросів." #: c-family/c.opt:1427 #, no-c-format msgid "Warn about questionable usage of the macros used to retrieve variable arguments." -msgstr "" +msgstr "Попереджувати про сумнівне використання макросів, що використовуються для отримання змінних аргументів." #: c-family/c.opt:1431 #, no-c-format msgid "Warn about the most vexing parse syntactic ambiguity." -msgstr "" +msgstr "Попереджувати про найбільш заплутану синтаксичну неоднозначність." #: c-family/c.opt:1435 #, no-c-format msgid "Warn if a variable length array is used." -msgstr "Попереджати, якщо використано масив змінної довжини." +msgstr "Попереджувати, якщо використовується масив змінної довжини." #: c-family/c.opt:1439 #, no-c-format msgid "-Wvla-larger-than=\tWarn on unbounded uses of variable-length arrays, and on bounded uses of variable-length arrays whose bound can be larger than bytes." -msgstr "" +msgstr "-Wvla-larger-than=<число>\tПопереджувати про невизначене використання масивів змінної довжини, а також про обмежене використання масивів змінної довжини, довжина яких може бути більшою за <число> байтів." #: c-family/c.opt:1445 #, no-c-format msgid "Disable Wvla-larger-than= warning. Equivalent to Wvla-larger-than= or larger." -msgstr "Вимкнути попередження Wvla-larger-than=. Еквівалент Wvla-larger-than= або більше." +msgstr "Вимкнути попередження Wvla-larger-than=. Еквівалентно Wvla-larger-than= або більше." #: c-family/c.opt:1449 #, no-c-format msgid "Warn about mismatched declarations of VLA parameters." -msgstr "Попереджати про невідповідні оголошення параметрів VLA." +msgstr "Попереджати про невідповідні декларації параметрів VLA." #: c-family/c.opt:1453 #, no-c-format msgid "Warn about deprecated uses of volatile qualifier." -msgstr "" +msgstr "Попереджати про застаріле використання кваліфікатора volatile." #: c-family/c.opt:1457 #, no-c-format msgid "Warn when a register variable is declared volatile." -msgstr "" +msgstr "Попереджати, коли регістрова змінна оголошується як volatile." #: c-family/c.opt:1461 #, no-c-format msgid "Warn on direct virtual inheritance." -msgstr "" +msgstr "Попереджувати про пряме віртуальне успадкування." #: c-family/c.opt:1465 #, no-c-format msgid "Warn if a virtual base has a non-trivial move assignment operator." -msgstr "" +msgstr "Попереджувати, якщо віртуальна база має незвичайний оператор переміщення присвоєння." #: c-family/c.opt:1469 #, no-c-format msgid "In C++, nonzero means warn about deprecated conversion from string literals to 'char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard." -msgstr "" +msgstr "У C++, ненульове значення означає попередження про застаріле перетворення з літералів рядків у «char *». У C подібне попередження, за винятком того, що перетворення, звичайно, не є застарілим згідно зі стандартом ISO C." #: c-family/c.opt:1473 #, no-c-format msgid "Warn about xor operators where it appears the user meant exponentiation." -msgstr "" +msgstr "Попереджувати про оператори xor, де здається, що користувач мав на увазі піднесення до степеня." #: c-family/c.opt:1477 #, no-c-format msgid "Warn when a literal '0' is used as null pointer." -msgstr "" +msgstr "Попереджати, коли літерал '0' використовується як нульовий вказівник." #: c-family/c.opt:1481 #, no-c-format msgid "Warn about useless casts." -msgstr "" +msgstr "Попереджати про непотрібні приведення типів." #: c-family/c.opt:1485 #, no-c-format msgid "Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage." -msgstr "" +msgstr "Попереджати, якщо тип класу має базу або поле, тип якого використовує анонімний простір імен або залежить від типу без звʼязку." #: c-family/c.opt:1489 #, no-c-format msgid "Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier." -msgstr "" +msgstr "Попереджувати, коли оголошення має дублюючий специфікатор const, volatile, restrict або _Atomic." #: c-family/c.opt:1493 #, no-c-format msgid "Warn when an argument passed to a restrict-qualified parameter aliases with another argument." -msgstr "" +msgstr "Попереджувати, коли аргумент, переданий до параметра з обмеженням restrict, має псевдонім з іншим аргументом." #: c-family/c.opt:1498 #, no-c-format msgid "A synonym for -std=c89 (for C) or -std=c++98 (for C++)." -msgstr "" +msgstr "Синонім для -std=c89 (для C) або -std=c++98 (для C++)." #: c-family/c.opt:1506 #, no-c-format msgid "The version of the C++ ABI used for -Wabi warnings and link compatibility aliases." -msgstr "" +msgstr "Версія C++ ABI, яка використовується для попереджень -Wabi та псевдонімів сумісності звʼязку." #: c-family/c.opt:1510 #, no-c-format msgid "Enforce class member access control semantics." -msgstr "" +msgstr "Застосовувати семантику контролю доступу до членів класу." #: c-family/c.opt:1514 #, no-c-format msgid "-fada-spec-parent=unit\tDump Ada specs as child units of given parent." -msgstr "" +msgstr "-fada-spec-parent=unit\tВивантажити специфікації Ada як дочірні одиниці заданого батька." #: c-family/c.opt:1518 #, no-c-format msgid "Support C++17 allocation of over-aligned types." -msgstr "" +msgstr "Підтримка виділення типів з перевищеною вирівнюванням у C++17." #: c-family/c.opt:1522 #, no-c-format msgid "-faligned-new=\tUse C++17 over-aligned type allocation for alignments greater than N." -msgstr "" +msgstr "-faligned-new=\tВикористовувати виділення типів з перевищеною вирівнюванням у C++17 для вирівнювань, більших за N." #: c-family/c.opt:1533 c-family/c.opt:1846 c-family/c.opt:2240 #: c-family/c.opt:2244 c-family/c.opt:2260 @@ -2659,192 +2654,192 @@ msgstr "Більше не підтримується." #: c-family/c.opt:1537 #, no-c-format msgid "Recognize the \"asm\" keyword." -msgstr "" +msgstr "Розпізнавати ключове слово «asm»." #: c-family/c.opt:1545 #, no-c-format msgid "Recognize built-in functions." -msgstr "" +msgstr "Розпізнавати вбудовані функції." #: c-family/c.opt:1552 #, no-c-format msgid "Where shorter, use canonicalized paths to systems headers." -msgstr "" +msgstr "Де це коротше, використовуйте канонізовані шляхи до системних заголовків." #: c-family/c.opt:1556 #, no-c-format msgid "Enable the char8_t fundamental type and use it as the type for UTF-8 string and character literals." -msgstr "" +msgstr "Увімкнути фундаментальний тип char8_t і використовувати його як тип для UTF-8 рядків і літералів символів." #: c-family/c.opt:1644 #, no-c-format msgid "Removed in GCC 8. This switch has no effect." -msgstr "" +msgstr "Вилучено в GCC 8. Цей перемикач не має ефекту." #: c-family/c.opt:1648 #, no-c-format msgid "Enable support for C++ concepts." -msgstr "" +msgstr "Увімкнути підтримку концепцій C++." #: c-family/c.opt:1652 #, no-c-format msgid "Enable certain features present in the Concepts TS." -msgstr "" +msgstr "Увімкнути певні функції, які є в Технічній специфікації концепцій (Concepts TS)." #: c-family/c.opt:1656 #, no-c-format msgid "Specify maximum error replay depth during recursive diagnosis of a constraint satisfaction failure." -msgstr "" +msgstr "Вказати максимальну глибину повторного відтворення помилок під час рекурсивного діагностування невиконання обмежень." #: c-family/c.opt:1660 #, no-c-format msgid "Allow the arguments of the '?' operator to have different types." -msgstr "" +msgstr "Дозволити аргументам оператора '?' мати різні типи." #: c-family/c.opt:1668 #, no-c-format msgid "-fconst-string-class=\tUse class for constant strings." -msgstr "" +msgstr "-fconst-string-class=<імʼя>\tВикористовуйте клас <імʼя> для константних рядків." #: c-family/c.opt:1672 #, no-c-format msgid "-fconstexpr-depth=\tSpecify maximum constexpr recursion depth." -msgstr "" +msgstr "-fconstexpr-depth=<число>\tВказати максимальну глибину рекурсії constexpr." #: c-family/c.opt:1676 #, no-c-format msgid "-fconstexpr-cache-depth=\tSpecify maximum constexpr recursion cache depth." -msgstr "" +msgstr "-fconstexpr-cache-depth=<число>\tВказати максимальну глибину кешування рекурсії constexpr." #: c-family/c.opt:1680 #, no-c-format msgid "Allow IEC559 floating point exceptions in constant expressions." -msgstr "" +msgstr "Дозволити винятки з плаваючою точкою IEC559 в константних виразах." #: c-family/c.opt:1684 #, no-c-format msgid "-fconstexpr-loop-limit=\tSpecify maximum constexpr loop iteration count." -msgstr "" +msgstr "-fconstexpr-loop-limit=<число>\tВказати максимальну кількість ітерацій циклу constexpr." #: c-family/c.opt:1688 #, no-c-format msgid "-fconstexpr-ops-limit=\tSpecify maximum number of constexpr operations during a single constexpr evaluation." -msgstr "" +msgstr "-fconstexpr-ops-limit=<число>\tВказує максимальну кількість операцій constexpr під час однієї оцінки constexpr." #: c-family/c.opt:1692 #, no-c-format msgid "Enable certain features present in drafts of C++ Contracts." -msgstr "" +msgstr "Увімкнути певні функції, які присутні у чернетках контрактів C++." #: c-family/c.opt:1705 #, no-c-format msgid "-fcontract-assumption-mode=[on|off]\tEnable or disable treating axiom level contracts as assumptions (default on)." -msgstr "" +msgstr "-fcontract-assumption-mode=[on|off]\tУвімкнути або вимкнути обробку контрактів на рівні аксіом як припущень (за замовчуванням увімкнено)." #: c-family/c.opt:1709 #, no-c-format msgid "-fcontract-build-level=[off|default|audit]\tSpecify max contract level to generate runtime checks for." -msgstr "" +msgstr "-fcontract-build-level=[off|default|audit]\tВказати максимальний рівень контракту для генерації перевірок під час виконання." #: c-family/c.opt:1713 #, no-c-format msgid "-fcontract-strict-declarations=[on|off]\tEnable or disable warnings on generalized redeclaration of functions with contracts (default off)." -msgstr "" +msgstr "-fcontract-strict-declarations=[on|off]\tУвімкнути або вимкнути попередження про узагальнене повторне оголошення функцій з контрактами (за замовчуванням вимкнено)." #: c-family/c.opt:1717 #, no-c-format msgid "-fcontract-mode=[on|off]\tEnable or disable all contract facilities (default on)." -msgstr "" +msgstr "-fcontract-mode=[on|off]\tУвімкнути або вимкнути всі можливості контрактів (за замовчуванням увімкнено)." #: c-family/c.opt:1721 #, no-c-format msgid "-fcontract-continuation-mode=[on|off]\tEnable or disable contract continuation mode (default off)." -msgstr "" +msgstr "-fcontract-continuation-mode=[on|off]\tУвімкнути або вимкнути режим продовження контракту (за замовчуванням вимкнено)." #: c-family/c.opt:1725 #, no-c-format msgid "-fcontract-role=:\tSpecify the semantics for all levels in a role (default, review), or a custom contract role with given semantics (ex: opt:assume,assume,assume)." -msgstr "" +msgstr "-fcontract-role=<імʼя>:<семантика>\tВказує семантику для всіх рівнів у ролі (за замовчуванням, перегляд), або власну роль контракту з заданою семантикою (наприклад: opt:assume,assume,assume)." #: c-family/c.opt:1729 #, no-c-format msgid "-fcontract-semantic=:\tSpecify the concrete semantics for level." -msgstr "" +msgstr "-fcontract-semantic=<рівень>:<семантика>\tВказує конкретну семантику для рівня." #: c-family/c.opt:1733 #, no-c-format msgid "Enable C++ coroutines (experimental)." -msgstr "" +msgstr "Увімкнути C++ корутини (експериментально)." #: c-family/c.opt:1737 #, no-c-format msgid "Emit debug annotations during preprocessing." -msgstr "" +msgstr "Виводити анотації для налагодження під час попередньої обробки." #: c-family/c.opt:1745 #, no-c-format msgid "Factor complex constructors and destructors to favor space over speed." -msgstr "" +msgstr "Факторизувати складні конструктори та деструктори на користь простору перед швидкістю." #: c-family/c.opt:1753 #, no-c-format msgid "Print hierarchical comparisons when template types are mismatched." -msgstr "" +msgstr "Друкувати ієрархічні порівняння, коли типи шаблонів не збігаються." #: c-family/c.opt:1757 #, no-c-format msgid "Preprocess directives only." -msgstr "" +msgstr "Обробляти лише директиви попередньої обробки." #: c-family/c.opt:1761 #, no-c-format msgid "Permit '$' as an identifier character." -msgstr "" +msgstr "Дозволити «$» як символ ідентифікатора." #: c-family/c.opt:1765 #, no-c-format msgid "-fmacro-prefix-map==\tMap one directory name to another in __FILE__, __BASE_FILE__, and __builtin_FILE()." -msgstr "" +msgstr "-fmacro-prefix-map=<старий>=<новий>\tПоказувати одне імʼя каталогу на інше в __FILE__, __BASE_FILE__ та __builtin_FILE()." #: c-family/c.opt:1769 #, no-c-format msgid "Write all declarations as Ada code transitively." -msgstr "" +msgstr "Записувати всі оголошення як код Ada транзитивно." #: c-family/c.opt:1773 #, no-c-format msgid "Write all declarations as Ada code for the given file only." -msgstr "" +msgstr "Перетворити всі оголошення у код Ada лише для вказаного файлу." #: c-family/c.opt:1780 #, no-c-format msgid "Do not elide common elements in template comparisons." -msgstr "" +msgstr "Не викидати спільні елементи при порівнянні шаблонів." #: c-family/c.opt:1784 #, no-c-format msgid "Generate code to check exception specifications." -msgstr "" +msgstr "Створити код для перевірки специфікацій винятків." #: c-family/c.opt:1791 #, no-c-format msgid "-fexec-charset=\tConvert all strings and character constants to character set ." -msgstr "" +msgstr "-fexec-charset=\tПеретворити всі рядки та символьні константи у символьний набір ." #: c-family/c.opt:1795 #, no-c-format msgid "Permit universal character names (\\u and \\U) in identifiers." -msgstr "" +msgstr "Дозволити універсальні імена символів (\\u та \\U) у ідентифікаторах." #: c-family/c.opt:1799 #, no-c-format msgid "-finput-charset=\tSpecify the default character set for source files." -msgstr "" +msgstr "-finput-charset=\tВказати типовий набір символів для вихідних файлів." #: c-family/c.opt:1803 #, no-c-format msgid "Support dynamic initialization of thread-local variables in a different translation unit." -msgstr "" +msgstr "Підтримка динамічної ініціалізації змінних, локальних для потоку, в іншій одиниці перекладу." #: c-family/c.opt:1810 #, no-c-format @@ -2854,17 +2849,17 @@ msgstr "Згорнути виклики простих вбудованих фу #: c-family/c.opt:1817 #, no-c-format msgid "Do not assume that standard C libraries and \"main\" exist." -msgstr "" +msgstr "Не припускати, що існують стандартні бібліотеки C та «main»." #: c-family/c.opt:1821 #, no-c-format msgid "Recognize GNU-defined keywords." -msgstr "" +msgstr "Розпізнавати ключові слова, визначені GNU." #: c-family/c.opt:1825 #, no-c-format msgid "Generate code for GNU runtime environment." -msgstr "" +msgstr "Генерувати код для середовища виконання GNU." #: c-family/c.opt:1829 #, no-c-format @@ -2874,773 +2869,773 @@ msgstr "Використовувати традиційну семантику G #: c-family/c.opt:1842 #, no-c-format msgid "Assume normal C execution environment." -msgstr "Припускати звичайне середовище виконання C." +msgstr "Припускати нормальне середовище виконання C." #: c-family/c.opt:1850 #, no-c-format msgid "Export functions even if they can be inlined." -msgstr "" +msgstr "Експортувати функції навіть якщо вони можуть бути вбудовані." #: c-family/c.opt:1854 #, no-c-format msgid "Make inline functions constexpr by default." -msgstr "" +msgstr "За замовчуванням робити вбудовані функції constexpr." #: c-family/c.opt:1858 #, no-c-format msgid "Emit implicit instantiations of inline templates." -msgstr "" +msgstr "Видавати неявні інстанціювання вбудованих шаблонів." #: c-family/c.opt:1862 #, no-c-format msgid "Emit implicit instantiations of templates." -msgstr "" +msgstr "Видавати неявні інстанціювання шаблонів." #: c-family/c.opt:1866 #, no-c-format msgid "Implement C++17 inheriting constructor semantics." -msgstr "" +msgstr "Реалізувати семантику успадковування конструкторів C++17." #: c-family/c.opt:1873 #, no-c-format msgid "Don't emit dllexported inline functions unless needed." -msgstr "" +msgstr "Не видаляйте dllexported вбудовані функції, якщо не потрібно." #: c-family/c.opt:1880 #, no-c-format msgid "Allow implicit conversions between vectors with differing numbers of subparts and/or differing element types." -msgstr "" +msgstr "Дозволити неявні перетворення між векторами з різною кількістю підчастин і/або різними типами елементів." #: c-family/c.opt:1884 #, no-c-format msgid "Enable C++ modules-ts (experimental)." -msgstr "Увімкнути modules-ts C++ (експериментальна можливість)." +msgstr "Увімкнути C++ модулі-ts (експериментально)." #: c-family/c.opt:1892 #, no-c-format msgid "Enable C++ header module (experimental)." -msgstr "Увімкнути модуль заголовків C++ (експериментальна можливість)." +msgstr "Увімкнути C++ заголовковий модуль (експериментально)." #: c-family/c.opt:1899 #, no-c-format msgid "Member functions defined within their class are inline in module purview." -msgstr "" +msgstr "Члени-функції, визначені всередині свого класу, є вбудованими в модульному контексті." #: c-family/c.opt:1903 #, no-c-format msgid "Only emit Compiled Module Interface." -msgstr "" +msgstr "Видавати лише скомпільований інтерфейс модуля." #: c-family/c.opt:1907 #, no-c-format msgid "Mapper for module to CMI files." -msgstr "Засіб прив'язки модулів до файлів CMI." +msgstr "Мапер для модуля до файлів CMI." #: c-family/c.opt:1911 #, no-c-format msgid "Enable lazy module importing." -msgstr "Увімкнути «ліниве» імпортування модулів." +msgstr "Увімкнути лінивий імпорт модуля." #: c-family/c.opt:1919 #, no-c-format msgid "Warn about macros that have conflicting header units definitions." -msgstr "Попереджати про макроси, у яких є конфліктні визначення модулів заголовків." +msgstr "Попереджати про макроси, які мають конфліктні визначення одиниць заголовка." #: c-family/c.opt:1923 #, no-c-format msgid "Note #include directives translated to import declarations." -msgstr "" +msgstr "Зауважити директиви #include, перекладені в декларації імпорту." #: c-family/c.opt:1927 #, no-c-format msgid "Note #include directives not translated to import declarations, and not known to be textual." -msgstr "" +msgstr "Зауважити директиви #include, які не перекладені в декларації імпорту і не відомо, що вони текстові." #: c-family/c.opt:1931 #, no-c-format msgid "Note a #include translation of a specific header." -msgstr "" +msgstr "Примітка: переклад #include для конкретного заголовка." #: c-family/c.opt:1935 #, no-c-format msgid "Note Compiled Module Interface pathnames." -msgstr "" +msgstr "Примітка: шляхи до скомпільованих інтерфейсів модулів." #: c-family/c.opt:1939 #, no-c-format msgid "Note Compiled Module Interface pathname of a specific module or header-unit." -msgstr "" +msgstr "Примітка: шлях до скомпільованого інтерфейсу модуля або заголовкової одиниці." #: c-family/c.opt:1943 #, no-c-format msgid "fmax-include-depth= Set the maximum depth of the nested #include." -msgstr "" +msgstr "fmax-include-depth=<число> Встановити максимальну глибину вкладеного #include." #: c-family/c.opt:1947 #, no-c-format msgid "Don't warn about uses of Microsoft extensions." -msgstr "" +msgstr "Не попереджувати про використання розширень Microsoft." #: c-family/c.opt:1966 #, no-c-format msgid "Implement resolution of DR 150 for matching of template template arguments." -msgstr "" +msgstr "Реалізувати вирішення DR 150 для відповідності аргументів шаблону шаблону." #: c-family/c.opt:1970 #, no-c-format msgid "Generate code for NeXT (Apple Mac OS X) runtime environment." -msgstr "" +msgstr "Генерувати код для середовища виконання NeXT (Apple Mac OS X)." #: c-family/c.opt:1974 #, no-c-format msgid "Assume that receivers of Objective-C messages may be nil." -msgstr "" +msgstr "Припускати, що отримувачі повідомлень Objective-C можуть бути nil." #: c-family/c.opt:1978 #, no-c-format msgid "Allow access to instance variables as if they were local declarations within instance method implementations." -msgstr "" +msgstr "Дозволяти доступ до змінних екземпляра, ніби вони були локальними оголошеннями у реалізаціях методів екземпляра." #: c-family/c.opt:1982 #, no-c-format msgid "-fvisibility=[private|protected|public|package]\tSet the default symbol visibility." -msgstr "" +msgstr "-fvisibility=[private|protected|public|package]\tВстановити типову видимість символів." #: c-family/c.opt:2007 #, no-c-format msgid "Treat a throw() exception specification as noexcept to improve code size." -msgstr "" +msgstr "Трактувати специфікацію винятку throw() як noexcept для покращення розміру коду." #: c-family/c.opt:2011 #, no-c-format msgid "Specify which ABI to use for Objective-C family code and meta-data generation." -msgstr "" +msgstr "Вказати, яке ABI використовувати для генерації коду та метаданих родини Objective-C." #: c-family/c.opt:2017 #, no-c-format msgid "Generate special Objective-C methods to initialize/destroy non-POD C++ ivars, if needed." -msgstr "" +msgstr "Генерувати спеціальні методи Objective-C для ініціалізації/знищення не-POD C++ ivars, якщо потрібно." #: c-family/c.opt:2021 #, no-c-format msgid "Allow fast jumps to the message dispatcher." -msgstr "" +msgstr "Дозволити швидкі переходи до диспетчера повідомлень." #: c-family/c.opt:2027 #, no-c-format msgid "Enable Objective-C exception and synchronization syntax." -msgstr "" +msgstr "Увімкнути синтаксис винятків та синхронізації Objective-C." #: c-family/c.opt:2031 #, no-c-format msgid "Enable garbage collection (GC) in Objective-C/Objective-C++ programs." -msgstr "" +msgstr "Увімкнути збірку сміття (GC) в програмах Objective-C/Objective-C++." #: c-family/c.opt:2035 #, no-c-format msgid "Enable inline checks for nil receivers with the NeXT runtime and ABI version 2." -msgstr "" +msgstr "Увімкнути перевірку на нульовий отримувач з використанням NeXT runtime та версії ABI 2." #: c-family/c.opt:2040 #, no-c-format msgid "Enable Objective-C setjmp exception handling runtime." -msgstr "" +msgstr "Увімкнути обробку виключень setjmp для Objective-C runtime." #: c-family/c.opt:2044 #, no-c-format msgid "Conform to the Objective-C 1.0 language as implemented in GCC 4.0." -msgstr "" +msgstr "Відповідати мові Objective-C 1.0, реалізованій в GCC 4.0." #: c-family/c.opt:2048 #, no-c-format msgid "Enable OpenACC." -msgstr "" +msgstr "Увімкнути OpenACC." #: c-family/c.opt:2052 #, no-c-format msgid "Specify default OpenACC compute dimensions." -msgstr "" +msgstr "Вказати типові розміри обчислень для OpenACC." #: c-family/c.opt:2056 #, no-c-format msgid "Enable OpenMP (implies -frecursive in Fortran)." -msgstr "" +msgstr "Увімкнути OpenMP (включає -frecursive для Fortran)." #: c-family/c.opt:2060 #, no-c-format msgid "Enable OpenMP's SIMD directives." -msgstr "" +msgstr "Увімкнути директиви SIMD для OpenMP." #: c-family/c.opt:2064 #, no-c-format msgid "Recognize C++ keywords like \"compl\" and \"xor\"." -msgstr "" +msgstr "Розпізнавати ключові слова C++, такі як «compl» та «xor»." #: c-family/c.opt:2075 #, no-c-format msgid "Look for and use PCH files even when preprocessing." -msgstr "" +msgstr "Шукати та використовувати PCH-файли навіть під час попередньої обробки." #: c-family/c.opt:2079 #, no-c-format msgid "Downgrade conformance errors to warnings." -msgstr "" +msgstr "Знизити рівень помилок відповідності до попереджень." #: c-family/c.opt:2083 #, no-c-format msgid "Enable Plan 9 language extensions." -msgstr "" +msgstr "Увімкнути розширення мови Plan 9." #: c-family/c.opt:2087 #, no-c-format msgid "Treat the input file as already preprocessed." -msgstr "" +msgstr "Трактувати вхідний файл як вже попередньо оброблений." #: c-family/c.opt:2095 #, no-c-format msgid "-ftrack-macro-expansion=<0|1|2>\tTrack locations of tokens coming from macro expansion and display them in error messages." -msgstr "" +msgstr "-ftrack-macro-expansion=<0|1|2>\tВідстежувати розташування токенів, що походять з розширення макросів, та показувати їх у повідомленнях про помилки." #: c-family/c.opt:2099 #, no-c-format msgid "Do not pretty-print template specializations as the template signature followed by the arguments." -msgstr "" +msgstr "Не форматувати шаблонні спеціалізації як підпис шаблону, за яким слідують аргументи." #: c-family/c.opt:2103 #, no-c-format msgid "Treat known sprintf return values as constants." -msgstr "" +msgstr "Трактувати відомі значення повернення sprintf як константи." #: c-family/c.opt:2107 #, no-c-format msgid "Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime." -msgstr "" +msgstr "Використовується в режимі Fix-and-Continue для позначення того, що обʼєктні файли можуть бути обмінені під час виконання." #: c-family/c.opt:2111 #, no-c-format msgid "Removed in GCC 10. This switch has no effect." -msgstr "" +msgstr "Видалено в GCC 10. Цей перемикач не має ефекту." #: c-family/c.opt:2115 #, no-c-format msgid "Generate run time type descriptor information." -msgstr "" +msgstr "Створювати інформацію про опис типу під час виконання." #: c-family/c.opt:2119 ada/gcc-interface/lang.opt:81 #, no-c-format msgid "Use the narrowest integer type possible for enumeration types." -msgstr "" +msgstr "Використовувати найвужчий можливий цілочисельний тип для типів перелічування." #: c-family/c.opt:2123 #, no-c-format msgid "Force the underlying type for \"wchar_t\" to be \"unsigned short\"." -msgstr "" +msgstr "Змусити базовий тип для «wchar_t» бути «unsigned short»." #: c-family/c.opt:2127 #, no-c-format msgid "When \"signed\" or \"unsigned\" is not given make the bitfield signed." -msgstr "" +msgstr "Якщо не вказано «signed» або «unsigned», зробити бітове поле зі знаком." #: c-family/c.opt:2131 ada/gcc-interface/lang.opt:85 #, no-c-format msgid "Make \"char\" signed by default." -msgstr "" +msgstr "За замовчуванням зробити «char» зі знаком." #: c-family/c.opt:2135 #, no-c-format msgid "Enable C++14 sized deallocation support." -msgstr "" +msgstr "Увімкнути підтримку звільнення памʼяті з вказаною розміром у C++14." #: c-family/c.opt:2142 #, no-c-format msgid "-fstrict-flex-arrays= Control when to treat the trailing array of a structure as a flexible array member for the purposes of accessing the elements of such an array. The default is treating all trailing arrays of structures as flexible array members." -msgstr "" +msgstr "-fstrict-flex-arrays=<рівень> Контролює, коли треба розглядати кінцевий масив структури як гнучкий елемент масиву для доступу до елементів такого масиву. За замовчуванням всі кінцеві масиви структур розглядаються як гнучкі елементи масиву." #: c-family/c.opt:2149 #, no-c-format msgid "-fsso-struct=[big-endian|little-endian|native]\tSet the default scalar storage order." -msgstr "" +msgstr "-fsso-struct=[big-endian|little-endian|native]\tВстановити порядок зберігання скалярів за замовчуванням." #: c-family/c.opt:2165 #, no-c-format msgid "Display statistics accumulated during compilation." -msgstr "" +msgstr "Показування статистики, накопиченої під час компіляції." #: c-family/c.opt:2169 #, no-c-format msgid "Assume that values of enumeration type are always within the minimum range of that type." -msgstr "" +msgstr "Припускати, що значення перелічувального типу завжди знаходяться в мінімальному діапазоні цього типу." #: c-family/c.opt:2176 c-family/c.opt:2181 #, no-c-format msgid "Follow the C++17 evaluation order requirements for assignment expressions, shift, member function calls, etc." -msgstr "" +msgstr "Дотримуйтесь вимог C++17 щодо порядку оцінки виразів присвоєння, зсуву, викликів функцій-членів тощо." #: c-family/c.opt:2198 #, no-c-format msgid "Set the maximum number of template instantiation notes for a single warning or error." -msgstr "" +msgstr "Встановити максимальну кількість приміток про інстанціювання шаблону для одного попередження або помилки." #: c-family/c.opt:2205 #, no-c-format msgid "-ftemplate-depth=\tSpecify maximum template instantiation depth." -msgstr "" +msgstr "-ftemplate-depth=<число>\tВказати максимальну глибину інстанціювання шаблону." #: c-family/c.opt:2212 #, no-c-format msgid "-fno-threadsafe-statics\tDo not generate thread-safe code for initializing local statics." -msgstr "" +msgstr "-fno-threadsafe-statics\tНе генерувати потокобезпечний код для ініціалізації локальних статичних змінних." #: c-family/c.opt:2216 #, no-c-format msgid "When \"signed\" or \"unsigned\" is not given make the bitfield unsigned." -msgstr "" +msgstr "Якщо не вказано «signed» або «unsigned», зробити бітове поле беззнаковим." #: c-family/c.opt:2220 ada/gcc-interface/lang.opt:89 #, no-c-format msgid "Make \"char\" unsigned by default." -msgstr "" +msgstr "За замовчуванням зробити «char» беззнаковим." #: c-family/c.opt:2224 #, no-c-format msgid "Use __cxa_atexit to register destructors." -msgstr "" +msgstr "Використовуйте __cxa_atexit для реєстрації деструкторів." #: c-family/c.opt:2228 #, no-c-format msgid "Use __cxa_get_exception_ptr in exception handling." -msgstr "" +msgstr "Використовуйте __cxa_get_exception_ptr у обробці винятків." #: c-family/c.opt:2232 #, no-c-format msgid "Marks all inlined functions and methods as having hidden visibility." -msgstr "" +msgstr "Позначає всі вбудовані функції та методи як з прихованою видимістю." #: c-family/c.opt:2236 #, no-c-format msgid "Changes visibility to match Microsoft Visual Studio by default." -msgstr "" +msgstr "За замовчуванням змінює видимість, щоб відповідати Microsoft Visual Studio." #: c-family/c.opt:2248 #, no-c-format msgid "Emit common-like symbols as weak symbols." -msgstr "" +msgstr "Випускати символи, подібні до загальних, як слабкі символи." #: c-family/c.opt:2252 #, no-c-format msgid "-fwide-exec-charset=\tConvert all wide strings and character constants to character set ." -msgstr "" +msgstr "-fwide-exec-charset=\tПеретворити всі широкі рядки та символьні константи в набір символів ." #: c-family/c.opt:2256 #, no-c-format msgid "Generate a #line directive pointing at the current working directory." -msgstr "" +msgstr "Створити директиву #line, яка вказує на поточний робочий каталог." #: c-family/c.opt:2264 #, no-c-format msgid "Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode." -msgstr "" +msgstr "Створити лінивий пошук класу (за допомогою objc_getClass()) для використання в режимі Zero-Link." #: c-family/c.opt:2268 #, no-c-format msgid "Dump declarations to a .decl file." -msgstr "" +msgstr "Вивантажити оголошення в файл .decl." #: c-family/c.opt:2272 #, no-c-format msgid "-femit-struct-debug-baseonly\tAggressive reduced debug info for structs." -msgstr "" +msgstr "-femit-struct-debug-baseonly\tАгресивно зменшена інформація для налагодження структур." #: c-family/c.opt:2276 #, no-c-format msgid "-femit-struct-debug-reduced\tConservative reduced debug info for structs." -msgstr "" +msgstr "-femit-struct-debug-reduced\tКонсервативно зменшена інформація для налагодження структур." #: c-family/c.opt:2280 #, no-c-format msgid "-femit-struct-debug-detailed=\tDetailed reduced debug info for structs." -msgstr "" +msgstr "-femit-struct-debug-detailed=\tДетальна зменшена інформація для структур." #: c-family/c.opt:2284 #, no-c-format msgid "Interpret imaginary, fixed-point, or other gnu number suffix as the corresponding number literal rather than a user-defined number literal." -msgstr "" +msgstr "Інтерпретувати уявні, фіксовані або інші суфікси чисел GNU як відповідні числові літерали, а не визначені користувачем числові літерали." #: c-family/c.opt:2289 #, no-c-format msgid "-idirafter \tAdd to the end of the system include path." -msgstr "" +msgstr "-idirafter \tДодати в кінець системного шляху включення." #: c-family/c.opt:2293 #, no-c-format msgid "-imacros \tAccept definition of macros in ." -msgstr "" +msgstr "-imacros \tПрийняти визначення макросів у файлі ." #: c-family/c.opt:2297 #, no-c-format msgid "-imultilib \tSet to be the multilib include subdirectory." -msgstr "" +msgstr "-imultilib \tВстановити як підкаталог multilib для включення." #: c-family/c.opt:2301 #, no-c-format msgid "-include \tInclude the contents of before other files." -msgstr "" +msgstr "-include \tВключити вміст файлу перед іншими файлами." #: c-family/c.opt:2305 #, no-c-format msgid "-iprefix \tSpecify as a prefix for next two options." -msgstr "" +msgstr "-iprefix <шлях>\tВказати <шлях> як префікс для наступних двох опцій." #: c-family/c.opt:2309 #, no-c-format msgid "-isysroot \tSet to be the system root directory." -msgstr "" +msgstr "-isysroot <каталог>\tВстановити <каталог> як кореневий каталог системи." #: c-family/c.opt:2313 #, no-c-format msgid "-isystem \tAdd to the start of the system include path." -msgstr "" +msgstr "-isystem <каталог>\tДодати <каталог> в початок шляху включення системи." #: c-family/c.opt:2317 #, no-c-format msgid "-iquote \tAdd to the end of the quote include path." -msgstr "" +msgstr "-iquote <каталог>\tДодати <каталог> в кінець шляху включення в лапки." #: c-family/c.opt:2321 #, no-c-format msgid "-iwithprefix \tAdd to the end of the system include path." -msgstr "" +msgstr "-iwithprefix <каталог>\tДодати <каталог> в кінець шляху включення системи." #: c-family/c.opt:2325 #, no-c-format msgid "-iwithprefixbefore \tAdd to the end of the main include path." -msgstr "" +msgstr "-iwithprefixbefore <каталог>\tДодати <каталог> в кінець основного шляху включення." #: c-family/c.opt:2335 #, no-c-format msgid "Do not search standard system include directories (those specified with -isystem will still be used)." -msgstr "" +msgstr "Не шукати стандартні системні каталоги включення (те, що вказано з -isystem, все ще буде використовуватися)." #: c-family/c.opt:2339 #, no-c-format msgid "Do not search standard system include directories for C++." -msgstr "" +msgstr "Не шукати стандартні системні каталоги включення для C++." #: c-family/c.opt:2351 #, no-c-format msgid "Generate C header of platform-specific features." -msgstr "" +msgstr "Генерувати C-заголовок платформо-специфічних функцій." #: c-family/c.opt:2355 #, no-c-format msgid "Remap file names when including files." -msgstr "" +msgstr "Перейменовувати імена файлів при включенні файлів." #: c-family/c.opt:2359 c-family/c.opt:2363 #, no-c-format msgid "Conform to the ISO 1998 C++ standard revised by the 2003 technical corrigendum." -msgstr "" +msgstr "Відповідати стандарту ISO 1998 C++, переглянутому технічним коригуванням 2003 року." #: c-family/c.opt:2367 #, no-c-format msgid "Conform to the ISO 2011 C++ standard." -msgstr "" +msgstr "Відповідати стандарту ISO 2011 C++." #: c-family/c.opt:2371 #, no-c-format msgid "Deprecated in favor of -std=c++11." -msgstr "" +msgstr "Застарілий на користь -std=c++11." #: c-family/c.opt:2375 #, no-c-format msgid "Deprecated in favor of -std=c++14." -msgstr "" +msgstr "Застарілий на користь -std=c++14." #: c-family/c.opt:2379 #, no-c-format msgid "Conform to the ISO 2014 C++ standard." -msgstr "" +msgstr "Відповідати стандарту ISO 2014 C++." #: c-family/c.opt:2383 #, no-c-format msgid "Deprecated in favor of -std=c++17." -msgstr "" +msgstr "Застарілий на користь -std=c++17." #: c-family/c.opt:2387 #, no-c-format msgid "Conform to the ISO 2017 C++ standard." -msgstr "" +msgstr "Відповідати ISO 2017 стандарту C++." #: c-family/c.opt:2391 c-family/c.opt:2395 #, no-c-format msgid "Conform to the ISO 2020 C++ standard (experimental and incomplete support)." -msgstr "" +msgstr "Відповідати ISO 2020 стандарту C++ (експериментальна та неповна підтримка)." #: c-family/c.opt:2399 c-family/c.opt:2403 #, no-c-format msgid "Conform to the ISO 2023 C++ draft standard (experimental and incomplete support)." -msgstr "" +msgstr "Відповідати проекту стандарту C++ ISO 2023 (експериментальна та неповна підтримка)." #: c-family/c.opt:2407 c-family/c.opt:2545 #, no-c-format msgid "Conform to the ISO 2011 C standard." -msgstr "" +msgstr "Відповідати стандарту C ISO 2011." #: c-family/c.opt:2411 #, no-c-format msgid "Deprecated in favor of -std=c11." -msgstr "" +msgstr "Застарілий на користь -std=c11." #: c-family/c.opt:2415 c-family/c.opt:2419 c-family/c.opt:2549 #: c-family/c.opt:2553 #, no-c-format msgid "Conform to the ISO 2017 C standard (published in 2018)." -msgstr "" +msgstr "Відповідність стандарту C ISO 2017 (опубліковано в 2018 році)." #: c-family/c.opt:2423 #, no-c-format msgid "Conform to the ISO 202X C standard draft (experimental and incomplete support)." -msgstr "" +msgstr "Відповідність проекту стандарту C ISO 202X (експериментальна та неповна підтримка)." #: c-family/c.opt:2427 c-family/c.opt:2431 c-family/c.opt:2529 #, no-c-format msgid "Conform to the ISO 1990 C standard." -msgstr "" +msgstr "Відповідність стандарту C ISO 1990." #: c-family/c.opt:2435 c-family/c.opt:2537 #, no-c-format msgid "Conform to the ISO 1999 C standard." -msgstr "" +msgstr "Відповідність стандарту C ISO 1999." #: c-family/c.opt:2439 #, no-c-format msgid "Deprecated in favor of -std=c99." -msgstr "" +msgstr "Застарілий на користь -std=c99." #: c-family/c.opt:2443 c-family/c.opt:2448 #, no-c-format msgid "Conform to the ISO 1998 C++ standard revised by the 2003 technical corrigendum with GNU extensions." -msgstr "" +msgstr "Відповідність стандарту C++ ISO 1998, переглянутого технічним коригуванням 2003 року з розширеннями GNU." #: c-family/c.opt:2453 #, no-c-format msgid "Conform to the ISO 2011 C++ standard with GNU extensions." -msgstr "" +msgstr "Відповідність стандарту C++ ISO 2011 з розширеннями GNU." #: c-family/c.opt:2457 #, no-c-format msgid "Deprecated in favor of -std=gnu++11." -msgstr "" +msgstr "Застарілий на користь -std=gnu++11." #: c-family/c.opt:2461 #, no-c-format msgid "Deprecated in favor of -std=gnu++14." -msgstr "" +msgstr "Застарілий на користь -std=gnu++14." #: c-family/c.opt:2465 #, no-c-format msgid "Conform to the ISO 2014 C++ standard with GNU extensions." -msgstr "" +msgstr "Відповідати стандарту C++ ISO 2014 з розширеннями GNU." #: c-family/c.opt:2469 #, no-c-format msgid "Deprecated in favor of -std=gnu++17." -msgstr "" +msgstr "Застарілий на користь -std=gnu++17." #: c-family/c.opt:2473 #, no-c-format msgid "Conform to the ISO 2017 C++ standard with GNU extensions." -msgstr "" +msgstr "Відповідати стандарту C++ ISO 2017 з розширеннями GNU." #: c-family/c.opt:2477 c-family/c.opt:2481 #, no-c-format msgid "Conform to the ISO 2020 C++ standard with GNU extensions (experimental and incomplete support)." -msgstr "" +msgstr "Відповідати стандарту C++ ISO 2020 з розширеннями GNU (експериментальна та неповна підтримка)." #: c-family/c.opt:2485 c-family/c.opt:2489 #, no-c-format msgid "Conform to the ISO 2023 C++ draft standard with GNU extensions (experimental and incomplete support)." -msgstr "" +msgstr "Відповідати проекту стандарту C++ ISO 2023 з розширеннями GNU (експериментальна та неповна підтримка)." #: c-family/c.opt:2493 #, no-c-format msgid "Conform to the ISO 2011 C standard with GNU extensions." -msgstr "" +msgstr "Відповідати стандарту C ISO 2011 з розширеннями GNU." #: c-family/c.opt:2497 #, no-c-format msgid "Deprecated in favor of -std=gnu11." -msgstr "" +msgstr "Застарілий на користь -std=gnu11." #: c-family/c.opt:2501 c-family/c.opt:2505 #, no-c-format msgid "Conform to the ISO 2017 C standard (published in 2018) with GNU extensions." -msgstr "" +msgstr "Відповідати стандарту C ISO 2017 (опублікованому в 2018 році) з розширеннями GNU." #: c-family/c.opt:2509 #, no-c-format msgid "Conform to the ISO 202X C standard draft with GNU extensions (experimental and incomplete support)." -msgstr "" +msgstr "Відповідати проекту стандарту C ISO 202X з розширеннями GNU (експериментальна та неповна підтримка)." #: c-family/c.opt:2513 c-family/c.opt:2517 #, no-c-format msgid "Conform to the ISO 1990 C standard with GNU extensions." -msgstr "" +msgstr "Відповідати стандарту C ISO 1990 з розширеннями GNU." #: c-family/c.opt:2521 #, no-c-format msgid "Conform to the ISO 1999 C standard with GNU extensions." -msgstr "" +msgstr "Відповідати стандарту C ISO 1999 з розширеннями GNU." #: c-family/c.opt:2525 #, no-c-format msgid "Deprecated in favor of -std=gnu99." -msgstr "" +msgstr "Застарілий на користь -std=gnu99." #: c-family/c.opt:2533 #, no-c-format msgid "Conform to the ISO 1990 C standard as amended in 1994." -msgstr "" +msgstr "Відповідати стандарту C ISO 1990 з поправками 1994 року." #: c-family/c.opt:2541 #, no-c-format msgid "Deprecated in favor of -std=iso9899:1999." -msgstr "" +msgstr "Застарілий на користь -std=iso9899:1999." #: c-family/c.opt:2557 #, no-c-format msgid "-stdlib=[libstdc++|libc++]\tThe standard library to be used for C++ headers and runtime." -msgstr "" +msgstr "-stdlib=[libstdc++|libc++]\tСтандартна бібліотека, яка буде використовуватися для заголовків та виконання C++." #: c-family/c.opt:2574 #, no-c-format msgid "Enable traditional preprocessing." -msgstr "" +msgstr "Увімкнути традиційну попередню обробку." #: c-family/c.opt:2578 #, no-c-format msgid "-trigraphs\tSupport ISO C trigraphs." -msgstr "" +msgstr "-trigraphs\tПідтримка триграфів ISO C." #: c-family/c.opt:2582 #, no-c-format msgid "Do not predefine system-specific and GCC-specific macros." -msgstr "" +msgstr "Не визначати наперед системно-специфічні та GCC-специфічні макроси." #: ada/gcc-interface/lang.opt:61 #, no-c-format msgid "Dump Source Coverage Obligations." -msgstr "" +msgstr "Записати обовʼязки покриття вихідного коду." #: ada/gcc-interface/lang.opt:65 #, no-c-format msgid "Synonym of -gnatk8." -msgstr "" +msgstr "Синонім для -gnatk8." #: ada/gcc-interface/lang.opt:73 #, no-c-format msgid "Do not look for object files in standard path." -msgstr "" +msgstr "Не шукати обʼєктні файли в стандартному шляху." #: ada/gcc-interface/lang.opt:77 #, no-c-format msgid "Select the runtime." -msgstr "" +msgstr "Вибрати середовище виконання." #: ada/gcc-interface/lang.opt:93 #, no-c-format msgid "Catch typos." -msgstr "" +msgstr "Виявляти описки." #: ada/gcc-interface/lang.opt:97 #, no-c-format msgid "Set name of output ALI file (internal switch)." -msgstr "" +msgstr "Встановити імʼя вихідного файлу ALI (внутрішній перемикач)." #: ada/gcc-interface/lang.opt:101 #, no-c-format msgid "-gnat\tSpecify options to GNAT." -msgstr "" +msgstr "-gnat<опції>\tВказати параметри для GNAT." #: ada/gcc-interface/lang.opt:105 #, no-c-format msgid "Ignored." -msgstr "Проігноровано." +msgstr "Ігнорується." #: d/lang.opt:51 #, no-c-format msgid "-Hd \tWrite D interface files to directory ." -msgstr "" +msgstr "-Hd <кат>\tЗаписати файли інтерфейсу D у каталог <кат>." #: d/lang.opt:55 #, no-c-format msgid "-Hf \tWrite D interface to ." -msgstr "" +msgstr "-Hf <файл>\tЗаписати D інтерфейс у файл ." #: d/lang.opt:127 #, no-c-format msgid "Warn about casts that will produce a null result." -msgstr "" +msgstr "Попереджати про приведення типів, які призведуть до отримання значення null." #: d/lang.opt:143 #, no-c-format msgid "Warn from speculative compiles such as __traits(compiles)." -msgstr "" +msgstr "Попереджати про спекулятивні компіляції, такі як __traits(compiles)." #: d/lang.opt:155 #, no-c-format msgid "Generate JSON file." -msgstr "" +msgstr "Створити файл JSON." #: d/lang.opt:159 #, no-c-format msgid "-Xf \tWrite JSON output to the given ." -msgstr "" +msgstr "-Xf <файл>\tЗаписати JSON-вивід у вказаний <файл>." #: d/lang.opt:163 #, no-c-format msgid "Debug library to use instead of phobos." -msgstr "" +msgstr "Бібліотека для налагодження, яку слід використовувати замість phobos." #: d/lang.opt:167 #, no-c-format msgid "Default library to use instead of phobos." -msgstr "" +msgstr "Бібліотека за замовчуванням, яку слід використовувати замість phobos." #: d/lang.opt:171 #, no-c-format msgid "Do link the standard D startup files in the compilation." -msgstr "" +msgstr "Підключити стандартні файли запуску D під час компіляції." #: d/lang.opt:178 #, no-c-format msgid "Generate code for all template instantiations." -msgstr "" +msgstr "Генерувати код для всіх інстанціювань шаблонів." #: d/lang.opt:182 #, no-c-format msgid "Generate code for assert contracts." -msgstr "" +msgstr "Створити код для контрактів assert." #: d/lang.opt:190 #, no-c-format msgid "-fbounds-check=[on|safeonly|off]\tTurn array bounds checks on, in @safe code only, or off." -msgstr "" +msgstr "-fbounds-check=[on|safeonly|off]\tУвімкнути перевірку меж масиву, тільки в безпечному коді @safe, або вимкнути." #: d/lang.opt:232 #, no-c-format msgid "-fcheckaction=[throw,halt,context]\tBehavior on contract failure." -msgstr "" +msgstr "-fcheckaction=[throw,halt,context]\tПоведінка при порушенні контракту." #: d/lang.opt:248 #, no-c-format msgid "Compile in debug code." -msgstr "" +msgstr "Компілювати в режимі налагодження." #: d/lang.opt:252 #, no-c-format msgid "-fdebug=\tCompile in debug code identified by ." -msgstr "" +msgstr "-fdebug=<ідент>\tКомпілювати в режимі налагодження код, ідентифікований за допомогою <ідент>." #: d/lang.opt:256 #, no-c-format @@ -3650,1512 +3645,1492 @@ msgstr "Створити документацію." #: d/lang.opt:260 #, no-c-format msgid "-fdoc-dir=\tWrite documentation file to directory ." -msgstr "" +msgstr "-fdoc-dir=<кат>\tЗаписати файл документації в каталог <кат>." #: d/lang.opt:264 #, no-c-format msgid "-fdoc-file=\tWrite documentation to ." -msgstr "" +msgstr "-fdoc-file=<файл>\tЗаписати документацію в файл <файл>." #: d/lang.opt:268 #, no-c-format msgid "-fdoc-inc=\tInclude a Ddoc macro ." -msgstr "" +msgstr "-fdoc-inc=<файл>\tВключити макро Ddoc з <файл>." #: d/lang.opt:272 #, no-c-format msgid "Assume that standard D runtime libraries and \"D main\" exist." -msgstr "" +msgstr "Припустити, що існують стандартні бібліотеки виконання D та «D main»." #: d/lang.opt:276 #, no-c-format msgid "Add comments for ignored declarations in the generated C++ header." -msgstr "" +msgstr "Додати коментарі до ігнорованих оголошень у згенерованому заголовку C++." #: d/lang.opt:280 #, no-c-format msgid "-fdump-cxx-spec=\tWrite all declarations as C++ code to ." -msgstr "" +msgstr "-fdump-cxx-spec=<файл>\tЗаписати всі оголошення у вигляді коду C++ у <файл>." #: d/lang.opt:284 #, no-c-format msgid "Display the frontend AST after parsing and semantic passes." -msgstr "" +msgstr "Показувати AST frontend після проходження парсера та семантичних проходів." #: d/lang.opt:288 #, no-c-format msgid "-fextern-std=\tSet C++ name mangling compatibility with ." -msgstr "" +msgstr "-fextern-std=\tВстановити сумісність декорування імен C++ з ." #: d/lang.opt:313 #, no-c-format msgid "Ignore unsupported pragmas." -msgstr "" +msgstr "Ігнорувати непідтримувані pragma-директиви." #: d/lang.opt:317 #, no-c-format msgid "Generate code for class invariant contracts." -msgstr "" +msgstr "Створити код для контрактів незмінності класу." #: d/lang.opt:321 #, no-c-format msgid "Generate a default D main() function when compiling." -msgstr "" +msgstr "Генерувати типову функцію main() для D при компіляції." #: d/lang.opt:325 #, no-c-format msgid "-fmodule-file==\tuse as source file for ." -msgstr "" +msgstr "-fmodule-file==\tвикористовувати як вихідний файл для ." #: d/lang.opt:329 #, no-c-format msgid "Generate ModuleInfo struct for output module." -msgstr "" +msgstr "Генерувати структуру ModuleInfo для вихідного модуля." #: d/lang.opt:333 #, no-c-format msgid "Process all modules specified on the command line, but only generate code for the module specified by the argument." -msgstr "" +msgstr "Обробляти всі модулі, вказані в командному рядку, але генерувати код лише для модуля, вказаного аргументом." #: d/lang.opt:337 #, no-c-format msgid "Generate code for postcondition contracts." -msgstr "" +msgstr "Генерувати код для контрактів післяумов." #: d/lang.opt:341 #, no-c-format msgid "Generate code for precondition contracts." -msgstr "" +msgstr "Генерувати код для контрактів передумов." #: d/lang.opt:345 #, no-c-format msgid "Turn on all upcoming D language features." -msgstr "" +msgstr "Увімкнути всі майбутні функції мови D." #: d/lang.opt:349 #, no-c-format msgid "Implement D bit-fields." -msgstr "" +msgstr "Реалізувати бітові поля D." #: d/lang.opt:353 #, no-c-format msgid "Implement DIP1000: Scoped pointers." -msgstr "" +msgstr "Реалізувати DIP1000: Обмежені вказівники." #: d/lang.opt:357 #, no-c-format msgid "Implement DIP1008: Allow exceptions in @nogc code." -msgstr "" +msgstr "Реалізувати DIP1008: Дозволити виключення в коді @nogc." #: d/lang.opt:361 #, no-c-format msgid "Implement DIP1021: Mutable function arguments." -msgstr "" +msgstr "Реалізувати DIP1021: Змінні аргументи функцій." #: d/lang.opt:365 #, no-c-format msgid "Destruct fields of partially constructed objects." -msgstr "" +msgstr "Руйнувати поля частково побудованих обʼєктів." #: d/lang.opt:369 #, no-c-format msgid "Use field-wise comparisons for struct equality." -msgstr "" +msgstr "Використовувати порівняння по полях для рівності структур." #: d/lang.opt:373 #, no-c-format msgid "When a symbol is resolved, check `alias this' scope before going to upper scopes." -msgstr "" +msgstr "Коли символ вирішується, перевіряти область «alias this» перед переходом до верхніх областей." #: d/lang.opt:377 #, no-c-format msgid "Disallow unsound immutable conversions that were formerly incorrectly permitted." -msgstr "" +msgstr "Заборонити неправильні незворотні перетворення, які раніше неправильно дозволялися." #: d/lang.opt:381 #, no-c-format msgid "Implement 'in' parameters to mean scope const." -msgstr "" +msgstr "Реалізувати параметри 'in' для означення константного обсягу." #: d/lang.opt:385 #, no-c-format msgid "Implement 'in' contracts of overridden methods to be a superset of parent contract." -msgstr "" +msgstr "Реалізувати 'in' контракти перевизначених методів як підмножину контракту батьківського методу." #: d/lang.opt:389 #, no-c-format msgid "Disable access to shared memory objects." -msgstr "" +msgstr "Вимкнути доступ до обʼєктів спільної памʼяті." #: d/lang.opt:393 #, no-c-format msgid "Enable rvalue arguments to ref parameters." -msgstr "" +msgstr "Увімкнути передачу rvalue-аргументів в ref-параметри." #: d/lang.opt:397 #, no-c-format msgid "Disable access to variables marked `@system' from @safe code." -msgstr "" +msgstr "Вимкнути доступ до змінних, позначених як «@system», з коду @safe." #: d/lang.opt:401 #, no-c-format msgid "Compile release version." -msgstr "" +msgstr "Компілювати версію для випуску." #: d/lang.opt:405 #, no-c-format msgid "Turn off all revertable D language features." -msgstr "" +msgstr "Вимкнути всі можливості мови D, які можна скасувати." #: d/lang.opt:409 #, no-c-format msgid "Revert DIP1000: Scoped pointers." -msgstr "" +msgstr "Скасувати DIP1000: Змінні з областю видимості." #: d/lang.opt:413 #, no-c-format msgid "Don't destruct fields of partially constructed objects." -msgstr "" +msgstr "Не знищувати поля частково побудованих обʼєктів." #: d/lang.opt:417 #, no-c-format msgid "Don't use C-style integral promotion for unary '+', '-' and '~'." -msgstr "" +msgstr "Не використовувати C-стильне цілочисельне просування для унарних операторів '+', '-' та '~'." #: d/lang.opt:425 #, no-c-format msgid "-fsave-mixins=\tExpand and save mixins to file specified by ." -msgstr "" +msgstr "-fsave-mixins=<імʼя_файлу>\tРозгорнути та зберегти міксини у файл, вказаний параметром <імʼя_файлу>." #: d/lang.opt:429 #, no-c-format msgid "Generate code for switches without a default case." -msgstr "" +msgstr "Генерувати код для операторів «switch» без вказання «default»." #: d/lang.opt:433 #, no-c-format msgid "List information on all D language transitions." -msgstr "" +msgstr "Вивести інформацію про всі переходи мови D." #: d/lang.opt:437 #, no-c-format msgid "List all non-mutable fields which occupy an object instance." -msgstr "" +msgstr "Вивести списком всі незмінні поля, які займають екземпляр обʼєкта." #: d/lang.opt:441 #, no-c-format msgid "List all usages of 'in' on parameter." -msgstr "" +msgstr "Вивести списком всі використання 'in' на параметрі." #: d/lang.opt:445 #, no-c-format msgid "List all hidden GC allocations." -msgstr "" +msgstr "Вивести списком всі приховані виділення памʼяті GC." #: d/lang.opt:449 #, no-c-format msgid "List statistics on template instantiations." -msgstr "" +msgstr "Вивести списком статистику щодо інстанціювання шаблонів." #: d/lang.opt:453 #, no-c-format msgid "List all variables going into thread local storage." -msgstr "" +msgstr "Вивести список усіх змінних, які потрапляють у потокове локальне сховище." #: d/lang.opt:457 #, no-c-format msgid "Compile in unittest code." -msgstr "" +msgstr "Компілювати код для модульних тестів." #: d/lang.opt:461 #, no-c-format msgid "-fversion=\tCompile in version code identified by ." -msgstr "" +msgstr "-fversion=\tКомпілювати код версії, ідентифікований за допомогою ." #: d/lang.opt:465 #, no-c-format msgid "Emit template instantiations as weak symbols." -msgstr "" +msgstr "Видавати інстанціювання шаблонів як слабкі символи." #: d/lang.opt:485 #, no-c-format msgid "Do not link the standard D library in the compilation." -msgstr "" +msgstr "Не звʼязувати стандартну бібліотеку D під час компіляції." #: d/lang.opt:493 #, no-c-format msgid "Link the standard D library statically in the compilation." -msgstr "" +msgstr "Звʼязати стандартну бібліотеку D статично під час компіляції." #: d/lang.opt:497 #, no-c-format msgid "Link the standard D library dynamically in the compilation." -msgstr "" +msgstr "Звʼязати стандартну бібліотеку D динамічно під час компіляції." #: m2/lang.opt:35 #, no-c-format msgid "compiler checks to force definition module procedure parameter names with their implementation module counterpart" -msgstr "" +msgstr "перевірки компілятора для примусового вказання імен параметрів процедур визначення модуля з їхніми відповідниками в модулі реалізації" #: m2/lang.opt:39 #, no-c-format msgid "compiler warns if a cast is being used on types of differing sizes" -msgstr "" +msgstr "компілятор попереджає, якщо використовується приведення типів різних розмірів" #: m2/lang.opt:43 #, no-c-format msgid "inform user which parameters will be passed by reference" -msgstr "" +msgstr "повідомляти користувача, які параметри будуть передані за посиланням" #: m2/lang.opt:47 #, no-c-format msgid "extra compile time semantic checking, typically tries to catch poor programming style" -msgstr "" +msgstr "додаткова перевірка семантики під час компіляції, зазвичай намагається виявити недоліки в стилі програмування" #: m2/lang.opt:51 #, no-c-format msgid "automatically initializes all pointers to NIL" -msgstr "" +msgstr "автоматично ініціалізує всі вказівники значенням NIL" #: m2/lang.opt:55 #, no-c-format msgid "turns on runtime subrange, array index and indirection via NIL pointer checking" -msgstr "" +msgstr "включає перевірку підмножин, індексів масивів та операцій з вказівниками через перевірку на NIL" #: m2/lang.opt:59 #, no-c-format msgid "turns on runtime checking to check whether a CASE statement requires an ELSE clause when one was not specified" -msgstr "" +msgstr "увімкнути перевірку під час виконання, щоб перевірити, чи потрібен оператор ELSE у виразі CASE, якщо він не був вказаний" #: m2/lang.opt:63 #, no-c-format msgid "use cpp to preprocess the module" -msgstr "" +msgstr "використовуйте cpp для попередньої обробки модуля" #: m2/lang.opt:67 m2/lang.opt:71 #, no-c-format msgid "passed to the preprocessor if -fcpp is used (internal switch)" -msgstr "" +msgstr "передається препроцесору, якщо використовується -fcpp (внутрішній перемикач)" #: m2/lang.opt:75 #, no-c-format msgid "call a real function, rather than the builtin equivalent" -msgstr "" +msgstr "викликати реальну функцію, а не вбудований еквівалент" #: m2/lang.opt:79 #, no-c-format msgid "turn on internal debugging of the compiler (internal switch)" -msgstr "" +msgstr "увімкнути внутрішнє налагодження компілятора (внутрішній перемикач)" #: m2/lang.opt:83 #, no-c-format msgid "turn on quadruple tracing (internal switch)" -msgstr "" +msgstr "увімкнути чотирикратне відстеження (внутрішній перемикач)" #: m2/lang.opt:87 #, no-c-format msgid "turn on the Modula-2 api tracing (internal switch)" -msgstr "" +msgstr "увімкнути відстеження api Modula-2 (внутрішній перемикач)" #: m2/lang.opt:91 #, no-c-format msgid "turn on the Modula-2 function line number generation (internal switch)" -msgstr "" +msgstr "увімкнути генерацію номерів рядків функцій Modula-2 (внутрішній перемикач)" #: m2/lang.opt:95 #, no-c-format msgid "recognise the specified suffix as a definition module filename" -msgstr "" +msgstr "визнати вказаний суфікс як імʼя файлу модуля визначення" #: m2/lang.opt:99 #, no-c-format msgid "display all inbuilt system items" -msgstr "" +msgstr "показувати всі вбудовані системні елементи" #: m2/lang.opt:103 #, no-c-format msgid "allows opaque types to be implemented as any type (a GNU Modula-2 extension)" -msgstr "" +msgstr "дозволяє реалізувати непрозорі типи як будь-який тип (розширення GNU Modula-2)" #: m2/lang.opt:107 #, no-c-format msgid "turns on runtime checking to check whether a floating point number will exceed range" -msgstr "" +msgstr "увімкнути перевірку під час виконання, щоб перевірити, чи перевищує діапазон плаваюча точка" #: m2/lang.opt:111 #, no-c-format msgid "create a topologically sorted module list from all dependent modules used in the application" -msgstr "" +msgstr "створити список модулів, відсортованих за топологією, з усіх залежних модулів, використаних у програмі" #: m2/lang.opt:115 m2/lang.opt:203 #, no-c-format msgid "turns on all range checking for numerical values" -msgstr "" +msgstr "увімкнути всі перевірки діапазону для числових значень" #: m2/lang.opt:119 #, no-c-format msgid "use ISO dialect of Modula-2" -msgstr "" +msgstr "використовувати ISO діалект Modula-2" #: m2/lang.opt:123 #, no-c-format msgid "specify the library order, the libraries may be specified by a comma separated abbreviation: log,min,pim,iso or by directory names: m2log,m2min,m2pim,m2iso." -msgstr "" +msgstr "вказати порядок бібліотек, бібліотеки можуть бути вказані комою розділеними абревіатурами: log,min,pim,iso або за назвами каталогів: m2log,m2min,m2pim,m2iso." #: m2/lang.opt:127 #, no-c-format msgid "set all location values to a specific value (internal switch)" -msgstr "" +msgstr "встановити всі значення розташування на певне значення (внутрішній перемикач)" #: m2/lang.opt:131 #, no-c-format msgid "generate extra nops to improve debugging, producing an instruction for every code related keyword" -msgstr "" +msgstr "генерувати додаткові nops для поліпшення налагодження, створюючи інструкцію для кожного ключового слова, повʼязаного з кодом" #: m2/lang.opt:135 #, no-c-format msgid "generate error messages which render keywords in lower case" -msgstr "" +msgstr "генерувати повідомлення про помилки, які показують ключові слова у нижньому регістрі" #: m2/lang.opt:139 #, no-c-format msgid "specify the module mangled prefix name for all modules in the following include paths" -msgstr "" +msgstr "вказати декороване імʼя префікса модуля для всіх модулів у наступних шляхах включення" #: m2/lang.opt:147 #, no-c-format msgid "insert plugin to identify runtime errors at compiletime" -msgstr "" +msgstr "вставити плагін для виявлення помилок в час компіляції" #: m2/lang.opt:151 #, no-c-format msgid "specify the module mangled prefix name" -msgstr "" +msgstr "вказати декороване імʼя префікса модуля" #: m2/lang.opt:155 #, no-c-format msgid "display statistics about the amount of source lines compiled and symbols used" -msgstr "" +msgstr "показувати статистику про кількість скомпільованих рядків початкового коду та використаних символів" #: m2/lang.opt:159 #, no-c-format msgid "experimental flag to turn on the new strict type checker" -msgstr "" +msgstr "експериментальний прапорець для увімкнення нового строгого перевіряльника типів" #: m2/lang.opt:163 #, no-c-format msgid "compile all implementation modules and program module at once" -msgstr "" +msgstr "компілювати всі модулі реалізації та модуль програми одночасно" #: m2/lang.opt:167 #, no-c-format msgid "recognise the specified suffix as implementation and module filenames" -msgstr "" +msgstr "визнати вказаний суфікс як імена файлів реалізації та модуля" #: m2/lang.opt:171 #, no-c-format msgid "turns on runtime checking to detect accessing data through a NIL value pointer" -msgstr "" +msgstr "увімкнути перевірку під час виконання для виявлення доступу до даних через вказівник зі значенням NIL" #: m2/lang.opt:175 #, no-c-format msgid "use PIM [234] dialect of Modula-2" -msgstr "" +msgstr "використовувати діалект PIM [234] Modula-2" #: m2/lang.opt:179 #, no-c-format msgid "use PIM 2 dialect of Modula-2" -msgstr "" +msgstr "використовувати діалект PIM 2 Modula-2" #: m2/lang.opt:183 #, no-c-format msgid "use PIM 3 dialect of Modula-2" -msgstr "" +msgstr "використовувати діалект PIM 3 Modula-2" #: m2/lang.opt:187 #, no-c-format msgid "use PIM 4 dialect of Modula-2" -msgstr "" +msgstr "використовувати діалект PIM 4 Modula-2" #: m2/lang.opt:191 #, no-c-format msgid "force positive result from MOD and DIV result floor" -msgstr "" +msgstr "примусити позитивний результат від округлення результату MOD та DIV" #: m2/lang.opt:195 #, no-c-format msgid "link against the pthread library (default on)" -msgstr "" +msgstr "посилання на бібліотеку pthread (за замовчуванням увімкнено)" #: m2/lang.opt:199 #, no-c-format msgid "internal compiler debugging information, dump the list of quadruples" -msgstr "" +msgstr "внутрішня інформація для налагодження компілятора, вивести список квадруплів" #: m2/lang.opt:207 #, no-c-format msgid "turns on runtime checking for functions which finish without executing a RETURN statement" -msgstr "" +msgstr "увімкнути перевірку часу виконання для функцій, які завершуються без виконання оператора RETURN" #: m2/lang.opt:211 #, no-c-format msgid "specify the list of runtime modules and their initialization order" -msgstr "" +msgstr "вказати список модулів часу виконання та їх порядок ініціалізації" #: m2/lang.opt:215 #, no-c-format msgid "the modules initialization order is dynamically determined by M2RTS and application dependencies" -msgstr "" +msgstr "порядок ініціалізації модулів динамічно визначається M2RTS та залежностями програми" #: m2/lang.opt:219 #, no-c-format msgid "generate a C source scaffold for the current module being compiled" -msgstr "" +msgstr "створити каркас джерела на мові C для поточного модуля, який компілюється" #: m2/lang.opt:223 #, no-c-format msgid "generate a C++ source scaffold for the current module being compiled" -msgstr "" +msgstr "створити риштування джерела на мові C++ для поточного модуля, який компілюється" #: m2/lang.opt:227 -#, fuzzy, no-c-format -#| msgid "Generate hardware abs instructions." +#, no-c-format msgid "generate the main function" -msgstr "Створити апаратні інструкції abs." +msgstr "створити головну функцію" #: m2/lang.opt:231 #, no-c-format msgid "generate static scaffold initialization and finalization for every module inside main" -msgstr "" +msgstr "створити статичну ініціалізацію та фіналізацію риштування для кожного модуля всередині головної функції" #: m2/lang.opt:235 -#, fuzzy, no-c-format -#| msgid "Create a shared library." +#, no-c-format msgid "generate a shared library from the module" -msgstr "Створити бібліотеку спільного використання." +msgstr "створити спільну бібліотеку з модуля" #: m2/lang.opt:239 #, no-c-format msgid "turns on all software runtime checking (an abbreviation for -fnil -frange -findex -fwholediv -fcase -freturn -fwholevalue -ffloatvalue)" -msgstr "" +msgstr "увімкнути всі перевірки програмного забезпечення під час виконання (скорочення для -fnil -frange -findex -fwholediv -fcase -freturn -fwholevalue -ffloatvalue)" #: m2/lang.opt:243 #, no-c-format msgid "display the location of module source files as they are compiled" -msgstr "" +msgstr "показувати розташування файлів джерела модуля під час компіляції" #: m2/lang.opt:247 #, no-c-format msgid "create a swig interface file for the module" -msgstr "" +msgstr "створити файл інтерфейсу SWIG для модуля" #: m2/lang.opt:251 #, no-c-format msgid "optimize non var unbounded parameters by passing it by reference, providing it is not written to within the callee procedure." -msgstr "" +msgstr "оптимізувати незмінні незвʼязані параметри, передаючи їх за посиланням, за умови, що вони не змінюються у процедурі, яка їх викликає." #: m2/lang.opt:255 #, no-c-format msgid "orders the initialization/finalializations for scaffold-static or force linking of modules if scaffold-dynamic" -msgstr "" +msgstr "впорядковує ініціалізацію/фіналізацію для статичного риштування або примусового звʼязування модулів, якщо риштування динамічне" #: m2/lang.opt:263 #, no-c-format msgid "turns on all division and modulus by zero checking for ordinal values" -msgstr "" +msgstr "увімкнути перевірку ділення на нуль та залишку від ділення для ординальних значень" #: m2/lang.opt:267 #, no-c-format msgid "turns on runtime checking to check whether a whole number will exceed range" -msgstr "" +msgstr "увімкнути перевірку під час виконання, щоб перевірити, чи перевищить ціле число діапазон" #: m2/lang.opt:271 #, no-c-format msgid "Link the standard Modula-2 libraries statically in the compilation." -msgstr "" +msgstr "Статично звʼязати стандартні бібліотеки Modula-2 під час компіляції." #: m2/lang.opt:412 m2/lang.opt:416 #, no-c-format msgid "save temporary preprocessed files" -msgstr "" +msgstr "зберегти тимчасові попередньо оброблені файли" #: go/lang.opt:42 #, no-c-format msgid "-fgo-c-header=\tWrite Go struct definitions to file as C code." -msgstr "" +msgstr "-fgo-c-header=<файл>\tЗаписати визначення структур Go у файл у вигляді коду C." #: go/lang.opt:46 #, no-c-format msgid "Add explicit checks for division by zero." -msgstr "" +msgstr "Додати явні перевірки на ділення на нуль." #: go/lang.opt:50 #, no-c-format msgid "Add explicit checks for division overflow in INT_MIN / -1." -msgstr "" +msgstr "Додати явні перевірки на переповнення ділення в INT_MIN / -1." #: go/lang.opt:54 #, no-c-format msgid "Apply special rules for compiling runtime package." -msgstr "" +msgstr "Застосувати спеціальні правила для компіляції пакету виконавчої системи." #: go/lang.opt:58 #, no-c-format msgid "-fgo-dump-\tDump Go frontend internal information." -msgstr "" +msgstr "-fgo-dump-<тип>\tВивести внутрішню інформацію про фронтенд Go." #: go/lang.opt:62 #, no-c-format msgid "-fgo-embedcfg=\tList embedded files via go:embed." -msgstr "" +msgstr "-fgo-embedcfg=<файл>\tВивести списком вбудовані файли за допомогою go:embed." #: go/lang.opt:66 #, no-c-format msgid "-fgo-optimize-\tTurn on optimization passes in the frontend." -msgstr "" +msgstr "-fgo-optimize-<тип>\tУвімкнути проходи оптимізації в фронтенді." #: go/lang.opt:70 #, no-c-format msgid "-fgo-pkgpath=\tSet Go package path." -msgstr "" +msgstr "-fgo-pkgpath=<рядок>\tВстановити шлях пакету Go." #: go/lang.opt:74 #, no-c-format msgid "-fgo-prefix=\tSet package-specific prefix for exported Go names." -msgstr "" +msgstr "-fgo-prefix=<рядок>\tВстановити пакет-специфічний префікс для експортованих імен Go." #: go/lang.opt:78 #, no-c-format msgid "-fgo-relative-import-path=\tTreat a relative import as relative to path." -msgstr "" +msgstr "-fgo-relative-import-path=<шлях>\tТрактувати відносний імпорт як відносний до шляху." #: go/lang.opt:82 #, no-c-format msgid "Functions which return values must end with return statements." -msgstr "" +msgstr "Функції, які повертають значення, повинні закінчуватися заявами return." #: go/lang.opt:86 #, no-c-format msgid "Emit debugging information related to the escape analysis pass when run with -fgo-optimize-allocs." -msgstr "" +msgstr "Вивести інформацію для налагодження, повʼязану з проходом аналізу втечі, коли виконується з -fgo-optimize-allocs." #: go/lang.opt:90 #, no-c-format msgid "-fgo-debug-escape-hash=\tHash value to debug escape analysis." -msgstr "" +msgstr "-fgo-debug-escape-hash=<рядок>\tХеш-значення для налагодження аналізу втечі." #: go/lang.opt:94 #, no-c-format msgid "Emit optimization diagnostics." -msgstr "" +msgstr "Вивести діагностичну інформацію про оптимізацію." #: analyzer/analyzer.opt:27 #, no-c-format msgid "The maximum number of 'after supernode' exploded nodes within the analyzer per supernode, before terminating analysis." -msgstr "" +msgstr "Максимальна кількість вибухнутих вузлів 'після супервузла' в аналізаторі на кожен супервузол, перед припиненням аналізу." #: analyzer/analyzer.opt:31 #, no-c-format msgid "The maximum number of exploded nodes per program point within the analyzer, before terminating analysis of that point." -msgstr "" +msgstr "Максимальна кількість вибухнутих вузлів на кожну точку програми в аналізаторі, перед припиненням аналізу цієї точки." #: analyzer/analyzer.opt:35 #, no-c-format msgid "The maximum number of constraints per state." -msgstr "" +msgstr "Максимальна кількість обмежень на стан." #: analyzer/analyzer.opt:39 #, no-c-format msgid "The maximum number of infeasible edges to reject before declaring a diagnostic as infeasible." -msgstr "" +msgstr "Максимальна кількість неможливих ребер, які слід відхилити, перш ніж оголосити діагностику як неможливу." #: analyzer/analyzer.opt:43 #, no-c-format msgid "The maximum number of times a callsite can appear in a call stack within the analyzer, before terminating analysis of a call that would recurse deeper." -msgstr "" +msgstr "Максимальна кількість разів, які виклик може зʼявитися в стеку викликів в аналізаторі, перед припиненням аналізу виклику, який рекурсивно викликається глибше." #: analyzer/analyzer.opt:47 #, no-c-format msgid "The maximum depth of a symbolic value, before approximating the value as unknown." -msgstr "" +msgstr "Максимальна глибина символьного значення, перед наближенням значення як невідомого." #: analyzer/analyzer.opt:51 #, no-c-format msgid "The minimum number of supernodes within a function for the analyzer to consider summarizing its effects at call sites." -msgstr "" +msgstr "Мінімальна кількість супервузлів у межах функції, яку аналізатор вважає для узагальнення її ефектів на місцях виклику." #: analyzer/analyzer.opt:55 #, no-c-format msgid "The maximum depth of exploded nodes that should appear in a dot dump before switching to a less verbose format." -msgstr "" +msgstr "Максимальна глибина вибухнутих вузлів, які повинні зʼявлятися в дампі точок, перш ніж перейти до менш докладного формату." #: analyzer/analyzer.opt:59 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a pointer to a buffer is assigned to an incompatible type." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких вказівник на буфер призначається несумісному типу." #: analyzer/analyzer.opt:63 #, no-c-format msgid "Warn about code paths in which a pointer is checked for NULL after it has already been dereferenced." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких після вже виконаного розіменування перевіряється вказівник на NULL." #: analyzer/analyzer.opt:67 #, no-c-format msgid "Warn about code paths in which a stdio FILE can be closed more than once." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких stdio FILE може бути закритий більше одного разу." #: analyzer/analyzer.opt:71 #, no-c-format msgid "Warn about code paths in which a pointer can be freed more than once." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких вказівник може бути звільнений більше одного разу." #: analyzer/analyzer.opt:75 #, no-c-format msgid "Warn about code paths in which sensitive data is written to a file." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких записується чутлива інформація в файл." #: analyzer/analyzer.opt:79 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which sensitive data is copied across a security boundary." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких чутлива інформація копіюється через межу безпеки." #: analyzer/analyzer.opt:83 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which read on a write-only file descriptor is attempted, or vice versa." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких спробується читати з файлового дескриптора, який доступний тільки для запису, або навпаки." #: analyzer/analyzer.opt:87 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a file descriptor can be closed more than once." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких файловий дескриптор може бути закритий більше одного разу." #: analyzer/analyzer.opt:91 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a file descriptor is not closed." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких файловий дескриптор не закрито." #: analyzer/analyzer.opt:95 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which an operation is attempted in the wrong phase of a file descriptor's lifetime." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких спроба виконання операції відбувається в неправильній фазі життєвого циклу файлового дескриптора." #: analyzer/analyzer.opt:99 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which an operation is attempted on the wrong type of file descriptor." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких спроба виконання операції відбувається на неправильному типі файлового дескриптора." #: analyzer/analyzer.opt:103 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a read or write is performed on a closed file descriptor." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких виконується читання або запис на закритому файловому дескрипторі." #: analyzer/analyzer.opt:107 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a file descriptor is used without being checked for validity." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких використовується файловий дескриптор без перевірки його валідності." #: analyzer/analyzer.opt:111 #, no-c-format msgid "Warn about code paths in which a stdio FILE is not closed." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких не закрито stdio FILE." #: analyzer/analyzer.opt:115 #, no-c-format msgid "Warn about code paths in which a non-heap pointer is freed." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких звільняється не-heap вказівник." #: analyzer/analyzer.opt:119 #, no-c-format msgid "Warn about code paths in which floating-point arithmetic is used in locations where precise computation is needed." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких використовується плаваюча точка арифметика в місцях, де потрібні точні обчислення." #: analyzer/analyzer.opt:123 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths which appear to lead to infinite recursion." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, які, здається, призводять до безкінечної рекурсії." #: analyzer/analyzer.opt:127 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a NULL function pointer is called." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких викликається NULL вказівник на функцію." #: analyzer/analyzer.opt:131 #, no-c-format msgid "Warn about code paths in which a heap-allocated pointer leaks." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких витікає вказівник, виділений з купи." #: analyzer/analyzer.opt:135 #, no-c-format msgid "Warn about code paths in which the wrong deallocation function is called." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких викликається неправильна функція звільнення памʼяті." #: analyzer/analyzer.opt:139 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a write or read to a buffer is out-of-bounds." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких запис або читання в буфер виходить за межі." #: analyzer/analyzer.opt:143 #, no-c-format msgid "Warn about code paths in which a possibly-NULL value is passed to a must-not-be-NULL function argument." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких можливо-NULL значення передається в аргумент функції, який не може бути NULL." #: analyzer/analyzer.opt:147 #, no-c-format msgid "Warn about code paths in which a possibly-NULL pointer is dereferenced." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких можливо-NULL вказівник розіменовується." #: analyzer/analyzer.opt:151 #, no-c-format msgid "Warn about code paths in which an async-signal-unsafe function is called from a signal handler." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких з сигнального обробника викликається функція, яка не є безпечною для асинхронних сигналів." #: analyzer/analyzer.opt:155 #, no-c-format msgid "Warn about code paths in which NULL is passed to a must-not-be-NULL function argument." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких NULL передається в аргумент функції, який не може бути NULL." #: analyzer/analyzer.opt:159 #, no-c-format msgid "Warn about code paths in which a NULL pointer is dereferenced." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких розіменовується NULL-вказівник." #: analyzer/analyzer.opt:163 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which an on-stack buffer is passed to putenv." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких на стеку передається буфер для putenv." #: analyzer/analyzer.opt:167 #, no-c-format msgid "Warn about code paths in which a shift with negative count is attempted." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких виконується зсув з відʼємним лічильником." #: analyzer/analyzer.opt:171 #, no-c-format msgid "Warn about code paths in which a shift with count >= width of type is attempted." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких виконується зсув з лічильником >= ширини типу." #: analyzer/analyzer.opt:175 #, no-c-format msgid "Warn about code paths in which a longjmp rewinds to a jmp_buf saved in a stack frame that has returned." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких longjmp перекручує до jmp_buf, збереженого в стековому фреймі, який повернувся." #: analyzer/analyzer.opt:179 #, no-c-format msgid "Warn about code paths in which an unsanitized value is used as an allocation size." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких невідфільтроване значення використовується як розмір виділення памʼяті." #: analyzer/analyzer.opt:183 #, no-c-format msgid "Warn about code paths in which an unsanitized value is used as an array index." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких невідфільтроване значення використовується як індекс масиву." #: analyzer/analyzer.opt:187 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which an 'assert()' is made involving an unsanitized value." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких використовується 'assert()', що включає невідфільтроване значення." #: analyzer/analyzer.opt:191 #, no-c-format msgid "Warn about code paths in which an unsanitized value is used as a divisor." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких невідфільтроване значення використовується як дільник." #: analyzer/analyzer.opt:195 #, no-c-format msgid "Warn about code paths in which an unsanitized value is used as a pointer offset." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких невідфільтроване значення використовується як зсув вказівника." #: analyzer/analyzer.opt:199 #, no-c-format msgid "Warn about code paths in which an unsanitized value is used as a size." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких невідфільтроване значення використовується як розмір." #: analyzer/analyzer.opt:203 #, no-c-format msgid "Warn about code paths in which a freed value is used." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких використовується відпущена значення." #: analyzer/analyzer.opt:207 #, no-c-format msgid "Warn about code paths in which a pointer to a stale stack frame is used." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких використовується вказівник на застарілий стековий фрейм." #: analyzer/analyzer.opt:211 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which va_arg uses the wrong type." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких va_arg використовує неправильний тип." #: analyzer/analyzer.opt:215 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which va_arg is used too many times on a va_list." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких va_arg використовується занадто багато разів на va_list." #: analyzer/analyzer.opt:219 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which va_start or va_copy is used without a corresponding va_end." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких va_start або va_copy використовується без відповідного va_end." #: analyzer/analyzer.opt:223 -#, fuzzy, no-c-format -#| msgid "Warn about code paths which attempt to write to a string literal." +#, no-c-format msgid "Warn about code paths in which a va_list is used after va_end." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, в яких va_list використовується після va_end." #: analyzer/analyzer.opt:227 #, no-c-format msgid "Warn about code paths which attempt to write to a const object." -msgstr "" +msgstr "Попереджувати про шляхи коду, які намагаються записати в const-обʼєкт." #: analyzer/analyzer.opt:231 #, no-c-format msgid "Warn about code paths which attempt to write to a string literal." -msgstr "Попереджати про шляхи коду, у яких робиться спроба записати до рядкового літерала." +msgstr "Попереджувати про шляхи коду, які намагаються записати в літерал рядка." #: analyzer/analyzer.opt:235 #, no-c-format msgid "Warn about code paths in which an uninitialized value is used." -msgstr "" +msgstr "Попереджувати про шляхи коду, в яких використовується неініціалізоване значення." #: analyzer/analyzer.opt:239 #, no-c-format msgid "Warn if the code is too complicated for the analyzer to fully explore." -msgstr "" +msgstr "Попереджувати, якщо код занадто складний для повного дослідження аналізатором." #: analyzer/analyzer.opt:243 #, no-c-format msgid "Restrict the analyzer to run just the named checker." -msgstr "" +msgstr "Обмежити роботу аналізатора лише вказаним перевіряючим." #: analyzer/analyzer.opt:247 #, no-c-format msgid "Avoid combining multiple statements into one exploded edge." -msgstr "" +msgstr "Уникати поєднання кількох операторів в одне вибухнуте ребро." #: analyzer/analyzer.opt:251 #, no-c-format msgid "Verify that paths are feasible when emitting diagnostics." -msgstr "" +msgstr "Перевіряти, що шляхи є доцільними при видачі діагностичних повідомлень." #: analyzer/analyzer.opt:255 #, no-c-format msgid "Issue a note when diagnostics are deduplicated." -msgstr "" +msgstr "Видавати примітку, коли діагностичні повідомлення зводяться до одного." #: analyzer/analyzer.opt:259 #, no-c-format msgid "Purge unneeded state during analysis." -msgstr "" +msgstr "Видалити непотрібний стан під час аналізу." #: analyzer/analyzer.opt:263 #, no-c-format msgid "Merge similar-enough states during analysis." -msgstr "" +msgstr "Обʼєднати достатньо схожі стани під час аналізу." #: analyzer/analyzer.opt:267 #, no-c-format msgid "Stop exploring an execution path after certain diagnostics." -msgstr "" +msgstr "Зупинити дослідження шляху виконання після певних діагностичних повідомлень." #: analyzer/analyzer.opt:271 #, no-c-format msgid "Enable transitivity of constraints during analysis." -msgstr "" +msgstr "Увімкнути транзитивність обмежень під час аналізу." #: analyzer/analyzer.opt:275 #, no-c-format msgid "Approximate the effect of function calls to simplify analysis." -msgstr "" +msgstr "Наблизити ефект викликів функцій для спрощення аналізу." #: analyzer/analyzer.opt:279 #, no-c-format msgid "Try to reconstruct function calls and returns after inlining." -msgstr "" +msgstr "Спроба відновити виклики функцій та повернення після інлайнування." #: analyzer/analyzer.opt:283 #, no-c-format msgid "Emit more verbose descriptions of control flow in diagnostics." -msgstr "" +msgstr "Виводити більш докладні описи потоку керування в діагностиці." #: analyzer/analyzer.opt:287 #, no-c-format msgid "Emit more verbose descriptions of state changes in diagnostics." -msgstr "" +msgstr "Виводити більш докладні описи змін стану в діагностиці." #: analyzer/analyzer.opt:291 #, no-c-format msgid "Control which events are displayed in diagnostic paths." -msgstr "" +msgstr "Контролюйте, які події показуються в діагностичних шляхах." #: analyzer/analyzer.opt:295 #, no-c-format msgid "Dump various analyzer internals to SRCFILE.analyzer.txt." -msgstr "" +msgstr "Вивантажте різні внутрішні частини аналізатора в SRCFILE.analyzer.txt." #: analyzer/analyzer.opt:299 #, no-c-format msgid "Dump various analyzer internals to stderr." -msgstr "" +msgstr "Вивантажте різні внутрішні частини аналізатора в stderr." #: analyzer/analyzer.opt:303 #, no-c-format msgid "Dump analyzer-specific call graph information to a SRCFILE.callgraph.dot file." -msgstr "" +msgstr "Вивантажте інформацію про граф викликів, специфічну для аналізатора, в файл SRCFILE.callgraph.dot." #: analyzer/analyzer.opt:307 #, no-c-format msgid "Dump the analyzer exploded graph to a SRCFILE.eg.dot file." -msgstr "" +msgstr "Вивантажте вибухнутий граф аналізатора в файл SRCFILE.eg.dot." #: analyzer/analyzer.opt:311 #, no-c-format msgid "Emit diagnostics showing the location of nodes in the exploded graph." -msgstr "" +msgstr "Виводьте діагностику, показуючи розташування вузлів у вибухнутому графі." #: analyzer/analyzer.opt:315 #, no-c-format msgid "Dump a textual representation of the exploded graph to SRCFILE.eg.txt." -msgstr "" +msgstr "Зберегти текстове представлення вибухнутого графа у файл SRCFILE.eg.txt." #: analyzer/analyzer.opt:319 #, no-c-format msgid "Dump a textual representation of the exploded graph to SRCFILE.eg-ID.txt." -msgstr "" +msgstr "Зберегти текстове представлення вибухнотого графа у файл SRCFILE.eg-ID.txt." #: analyzer/analyzer.opt:323 #, no-c-format msgid "Dump a textual representation of each diagnostic's exploded path to SRCFILE.IDX.KIND.epath.txt." -msgstr "" +msgstr "Зберегти текстове представлення вибухнутого шляху для кожного діагностичного повідомлення у файл SRCFILE.IDX.KIND.epath.txt." #: analyzer/analyzer.opt:327 #, no-c-format msgid "Dump various analyzer internals to SRCFILE.*.fg.dot and SRCFILE.*.tg.dot." -msgstr "" +msgstr "Зберегти різноманітні внутрішні дані аналізатора у файли SRCFILE.*.fg.dot та SRCFILE.*.tg.dot." #: analyzer/analyzer.opt:331 #, no-c-format msgid "Dump analyzer-specific data to a SRCFILE.analyzer.json.gz file." -msgstr "" +msgstr "Зберегти специфічні дані аналізатора у файл SRCFILE.analyzer.json.gz." #: analyzer/analyzer.opt:335 #, no-c-format msgid "Dump state-purging information to a SRCFILE.state-purge.dot file." -msgstr "" +msgstr "Зберегти інформацію про видалення стану у файл SRCFILE.state-purge.dot." #: analyzer/analyzer.opt:339 #, no-c-format msgid "Dump the analyzer supergraph to a SRCFILE.supergraph.dot file." -msgstr "" +msgstr "Зберегти суперграф аналізатора у файл SRCFILE.supergraph.dot." #: analyzer/analyzer.opt:343 #, no-c-format msgid "Emit custom warnings with internal details intended for analyzer developers." -msgstr "" +msgstr "Виводити користувацькі попередження з внутрішніми деталями, призначеними для розробників аналізатора." #: config/vms/vms.opt:27 #, no-c-format msgid "Malloc data into P2 space." -msgstr "" +msgstr "Виділити памʼять для даних у просторі P2." #: config/vms/vms.opt:31 #, no-c-format msgid "Set name of main routine for the debugger." -msgstr "" +msgstr "Встановити імʼя головної процедури для відлагоджувача." #: config/vms/vms.opt:35 #, no-c-format msgid "Use VMS exit codes instead of posix ones." -msgstr "" +msgstr "Використовувати коди виходу VMS замість кодів posix." #: config/vms/vms.opt:39 #, no-c-format msgid "-mpointer-size=[no,32,short,64,long]\tSet the default pointer size." -msgstr "" +msgstr "-mpointer-size=[no,32,short,64,long]\tВстановити розмір вказівника за замовчуванням." #: config/mcore/mcore.opt:23 #, no-c-format msgid "Generate code for the M*Core M210." -msgstr "" +msgstr "Генерувати код для M*Core M210." #: config/mcore/mcore.opt:27 #, no-c-format msgid "Generate code for the M*Core M340." -msgstr "" +msgstr "Генерувати код для M*Core M340." #: config/mcore/mcore.opt:31 #, no-c-format msgid "Force functions to be aligned to a 4 byte boundary." -msgstr "" +msgstr "Примусово вирівнювати функції за межу 4 байти." #: config/mcore/mcore.opt:35 config/moxie/moxie.opt:23 config/csky/csky.opt:44 #, no-c-format msgid "Generate big-endian code." -msgstr "" +msgstr "Генерувати код у великому порядку байтів." #: config/mcore/mcore.opt:39 #, no-c-format msgid "Emit call graph information." -msgstr "" +msgstr "Виводити інформацію про граф викликів." #: config/mcore/mcore.opt:43 #, no-c-format msgid "Use the divide instruction." -msgstr "" +msgstr "Використовувати інструкцію ділення." #: config/mcore/mcore.opt:47 #, no-c-format msgid "Inline constants if it can be done in 2 insns or less." -msgstr "" +msgstr "Вбудовувати константи, якщо це можливо зробити за 2 інструкції або менше." #: config/mcore/mcore.opt:51 config/moxie/moxie.opt:27 config/csky/csky.opt:51 #, no-c-format msgid "Generate little-endian code." -msgstr "" +msgstr "Генерувати код у малому порядку байтів." #: config/mcore/mcore.opt:56 config/fr30/fr30.opt:27 #, no-c-format msgid "Assume that run-time support has been provided, so omit -lsim from the linker command line." -msgstr "" +msgstr "Припускати, що підтримка часу виконання надана, тому пропустити -lsim з командного рядка звʼязувача." #: config/mcore/mcore.opt:60 #, no-c-format msgid "Use arbitrary sized immediates in bit operations." -msgstr "" +msgstr "Використовувати довільні розміри негайних значень у бітових операціях." #: config/mcore/mcore.opt:64 #, no-c-format msgid "Prefer word accesses over byte accesses." -msgstr "" +msgstr "Віддавати перевагу доступу до слова над доступом до байта." #: config/mcore/mcore.opt:71 #, no-c-format msgid "Set the maximum amount for a single stack increment operation." -msgstr "" +msgstr "Встановити максимальну кількість для однієї операції збільшення стеку." #: config/mcore/mcore.opt:75 #, no-c-format msgid "Always treat bitfields as int-sized." -msgstr "" +msgstr "Завжди розглядайте бітові поля як поля типу int." #: config/linux-android.opt:23 #, no-c-format msgid "Generate code for the Android platform." -msgstr "" +msgstr "Генерувати код для платформи Android." #: config/mmix/mmix.opt:24 #, no-c-format msgid "For intrinsics library: pass all parameters in registers." -msgstr "" +msgstr "Для бібліотеки інтринсиків: передавати всі параметри в регістрах." #: config/mmix/mmix.opt:28 #, no-c-format msgid "Use register stack for parameters and return value." -msgstr "" +msgstr "Використовувати стек регістрів для параметрів та значення, що повертається." #: config/mmix/mmix.opt:32 #, no-c-format msgid "Use call-clobbered registers for parameters and return value." -msgstr "" +msgstr "Використовувати регістри, що змінюються під час виклику, для параметрів та значення, що повертається." #: config/mmix/mmix.opt:37 #, no-c-format msgid "Use epsilon-respecting floating point compare instructions." -msgstr "" +msgstr "Використовуйте інструкції порівняння з плаваючою комою, які враховують епсилон." #: config/mmix/mmix.opt:41 #, no-c-format msgid "Use zero-extending memory loads, not sign-extending ones." -msgstr "" +msgstr "Використовуйте завантаження з памʼяті з розширенням нулем, а не з розширенням знаку." #: config/mmix/mmix.opt:45 #, no-c-format msgid "Generate divide results with reminder having the same sign as the divisor (not the dividend)." -msgstr "" +msgstr "Генерувати результати ділення зі знаком залишку, який співпадає зі знаком дільника (а не ділене)." #: config/mmix/mmix.opt:49 #, no-c-format msgid "Prepend global symbols with \":\" (for use with PREFIX)." -msgstr "" +msgstr "Додавати двокрапку до глобальних символів (для використання з PREFIX)." #: config/mmix/mmix.opt:53 #, no-c-format msgid "Do not provide a default start-address 0x100 of the program." -msgstr "" +msgstr "Не вказувати типову початкову адресу 0x100 програми." #: config/mmix/mmix.opt:57 #, no-c-format msgid "Link to emit program in ELF format (rather than mmo)." -msgstr "" +msgstr "Посилання на створення програми у форматі ELF (а не mmo)." #: config/mmix/mmix.opt:61 #, no-c-format msgid "Use P-mnemonics for branches statically predicted as taken." -msgstr "" +msgstr "Використовувати P-мнемоніки для гілок, статично передбачених як виконувані." #: config/mmix/mmix.opt:65 #, no-c-format msgid "Don't use P-mnemonics for branches." -msgstr "" +msgstr "Не використовувати P-мнемоніки для гілок." #: config/mmix/mmix.opt:79 #, no-c-format msgid "Use addresses that allocate global registers." -msgstr "" +msgstr "Використовувати адреси, які виділяють глобальні регістри." #: config/mmix/mmix.opt:83 #, no-c-format msgid "Do not use addresses that allocate global registers." -msgstr "" +msgstr "Не використовувати адреси, які виділяють глобальні регістри." #: config/mmix/mmix.opt:87 #, no-c-format msgid "Generate a single exit point for each function." -msgstr "" +msgstr "Створити одну точку виходу для кожної функції." #: config/mmix/mmix.opt:91 #, no-c-format msgid "Do not generate a single exit point for each function." -msgstr "" +msgstr "Не генерувати єдину точку виходу для кожної функції." #: config/mmix/mmix.opt:95 #, no-c-format msgid "Set start-address of the program." -msgstr "" +msgstr "Встановити початкову адресу програми." #: config/mmix/mmix.opt:99 #, no-c-format msgid "Set start-address of data." -msgstr "" +msgstr "Встановити початкову адресу даних." #: config/darwin.opt:34 #, no-c-format msgid "Generate code for darwin loadable kernel extensions." -msgstr "" +msgstr "Створити код для завантажуваних розширень ядра Darwin." #: config/darwin.opt:38 #, no-c-format msgid "-iframework \tAdd to the end of the system framework include path." -msgstr "" +msgstr "-iframework <каталог>\tДодати <каталог> в кінець шляху включення системного фреймворку." #: config/darwin.opt:42 #, no-c-format msgid "Generate compile-time CFString objects." -msgstr "" +msgstr "Створити обʼєкти CFString на етапі компіляції." #: config/darwin.opt:46 #, no-c-format msgid "Warn if constant CFString objects contain non-portable characters." -msgstr "" +msgstr "Попереджати, якщо константні обʼєкти CFString містять непереносимі символи." #: config/darwin.opt:51 #, no-c-format msgid "Generate AT&T-style stubs for Mach-O." -msgstr "" +msgstr "Генерувати заглушки у стилі AT&T для Mach-O." #: config/darwin.opt:55 #, no-c-format msgid "Generate code suitable for executables (NOT shared libs)." -msgstr "" +msgstr "Генерувати код, придатний для виконуваних файлів (НЕ спільних бібліотек)." #: config/darwin.opt:59 #, no-c-format msgid "Generate code suitable for fast turn around debugging." -msgstr "" +msgstr "Генерувати код, придатний для швидкого налагодження." #: config/darwin.opt:63 #, no-c-format msgid "Generate code for the kernel or loadable kernel extensions." -msgstr "" +msgstr "Створити код для ядра або завантажуваних розширень ядра." #: config/darwin.opt:71 #, no-c-format msgid "The earliest macOS version on which this program will run." -msgstr "" +msgstr "Найстарша версія macOS, на якій ця програма буде працювати." #: config/darwin.opt:76 #, no-c-format msgid "Set sizeof(bool) to 1." -msgstr "" +msgstr "Встановити sizeof(bool) на 1." #: config/darwin.opt:80 #, no-c-format msgid "Force generation of external symbol indirection stubs." -msgstr "" +msgstr "Примусово генерувати заглушки для зовнішніх символів індирекції." #: config/darwin.opt:88 #, no-c-format msgid "-mtarget-linker \tSpecify that ld64 is the toolchain linker for the current invocation." -msgstr "" +msgstr "-mtarget-linker <версія>\tВказує, що ld64 <версія> є ланцюжком інструментів лінкера для поточного виклику." #: config/darwin.opt:94 #, no-c-format msgid "Load all members of archive libraries, rather than only those that satisfy undefined symbols." -msgstr "" +msgstr "Завантажувати всі члени архівних бібліотек, а не лише ті, які задовольняють невизначені символи." #: config/darwin.opt:98 #, no-c-format msgid "-allowable_client \tThe output dylib is private to the client ." -msgstr "" +msgstr "-allowable_client <імʼя>\tВихідний dylib є приватним для клієнта <імʼя>." #: config/darwin.opt:102 #, no-c-format msgid "-arch \tGenerate output for architecture ." -msgstr "" +msgstr "-arch <імʼя>\tГенерувати вихідний файл для архітектури <імʼя>." #: config/darwin.opt:106 #, no-c-format msgid "Mismatches between file architecture and one specified by \"-arch\" are errors instead of warnings." -msgstr "" +msgstr "Неспівпадіння між архітектурою файлу та тією, яка вказана за допомогою «-arch», є помилками, а не попередженнями." #: config/darwin.opt:110 #, no-c-format msgid "The earliest macOS version on which this program will run (formatted for the assembler)." -msgstr "" +msgstr "Найстарша версія macOS, на якій буде працювати ця програма (відформатована для асемблера)." #: config/darwin.opt:114 #, no-c-format msgid "Generate an output executable that binds symbols on load, rather than lazily." -msgstr "" +msgstr "Генерувати вихідний виконуваний файл, який звʼязує символи при завантаженні, а не ліниво." #: config/darwin.opt:118 #, no-c-format msgid "Generate a Mach-O bundle (file type MH_BUNDLE)." -msgstr "" +msgstr "Створити пакет Mach-O (тип файлу MH_BUNDLE)." #: config/darwin.opt:122 #, no-c-format msgid "-bundle_loader \tTreat (that will be loading this bundle) as if it was one of the dynamic libraries the bundle is linked against for symbol resolution." -msgstr "" +msgstr "-bundle_loader <виконуваний файл>\tТрактувати <виконуваний файл> (який буде завантажувати цей пакет) так, ніби він є однією з динамічних бібліотек, з якими пакет повʼязаний для розрішення символів." #: config/darwin.opt:126 #, no-c-format msgid "-client_name \tEnable the executable being built to link against a private dylib (using allowable_client)." -msgstr "" +msgstr "-client_name <імʼя>\tДозволити збиранню виконуваного файлу звʼязуватися з приватною dylib (використовуючи allowable_client)." #: config/darwin.opt:130 #, no-c-format msgid "-compatibility_version \tSet the version for the client interface. Client programs must record a value less than or equal to , or the binding will fail at runtime." -msgstr "" +msgstr "-compatibility_version <число>\tВстановлює версію для інтерфейсу клієнта. Клієнтські програми повинні записувати значення менше або рівне <число>, інакше звʼязування не вдасться під час виконання." #: config/darwin.opt:134 #, no-c-format msgid "-current_version \tSet the current version for the library to ." -msgstr "" +msgstr "-current_version <число>\tВстановити поточну версію бібліотеки на <число>." #: config/darwin.opt:138 #, no-c-format msgid "Remove code and data that is unreachable from any exported symbol (including the entry point)." -msgstr "" +msgstr "Видалити код та дані, які недосяжні з будь-якого експортованого символу (включаючи точку входу)." #: config/darwin.opt:142 #, no-c-format msgid "-dylib_file install_name:file_name\tThis allows linking of a dylib with \"install_name\" but to be found in a different install position \"file_name\"" -msgstr "" +msgstr "-dylib_file install_name:file_name\tЦе дозволяє звʼязування dylib з «install_name», але знаходити його в іншому місці встановлення «file_name»" #: config/darwin.opt:146 #, no-c-format msgid "Produce a Mach-O dylinker (file type MH_DYLINKER), only used for building dyld." -msgstr "" +msgstr "Створити Mach-O dylinker (тип файлу MH_DYLINKER), використовується лише для побудови dyld." #: config/darwin.opt:150 #, no-c-format msgid "-dylinker_install_name \tOnly used for building dyld." -msgstr "" +msgstr "-dylinker_install_name <шлях>\tВикористовується лише для побудови dyld." #: config/darwin.opt:154 #, no-c-format msgid "The default (and opposite of -static), implied by user mode executables, shared libraries and bundles." -msgstr "" +msgstr "Стандартне значення (і протилежне до -static), за замовчуванням використовується для виконуваних файлів, спільних бібліотек та пакетів." #: config/darwin.opt:158 #, no-c-format msgid "Produce a Mach-O shared library (file type MH_DYLIB), synonym for \"-shared\"." -msgstr "" +msgstr "Створює спільну бібліотеку Mach-O (тип файлу MH_DYLIB), синонім для «-shared»." #: config/darwin.opt:162 #, no-c-format msgid "-exported_symbols_list \tExport global symbols in in linked output file; any symbols not mentioned will be treated as \"hidden\"." -msgstr "" +msgstr "-exported_symbols_list <імʼя_файлу>\tЕкспортує глобальні символи з <імʼя_файлу> у звʼязаному вихідному файлі; будь-які символи, які не згадуються, будуть вважатися «прихованими»." #: config/darwin.opt:166 #, no-c-format msgid "Supply a list of objects to be linked from a file, rather than the command line." -msgstr "" +msgstr "Надайте список обʼєктів для звʼязування з файлу, а не з командного рядка." #: config/darwin.opt:170 config/darwin.opt:190 #, no-c-format msgid "Used for generating code for some older kernel revisions." -msgstr "" +msgstr "Використовується для генерації коду для деяких старіших версій ядра." #: config/darwin.opt:174 #, no-c-format msgid "Ignore the normal two-level namespace; resolve symbols in command line order and do not record which library provided the resolved symbol." -msgstr "" +msgstr "Ігнорувати звичайний дворівневий простір імен; розрішувати символи в порядку командного рядка і не записувати, яка бібліотека надала розрішений символ." #: config/darwin.opt:178 #, no-c-format msgid "For the assembler (and linker) permit any architecture sub-variant to be used without error." -msgstr "" +msgstr "Для асемблера (і лінкера) дозволити використовувати будь-яку підваріант архітектури без помилок." #: config/darwin.opt:182 #, no-c-format msgid "Set the output object such that, on loading, dyld will ignore any two-level namespace information and resolve symbols in the discovery order for loaded libs." -msgstr "" +msgstr "Встановити вихідний обʼєкт таким чином, щоб при завантаженні dyld ігнорував будь-яку інформацію про дворівневий простір імен і розрішував символи в порядку виявлення для завантажених бібліотек." #: config/darwin.opt:186 #, no-c-format msgid "-framework \tThe linker should search for the framework in the framework search path." -msgstr "" +msgstr "-framework <імʼя>\tЛінкер повинен шукати фреймворк <імʼя> в шляху пошуку фреймворків." #: config/darwin.opt:194 #, no-c-format msgid "Abbreviation for \"-g -fno-eliminate-unused-debug-symbols\"." -msgstr "" +msgstr "Скорочення для «-g -fno-eliminate-unused-debug-symbols»." #: config/darwin.opt:198 #, no-c-format msgid "Abbreviation for \"-g -feliminate-unused-debug-symbols\"." -msgstr "" +msgstr "Скорочення для «-g -feliminate-unused-debug-symbols»." #: config/darwin.opt:202 #, no-c-format msgid "Automatically adds space for longer path names in load commands (up to MAXPATHLEN)." -msgstr "" +msgstr "Автоматично додає простір для довших імен шляхів у командах завантаження (до MAXPATHLEN)." #: config/darwin.opt:206 #, no-c-format msgid "-image_base
\tSpecify
as the base address for a dylib or bundle." -msgstr "" +msgstr "-image_base <адреса>\tВказати <адресу> як базову адресу для dylib або пакету." #: config/darwin.opt:210 #, no-c-format msgid "-init \tThe symbol will be used as the first initialiser for a dylib." -msgstr "" +msgstr "-init <імʼя_символу>\tСимвол <імʼя_символу> буде використовуватися як перший ініціалізатор для dylib." #: config/darwin.opt:214 #, no-c-format msgid "-install_name \tSet the install name for a dylib." -msgstr "" +msgstr "-install_name <імʼя>\tВстановити імʼя встановлення для dylib." #: config/darwin.opt:218 #, no-c-format msgid "Usually \"private extern\" (hidden) symbols are made local when linking, this command suppresses that such that they remain exported." -msgstr "" +msgstr "Зазвичай символи «private extern» (приховані) стають локальними під час звʼязування, ця команда пригнічує це, щоб вони залишалися експортованими." #: config/darwin.opt:222 #, no-c-format msgid "(Obsolete after 10.4) Multi modules are ignored at runtime since macOS 10.4." -msgstr "" +msgstr "(Застаріло після 10.4) Багатомодульні модулі ігноруються під час виконання з macOS 10.4." #: config/darwin.opt:226 #, no-c-format msgid "(Obsolete after 10.4) -multiply_defined \tProvided a mechanism for warning about symbols defined in multiple dylibs." -msgstr "" +msgstr "(Застаріло після 10.4) -multiply_defined <обробка>\tНадав механізм для попередження про символи, що визначені в кількох dylibs." #: config/darwin.opt:230 #, no-c-format msgid "(Obsolete after 10.4) -multiply_defined_unused \tProvided a mechanism for warning about symbols defined in the current executable also being defined in linked dylibs." -msgstr "" +msgstr "(Застаріло після 10.4) -multiply_defined_unused <обробка>\tНадав механізм для попередження про символи, визначені в поточному виконуваному файлі, які також визначені в звʼязаних dylibs." #: config/darwin.opt:234 #, no-c-format msgid "(Obsolete) Current linkers never dead-strip these items, so the option is not needed." -msgstr "" +msgstr "(Застаріло) Поточні лінкери ніколи не видаляють ці елементи, тому ця опція не потрібна." #: config/darwin.opt:238 #, no-c-format msgid "Do not add a default symbol exports to modules or dynamic libraries." -msgstr "" +msgstr "Не додавати експорт символів за замовчуванням до модулів або динамічних бібліотек." #: config/darwin.opt:242 #, no-c-format msgid "(Obsolete after 10.3.9) Set MH_NOPREFIXBINDING, in an executable." -msgstr "" +msgstr "(Застаріло після 10.3.9) Встановити MH_NOPREFIXBINDING в виконуваному файлі." #: config/darwin.opt:246 #, no-c-format msgid "(Obsolete after 10.4)\tSet MH_NOMULTIDEFS in an umbrella framework." -msgstr "" +msgstr "(Застаріло після 10.4)\tВстановити MH_NOMULTIDEFS в універсальному фреймворку." #: config/darwin.opt:250 config/darwin.opt:265 config/darwin.opt:269 #, no-c-format msgid "(Obsolete) LD_PREBIND is no longer supported." -msgstr "" +msgstr "(Застаріло) LD_PREBIND більше не підтримується." #: config/darwin.opt:254 #, no-c-format msgid "(Obsolete) This is the default." -msgstr "" +msgstr "(Застаріло) Це значення за замовчуванням." #: config/darwin.opt:261 #, no-c-format msgid "-pagezero_size \tAllows setting the page 0 size to 4kb when required." -msgstr "" +msgstr "-pagezero_size <розмір>\tДозволяє встановити розмір сторінки 0 на 4 КБ, якщо це потрібно." #: config/darwin.opt:273 #, no-c-format msgid "Produces a Mach-O file suitable for embedded/ROM use." -msgstr "" +msgstr "Створює файл Mach-O, придатний для використання вбудованим/у ROM." #: config/darwin.opt:277 #, no-c-format msgid "(Obsolete) Allowed linking to proceed with \"-flat_namespace\" when a linked bundle contained a symbol also exported from the main executable." -msgstr "" +msgstr "(Застарілий) Дозволяло продовжувати звʼязування з «-flat_namespace», коли звʼязаний пакет містив символ, також експортований з основного виконуваного файлу." #: config/darwin.opt:284 #, no-c-format msgid "Synonym for \"-export-dynamic\" for linker versions that support it." -msgstr "" +msgstr "Синонім для «-export-dynamic» для версій лінкера, які його підтримують." #: config/darwin.opt:288 #, no-c-format msgid "-read_only_relocs \tAllow relocations in read-only pages (not recommended)." -msgstr "" +msgstr "-read_only_relocs <обробка>\tДозволяє переміщення в сторінках тільки для читання (не рекомендується)." #: config/darwin.opt:292 #, no-c-format msgid "-sectalign \tSet section in segment to have alignment which must be an integral power of two expressed in hexadecimal form." -msgstr "" +msgstr "-sectalign <імʼя сегмента> <імʼя секції> <значення>\tВстановлює вирівнювання секції <імʼя секції> у сегменті <імʼя сегмента> на значення <значення>, яке повинно бути цілочисельною степенню двійки, вираженою у шістнадцятковій формі." #: config/darwin.opt:296 #, no-c-format msgid "-sectcreate \tCreate section in segment from the contents of ." -msgstr "" +msgstr "-sectcreate <імʼя сегмента> <імʼя секції> <файл>\tСтворює секцію <імʼя секції> у сегменті <імʼя сегмента> з вмісту файлу <файл>." #: config/darwin.opt:300 #, no-c-format msgid "(Obsolete) -sectobjectsymbols \tSetting a local symbol at the start of a section is no longer supported." -msgstr "" +msgstr "(Застаріле) -sectobjectsymbols \tВстановлення локального символу на початку секції більше не підтримується." #: config/darwin.opt:304 #, no-c-format msgid "(Obsolete) -sectorder \tReplaced by a more general option \"-order_file\"." -msgstr "" +msgstr "(Застаріле) -sectorder \tЗамінено більш загальною опцією «-order_file»." #: config/darwin.opt:308 #, no-c-format msgid "-seg_addr_table \tSpecify the base addresses for dynamic libraries; contains a line for each library." -msgstr "" +msgstr "-seg_addr_table \tВказати базові адреси для динамічних бібліотек; містить рядок для кожної бібліотеки." #: config/darwin.opt:313 #, no-c-format msgid "(Obsolete, ld_classic only) -seg_addr_table_filename ." -msgstr "" +msgstr "(Застаріле, лише ld_classic) -seg_addr_table_filename ." #: config/darwin.opt:317 #, no-c-format @@ -5165,47 +5140,47 @@ msgstr "Синонім «image_base»." #: config/darwin.opt:321 #, no-c-format msgid "-segaddr
\tSet the base address of segment to
which must be aligned to a page boundary (currently 4kb)." -msgstr "" +msgstr "-segaddr
\tВстановити базову адресу сегмента на
, яка повинна бути вирівняна за межі сторінки (наразі 4 КБ)." #: config/darwin.opt:326 #, no-c-format msgid "(Obsolete, ld_classic only) -sectcreate \tAllowed creation of a section from a file." -msgstr "" +msgstr "(Застаріле, тільки ld_classic) -sectcreate \tДозволяло створювати секцію з файлу." #: config/darwin.opt:330 #, no-c-format msgid "(Obsolete) Object files with LINKEDIT sections are no longer supported." -msgstr "" +msgstr "(Застаріле) Обʼєктні файли з розділами LINKEDIT більше не підтримуються." #: config/darwin.opt:334 #, no-c-format msgid "-segprot \tThe virtual memory protections for segment have maximum and initial values and respectively. The specified values may contain \"r\", \"w\", \"x\" or \"-\" the latter meaning \"no access\"." -msgstr "" +msgstr "-segprot <імʼя_сегмента> <макс_захист> <ініц_захист>\tЗахист віртуальної памʼяті для сегмента <імʼя_сегмента> має максимальні та початкові значення <макс_захист> та <ініц_захист> відповідно. Вказані значення можуть містити «r», «w», «x» або «-», останнє означає «немає доступу»." #: config/darwin.opt:338 #, no-c-format msgid "-segs_read_only_addr
\tSpecify that
is the base address of the read-only segments of a dylib." -msgstr "" +msgstr "-segs_read_only_addr <адреса>\tВказує, що <адреса> є базовою адресою сегментів тільки для читання dylib." #: config/darwin.opt:342 #, no-c-format msgid "-segs_read_write_addr
\tSpecify that
is the base address address of the read-write segments of a dylib." -msgstr "" +msgstr "-segs_read_write_addr <адреса>\tВказує, що <адреса> є базовою адресою сегментів для читання-запису dylib." #: config/darwin.opt:346 #, no-c-format msgid "(Obsolete)\tThis is the default." -msgstr "" +msgstr "(Застаріле)\tЦе значення за замовчуванням." #: config/darwin.opt:350 #, no-c-format msgid "-sub_library \tLibrary named will be re-exported (only useful for dylibs)." -msgstr "" +msgstr "-sub_library <імʼя>\tБібліотека з іменем <імʼя> буде повторно експортована (корисно лише для dylibs)." #: config/darwin.opt:354 #, no-c-format msgid "-sub_umbrella \tFramework named will be re-exported (only useful for dylibs)." -msgstr "" +msgstr "-sub_umbrella <імʼя>\tФреймворк з назвою <імʼя> буде повторно експортований (корисно лише для dylibs)." #: config/darwin.opt:358 #, no-c-format @@ -5215,2738 +5190,2738 @@ msgstr "Це типове значення." #: config/darwin.opt:362 #, no-c-format msgid "Add extra information to the executable that can speed up dynamic loading (provided that dependent libraries are unchanged)." -msgstr "" +msgstr "Додати додаткову інформацію до виконуваного файлу, що може прискорити динамічне завантаження (за умови, що залежні бібліотеки не змінені)." #: config/darwin.opt:366 #, no-c-format msgid "-umbrella \tThe specified framework will be re-exported." -msgstr "" +msgstr "-umbrella <фреймворк>\tВказаний фреймворк буде повторно експортований." #: config/darwin.opt:370 #, no-c-format msgid "-undefined \tSpecify the handling for undefined symbols (default is error)." -msgstr "" +msgstr "-undefined <обробка>\tВказати обробку невизначених символів (за замовчуванням - помилка)." #: config/darwin.opt:374 #, no-c-format msgid "-unexported_symbols_list \tDo not export the global symbols listed in ." -msgstr "" +msgstr "-unexported_symbols_list <імʼя_файлу>\tНе експортувати глобальні символи, перелічовані в <імʼя_файлу>." #: config/darwin.opt:378 #, no-c-format msgid "-weak_reference_mismatches \tSpecifies what to do if a symbol import conflicts between file (weak in one and not in another) the default is to treat the symbol as non-weak." -msgstr "" +msgstr "-weak_reference_mismatches <обробка>\tВказує, що робити, якщо імпорт символу конфліктує між файлами (слабкий в одному і не в іншому), за замовчуванням символ вважається непривʼязаним." #: config/darwin.opt:382 #, no-c-format msgid "Logs which object files the linker loads." -msgstr "" +msgstr "Записує, які обʼєктні файли завантажує лінкер." #: config/darwin.opt:386 #, no-c-format msgid "Logs which symbol(s) caused an object to be loaded." -msgstr "" +msgstr "Записує символ(и), які спричинили завантаження обʼєкта." #: config/darwin.opt:394 #, no-c-format msgid "(Obsolete, ignored)\tOld support similar to \"-whyload\"." -msgstr "" +msgstr "(Застаріле, ігнорується)\tСтара підтримка, схожа на «-whyload»." #: config/darwin.opt:398 #, no-c-format msgid "(Obsolete and unhandled by ld64, ignored)\tld should produce an executable (only handled by ld_classic)." -msgstr "" +msgstr "(Застаріле і необроблене ld64, ігнорується)\tld повинен створювати виконуваний файл (обробляється лише ld_classic)." #: config/bfin/bfin.opt:40 config/msp430/msp430.opt:3 config/c6x/c6x.opt:38 #, no-c-format msgid "Use simulator runtime." -msgstr "" +msgstr "Використовувати середовище виконання симулятора." #: config/bfin/bfin.opt:44 config/arm/arm.opt:120 #, no-c-format msgid "Specify the name of the target CPU." -msgstr "" +msgstr "Вказати назву цільового процесора." #: config/bfin/bfin.opt:48 #, no-c-format msgid "Omit frame pointer for leaf functions." -msgstr "" +msgstr "Пропустити вказівник рамки для листкових функцій." #: config/bfin/bfin.opt:52 #, no-c-format msgid "Program is entirely located in low 64k of memory." -msgstr "" +msgstr "Програма повністю розташована в нижніх 64 кБ памʼяті." #: config/bfin/bfin.opt:56 #, no-c-format msgid "Work around a hardware anomaly by adding a number of NOPs before a CSYNC or SSYNC instruction." -msgstr "" +msgstr "Уникнути аномалії апаратного забезпечення, додавши кілька NOPs перед інструкцією CSYNC або SSYNC." #: config/bfin/bfin.opt:61 #, no-c-format msgid "Avoid speculative loads to work around a hardware anomaly." -msgstr "" +msgstr "Уникайте спекулятивних завантажень, щоб уникнути аномалії апаратного забезпечення." #: config/bfin/bfin.opt:65 #, no-c-format msgid "Enabled ID based shared library." -msgstr "Увімкнено засновану на ідентифікаторах бібліотеку спільного використання." +msgstr "Увімкнено ID-засновану спільну бібліотеку." #: config/bfin/bfin.opt:69 #, no-c-format msgid "Generate code that won't be linked against any other ID shared libraries, but may be used as a shared library." -msgstr "" +msgstr "Генерувати код, який не буде посилатися на жодну іншу ID-спільну бібліотеку, але може використовуватися як спільна бібліотека." #: config/bfin/bfin.opt:74 config/m68k/m68k.opt:175 #, no-c-format msgid "ID of shared library to build." -msgstr "Ідентифікатор бібліотеки спільного використання для збирання." +msgstr "ID спільної бібліотеки, яку потрібно побудувати." #: config/bfin/bfin.opt:78 config/m68k/m68k.opt:171 #, no-c-format msgid "Enable separate data segment." -msgstr "" +msgstr "Увімкнути окремий сегмент даних." #: config/bfin/bfin.opt:82 config/c6x/c6x.opt:63 #, no-c-format msgid "Avoid generating pc-relative calls; use indirection." -msgstr "" +msgstr "Уникайте генерації викликів, що відносяться до pc; використовуйте непряме звертання." #: config/bfin/bfin.opt:86 #, no-c-format msgid "Link with the fast floating-point library." -msgstr "" +msgstr "Посилатися на швидку бібліотеку з плаваючою комою." #: config/bfin/bfin.opt:90 config/arm/arm.opt:339 config/frv/frv.opt:130 #, no-c-format msgid "Enable Function Descriptor PIC mode." -msgstr "" +msgstr "Увімкнути режим PIC для опису функцій." #: config/bfin/bfin.opt:94 config/frv/frv.opt:162 #, no-c-format msgid "Enable inlining of PLT in function calls." -msgstr "" +msgstr "Увімкнути вбудовування PLT у виклики функцій." #: config/bfin/bfin.opt:98 #, no-c-format msgid "Do stack checking using bounds in L1 scratch memory." -msgstr "" +msgstr "Виконувати перевірку стеку з використанням меж у L1 тимчасовій памʼяті." #: config/bfin/bfin.opt:102 #, no-c-format msgid "Enable multicore support." -msgstr "" +msgstr "Увімкнути підтримку багатоядерності." #: config/bfin/bfin.opt:106 #, no-c-format msgid "Build for Core A." -msgstr "" +msgstr "Збудувати для ядра A." #: config/bfin/bfin.opt:110 #, no-c-format msgid "Build for Core B." -msgstr "" +msgstr "Збудувати для ядра B." #: config/bfin/bfin.opt:114 #, no-c-format msgid "Build for SDRAM." -msgstr "" +msgstr "Збудувати для SDRAM." #: config/bfin/bfin.opt:118 #, no-c-format msgid "Assume ICPLBs are enabled at runtime." -msgstr "" +msgstr "Припустити, що ICPLB увімкнені під час виконання." #: config/m68k/m68k-tables.opt:25 #, no-c-format msgid "Known M68K CPUs (for use with the -mcpu= option):" -msgstr "" +msgstr "Відомі процесори M68K (для використання з опцією -mcpu=):" #: config/m68k/m68k-tables.opt:365 #, no-c-format msgid "Known M68K microarchitectures (for use with the -mtune= option):" -msgstr "" +msgstr "Відомі мікроархітектури M68K (для використання з опцією -mtune=):" #: config/m68k/m68k-tables.opt:411 #, no-c-format msgid "Known M68K ISAs (for use with the -march= option):" -msgstr "" +msgstr "Відомі ISA M68K (для використання з опцією -march=):" #: config/m68k/ieee.opt:24 config/i386/i386.opt:374 #, no-c-format msgid "Use IEEE math for fp comparisons." -msgstr "" +msgstr "Використовуйте IEEE математику для порівнянь з плаваючою комою." #: config/m68k/m68k.opt:30 #, no-c-format msgid "Generate code for a 520X." -msgstr "" +msgstr "Створити код для 520X." #: config/m68k/m68k.opt:34 #, no-c-format msgid "Generate code for a 5206e." -msgstr "" +msgstr "Створити код для 5206e." #: config/m68k/m68k.opt:38 #, no-c-format msgid "Generate code for a 528x." -msgstr "" +msgstr "Створити код для 528x." #: config/m68k/m68k.opt:42 #, no-c-format msgid "Generate code for a 5307." -msgstr "" +msgstr "Створити код для 5307." #: config/m68k/m68k.opt:46 #, no-c-format msgid "Generate code for a 5407." -msgstr "" +msgstr "Створити код для 5407." #: config/m68k/m68k.opt:50 config/m68k/m68k.opt:111 #, no-c-format msgid "Generate code for a 68000." -msgstr "" +msgstr "Створити код для 68000." #: config/m68k/m68k.opt:54 #, no-c-format msgid "Generate code for a 68010." -msgstr "" +msgstr "Створити код для 68010." #: config/m68k/m68k.opt:58 config/m68k/m68k.opt:115 #, no-c-format msgid "Generate code for a 68020." -msgstr "" +msgstr "Створити код для 68020." #: config/m68k/m68k.opt:62 #, no-c-format msgid "Generate code for a 68040, without any new instructions." -msgstr "" +msgstr "Створити код для 68040 без нових інструкцій." #: config/m68k/m68k.opt:66 #, no-c-format msgid "Generate code for a 68060, without any new instructions." -msgstr "" +msgstr "Створити код для 68060 без нових інструкцій." #: config/m68k/m68k.opt:70 #, no-c-format msgid "Generate code for a 68030." -msgstr "" +msgstr "Створити код для 68030." #: config/m68k/m68k.opt:74 #, no-c-format msgid "Generate code for a 68040." -msgstr "" +msgstr "Створити код для 68040." #: config/m68k/m68k.opt:78 #, no-c-format msgid "Generate code for a 68060." -msgstr "" +msgstr "Створити код для 68060." #: config/m68k/m68k.opt:82 #, no-c-format msgid "Generate code for a 68302." -msgstr "" +msgstr "Створити код для 68302." #: config/m68k/m68k.opt:86 #, no-c-format msgid "Generate code for a 68332." -msgstr "" +msgstr "Створити код для 68332." #: config/m68k/m68k.opt:91 #, no-c-format msgid "Generate code for a 68851." -msgstr "" +msgstr "Створити код для 68851." #: config/m68k/m68k.opt:95 #, no-c-format msgid "Generate code that uses 68881 floating-point instructions." -msgstr "" +msgstr "Створити код, що використовує інструкції з плаваючою комою 68881." #: config/m68k/m68k.opt:99 #, no-c-format msgid "Align variables on a 32-bit boundary." -msgstr "" +msgstr "Вирівнювати змінні на границі 32 біт." #: config/m68k/m68k.opt:103 config/arm/arm.opt:89 config/nios2/nios2.opt:570 #: config/nds32/nds32.opt:171 config/c6x/c6x.opt:67 #, no-c-format msgid "Specify the name of the target architecture." -msgstr "" +msgstr "Вказати назву цільової архітектури." #: config/m68k/m68k.opt:107 #, no-c-format msgid "Use the bit-field instructions." -msgstr "" +msgstr "Використовувати інструкції поля бітів." #: config/m68k/m68k.opt:119 #, no-c-format msgid "Generate code for a ColdFire v4e." -msgstr "" +msgstr "Створити код для ColdFire v4e." #: config/m68k/m68k.opt:123 #, no-c-format msgid "Specify the target CPU." -msgstr "" +msgstr "Вказати цільовий процесор." #: config/m68k/m68k.opt:127 #, no-c-format msgid "Generate code for a cpu32." -msgstr "" +msgstr "Створити код для cpu32." #: config/m68k/m68k.opt:131 #, no-c-format msgid "Use hardware division instructions on ColdFire." -msgstr "" +msgstr "Використовувати апаратні інструкції ділення на ColdFire." #: config/m68k/m68k.opt:135 #, no-c-format msgid "Generate code for a Fido A." -msgstr "" +msgstr "Створити код для Fido A." #: config/m68k/m68k.opt:139 #, no-c-format msgid "Generate code which uses hardware floating point instructions." -msgstr "" +msgstr "Створити код, який використовує апаратні інструкції з плаваючою комою." #: config/m68k/m68k.opt:143 #, no-c-format msgid "Enable ID based shared library." -msgstr "Увімкнути засновану на ідентифікаторах бібліотеку спільного використання." +msgstr "Увімкнути спільну бібліотеку на основі ID." #: config/m68k/m68k.opt:147 #, no-c-format msgid "Use 32-bit offsets in jump tables rather than 16-bit offsets." -msgstr "" +msgstr "Використовувати зсуви на 32 біти в таблицях переходів замість зсувів на 16 біт." #: config/m68k/m68k.opt:151 #, no-c-format msgid "Do not use the bit-field instructions." -msgstr "" +msgstr "Не використовувати інструкції для бітових полів." #: config/m68k/m68k.opt:155 #, no-c-format msgid "Use normal calling convention." -msgstr "" +msgstr "Використовувати звичайну конвенцію виклику." #: config/m68k/m68k.opt:159 #, no-c-format msgid "Consider type 'int' to be 32 bits wide." -msgstr "" +msgstr "Вважати тип 'int' шириною 32 біти." #: config/m68k/m68k.opt:163 #, no-c-format msgid "Generate pc-relative code." -msgstr "" +msgstr "Створити код з відносним вказівником на програмний лічильник (PC)." #: config/m68k/m68k.opt:167 #, no-c-format msgid "Use different calling convention using 'rtd'." -msgstr "" +msgstr "Використовувати іншу конвенцію виклику з використанням 'rtd'." #: config/m68k/m68k.opt:179 #, no-c-format msgid "Consider type 'int' to be 16 bits wide." -msgstr "" +msgstr "Вважати тип 'int' шириною 16 біт." #: config/m68k/m68k.opt:183 #, no-c-format msgid "Generate code with library calls for floating point." -msgstr "" +msgstr "Створити код з викликами бібліотеки для операцій з плаваючою комою." #: config/m68k/m68k.opt:187 #, no-c-format msgid "Do not use unaligned memory references." -msgstr "" +msgstr "Не використовуйте незбалансовані посилання на памʼять." #: config/m68k/m68k.opt:191 #, no-c-format msgid "Tune for the specified target CPU or architecture." -msgstr "" +msgstr "Налаштуйте для вказаного цільового процесора або архітектури." #: config/m68k/m68k.opt:195 #, no-c-format msgid "Support more than 8192 GOT entries on ColdFire." -msgstr "" +msgstr "Підтримка більше 8192 записів GOT на ColdFire." #: config/m68k/m68k.opt:199 #, no-c-format msgid "Support TLS segment larger than 64K." -msgstr "" +msgstr "Підтримка TLS-сегменту більше 64K." #: config/riscv/riscv.opt:26 config/aarch64/aarch64.opt:74 #: config/arm/arm.opt:108 config/microblaze/microblaze.opt:60 #, no-c-format msgid "Assume target CPU is configured as big endian." -msgstr "" +msgstr "Припустити, що цільовий процесор налаштований як big endian." #: config/riscv/riscv.opt:30 config/aarch64/aarch64.opt:94 #: config/arm/arm.opt:173 config/microblaze/microblaze.opt:64 #, no-c-format msgid "Assume target CPU is configured as little endian." -msgstr "" +msgstr "Припустити, що цільовий процесор налаштований як little endian." #: config/riscv/riscv.opt:34 #, no-c-format msgid "-mbranch-cost=N\tSet the cost of branches to roughly N instructions." -msgstr "" +msgstr "-mbranch-cost=N\tВстановити вартість гілок приблизно N інструкцій." #: config/riscv/riscv.opt:38 #, no-c-format msgid "When generating -fpic code, allow the use of PLTs. Ignored for fno-pic." -msgstr "" +msgstr "При генерації коду -fpic дозволяє використання PLT. Ігнорується для fno-pic." #: config/riscv/riscv.opt:42 #, no-c-format msgid "Specify integer and floating-point calling convention." -msgstr "" +msgstr "Вказати конвенцію виклику для цілочисельних та чисел з плаваючою комою." #: config/riscv/riscv.opt:46 config/i386/i386.opt:429 #, no-c-format msgid "Attempt to keep stack aligned to this power of 2." -msgstr "" +msgstr "Спроба зберегти вирівнювання стеку за допомогою цієї степені числа 2." #: config/riscv/riscv.opt:50 #, no-c-format msgid "Supported ABIs (for use with the -mabi= option):" -msgstr "" +msgstr "Підтримувані ABIs (для використання з опцією -mabi=):" #: config/riscv/riscv.opt:75 #, no-c-format msgid "Use hardware floating-point divide and square root instructions." -msgstr "" +msgstr "Використовувати апаратні інструкції для ділення та обчислення квадратного кореня з числами з плаваючою комою." #: config/riscv/riscv.opt:79 #, no-c-format msgid "Use hardware instructions for integer division." -msgstr "" +msgstr "Використовувати апаратні інструкції для цілочисельного ділення." #: config/riscv/riscv.opt:83 #, no-c-format msgid "-march=\tGenerate code for given RISC-V ISA (e.g. RV64IM). ISA strings must be lower-case." -msgstr "" +msgstr "-march=\tГенерувати код для заданої RISC-V ISA (наприклад, RV64IM). Рядки ISA повинні бути у нижньому регістрі." #: config/riscv/riscv.opt:88 config/mips/mips.opt:405 #, no-c-format msgid "-mtune=PROCESSOR\tOptimize the output for PROCESSOR." -msgstr "" +msgstr "-mtune=PROCESSOR\tОптимізувати вихідний код для PROCESSOR." #: config/riscv/riscv.opt:92 #, no-c-format msgid "-mcpu=PROCESSOR\tUse architecture of and optimize the output for PROCESSOR." -msgstr "" +msgstr "-mcpu=PROCESSOR\tВикористовувати архітектуру та оптимізувати вихідний код для PROCESSOR." #: config/riscv/riscv.opt:96 #, no-c-format msgid "-msmall-data-limit=N\tPut global and static data smaller than bytes into a special section (on some targets)." -msgstr "" +msgstr "-msmall-data-limit=N\tРозміщує глобальні та статичні дані розміром менше <число> байтів у спеціальному розділі (на деяких цільових платформах)." #: config/riscv/riscv.opt:100 #, no-c-format msgid "Use smaller but slower prologue and epilogue code." -msgstr "" +msgstr "Використовуйте менший, але повільніший код прологу та епілогу." #: config/riscv/riscv.opt:104 #, no-c-format msgid "Convert BASE + LARGE_OFFSET addresses to NEW_BASE + SMALL_OFFSET to allow more memory accesses to be generated as compressed instructions. Currently targets 32-bit integer load/stores." -msgstr "" +msgstr "Конвертувати адреси BASE + LARGE_OFFSET в NEW_BASE + SMALL_OFFSET, щоб дозволити генерувати більше доступів до памʼяті у вигляді стиснених інструкцій. Наразі цілі спрямовані на 32-бітові завантаження/збереження цілочисельних." #: config/riscv/riscv.opt:110 config/aarch64/aarch64.opt:98 #: config/loongarch/loongarch.opt:193 #, no-c-format msgid "Specify the code model." -msgstr "" +msgstr "Вказати модель коду." #: config/riscv/riscv.opt:114 config/loongarch/loongarch.opt:158 #, no-c-format msgid "Do not generate unaligned memory accesses." -msgstr "" +msgstr "Не генерувати незбалансовані доступи до памʼяті." #: config/riscv/riscv.opt:118 config/i386/i386.opt:293 #: config/rs6000/aix64.opt:36 config/rs6000/linux64.opt:32 #, no-c-format msgid "Known code models (for use with the -mcmodel= option):" -msgstr "" +msgstr "Відомі моделі коду (для використання з опцією -mcmodel=):" #: config/riscv/riscv.opt:128 #, no-c-format msgid "Use %reloc() operators, rather than assembly macros, to load addresses." -msgstr "" +msgstr "Використовуйте оператори %reloc(), а не макроси збірки, для завантаження адрес." #: config/riscv/riscv.opt:132 #, no-c-format msgid "Take advantage of linker relaxations to reduce the number of instructions required to materialize symbol addresses." -msgstr "" +msgstr "Скористайтеся можливостями розслаблення звʼязувача, щоб зменшити кількість інструкцій, необхідних для матеріалізації адрес символів." #: config/riscv/riscv.opt:137 #, no-c-format msgid "Enable the CSR checking for the ISA-dependent CRS and the read-only CSR. The ISA-dependent CSR are only valid when the specific ISA is set. The read-only CSR can not be written by the CSR instructions." -msgstr "" +msgstr "Увімкнути перевірку CSR для залежних від ISA CRS та для CSR, доступних тільки для читання. Залежні від ISA CRS є дійсними лише тоді, коли встановлено конкретний ISA. CSR, доступні тільки для читання, не можна записувати за допомогою інструкцій CSR." #: config/riscv/riscv.opt:161 #, no-c-format msgid "Emit RISC-V ELF attribute." -msgstr "" +msgstr "Видавати атрибут RISC-V ELF." #: config/riscv/riscv.opt:165 config/i386/i386.opt:246 #, no-c-format msgid "Use the given data alignment." -msgstr "" +msgstr "Використовувати задане вирівнювання даних." #: config/riscv/riscv.opt:169 config/i386/i386.opt:250 #, no-c-format msgid "Known data alignment choices (for use with the -malign-data= option):" -msgstr "" +msgstr "Відомі варіанти вирівнювання даних (для використання з опцією -malign-data=):" #: config/riscv/riscv.opt:179 config/aarch64/aarch64.opt:241 #: config/i386/i386.opt:1015 config/arm/arm.opt:343 #: config/rs6000/rs6000.opt:550 #, no-c-format msgid "Use given stack-protector guard." -msgstr "" +msgstr "Використовувати заданий захисник стека." #: config/riscv/riscv.opt:183 config/aarch64/aarch64.opt:245 #: config/arm/arm.opt:347 config/rs6000/rs6000.opt:554 #, no-c-format msgid "Valid arguments to -mstack-protector-guard=:" -msgstr "" +msgstr "Допустимі аргументи для -mstack-protector-guard=:" #: config/riscv/riscv.opt:193 config/i386/i386.opt:1029 #: config/rs6000/rs6000.opt:564 #, no-c-format msgid "Use the given base register for addressing the stack-protector guard." -msgstr "" +msgstr "Використовувати заданий базовий регістр для адресації захисника стека." #: config/riscv/riscv.opt:200 config/i386/i386.opt:1036 #: config/rs6000/rs6000.opt:571 #, no-c-format msgid "Use the given offset for addressing the stack-protector guard." -msgstr "" +msgstr "Використовуйте задане зміщення для адресації захисника стека." #: config/riscv/riscv.opt:243 #, no-c-format msgid "Supported ISA specs (for use with the -misa-spec= option):" -msgstr "" +msgstr "Підтримувані специфікації ISA (для використання з опцією -misa-spec=):" #: config/riscv/riscv.opt:256 #, no-c-format msgid "Set the version of RISC-V ISA spec." -msgstr "" +msgstr "Встановити версію специфікації RISC-V ISA." #: config/m32c/m32c.opt:23 #, no-c-format msgid "-msim\tUse simulator runtime." -msgstr "" +msgstr "-msim\tВикористовуйте час виконання симулятора." #: config/m32c/m32c.opt:27 #, no-c-format msgid "-mcpu=r8c\tCompile code for R8C variants." -msgstr "" +msgstr "-mcpu=r8c\tКомпілювати код для варіантів R8C." #: config/m32c/m32c.opt:31 #, no-c-format msgid "-mcpu=m16c\tCompile code for M16C variants." -msgstr "" +msgstr "-mcpu=m16c\tКомпілювати код для варіантів M16C." #: config/m32c/m32c.opt:35 #, no-c-format msgid "-mcpu=m32cm\tCompile code for M32CM variants." -msgstr "" +msgstr "-mcpu=m32cm\tКомпілювати код для варіантів M32CM." #: config/m32c/m32c.opt:39 #, no-c-format msgid "-mcpu=m32c\tCompile code for M32C variants." -msgstr "" +msgstr "-mcpu=m32c\tКомпілювати код для варіантів M32C." #: config/m32c/m32c.opt:43 #, no-c-format msgid "-memregs=\tNumber of memreg bytes (default: 16, range: 0..16)." -msgstr "" +msgstr "-memregs=\tКількість байтів memreg (за замовчуванням: 16, діапазон: 0..16)." #: config/msp430/msp430.opt:7 #, no-c-format msgid "Use a lightweight configuration of printf and puts to reduce code size. For single-threaded applications, not requiring reentrant I/O only. Requires Newlib Nano IO." -msgstr "" +msgstr "Використовуйте легку конфігурацію printf та puts для зменшення розміру коду. Тільки для однопотокових додатків, які не потребують переходу до введення/виведення. Вимагає Newlib Nano IO." #: config/msp430/msp430.opt:11 #, no-c-format msgid "Force assembly output to always use hex constants." -msgstr "" +msgstr "Примусово використовувати шістнадцяткові константи у вихідному коді асемблера." #: config/msp430/msp430.opt:15 #, no-c-format msgid "Specify the MCU to build for." -msgstr "" +msgstr "Вказати МКП, для якого будується програма." #: config/msp430/msp430.opt:19 #, no-c-format msgid "Warn if an MCU name is unrecognized or conflicts with other options (default: on)." -msgstr "" +msgstr "Попереджати, якщо назва МКП невідома або конфліктує з іншими параметрами (за замовчуванням: увімкнено)." #: config/msp430/msp430.opt:23 #, no-c-format msgid "Warn if devices.csv is not found or there are problem parsing it (default: on)." -msgstr "" +msgstr "Попереджати, якщо не знайдено файл devices.csv або виникли проблеми з його обробкою (за замовчуванням: увімкнено)." #: config/msp430/msp430.opt:27 #, no-c-format msgid "Specify the ISA to build for: msp430, msp430x, msp430xv2." -msgstr "" +msgstr "Вказати ISA, для якої будується програма: msp430, msp430x, msp430xv2." #: config/msp430/msp430.opt:52 #, no-c-format msgid "Select large model - 20-bit addresses/pointers." -msgstr "" +msgstr "Вибрати велику модель - 20-бітні адреси/вказівники." #: config/msp430/msp430.opt:56 #, no-c-format msgid "Select small model - 16-bit addresses/pointers (default)." -msgstr "" +msgstr "Вибрати малу модель - 16-бітні адреси/вказівники (за замовчуванням)." #: config/msp430/msp430.opt:60 #, no-c-format msgid "Optimize opcode sizes at link time." -msgstr "" +msgstr "Оптимізувати розміри опкодів під час звʼязування." #: config/msp430/msp430.opt:67 config/pru/pru.opt:26 #, no-c-format msgid "Use a minimum runtime (no static initializers or ctors) for memory-constrained devices." -msgstr "" +msgstr "Використовуйте мінімальний час виконання (без статичних ініціалізаторів або конструкторів) для пристроїв з обмеженим обсягом памʼяті." #: config/msp430/msp430.opt:74 #, no-c-format msgid "Specify the type of hardware multiply to support." -msgstr "" +msgstr "Вказати тип апаратного множення, який потрібно підтримувати." #: config/msp430/msp430.opt:96 #, no-c-format msgid "Specify whether functions should be placed into the lower or upper memory regions, or if they should be shuffled between the regions (either) for best fit (default: lower)." -msgstr "" +msgstr "Вказати, чи функції повинні розміщуватися в нижніх або верхніх областях памʼяті, або чи вони повинні переміщуватися між областями (будь-якими) для найкращого впису (за замовчуванням: нижні)." #: config/msp430/msp430.opt:100 #, no-c-format msgid "Specify whether variables should be placed into the lower or upper memory regions, or if they should be shuffled between the regions (either) for best fit (default: lower)." -msgstr "" +msgstr "Вказати, чи змінні повинні бути розміщені в нижніх або верхніх регіонах памʼяті, або чи вони повинні переміщуватися між регіонами (будь-якими) для найкращого впорядкування (за замовчуванням: нижні)." #: config/msp430/msp430.opt:104 #, no-c-format msgid "Add the .lower prefix to section names when compiling with -m{code,data}-region=lower (disabled by default)." -msgstr "" +msgstr "Додати префікс .lower до назв розділів при компіляції з -m{code,data}-region=lower (за замовчуванням вимкнено)." #: config/msp430/msp430.opt:123 #, no-c-format msgid "Passes on a request to the assembler to enable fixes for various silicon errata." -msgstr "" +msgstr "Передає запит до асемблера для увімкнення виправлень різних помилок у кремнієвих кристалах." #: config/msp430/msp430.opt:127 #, no-c-format msgid "Passes on a request to the assembler to warn about various silicon errata." -msgstr "" +msgstr "Передає запит асемблеру для попередження про різні помилки в кристалі." #: config/msp430/msp430.opt:131 #, no-c-format msgid "The path to devices.csv. The GCC driver can normally locate devices.csv itself and pass this option to the compiler, so the user shouldn't need to pass this." -msgstr "" +msgstr "Шлях до devices.csv. Зазвичай драйвер GCC може сам знайти файл devices.csv і передати цю опцію компілятору, тому користувачу не потрібно цього робити." #: config/msp430/msp430.opt:136 #, no-c-format msgid "For shift operations by a constant amount, which require an individual instruction to shift by one position, set the maximum number of inline shift instructions (maximum value 64) to emit instead of using the corresponding __mspabi helper function. The default value is 4." -msgstr "" +msgstr "Для операцій зсуву на константну величину, які вимагають окремої інструкції для зсуву на одну позицію, встановити максимальну кількість вставних інструкцій зсуву (максимальне значення 64), які слід виводити замість використання відповідної допоміжної функції __mspabi. Значення за замовчуванням - 4." #: config/aarch64/aarch64.opt:49 #, no-c-format msgid "The possible TLS dialects:" -msgstr "" +msgstr "Можливі діалекти TLS:" #: config/aarch64/aarch64.opt:61 config/loongarch/loongarch.opt:171 #, no-c-format msgid "The code model option names for -mcmodel:" -msgstr "" +msgstr "Назви опцій моделі коду для -mcmodel:" #: config/aarch64/aarch64.opt:78 config/i386/i386.opt:1050 #, no-c-format msgid "Generate code which uses only the general registers." -msgstr "" +msgstr "Генерувати код, який використовує лише загальні регістри." #: config/aarch64/aarch64.opt:82 config/i386/i386.opt:1142 #, no-c-format msgid "Generate code to mitigate against straight line speculation." -msgstr "" +msgstr "Генерувати код для зменшення прямолінійної спекуляції." #: config/aarch64/aarch64.opt:86 #, no-c-format msgid "Workaround for ARM Cortex-A53 Erratum number 835769." -msgstr "" +msgstr "Обхід для помилки ARM Cortex-A53 з номером 835769." #: config/aarch64/aarch64.opt:90 #, no-c-format msgid "Workaround for ARM Cortex-A53 Erratum number 843419." -msgstr "" +msgstr "Обхід для помилки ARM Cortex-A53 з номером 843419." #: config/aarch64/aarch64.opt:102 #, no-c-format msgid "Don't assume that unaligned accesses are handled by the system." -msgstr "" +msgstr "Не припускати, що незбалансований доступ обробляється системою." #: config/aarch64/aarch64.opt:106 config/i386/i386.opt:405 #, no-c-format msgid "Omit the frame pointer in leaf functions." -msgstr "" +msgstr "Пропустити вказівник рамки в листових функціях." #: config/aarch64/aarch64.opt:110 #, no-c-format msgid "Specify TLS dialect." -msgstr "" +msgstr "Вказати діалект TLS." #: config/aarch64/aarch64.opt:114 #, no-c-format msgid "Specifies bit size of immediate TLS offsets. Valid values are 12, 24, 32, 48." -msgstr "" +msgstr "Вказує розмір бітів негайних зсувів TLS. Допустимі значення: 12, 24, 32, 48." #: config/aarch64/aarch64.opt:133 #, no-c-format msgid "Use features of architecture ARCH." -msgstr "" +msgstr "Використовуйте можливості архітектури ARCH." #: config/aarch64/aarch64.opt:137 #, no-c-format msgid "Use features of and optimize for CPU." -msgstr "" +msgstr "Використовуйте можливості та оптимізуйте для процесора." #: config/aarch64/aarch64.opt:141 #, no-c-format msgid "Optimize for CPU." -msgstr "" +msgstr "Оптимізувати для процесора." #: config/aarch64/aarch64.opt:145 #, no-c-format msgid "Generate code that conforms to the specified ABI." -msgstr "" +msgstr "Створюйте код, який відповідає вказаному ABI." #: config/aarch64/aarch64.opt:149 #, no-c-format msgid "-moverride=\tPower users only! Override CPU optimization parameters." -msgstr "" +msgstr "-moverride=<рядок>\tТільки для досвідчених користувачів! Перевизначте параметри оптимізації процесора." #: config/aarch64/aarch64.opt:153 #, no-c-format msgid "Known AArch64 ABIs (for use with the -mabi= option):" -msgstr "" +msgstr "Відомі AArch64 ABI (для використання з опцією -mabi=):" #: config/aarch64/aarch64.opt:163 #, no-c-format msgid "PC relative literal loads." -msgstr "" +msgstr "Завантаження літералів відносно PC." #: config/aarch64/aarch64.opt:167 config/arm/arm.opt:331 #, no-c-format msgid "Use branch-protection features." -msgstr "" +msgstr "Використовуйте функції захисту гілок." #: config/aarch64/aarch64.opt:171 #, no-c-format msgid "Select return address signing scope." -msgstr "" +msgstr "Виберати область підпису повернення адреси." #: config/aarch64/aarch64.opt:175 #, no-c-format msgid "Supported AArch64 return address signing scope (for use with -msign-return-address= option):" -msgstr "" +msgstr "Підтримувана область підпису повернення адреси AArch64 (для використання з опцією -msign-return-address=):" #: config/aarch64/aarch64.opt:188 #, no-c-format msgid "Enable the reciprocal square root approximation. Enabling this reduces precision of reciprocal square root results to about 16 bits for single precision and to 32 bits for double precision." -msgstr "" +msgstr "Увімкнути наближення оберненої квадратного кореня. Увімкнення цієї опції знижує точність результатів оберненого квадратного кореня до приблизно 16 біт для одинарної точності і 32 біт для подвійної точності." #: config/aarch64/aarch64.opt:194 #, no-c-format msgid "Enable the square root approximation. Enabling this reduces precision of square root results to about 16 bits for single precision and to 32 bits for double precision. If enabled, it implies -mlow-precision-recip-sqrt." -msgstr "" +msgstr "Увімкнути наближення квадратного кореня. Увімкнення цієї опції знижує точність результатів квадратного кореня до приблизно 16 біт для одинарної точності і 32 біт для подвійної точності. Якщо ввімкнено, це означає -mlow-precision-recip-sqrt." #: config/aarch64/aarch64.opt:201 #, no-c-format msgid "Enable the division approximation. Enabling this reduces precision of division results to about 16 bits for single precision and to 32 bits for double precision." -msgstr "" +msgstr "Увімкнути наближення ділення. Увімкнення цієї опції знижує точність результатів ділення до приблизно 16 біт для одинарної точності і до 32 біт для подвійної точності." #: config/aarch64/aarch64.opt:207 #, no-c-format msgid "The possible SVE vector lengths:" -msgstr "" +msgstr "Можливі довжини векторів SVE:" #: config/aarch64/aarch64.opt:229 #, no-c-format msgid "-msve-vector-bits=\tSet the number of bits in an SVE vector register." -msgstr "" +msgstr "-msve-vector-bits=<число>\tВстановити кількість бітів у регістрі вектора SVE." #: config/aarch64/aarch64.opt:233 #, no-c-format msgid "Enables verbose cost model dumping in the debug dump files." -msgstr "" +msgstr "Увімкнути докладне виведення моделі витрат у файлах виведення налагодження." #: config/aarch64/aarch64.opt:237 #, no-c-format msgid "Generate code to track when the CPU might be speculating incorrectly." -msgstr "" +msgstr "Генерувати код для відстеження, коли процесор може неправильно спекулювати." #: config/aarch64/aarch64.opt:255 #, no-c-format msgid "Use the system register specified on the command line as the stack protector guard register. This option is for use with fstack-protector-strong and not for use in user-land code." -msgstr "" +msgstr "Використовуйте системний регістр, вказаний у командному рядку, як регістр захисту стека. Ця опція призначена для використання з fstack-protector-strong і не призначена для використання в коді користувача." #: config/aarch64/aarch64.opt:261 #, no-c-format msgid "Use an immediate to offset from the stack protector guard register, sp_el0. This option is for use with fstack-protector-strong and not for use in user-land code." -msgstr "" +msgstr "Використовуйте негайний зсув від реєстра-охоронця стека, sp_el0. Ця опція призначена для використання з fstack-protector-strong і не призначена для використання в коді користувача." #: config/aarch64/aarch64.opt:270 #, no-c-format msgid "Generate local calls to out-of-line atomic operations." -msgstr "" +msgstr "Генерувати локальні виклики до атомних операцій, що знаходяться поза лінією." #: config/aarch64/aarch64.opt:274 #, no-c-format msgid "When vectorizing for SVE, consider using unpacked vectors for smaller elements and use the cost model to pick the cheapest approach. Also use the cost model to choose between SVE and Advanced SIMD vectorization." -msgstr "" +msgstr "При векторизації для SVE розгляньте використання розпакованих векторів для менших елементів та використовуйте модель вартості для вибору найбільш економного підходу. Також використовуйте модель вартості для вибору між векторизацією SVE та Advanced SIMD." #: config/aarch64/aarch64.opt:278 #, no-c-format msgid "The number of Newton iterations for calculating the reciprocal for float type. The precision of division is proportional to this param when division approximation is enabled. The default value is 1." -msgstr "" +msgstr "Кількість ітерацій Ньютона для обчислення оберненого значення для типу float. Точність ділення пропорційна цьому параметру, коли ввімкнено наближене ділення. Значення за замовчуванням - 1." #: config/aarch64/aarch64.opt:282 #, no-c-format msgid "The number of Newton iterations for calculating the reciprocal for double type. The precision of division is proportional to this param when division approximation is enabled. The default value is 2." -msgstr "" +msgstr "Кількість ітерацій Ньютона для обчислення оберненого значення для типу double. Точність ділення пропорційна цьому параметру, коли ввімкнено наближення ділення. Значення за замовчуванням - 2." #: config/aarch64/aarch64.opt:292 #, no-c-format msgid "Constant memcpy size in bytes above which to start using MOPS sequence." -msgstr "" +msgstr "Константний розмір memcpy в байтах, після якого починається використання послідовності MOPS." #: config/aarch64/aarch64.opt:296 #, no-c-format msgid "Constant memmove size in bytes above which to start using MOPS sequence." -msgstr "" +msgstr "Константний розмір memmove в байтах, після якого починається використання послідовності MOPS." #: config/aarch64/aarch64.opt:300 #, no-c-format msgid "Constant memset size in bytes from which to start using MOPS sequence." -msgstr "" +msgstr "Константний розмір memset в байтах, з якого починається використання послідовності MOPS." #: config/aarch64/aarch64.opt:304 #, no-c-format msgid "Limit how much the autovectorizer may unroll a loop." -msgstr "" +msgstr "Обмежити, наскільки далеко автовекторизатор може розгорнути цикл." #: config/linux.opt:24 #, no-c-format msgid "Use Bionic C library." -msgstr "" +msgstr "Використовуйте бібліотеку Bionic C." #: config/linux.opt:28 #, no-c-format msgid "Use GNU C library." -msgstr "" +msgstr "Використовуйте бібліотеку GNU C." #: config/linux.opt:32 #, no-c-format msgid "Use uClibc C library." -msgstr "" +msgstr "Використовуйте бібліотеку uClibc C." #: config/linux.opt:36 #, no-c-format msgid "Use musl C library." -msgstr "" +msgstr "Використовуйте бібліотеку musl C." #: config/ia64/ilp32.opt:3 #, no-c-format msgid "Generate ILP32 code." -msgstr "" +msgstr "Створюйте код ILP32." #: config/ia64/ilp32.opt:7 #, no-c-format msgid "Generate LP64 code." -msgstr "" +msgstr "Створюйте код LP64." #: config/ia64/ia64.opt:28 #, no-c-format msgid "Generate big endian code." -msgstr "" +msgstr "Створюйте код з великим порядком байтів." #: config/ia64/ia64.opt:32 #, no-c-format msgid "Generate little endian code." -msgstr "" +msgstr "Створюйте код з маленьким порядком байтів." #: config/ia64/ia64.opt:36 #, no-c-format msgid "Generate code for GNU as." -msgstr "" +msgstr "Створюйте код для GNU as." #: config/ia64/ia64.opt:40 #, no-c-format msgid "Generate code for GNU ld." -msgstr "" +msgstr "Створюйте код для GNU ld." #: config/ia64/ia64.opt:44 #, no-c-format msgid "Emit stop bits before and after volatile extended asms." -msgstr "" +msgstr "Випускати стоп-біти перед та після волатильних розширених asms." #: config/ia64/ia64.opt:48 #, no-c-format msgid "Use in/loc/out register names." -msgstr "Використовувати назви регістрів in/loc/out." +msgstr "Використовуйте імена реєстрів in/loc/out." #: config/ia64/ia64.opt:55 #, no-c-format msgid "Enable use of sdata/scommon/sbss." -msgstr "" +msgstr "Увімкнути використання sdata/scommon/sbss." #: config/ia64/ia64.opt:59 #, no-c-format msgid "Generate code without GP reg." -msgstr "" +msgstr "Створюйте код без регістра GP." #: config/ia64/ia64.opt:63 #, no-c-format msgid "gp is constant (but save/restore gp on indirect calls)." -msgstr "" +msgstr "gp є константним (але зберігайте/відновлюйте gp при непрямих викликах)." #: config/ia64/ia64.opt:67 #, no-c-format msgid "Generate self-relocatable code." -msgstr "" +msgstr "Генерувати самозміщуваний код." #: config/ia64/ia64.opt:71 #, no-c-format msgid "Generate inline floating point division, optimize for latency." -msgstr "" +msgstr "Генерувати вбудоване ділення з плаваючою точкою, оптимізувати для затримки." #: config/ia64/ia64.opt:75 #, no-c-format msgid "Generate inline floating point division, optimize for throughput." -msgstr "" +msgstr "Генерувати вбудоване ділення з плаваючою точкою, оптимізувати для пропускної здатності." #: config/ia64/ia64.opt:82 #, no-c-format msgid "Generate inline integer division, optimize for latency." -msgstr "" +msgstr "Генерувати вбудоване цілочисельне ділення, оптимізувати для затримки." #: config/ia64/ia64.opt:86 #, no-c-format msgid "Generate inline integer division, optimize for throughput." -msgstr "" +msgstr "Генерувати вбудоване цілочисельне ділення, оптимізувати для пропускної здатності." #: config/ia64/ia64.opt:90 #, no-c-format msgid "Do not inline integer division." -msgstr "" +msgstr "Не генерувати цілочисельне ділення вбудовано." #: config/ia64/ia64.opt:94 #, no-c-format msgid "Generate inline square root, optimize for latency." -msgstr "" +msgstr "Генерувати вбудований квадратний корінь, оптимізувати для затримки." #: config/ia64/ia64.opt:98 #, no-c-format msgid "Generate inline square root, optimize for throughput." -msgstr "" +msgstr "Генерувати вбудований квадратний корінь, оптимізувати для пропускної здатності." #: config/ia64/ia64.opt:102 #, no-c-format msgid "Do not inline square root." -msgstr "" +msgstr "Не генерувати вбудований квадратний корінь." #: config/ia64/ia64.opt:106 #, no-c-format msgid "Enable DWARF line debug info via GNU as." -msgstr "" +msgstr "Увімкнути інформацію про відлагодження рядків DWARF через GNU as." #: config/ia64/ia64.opt:110 #, no-c-format msgid "Enable earlier placing stop bits for better scheduling." -msgstr "" +msgstr "Увімкнути раніше розміщення стоп-бітів для кращого планування." #: config/ia64/ia64.opt:114 config/pa/pa.opt:70 config/sh/sh.opt:227 #, no-c-format msgid "Specify range of registers to make fixed." -msgstr "" +msgstr "Вкажзати діапазон регістрів, які потрібно зафіксувати." #: config/ia64/ia64.opt:118 config/alpha/alpha.opt:130 #, no-c-format msgid "Specify bit size of immediate TLS offsets." -msgstr "" +msgstr "Вказати розмір бітів негайних зміщень TLS." #: config/ia64/ia64.opt:122 config/i386/i386.opt:527 config/s390/s390.opt:203 #: config/sparc/sparc.opt:146 config/visium/visium.opt:49 #, no-c-format msgid "Schedule code for given CPU." -msgstr "" +msgstr "Розклад коду для вказаного процесора." #: config/ia64/ia64.opt:126 #, no-c-format msgid "Known Itanium CPUs (for use with the -mtune= option):" -msgstr "" +msgstr "Відомі процесори Itanium (для використання з опцією -mtune=):" #: config/ia64/ia64.opt:136 #, no-c-format msgid "Use data speculation before reload." -msgstr "" +msgstr "Використовувати спекуляцію даних перед перезавантаженням." #: config/ia64/ia64.opt:140 #, no-c-format msgid "Use data speculation after reload." -msgstr "" +msgstr "Використовувати спекуляцію даних після перезавантаження." #: config/ia64/ia64.opt:144 #, no-c-format msgid "Use control speculation." -msgstr "" +msgstr "Використовувати спекуляцію управління." #: config/ia64/ia64.opt:148 #, no-c-format msgid "Use in block data speculation before reload." -msgstr "" +msgstr "Використовувати спекуляцію даних у блоках перед перезавантаженням." #: config/ia64/ia64.opt:152 #, no-c-format msgid "Use in block data speculation after reload." -msgstr "" +msgstr "Використовувати спекуляцію даних у блоках після перезавантаження." #: config/ia64/ia64.opt:156 #, no-c-format msgid "Use in block control speculation." -msgstr "" +msgstr "Використовувати спекуляцію контролю в блоках." #: config/ia64/ia64.opt:160 #, no-c-format msgid "Use simple data speculation check." -msgstr "" +msgstr "Використовувати просту перевірку спекуляції даних." #: config/ia64/ia64.opt:164 #, no-c-format msgid "Use simple data speculation check for control speculation." -msgstr "" +msgstr "Використовувати просту перевірку спекуляції даних для спекуляції контролю." #: config/ia64/ia64.opt:174 #, no-c-format msgid "Count speculative dependencies while calculating priority of instructions." -msgstr "" +msgstr "Підраховувати спекулятивні залежності під час обчислення пріоритету інструкцій." #: config/ia64/ia64.opt:178 #, no-c-format msgid "Place a stop bit after every cycle when scheduling." -msgstr "" +msgstr "Розміщувати біт зупинки після кожного циклу при плануванні." #: config/ia64/ia64.opt:182 #, no-c-format msgid "Assume that floating-point stores and loads are not likely to cause conflict when placed into one instruction group." -msgstr "" +msgstr "Припускати, що збереження та завантаження чисел з рухомою комою, ймовірно, не спричинять конфлікт, якщо вони розміщені в одній групі інструкцій." #: config/ia64/ia64.opt:186 #, no-c-format msgid "Soft limit on number of memory insns per instruction group, giving lower priority to subsequent memory insns attempting to schedule in the same insn group. Frequently useful to prevent cache bank conflicts. Default value is 1." -msgstr "" +msgstr "Мʼякий ліміт на кількість памʼяті insns на групу інструкцій, надаючи нижчий пріоритет наступним памʼяті insns, які намагаються розкладати в тій же групі insn. Часто корисно, щоб уникнути конфліктів у кеш-памʼяті. Значення за замовчуванням - 1." #: config/ia64/ia64.opt:190 #, no-c-format msgid "Disallow more than 'msched-max-memory-insns' in instruction group. Otherwise, limit is 'soft' (prefer non-memory operations when limit is reached)." -msgstr "" +msgstr "Заборонити більше, ніж 'msched-max-memory-insns' в групі інструкцій. В іншому випадку, ліміт є 'мʼяким' (віддають перевагу операціям без памʼяті, коли досягнуто ліміту)." #: config/ia64/ia64.opt:194 #, no-c-format msgid "Don't generate checks for control speculation in selective scheduling." -msgstr "" +msgstr "Не генерувати перевірки для контролю спекуляції в селективному плануванні." #: config/epiphany/epiphany.opt:24 #, no-c-format msgid "Don't use any of r32..r63." -msgstr "" +msgstr "Не використовувати жодного з r32..r63." #: config/epiphany/epiphany.opt:28 #, no-c-format msgid "Preferentially allocate registers that allow short instruction generation." -msgstr "" +msgstr "Перевага надається реєстрам, які дозволяють генерувати короткі інструкції." #: config/epiphany/epiphany.opt:32 #, no-c-format msgid "Set branch cost." -msgstr "" +msgstr "Встановити вартість гілки." #: config/epiphany/epiphany.opt:36 #, no-c-format msgid "Enable conditional move instruction usage." -msgstr "Увімкнути використання інструкцій із умовного пересування." +msgstr "Увімкнути використання умовних команд переміщення." #: config/epiphany/epiphany.opt:40 #, no-c-format msgid "Set number of nops to emit before each insn pattern." -msgstr "" +msgstr "Встановити кількість nop-інструкцій, які випускаються перед кожним шаблоном інструкцій." #: config/epiphany/epiphany.opt:52 #, no-c-format msgid "Use software floating point comparisons." -msgstr "" +msgstr "Використовувати програмне порівняння з плаваючою комою." #: config/epiphany/epiphany.opt:56 #, no-c-format msgid "Enable split of 32 bit immediate loads into low / high part." -msgstr "" +msgstr "Увімкнути розбиття 32-бітних негайних завантажень на нижню / верхню частину." #: config/epiphany/epiphany.opt:60 #, no-c-format msgid "Enable use of POST_INC / POST_DEC." -msgstr "" +msgstr "Увімкнути використання POST_INC / POST_DEC." #: config/epiphany/epiphany.opt:64 #, no-c-format msgid "Enable use of POST_MODIFY." -msgstr "" +msgstr "Увімкнути використання POST_MODIFY." #: config/epiphany/epiphany.opt:68 #, no-c-format msgid "Set number of bytes on the stack preallocated for use by the callee." -msgstr "" +msgstr "Встановити кількість байтів на стеку, які передбачені для використання викликаючим." #: config/epiphany/epiphany.opt:72 #, no-c-format msgid "Assume round to nearest is selected for purposes of scheduling." -msgstr "" +msgstr "Припускається, що вибрано округлення до найближчого значення для планування." #: config/epiphany/epiphany.opt:76 #, no-c-format msgid "Generate call insns as indirect calls." -msgstr "" +msgstr "Генерувати виклики інструкцій як непрямі виклики." #: config/epiphany/epiphany.opt:80 #, no-c-format msgid "Generate call insns as direct calls." -msgstr "" +msgstr "Генерувати виклики інструкцій як прямі виклики." #: config/epiphany/epiphany.opt:84 #, no-c-format msgid "Assume labels and symbols can be addressed using 16 bit absolute addresses." -msgstr "" +msgstr "Припускається, що мітки та символи можуть бути адресовані за допомогою абсолютних адрес 16 біт." #: config/epiphany/epiphany.opt:108 #, no-c-format msgid "A floatig point to integer truncation may be replaced with rounding to save mode switching." -msgstr "" +msgstr "Обрізання з плаваючої точки до цілого числа може бути замінено округленням для збереження перемикання режимів." #: config/epiphany/epiphany.opt:112 #, no-c-format msgid "Vectorize for double-word operations." -msgstr "" +msgstr "Векторизувати для операцій з подвійним словом." #: config/epiphany/epiphany.opt:128 #, no-c-format msgid "Split unaligned 8 byte vector moves before post-modify address generation." -msgstr "" +msgstr "Розбити незбалансовані переміщення векторів довжиною 8 байт перед генерацією адреси після модифікації." #: config/epiphany/epiphany.opt:132 #, no-c-format msgid "Use the floating point unit for integer add/subtract." -msgstr "" +msgstr "Використовуйте рухому кому для додавання / віднімання цілочисельних." #: config/epiphany/epiphany.opt:136 #, no-c-format msgid "Set register to hold -1." -msgstr "" +msgstr "Встановити регістр для зберігання -1." #: config/ft32/ft32.opt:23 #, no-c-format msgid "Target the software simulator." -msgstr "" +msgstr "Спрямовуйте на програмний симулятор." #: config/ft32/ft32.opt:27 config/s390/s390.opt:234 config/mips/mips.opt:393 #: config/arc/arc.opt:405 #, no-c-format msgid "Use LRA instead of reload." -msgstr "" +msgstr "Використовуйте LRA замість перезавантаження." #: config/ft32/ft32.opt:31 #, no-c-format msgid "Avoid use of the DIV and MOD instructions." -msgstr "" +msgstr "Уникайте використання інструкцій DIV і MOD." #: config/ft32/ft32.opt:35 #, no-c-format msgid "Target the FT32B architecture." -msgstr "" +msgstr "Спрямовуйте на архітектуру FT32B." #: config/ft32/ft32.opt:39 #, no-c-format msgid "Enable FT32B code compression." -msgstr "Увімкнути стискання коду FT32B." +msgstr "Увімкнути стиснення коду FT32B." #: config/ft32/ft32.opt:43 #, no-c-format msgid "Avoid placing any readable data in program memory." -msgstr "" +msgstr "Уникати розміщення будь-яких даних, придатних для читання, в памʼяті програми." #: config/h8300/h8300.opt:23 #, no-c-format msgid "Generate H8S code." -msgstr "" +msgstr "Створити код H8S." #: config/h8300/h8300.opt:27 #, no-c-format msgid "Generate H8SX code." -msgstr "" +msgstr "Створити код H8SX." #: config/h8300/h8300.opt:31 #, no-c-format msgid "Generate H8S/2600 code." -msgstr "" +msgstr "Створити код H8S/2600." #: config/h8300/h8300.opt:35 #, no-c-format msgid "Make integers 32 bits wide." -msgstr "" +msgstr "Зробити цілі числа шириною 32 біти." #: config/h8300/h8300.opt:42 #, no-c-format msgid "Use registers for argument passing." -msgstr "" +msgstr "Використовувати регістри для передачі аргументів." #: config/h8300/h8300.opt:46 #, no-c-format msgid "Consider access to byte sized memory slow." -msgstr "" +msgstr "Вважати доступ до памʼяті розміром в байти повільним." #: config/h8300/h8300.opt:50 #, no-c-format msgid "Enable linker relaxing." -msgstr "" +msgstr "Увімкнути розслаблення лінкера." #: config/h8300/h8300.opt:54 #, no-c-format msgid "Generate H8/300H code." -msgstr "" +msgstr "Генерувати код H8/300H." #: config/h8300/h8300.opt:58 #, no-c-format msgid "Enable the normal mode." -msgstr "" +msgstr "Увімкнути нормальний режим." #: config/h8300/h8300.opt:62 #, no-c-format msgid "Use H8/300 alignment rules." -msgstr "" +msgstr "Використовувати правила вирівнювання H8/300." #: config/h8300/h8300.opt:66 #, no-c-format msgid "Push extended registers on stack in monitor functions." -msgstr "" +msgstr "Помістити розширені регістри у стек у функціях моніторингу." #: config/h8300/h8300.opt:70 #, no-c-format msgid "Do not push extended registers on stack in monitor functions." -msgstr "" +msgstr "Не поміщати розширені регістри у стек у функціях моніторингу." #: config/pru/pru.opt:31 #, no-c-format msgid "-mmcu=MCU\tSelect the target System-On-Chip variant that embeds this PRU." -msgstr "" +msgstr "-mmcu=МКП\tВиберати цільовий варіант системи-на-кристалі, який вбудовує цю PRU." #: config/pru/pru.opt:35 #, no-c-format msgid "Make GCC pass the --no-relax command-line option to the linker instead of the --relax option." -msgstr "" +msgstr "Змусити GCC передавати опцію командного рядка --no-relax лінкеру замість опції --relax." #: config/pru/pru.opt:40 #, no-c-format msgid "Allow (or do not allow) gcc to use the LOOP instruction." -msgstr "" +msgstr "Дозволити (або не дозволяти) gcc використовувати інструкцію LOOP." #: config/pru/pru.opt:44 #, no-c-format msgid "Select target ABI variant." -msgstr "" +msgstr "Виберати варіант цільового ABI." #: config/pru/pru.opt:48 #, no-c-format msgid "ABI variant code generation (for use with -mabi= option):" -msgstr "" +msgstr "Генерація коду для варіанту ABI (для використання з опцією -mabi=):" #: config/pdp11/pdp11.opt:23 #, no-c-format msgid "Generate code for an 11/10." -msgstr "" +msgstr "Генерувати код для 11/10." #: config/pdp11/pdp11.opt:27 #, no-c-format msgid "Generate code for an 11/40." -msgstr "" +msgstr "Створити код для 11/40." #: config/pdp11/pdp11.opt:31 #, no-c-format msgid "Generate code for an 11/45." -msgstr "" +msgstr "Створити код для 11/45." #: config/pdp11/pdp11.opt:35 #, no-c-format msgid "Return floating-point results in ac0 (fr0 in Unix assembler syntax)." -msgstr "" +msgstr "Повертати результати з плаваючою комою в ac0 (fr0 в синтаксисі асемблера Unix)." #: config/pdp11/pdp11.opt:39 #, no-c-format msgid "Use the DEC assembler syntax." -msgstr "" +msgstr "Використовувати синтаксис асемблера DEC." #: config/pdp11/pdp11.opt:43 #, no-c-format msgid "Use the GNU assembler syntax." -msgstr "" +msgstr "Використовувати синтаксис асемблера GNU." #: config/pdp11/pdp11.opt:47 config/rs6000/rs6000.opt:183 #: config/frv/frv.opt:158 #, no-c-format msgid "Use hardware floating point." -msgstr "" +msgstr "Використовувати апаратне з плаваючою комою." #: config/pdp11/pdp11.opt:51 #, no-c-format msgid "Use 16 bit int." -msgstr "" +msgstr "Використовувати 16-бітне ціле." #: config/pdp11/pdp11.opt:55 #, no-c-format msgid "Use 32 bit int." -msgstr "" +msgstr "Використовуйте 32-бітні цілі числа." #: config/pdp11/pdp11.opt:59 config/rs6000/rs6000.opt:179 #, no-c-format msgid "Do not use hardware floating point." -msgstr "" +msgstr "Не використовуйте апаратне з плаваючою комою." #: config/pdp11/pdp11.opt:63 #, no-c-format msgid "Target has split I&D." -msgstr "" +msgstr "Ціль має розділення I&D." #: config/pdp11/pdp11.opt:67 #, no-c-format msgid "Use UNIX assembler syntax." -msgstr "" +msgstr "Використати синтаксис асемблера UNIX." #: config/pdp11/pdp11.opt:71 #, no-c-format msgid "Use LRA register allocator." -msgstr "" +msgstr "Використати реєстровий алокатор LRA." #: config/xtensa/xtensa.opt:23 #, no-c-format msgid "Use CONST16 instruction to load constants." -msgstr "" +msgstr "Використати інструкцію CONST16 для завантаження констант." #: config/xtensa/xtensa.opt:27 #, no-c-format msgid "Disable position-independent code (PIC) for use in OS kernel code." -msgstr "" +msgstr "Вимкнути незалежний від положення код (PIC) для використання в коді ядра ОС." #: config/xtensa/xtensa.opt:31 #, no-c-format msgid "Use indirect CALLXn instructions for large programs." -msgstr "" +msgstr "Використати непрямі інструкції CALLXn для великих програм." #: config/xtensa/xtensa.opt:35 #, no-c-format msgid "Set extra memory access cost for L32R instruction, in clock-cycle units." -msgstr "" +msgstr "Встановити додаткові витрати на доступ до памʼяті для інструкції L32R, в одиницях тактового циклу." #: config/xtensa/xtensa.opt:39 config/sh/sh.opt:303 #, no-c-format msgid "Use LRA instead of reload (transitional)." -msgstr "" +msgstr "Використовуйте LRA замість перезавантаження (перехідний)." #: config/xtensa/xtensa.opt:43 #, no-c-format msgid "Automatically align branch targets to reduce branch penalties." -msgstr "" +msgstr "Автоматично вирівнювати цілі гілок, щоб зменшити штрафи за гілки." #: config/xtensa/xtensa.opt:47 #, no-c-format msgid "Intersperse literal pools with code in the text section." -msgstr "" +msgstr "Вставляти літеральні пули з кодом в розділі тексту." #: config/xtensa/xtensa.opt:51 #, no-c-format msgid "Relax literals in assembler and place them automatically in the text section." -msgstr "" +msgstr "Розслабити літерали в асемблері та автоматично розмістити їх у розділі тексту." #: config/xtensa/xtensa.opt:55 #, no-c-format msgid "-mno-serialize-volatile\tDo not serialize volatile memory references with MEMW instructions." -msgstr "" +msgstr "-mno-serialize-volatile\tНе серіалізувати волатильні посилання на памʼять з інструкціями MEMW." #: config/xtensa/xtensa.opt:62 #, no-c-format msgid "Use call0 ABI." -msgstr "" +msgstr "Використовувати ABI call0." #: config/xtensa/xtensa.opt:66 #, no-c-format msgid "Use windowed registers ABI." -msgstr "Використовувати бінарний інтерфейс із віконними регістрами." +msgstr "Використовувати ABI з віконними регістрами." #: config/i386/cygming.opt:23 #, no-c-format msgid "Create console application." -msgstr "" +msgstr "Створити консольний додаток." #: config/i386/cygming.opt:27 #, no-c-format msgid "Generate code for a DLL." -msgstr "" +msgstr "Генерувати код для DLL." #: config/i386/cygming.opt:31 #, no-c-format msgid "Ignore dllimport for functions." -msgstr "" +msgstr "Ігнорувати dllimport для функцій." #: config/i386/cygming.opt:35 #, no-c-format msgid "Use Mingw-specific thread support." -msgstr "" +msgstr "Використовувати специфічну для Mingw підтримку потоків." #: config/i386/cygming.opt:39 #, no-c-format msgid "Set Windows defines." -msgstr "" +msgstr "Встановити визначення для Windows." #: config/i386/cygming.opt:43 #, no-c-format msgid "Create GUI application." -msgstr "" +msgstr "Створити GUI-додаток." #: config/i386/cygming.opt:47 #, no-c-format msgid "Use the GNU extension to the PE format for aligned common data." -msgstr "" +msgstr "Використовувати розширення GNU для формату PE для вирівняних загальних даних." #: config/i386/cygming.opt:51 #, no-c-format msgid "Compile code that relies on Cygwin DLL wrappers to support C++ operator new/delete replacement." -msgstr "" +msgstr "Компілювати код, який покладається на обгортки DLL Cygwin для підтримки заміни оператора new/delete C++." #: config/i386/cygming.opt:55 #, no-c-format msgid "For nested functions on stack executable permission is set." -msgstr "" +msgstr "Для вкладених функцій на стеку встановлено дозвіл на виконання." #: config/i386/cygming.opt:62 #, no-c-format msgid "Put relocated read-only data into .data section." -msgstr "" +msgstr "Помістити переміщені дані тільки для читання в розділ .data." #: config/i386/mingw.opt:29 #, no-c-format msgid "Warn about none ISO msvcrt scanf/printf width extensions." -msgstr "" +msgstr "Попереджати про відсутність розширень ширини scanf/printf msvcrt ISO." #: config/i386/mingw-w64.opt:23 #, no-c-format msgid "Use unicode startup and define UNICODE macro." -msgstr "" +msgstr "Використовувати запуск у кодуванні Unicode та визначити макрос UNICODE." #: config/i386/i386.opt:198 #, no-c-format msgid "sizeof(long double) is 16." -msgstr "" +msgstr "sizeof(long double) дорівнює 16." #: config/i386/i386.opt:202 config/i386/i386.opt:370 #, no-c-format msgid "Use hardware fp." -msgstr "" +msgstr "Використовувати апаратне засіб fp." #: config/i386/i386.opt:206 #, no-c-format msgid "sizeof(long double) is 12." -msgstr "" +msgstr "sizeof(long double) дорівнює 12." #: config/i386/i386.opt:210 #, no-c-format msgid "Use 80-bit long double." -msgstr "" +msgstr "Використовувати 80-бітний long double." #: config/i386/i386.opt:214 config/s390/s390.opt:163 #: config/sparc/long-double-switch.opt:27 config/alpha/alpha.opt:102 #, no-c-format msgid "Use 64-bit long double." -msgstr "" +msgstr "Використовуйте 64-бітний long double." #: config/i386/i386.opt:218 config/s390/s390.opt:159 #: config/sparc/long-double-switch.opt:23 config/alpha/alpha.opt:98 #, no-c-format msgid "Use 128-bit long double." -msgstr "" +msgstr "Використовуйте 128-бітний long double." #: config/i386/i386.opt:222 config/sh/sh.opt:179 #, no-c-format msgid "Reserve space for outgoing arguments in the function prologue." -msgstr "" +msgstr "Зарезервуйте місце для вихідних аргументів у прологу функції." #: config/i386/i386.opt:226 #, no-c-format msgid "Align some doubles on dword boundary." -msgstr "" +msgstr "Вирівняйте деякі числа з плаваючою комою на границі dword." #: config/i386/i386.opt:230 #, no-c-format msgid "Function starts are aligned to this power of 2." -msgstr "" +msgstr "Початки функцій вирівнюються за цією степенем числа 2." #: config/i386/i386.opt:234 #, no-c-format msgid "Jump targets are aligned to this power of 2." -msgstr "" +msgstr "Цілі переходів вирівнюються за цією степенем числа 2." #: config/i386/i386.opt:238 #, no-c-format msgid "Loop code aligned to this power of 2." -msgstr "" +msgstr "Код циклів вирівнюється за цією степенем числа 2." #: config/i386/i386.opt:242 #, no-c-format msgid "Align destination of the string operations." -msgstr "" +msgstr "Вирівняйте призначення операцій з рядками." #: config/i386/i386.opt:263 config/s390/s390.opt:56 #, no-c-format msgid "Generate code for given CPU." -msgstr "" +msgstr "Створити код для вказаного процесора." #: config/i386/i386.opt:267 #, no-c-format msgid "Use given assembler dialect." -msgstr "" +msgstr "Використовуйте вказаний діалект асемблера." #: config/i386/i386.opt:271 #, no-c-format msgid "Known assembler dialects (for use with the -masm= option):" -msgstr "" +msgstr "Відомі діалекти асемблера (для використання з опцією -masm=):" #: config/i386/i386.opt:281 #, no-c-format msgid "Branches are this expensive (arbitrary units)." -msgstr "" +msgstr "Гілки коштують так дорого (довільні одиниці)." #: config/i386/i386.opt:285 #, no-c-format msgid "-mlarge-data-threshold=\tData greater than given threshold will go into .ldata section in x86-64 medium model." -msgstr "" +msgstr "-mlarge-data-threshold=<число>\tДані, більші за вказаний поріг, будуть розміщені в розділі .ldata в середньому моделі x86-64." #: config/i386/i386.opt:289 #, no-c-format msgid "Use given x86-64 code model." -msgstr "" +msgstr "Використовуйте вказану модель коду x86-64." #: config/i386/i386.opt:312 #, no-c-format msgid "Use given address mode." -msgstr "Використовувати вказаний режим адресування." +msgstr "Використовуйте вказаний режим адреси." #: config/i386/i386.opt:316 #, no-c-format msgid "Known address mode (for use with the -maddress-mode= option):" -msgstr "" +msgstr "Відомі режими адреси (для використання з опцією -maddress-mode=):" #: config/i386/i386.opt:329 #, no-c-format msgid "Generate sin, cos, sqrt for FPU." -msgstr "" +msgstr "Генерувати sin, cos, sqrt для FPU." #: config/i386/i386.opt:333 #, no-c-format msgid "Always use Dynamic Realigned Argument Pointer (DRAP) to realign stack." -msgstr "" +msgstr "Завжди використовуйте Dynamic Realigned Argument Pointer (DRAP) для переустановки стеку." #: config/i386/i386.opt:337 #, no-c-format msgid "Return values of functions in FPU registers." -msgstr "" +msgstr "Повертати значення функцій у регістрах FPU." #: config/i386/i386.opt:341 #, no-c-format msgid "Generate floating point mathematics using given instruction set." -msgstr "" +msgstr "Генерувати операції з плаваючою комою за допомогою заданого набору інструкцій." #: config/i386/i386.opt:345 #, no-c-format msgid "Valid arguments to -mfpmath=:" -msgstr "" +msgstr "Допустимі аргументи для -mfpmath=:" #: config/i386/i386.opt:378 #, no-c-format msgid "Inline all known string operations." -msgstr "" +msgstr "Вбудовувати всі відомі операції з рядками." #: config/i386/i386.opt:382 #, no-c-format msgid "Inline memset/memcpy string operations, but perform inline version only for small blocks." -msgstr "" +msgstr "Вбудовувати операції з рядками memset/memcpy, але виконувати вбудовану версію тільки для невеликих блоків." #: config/i386/i386.opt:389 #, no-c-format msgid "Use native (MS) bitfield layout." -msgstr "" +msgstr "Використовувати власну (MS) структуру бітових полів." #: config/i386/i386.opt:409 #, no-c-format msgid "Relax cmpxchg loop for atomic_fetch_{or,xor,and,nand} by adding load and cmp before cmpxchg, execute pause and loop back to load and compare if load value is not expected." -msgstr "" +msgstr "Розслабити цикл cmpxchg для atomic_fetch_{or,xor,and,nand} шляхом додавання завантаження та порівняння перед cmpxchg, виконати паузу та повернутися до завантаження та порівняння, якщо значення завантаження неочікуване." #: config/i386/i386.opt:413 #, no-c-format msgid "Set 80387 floating-point precision to 32-bit." -msgstr "" +msgstr "Встановити точність плаваючої коми 80387 на 32 біти." #: config/i386/i386.opt:417 #, no-c-format msgid "Set 80387 floating-point precision to 64-bit." -msgstr "" +msgstr "Встановити точність плаваючої коми 80387 на 64 біти." #: config/i386/i386.opt:421 #, no-c-format msgid "Set 80387 floating-point precision to 80-bit." -msgstr "" +msgstr "Встановити точність плаваючої коми 80387 на 80 біт." #: config/i386/i386.opt:425 #, no-c-format msgid "Set the FTZ and DAZ Flags." -msgstr "" +msgstr "Встановити прапорці FTZ та DAZ." #: config/i386/i386.opt:433 #, no-c-format msgid "Assume incoming stack aligned to this power of 2." -msgstr "" +msgstr "Припустити, що вхідний стек вирівняний за цією степенем числа 2." #: config/i386/i386.opt:437 #, no-c-format msgid "Use push instructions to save outgoing arguments." -msgstr "" +msgstr "Використовуйте інструкції push для збереження вихідних аргументів." #: config/i386/i386.opt:441 #, no-c-format msgid "Use red-zone in the x86-64 code." -msgstr "" +msgstr "Використовуйте червону зону в коді x86-64." #: config/i386/i386.opt:445 #, no-c-format msgid "Number of registers used to pass integer arguments." -msgstr "" +msgstr "Кількість регістрів, використовуваних для передачі цілих аргументів." #: config/i386/i386.opt:449 #, no-c-format msgid "Alternate calling convention." -msgstr "" +msgstr "Альтернативна конвенція виклику." #: config/i386/i386.opt:453 config/alpha/alpha.opt:23 #, no-c-format msgid "Do not use hardware fp." -msgstr "" +msgstr "Не використовуйте апаратний fp." #: config/i386/i386.opt:457 #, no-c-format msgid "Use SSE register passing conventions for SF and DF mode." -msgstr "" +msgstr "Використовуйте конвенції передачі регістрів SSE для режиму SF і DF." #: config/i386/i386.opt:461 #, no-c-format msgid "Realign stack in prologue." -msgstr "" +msgstr "Переналаштуйте стек у прологу." #: config/i386/i386.opt:465 #, no-c-format msgid "Enable stack probing." -msgstr "" +msgstr "Увімкнути перевірку стеку." #: config/i386/i386.opt:469 #, no-c-format msgid "Specify memcpy expansion strategy when expected size is known." -msgstr "" +msgstr "Вказати стратегію розширення memcpy, коли відомий очікуваний розмір." #: config/i386/i386.opt:473 #, no-c-format msgid "Specify memset expansion strategy when expected size is known." -msgstr "" +msgstr "Вказати стратегію розширення memset, коли відомий очікуваний розмір." #: config/i386/i386.opt:477 #, no-c-format msgid "Chose strategy to generate stringop using." -msgstr "" +msgstr "Виберати стратегію для генерації stringop." #: config/i386/i386.opt:481 #, no-c-format msgid "Valid arguments to -mstringop-strategy=:" -msgstr "" +msgstr "Дійсні аргументи для -mstringop-strategy=." #: config/i386/i386.opt:509 #, no-c-format msgid "Use given thread-local storage dialect." -msgstr "" +msgstr "Використовуйте заданий діалект локального сховища потоків." #: config/i386/i386.opt:513 #, no-c-format msgid "Known TLS dialects (for use with the -mtls-dialect= option):" -msgstr "" +msgstr "Відомі діалекти TLS (для використання з опцією -mtls-dialect=):" #: config/i386/i386.opt:523 #, no-c-format msgid "Use direct references against %gs when accessing tls data." -msgstr "" +msgstr "Використовуйте прямі посилання на %gs при доступі до даних tls." #: config/i386/i386.opt:531 #, no-c-format msgid "Fine grain control of tune features." -msgstr "" +msgstr "Детальне керування функціями настрою." #: config/i386/i386.opt:535 #, no-c-format msgid "Clear all tune features." -msgstr "" +msgstr "Очистити всі функції настрою." #: config/i386/i386.opt:542 #, no-c-format msgid "Generate code that conforms to Intel MCU psABI." -msgstr "" +msgstr "Генерувати код, який відповідає Intel MCU psABI." #: config/i386/i386.opt:546 #, no-c-format msgid "Generate code that conforms to the given ABI." -msgstr "" +msgstr "Генерувати код, який відповідає заданому ABI." #: config/i386/i386.opt:550 config/nds32/nds32.opt:51 #, no-c-format msgid "Known ABIs (for use with the -mabi= option):" -msgstr "" +msgstr "Відомі ABIs (для використання з опцією -mabi=)." #: config/i386/i386.opt:560 #, no-c-format msgid "Use libgcc stubs to save and restore registers clobbered by 64-bit Microsoft to System V ABI calls." -msgstr "" +msgstr "Використовуйте заглушки libgcc для збереження та відновлення регістрів, які пошкоджуються викликами 64-бітного Microsoft до System V ABI." #: config/i386/i386.opt:564 config/rs6000/rs6000.opt:195 #, no-c-format msgid "Vector library ABI to use." -msgstr "" +msgstr "ABI векторної бібліотеки, яку слід використовувати." #: config/i386/i386.opt:568 #, no-c-format msgid "Known vectorization library ABIs (for use with the -mveclibabi= option):" -msgstr "" +msgstr "Відомі ABI векторизаційних бібліотек (для використання з опцією -mveclibabi=):" #: config/i386/i386.opt:578 #, no-c-format msgid "Return 8-byte vectors in memory." -msgstr "" +msgstr "Повертати 8-байтові вектори в памʼяті." #: config/i386/i386.opt:582 #, no-c-format msgid "Generate reciprocals instead of divss and sqrtss." -msgstr "" +msgstr "Генерувати обернені значення замість divss і sqrtss." #: config/i386/i386.opt:586 #, no-c-format msgid "Control generation of reciprocal estimates." -msgstr "" +msgstr "Контролювати генерацію оцінок обернених значень." #: config/i386/i386.opt:590 #, no-c-format msgid "Generate cld instruction in the function prologue." -msgstr "" +msgstr "Генерувати інструкцію cld у прологу функції." #: config/i386/i386.opt:594 #, no-c-format msgid "Generate vzeroupper instruction before a transfer of control flow out of the function." -msgstr "" +msgstr "Генерувати інструкцію vzeroupper перед передачею потоку керування з функції." #: config/i386/i386.opt:599 #, no-c-format msgid "Disable Scalar to Vector optimization pass transforming 64-bit integer computations into a vector ones." -msgstr "" +msgstr "Вимкнути прохід Scalar to Vector оптимізації, який перетворює обчислення 64-бітних цілочисельних у векторні." #: config/i386/i386.opt:604 #, no-c-format msgid "The maximum number of use and def visits when discovering a STV chain before the discovery is aborted." -msgstr "" +msgstr "Максимальна кількість відвідувань use та def при виявленні ланцюга STV перед припиненням виявлення." #: config/i386/i386.opt:608 #, no-c-format msgid "Do dispatch scheduling if processor is bdver1, bdver2, bdver3, bdver4 or znver1 and Haifa scheduling is selected." -msgstr "" +msgstr "Виконувати планування розподілу, якщо процесор bdver1, bdver2, bdver3, bdver4 або znver1, і вибране планування Haifa." #: config/i386/i386.opt:613 #, no-c-format msgid "Use 128-bit AVX instructions instead of 256-bit AVX instructions in the auto-vectorizer." -msgstr "" +msgstr "Використовувати 128-бітні AVX-інструкції замість 256-бітних AVX-інструкцій у автоматичному векторизаторі." #: config/i386/i386.opt:617 #, no-c-format msgid "Use given register vector width instructions instead of maximum register width in the auto-vectorizer." -msgstr "" +msgstr "Використовувати задані інструкції ширини вектора регістра замість максимальної ширини регістра в автоматичному векторизаторі." #: config/i386/i386.opt:621 #, no-c-format msgid "Known preferred register vector length (to use with the -mprefer-vector-width= option):" -msgstr "" +msgstr "Відома бажана довжина вектора регістра (для використання з опцією -mprefer-vector-width=):" #: config/i386/i386.opt:637 #, no-c-format msgid "Maximum number of bits that can be moved from memory to memory efficiently." -msgstr "" +msgstr "Максимальна кількість бітів, яку можна ефективно перемістити з памʼяті в памʼять." #: config/i386/i386.opt:641 #, no-c-format msgid "Maximum number of bits that can be stored to memory efficiently." -msgstr "" +msgstr "Максимальна кількість бітів, яку можна ефективно зберегти в памʼяті." #: config/i386/i386.opt:647 #, no-c-format msgid "Generate 32bit i386 code." -msgstr "" +msgstr "Генерувати 32-бітний код i386." #: config/i386/i386.opt:651 #, no-c-format msgid "Generate 64bit x86-64 code." -msgstr "" +msgstr "Генерувати 64-бітний код x86-64." #: config/i386/i386.opt:655 #, no-c-format msgid "Generate 32bit x86-64 code." -msgstr "" +msgstr "Генерувати 32-бітний код x86-64." #: config/i386/i386.opt:659 #, no-c-format msgid "Generate 16bit i386 code." -msgstr "" +msgstr "Генерувати 16-бітний код i386." #: config/i386/i386.opt:663 #, no-c-format msgid "Support MMX built-in functions." -msgstr "" +msgstr "Підтримка вбудованих функцій MMX." #: config/i386/i386.opt:667 #, no-c-format msgid "Support 3DNow! built-in functions." -msgstr "" +msgstr "Підтримка вбудованих функцій 3DNow!." #: config/i386/i386.opt:671 #, no-c-format msgid "Support Athlon 3Dnow! built-in functions." -msgstr "" +msgstr "Підтримка вбудованих функцій Athlon 3Dnow!" #: config/i386/i386.opt:675 #, no-c-format msgid "Support MMX and SSE built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій MMX і SSE та генерація коду." #: config/i386/i386.opt:679 #, no-c-format msgid "Support MMX, SSE and SSE2 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій MMX, SSE і SSE2 та генерація коду." #: config/i386/i386.opt:683 #, no-c-format msgid "Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій MMX, SSE, SSE2 і SSE3 та генерація коду." #: config/i386/i386.opt:687 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3 and SSSE3 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3 та SSSE3." #: config/i386/i386.opt:691 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3 та SSE4.1." #: config/i386/i386.opt:695 config/i386/i386.opt:699 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 та SSE4.2." #: config/i386/i386.opt:703 #, no-c-format msgid "Do not support SSE4.1 and SSE4.2 built-in functions and code generation." -msgstr "" +msgstr "Не підтримується вбудованих функцій та генерація коду для SSE4.1 та SSE4.2." #: config/i386/i386.opt:711 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 and AVX built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 та AVX." #: config/i386/i386.opt:715 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and AVX2 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX та AVX2." #: config/i386/i386.opt:719 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та AVX512F." #: config/i386/i386.opt:723 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512PF built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512PF." #: config/i386/i386.opt:727 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512ER built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512ER." #: config/i386/i386.opt:731 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512CD built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512CD." #: config/i386/i386.opt:735 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512DQ built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512DQ." #: config/i386/i386.opt:739 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512BW built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512BW." #: config/i386/i386.opt:743 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512VL built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512VL." #: config/i386/i386.opt:747 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512IFMA built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та AVX512F і AVX512IFMA." #: config/i386/i386.opt:751 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512VBMI built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та AVX512F і AVX512VBMI." #: config/i386/i386.opt:755 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX5124FMAPS built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX5124FMAPS." #: config/i386/i386.opt:759 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX5124VNNIW built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX5124VNNIW." #: config/i386/i386.opt:763 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512VPOPCNTDQ built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512VPOPCNTDQ." #: config/i386/i386.opt:767 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512VBMI2 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512VBMI2." #: config/i386/i386.opt:771 #, no-c-format msgid "Support AVX512VNNI built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для AVX512VNNI." #: config/i386/i386.opt:775 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512BITALG built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512BITALG." #: config/i386/i386.opt:779 #, no-c-format msgid "Support AVX512VP2INTERSECT built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для AVX512VP2INTERSECT." #: config/i386/i386.opt:783 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and FMA built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій і генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX і FMA." #: config/i386/i386.opt:787 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3 and SSE4A built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій і генерація коду для MMX, SSE, SSE2, SSE3 і SSE4A." #: config/i386/i386.opt:791 #, no-c-format msgid "Support FMA4 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій і генерація коду для FMA4." #: config/i386/i386.opt:795 #, no-c-format msgid "Support XOP built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій і генерація коду для XOP." #: config/i386/i386.opt:799 #, no-c-format msgid "Support LWP built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій і генерація коду для LWP." #: config/i386/i386.opt:803 #, no-c-format msgid "Support code generation of Advanced Bit Manipulation (ABM) instructions." -msgstr "" +msgstr "Підтримка генерації коду для команд розширеного побітового маніпулювання (ABM)." #: config/i386/i386.opt:807 #, no-c-format msgid "Support code generation of popcnt instruction." -msgstr "" +msgstr "Підтримка генерації коду для команди popcnt." #: config/i386/i386.opt:811 #, no-c-format msgid "Support PCONFIG built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій PCONFIG та генерація коду." #: config/i386/i386.opt:815 #, no-c-format msgid "Support WBNOINVD built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій WBNOINVD та генерація коду." #: config/i386/i386.opt:819 #, no-c-format msgid "Support PTWRITE built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій PTWRITE та генерація коду." #: config/i386/i386.opt:823 #, no-c-format msgid "Support UINTR built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій UINTR та генерація коду." #: config/i386/i386.opt:827 #, no-c-format msgid "Support SGX built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій SGX та генерація коду." #: config/i386/i386.opt:831 #, no-c-format msgid "Support RDPID built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій RDPID та генерація коду." #: config/i386/i386.opt:835 #, no-c-format msgid "Support GFNI built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій GFNI та генерація коду." #: config/i386/i386.opt:839 #, no-c-format msgid "Support VAES built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій VAES та генерація коду." #: config/i386/i386.opt:843 #, no-c-format msgid "Support VPCLMULQDQ built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій VPCLMULQDQ та генерація коду." #: config/i386/i386.opt:847 #, no-c-format msgid "Support BMI built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій BMI та генерація коду." #: config/i386/i386.opt:851 #, no-c-format msgid "Support BMI2 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій BMI2 та генерація коду." #: config/i386/i386.opt:855 #, no-c-format msgid "Support LZCNT built-in function and code generation." -msgstr "" +msgstr "Підтримка вбудованої функції LZCNT та генерація коду." #: config/i386/i386.opt:859 #, no-c-format msgid "Support Hardware Lock Elision prefixes." -msgstr "" +msgstr "Підтримка префіксів для апаратного усунення блокування." #: config/i386/i386.opt:863 #, no-c-format msgid "Support RDSEED instruction." -msgstr "" +msgstr "Підтримка інструкції RDSEED." #: config/i386/i386.opt:867 #, no-c-format msgid "Support PREFETCHW instruction." -msgstr "" +msgstr "Підтримка інструкції PREFETCHW." #: config/i386/i386.opt:871 #, no-c-format msgid "Support flag-preserving add-carry instructions." -msgstr "" +msgstr "Підтримка інструкцій збереження прапорців при додаванні з переносом." #: config/i386/i386.opt:875 #, no-c-format msgid "Support CLFLUSHOPT instructions." -msgstr "" +msgstr "Підтримка інструкцій CLFLUSHOPT." #: config/i386/i386.opt:879 #, no-c-format msgid "Support CLWB instruction." -msgstr "" +msgstr "Підтримка інструкції CLWB." #: config/i386/i386.opt:886 #, no-c-format msgid "Support FXSAVE and FXRSTOR instructions." -msgstr "" +msgstr "Підтримка інструкцій FXSAVE та FXRSTOR." #: config/i386/i386.opt:890 #, no-c-format msgid "Support XSAVE and XRSTOR instructions." -msgstr "" +msgstr "Підтримка інструкцій XSAVE та XRSTOR." #: config/i386/i386.opt:894 #, no-c-format msgid "Support XSAVEOPT instruction." -msgstr "" +msgstr "Підтримка інструкції XSAVEOPT." #: config/i386/i386.opt:898 #, no-c-format msgid "Support XSAVEC instructions." -msgstr "" +msgstr "Підтримка інструкцій XSAVEC." #: config/i386/i386.opt:902 #, no-c-format msgid "Support XSAVES and XRSTORS instructions." -msgstr "" +msgstr "Підтримка інструкцій XSAVES та XRSTORS." #: config/i386/i386.opt:906 #, no-c-format msgid "Support TBM built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій TBM та генерація коду." #: config/i386/i386.opt:910 #, no-c-format msgid "Support code generation of cmpxchg16b instruction." -msgstr "" +msgstr "Підтримка генерації коду для інструкції cmpxchg16b." #: config/i386/i386.opt:914 #, no-c-format msgid "Support code generation of sahf instruction in 64bit x86-64 code." -msgstr "" +msgstr "Підтримка генерації коду для інструкції sahf в 64-бітовому x86-64 коді." #: config/i386/i386.opt:918 #, no-c-format msgid "Support code generation of movbe instruction." -msgstr "" +msgstr "Підтримка генерації коду для інструкції movbe." #: config/i386/i386.opt:922 #, no-c-format msgid "Support code generation of crc32 instruction." -msgstr "" +msgstr "Підтримка генерації коду для інструкції crc32." #: config/i386/i386.opt:926 #, no-c-format msgid "Support AES built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій AES та генерація коду." #: config/i386/i386.opt:930 #, no-c-format msgid "Support SHA1 and SHA256 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій SHA1 та SHA256 та генерація коду." #: config/i386/i386.opt:934 #, no-c-format msgid "Support PCLMUL built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій PCLMUL та генерація коду." #: config/i386/i386.opt:938 #, no-c-format msgid "Encode SSE instructions with VEX prefix." -msgstr "" +msgstr "Кодування інструкцій SSE з префіксом VEX." #: config/i386/i386.opt:942 #, no-c-format msgid "Support FSGSBASE built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій FSGSBASE та генерація коду." #: config/i386/i386.opt:946 #, no-c-format msgid "Support RDRND built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій RDRND та генерація коду." #: config/i386/i386.opt:950 #, no-c-format msgid "Support F16C built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій F16C та генерація коду." #: config/i386/i386.opt:954 #, no-c-format msgid "Support PREFETCHWT1 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій PREFETCHWT1 та генерація коду." #: config/i386/i386.opt:958 #, no-c-format msgid "Emit profiling counter call at function entry before prologue." -msgstr "" +msgstr "Вивести виклик лічильника профілювання при вході в функцію перед прологом." #: config/i386/i386.opt:962 #, no-c-format msgid "Generate __mcount_loc section with all mcount or __fentry__ calls." -msgstr "" +msgstr "Створити розділ __mcount_loc з усіма викликами mcount або __fentry__." #: config/i386/i386.opt:966 config/s390/s390.opt:311 #, no-c-format msgid "Generate mcount/__fentry__ calls as nops. To activate they need to be patched in." -msgstr "" +msgstr "Створити виклики mcount/__fentry__ як nops. Щоб активувати їх, потрібно внести зміни." #: config/i386/i386.opt:971 #, no-c-format msgid "Set name of __fentry__ symbol called at function entry." -msgstr "" +msgstr "Встановити імʼя символу __fentry__, який викликається при вході в функцію." #: config/i386/i386.opt:975 #, no-c-format msgid "Set name of section to record mrecord-mcount calls." -msgstr "" +msgstr "Встановити імʼя розділу для запису викликів mrecord-mcount." #: config/i386/i386.opt:979 #, no-c-format msgid "Skip setting up RAX register when passing variable arguments." -msgstr "" +msgstr "Пропустити налаштування регістру RAX при передачі змінних аргументів." #: config/i386/i386.opt:983 #, no-c-format msgid "Expand 32bit/64bit integer divide into 8bit unsigned integer divide with run-time check." -msgstr "" +msgstr "Розширити ділення цілочисельних 32/64 біт на ділення беззнакових цілочисельних 8 біт з перевіркою під час виконання." #: config/i386/i386.opt:987 #, no-c-format msgid "Split 32-byte AVX unaligned load." -msgstr "" +msgstr "Розбити 32-байтове незвичайне завантаження AVX." #: config/i386/i386.opt:991 #, no-c-format msgid "Split 32-byte AVX unaligned store." -msgstr "" +msgstr "Розбити 32-байтове незвичайне збереження AVX." #: config/i386/i386.opt:995 #, no-c-format msgid "Support RTM built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду RTM." #: config/i386/i386.opt:1003 #, no-c-format msgid "Support MWAITX and MONITORX built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду MWAITX та MONITORX." #: config/i386/i386.opt:1007 #, no-c-format msgid "Support CLZERO built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду CLZERO." #: config/i386/i386.opt:1011 #, no-c-format msgid "Support PKU built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду PKU." #: config/i386/i386.opt:1019 #, no-c-format msgid "Known stack protector guard (for use with the -mstack-protector-guard= option):" -msgstr "" +msgstr "Відомий захисник стеку (для використання з опцією -mstack-protector-guard=):" #: config/i386/i386.opt:1043 #, no-c-format msgid "Use the given symbol for addressing the stack-protector guard." -msgstr "" +msgstr "Використовуйте заданий символ для адресації захисника стеку." #: config/i386/i386.opt:1054 #, no-c-format msgid "Enable shadow stack built-in functions from Control-flow Enforcement Technology (CET)." -msgstr "" +msgstr "Увімкнути вбудовані функції тіньового стеку з технології контролю потоку виконання (CET)." #: config/i386/i386.opt:1059 #, no-c-format msgid "Turn on CET instrumentation for switch statements that use a jump table and an indirect jump." -msgstr "" +msgstr "Увімкнути інструментування CET для операторів switch, які використовують таблицю переходів та непрямий перехід." #: config/i386/i386.opt:1064 #, no-c-format msgid "Insert ENDBR instruction at function entry only via cf_check attribute for CET instrumentation." -msgstr "" +msgstr "Вставити інструкцію ENDBR лише при вході в функцію через атрибут cf_check для інструментування CET." #: config/i386/i386.opt:1069 #, no-c-format msgid "Make all function calls indirect." -msgstr "" +msgstr "Зробити всі виклики функцій непрямими." #: config/i386/i386.opt:1073 #, no-c-format msgid "Convert indirect call and jump to call and return thunks." -msgstr "" +msgstr "Перетворити непрямий виклик та перехід на виклик та повернення тунків." #: config/i386/i386.opt:1077 #, no-c-format msgid "Convert function return to call and return thunk." -msgstr "" +msgstr "Перетворити повернення з функції на виклик та повернення тунку." #: config/i386/i386.opt:1081 config/s390/s390.opt:277 #, no-c-format msgid "Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options):" -msgstr "" +msgstr "Відомі вибори непрямих гілок (для використання з параметрами -mindirect-branch=/-mfunction-return=):" #: config/i386/i386.opt:1097 #, no-c-format msgid "Add CS prefix to call and jmp to indirect thunk with branch target in r8-r15 registers." -msgstr "" +msgstr "Додати префікс CS до виклику та jmp до непрямого тунку з ціллю гілки в регістрах r8-r15." #: config/i386/i386.opt:1101 #, no-c-format msgid "Force indirect call and jump via register." -msgstr "" +msgstr "Примусовий непрямий виклик та стрибок через регістр." #: config/i386/i386.opt:1105 #, no-c-format msgid "Support MOVDIRI built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій MOVDIRI та генерація коду." #: config/i386/i386.opt:1109 #, no-c-format msgid "Support MOVDIR64B built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій MOVDIR64B та генерація коду." #: config/i386/i386.opt:1113 #, no-c-format msgid "Support WAITPKG built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій WAITPKG та генерація коду." #: config/i386/i386.opt:1117 #, no-c-format msgid "Support CLDEMOTE built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій CLDEMOTE та генерація коду." #: config/i386/i386.opt:1121 #, no-c-format msgid "Instrument function exit in instrumented functions with __fentry__." -msgstr "" +msgstr "Інструментальна функція виходу в інструментованих функціях з __fentry__." #: config/i386/i386.opt:1125 #, no-c-format msgid "Known choices for return instrumentation with -minstrument-return=:" -msgstr "" +msgstr "Відомі варіанти для інструментальної обробки повернення з -minstrument-return=:" #: config/i386/i386.opt:1138 #, no-c-format msgid "Generate a __return_loc section pointing to all return instrumentation code." -msgstr "" +msgstr "Створити розділ __return_loc, що вказує на весь код інструментальної обробки повернення." #: config/i386/i386.opt:1146 #, no-c-format msgid "Known choices for mitigation against straight line speculation with -mharden-sls=:" -msgstr "" +msgstr "Відомі варіанти для зменшення прямої лінії спекуляції з -mharden-sls=:" #: config/i386/i386.opt:1162 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512BF16 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512BF16." #: config/i386/i386.opt:1167 #, no-c-format msgid "Support ENQCMD built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для ENQCMD." #: config/i386/i386.opt:1171 #, no-c-format msgid "Support SERIALIZE built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій SERIALIZE та генерація коду." #: config/i386/i386.opt:1175 #, no-c-format msgid "Support TSXLDTRK built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій TSXLDTRK та генерація коду." #: config/i386/i386.opt:1179 #, no-c-format msgid "Support AMX-TILE built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій AMX-TILE та генерація коду." #: config/i386/i386.opt:1183 #, no-c-format msgid "Support AMX-INT8 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій AMX-INT8 та генерація коду." #: config/i386/i386.opt:1187 #, no-c-format msgid "Support AMX-BF16 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій AMX-BF16 та генерація коду." #: config/i386/i386.opt:1191 #, no-c-format msgid "Support HRESET built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій HRESET та генерація коду." #: config/i386/i386.opt:1195 #, no-c-format msgid "Support KL built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій KL та генерація коду." #: config/i386/i386.opt:1199 #, no-c-format msgid "Support WIDEKL built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій WIDEKL та генерація коду." #: config/i386/i386.opt:1203 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and AVXVNNI built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та AVXVNNI." #: config/i386/i386.opt:1208 #, no-c-format msgid "Emit GNU_PROPERTY_X86_ISA_1_NEEDED GNU property." -msgstr "" +msgstr "Генерувати властивість GNU_PROPERTY_X86_ISA_1_NEEDED GNU." #: config/i386/i386.opt:1212 #, no-c-format msgid "Support MWAIT and MONITOR built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MWAIT та MONITOR." #: config/i386/i386.opt:1216 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512-FP16 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F та AVX512-FP16." #: config/i386/i386.opt:1220 #, no-c-format msgid "Do not use GOT to access external symbols." -msgstr "" +msgstr "Не використовувати GOT для доступу до зовнішніх символів." #: config/i386/i386.opt:1224 #, no-c-format msgid "Instructions number above which STFL stall penalty can be compensated." -msgstr "" +msgstr "Кількість інструкцій, після якої можна компенсувати штраф STFL." #: config/i386/i386.opt:1228 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and AVXIFMA built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та AVXIFMA." #: config/i386/i386.opt:1233 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVXVNNIINT8 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та AVXVNNIINT8." #: config/i386/i386.opt:1238 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and AVXNECONVERT build-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та AVXNECONVERT." #: config/i386/i386.opt:1243 #, no-c-format msgid "Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and CMPCCXADD build-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 та CMPCCXADD." #: config/i386/i386.opt:1248 #, no-c-format msgid "Support AMX-FP16 built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для AMX-FP16." #: config/i386/i386.opt:1252 #, no-c-format msgid "Support PREFETCHI built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для PREFETCHI." #: config/i386/i386.opt:1256 #, no-c-format msgid "Support RAOINT built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для RAOINT." #: config/i386/i386.opt:1260 #, no-c-format msgid "Enable conservative small loop unrolling." -msgstr "" +msgstr "Увімкнути консервативне розгортання невеликих циклів." #: config/i386/i386.opt:1264 #, no-c-format msgid "-mlam=[none|u48|u57] Instrument meta data position in user data pointers." -msgstr "" +msgstr "-mlam=[none|u48|u57] Позиція метаданих інструментування вказівників на дані користувача." #: config/i386/i386.opt:1280 #, no-c-format msgid "Support AMX-COMPLEX built-in functions and code generation." -msgstr "" +msgstr "Підтримка вбудованих функцій та генерація коду для AMX-COMPLEX." #: config/pa/pa64-hpux.opt:23 #, no-c-format msgid "Assume code will be linked by GNU ld." -msgstr "" +msgstr "Припускати, що код буде звʼязаний за допомогою GNU ld." #: config/pa/pa64-hpux.opt:27 #, no-c-format msgid "Assume code will be linked by HP ld." -msgstr "" +msgstr "Припускати, що код буде звʼязаний за допомогою HP ld." #: config/pa/pa-hpux1010.opt:23 config/pa/pa-hpux.opt:31 #: config/pa/pa-hpux1131.opt:23 config/pa/pa-hpux1111.opt:23 #, no-c-format msgid "Specify UNIX standard for predefines and linking." -msgstr "" +msgstr "Вказати стандарт UNIX для попередніх визначень та звʼязування." #: config/pa/pa-hpux.opt:27 #, no-c-format msgid "Generate cpp defines for server IO." -msgstr "" +msgstr "Створити cpp-визначення для введення-виведення сервера." #: config/pa/pa-hpux.opt:35 #, no-c-format msgid "Generate cpp defines for workstation IO." -msgstr "" +msgstr "Створити cpp-визначення для введення-виведення робочої станції." #: config/pa/pa.opt:30 config/pa/pa.opt:95 config/pa/pa.opt:107 #, no-c-format msgid "Generate PA1.0 code." -msgstr "" +msgstr "Створити код PA1.0." #: config/pa/pa.opt:34 config/pa/pa.opt:111 config/pa/pa.opt:156 #, no-c-format msgid "Generate PA1.1 code." -msgstr "" +msgstr "Створити код PA1.1." #: config/pa/pa.opt:38 config/pa/pa.opt:115 #, no-c-format msgid "Generate PA2.0 code (requires binutils 2.10 or later)." -msgstr "" +msgstr "Створити код PA2.0 (потрібні binutils 2.10 або пізніше)." #: config/pa/pa.opt:42 #, no-c-format msgid "Generate libcalls for atomic loads and stores when sync libcalls are disabled." -msgstr "" +msgstr "Створити libcalls для атомних завантажень та збережень, коли синхронні libcalls вимкнені." #: config/pa/pa.opt:50 #, no-c-format msgid "Caller copies function arguments passed by hidden reference." -msgstr "" +msgstr "Викликач копіює аргументи функції, передані захованим посиланням." #: config/pa/pa.opt:54 #, no-c-format msgid "Use ldcw/ldcd coherent cache-control hint." -msgstr "" +msgstr "Використовувати підказку ldcw/ldcd для керування кешем з однорідною поведінкою." #: config/pa/pa.opt:58 #, no-c-format msgid "Disable FP regs. Equivalent to -msoft-float." -msgstr "" +msgstr "Вимкнути FP регістри. Еквівалентно -msoft-float." #: config/pa/pa.opt:62 #, no-c-format msgid "Disable indexed addressing." -msgstr "Вимкнути індексоване адресування." +msgstr "Вимкнути індексовану адресацію." #: config/pa/pa.opt:66 #, no-c-format msgid "Generate fast indirect calls." -msgstr "" +msgstr "Генерувати швидкі непрямі виклики." #: config/pa/pa.opt:74 #, no-c-format msgid "Assume code will be assembled by GAS." -msgstr "" +msgstr "Припускати, що код буде зібраний за допомогою GAS." #: config/pa/pa.opt:83 #, no-c-format msgid "Enable linker optimizations." -msgstr "" +msgstr "Увімкнути оптимізацію лінкера." #: config/pa/pa.opt:87 #, no-c-format msgid "Always generate long calls." -msgstr "" +msgstr "Завжди генерувати довгі виклики." #: config/pa/pa.opt:91 #, no-c-format msgid "Emit long load/store sequences." -msgstr "" +msgstr "Видавати довгі послідовності завантаження/збереження." #: config/pa/pa.opt:99 #, no-c-format msgid "Disable space regs." -msgstr "" +msgstr "Вимкнути регістри простору." #: config/pa/pa.opt:103 #, no-c-format msgid "Assume memory references are ordered and barriers are not needed." -msgstr "" +msgstr "Припускати, що посилання на памʼять впорядковані і барʼєри не потрібні." #: config/pa/pa.opt:119 #, no-c-format msgid "Use portable calling conventions." -msgstr "" +msgstr "Використовувати переносні конвенції виклику." #: config/pa/pa.opt:123 #, no-c-format msgid "Specify CPU for scheduling purposes. Valid arguments are 700, 7100, 7100LC, 7200, 7300, and 8000." -msgstr "" +msgstr "Вказати процесор для планування. Допустимі аргументи: 700, 7100, 7100LC, 7200, 7300 і 8000." #: config/pa/pa.opt:148 config/frv/frv.opt:215 #, no-c-format msgid "Use software floating point." -msgstr "" +msgstr "Використовуйте програмне змінне плаваючої коми." #: config/pa/pa.opt:152 #, no-c-format msgid "Use software integer multiplication." -msgstr "" +msgstr "Використовуйте програмне цілочисельне множення." #: config/pa/pa.opt:160 #, no-c-format msgid "Do not disable space regs." -msgstr "" +msgstr "Не вимикайте регістри простору." #: config/v850/v850.opt:29 #, no-c-format msgid "Use registers r2 and r5." -msgstr "Використовувати регістри r2 і r5." +msgstr "Використовуйте регістри r2 та r5." #: config/v850/v850.opt:33 #, no-c-format msgid "Use 4 byte entries in switch tables." -msgstr "" +msgstr "Використовуйте 4-байтові записи в таблицях перемикача." #: config/v850/v850.opt:37 #, no-c-format msgid "Enable backend debugging." -msgstr "" +msgstr "Увімкнути налагодження backend." #: config/v850/v850.opt:41 #, no-c-format msgid "Do not use the callt instruction (default)." -msgstr "" +msgstr "Не використовуйте інструкцію callt (за замовчуванням)." #: config/v850/v850.opt:45 #, no-c-format msgid "Reuse r30 on a per function basis." -msgstr "" +msgstr "Повторне використання r30 на основі функцій." #: config/v850/v850.opt:52 #, no-c-format msgid "Prohibit PC relative function calls." -msgstr "" +msgstr "Заборонити виклики функцій відносно PC." #: config/v850/v850.opt:56 #, no-c-format msgid "Use stubs for function prologues." -msgstr "" +msgstr "Використовуйте заглушки для прологів функцій." #: config/v850/v850.opt:60 #, no-c-format msgid "Set the max size of data eligible for the SDA area." -msgstr "" +msgstr "Встановити максимальний розмір даних, придатних для області SDA." #: config/v850/v850.opt:67 #, no-c-format msgid "Enable the use of the short load instructions." -msgstr "" +msgstr "Увімкнути використання коротких інструкцій завантаження." #: config/v850/v850.opt:71 #, no-c-format msgid "Same as: -mep -mprolog-function." -msgstr "" +msgstr "Те саме, що й: -mep -mprolog-function." #: config/v850/v850.opt:75 #, no-c-format msgid "Set the max size of data eligible for the TDA area." -msgstr "" +msgstr "Встановити максимальний розмір даних, придатних для області TDA." #: config/v850/v850.opt:82 #, no-c-format msgid "Do not enforce strict alignment." -msgstr "" +msgstr "Не накладати жорстку вирівнювання." #: config/v850/v850.opt:86 #, no-c-format msgid "Put jump tables for switch statements into the .data section rather than the .code section." -msgstr "" +msgstr "Розмістити таблиці переходів для операторів switch в розділ .data, а не в розділ .code." #: config/v850/v850.opt:93 #, no-c-format msgid "Compile for the v850 processor." -msgstr "" +msgstr "Компілювати для процесора v850." #: config/v850/v850.opt:97 #, no-c-format msgid "Compile for the v850e processor." -msgstr "" +msgstr "Компілювати для процесора v850e." #: config/v850/v850.opt:101 #, no-c-format msgid "Compile for the v850e1 processor." -msgstr "" +msgstr "Компілювати для процесора v850e1." #: config/v850/v850.opt:105 #, no-c-format msgid "Compile for the v850es variant of the v850e1." -msgstr "" +msgstr "Компілювати для варіанту v850es процесора v850e1." #: config/v850/v850.opt:109 #, no-c-format msgid "Compile for the v850e2 processor." -msgstr "" +msgstr "Компілювати для процесора v850e2." #: config/v850/v850.opt:113 #, no-c-format msgid "Compile for the v850e2v3 processor." -msgstr "" +msgstr "Компілювати для процесора v850e2v3." #: config/v850/v850.opt:117 #, no-c-format msgid "Compile for the v850e3v5 processor." -msgstr "" +msgstr "Компілювати для процесора v850e3v5." #: config/v850/v850.opt:124 #, no-c-format msgid "Enable v850e3v5 loop instructions." -msgstr "" +msgstr "Увімкнути інструкції циклу для v850e3v5." #: config/v850/v850.opt:128 #, no-c-format msgid "Set the max size of data eligible for the ZDA area." -msgstr "" +msgstr "Встановити максимальний розмір даних, придатних для області ZDA." #: config/v850/v850.opt:135 #, no-c-format msgid "Enable relaxing in the assembler." -msgstr "" +msgstr "Увімкнути розслаблення в асемблері." #: config/v850/v850.opt:139 #, no-c-format msgid "Prohibit PC relative jumps." -msgstr "" +msgstr "Заборонити відносні стрибки PC." #: config/v850/v850.opt:143 #, no-c-format msgid "Inhibit the use of hardware floating point instructions." -msgstr "" +msgstr "Заборонити використання апаратних інструкцій з плаваючою комою." #: config/v850/v850.opt:147 #, no-c-format msgid "Allow the use of hardware floating point instructions for V850E2V3 and up." -msgstr "" +msgstr "Дозволити використання апаратних інструкцій з плаваючою комою для V850E2V3 і вище." #: config/v850/v850.opt:151 #, no-c-format msgid "Enable support for the RH850 ABI. This is the default." -msgstr "" +msgstr "Увімкнути підтримку RH850 ABI. Це значення за замовчуванням." #: config/v850/v850.opt:155 #, no-c-format msgid "Enable support for the old GCC ABI." -msgstr "" +msgstr "Увімкнути підтримку старого GCC ABI." #: config/v850/v850.opt:159 #, no-c-format msgid "Support alignments of up to 64-bits." -msgstr "" +msgstr "Підтримка вирівнювання до 64 біт." #: config/g.opt:27 #, no-c-format msgid "-G\tPut global and static data smaller than bytes into a special section (on some targets)." -msgstr "" +msgstr "-G<число>\tРозмістити глобальні та статичні дані розміром менше <число> байт у спеціальний розділ (на деяких цільових платформах)." #: config/lynx.opt:23 #, no-c-format msgid "Support legacy multi-threading." -msgstr "" +msgstr "Підтримка старого багатопотокового виконання." #: config/lynx.opt:27 #, no-c-format @@ -7956,1443 +7931,1443 @@ msgstr "Використовувати бібліотеки спільного #: config/lynx.opt:31 #, no-c-format msgid "Support multi-threading." -msgstr "" +msgstr "Підтримка багатопотокового виконання." #: config/nvptx/nvptx-gen.opt:24 #, no-c-format msgid "Known PTX ISA target architectures (for use with the -misa= option):" -msgstr "" +msgstr "Відомі архітектури цільової системи PTX ISA (для використання з опцією -misa=):" #: config/nvptx/nvptx.opt:28 #, no-c-format msgid "Ignored, but preserved for backward compatibility. Only 64-bit ABI is supported." -msgstr "" +msgstr "Ігнорується, але зберігається для забезпечення сумісності з попередніми версіями. Підтримується лише 64-бітна ABI." #: config/nvptx/nvptx.opt:33 #, no-c-format msgid "Link in code for a __main kernel." -msgstr "" +msgstr "Посилання на код для ядра __main." #: config/nvptx/nvptx.opt:37 #, no-c-format msgid "Optimize partition neutering." -msgstr "" +msgstr "Оптимізація нейтралізації розділів." #: config/nvptx/nvptx.opt:41 #, no-c-format msgid "Use custom stacks instead of local memory for automatic storage." -msgstr "" +msgstr "Використовувати власні стеки замість локальної памʼяті для автоматичного зберігання." #: config/nvptx/nvptx.opt:45 #, no-c-format msgid "Specify size of .local memory used for stack when the exact amount is not known." -msgstr "" +msgstr "Вказати розмір .local памʼяті, яка використовується для стеку, коли точна кількість не відома." #: config/nvptx/nvptx.opt:49 #, no-c-format msgid "Generate code that can keep local state uniform across all lanes." -msgstr "" +msgstr "Генерувати код, який може зберігати локальний стан однорідним для всіх доріжок." #: config/nvptx/nvptx.opt:53 #, no-c-format msgid "Generate code for OpenMP offloading: enables -msoft-stack and -muniform-simt." -msgstr "" +msgstr "Генерувати код для віддаленого виконання OpenMP: увімкнути -msoft-stack та -muniform-simt." #: config/nvptx/nvptx.opt:57 #, no-c-format msgid "Specify the PTX ISA target architecture to use." -msgstr "" +msgstr "Вказати цільову архітектуру PTX ISA, яку слід використовувати." #: config/nvptx/nvptx.opt:61 #, no-c-format msgid "Alias:" -msgstr "Замінник:" +msgstr "Псевдонім:" #: config/nvptx/nvptx.opt:116 #, no-c-format msgid "Known PTX ISA versions (for use with the -mptx= option):" -msgstr "" +msgstr "Відомі версії PTX ISA (для використання з опцією -mptx=):" #: config/nvptx/nvptx.opt:135 #, no-c-format msgid "Specify the PTX ISA version to use." -msgstr "" +msgstr "Вказати версію PTX ISA, яку слід використовувати." #: config/nvptx/nvptx.opt:139 #, no-c-format msgid "Initialize ptx registers." -msgstr "Ініціалізувати ptx-регістри." +msgstr "Ініціалізувати регістри ptx." #: config/vxworks.opt:36 #, no-c-format msgid "Assume the VxWorks RTP environment." -msgstr "" +msgstr "Припустити середовище VxWorks RTP." #: config/vxworks.opt:43 #, no-c-format msgid "Assume the VxWorks vThreads environment." -msgstr "" +msgstr "Припустимо середовище VxWorks vThreads." #: config/avr/avr.opt:23 #, no-c-format msgid "Use subroutines for function prologues and epilogues." -msgstr "" +msgstr "Використовуйте підпрограми для прологів та епілогів функцій." #: config/avr/avr.opt:27 #, no-c-format msgid "-mmcu=MCU\tSelect the target MCU." -msgstr "" +msgstr "-mmcu=МКП\tВиберати цільовий МКП." #: config/avr/avr.opt:31 #, no-c-format msgid "Allow usage of __gcc_isr pseudo instructions in ISR prologues and epilogues." -msgstr "" +msgstr "Дозволити використання псевдоінструкцій __gcc_isr в прологах та епілогах обробників переривань." #: config/avr/avr.opt:35 #, no-c-format msgid "Set the number of 64 KiB flash segments." -msgstr "" +msgstr "Встановити кількість сегментів флеш-памʼяті розміром 64 Кб." #: config/avr/avr.opt:39 #, no-c-format msgid "Indicate presence of a processor erratum." -msgstr "" +msgstr "Вказати наявність помилки процесора." #: config/avr/avr.opt:43 #, no-c-format msgid "Enable Read-Modify-Write (RMW) instructions support/use." -msgstr "" +msgstr "Увімкнути підтримку/використання інструкцій Read-Modify-Write (RMW)." #: config/avr/avr.opt:53 #, no-c-format msgid "Use RJMP / RCALL even though CALL / JMP are available." -msgstr "" +msgstr "Використовуйте RJMP / RCALL, навіть якщо доступні CALL / JMP." #: config/avr/avr.opt:57 #, no-c-format msgid "Use an 8-bit 'int' type." -msgstr "" +msgstr "Використовуйте тип 'int' з розміром 8 біт." #: config/avr/avr.opt:61 #, no-c-format msgid "Change the stack pointer without disabling interrupts." -msgstr "" +msgstr "Змінити вказівник стеку без вимкнення переривань." #: config/avr/avr.opt:65 #, no-c-format msgid "Set the branch costs for conditional branch instructions. Reasonable values are small, non-negative integers. The default branch cost is 0." -msgstr "" +msgstr "Встановити вартість гілок для умовних гілкових інструкцій. Розумні значення - це невеликі, не відʼємні цілі числа. За замовчуванням вартість гілки дорівнює 0." #: config/avr/avr.opt:69 #, no-c-format msgid "Treat main as if it had attribute OS_task." -msgstr "" +msgstr "Трактувати main так, ніби вона мала атрибут OS_task." #: config/avr/avr.opt:79 #, no-c-format msgid "Change only the low 8 bits of the stack pointer." -msgstr "" +msgstr "Змінити лише нижні 8 біт вказівника стеку." #: config/avr/avr.opt:83 #, no-c-format msgid "Relax branches." -msgstr "" +msgstr "Розслабити гілки." #: config/avr/avr.opt:87 #, no-c-format msgid "Make the linker relaxation machine assume that a program counter wrap-around occurs." -msgstr "" +msgstr "Зробити машину розслаблення лінкера припускає, що відбувається обгортання лічильника програми." #: config/avr/avr.opt:91 #, no-c-format msgid "Accumulate outgoing function arguments and acquire/release the needed stack space for outgoing function arguments in function prologue/epilogue. Without this option, outgoing arguments are pushed before calling a function and popped afterwards. This option can lead to reduced code size for functions that call many functions that get their arguments on the stack like, for example printf." -msgstr "" +msgstr "Накопичувати вихідні аргументи функції та здобудьте / звільніть необхідний простір стеку для вихідних аргументів функції в пролог / епілог функції. Без цієї опції вихідні аргументи викликаються перед викликом функції та видаляються після цього. Ця опція може призвести до зменшення розміру коду для функцій, які викликають багато функцій, які отримують свої аргументи зі стеку, наприклад, printf." #: config/avr/avr.opt:95 #, no-c-format msgid "When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register. Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X." -msgstr "" +msgstr "При доступі до ОЗП використовувати X, як вимагає апаратне забезпечення, тобто використовувати переддекремент, післяінкремент та непряме звертання з використанням регістра X. Без цієї опції компілятор може припустити, що існує режим адресації X+const, подібний до Y+const та Z+const, і генерувати інструкції для емуляції такого режиму адресації для X." #: config/avr/avr.opt:100 #, no-c-format msgid "The device has no SPH special function register. This option will be overridden by the compiler driver with the correct setting if presence/absence of SPH can be deduced from -mmcu=MCU." -msgstr "" +msgstr "Пристрій не має спеціального регістра функцій SPH. Ця опція буде перезаписана компілятором з правильним налаштуванням, якщо наявність/відсутність SPH може бути виведена з -mmcu=МКП." #: config/avr/avr.opt:104 #, no-c-format msgid "Warn if the address space of an address is changed." -msgstr "" +msgstr "Попереджати, якщо простір адреси змінюється." #: config/avr/avr.opt:108 #, no-c-format msgid "Warn if the ISR is misspelled, i.e. without __vector prefix. Enabled by default." -msgstr "" +msgstr "Попереджати, якщо ISR неправильно написано, тобто без префіксу __vector. Увімкнено за замовчуванням." #: config/avr/avr.opt:112 #, no-c-format msgid "Allow to use truncation instead of rounding towards zero for fractional fixed-point types." -msgstr "" +msgstr "Дозволити використовувати обрізку замість округлення до нуля для дробових фіксованих типів." #: config/avr/avr.opt:116 #, no-c-format msgid "Assume that all data in static storage can be accessed by LDS / STS. This option is only useful for reduced Tiny devices." -msgstr "" +msgstr "Припускати, що всі дані у статичному сховищі можна отримати за допомогою LDS / STS. Ця опція корисна лише для зменшених пристроїв Tiny." #: config/avr/avr.opt:120 #, no-c-format msgid "-mdouble=\tUse bits wide double type." -msgstr "" +msgstr "-mdouble=\tВикористовувати тип double з шириною біт." #: config/avr/avr.opt:124 #, no-c-format msgid "-mlong-double=\tUse bits wide long double type." -msgstr "" +msgstr "-mlong-double=\tВикористовувати тип long double з шириною біт." #: config/avr/avr.opt:128 #, no-c-format msgid "Do not link against the device-specific library lib.a." -msgstr "" +msgstr "Не підключати до бібліотеки lib<МКП>.a, яка специфічна для пристрою." #: config/avr/avr.opt:132 #, no-c-format msgid "Do not use the device-specific specs file device-specs/specs-." -msgstr "" +msgstr "Не використовувати специфічний для пристрою файл specs-<МКП> у каталозі device-specs." #: config/avr/avr.opt:136 #, no-c-format msgid "Available BITS selections:" -msgstr "" +msgstr "Доступні варіанти BITS:" #: config/m32r/m32r.opt:34 #, no-c-format msgid "Compile for the m32rx." -msgstr "" +msgstr "Компілювати для m32rx." #: config/m32r/m32r.opt:38 #, no-c-format msgid "Compile for the m32r2." -msgstr "" +msgstr "Компілювати для m32r2." #: config/m32r/m32r.opt:42 #, no-c-format msgid "Compile for the m32r." -msgstr "" +msgstr "Компілювати для m32r." #: config/m32r/m32r.opt:46 #, no-c-format msgid "Align all loops to 32 byte boundary." -msgstr "" +msgstr "Вирівнювати всі цикли до границі 32 байти." #: config/m32r/m32r.opt:50 #, no-c-format msgid "Prefer branches over conditional execution." -msgstr "" +msgstr "Віддавати перевагу гілкам перед умовним виконанням." #: config/m32r/m32r.opt:54 #, no-c-format msgid "Give branches their default cost." -msgstr "" +msgstr "Надавати гілкам їхню типову вартість." #: config/m32r/m32r.opt:58 #, no-c-format msgid "Display compile time statistics." -msgstr "" +msgstr "Показувати статистику часу компіляції." #: config/m32r/m32r.opt:62 #, no-c-format msgid "Specify cache flush function." -msgstr "" +msgstr "Вказати функцію очищення кешу." #: config/m32r/m32r.opt:66 #, no-c-format msgid "Specify cache flush trap number." -msgstr "" +msgstr "Вказати номер пастки очищення кешу." #: config/m32r/m32r.opt:70 #, no-c-format msgid "Only issue one instruction per cycle." -msgstr "" +msgstr "Видавати тільки одну інструкцію на цикл." #: config/m32r/m32r.opt:74 #, no-c-format msgid "Allow two instructions to be issued per cycle." -msgstr "" +msgstr "Дозволити видавати дві інструкції на цикл." #: config/m32r/m32r.opt:78 #, no-c-format msgid "Code size: small, medium or large." -msgstr "" +msgstr "Розмір коду: малий, середній або великий." #: config/m32r/m32r.opt:94 #, no-c-format msgid "Don't call any cache flush functions." -msgstr "" +msgstr "Не викликати жодну функцію очищення кешу." #: config/m32r/m32r.opt:98 #, no-c-format msgid "Don't call any cache flush trap." -msgstr "" +msgstr "Не викликати жодну пастку очищення кешу." #: config/m32r/m32r.opt:105 #, no-c-format msgid "Small data area: none, sdata, use." -msgstr "" +msgstr "Мала область даних: немає, sdata, використовувати." #: config/s390/tpf.opt:23 #, no-c-format msgid "Enable TPF-OS tracing code." -msgstr "" +msgstr "Увімкнути код відстеження TPF-OS." #: config/s390/tpf.opt:27 #, no-c-format msgid "Set the trace check address for prologue tpf hook" -msgstr "" +msgstr "Встановити адресу перевірки сліду для гачка tpf прологу" #: config/s390/tpf.opt:31 #, no-c-format msgid "Set the trace jump address for prologue tpf hook" -msgstr "" +msgstr "Встановити адресу переходу сліду для гачка tpf прологу" #: config/s390/tpf.opt:35 #, no-c-format msgid "Set the trace check address for epilogue tpf hook" -msgstr "" +msgstr "Встановити адресу перевірки сліду для гачка tpf епілогу" #: config/s390/tpf.opt:39 #, no-c-format msgid "Set the trace jump address for epilogue tpf hook" -msgstr "" +msgstr "Встановити адресу переходу сліду для гачка tpf епілогу" #: config/s390/tpf.opt:43 #, no-c-format msgid "Set the prologue and epilogue hook addresses to TPF_TRACE_PROLOGUE_SKIP_TARGET and TPF_TRACE_EPILOGUE_SKIP_TARGET. Equivalent to using -mtpf-trace-hook-prologue-target=TPF_TRACE_PROLOGUE_SKIP_TARGET and -mtpf-trace-hook-epilogue-target=TPF_TRACE_EPILOGUE_SKIP_TARGET" -msgstr "" +msgstr "Встановити адреси гачків прологу та епілогу на TPF_TRACE_PROLOGUE_SKIP_TARGET та TPF_TRACE_EPILOGUE_SKIP_TARGET. Еквівалентно використанню -mtpf-trace-hook-prologue-target=TPF_TRACE_PROLOGUE_SKIP_TARGET та -mtpf-trace-hook-epilogue-target=TPF_TRACE_EPILOGUE_SKIP_TARGET" #: config/s390/tpf.opt:47 #, no-c-format msgid "Specify main object for TPF-OS." -msgstr "" +msgstr "Вказати основний обʼєкт для TPF-OS." #: config/s390/s390.opt:48 #, no-c-format msgid "31 bit ABI." -msgstr "" +msgstr "ABI 31 біт." #: config/s390/s390.opt:52 #, no-c-format msgid "64 bit ABI." -msgstr "" +msgstr "ABI 64 біт." #: config/s390/s390.opt:129 #, no-c-format msgid "Maintain backchain pointer." -msgstr "" +msgstr "Підтримувати вказівник backchain." #: config/s390/s390.opt:133 #, no-c-format msgid "Additional debug prints." -msgstr "" +msgstr "Додаткові відлагоджувальні виводи." #: config/s390/s390.opt:137 #, no-c-format msgid "ESA/390 architecture." -msgstr "" +msgstr "Архітектура ESA/390." #: config/s390/s390.opt:141 #, no-c-format msgid "Enable decimal floating point hardware support." -msgstr "" +msgstr "Увімкнути підтримку апаратного забезпечення для десяткових чисел з плаваючою комою." #: config/s390/s390.opt:145 #, no-c-format msgid "Enable hardware floating point." -msgstr "" +msgstr "Увімкнути апаратну підтримку чисел з плаваючою комою." #: config/s390/s390.opt:149 #, no-c-format msgid "Takes two non-negative integer numbers separated by a comma. Prepend the function label with the number of two-byte Nop instructions indicated by the first. Append Nop instructions covering the number of halfwords indicated by the second after the label. Nop instructions of the largest possible size are used (six, four or two bytes), beginning with the largest possible size. Using 0 for both values disables hotpatching." -msgstr "" +msgstr "Приймає два не відʼємних цілих числа, розділені комою. Додає до мітки функції кількість двобайтових інструкцій Nop, вказаних першим числом. Після мітки додаються інструкції Nop, що покривають кількість половин слів, вказану другим числом. Використовуються Nop-інструкції найбільшого можливого розміру (шість, чотири або два байти), починаючи з найбільшого можливого розміру. Використання значення 0 для обох чисел забороняє гаряче латання." #: config/s390/s390.opt:167 #, no-c-format msgid "Use hardware transactional execution instructions." -msgstr "" +msgstr "Використовувати інструкції апаратного виконання транзакцій." #: config/s390/s390.opt:171 #, no-c-format msgid "Use hardware vector facility instructions and enable the vector ABI." -msgstr "" +msgstr "Використовувати інструкції апаратного виконання векторних операцій та увімкнути векторний ABI." #: config/s390/s390.opt:175 #, no-c-format msgid "Use packed stack layout." -msgstr "" +msgstr "Використовуйте упаковану структуру стеку." #: config/s390/s390.opt:179 #, no-c-format msgid "Use bras for executable < 64k." -msgstr "" +msgstr "Використовувати bras для виконуваних файлів менше 64к." #: config/s390/s390.opt:183 #, no-c-format msgid "Disable hardware floating point." -msgstr "" +msgstr "Вимкнути апаратне з плаваючою комою." #: config/s390/s390.opt:187 #, no-c-format msgid "Set the max. number of bytes which has to be left to stack size before a trap instruction is triggered." -msgstr "" +msgstr "Встановити максимальну кількість байтів, які мають залишитися до розміру стеку, перш ніж буде викликана пастка." #: config/s390/s390.opt:191 #, no-c-format msgid "Switches off the -mstack-guard= option." -msgstr "" +msgstr "Вимкнути опцію -mstack-guard=." #: config/s390/s390.opt:195 #, no-c-format msgid "Emit extra code in the function prologue in order to trap if the stack size exceeds the given limit." -msgstr "" +msgstr "Видавати додатковий код у прологу функції, щоб викликати пастку, якщо розмір стеку перевищує задане обмеження." #: config/s390/s390.opt:199 #, no-c-format msgid "Switches off the -mstack-size= option." -msgstr "" +msgstr "Вимикає опцію -mstack-size=." #: config/s390/s390.opt:207 #, no-c-format msgid "Use the mvcle instruction for block moves." -msgstr "" +msgstr "Використовуйте інструкцію mvcle для переміщення блоків." #: config/s390/s390.opt:211 #, no-c-format msgid "Enable the z vector language extension providing the context-sensitive vector macro and enable the Altivec-style builtins in vecintrin.h." -msgstr "" +msgstr "Увімкнути розширення мови з векторами z, яке надає контекстно-чутливий векторний макрос та увімкнути вбудовані функції у стилі Altivec в vecintrin.h." #: config/s390/s390.opt:216 #, no-c-format msgid "Warn if a function uses alloca or creates an array with dynamic size." -msgstr "" +msgstr "Попереджати, якщо функція використовує alloca або створює масив з динамічним розміром." #: config/s390/s390.opt:220 #, no-c-format msgid "Warn if a single function's framesize exceeds the given framesize." -msgstr "" +msgstr "Попереджати, якщо розмір рамки однієї функції перевищує заданий розмір рамки." #: config/s390/s390.opt:224 #, no-c-format msgid "z/Architecture." -msgstr "" +msgstr "z/Архітектура." #: config/s390/s390.opt:228 #, no-c-format msgid "Set the branch costs for conditional branch instructions. Reasonable values are small, non-negative integers. The default branch cost is 1." -msgstr "" +msgstr "Встановити вартість гілок для умовних гілкових інструкцій. Розумні значення - це невеликі невідʼємні цілі числа. За замовчуванням вартість гілки становить 1." #: config/s390/s390.opt:238 config/arm/arm.opt:181 #, no-c-format msgid "Assume data segments are relative to text segment." -msgstr "" +msgstr "Припустимо, що сегменти даних відносяться до сегмента тексту." #: config/s390/s390.opt:243 #, no-c-format msgid "Wrap all indirect branches into execute in order to disable branch prediction." -msgstr "" +msgstr "Обернути всі непрямі гілки в execute, щоб вимкнути передбачення гілок." #: config/s390/s390.opt:248 #, no-c-format msgid "Wrap indirect table jumps and computed gotos into execute in order to disable branch prediction. Using thunk or thunk-extern with this option requires the thunks to be considered signal handlers to order to generate correct CFI. For environments where unwinding (e.g. for exceptions) is required please use thunk-inline instead." -msgstr "" +msgstr "Обгорнути непрямі переходи до таблиці та обчислені gotos в execute, щоб вимкнути передбачення гілок. Використання thunk або thunk-extern з цією опцією вимагає, щоб тунки вважалися обробниками сигналів, щоб згенерувати правильний CFI. Для середовищ, де потрібне розгортання (наприклад, для винятків), будь ласка, використовуйте thunk-inline замість цього." #: config/s390/s390.opt:256 #, no-c-format msgid "Wrap all indirect calls into execute in order to disable branch prediction." -msgstr "" +msgstr "Обгорнути всі непрямі виклики в execute, щоб вимкнути передбачення гілок." #: config/s390/s390.opt:260 #, no-c-format msgid "Wrap all indirect return branches into execute in order to disable branch prediction." -msgstr "" +msgstr "Обгорнути всі непрямі гілки повернення в execute, щоб вимкнути передбачення гілок." #: config/s390/s390.opt:265 #, no-c-format msgid "Wrap indirect return branches into execute in order to disable branch prediction. This affects only branches where the return address is going to be restored from memory." -msgstr "" +msgstr "Обгорнути непрямі гілки повернення в execute, щоб вимкнути передбачення гілок. Це стосується лише гілок, де адреса повернення буде відновлена з памʼяті." #: config/s390/s390.opt:271 #, no-c-format msgid "Wrap indirect return branches into execute in order to disable branch prediction. This affects only branches where the return address doesn't need to be restored from memory." -msgstr "" +msgstr "Обгорнути непрямі гілки повернення в execute, щоб вимкнути передбачення гілок. Це стосується лише гілок, де адресу повернення не потрібно відновлювати з памʼяті." #: config/s390/s390.opt:293 #, no-c-format msgid "Generate sections .s390_indirect_jump, .s390_indirect_call, .s390_return_reg, and .s390_return_mem to contain the indirect branch locations which have been patched as part of using one of the -mindirect-branch* or -mfunction-return* options. The sections consist of an array of 32 bit elements. Each entry holds the offset from the entry to the patched location." -msgstr "" +msgstr "Створити розділи .s390_indirect_jump, .s390_indirect_call, .s390_return_reg та .s390_return_mem, щоб містити місця непрямих гілок, які були виправлені в рамках використання однієї з опцій -mindirect-branch* або -mfunction-return*. Розділи складаються з масиву 32-бітних елементів. Кожен запис містить зсув від запису до виправленого місця." #: config/s390/s390.opt:302 #, no-c-format msgid "Emit profiling counter call at function entry before prologue. The compiled code will require a 64-bit CPU and glibc 2.29 or newer to run." -msgstr "" +msgstr "Видавати виклик лічильника профілювання при вході в функцію перед прологом. Скомпільований код буде потребувати 64-бітний процесор і glibc 2.29 або новішу версію для запуску." #: config/s390/s390.opt:307 #, no-c-format msgid "Generate __mcount_loc section with all _mcount and __fentry__ calls." -msgstr "" +msgstr "Створити розділ __mcount_loc з усіма викликами _mcount та __fentry__." #: config/s390/s390.opt:316 #, no-c-format msgid "Emit fused multiply-add instructions for long doubles in vector registers (wfmaxb, wfmsxb, wfnmaxb, wfnmsxb). Reassociation pass does not handle fused multiply-adds, therefore code generated by the middle-end is prone to having long fused multiply-add chains. This is not pipeline-friendly, and the default behavior is to emit separate multiplication and addition instructions for long doubles in vector registers, because measurements show that this improves performance. This option allows overriding it for testing purposes." -msgstr "" +msgstr "Генерувати обʼєднані інструкції множення-додавання для довгих чисел з плаваючою комою в векторних регістрах (wfmaxb, wfmsxb, wfnmaxb, wfnmsxb). Прохід переасоціації не обробляє обʼєднані інструкції множення-додавання, тому код, що генерується середнім рівнем, схильний до наявності довгих ланцюжків обʼєднаних інструкцій множення-додавання. Це не сприятливо для конвеєра, і типова поведінка полягає в генерації окремих інструкцій множення і додавання для довгих чисел з плаваючою комою в векторних регістрах, оскільки вимірювання показують, що це покращує продуктивність. Ця опція дозволяє її перевизначити для тестування." #: config/s390/s390.opt:331 #, no-c-format msgid "Store all argument registers on the stack." -msgstr "" +msgstr "Зберігайте всі регістри аргументів у стеку." #: config/rl78/rl78.opt:27 config/rx/elf.opt:26 config/csky/csky.opt:198 #, no-c-format msgid "Use the simulator runtime." -msgstr "" +msgstr "Використовуйте рантайм симулятора." #: config/rl78/rl78.opt:31 #, no-c-format msgid "Selects the type of hardware multiplication and division to use (none/g13/g14)." -msgstr "" +msgstr "Виберати тип апаратного множення та ділення, який слід використовувати (none/g13/g14)." #: config/rl78/rl78.opt:50 #, no-c-format msgid "Use all registers, reserving none for interrupt handlers." -msgstr "" +msgstr "Використовувати всі регістри, не залишаючи жодного для обробників переривань." #: config/rl78/rl78.opt:54 #, no-c-format msgid "Enable assembler and linker relaxation. Enabled by default at -Os." -msgstr "" +msgstr "Увімкнути розслаблення асемблера та лінкера. За замовчуванням увімкнено при -Os." #: config/rl78/rl78.opt:58 #, no-c-format msgid "Selects the type of RL78 core being targeted (g10/g13/g14). The default is the G14. If set, also selects the hardware multiply support to be used." -msgstr "" +msgstr "Виберати тип цільового ядра RL78 (g10/g13/g14). За замовчуванням використовується G14. Якщо встановлено, також вибирається підтримка апаратного множення, яка буде використовуватися." #: config/rl78/rl78.opt:77 #, no-c-format msgid "Alias for -mcpu=g10." -msgstr "" +msgstr "Псевдонім для -mcpu=g10." #: config/rl78/rl78.opt:81 #, no-c-format msgid "Alias for -mcpu=g13." -msgstr "" +msgstr "Псевдонім для -mcpu=g13." #: config/rl78/rl78.opt:85 config/rl78/rl78.opt:89 #, no-c-format msgid "Alias for -mcpu=g14." -msgstr "" +msgstr "Псевдонім для -mcpu=g14." #: config/rl78/rl78.opt:93 #, no-c-format msgid "Assume ES is zero throughout program execution, use ES: for read-only data." -msgstr "" +msgstr "Припускається, що ES дорівнює нулю протягом виконання програми, використовуйте ES: для даних тільки для читання." #: config/rl78/rl78.opt:97 #, no-c-format msgid "Stores the MDUC registers in interrupt handlers for G13 target." -msgstr "" +msgstr "Зберігає регістри MDUC у обробниках переривань для цілі G13." #: config/stormy16/stormy16.opt:24 #, no-c-format msgid "Provide libraries for the simulator." -msgstr "" +msgstr "Надавати бібліотеки для симулятора." #: config/arm/arm-tables.opt:25 #, no-c-format msgid "Known ARM CPUs (for use with the -mcpu= and -mtune= options):" -msgstr "" +msgstr "Відомі процесори ARM (для використання з опціями -mcpu= та -mtune=):" #: config/arm/arm-tables.opt:302 #, no-c-format msgid "Known ARM architectures (for use with the -march= option):" -msgstr "" +msgstr "Відомі архітектури ARM (для використання з опцією -march=):" #: config/arm/arm-tables.opt:408 #, no-c-format msgid "Known ARM FPUs (for use with the -mfpu= option):" -msgstr "" +msgstr "Відомі FPU ARM (для використання з опцією -mfpu=):" #: config/arm/arm.opt:38 #, no-c-format msgid "TLS dialect to use:" -msgstr "" +msgstr "Діалект TLS, який слід використовувати:" #: config/arm/arm.opt:48 #, no-c-format msgid "Specify an ABI." -msgstr "" +msgstr "Вказати ABI." #: config/arm/arm.opt:52 #, no-c-format msgid "Known ARM ABIs (for use with the -mabi= option):" -msgstr "" +msgstr "Відомі ABI ARM (для використання з опцією -mabi=):" #: config/arm/arm.opt:71 #, no-c-format msgid "Generate a call to abort if a noreturn function returns." -msgstr "" +msgstr "Згенерувати виклик функції «abort», якщо функція з атрибутом «noreturn» повертається." #: config/arm/arm.opt:78 #, no-c-format msgid "Generate APCS conformant stack frames." -msgstr "" +msgstr "Створювати стекові фрейми, відповідні до APCS." #: config/arm/arm.opt:82 #, no-c-format msgid "Generate re-entrant, PIC code." -msgstr "" +msgstr "Створювати код, який може бути викликаний з різних місць та є PIC." #: config/arm/arm.opt:104 #, no-c-format msgid "Generate code in 32 bit ARM state." -msgstr "" +msgstr "Створювати код у 32-бітному стані ARM." #: config/arm/arm.opt:112 #, no-c-format msgid "Thumb: Assume non-static functions may be called from ARM code." -msgstr "" +msgstr "Thumb: Припускати, що нестатичні функції можуть бути викликані з коду ARM." #: config/arm/arm.opt:116 #, no-c-format msgid "Thumb: Assume function pointers may go to non-Thumb aware code." -msgstr "" +msgstr "Thumb: Припускати, що вказівники на функції можуть вказувати на код, який не підтримує Thumb." #: config/arm/arm.opt:124 config/csky/csky.opt:73 #, no-c-format msgid "Specify if floating point hardware should be used." -msgstr "" +msgstr "Вказати, чи слід використовувати апаратне забезпечення з плаваючою комою." #: config/arm/arm.opt:128 #, no-c-format msgid "Specify that the compiler should target secure code as per ARMv8-M Security Extensions." -msgstr "" +msgstr "Вказати, що компілятор має спрямовуватися на безпечний код згідно з розширеннями безпеки ARMv8-M." #: config/arm/arm.opt:132 config/csky/csky.opt:77 #, no-c-format msgid "Known floating-point ABIs (for use with the -mfloat-abi= option):" -msgstr "" +msgstr "Відомі ABI з плаваючою комою (для використання з опцією -mfloat-abi=):" #: config/arm/arm.opt:145 #, no-c-format msgid "Switch ARM/Thumb modes on alternating functions for compiler testing." -msgstr "" +msgstr "Перемикати режими ARM/Thumb на чергуючих функціях для тестування компілятора." #: config/arm/arm.opt:149 #, no-c-format msgid "Specify the __fp16 floating-point format." -msgstr "" +msgstr "Вказати формат плаваючої коми __fp16." #: config/arm/arm.opt:153 #, no-c-format msgid "Known __fp16 formats (for use with the -mfp16-format= option):" -msgstr "" +msgstr "Відомі формати __fp16 (для використання з опцією -mfp16-format=):" #: config/arm/arm.opt:166 #, no-c-format msgid "Specify the name of the target floating point hardware/format." -msgstr "" +msgstr "Вказати назву апаратного/формату плаваючої коми цільової системи." #: config/arm/arm.opt:177 #, no-c-format msgid "Generate call insns as indirect calls, if necessary." -msgstr "" +msgstr "Генерувати інструкції виклику як непрямі виклики, якщо потрібно." #: config/arm/arm.opt:185 #, no-c-format msgid "Specify the register to be used for PIC addressing." -msgstr "" +msgstr "Вказати регістр, який буде використовуватися для адресації PIC." #: config/arm/arm.opt:189 #, no-c-format msgid "Store function names in object code." -msgstr "" +msgstr "Зберігати імена функцій у коді обʼєкта." #: config/arm/arm.opt:193 #, no-c-format msgid "Permit scheduling of a function's prologue sequence." -msgstr "" +msgstr "Дозволити планування послідовності прологу функції." #: config/arm/arm.opt:197 config/rs6000/rs6000.opt:235 #, no-c-format msgid "Do not load the PIC register in function prologues." -msgstr "" +msgstr "Не завантажувати регістр PIC у прологах функцій." #: config/arm/arm.opt:204 #, no-c-format msgid "Specify the minimum bit alignment of structures. (Deprecated)." -msgstr "" +msgstr "Вказати мінімальне вирівнювання бітів структур. (Застаріло)." #: config/arm/arm.opt:208 #, no-c-format msgid "Generate code for Thumb state." -msgstr "" +msgstr "Генерувати код для режиму Thumb." #: config/arm/arm.opt:212 #, no-c-format msgid "Support calls between Thumb and ARM instruction sets." -msgstr "" +msgstr "Підтримка викликів між наборами інструкцій Thumb та ARM." #: config/arm/arm.opt:216 #, no-c-format msgid "Specify thread local storage scheme." -msgstr "" +msgstr "Вказати схему локального сховища потоків." #: config/arm/arm.opt:220 #, no-c-format msgid "Specify how to access the thread pointer." -msgstr "" +msgstr "Вказати, як отримати доступ до вказівника потоку." #: config/arm/arm.opt:224 #, no-c-format msgid "Valid arguments to -mtp=:" -msgstr "" +msgstr "Дійсні аргументи для -mtp=:" #: config/arm/arm.opt:237 #, no-c-format msgid "Thumb: Generate (non-leaf) stack frames even if not needed." -msgstr "" +msgstr "Thumb: Генерувати (не-листочкові) стекові фрейми навіть якщо не потрібно." #: config/arm/arm.opt:241 #, no-c-format msgid "Thumb: Generate (leaf) stack frames even if not needed." -msgstr "" +msgstr "Thumb: Генерувати (листочкові) стекові фрейми навіть якщо не потрібно." #: config/arm/arm.opt:245 config/mn10300/mn10300.opt:42 #, no-c-format msgid "Tune code for the given processor." -msgstr "" +msgstr "Налаштувати код для заданого процесора." #: config/arm/arm.opt:249 #, no-c-format msgid "Print CPU tuning information as comment in assembler file. This is an option used only for regression testing of the compiler and not intended for ordinary use in compiling code." -msgstr "" +msgstr "Вивести інформацію про налаштування CPU як коментар у файлі асемблера. Ця опція використовується лише для регресійного тестування компілятора і не призначена для звичайного використання при компіляції коду." #: config/arm/arm.opt:260 #, no-c-format msgid "Use Neon quad-word (rather than double-word) registers for vectorization." -msgstr "" +msgstr "Використовувати Neon квадро-слова (замість двійкових слів) регістри для векторизації." #: config/arm/arm.opt:264 #, no-c-format msgid "Use Neon double-word (rather than quad-word) registers for vectorization." -msgstr "" +msgstr "Використовувати Neon двійкові слова (замість квадро-слів) регістри для векторизації." #: config/arm/arm.opt:268 #, no-c-format msgid "Enable more verbose RTX cost dumps during debug. For GCC developers use only." -msgstr "" +msgstr "Увімкнути більш детальний вивід витрат RTX під час налагодження. Тільки для розробників GCC." #: config/arm/arm.opt:272 #, no-c-format msgid "Only generate absolute relocations on word sized values." -msgstr "" +msgstr "Генерувати тільки абсолютні переклади для значень розміром слова." #: config/arm/arm.opt:276 #, no-c-format msgid "Generate IT blocks appropriate for ARMv8." -msgstr "" +msgstr "Генерувати блоки IT, відповідні для ARMv8." #: config/arm/arm.opt:280 #, no-c-format msgid "Avoid overlapping destination and address registers on LDRD instructions that may trigger Cortex-M3 errata." -msgstr "" +msgstr "Уникати перекриття регістрів призначення та адреси в інструкціях LDRD, які можуть спричинити помилки Cortex-M3." #: config/arm/arm.opt:285 #, no-c-format msgid "Mitigate issues with VLLDM on some M-profile devices (CVE-2021-35465)." -msgstr "" +msgstr "Усунути проблеми з VLLDM на деяких пристроях M-профілю (CVE-2021-35465)." #: config/arm/arm.opt:289 #, no-c-format msgid "Mitigate issues with AES instructions on Cortex-A57 and Cortex-A72 (Arm erratum #1742098)." -msgstr "" +msgstr "Усунути проблеми з інструкціями AES на Cortex-A57 та Cortex-A72 (Arm erratum #1742098)." #: config/arm/arm.opt:294 #, no-c-format msgid "Mitigate issues with AES instructions on Cortex-A57 and Cortex-A72 (Arm erratum #1655431)." -msgstr "" +msgstr "Усунути проблеми з інструкціями AES на Cortex-A57 та Cortex-A72 (Arm erratum #1655431)." #: config/arm/arm.opt:299 config/nds32/nds32.opt:461 config/arc/arc.opt:495 #, no-c-format msgid "Enable unaligned word and halfword accesses to packed data." -msgstr "" +msgstr "Увімкнути доступ до незаініціалізованих слів та напівслів до упакованих даних." #: config/arm/arm.opt:303 #, no-c-format msgid "This option is deprecated and has no effect." -msgstr "" +msgstr "Ця опція застаріла і не має жодного ефекту." #: config/arm/arm.opt:307 #, no-c-format msgid "Assume loading data from flash is slower than fetching instructions." -msgstr "" +msgstr "Припустити, що завантаження даних з флеш-памʼяті повільніше, ніж отримання інструкцій." #: config/arm/arm.opt:311 #, no-c-format msgid "Assume unified syntax for inline assembly code." -msgstr "" +msgstr "Припустити єдиний синтаксис для вбудованого коду асемблера." #: config/arm/arm.opt:315 #, no-c-format msgid "Do not allow constant data to be placed in code sections." -msgstr "" +msgstr "Не дозволяти розміщувати константні дані в розділах коду." #: config/arm/arm.opt:319 #, no-c-format msgid "When linking for big-endian targets, generate a BE8 format image." -msgstr "" +msgstr "При звʼязуванні для цілей з великим порядком байтів, генерувати зображення у форматі BE8." #: config/arm/arm.opt:323 #, no-c-format msgid "When linking for big-endian targets, generate a legacy BE32 format image." -msgstr "" +msgstr "При звʼязуванні для цілей з великим порядком байтів, генерувати зображення у форматі спадкового BE32." #: config/arm/arm.opt:327 config/sh/sh.opt:195 #, no-c-format msgid "Cost to assume for a branch insn." -msgstr "" +msgstr "Вартість, яку слід припустити для інструкції гілки." #: config/arm/arm.opt:335 #, no-c-format msgid "Generate code which uses the core registers only (r0-r14)." -msgstr "" +msgstr "Генерувати код, який використовує лише реєстри ядра (r0-r14)." #: config/arm/arm.opt:357 #, no-c-format msgid "Use an immediate to offset from the TLS register. This option is for use with fstack-protector-guard=tls and not for use in user-land code." -msgstr "" +msgstr "Використовувати негайний зсув від реєстру TLS. Ця опція призначена для використання з fstack-protector-guard=tls і не призначена для використання в коді користувача." #: config/sparc/sparc.opt:30 config/sparc/sparc.opt:34 #: config/visium/visium.opt:37 #, no-c-format msgid "Use hardware FP." -msgstr "" +msgstr "Використовувати апаратну плаваючу кому." #: config/sparc/sparc.opt:38 config/visium/visium.opt:41 #, no-c-format msgid "Do not use hardware FP." -msgstr "" +msgstr "Не використовувати апаратну плаваючу кому." #: config/sparc/sparc.opt:42 #, no-c-format msgid "Use flat register window model." -msgstr "" +msgstr "Використовувати модель плоского вікна регістрів." #: config/sparc/sparc.opt:46 #, no-c-format msgid "Assume possible double misalignment." -msgstr "" +msgstr "Припускати можливу подвійну невідповідність." #: config/sparc/sparc.opt:50 #, no-c-format msgid "Use ABI reserved registers." -msgstr "" +msgstr "Використовувати зарезервовані регістри ABI." #: config/sparc/sparc.opt:54 #, no-c-format msgid "Use hardware quad FP instructions." -msgstr "" +msgstr "Використовувати апаратні чотирикратні FP-інструкції." #: config/sparc/sparc.opt:58 #, no-c-format msgid "Do not use hardware quad fp instructions." -msgstr "" +msgstr "Не використовувати апаратні чотирикратні FP-інструкції." #: config/sparc/sparc.opt:62 config/vax/vax.opt:47 #, no-c-format msgid "Enable Local Register Allocation." -msgstr "" +msgstr "Увімкнути локальне розподілення регістрів." #: config/sparc/sparc.opt:66 #, no-c-format msgid "Compile for V8+ ABI." -msgstr "" +msgstr "Компілювати для ABI V8+." #: config/sparc/sparc.opt:70 #, no-c-format msgid "Use UltraSPARC Visual Instruction Set version 1.0 extensions." -msgstr "" +msgstr "Використовувати розширення UltraSPARC Visual Instruction Set версії 1.0." #: config/sparc/sparc.opt:74 #, no-c-format msgid "Use UltraSPARC Visual Instruction Set version 2.0 extensions." -msgstr "" +msgstr "Використовувати розширення UltraSPARC Visual Instruction Set версії 2.0." #: config/sparc/sparc.opt:78 #, no-c-format msgid "Use UltraSPARC Visual Instruction Set version 3.0 extensions." -msgstr "" +msgstr "Використовувати розширення UltraSPARC Visual Instruction Set версії 3.0." #: config/sparc/sparc.opt:82 #, no-c-format msgid "Use UltraSPARC Visual Instruction Set version 4.0 extensions." -msgstr "" +msgstr "Використовуйте розширення UltraSPARC Visual Instruction Set версії 4.0." #: config/sparc/sparc.opt:86 #, no-c-format msgid "Use additional VIS instructions introduced in OSA2017." -msgstr "" +msgstr "Використовуйте додаткові інструкції VIS, введені в OSA2017." #: config/sparc/sparc.opt:90 #, no-c-format msgid "Use UltraSPARC Compare-and-Branch extensions." -msgstr "" +msgstr "Використовуйте розширення UltraSPARC Compare-and-Branch." #: config/sparc/sparc.opt:94 #, no-c-format msgid "Use UltraSPARC Fused Multiply-Add extensions." -msgstr "" +msgstr "Використовуйте розширення UltraSPARC Fused Multiply-Add." #: config/sparc/sparc.opt:98 #, no-c-format msgid "Use Floating-point Multiply Single to Double (FsMULd) instruction." -msgstr "" +msgstr "Використовуйте інструкцію з множення з плаваючою точкою з одинарної на подвійну точність (FsMULd)." #: config/sparc/sparc.opt:102 #, no-c-format msgid "Use UltraSPARC Population-Count instruction." -msgstr "" +msgstr "Використовуйте інструкцію UltraSPARC Population-Count." #: config/sparc/sparc.opt:106 #, no-c-format msgid "Use UltraSPARC Subtract-Extended-with-Carry instruction." -msgstr "" +msgstr "Використовуйте інструкцію віднімання з розширенням з переносом UltraSPARC." #: config/sparc/sparc.opt:110 #, no-c-format msgid "Pointers are 64-bit." -msgstr "" +msgstr "Вказівники мають розмір 64 біти." #: config/sparc/sparc.opt:114 #, no-c-format msgid "Pointers are 32-bit." -msgstr "" +msgstr "Вказівники мають розмір 32 біти." #: config/sparc/sparc.opt:118 #, no-c-format msgid "Use 64-bit ABI." -msgstr "" +msgstr "Використовуйте 64-бітне ABI." #: config/sparc/sparc.opt:122 #, no-c-format msgid "Use 32-bit ABI." -msgstr "" +msgstr "Використовуйте 32-бітне ABI." #: config/sparc/sparc.opt:126 #, no-c-format msgid "Use stack bias." -msgstr "" +msgstr "Використовуйте зсув стеку." #: config/sparc/sparc.opt:130 #, no-c-format msgid "Use structs on stronger alignment for double-word copies." -msgstr "" +msgstr "Використовуйте структури з більшою вирівнюванням для копіювання двохслівних даних." #: config/sparc/sparc.opt:134 #, no-c-format msgid "Optimize tail call instructions in assembler and linker." -msgstr "" +msgstr "Оптимізуйте інструкції хвостового виклику в асемблері та лінкері." #: config/sparc/sparc.opt:138 #, no-c-format msgid "Do not generate code that can only run in supervisor mode (default)." -msgstr "" +msgstr "Не генерувати код, який може працювати тільки в режимі супервізора (за замовчуванням)." #: config/sparc/sparc.opt:142 #, no-c-format msgid "Use instructions of and schedule code for given CPU." -msgstr "" +msgstr "Використовуйте інструкції та розкладайте код для вказаного процесора." #: config/sparc/sparc.opt:228 #, no-c-format msgid "Use given SPARC-V9 code model." -msgstr "" +msgstr "Використовуйте задану модель коду SPARC-V9." #: config/sparc/sparc.opt:250 #, no-c-format msgid "Enable debug output." -msgstr "Увімкнути виведення діагностичних даних." +msgstr "Увімкнути вивід для налагодження." #: config/sparc/sparc.opt:254 #, no-c-format msgid "Enable strict 32-bit psABI struct return checking." -msgstr "" +msgstr "Увімкнути строгу перевірку повернення структур psABI 32-біт." #: config/sparc/sparc.opt:258 #, no-c-format msgid "Enable workaround for single erratum of AT697F processor (corresponding to erratum #13 of AT697E processor)." -msgstr "" +msgstr "Увімкнути обхід для одного помилкового сценарію процесора AT697F (відповідає помилковому сценарію №13 процесора AT697E)." #: config/sparc/sparc.opt:263 #, no-c-format msgid "Enable workarounds for the errata of the UT699 processor." -msgstr "" +msgstr "Увімкнути обхідні рішення для помилок процесора UT699." #: config/sparc/sparc.opt:267 #, no-c-format msgid "Enable workarounds for the errata of the UT699E/UT700 processor." -msgstr "" +msgstr "Увімкнути обхідні рішення для помилок процесорів UT699E/UT700." #: config/sparc/sparc.opt:271 #, no-c-format msgid "Enable workarounds for the errata of the GR712RC processor." -msgstr "" +msgstr "Увімкнути обхідні рішення для помилок процесора GR712RC." #: config/sparc/sparc.opt:308 #, no-c-format msgid "Specify the memory model in effect for the program." -msgstr "" +msgstr "Вказати модель памʼяті, що застосовується для програми." #: config/rs6000/darwin.opt:38 config/rs6000/sysv4.opt:145 #, no-c-format msgid "Generate 64-bit code." -msgstr "" +msgstr "Генерувати 64-бітний код." #: config/rs6000/darwin.opt:42 config/rs6000/sysv4.opt:149 #, no-c-format msgid "Generate 32-bit code." -msgstr "" +msgstr "Генерувати 32-бітний код." #: config/rs6000/rs6000-tables.opt:24 #, no-c-format msgid "Known CPUs (for use with the -mcpu= and -mtune= options):" -msgstr "" +msgstr "Відомі процесори (для використання з опціями -mcpu= та -mtune=):" #: config/rs6000/476.opt:24 #, no-c-format msgid "Preserve the PowerPC 476's link stack by matching up a blr with the bcl/bl insns used for GOT accesses." -msgstr "" +msgstr "Зберегти стек звʼязку PowerPC 476 з допомогою парування blr з інструкціями bcl/bl, що використовуються для доступу до GOT." #: config/rs6000/aix64.opt:24 #, no-c-format msgid "Compile for 64-bit pointers." -msgstr "" +msgstr "Компілювати для 64-бітних вказівників." #: config/rs6000/aix64.opt:28 #, no-c-format msgid "Compile for 32-bit pointers." -msgstr "" +msgstr "Компілювати для 32-бітних вказівників." #: config/rs6000/aix64.opt:32 config/rs6000/linux64.opt:28 #, no-c-format msgid "Select code model." -msgstr "" +msgstr "Вибрати модель коду." #: config/rs6000/aix64.opt:49 #, no-c-format msgid "Support message passing with the Parallel Environment." -msgstr "" +msgstr "Підтримка передачі повідомлень з паралельним середовищем." #: config/rs6000/linux64.opt:24 #, no-c-format msgid "Call mcount for profiling before a function prologue." -msgstr "" +msgstr "Викликати mcount для профілювання перед прологом функції." #: config/rs6000/rs6000.opt:117 #, no-c-format msgid "Use PowerPC-64 instruction set." -msgstr "" +msgstr "Використовувати набір інструкцій PowerPC-64." #: config/rs6000/rs6000.opt:121 #, no-c-format msgid "Use PowerPC General Purpose group optional instructions." -msgstr "" +msgstr "Використовувати необовʼязкові інструкції групи загального призначення PowerPC." #: config/rs6000/rs6000.opt:125 #, no-c-format msgid "Use PowerPC Graphics group optional instructions." -msgstr "" +msgstr "Використовувати необовʼязкові інструкції групи графіки PowerPC." #: config/rs6000/rs6000.opt:129 #, no-c-format msgid "Use PowerPC V2.01 single field mfcr instruction." -msgstr "" +msgstr "Використовувати інструкцію mfcr з одним полем PowerPC V2.01." #: config/rs6000/rs6000.opt:133 #, no-c-format msgid "Use PowerPC V2.02 popcntb instruction." -msgstr "" +msgstr "Використовувати інструкцію popcntb PowerPC V2.02." #: config/rs6000/rs6000.opt:137 #, no-c-format msgid "Use PowerPC V2.02 floating point rounding instructions." -msgstr "" +msgstr "Використовуйте інструкції округлення з плаваючою комою PowerPC V2.02." #: config/rs6000/rs6000.opt:141 #, no-c-format msgid "Use PowerPC V2.05 compare bytes instruction." -msgstr "" +msgstr "Використовуйте інструкцію порівняння байтів PowerPC V2.05." #: config/rs6000/rs6000.opt:152 #, no-c-format msgid "Use AltiVec instructions." -msgstr "" +msgstr "Використовуйте інструкції AltiVec." #: config/rs6000/rs6000.opt:156 #, no-c-format msgid "Use decimal floating point instructions." -msgstr "" +msgstr "Використовуйте інструкції десяткової плаваючої коми." #: config/rs6000/rs6000.opt:160 #, no-c-format msgid "Use 4xx half-word multiply instructions." -msgstr "" +msgstr "Використовувати інструкції множення напівслів 4xx." #: config/rs6000/rs6000.opt:164 #, no-c-format msgid "Use 4xx string-search dlmzb instruction." -msgstr "" +msgstr "Використовуйте інструкцію пошуку рядка dlmzb 4xx." #: config/rs6000/rs6000.opt:168 #, no-c-format msgid "Generate load/store multiple instructions." -msgstr "" +msgstr "Генерувати інструкції завантаження/збереження декількох значень." #: config/rs6000/rs6000.opt:187 #, no-c-format msgid "Use PowerPC V2.06 popcntd instruction." -msgstr "" +msgstr "Використовуйте інструкцію popcntd PowerPC V2.06." #: config/rs6000/rs6000.opt:191 #, no-c-format msgid "Under -ffast-math, generate a FRIZ instruction for (double)(long long) conversions." -msgstr "" +msgstr "При використанні -ffast-math, генерувати інструкцію FRIZ для перетворень (double)(long long)." #: config/rs6000/rs6000.opt:199 #, no-c-format msgid "Use vector/scalar (VSX) instructions." -msgstr "" +msgstr "Використовуйте інструкції вектор/скаляр (VSX)." #: config/rs6000/rs6000.opt:227 #, no-c-format msgid "Do not generate load/store with update instructions." -msgstr "" +msgstr "Не генерувати інструкції завантаження/збереження з оновленням." #: config/rs6000/rs6000.opt:231 #, no-c-format msgid "Generate load/store with update instructions." -msgstr "" +msgstr "Генерувати інструкції завантаження/збереження з оновленням." #: config/rs6000/rs6000.opt:239 #, no-c-format msgid "Avoid generation of indexed load/store instructions when possible." -msgstr "" +msgstr "Уникайте генерації індексованих інструкцій завантаження/збереження, якщо це можливо." #: config/rs6000/rs6000.opt:246 #, no-c-format msgid "Schedule the start and end of the procedure." -msgstr "" +msgstr "Заплануйте початок і кінець процедури." #: config/rs6000/rs6000.opt:250 #, no-c-format msgid "Return all structures in memory (AIX default)." -msgstr "" +msgstr "Повертайте всі структури у памʼяті (типове значення AIX)." #: config/rs6000/rs6000.opt:254 #, no-c-format msgid "Return small structures in registers (SVR4 default)." -msgstr "" +msgstr "Повертайте невеликі структури у регістрах (типове значення SVR4)." #: config/rs6000/rs6000.opt:258 #, no-c-format msgid "Conform more closely to IBM XLC semantics." -msgstr "" +msgstr "Більш точно відповідайте семантиці IBM XLC." #: config/rs6000/rs6000.opt:262 config/rs6000/rs6000.opt:266 #, no-c-format msgid "Generate software reciprocal divide and square root for better throughput." -msgstr "" +msgstr "Генерувати програмне ділення зворотним значенням та квадратний корінь для кращої продуктивності." #: config/rs6000/rs6000.opt:270 #, no-c-format msgid "Assume that the reciprocal estimate instructions provide more accuracy." -msgstr "" +msgstr "Припустимо, що інструкції оцінки оберненого значення надають більшу точність." #: config/rs6000/rs6000.opt:274 #, no-c-format msgid "Do not place floating point constants in TOC." -msgstr "" +msgstr "Не розміщуйте константи з плаваючою точкою в TOC." #: config/rs6000/rs6000.opt:278 #, no-c-format msgid "Place floating point constants in TOC." -msgstr "" +msgstr "Розмістіть константи з плаваючою точкою в TOC." #: config/rs6000/rs6000.opt:282 #, no-c-format msgid "Do not place symbol+offset constants in TOC." -msgstr "" +msgstr "Не розміщуйте константи символу+зсуву в TOC." #: config/rs6000/rs6000.opt:286 #, no-c-format msgid "Place symbol+offset constants in TOC." -msgstr "" +msgstr "Розмістіть константи символу+зсуву в TOC." #: config/rs6000/rs6000.opt:297 #, no-c-format msgid "Use only one TOC entry per procedure." -msgstr "" +msgstr "Використовуйте лише один запис TOC для кожної процедури." #: config/rs6000/rs6000.opt:301 #, no-c-format msgid "Put everything in the regular TOC." -msgstr "" +msgstr "Помістіть все в звичайний TOC." #: config/rs6000/rs6000.opt:305 #, no-c-format msgid "Generate VRSAVE instructions when generating AltiVec code." -msgstr "" +msgstr "Генерувати інструкції VRSAVE при генерації коду AltiVec." #: config/rs6000/rs6000.opt:309 #, no-c-format msgid "Deprecated option. Use -mno-vrsave instead." -msgstr "" +msgstr "Застаріла опція. Використовуйте -mno-vrsave замість цього." #: config/rs6000/rs6000.opt:313 #, no-c-format msgid "Deprecated option. Use -mvrsave instead." -msgstr "" +msgstr "Застаріла опція. Використовуйте -mvrsave замість неї." #: config/rs6000/rs6000.opt:317 #, no-c-format msgid "Max number of bytes to move inline." -msgstr "" +msgstr "Максимальна кількість байтів для переміщення в рядку." #: config/rs6000/rs6000.opt:321 #, no-c-format msgid "Generate unaligned VSX load/store for inline expansion of memcpy/memmove." -msgstr "" +msgstr "Генерувати незбалансоване завантаження/збереження VSX для вбудованого розширення memcpy/memmove." #: config/rs6000/rs6000.opt:325 #, no-c-format msgid "Generate unaligned VSX vector pair load/store for inline expansion of memcpy/memmove." -msgstr "" +msgstr "Генерувати незбалансоване завантаження/збереження пари векторів VSX для вбудованого розширення memcpy/memmove." #: config/rs6000/rs6000.opt:329 #, no-c-format msgid "Max number of bytes to compare without loops." -msgstr "" +msgstr "Максимальна кількість байтів для порівняння без циклів." #: config/rs6000/rs6000.opt:333 #, no-c-format msgid "Max number of bytes to compare with loops." -msgstr "" +msgstr "Максимальна кількість байтів для порівняння з циклами." #: config/rs6000/rs6000.opt:337 #, no-c-format msgid "Max number of bytes to compare." -msgstr "" +msgstr "Максимальна кількість байтів для порівняння." #: config/rs6000/rs6000.opt:341 #, no-c-format msgid "Generate isel instructions." -msgstr "" +msgstr "Генерувати інструкції isel." #: config/rs6000/rs6000.opt:345 #, no-c-format msgid "-mdebug=\tEnable debug output." -msgstr "-mdebug=\tУвімкнути виведення діагностичних даних." +msgstr "-mdebug=\tУвімкнути вивід для налагодження." #: config/rs6000/rs6000.opt:350 #, no-c-format msgid "Use the AltiVec ABI extensions." -msgstr "" +msgstr "Використовувати розширення AltiVec ABI." #: config/rs6000/rs6000.opt:354 #, no-c-format msgid "Do not use the AltiVec ABI extensions." -msgstr "" +msgstr "Не використовуйте розширення AltiVec ABI." #: config/rs6000/rs6000.opt:359 #, no-c-format msgid "Use the AIX Vector Extended ABI." -msgstr "" +msgstr "Використовуйте розширення AIX Vector Extended ABI." #: config/rs6000/rs6000.opt:363 #, no-c-format msgid "Do not use the AIX Vector Extended ABI." -msgstr "" +msgstr "Не використовуйте розширення AIX Vector Extended ABI." #: config/rs6000/rs6000.opt:368 #, no-c-format msgid "Use the ELFv1 ABI." -msgstr "" +msgstr "Використовуйте розширення ELFv1 ABI." #: config/rs6000/rs6000.opt:372 #, no-c-format msgid "Use the ELFv2 ABI." -msgstr "" +msgstr "Використовуйте розширення ELFv2 ABI." #: config/rs6000/rs6000.opt:392 #, no-c-format msgid "-mcpu=\tUse features of and schedule code for given CPU." -msgstr "" +msgstr "-mcpu=\tВикористовуйте можливості та розкладайте код для вказаного процесора." #: config/rs6000/rs6000.opt:396 #, no-c-format msgid "-mtune=\tSchedule code for given CPU." -msgstr "" +msgstr "-mtune=\tРозкладайте код для вказаного процесора." #: config/rs6000/rs6000.opt:400 #, no-c-format msgid "-mtraceback=[full,part,no]\tSelect type of traceback table." -msgstr "" +msgstr "-mtraceback=[full,part,no]\tВиберіть тип таблиці відстеження." #: config/rs6000/rs6000.opt:416 #, no-c-format msgid "Avoid all range limits on call instructions." -msgstr "" +msgstr "Уникайте всіх обмежень діапазону на інструкціях виклику." #: config/rs6000/rs6000.opt:424 #, no-c-format msgid "Warn about deprecated 'vector long ...' AltiVec type usage." -msgstr "" +msgstr "Попереджати про застаріле використання типу AltiVec «vector long ...»." #: config/rs6000/rs6000.opt:428 #, no-c-format msgid "Use -mlong-double-64 for 64-bit IEEE floating point format. Use -mlong-double-128 for 128-bit floating point format (either IEEE or IBM)." -msgstr "" +msgstr "Використовуйте -mlong-double-64 для формату з плаваючою комою IEEE 64-біт. Використовуйте -mlong-double-128 для формату з плаваючою комою 128-біт (або IEEE, або IBM)." #: config/rs6000/rs6000.opt:437 #, no-c-format msgid "Determine which dependences between insns are considered costly." -msgstr "" +msgstr "Визначити, які залежності між інструкціями вважаються витратними." #: config/rs6000/rs6000.opt:441 #, no-c-format msgid "Specify which post scheduling nop insertion scheme to apply." -msgstr "" +msgstr "Вказати, яку схему вставки NOP після планування застосувати." #: config/rs6000/rs6000.opt:445 #, no-c-format msgid "Specify alignment of structure fields default/natural." -msgstr "" +msgstr "Вказати вирівнювання полів структури за замовчуванням/природне." #: config/rs6000/rs6000.opt:449 #, no-c-format msgid "Valid arguments to -malign-:" -msgstr "" +msgstr "Дійсні аргументи для -malign-:" #: config/rs6000/rs6000.opt:459 #, no-c-format msgid "Specify scheduling priority for dispatch slot restricted insns." -msgstr "" +msgstr "Вказати пріоритет планування для обмежених інструкцій вирішувального слоту." #: config/rs6000/rs6000.opt:463 #, no-c-format msgid "Use r11 to hold the static link in calls to functions via pointers." -msgstr "" +msgstr "Використовуйте регістр r11 для зберігання статичного звʼязку при викликах функцій через вказівники." #: config/rs6000/rs6000.opt:467 #, no-c-format msgid "Save the TOC in the prologue for indirect calls rather than inline." -msgstr "" +msgstr "Зберігайте TOC в прологу для непрямих викликів, а не вбудованих." #: config/rs6000/rs6000.opt:475 #, no-c-format msgid "Fuse certain integer operations together for better performance on power8." -msgstr "" +msgstr "Обʼєднуйте певні цілочисельні операції для кращої продуктивності на power8." #: config/rs6000/rs6000.opt:479 #, no-c-format msgid "Allow sign extension in fusion operations." -msgstr "" +msgstr "Дозволяйте розширення знаку в операціях злиття." #: config/rs6000/rs6000.opt:483 #, no-c-format msgid "Use vector and scalar instructions added in ISA 2.07." -msgstr "" +msgstr "Використовуйте векторні та скалярні інструкції, додані в ISA 2.07." #: config/rs6000/rs6000.opt:487 #, no-c-format msgid "Fuse certain integer operations together for better performance on power10." -msgstr "" +msgstr "Обʼєднуйте певні цілочисельні операції для кращої продуктивності на power10." #: config/rs6000/rs6000.opt:491 #, no-c-format msgid "Use ISA 2.07 Category:Vector.AES and Category:Vector.SHA2 instructions." -msgstr "" +msgstr "Використовуйте інструкції ISA 2.07 Category:Vector.AES та Category:Vector.SHA2." #: config/rs6000/rs6000.opt:498 #, no-c-format msgid "Use ISA 2.07 transactional memory (HTM) instructions." -msgstr "" +msgstr "Використовуйте інструкції транзакційної памʼяті ISA 2.07 (HTM)." #: config/rs6000/rs6000.opt:502 #, no-c-format msgid "Generate the quad word memory instructions (lq/stq)." -msgstr "" +msgstr "Створюйте інструкції памʼяті квадратного слова (lq/stq)." #: config/rs6000/rs6000.opt:506 #, no-c-format msgid "Generate the quad word memory atomic instructions (lqarx/stqcx)." -msgstr "" +msgstr "Генерувати атомні інструкції памʼяті квадратного слова (lqarx/stqcx)." #: config/rs6000/rs6000.opt:510 #, no-c-format msgid "Generate aggregate parameter passing code with at most 64-bit alignment." -msgstr "" +msgstr "Генерувати код передачі агрегатних параметрів з максимальним вирівнюванням 64 біти." #: config/rs6000/rs6000.opt:514 #, no-c-format msgid "Analyze and remove doubleword swaps from VSX computations." -msgstr "" +msgstr "Аналізувати та видаляти обміни двохслівних слів з обчислень VSX." #: config/rs6000/rs6000.opt:522 #, no-c-format msgid "Use certain scalar instructions added in ISA 3.0." -msgstr "" +msgstr "Використовувати певні скалярні інструкції, додані в ISA 3.0." #: config/rs6000/rs6000.opt:526 #, no-c-format msgid "Use vector instructions added in ISA 3.0." -msgstr "" +msgstr "Використовувати векторні інструкції, додані в ISA 3.0." #: config/rs6000/rs6000.opt:530 #, no-c-format msgid "Use the new min/max instructions defined in ISA 3.0." -msgstr "" +msgstr "Використовувати нові інструкції min/max, визначені в ISA 3.0." #: config/rs6000/rs6000.opt:534 #, no-c-format msgid "Generate the integer modulo instructions." -msgstr "" +msgstr "Генерувати інструкції з цілим залишком." #: config/rs6000/rs6000.opt:538 #, no-c-format msgid "Enable IEEE 128-bit floating point via the __float128 keyword." -msgstr "" +msgstr "Увімкнути IEEE 128-бітне плаваюча кома з використанням ключового слова __float128." #: config/rs6000/rs6000.opt:542 #, no-c-format msgid "Enable using IEEE 128-bit floating point instructions." -msgstr "" +msgstr "Увімкнути використання інструкцій з плаваючою комою IEEE 128 біт." #: config/rs6000/rs6000.opt:546 #, no-c-format msgid "Enable default conversions between __float128 & long double." -msgstr "" +msgstr "Увімкнути типові перетворення між __float128 та long double." #: config/rs6000/rs6000.opt:586 #, no-c-format msgid "Generate (do not generate) prefixed memory instructions." -msgstr "" +msgstr "Генерувати (не генерувати) інструкції памʼяті з префіксом." #: config/rs6000/rs6000.opt:590 #, no-c-format msgid "Generate (do not generate) pc-relative memory addressing." -msgstr "" +msgstr "Створювати (не створювати) адресування памʼяті відносно PC." #: config/rs6000/rs6000.opt:594 #, no-c-format msgid "Generate (do not generate) pc-relative memory optimizations for externals." -msgstr "" +msgstr "Створювати (не створювати) оптимізації памʼяті відносно PC для зовнішніх обʼєктів." #: config/rs6000/rs6000.opt:598 #, no-c-format @@ -9402,4170 +9377,4169 @@ msgstr "Створювати (не створювати) інструкції MM #: config/rs6000/rs6000.opt:605 #, no-c-format msgid "Enable instructions that guard against return-oriented programming attacks." -msgstr "" +msgstr "Увімкнути інструкції, що захищають від атак, заснованих на орієнтованому поверненні." #: config/rs6000/rs6000.opt:609 #, no-c-format msgid "Generate code that will run in privileged state." -msgstr "" +msgstr "Генерувати код, який буде виконуватися в привілейованому стані." #: config/rs6000/rs6000.opt:613 #, no-c-format msgid "Generate (do not generate) code that uses the XXSPLTIW instruction." -msgstr "" +msgstr "Генерувати (не генерувати) код, який використовує інструкцію XXSPLTIW." #: config/rs6000/rs6000.opt:617 #, no-c-format msgid "Generate (do not generate) code that uses the XXSPLTIDP instruction." -msgstr "" +msgstr "Генерувати (не генерувати) код, який використовує інструкцію XXSPLTIDP." #: config/rs6000/rs6000.opt:621 #, no-c-format msgid "Generate (do not generate) code that uses the LXVKQ instruction." -msgstr "" +msgstr "Генерувати (не генерувати) код, який використовує інструкцію LXVKQ." #: config/rs6000/rs6000.opt:627 #, no-c-format msgid "Used to limit unroll factor which indicates how much the autovectorizer may unroll a loop. The default value is 4." -msgstr "" +msgstr "Використовується для обмеження фактора розгортання, який вказує, наскільки автоматичний векторизатор може розгорнути цикл. Значення за замовчуванням - 4." #: config/rs6000/rs6000.opt:633 #, no-c-format msgid "When costing for loop vectorization, we probably need to penalize the loop body cost if the existing cost model may not adequately reflect delays from unavailable vector resources. We collect the cost for vectorized statements and non-vectorized statements separately, check the proportion of vec_cost to total cost of vec_cost and non vec_cost, and penalize only if the proportion exceeds the threshold specified by this parameter. The default value is 85." -msgstr "" +msgstr "При вартості векторизації циклу, ми, ймовірно, повинні покарати вартість тіла циклу, якщо існуюча модель вартості може недостатньо відбивати затримки від недоступних векторних ресурсів. Ми окремо збираємо вартість для векторизованих та невекторизованих операторів, перевіряємо співвідношення vec_cost до загальної вартості vec_cost та non vec_cost, і покараємо лише якщо співвідношення перевищує поріг, вказаний цим параметром. Значення за замовчуванням - 85." #: config/rs6000/rs6000.opt:642 #, no-c-format msgid "Like parameter rs6000-density-pct-threshold, we also check the total sum of vec_cost and non vec_cost, and penalize only if the sum exceeds the threshold specified by this parameter. The default value is 70." -msgstr "" +msgstr "Подібно до параметра rs6000-density-pct-threshold, ми також перевіряємо загальну суму vec_cost та non vec_cost і накладаємо штраф лише у випадку, якщо сума перевищує поріг, вказаний цим параметром. Значення за замовчуванням - 70." #: config/rs6000/rs6000.opt:648 #, no-c-format msgid "When both heuristics with rs6000-density-pct-threshold and rs6000-density-size-threshold are satisfied, we decide to penalize the loop body cost by the value which is specified by this parameter. The default value is 10." -msgstr "" +msgstr "Коли обидва евристики rs6000-density-pct-threshold та rs6000-density-size-threshold задовольняються, ми вирішуємо покарати вартість тіла циклу значенням, яке вказано цим параметром. Значення за замовчуванням - 10." #: config/rs6000/rs6000.opt:655 #, no-c-format msgid "When costing for loop vectorization, we probably need to penalize the loop body cost by accounting for excess strided or elementwise loads. We collect the numbers for general statements and load statements according to the information for statements to be vectorized, check the proportion of load statements, and penalize only if the proportion exceeds the threshold specified by this parameter. The default value is 45." -msgstr "" +msgstr "При оцінці вартості векторизації циклу, ми, ймовірно, повинні покарати вартість тіла циклу, враховуючи надмірні зарядження з кроком або поелементні зарядження. Ми збираємо числа загальних операторів та операторів зарядження згідно з інформацією для операторів, які мають бути векторизовані, перевіряємо відношення операторів зарядження та покараємо лише якщо відношення перевищує поріг, вказаний цим параметром. Значення за замовчуванням - 45." #: config/rs6000/rs6000.opt:664 #, no-c-format msgid "Like parameter rs6000-density-load-pct-threshold, we also check if the total number of load statements exceeds the threshold specified by this parameter, and penalize only if it's satisfied. The default value is 20." -msgstr "" +msgstr "Подібно до параметра rs6000-density-load-pct-threshold, ми також перевіряємо, чи перевищує загальна кількість заявок на завантаження поріг, вказаний цим параметром, і штрафуємо лише у разі його виконання. Значення за замовчуванням - 20." #: config/rs6000/rs6000.opt:670 #, no-c-format msgid "Indicate how many non memory access vector instructions can be issued per cycle, it's used in unroll factor determination for autovectorizer. The default value is 4." -msgstr "" +msgstr "Вказує, скільки векторних інструкцій, що не використовують доступ до памʼяті, можуть бути видані за цикл. Використовується при визначенні фактора розгортання для автовекторизатора. Значення за замовчуванням - 4." #: config/rs6000/rs6000.opt:676 #, no-c-format msgid "When reduction factor computed for a loop exceeds the threshold specified by this parameter, prefer to unroll this loop. The default value is 1." -msgstr "" +msgstr "Якщо фактор зменшення, обчислений для циклу, перевищує поріг, вказаний цим параметром, віддається перевага розгортанню цього циклу. Значення за замовчуванням - 1." #: config/rs6000/sysv4.opt:24 #, no-c-format msgid "-mcall-ABI\tSelect ABI calling convention." -msgstr "" +msgstr "-mcall-ABI\tВиберіть конвенцію виклику ABI." #: config/rs6000/sysv4.opt:28 #, no-c-format msgid "-msdata=[none,data,sysv,eabi]\tSelect method for sdata handling." -msgstr "" +msgstr "-msdata=[none,data,sysv,eabi]\tВиберіть метод обробки sdata." #: config/rs6000/sysv4.opt:32 #, no-c-format msgid "Allow readonly data in sdata." -msgstr "" +msgstr "Дозволити тільки читання даних в sdata." #: config/rs6000/sysv4.opt:36 #, no-c-format msgid "-mtls-size=[16,32]\tSpecify bit size of immediate TLS offsets." -msgstr "" +msgstr "-mtls-size=[16,32]\tВказати розмір бітів негайних зсувів TLS." #: config/rs6000/sysv4.opt:52 #, no-c-format msgid "Align to the base type of the bit-field." -msgstr "" +msgstr "Вирівняти за базовим типом бітового поля." #: config/rs6000/sysv4.opt:56 #, no-c-format msgid "Align to the base type of the bit-field. Don't assume that unaligned accesses are handled by the system." -msgstr "" +msgstr "Вирівняти за базовим типом бітового поля. Не припускати, що незаініціалізовані доступи обробляються системою." #: config/rs6000/sysv4.opt:61 config/rs6000/sysv4.opt:65 #, no-c-format msgid "Produce code relocatable at runtime." -msgstr "" +msgstr "Створювати код, який можна переміщувати під час виконання." #: config/rs6000/sysv4.opt:69 config/rs6000/sysv4.opt:73 #, no-c-format msgid "Produce little endian code." -msgstr "" +msgstr "Створювати код у форматі little endian." #: config/rs6000/sysv4.opt:77 config/rs6000/sysv4.opt:81 #, no-c-format msgid "Produce big endian code." -msgstr "" +msgstr "Створювати код у форматі big endian." #: config/rs6000/sysv4.opt:86 config/rs6000/sysv4.opt:90 #: config/rs6000/sysv4.opt:99 config/rs6000/sysv4.opt:141 #: config/rs6000/sysv4.opt:153 #, no-c-format msgid "No description yet." -msgstr "" +msgstr "Поки що немає опису." #: config/rs6000/sysv4.opt:94 #, no-c-format msgid "Assume all variable arg functions are prototyped." -msgstr "" +msgstr "Припускати, що всі функції зі змінною кількістю аргументів мають прототип." #: config/rs6000/sysv4.opt:103 #, no-c-format msgid "Use EABI." -msgstr "" +msgstr "Використовувати EABI." #: config/rs6000/sysv4.opt:107 #, no-c-format msgid "Allow bit-fields to cross word boundaries." -msgstr "" +msgstr "Дозволити полям бітів перетинати межі слова." #: config/rs6000/sysv4.opt:111 #, no-c-format msgid "Use alternate register names." -msgstr "" +msgstr "Використовувати альтернативні назви регістрів." #: config/rs6000/sysv4.opt:117 #, no-c-format msgid "Use default method for sdata handling." -msgstr "" +msgstr "Використовувати метод за замовчуванням для обробки sdata." #: config/rs6000/sysv4.opt:121 #, no-c-format msgid "Link with libsim.a, libc.a and sim-crt0.o." -msgstr "" +msgstr "Звʼязати з libsim.a, libc.a та sim-crt0.o." #: config/rs6000/sysv4.opt:125 #, no-c-format msgid "Link with libads.a, libc.a and crt0.o." -msgstr "" +msgstr "Звʼязати з libads.a, libc.a та crt0.o." #: config/rs6000/sysv4.opt:129 #, no-c-format msgid "Link with libyk.a, libc.a and crt0.o." -msgstr "" +msgstr "Звʼязати з libyk.a, libc.a та crt0.o." #: config/rs6000/sysv4.opt:133 #, no-c-format msgid "Link with libmvme.a, libc.a and crt0.o." -msgstr "" +msgstr "Звʼязати з libmvme.a, libc.a та crt0.o." #: config/rs6000/sysv4.opt:137 #, no-c-format msgid "Set the PPC_EMB bit in the ELF flags header." -msgstr "" +msgstr "Встановити біт PPC_EMB у заголовку прапорців ELF." #: config/rs6000/sysv4.opt:157 #, no-c-format msgid "Generate code to use a non-exec PLT and GOT." -msgstr "" +msgstr "Генерувати код для використання невиконуваної PLT (Procedure Linkage Table) та GOT (Global Offsets Table)." #: config/rs6000/sysv4.opt:161 #, no-c-format msgid "Generate code for old exec BSS PLT." -msgstr "" +msgstr "Генерувати код для старої виконуваної PLT в BSS." #: config/rs6000/sysv4.opt:165 #, no-c-format msgid "Use inline plt sequences to implement long calls and -fno-plt." -msgstr "" +msgstr "Використовувати вбудовані послідовності plt для реалізації довгих викликів та -fno-plt." #: config/rs6000/sysv4.opt:169 #, no-c-format msgid "Emit .gnu_attribute tags." -msgstr "" +msgstr "Видавати теги .gnu_attribute." #: config/alpha/alpha.opt:27 #, no-c-format msgid "Use fp registers." -msgstr "Використовувати fp-регістри." +msgstr "Використовувати регістри FP." #: config/alpha/alpha.opt:35 #, no-c-format msgid "Request IEEE-conformant math library routines (OSF/1)." -msgstr "" +msgstr "Запитати рутини бібліотеки математики, що відповідають стандарту IEEE (OSF/1)." #: config/alpha/alpha.opt:39 #, no-c-format msgid "Emit IEEE-conformant code, without inexact exceptions." -msgstr "" +msgstr "Видавати код, що відповідає стандарту IEEE, без неточних виключень." #: config/alpha/alpha.opt:46 #, no-c-format msgid "Do not emit complex integer constants to read-only memory." -msgstr "" +msgstr "Не випускайте складні цілі константи в памʼять тільки для читання." #: config/alpha/alpha.opt:50 #, no-c-format msgid "Use VAX fp." -msgstr "" +msgstr "Використовуйте VAX fp." #: config/alpha/alpha.opt:54 #, no-c-format msgid "Do not use VAX fp." -msgstr "" +msgstr "Не використовуйте VAX fp." #: config/alpha/alpha.opt:58 #, no-c-format msgid "Emit code for the byte/word ISA extension." -msgstr "" +msgstr "Випускати код для розширення ISA байт/слово." #: config/alpha/alpha.opt:62 #, no-c-format msgid "Emit code for the motion video ISA extension." -msgstr "" +msgstr "Випускати код для розширення ISA рухового відео." #: config/alpha/alpha.opt:66 #, no-c-format msgid "Emit code for the fp move and sqrt ISA extension." -msgstr "" +msgstr "Генерувати код для розширення ISA для переміщення fp та sqrt." #: config/alpha/alpha.opt:70 #, no-c-format msgid "Emit code for the counting ISA extension." -msgstr "" +msgstr "Генерувати код для розширення ISA для підрахунку." #: config/alpha/alpha.opt:74 #, no-c-format msgid "Emit code using explicit relocation directives." -msgstr "" +msgstr "Генерувати код, використовуючи явні директиви перенесення." #: config/alpha/alpha.opt:78 #, no-c-format msgid "Emit 16-bit relocations to the small data areas." -msgstr "" +msgstr "Генерувати 16-бітні перенесення до малих областей даних." #: config/alpha/alpha.opt:82 #, no-c-format msgid "Emit 32-bit relocations to the small data areas." -msgstr "" +msgstr "Генерувати 32-бітні перенесення до малих областей даних." #: config/alpha/alpha.opt:86 #, no-c-format msgid "Emit direct branches to local functions." -msgstr "" +msgstr "Генерувати прямі гілки до локальних функцій." #: config/alpha/alpha.opt:90 #, no-c-format msgid "Emit indirect branches to local functions." -msgstr "" +msgstr "Генерувати непрямі гілки до локальних функцій." #: config/alpha/alpha.opt:94 #, no-c-format msgid "Emit rdval instead of rduniq for thread pointer." -msgstr "" +msgstr "Видаляти rdval замість rduniq для вказівника на потік." #: config/alpha/alpha.opt:106 #, no-c-format msgid "Use features of and schedule given CPU." -msgstr "" +msgstr "Використовувати можливості та планувати вказаний процесор." #: config/alpha/alpha.opt:110 #, no-c-format msgid "Schedule given CPU." -msgstr "" +msgstr "Планувати вказаний процесор." #: config/alpha/alpha.opt:114 #, no-c-format msgid "Control the generated fp rounding mode." -msgstr "" +msgstr "Контролювати режим округлення fp, що генерується." #: config/alpha/alpha.opt:118 #, no-c-format msgid "Control the IEEE trap mode." -msgstr "" +msgstr "Контролювати режим пастки IEEE." #: config/alpha/alpha.opt:122 #, no-c-format msgid "Control the precision given to fp exceptions." -msgstr "" +msgstr "Контролювати точність, яка надається виняткам fp." #: config/alpha/alpha.opt:126 #, no-c-format msgid "Tune expected memory latency." -msgstr "" +msgstr "Налаштувати очікувану затримку памʼяті." #: config/lm32/lm32.opt:24 #, no-c-format msgid "Enable multiply instructions." -msgstr "" +msgstr "Увімкнути інструкції множення." #: config/lm32/lm32.opt:28 #, no-c-format msgid "Enable divide and modulus instructions." -msgstr "" +msgstr "Увімкнути інструкції ділення та залишку." #: config/lm32/lm32.opt:32 #, no-c-format msgid "Enable barrel shift instructions." -msgstr "" +msgstr "Увімкнути інструкції револьверного зсуву." #: config/lm32/lm32.opt:36 #, no-c-format msgid "Enable sign extend instructions." -msgstr "" +msgstr "Увімкнути інструкції розширення знаку." #: config/lm32/lm32.opt:40 #, no-c-format msgid "Enable user-defined instructions." -msgstr "" +msgstr "Увімкнути користувацькі інструкції." #: config/loongarch/loongarch.opt:47 #, no-c-format msgid "Basic ISAs of LoongArch:" -msgstr "" +msgstr "Основні ISA LoongArch:" #: config/loongarch/loongarch.opt:56 #, no-c-format msgid "FPU types of LoongArch:" -msgstr "" +msgstr "Типи FPU LoongArch:" #: config/loongarch/loongarch.opt:69 #, no-c-format msgid "-mfpu=FPU\tGenerate code for the given FPU." -msgstr "" +msgstr "-mfpu=FPU\tГенерувати код для вказаного FPU." #: config/loongarch/loongarch.opt:76 config/mips/mips.opt:377 #, no-c-format msgid "Prevent the use of all hardware floating-point instructions." -msgstr "" +msgstr "Заборонити використання всіх апаратних інструкцій з плаваючою комою." #: config/loongarch/loongarch.opt:80 config/mips/mips.opt:369 #, no-c-format msgid "Restrict the use of hardware floating-point instructions to 32-bit operations." -msgstr "" +msgstr "Обмежити використання апаратних інструкцій з плаваючою комою до 32-бітних операцій." #: config/loongarch/loongarch.opt:84 config/mips/mips.opt:116 #, no-c-format msgid "Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations." -msgstr "" +msgstr "Дозволити апаратним інструкціям з плаваючою комою охоплювати як 32-бітні, так і 64-бітні операції." #: config/loongarch/loongarch.opt:90 #, no-c-format msgid "LoongArch CPU types:" -msgstr "" +msgstr "Типи процесорів LoongArch:" #: config/loongarch/loongarch.opt:103 #, no-c-format msgid "-march=PROCESSOR\tGenerate code for the given PROCESSOR ISA." -msgstr "" +msgstr "-march=PROCESSOR\tГенерувати код для вказаного ISA процесора." #: config/loongarch/loongarch.opt:107 #, no-c-format msgid "-mtune=PROCESSOR\tGenerate optimized code for PROCESSOR." -msgstr "" +msgstr "-mtune=PROCESSOR\tГенерувати оптимізований код для процесора PROCESSOR." #: config/loongarch/loongarch.opt:116 #, no-c-format msgid "Base ABI types for LoongArch:" -msgstr "" +msgstr "Типи базових ABI для LoongArch:" #: config/loongarch/loongarch.opt:129 #, no-c-format msgid "-mabi=BASEABI\tGenerate code that conforms to the given BASEABI." -msgstr "" +msgstr "-mabi=BASEABI\tГенерувати код, який відповідає вказаному базовому ABI BASEABI." #: config/loongarch/loongarch.opt:138 config/mips/mips.opt:71 #, no-c-format msgid "-mbranch-cost=COST\tSet the cost of branches to roughly COST instructions." -msgstr "" +msgstr "-mbranch-cost=COST\tВстановити вартість гілок приблизно COST інструкцій." #: config/loongarch/loongarch.opt:142 config/mips/mips.opt:83 #, no-c-format msgid "Trap on integer divide by zero." -msgstr "" +msgstr "Перехоплювати ділення цілочисельних на нуль." #: config/loongarch/loongarch.opt:146 #, no-c-format msgid "Conditional moves for integral are enabled." -msgstr "" +msgstr "Увімкнено умовні переміщення для цілочисельних." #: config/loongarch/loongarch.opt:150 #, no-c-format msgid "Conditional moves for float are enabled." -msgstr "" +msgstr "Увімкнено умовні переміщення для дійсних чисел." #: config/loongarch/loongarch.opt:154 #, no-c-format msgid "Prevent optimizing block moves, which is also the default behavior of -Os." -msgstr "" +msgstr "Заборонити оптимізацію блочних переміщень, що також є стандартною поведінкою -Os." #: config/loongarch/loongarch.opt:162 #, no-c-format msgid "-mmax-inline-memcpy-size=SIZE\tSet the max size of memcpy to inline, default is 1024." -msgstr "" +msgstr "-mmax-inline-memcpy-size=SIZE\tВстановити максимальний розмір memcpy для вбудовування, за замовчуванням 1024." #: config/loongarch/loongarch.opt:166 #, no-c-format msgid "Use %reloc() assembly operators." -msgstr "" +msgstr "Використовувати оператори збірки %reloc()." #: config/loongarch/loongarch.opt:197 #, no-c-format msgid "Avoid using the GOT to access external symbols." -msgstr "" +msgstr "Уникати використання GOT для доступу до зовнішніх символів." #: config/or1k/elf.opt:28 #, no-c-format msgid "Configure the newlib board specific runtime. The default is or1ksim." -msgstr "" +msgstr "Налаштувати специфічний для плати newlib час виконання. За замовчуванням - or1ksim." #: config/or1k/elf.opt:32 #, no-c-format msgid "This option is ignored; it is provided for compatibility purposes only. This used to select linker and preprocessor options for use with newlib." -msgstr "" +msgstr "Ця опція ігнорується; вона надається лише для сумісності. Вона використовувалася для вибору опцій лінкера та препроцесора для використання з newlib." #: config/or1k/or1k.opt:29 #, no-c-format msgid "Enable generation of hardware divide (l.div, l.divu) instructions. This is the default; use -msoft-div to override." -msgstr "" +msgstr "Увімкнути генерацію апаратних інструкцій ділення (l.div, l.divu). Це значення за замовчуванням; використовуйте -msoft-div для заміни." #: config/or1k/or1k.opt:34 #, no-c-format msgid "Enable generation of binaries which use functions from libgcc to perform divide operations. The default is -mhard-div." -msgstr "" +msgstr "Увімкнути генерацію бінарних файлів, які використовують функції з libgcc для виконання операцій ділення. За замовчуванням -mhard-div." #: config/or1k/or1k.opt:39 #, no-c-format msgid "Enable generation of hardware multiply instructions (l.mul, l.muli) instructions. This is the default; use -msoft-mul to override." -msgstr "" +msgstr "Увімкнути генерацію апаратних інструкцій множення (l.mul, l.muli). Це значення за замовчуванням; використовуйте -msoft-mul для заміни." #: config/or1k/or1k.opt:44 #, no-c-format msgid "Enable generation of binaries which use functions from libgcc to perform multiply operations. The default is -mhard-mul." -msgstr "" +msgstr "Увімкнути генерацію бінарних файлів, які використовують функції з libgcc для виконання операцій множення. За замовчуванням -mhard-mul." #: config/or1k/or1k.opt:49 #, no-c-format msgid "Enable generation of binaries which use functions from libgcc to perform floating point operations. This is the default; use -mhard-float to override." -msgstr "" +msgstr "Увімкнути генерацію бінарних файлів, які використовують функції з libgcc для виконання операцій з плаваючою комою. Це значення за замовчуванням; використовуйте -mhard-float для заміни." #: config/or1k/or1k.opt:54 #, no-c-format msgid "Enable generation of hardware floating point instructions. The default is -msoft-float." -msgstr "" +msgstr "Увімкнути генерацію апаратних інструкцій з плаваючою комою. За замовчуванням використовується -msoft-float." #: config/or1k/or1k.opt:59 #, no-c-format msgid "When -mhard-float is selected, enables generation of double-precision floating point instructions. By default functions from libgcc are used to perform double-precision floating point operations." -msgstr "" +msgstr "При виборі -mhard-float, увімкнути генерацію апаратних інструкцій з плаваючою комою подвійної точності. За замовчуванням використовуються функції з бібліотеки libgcc для виконання операцій з плаваючою комою подвійної точності." #: config/or1k/or1k.opt:65 #, no-c-format msgid "When -mhard-float is selected, enables generation of unordered floating point compare and set flag (lf.sfun*) instructions. By default functions from libgcc are used to perform unordered floating point compare and set flag operations." -msgstr "" +msgstr "При виборі -mhard-float, увімкнути генерацію неупорядкованих інструкцій порівняння та встановлення прапорців з плаваючою комою (lf.sfun*). За замовчуванням використовуються функції з бібліотеки libgcc для виконання неупорядкованих операцій порівняння та встановлення прапорців з плаваючою комою." #: config/or1k/or1k.opt:71 #, no-c-format msgid "Specify the code model used for accessing memory addresses. Specifying large enables generating binaries with large global offset tables. By default the value is small." -msgstr "" +msgstr "Вказати модель коду, яка використовується для доступу до адрес памʼяті. Вказання значення large дозволяє генерувати бінарні файли з великими глобальними таблицями зміщень. За замовчуванням значення small." #: config/or1k/or1k.opt:77 #, no-c-format msgid "Known code model types (for use with the -mcmodel= option):" -msgstr "" +msgstr "Відомі типи моделей коду (для використання з опцією -mcmodel=):" #: config/or1k/or1k.opt:87 #, no-c-format msgid "Enable generation of conditional move (l.cmov) instructions. By default the equivalent will be generated using set and branch." -msgstr "" +msgstr "Увімкнути генерацію інструкцій умовного переміщення (l.cmov). За замовчуванням еквівалент буде згенерований за допомогою set і branch." #: config/or1k/or1k.opt:92 #, no-c-format msgid "Enable generation of rotate right (l.ror) instructions. By default functions from libgcc are used to perform rotate right operations." -msgstr "" +msgstr "Увімкнути генерацію інструкцій правого повороту (l.ror). За замовчуванням функції з libgcc використовуються для виконання операцій правого повороту." #: config/or1k/or1k.opt:97 #, no-c-format msgid "Enable generation of rotate right with immediate (l.rori) instructions. By default functions from libgcc are used to perform rotate right with immediate operations." -msgstr "" +msgstr "Увімкнути генерацію інструкцій повороту праворуч з негайним операндом (l.rori). За замовчуванням використовуються функції з libgcc для виконання операцій повороту праворуч з негайним." #: config/or1k/or1k.opt:103 #, no-c-format msgid "Enable generation of sign extension (l.ext*) instructions. By default memory loads are used to perform sign extension." -msgstr "" +msgstr "Увімкнути генерацію інструкцій розширення знака (l.ext*). За замовчуванням використовуються завантаження з памʼяті для виконання розширення знака." #: config/or1k/or1k.opt:108 #, no-c-format msgid "Enable generation of compare and set flag with immediate (l.sf*i) instructions. By default extra instructions will be generated to store the immediate to a register first." -msgstr "" +msgstr "Увімкнути генерацію інструкцій порівняння та встановлення прапорця з негайним значенням (l.sf*i). За замовчуванням будуть згенеровані додаткові інструкції для зберігання негайного значення в регістрі спочатку." #: config/or1k/or1k.opt:114 #, no-c-format msgid "Enable generation of shift with immediate (l.srai, l.srli, l.slli) instructions. By default extra instructions will be generated to store the immediate to a register first." -msgstr "" +msgstr "Увімкнути генерацію інструкцій зсуву з негайним значенням (l.srai, l.srli, l.slli). За замовчуванням будуть згенеровані додаткові інструкції для зберігання негайного значення в регістрі спочатку." #: config/nios2/elf.opt:26 #, no-c-format msgid "Link with a limited version of the C library." -msgstr "" +msgstr "Звʼязати з обмеженою версією бібліотеки C." #: config/nios2/elf.opt:30 #, no-c-format msgid "Name of system library to link against." -msgstr "" +msgstr "Назва системної бібліотеки для звʼязування." #: config/nios2/elf.opt:34 #, no-c-format msgid "Name of the startfile." -msgstr "" +msgstr "Назва стартового файлу." #: config/nios2/elf.opt:38 #, no-c-format msgid "Link with HAL BSP." -msgstr "" +msgstr "Посилання на HAL BSP." #: config/nios2/nios2.opt:35 #, no-c-format msgid "Enable DIV, DIVU." -msgstr "" +msgstr "Увімкнути DIV, DIVU." #: config/nios2/nios2.opt:39 #, no-c-format msgid "Enable MUL instructions." -msgstr "" +msgstr "Увімкнути інструкції MUL." #: config/nios2/nios2.opt:43 #, no-c-format msgid "Enable MULX instructions, assume fast shifter." -msgstr "" +msgstr "Увімкнути інструкції MULX, припускаючи швидкий зсув." #: config/nios2/nios2.opt:47 #, no-c-format msgid "Use table based fast divide (default at -O3)." -msgstr "" +msgstr "Використовувати швидке ділення на основі таблиці (за замовчуванням при -O3)." #: config/nios2/nios2.opt:51 #, no-c-format msgid "All memory accesses use I/O load/store instructions." -msgstr "" +msgstr "Всі доступи до памʼяті використовують I/O load/store інструкції." #: config/nios2/nios2.opt:55 #, no-c-format msgid "Volatile memory accesses use I/O load/store instructions." -msgstr "" +msgstr "Доступи до волатильної памʼяті використовують I/O load/store інструкції." #: config/nios2/nios2.opt:59 #, no-c-format msgid "Volatile memory accesses do not use I/O load/store instructions." -msgstr "" +msgstr "Доступи до волатильної памʼяті не використовують I/O load/store інструкції." #: config/nios2/nios2.opt:63 #, no-c-format msgid "Enable/disable GP-relative addressing." -msgstr "" +msgstr "Увімкнути/вимкнути адресування відносно GP." #: config/nios2/nios2.opt:67 #, no-c-format msgid "Valid options for GP-relative addressing (for -mgpopt):" -msgstr "" +msgstr "Допустимі параметри для адресування відносно GP (для -mgpopt):" #: config/nios2/nios2.opt:86 #, no-c-format msgid "Equivalent to -mgpopt=local." -msgstr "" +msgstr "Еквівалентно -mgpopt=local." #: config/nios2/nios2.opt:90 #, no-c-format msgid "Equivalent to -mgpopt=none." -msgstr "" +msgstr "Еквівалентно -mgpopt=none." #: config/nios2/nios2.opt:94 config/c6x/c6x.opt:30 config/mips/mips.opt:134 #, no-c-format msgid "Use big-endian byte order." -msgstr "" +msgstr "Використовувати порядок байтів big-endian." #: config/nios2/nios2.opt:98 config/c6x/c6x.opt:34 config/mips/mips.opt:138 #, no-c-format msgid "Use little-endian byte order." -msgstr "" +msgstr "Використовувати порядок байтів little-endian." #: config/nios2/nios2.opt:102 #, no-c-format msgid "Floating point custom instruction configuration name." -msgstr "" +msgstr "Назва конфігурації для власних інструкцій з плаваючою комою." #: config/nios2/nios2.opt:106 #, no-c-format msgid "Do not use the ftruncds custom instruction." -msgstr "" +msgstr "Не використовувати власну інструкцію ftruncds." #: config/nios2/nios2.opt:110 #, no-c-format msgid "Integer id (N) of ftruncds custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) власної інструкції ftruncds." #: config/nios2/nios2.opt:114 #, no-c-format msgid "Do not use the fextsd custom instruction." -msgstr "" +msgstr "Не використовувати власну інструкцію fextsd." #: config/nios2/nios2.opt:118 #, no-c-format msgid "Integer id (N) of fextsd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) власної інструкції fextsd." #: config/nios2/nios2.opt:122 #, no-c-format msgid "Do not use the fixdu custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fixdu»." #: config/nios2/nios2.opt:126 #, no-c-format msgid "Integer id (N) of fixdu custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «fixdu»." #: config/nios2/nios2.opt:130 #, no-c-format msgid "Do not use the fixdi custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fixdi»." #: config/nios2/nios2.opt:134 #, no-c-format msgid "Integer id (N) of fixdi custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «fixdi»." #: config/nios2/nios2.opt:138 #, no-c-format msgid "Do not use the fixsu custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fixsu»." #: config/nios2/nios2.opt:142 #, no-c-format msgid "Integer id (N) of fixsu custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «fixsu»." #: config/nios2/nios2.opt:146 #, no-c-format msgid "Do not use the fixsi custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fixsi»." #: config/nios2/nios2.opt:150 #, no-c-format msgid "Integer id (N) of fixsi custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «fixsi»." #: config/nios2/nios2.opt:154 #, no-c-format msgid "Do not use the floatud custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «floatud»." #: config/nios2/nios2.opt:158 #, no-c-format msgid "Integer id (N) of floatud custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «floatud»." #: config/nios2/nios2.opt:162 #, no-c-format msgid "Do not use the floatid custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «floatid»." #: config/nios2/nios2.opt:166 #, no-c-format msgid "Integer id (N) of floatid custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «floatid»." #: config/nios2/nios2.opt:170 #, no-c-format msgid "Do not use the floatus custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «floatus»." #: config/nios2/nios2.opt:174 #, no-c-format msgid "Integer id (N) of floatus custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «floatus»." #: config/nios2/nios2.opt:178 #, no-c-format msgid "Do not use the floatis custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «floatis»." #: config/nios2/nios2.opt:182 #, no-c-format msgid "Integer id (N) of floatis custom instruction." -msgstr "" +msgstr "Ціле число id (N) спеціальної інструкції «floatis»." #: config/nios2/nios2.opt:186 #, no-c-format msgid "Do not use the fcmpned custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpned»." #: config/nios2/nios2.opt:190 #, no-c-format msgid "Integer id (N) of fcmpned custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpned»." #: config/nios2/nios2.opt:194 #, no-c-format msgid "Do not use the fcmpeqd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpeqd»." #: config/nios2/nios2.opt:198 #, no-c-format msgid "Integer id (N) of fcmpeqd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpeqd»." #: config/nios2/nios2.opt:202 #, no-c-format msgid "Do not use the fcmpged custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpged»." #: config/nios2/nios2.opt:206 #, no-c-format msgid "Integer id (N) of fcmpged custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpged»." #: config/nios2/nios2.opt:210 #, no-c-format msgid "Do not use the fcmpgtd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpgtd»." #: config/nios2/nios2.opt:214 #, no-c-format msgid "Integer id (N) of fcmpgtd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpgtd»." #: config/nios2/nios2.opt:218 #, no-c-format msgid "Do not use the fcmpled custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpled»." #: config/nios2/nios2.opt:222 #, no-c-format msgid "Integer id (N) of fcmpled custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpled»." #: config/nios2/nios2.opt:226 #, no-c-format msgid "Do not use the fcmpltd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpltd»." #: config/nios2/nios2.opt:230 #, no-c-format msgid "Integer id (N) of fcmpltd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpltd»." #: config/nios2/nios2.opt:234 #, no-c-format msgid "Do not use the flogd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «flogd»." #: config/nios2/nios2.opt:238 #, no-c-format msgid "Integer id (N) of flogd custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції «flogd»." #: config/nios2/nios2.opt:242 #, no-c-format msgid "Do not use the fexpd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fexpd»." #: config/nios2/nios2.opt:246 #, no-c-format msgid "Integer id (N) of fexpd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fexpd»." #: config/nios2/nios2.opt:250 #, no-c-format msgid "Do not use the fatand custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fatand»." #: config/nios2/nios2.opt:254 #, no-c-format msgid "Integer id (N) of fatand custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fatand»." #: config/nios2/nios2.opt:258 #, no-c-format msgid "Do not use the ftand custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «ftand»." #: config/nios2/nios2.opt:262 #, no-c-format msgid "Integer id (N) of ftand custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «ftand»." #: config/nios2/nios2.opt:266 #, no-c-format msgid "Do not use the fsind custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fsind»." #: config/nios2/nios2.opt:270 #, no-c-format msgid "Integer id (N) of fsind custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fsind»." #: config/nios2/nios2.opt:274 #, no-c-format msgid "Do not use the fcosd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcosd»." #: config/nios2/nios2.opt:278 #, no-c-format msgid "Integer id (N) of fcosd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcosd»." #: config/nios2/nios2.opt:282 #, no-c-format msgid "Do not use the fsqrtd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fsqrtd»." #: config/nios2/nios2.opt:286 #, no-c-format msgid "Integer id (N) of fsqrtd custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції fsqrtd." #: config/nios2/nios2.opt:290 #, no-c-format msgid "Do not use the fabsd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fabsd." #: config/nios2/nios2.opt:294 #, no-c-format msgid "Integer id (N) of fabsd custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції fabsd." #: config/nios2/nios2.opt:298 #, no-c-format msgid "Do not use the fnegd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fnegd." #: config/nios2/nios2.opt:302 #, no-c-format msgid "Integer id (N) of fnegd custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції fnegd." #: config/nios2/nios2.opt:306 #, no-c-format msgid "Do not use the fmaxd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fmaxd." #: config/nios2/nios2.opt:310 #, no-c-format msgid "Integer id (N) of fmaxd custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції fmaxd." #: config/nios2/nios2.opt:314 #, no-c-format msgid "Do not use the fmind custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fmind." #: config/nios2/nios2.opt:318 #, no-c-format msgid "Integer id (N) of fmind custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції fmind." #: config/nios2/nios2.opt:322 #, no-c-format msgid "Do not use the fdivd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fdivd." #: config/nios2/nios2.opt:326 #, no-c-format msgid "Integer id (N) of fdivd custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції fdivd." #: config/nios2/nios2.opt:330 #, no-c-format msgid "Do not use the fmuld custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fmuld." #: config/nios2/nios2.opt:334 #, no-c-format msgid "Integer id (N) of fmuld custom instruction." -msgstr "" +msgstr "Цілочисельний ідентифікатор (N) спеціальної інструкції fmuld." #: config/nios2/nios2.opt:338 #, no-c-format msgid "Do not use the fsubd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fsubd»." #: config/nios2/nios2.opt:342 #, no-c-format msgid "Integer id (N) of fsubd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fsubd»." #: config/nios2/nios2.opt:346 #, no-c-format msgid "Do not use the faddd custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «faddd»." #: config/nios2/nios2.opt:350 #, no-c-format msgid "Integer id (N) of faddd custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «faddd»." #: config/nios2/nios2.opt:354 #, no-c-format msgid "Do not use the fcmpnes custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpnes»." #: config/nios2/nios2.opt:358 #, no-c-format msgid "Integer id (N) of fcmpnes custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpnes»." #: config/nios2/nios2.opt:362 #, no-c-format msgid "Do not use the fcmpeqs custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpeqs»." #: config/nios2/nios2.opt:366 #, no-c-format msgid "Integer id (N) of fcmpeqs custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpeqs»." #: config/nios2/nios2.opt:370 #, no-c-format msgid "Do not use the fcmpges custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpges»." #: config/nios2/nios2.opt:374 #, no-c-format msgid "Integer id (N) of fcmpges custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpges»." #: config/nios2/nios2.opt:378 #, no-c-format msgid "Do not use the fcmpgts custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmpgts»." #: config/nios2/nios2.opt:382 #, no-c-format msgid "Integer id (N) of fcmpgts custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fcmpgts»." #: config/nios2/nios2.opt:386 #, no-c-format msgid "Do not use the fcmples custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fcmples»." #: config/nios2/nios2.opt:390 #, no-c-format msgid "Integer id (N) of fcmples custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fcmples." #: config/nios2/nios2.opt:394 #, no-c-format msgid "Do not use the fcmplts custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fcmplts." #: config/nios2/nios2.opt:398 #, no-c-format msgid "Integer id (N) of fcmplts custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fcmplts." #: config/nios2/nios2.opt:402 #, no-c-format msgid "Do not use the flogs custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію flogs." #: config/nios2/nios2.opt:406 #, no-c-format msgid "Integer id (N) of flogs custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції flogs." #: config/nios2/nios2.opt:410 #, no-c-format msgid "Do not use the fexps custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fexps." #: config/nios2/nios2.opt:414 #, no-c-format msgid "Integer id (N) of fexps custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fexps." #: config/nios2/nios2.opt:418 #, no-c-format msgid "Do not use the fatans custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fatans." #: config/nios2/nios2.opt:422 #, no-c-format msgid "Integer id (N) of fatans custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fatans." #: config/nios2/nios2.opt:426 #, no-c-format msgid "Do not use the ftans custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію ftans." #: config/nios2/nios2.opt:430 #, no-c-format msgid "Integer id (N) of ftans custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції ftans." #: config/nios2/nios2.opt:434 #, no-c-format msgid "Do not use the fsins custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fsins." #: config/nios2/nios2.opt:438 #, no-c-format msgid "Integer id (N) of fsins custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fsins." #: config/nios2/nios2.opt:442 #, no-c-format msgid "Do not use the fcoss custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fcoss." #: config/nios2/nios2.opt:446 #, no-c-format msgid "Integer id (N) of fcoss custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fcoss." #: config/nios2/nios2.opt:450 #, no-c-format msgid "Do not use the fsqrts custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fsqrts." #: config/nios2/nios2.opt:454 #, no-c-format msgid "Integer id (N) of fsqrts custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fsqrts." #: config/nios2/nios2.opt:458 #, no-c-format msgid "Do not use the fabss custom instr." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fabss." #: config/nios2/nios2.opt:462 #, no-c-format msgid "Integer id (N) of fabss custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fabss." #: config/nios2/nios2.opt:466 #, no-c-format msgid "Do not use the fnegs custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fnegs." #: config/nios2/nios2.opt:470 #, no-c-format msgid "Integer id (N) of fnegs custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fnegs." #: config/nios2/nios2.opt:474 #, no-c-format msgid "Do not use the fmaxs custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fmaxs." #: config/nios2/nios2.opt:478 #, no-c-format msgid "Integer id (N) of fmaxs custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fmaxs." #: config/nios2/nios2.opt:482 #, no-c-format msgid "Do not use the fmins custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fmins." #: config/nios2/nios2.opt:486 #, no-c-format msgid "Integer id (N) of fmins custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fmins." #: config/nios2/nios2.opt:490 #, no-c-format msgid "Do not use the fdivs custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fdivs." #: config/nios2/nios2.opt:494 #, no-c-format msgid "Integer id (N) of fdivs custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fdivs»." #: config/nios2/nios2.opt:498 #, no-c-format msgid "Do not use the fmuls custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fmuls»." #: config/nios2/nios2.opt:502 #, no-c-format msgid "Integer id (N) of fmuls custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fmuls»." #: config/nios2/nios2.opt:506 #, no-c-format msgid "Do not use the fsubs custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fsubs»." #: config/nios2/nios2.opt:510 #, no-c-format msgid "Integer id (N) of fsubs custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fsubs»." #: config/nios2/nios2.opt:514 #, no-c-format msgid "Do not use the fadds custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію «fadds»." #: config/nios2/nios2.opt:518 #, no-c-format msgid "Integer id (N) of fadds custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції «fadds»." #: config/nios2/nios2.opt:522 #, no-c-format msgid "Do not use the frdy custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію frdy." #: config/nios2/nios2.opt:526 #, no-c-format msgid "Integer id (N) of frdy custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції frdy." #: config/nios2/nios2.opt:530 #, no-c-format msgid "Do not use the frdxhi custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію frdxhi." #: config/nios2/nios2.opt:534 #, no-c-format msgid "Integer id (N) of frdxhi custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції frdxhi." #: config/nios2/nios2.opt:538 #, no-c-format msgid "Do not use the frdxlo custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію frdxlo." #: config/nios2/nios2.opt:542 #, no-c-format msgid "Integer id (N) of frdxlo custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції frdxlo." #: config/nios2/nios2.opt:546 #, no-c-format msgid "Do not use the fwry custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fwry." #: config/nios2/nios2.opt:550 #, no-c-format msgid "Integer id (N) of fwry custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fwry." #: config/nios2/nios2.opt:554 #, no-c-format msgid "Do not use the fwrx custom instruction." -msgstr "" +msgstr "Не використовуйте спеціальну інструкцію fwrx." #: config/nios2/nios2.opt:558 #, no-c-format msgid "Integer id (N) of fwrx custom instruction." -msgstr "" +msgstr "Цілочисловий ідентифікатор (N) спеціальної інструкції fwrx." #: config/nios2/nios2.opt:562 #, no-c-format msgid "Do not use the round custom instruction." -msgstr "" +msgstr "Не використовуйте круглу спеціальну інструкцію." #: config/nios2/nios2.opt:566 #, no-c-format msgid "Integer id (N) of round custom instruction." -msgstr "" +msgstr "Ціле число id (N) круглої спеціальної інструкції." #: config/nios2/nios2.opt:574 #, no-c-format msgid "Valid Nios II ISA levels (for -march):" -msgstr "" +msgstr "Дійсні рівні Nios II ISA (для -march):" #: config/nios2/nios2.opt:584 #, no-c-format msgid "Enable generation of R2 BMX instructions." -msgstr "" +msgstr "Увімкнути генерацію інструкцій R2 BMX." #: config/nios2/nios2.opt:588 #, no-c-format msgid "Enable generation of R2 CDX instructions." -msgstr "" +msgstr "Увімкнути генерацію інструкцій R2 CDX." #: config/nios2/nios2.opt:592 #, no-c-format msgid "Regular expression matching additional GP-addressible section names." -msgstr "" +msgstr "Регулярний вираз, що відповідає додатковим іменам секцій, доступних за адресою GP." #: config/nios2/nios2.opt:596 #, no-c-format msgid "Regular expression matching section names for r0-relative addressing." -msgstr "" +msgstr "Регулярний вираз, що відповідає іменам секцій для відносної адресації r0." #: config/rx/elf.opt:32 #, no-c-format msgid "Generate assembler output that is compatible with the Renesas AS100 assembler. This may restrict some of the compiler's capabilities. The default is to generate GAS compatible syntax." -msgstr "" +msgstr "Генерувати вихідний код асемблера, який сумісний з асемблером Renesas AS100. Це може обмежити деякі можливості компілятора. За замовчуванням генерується синтаксис, сумісний з GAS." #: config/rx/elf.opt:38 config/rx/rx.opt:99 #, no-c-format msgid "Specifies the number of registers to reserve for interrupt handlers." -msgstr "" +msgstr "Вказує кількість регістрів, які слід зарезервувати для обробників переривань." #: config/rx/elf.opt:44 config/rx/rx.opt:105 #, no-c-format msgid "Specifies whether interrupt functions should save and restore the accumulator register." -msgstr "" +msgstr "Вказує, чи повинні функції переривань зберігати та відновлювати регістр акумулятора." #: config/rx/rx.opt:29 #, no-c-format msgid "Store doubles in 64 bits." -msgstr "" +msgstr "Зберігати подвійні числа у 64 бітах." #: config/rx/rx.opt:33 #, no-c-format msgid "Stores doubles in 32 bits. This is the default." -msgstr "" +msgstr "Зберігати подвійні числа у 32 бітах. Це значення за замовчуванням." #: config/rx/rx.opt:37 #, no-c-format msgid "Disable the use of RX FPU instructions." -msgstr "Вимкнути використання інструкцій FPU RX." +msgstr "Вимкнути використання інструкцій RX FPU." #: config/rx/rx.opt:44 #, no-c-format msgid "Enable the use of RX FPU instructions. This is the default." -msgstr "" +msgstr "Увімкнути використання інструкцій RX FPU. Це значення за замовчуванням." #: config/rx/rx.opt:50 #, no-c-format msgid "Specify the target RX cpu type." -msgstr "" +msgstr "Вказати тип цільового процесора RX." #: config/rx/rx.opt:71 #, no-c-format msgid "Data is stored in big-endian format." -msgstr "" +msgstr "Дані зберігаються у форматі big-endian." #: config/rx/rx.opt:75 #, no-c-format msgid "Data is stored in little-endian format. (Default)." -msgstr "" +msgstr "Дані зберігаються у форматі little-endian. (За замовчуванням)." #: config/rx/rx.opt:81 #, no-c-format msgid "Maximum size of global and static variables which can be placed into the small data area." -msgstr "" +msgstr "Максимальний розмір глобальних та статичних змінних, які можуть бути розміщені в області малих даних." #: config/rx/rx.opt:87 #, no-c-format msgid "Enable linker relaxation." -msgstr "" +msgstr "Увімкнути розслаблення лінкера." #: config/rx/rx.opt:93 #, no-c-format msgid "Maximum size in bytes of constant values allowed as operands." -msgstr "" +msgstr "Максимальний розмір у байтах дозволених константних значень як операндів." #: config/rx/rx.opt:111 #, no-c-format msgid "Enables Position-Independent-Data (PID) mode." -msgstr "" +msgstr "Увімкнути режим позиційно-незалежних даних (PID)." #: config/rx/rx.opt:117 #, no-c-format msgid "Warn when multiple, different, fast interrupt handlers are in the compilation unit." -msgstr "" +msgstr "Попереджати, коли в компіляційній одиниці є кілька різних швидких обробників переривань." #: config/rx/rx.opt:123 #, no-c-format msgid "Enable the use of the old, broken, ABI where all stacked function arguments are aligned to 32-bits." -msgstr "" +msgstr "Увімкнути використання старої, несправної ABI, де всі аргументи функцій, розміщені в стеку, вирівнюються до 32-біт." #: config/rx/rx.opt:127 #, no-c-format msgid "Enable the use the standard RX ABI where all stacked function arguments are naturally aligned. This is the default." -msgstr "" +msgstr "Увімкнути використання стандартної RX ABI, де всі аргументи функцій, розміщені в стеку, вирівнюються природним чином. Це значення за замовчуванням." #: config/rx/rx.opt:133 #, no-c-format msgid "Enable the use of the LRA register allocator." -msgstr "" +msgstr "Увімкнути використання реєстрового розподілювача LRA." #: config/rx/rx.opt:139 #, no-c-format msgid "Enables or disables the use of the SMOVF, SMOVB, SMOVU, SUNTIL, SWHILE and RMPA instructions. Enabled by default." -msgstr "" +msgstr "Увімкнути або вимкнути використання інструкцій SMOVF, SMOVB, SMOVU, SUNTIL, SWHILE та RMPA. За замовчуванням увімкнено." #: config/rx/rx.opt:145 #, no-c-format msgid "Always use JSR, never BSR, for calls." -msgstr "" +msgstr "Завжди використовувати JSR, а не BSR, для викликів." #: config/visium/visium.opt:25 #, no-c-format msgid "Link with libc.a and libdebug.a." -msgstr "" +msgstr "Посилання на libc.a та libdebug.a." #: config/visium/visium.opt:29 #, no-c-format msgid "Link with libc.a and libsim.a." -msgstr "" +msgstr "Посилання на libc.a та libsim.a." #: config/visium/visium.opt:33 #, no-c-format msgid "Use hardware FP (default)." -msgstr "" +msgstr "Використовувати апаратний FP (за замовчуванням)." #: config/visium/visium.opt:45 #, no-c-format msgid "Use features of and schedule code for given CPU." -msgstr "" +msgstr "Використовувати можливості та розкладати код для вказаного процесора." #: config/visium/visium.opt:65 #, no-c-format msgid "Generate code for the supervisor mode (default)." -msgstr "" +msgstr "Генерувати код для режиму супервізора (за замовчуванням)." #: config/visium/visium.opt:69 #, no-c-format msgid "Generate code for the user mode." -msgstr "" +msgstr "Генерувати код для режиму користувача." #: config/visium/visium.opt:73 #, no-c-format msgid "Only retained for backward compatibility." -msgstr "" +msgstr "Зберігається лише для забезпечення сумісності з попередніми версіями." #: config/sol2.opt:32 #, no-c-format msgid "Clear hardware capabilities when linking." -msgstr "" +msgstr "Очистити апаратні можливості під час звʼязування." #: config/sol2.opt:36 #, no-c-format msgid "Pass -z text to linker." -msgstr "" +msgstr "Передати -z text лінкеру." #: config/moxie/moxie.opt:31 #, no-c-format msgid "Enable MUL.X and UMUL.X instructions." -msgstr "" +msgstr "Увімкнути інструкції MUL.X та UMUL.X." #: config/microblaze/microblaze.opt:40 #, no-c-format msgid "Use software emulation for floating point (default)." -msgstr "" +msgstr "Використовувати програмну емуляцію для чисел з плаваючою комою (за замовчуванням)." #: config/microblaze/microblaze.opt:44 #, no-c-format msgid "Use hardware floating point instructions." -msgstr "" +msgstr "Використовувати апаратні інструкції з плаваючою комою." #: config/microblaze/microblaze.opt:48 #, no-c-format msgid "Use table lookup optimization for small signed integer divisions." -msgstr "" +msgstr "Використовувати оптимізацію пошуку в таблиці для ділення малих знакових цілочисельних." #: config/microblaze/microblaze.opt:52 #, no-c-format msgid "-mcpu=PROCESSOR\t\tUse features of and schedule code for given CPU." -msgstr "" +msgstr "-mcpu=ПРОЦЕСОР\t\tВикористовувати можливості та розкладати код для заданого процесора." #: config/microblaze/microblaze.opt:56 #, no-c-format msgid "Don't optimize block moves, use memcpy." -msgstr "" +msgstr "Не оптимізувати переміщення блоків, використовувати memcpy." #: config/microblaze/microblaze.opt:68 #, no-c-format msgid "Use the soft multiply emulation (default)." -msgstr "" +msgstr "Використовуйте емуляцію мʼякого множення (за замовчуванням)." #: config/microblaze/microblaze.opt:72 #, no-c-format msgid "Use reorder instructions (swap and byte reversed load/store) (default)." -msgstr "" +msgstr "Використовуйте інструкції перестановки (обмін та зворотне завантаження/збереження байтів) (за замовчуванням)." #: config/microblaze/microblaze.opt:76 #, no-c-format msgid "Use the software emulation for divides (default)." -msgstr "" +msgstr "Використовуйте програмну емуляцію для ділення (за замовчуванням)." #: config/microblaze/microblaze.opt:80 #, no-c-format msgid "Use the hardware barrel shifter instead of emulation." -msgstr "" +msgstr "Використовуйте револьверний зсувний регістр замість емуляції." #: config/microblaze/microblaze.opt:84 #, no-c-format msgid "Use pattern compare instructions." -msgstr "" +msgstr "Використовуйте інструкції порівняння шаблонів." #: config/microblaze/microblaze.opt:88 #, no-c-format msgid "Check for stack overflow at runtime." -msgstr "" +msgstr "Перевіряйте переповнення стеку під час виконання." #: config/microblaze/microblaze.opt:92 config/iq2000/iq2000.opt:65 #, no-c-format msgid "Use GP relative sdata/sbss sections." -msgstr "" +msgstr "Використовуйте секції sdata/sbss відносно GP." #: config/microblaze/microblaze.opt:96 #, no-c-format msgid "Clear the BSS to zero and place zero initialized in BSS." -msgstr "" +msgstr "Очистити BSS до нуля і розмістити нульові значення в BSS." #: config/microblaze/microblaze.opt:100 #, no-c-format msgid "Use multiply high instructions for high part of 32x32 multiply." -msgstr "" +msgstr "Використовуйте інструкції високого множення для високої частини множення 32х32." #: config/microblaze/microblaze.opt:104 #, no-c-format msgid "Use hardware floating point conversion instructions." -msgstr "" +msgstr "Використовуйте апаратні інструкції перетворення з плаваючою комою." #: config/microblaze/microblaze.opt:108 #, no-c-format msgid "Use hardware floating point square root instruction." -msgstr "" +msgstr "Використовуйте апаратну інструкцію кореня з плаваючою комою." #: config/microblaze/microblaze.opt:112 #, no-c-format msgid "Description for mxl-mode-executable." -msgstr "" +msgstr "Опис для режиму mxl-mode-executable." #: config/microblaze/microblaze.opt:116 #, no-c-format msgid "Description for mxl-mode-xmdstub." -msgstr "" +msgstr "Опис для режиму mxl-mode-xmdstub." #: config/microblaze/microblaze.opt:120 #, no-c-format msgid "Description for mxl-mode-bootstrap." -msgstr "" +msgstr "Опис для режиму mxl-mode-bootstrap." #: config/microblaze/microblaze.opt:124 #, no-c-format msgid "Description for mxl-mode-novectors." -msgstr "" +msgstr "Опис для режиму mxl-mode-novectors." #: config/microblaze/microblaze.opt:128 #, no-c-format msgid "Use hardware prefetch instruction." -msgstr "" +msgstr "Використовуйте апаратну інструкцію попереднього завантаження." #: config/microblaze/microblaze.opt:132 #, no-c-format msgid "Data referenced by offset from start of text instead of GOT (with -fPIC/-fPIE)." -msgstr "" +msgstr "Дані, на які посилається зсув від початку тексту, а не з GOT (з -fPIC/-fPIE)." #: config/vax/vax.opt:23 config/vax/vax.opt:27 #, no-c-format msgid "Target DFLOAT double precision code." -msgstr "" +msgstr "Генерувати код з подвійною точністю DFLOAT." #: config/vax/vax.opt:31 config/vax/vax.opt:35 #, no-c-format msgid "Generate GFLOAT double precision code." -msgstr "" +msgstr "Генерувати код з подвійною точністю GFLOAT." #: config/vax/vax.opt:39 #, no-c-format msgid "Generate code for GNU assembler (gas)." -msgstr "" +msgstr "Створити код для GNU асемблера (gas)." #: config/vax/vax.opt:43 #, no-c-format msgid "Generate code for UNIX assembler." -msgstr "" +msgstr "Створити код для UNIX асемблера." #: config/vax/vax.opt:51 #, no-c-format msgid "Use VAXC structure conventions." -msgstr "" +msgstr "Використовувати VAXC конвенції структури." #: config/vax/vax.opt:55 #, no-c-format msgid "Use new adddi3/subdi3 patterns." -msgstr "" +msgstr "Використовувати нові шаблони adddi3/subdi3." #: config/frv/frv.opt:30 #, no-c-format msgid "Use 4 media accumulators." -msgstr "" +msgstr "Використовувати 4 накопичувачі медіа." #: config/frv/frv.opt:34 #, no-c-format msgid "Use 8 media accumulators." -msgstr "" +msgstr "Використовувати 8 накопичувачів медіа." #: config/frv/frv.opt:38 #, no-c-format msgid "Enable label alignment optimizations." -msgstr "" +msgstr "Увімкнути оптимізацію вирівнювання міток." #: config/frv/frv.opt:42 #, no-c-format msgid "Dynamically allocate cc registers." -msgstr "" +msgstr "Динамічно виділяти регістри cc." #: config/frv/frv.opt:49 #, no-c-format msgid "Set the cost of branches." -msgstr "" +msgstr "Встановити вартість гілок." #: config/frv/frv.opt:53 #, no-c-format msgid "Enable conditional execution other than moves/scc." -msgstr "" +msgstr "Увімкнути умовне виконання, крім переміщень/копіювань." #: config/frv/frv.opt:57 #, no-c-format msgid "Change the maximum length of conditionally-executed sequences." -msgstr "" +msgstr "Змінити максимальну довжину умовно виконуваних послідовностей." #: config/frv/frv.opt:61 #, no-c-format msgid "Change the number of temporary registers that are available to conditionally-executed sequences." -msgstr "" +msgstr "Змінити кількість тимчасових регістрів, доступних для умовно виконуваних послідовностей." #: config/frv/frv.opt:65 #, no-c-format msgid "Enable conditional moves." -msgstr "" +msgstr "Увімкнути умовні переміщення." #: config/frv/frv.opt:69 #, no-c-format msgid "Set the target CPU type." -msgstr "" +msgstr "Встановити тип цільового процесора." #: config/frv/frv.opt:73 #, no-c-format msgid "Known FR-V CPUs (for use with the -mcpu= option):" -msgstr "" +msgstr "Відомі процесори FR-V (для використання з опцією -mcpu=):" #: config/frv/frv.opt:122 #, no-c-format msgid "Use fp double instructions." -msgstr "" +msgstr "Використовувати подвійні інструкції fp." #: config/frv/frv.opt:126 #, no-c-format msgid "Change the ABI to allow double word insns." -msgstr "" +msgstr "Змінити ABI, щоб дозволити подвійні слова insns." #: config/frv/frv.opt:134 #, no-c-format msgid "Just use icc0/fcc0." -msgstr "" +msgstr "Просто використовуйте icc0/fcc0." #: config/frv/frv.opt:138 #, no-c-format msgid "Only use 32 FPRs." -msgstr "" +msgstr "Використовувати лише 32 FPRs." #: config/frv/frv.opt:142 #, no-c-format msgid "Use 64 FPRs." -msgstr "" +msgstr "Використовувати 64 FPRs." #: config/frv/frv.opt:146 #, no-c-format msgid "Only use 32 GPRs." -msgstr "" +msgstr "Використовувати лише 32 GPRs." #: config/frv/frv.opt:150 #, no-c-format msgid "Use 64 GPRs." -msgstr "" +msgstr "Використовувати 64 GPRs." #: config/frv/frv.opt:154 #, no-c-format msgid "Enable use of GPREL for read-only data in FDPIC." -msgstr "" +msgstr "Увімкнути використання GPREL для даних тільки для читання в FDPIC." #: config/frv/frv.opt:166 #, no-c-format msgid "Enable PIC support for building libraries." -msgstr "" +msgstr "Увімкнути підтримку PIC для побудови бібліотек." #: config/frv/frv.opt:170 #, no-c-format msgid "Follow the EABI linkage requirements." -msgstr "" +msgstr "Дотримуйтесь вимог EABI звʼязку." #: config/frv/frv.opt:174 #, no-c-format msgid "Disallow direct calls to global functions." -msgstr "" +msgstr "Заборонити прямі виклики глобальних функцій." #: config/frv/frv.opt:178 #, no-c-format msgid "Use media instructions." -msgstr "" +msgstr "Використовуйте медіа-інструкції." #: config/frv/frv.opt:182 #, no-c-format msgid "Use multiply add/subtract instructions." -msgstr "" +msgstr "Використовуйте інструкції множення додавання / віднімання." #: config/frv/frv.opt:186 #, no-c-format msgid "Enable optimizing &&/|| in conditional execution." -msgstr "" +msgstr "Увімкнути оптимізацію &&/|| в умовному виконанні." #: config/frv/frv.opt:190 #, no-c-format msgid "Enable nested conditional execution optimizations." -msgstr "" +msgstr "Увімкнути оптимізацію вкладеного умовного виконання." #: config/frv/frv.opt:195 #, no-c-format msgid "Do not mark ABI switches in e_flags." -msgstr "" +msgstr "Не позначати перемикачі ABI в e_flags." #: config/frv/frv.opt:199 #, no-c-format msgid "Remove redundant membars." -msgstr "" +msgstr "Видалити зайві membar-и." #: config/frv/frv.opt:203 #, no-c-format msgid "Pack VLIW instructions." -msgstr "" +msgstr "Упаковувати VLIW-інструкції." #: config/frv/frv.opt:207 #, no-c-format msgid "Enable setting GPRs to the result of comparisons." -msgstr "" +msgstr "Увімкнути встановлення GPR до результату порівнянь." #: config/frv/frv.opt:211 #, no-c-format msgid "Change the amount of scheduler lookahead." -msgstr "" +msgstr "Змінити кількість попереднього перегляду планувальника." #: config/frv/frv.opt:219 #, no-c-format msgid "Assume a large TLS segment." -msgstr "" +msgstr "Припустити великий сегмент TLS." #: config/frv/frv.opt:223 #, no-c-format msgid "Do not assume a large TLS segment." -msgstr "" +msgstr "Не припускати великий сегмент TLS." #: config/frv/frv.opt:228 #, no-c-format msgid "Cause gas to print tomcat statistics." -msgstr "" +msgstr "Змусити gas вивести статистику tomcat." #: config/frv/frv.opt:233 #, no-c-format msgid "Link with the library-pic libraries." -msgstr "" +msgstr "Посилання на бібліотеки library-pic." #: config/frv/frv.opt:237 #, no-c-format msgid "Allow branches to be packed with other instructions." -msgstr "" +msgstr "Дозволити упаковку гілок з іншими інструкціями." #: config/mn10300/mn10300.opt:30 #, no-c-format msgid "Target the AM33 processor." -msgstr "" +msgstr "Цільовий процесор AM33." #: config/mn10300/mn10300.opt:34 #, no-c-format msgid "Target the AM33/2.0 processor." -msgstr "" +msgstr "Цільовий процесор AM33/2.0." #: config/mn10300/mn10300.opt:38 #, no-c-format msgid "Target the AM34 processor." -msgstr "" +msgstr "Цільовий процесор AM34." #: config/mn10300/mn10300.opt:46 #, no-c-format msgid "Work around hardware multiply bug." -msgstr "" +msgstr "Обійти помилку множення апаратного забезпечення." #: config/mn10300/mn10300.opt:55 #, no-c-format msgid "Enable linker relaxations." -msgstr "" +msgstr "Увімкнути розслаблення звʼязувальника." #: config/mn10300/mn10300.opt:59 #, no-c-format msgid "Return pointers in both a0 and d0." -msgstr "" +msgstr "Повертати вказівники як в a0, так і в d0." #: config/mn10300/mn10300.opt:63 #, no-c-format msgid "Allow gcc to generate LIW instructions." -msgstr "" +msgstr "Дозволити gcc генерувати інструкції LIW." #: config/mn10300/mn10300.opt:67 #, no-c-format msgid "Allow gcc to generate the SETLB and Lcc instructions." -msgstr "" +msgstr "Дозволити gcc генерувати інструкції SETLB та Lcc." #: config/nds32/nds32-elf.opt:3 config/nds32/nds32-linux.opt:3 #, no-c-format msgid "Specify the address generation strategy for code model." -msgstr "" +msgstr "Вказати стратегію генерації адреси для моделі коду." #: config/nds32/nds32-elf.opt:7 config/nds32/nds32-linux.opt:7 #, no-c-format msgid "Known cmodel types (for use with the -mcmodel= option):" -msgstr "" +msgstr "Відомі типи cmodel (для використання з опцією -mcmodel=):" #: config/nds32/nds32.opt:29 config/nds32/nds32.opt:89 #, no-c-format msgid "Generate code in big-endian mode." -msgstr "" +msgstr "Генерувати код у режимі big-endian." #: config/nds32/nds32.opt:33 config/nds32/nds32.opt:93 #, no-c-format msgid "Generate code in little-endian mode." -msgstr "" +msgstr "Генерувати код у режимі little-endian." #: config/nds32/nds32.opt:37 #, no-c-format msgid "Force performing fp-as-gp optimization." -msgstr "" +msgstr "Примусово виконувати оптимізацію fp-as-gp." #: config/nds32/nds32.opt:41 #, no-c-format msgid "Forbid performing fp-as-gp optimization." -msgstr "" +msgstr "Заборонити виконання оптимізації fp-as-gp." #: config/nds32/nds32.opt:47 #, no-c-format msgid "Specify which ABI type to generate code for: 2, 2fp+." -msgstr "" +msgstr "Вказати, для якого типу ABI генерувати код: 2, 2fp+." #: config/nds32/nds32.opt:61 #, no-c-format msgid "Specify use soft floating point ABI which mean alias to -mabi=2." -msgstr "" +msgstr "Вказати використання мʼякого ABI з плаваючою комою, що означає псевдонім -mabi=2." #: config/nds32/nds32.opt:65 #, no-c-format msgid "Specify use soft floating point ABI which mean alias to -mabi=2fp+." -msgstr "" +msgstr "Вказати використання мʼякого ABI з плаваючою комою, що означає псевдонім -mabi=2fp+." #: config/nds32/nds32.opt:71 #, no-c-format msgid "Use reduced-set registers for register allocation." -msgstr "" +msgstr "Використовувати обмежений набір регістрів для розподілу регістрів." #: config/nds32/nds32.opt:75 #, no-c-format msgid "Use full-set registers for register allocation." -msgstr "" +msgstr "Використовувати повний набір регістрів для розподілу регістрів." #: config/nds32/nds32.opt:81 #, no-c-format msgid "Always align function entry, jump target and return address." -msgstr "" +msgstr "Завжди вирівнювати вхід у функцію, ціль переходу та адресу повернення." #: config/nds32/nds32.opt:85 #, no-c-format msgid "Align function entry to 4 byte." -msgstr "" +msgstr "Вирівняти вхід у функцію до 4 байт." #: config/nds32/nds32.opt:97 #, no-c-format msgid "Prevent $fp being allocated during register allocation so that compiler is able to force performing fp-as-gp optimization." -msgstr "" +msgstr "Заборонити розподіл $fp під час розподілу регістрів, щоб компілятор міг примусити виконання оптимізації fp-as-gp." #: config/nds32/nds32.opt:101 #, no-c-format msgid "Forbid using $fp to access static and global variables. This option strictly forbids fp-as-gp optimization regardless of '-mforce-fp-as-gp'." -msgstr "" +msgstr "Заборонити використання $fp для доступу до статичних та глобальних змінних. Ця опція строго забороняє оптимізацію fp-as-gp незалежно від '-mforce-fp-as-gp'." #: config/nds32/nds32.opt:105 #, no-c-format msgid "Specify the address generation strategy for ICT call's code model." -msgstr "" +msgstr "Вказати стратегію генерації адреси для моделі коду виклику ICT." #: config/nds32/nds32.opt:109 #, no-c-format msgid "Known cmodel types (for use with the -mict-model= option):" -msgstr "" +msgstr "Відомі типи моделей cmodel (для використання з опцією -mict-model=):" #: config/nds32/nds32.opt:119 #, no-c-format msgid "Generate conditional move instructions." -msgstr "" +msgstr "Генерувати інструкції умовного переміщення." #: config/nds32/nds32.opt:123 #, no-c-format msgid "Generate hardware abs instructions." -msgstr "Створити апаратні інструкції abs." +msgstr "Генерувати апаратні інструкції abs." #: config/nds32/nds32.opt:127 #, no-c-format msgid "Generate performance extension instructions." -msgstr "" +msgstr "Генерувати інструкції розширення продуктивності." #: config/nds32/nds32.opt:131 #, no-c-format msgid "Generate performance extension version 2 instructions." -msgstr "" +msgstr "Генерувати інструкції розширення продуктивності версії 2." #: config/nds32/nds32.opt:135 #, no-c-format msgid "Generate string extension instructions." -msgstr "Створити інструкції розширення рядків." +msgstr "Генерувати інструкції розширення рядків." #: config/nds32/nds32.opt:139 #, no-c-format msgid "Generate DSP extension instructions." -msgstr "Створити інструкції розширення DSP." +msgstr "Генерувати інструкції розширення DSP." #: config/nds32/nds32.opt:143 #, no-c-format msgid "Generate v3 push25/pop25 instructions." -msgstr "" +msgstr "Генерувати інструкції push25/pop25 v3." #: config/nds32/nds32.opt:147 #, no-c-format msgid "Generate 16-bit instructions." -msgstr "" +msgstr "Генерувати 16-бітні інструкції." #: config/nds32/nds32.opt:151 #, no-c-format msgid "Insert relax hint for linker to do relaxation." -msgstr "" +msgstr "Вставити підказку для розслаблення лінкера." #: config/nds32/nds32.opt:155 #, no-c-format msgid "Enable Virtual Hosting support." -msgstr "" +msgstr "Увімкнути підтримку віртуального хостингу." #: config/nds32/nds32.opt:159 #, no-c-format msgid "Specify the size of each interrupt vector, which must be 4 or 16." -msgstr "" +msgstr "Вказати розмір кожного вектора переривання, який повинен бути 4 або 16." #: config/nds32/nds32.opt:163 #, no-c-format msgid "Specify the security level of c-isr for the whole file." -msgstr "" +msgstr "Вказати рівень безпеки c-isr для всього файлу." #: config/nds32/nds32.opt:167 #, no-c-format msgid "Specify the size of each cache block, which must be a power of 2 between 4 and 512." -msgstr "" +msgstr "Вказати розмір кожного блоку кешу, який повинен бути степенем числа 2 від 4 до 512." #: config/nds32/nds32.opt:175 #, no-c-format msgid "Known arch types (for use with the -march= option):" -msgstr "" +msgstr "Відомі типи архітектури (для використання з опцією -march=):" #: config/nds32/nds32.opt:197 #, no-c-format msgid "Specify the cpu for pipeline model." -msgstr "" +msgstr "Вказати процесор для моделі конвеєра." #: config/nds32/nds32.opt:201 #, no-c-format msgid "Known cpu types (for use with the -mcpu= option):" -msgstr "" +msgstr "Відомі типи процесорів (для використання з опцією -mcpu=):" #: config/nds32/nds32.opt:361 #, no-c-format msgid "Specify a fpu configuration value from 0 to 7; 0-3 is as FPU spec says, and 4-7 is corresponding to 0-3." -msgstr "" +msgstr "Вказати значення конфігурації fpu від 0 до 7; 0-3 відповідає специфікації FPU, а 4-7 відповідає 0-3." #: config/nds32/nds32.opt:365 #, no-c-format msgid "Known floating-point number of registers (for use with the -mconfig-fpu= option):" -msgstr "" +msgstr "Відома кількість регістрів з плаваючою комою (для використання з опцією -mconfig-fpu=):" #: config/nds32/nds32.opt:393 #, no-c-format msgid "Specify configuration of instruction mul: fast1, fast2 or slow. The default is fast1." -msgstr "" +msgstr "Вказати конфігурацію інструкції mul: fast1, fast2 або slow. За замовчуванням використовується fast1." #: config/nds32/nds32.opt:412 #, no-c-format msgid "Specify how many read/write ports for n9/n10 cores. The value should be 3r2w or 2r1w." -msgstr "" +msgstr "Вказати кількість портів для читання/запису для ядер n9/n10. Значення повинно бути 3r2w або 2r1w." #: config/nds32/nds32.opt:425 #, no-c-format msgid "Enable constructor/destructor feature." -msgstr "" +msgstr "Увімкнути функцію конструктора/деструктора." #: config/nds32/nds32.opt:429 #, no-c-format msgid "Guide linker to relax instructions." -msgstr "" +msgstr "Направити лінкер на розслаблення інструкцій." #: config/nds32/nds32.opt:433 #, no-c-format msgid "Generate floating-point multiply-accumulation instructions." -msgstr "Створити інструкції накопичення множення для чисел із рухомою крапкою." +msgstr "Генерувати інструкції з плаваючою комою для множення-накопичення." #: config/nds32/nds32.opt:437 #, no-c-format msgid "Generate single-precision floating-point instructions." -msgstr "Створити інструкції одинарної точності для чисел із рухомою крапкою." +msgstr "Генерувати інструкції з плаваючою комою одинарної точності." #: config/nds32/nds32.opt:441 #, no-c-format msgid "Generate double-precision floating-point instructions." -msgstr "Створити інструкції подвійної точності для чисел із рухомою крапкою." +msgstr "Генерувати інструкції з плаваючою комою подвійної точності." #: config/nds32/nds32.opt:445 #, no-c-format msgid "Force disable hardware loop, even use -mext-dsp." -msgstr "" +msgstr "Примусово вимкнути апаратну петлю, навіть якщо використовується -mext-dsp." #: config/nds32/nds32.opt:449 #, no-c-format msgid "Permit scheduling of a function's prologue and epilogue sequence." -msgstr "" +msgstr "Дозволити планування послідовності прологу та епілогу функції." #: config/nds32/nds32.opt:453 #, no-c-format msgid "Generate return instruction in naked function." -msgstr "" +msgstr "Генерувати інструкцію повернення в голій функції." #: config/nds32/nds32.opt:457 #, no-c-format msgid "Always save $lp in the stack." -msgstr "" +msgstr "Завжди зберігати $lp у стеку." #: config/nds32/nds32.opt:465 #, no-c-format msgid "Allow use r15 for inline ASM." -msgstr "" +msgstr "Дозволити використання r15 для вбудованого ASM." #: config/iq2000/iq2000.opt:31 #, no-c-format msgid "Specify CPU for code generation purposes." -msgstr "" +msgstr "Вказати процесор для цілей генерації коду." #: config/iq2000/iq2000.opt:47 #, no-c-format msgid "Specify CPU for scheduling purposes." -msgstr "" +msgstr "Вказати процесор для цілей планування." #: config/iq2000/iq2000.opt:51 #, no-c-format msgid "Known IQ2000 CPUs (for use with the -mcpu= option):" -msgstr "" +msgstr "Відомі процесори IQ2000 (для використання з опцією -mcpu=):" #: config/iq2000/iq2000.opt:61 config/mips/mips.opt:142 #, no-c-format msgid "Use ROM instead of RAM." -msgstr "" +msgstr "Використовувати ROM замість RAM." #: config/iq2000/iq2000.opt:70 #, no-c-format msgid "No default crt0.o." -msgstr "" +msgstr "Немає типового crt0.o." #: config/iq2000/iq2000.opt:74 config/mips/mips.opt:413 #, no-c-format msgid "Put uninitialized constants in ROM (needs -membedded-data)." -msgstr "" +msgstr "Помістити неініціалізовані константи в ROM (потрібно -membedded-data)." #: config/csky/csky.opt:34 #, no-c-format msgid "Specify the target architecture." -msgstr "" +msgstr "Вказати цільову архітектуру." #: config/csky/csky.opt:38 #, no-c-format msgid "Specify the target processor." -msgstr "" +msgstr "Вказати цільовий процесор." #: config/csky/csky.opt:90 #, no-c-format msgid "Specify the target floating-point hardware/format." -msgstr "" +msgstr "Вказати цільовий апаратний засіб/формат з плаваючою комою." #: config/csky/csky.opt:94 #, no-c-format msgid "Generate C-SKY FPU double float instructions (default for hard float)." -msgstr "" +msgstr "Генерувати інструкції подвійного плаваючого розряду C-SKY FPU (за замовчуванням для жорсткої плаваючої коми)." #: config/csky/csky.opt:98 #, no-c-format msgid "Generate frecipd/fsqrtd/fdivd instructions (default for hard float)." -msgstr "" +msgstr "Генерувати інструкції frecipd/fsqrtd/fdivd (за замовчуванням для жорсткої плаваючої коми)." #: config/csky/csky.opt:106 #, no-c-format msgid "Enable the extended LRW instruction (default for CK801)." -msgstr "" +msgstr "Увімкнути розширену інструкцію LRW (за замовчуванням для CK801)." #: config/csky/csky.opt:110 #, no-c-format msgid "Enable interrupt stack instructions." -msgstr "" +msgstr "Увімкнути інструкції стеку переривань." #: config/csky/csky.opt:114 #, no-c-format msgid "Enable multiprocessor instructions." -msgstr "Увімкнути багатопроцесорні інструкції." +msgstr "Увімкнути інструкції багатопроцесорності." #: config/csky/csky.opt:118 #, no-c-format msgid "Enable coprocessor instructions." -msgstr "Увімкнути інструкції для співпроцесорів." +msgstr "Увімкнути інструкції копроцесора." #: config/csky/csky.opt:122 #, no-c-format msgid "Enable cache prefetch instructions." -msgstr "Увімкнути інструкції попереднього отримання кешу." +msgstr "Увімкнути інструкції попереднього завантаження кешу." #: config/csky/csky.opt:126 #, no-c-format msgid "Enable C-SKY SECURE instructions." -msgstr "" +msgstr "Увімкнути інструкції C-SKY SECURE." #: config/csky/csky.opt:133 #, no-c-format msgid "Enable C-SKY TRUST instructions." -msgstr "" +msgstr "Увімкнути інструкції C-SKY TRUST." #: config/csky/csky.opt:137 #, no-c-format msgid "Enable C-SKY DSP instructions." -msgstr "" +msgstr "Увімкнути інструкції DSP C-SKY." #: config/csky/csky.opt:141 #, no-c-format msgid "Enable C-SKY Enhanced DSP instructions." -msgstr "" +msgstr "Увімкнути покращені інструкції DSP C-SKY." #: config/csky/csky.opt:145 #, no-c-format msgid "Enable C-SKY Vector DSP instructions." -msgstr "" +msgstr "Увімкнути інструкції C-SKY Vector DSP." #: config/csky/csky.opt:151 #, no-c-format msgid "Generate divide instructions." -msgstr "Створити інструкції divide." +msgstr "Генерувати інструкції ділення." #: config/csky/csky.opt:155 #, no-c-format msgid "Generate code for Smart Mode." -msgstr "" +msgstr "Генерувати код для режиму Smart." #: config/csky/csky.opt:159 #, no-c-format msgid "Enable use of R16-R31 (default)." -msgstr "" +msgstr "Увімкнути використання R16-R31 (за замовчуванням)." #: config/csky/csky.opt:163 #, no-c-format msgid "Generate code using global anchor symbol addresses." -msgstr "" +msgstr "Генерувати код, використовуючи глобальні адреси символів-якорів." #: config/csky/csky.opt:167 #, no-c-format msgid "Generate push/pop instructions (default)." -msgstr "" +msgstr "Генерувати інструкції push/pop (за замовчуванням)." #: config/csky/csky.opt:171 #, no-c-format msgid "Generate stm/ldm instructions (default)." -msgstr "" +msgstr "Генерувати інструкції stm/ldm (за замовчуванням)." #: config/csky/csky.opt:178 #, no-c-format msgid "Generate constant pools in the compiler instead of assembler." -msgstr "" +msgstr "Генерувати константні пули в компіляторі замість асемблера." #: config/csky/csky.opt:182 #, no-c-format msgid "Emit .stack_size directives." -msgstr "" +msgstr "Генерувати директиви .stack_size." #: config/csky/csky.opt:186 #, no-c-format msgid "Generate code for C-SKY compiler runtime instead of libgcc." -msgstr "" +msgstr "Генерувати код для виконання компілятора C-SKY замість libgcc." #: config/csky/csky.opt:190 #, no-c-format msgid "Set the branch costs to roughly the specified number of instructions." -msgstr "" +msgstr "Встановити вартість гілок приблизно на вказану кількість інструкцій." #: config/csky/csky.opt:194 #, no-c-format msgid "Permit scheduling of function prologue and epilogue sequences." -msgstr "" +msgstr "Дозволити планування послідовностей прологу та епілогу функцій." #: config/csky/csky_tables.opt:24 #, no-c-format msgid "Known CSKY CPUs (for use with the -mcpu= options):" -msgstr "" +msgstr "Відомі процесори CSKY (для використання з опцією -mcpu=):" #: config/csky/csky_tables.opt:205 #, no-c-format msgid "Known CSKY architectures (for use with the -march= option):" -msgstr "" +msgstr "Відомі архітектури CSKY (для використання з опцією -march=):" #: config/csky/csky_tables.opt:227 #, no-c-format msgid "Known CSKY FPUs (for use with the -mfpu= option):" -msgstr "" +msgstr "Відомі FPUs CSKY (для використання з опцією -mfpu=):" #: config/c6x/c6x-tables.opt:24 #, no-c-format msgid "Known C6X ISAs (for use with the -march= option):" -msgstr "" +msgstr "Відомі ISA C6X (для використання з опцією -march=):" #: config/c6x/c6x.opt:42 #, no-c-format msgid "Select method for sdata handling." -msgstr "" +msgstr "Виберати метод обробки sdata." #: config/c6x/c6x.opt:46 #, no-c-format msgid "Valid arguments for the -msdata= option:" -msgstr "Коректні аргументи для параметра -msdata=:" +msgstr "Дійсні аргументи для опції -msdata=:" #: config/c6x/c6x.opt:59 #, no-c-format msgid "Compile for the DSBT shared library ABI." -msgstr "" +msgstr "Компілювати для DSBT shared library ABI." #: config/cris/cris.opt:45 #, no-c-format msgid "Work around bug in multiplication instruction." -msgstr "" +msgstr "Обійти помилку в інструкції множення." #: config/cris/cris.opt:51 #, no-c-format msgid "Compile for ETRAX 4 (CRIS v3)." -msgstr "" +msgstr "Компілювати для ETRAX 4 (CRIS v3)." #: config/cris/cris.opt:56 #, no-c-format msgid "Compile for ETRAX 100 (CRIS v8)." -msgstr "" +msgstr "Компілювати для ETRAX 100 (CRIS v8)." #: config/cris/cris.opt:64 #, no-c-format msgid "Emit verbose debug information in assembly code." -msgstr "" +msgstr "Виводити детальну інформацію для налагодження у вигляді коду асемблера." #: config/cris/cris.opt:71 #, no-c-format msgid "Do not use condition codes from normal instructions." -msgstr "" +msgstr "Не використовувати умовні коди звичайних інструкцій." #: config/cris/cris.opt:80 #, no-c-format msgid "Do not emit addressing modes with side-effect assignment." -msgstr "" +msgstr "Не генерувати режими адресації з присвоєнням побічного ефекту." #: config/cris/cris.opt:89 #, no-c-format msgid "Do not tune stack alignment." -msgstr "" +msgstr "Не налаштовувати вирівнювання стеку." #: config/cris/cris.opt:98 #, no-c-format msgid "Do not tune writable data alignment." -msgstr "" +msgstr "Не налаштовувати вирівнювання записуваних даних." #: config/cris/cris.opt:107 #, no-c-format msgid "Do not tune code and read-only data alignment." -msgstr "" +msgstr "Не налаштовувати вирівнювання коду та даних, доступних тільки для читання." #: config/cris/cris.opt:116 #, no-c-format msgid "Align code and data to 32 bits." -msgstr "" +msgstr "Вирівнювати код та дані до 32 біт." #: config/cris/cris.opt:133 #, no-c-format msgid "Don't align items in code or data." -msgstr "" +msgstr "Не вирівнювати елементи в коді або даних." #: config/cris/cris.opt:142 #, no-c-format msgid "Do not emit function prologue or epilogue." -msgstr "" +msgstr "Не генерувати пролог або епілог функції." #: config/cris/cris.opt:149 #, no-c-format msgid "Use the most feature-enabling options allowed by other options." -msgstr "" +msgstr "Використовувати найбільш функціональні опції, дозволені іншими опціями." #: config/cris/cris.opt:158 #, no-c-format msgid "Override -mbest-lib-options." -msgstr "" +msgstr "Перевизначити -mbest-lib-options." #: config/cris/cris.opt:165 #, no-c-format msgid "-march=ARCH\tGenerate code for the specified chip or CPU version." -msgstr "" +msgstr "-march=ARCH\tГенерувати код для вказаного чипу або версії процесора." #: config/cris/cris.opt:169 #, no-c-format msgid "-mtune=ARCH\tTune alignment for the specified chip or CPU version." -msgstr "" +msgstr "-mtune=ARCH\tНалаштувати вирівнювання для вказаного чипу або версії процесора." #: config/cris/cris.opt:173 #, no-c-format msgid "-mmax-stackframe=SIZE\tWarn when a stackframe is larger than the specified size." -msgstr "" +msgstr "-mmax-stackframe=SIZE\tПопереджати, коли розмір стекового кадру більший за вказаний розмір." #: config/cris/cris.opt:180 #, no-c-format msgid "Emit traps as \"break 8\", default for CRIS v3 and up. If disabled, calls to abort() are used." -msgstr "" +msgstr "Видавати пастки як «break 8», за замовчуванням для CRIS v3 і вище. Якщо вимкнено, використовуються виклики abort()." #: config/cris/cris.opt:184 #, no-c-format msgid "Emit checks causing \"break 8\" instructions to execute when applying atomic builtins on misaligned memory." -msgstr "" +msgstr "Видавати перевірки, що призводять до виконання інструкцій «break 8» при застосуванні атомних вбудованих функцій на неправильно вирівняній памʼяті." #: config/cris/cris.opt:188 #, no-c-format msgid "Handle atomic builtins that may be applied to unaligned data by calling library functions. Overrides -mtrap-unaligned-atomic." -msgstr "" +msgstr "Обробка атомних вбудованих функцій, які можуть застосовуватися до незаініціалізованих даних, шляхом виклику функцій бібліотеки. Перевизначає -mtrap-unaligned-atomic." #: config/sh/superh.opt:6 #, no-c-format msgid "Board name [and memory region]." -msgstr "" +msgstr "Назва плати [та область памʼяті]." #: config/sh/superh.opt:10 #, no-c-format msgid "Runtime name." -msgstr "" +msgstr "Назва рантайму." #: config/sh/sh.opt:42 #, no-c-format msgid "Generate SH1 code." -msgstr "" +msgstr "Генерувати код SH1." #: config/sh/sh.opt:46 #, no-c-format msgid "Generate SH2 code." -msgstr "" +msgstr "Генерувати код SH2." #: config/sh/sh.opt:50 #, no-c-format msgid "Generate default double-precision SH2a-FPU code." -msgstr "" +msgstr "Генерувати код SH2a-FPU з подвійною точністю за замовчуванням." #: config/sh/sh.opt:54 #, no-c-format msgid "Generate SH2a FPU-less code." -msgstr "" +msgstr "Генерувати код SH2a без FPU." #: config/sh/sh.opt:58 #, no-c-format msgid "Generate default single-precision SH2a-FPU code." -msgstr "" +msgstr "Генерувати код SH2a-FPU з одинарною точністю за замовчуванням." #: config/sh/sh.opt:62 #, no-c-format msgid "Generate only single-precision SH2a-FPU code." -msgstr "" +msgstr "Генерувати лише код SH2a-FPU з одинарною точністю." #: config/sh/sh.opt:66 #, no-c-format msgid "Generate SH2e code." -msgstr "" +msgstr "Генерувати код SH2e." #: config/sh/sh.opt:70 #, no-c-format msgid "Generate SH3 code." -msgstr "" +msgstr "Генерувати код SH3." #: config/sh/sh.opt:74 #, no-c-format msgid "Generate SH3e code." -msgstr "" +msgstr "Генерувати код SH3e." #: config/sh/sh.opt:78 #, no-c-format msgid "Generate SH4 code." -msgstr "" +msgstr "Генерувати код SH4." #: config/sh/sh.opt:82 #, no-c-format msgid "Generate SH4-100 code." -msgstr "" +msgstr "Генерувати код SH4-100." #: config/sh/sh.opt:86 #, no-c-format msgid "Generate SH4-200 code." -msgstr "" +msgstr "Генерувати код для SH4-200." #: config/sh/sh.opt:92 #, no-c-format msgid "Generate SH4-300 code." -msgstr "" +msgstr "Генерувати код для SH4-300." #: config/sh/sh.opt:96 #, no-c-format msgid "Generate SH4 FPU-less code." -msgstr "" +msgstr "Генерувати код для SH4 без FPU." #: config/sh/sh.opt:100 #, no-c-format msgid "Generate SH4-100 FPU-less code." -msgstr "" +msgstr "Генерувати код для SH4-100 без FPU." #: config/sh/sh.opt:104 #, no-c-format msgid "Generate SH4-200 FPU-less code." -msgstr "" +msgstr "Генерувати код для SH4-200 без FPU." #: config/sh/sh.opt:108 #, no-c-format msgid "Generate SH4-300 FPU-less code." -msgstr "" +msgstr "Генерувати код для SH4-300 без FPU." #: config/sh/sh.opt:112 #, no-c-format msgid "Generate code for SH4 340 series (MMU/FPU-less)." -msgstr "" +msgstr "Генерувати код для серії SH4 340 (без MMU/FPU)." #: config/sh/sh.opt:117 #, no-c-format msgid "Generate code for SH4 400 series (MMU/FPU-less)." -msgstr "" +msgstr "Генерувати код для серії SH4 400 (без MMU/FPU)." #: config/sh/sh.opt:122 #, no-c-format msgid "Generate code for SH4 500 series (FPU-less)." -msgstr "" +msgstr "Генерувати код для серії SH4 500 (без FPU)." #: config/sh/sh.opt:127 #, no-c-format msgid "Generate default single-precision SH4 code." -msgstr "" +msgstr "Генерувати код SH4 зі стандартною одинарною точністю." #: config/sh/sh.opt:131 #, no-c-format msgid "Generate default single-precision SH4-100 code." -msgstr "" +msgstr "Генерувати код SH4-100 з одинарною точністю за замовчуванням." #: config/sh/sh.opt:135 #, no-c-format msgid "Generate default single-precision SH4-200 code." -msgstr "" +msgstr "Створити код SH4-200 з одинарною точністю за замовчуванням." #: config/sh/sh.opt:139 #, no-c-format msgid "Generate default single-precision SH4-300 code." -msgstr "" +msgstr "Створити типовий код SH4-300 з одинарною точністю." #: config/sh/sh.opt:143 #, no-c-format msgid "Generate only single-precision SH4 code." -msgstr "" +msgstr "Створити лише код SH4 з одинарною точністю." #: config/sh/sh.opt:147 #, no-c-format msgid "Generate only single-precision SH4-100 code." -msgstr "" +msgstr "Створити лише код SH4-100 з одинарною точністю." #: config/sh/sh.opt:151 #, no-c-format msgid "Generate only single-precision SH4-200 code." -msgstr "" +msgstr "Створити лише код SH4-200 з одинарною точністю." #: config/sh/sh.opt:155 #, no-c-format msgid "Generate only single-precision SH4-300 code." -msgstr "" +msgstr "Створити лише код SH4-300 з одинарною точністю." #: config/sh/sh.opt:159 #, no-c-format msgid "Generate SH4a code." -msgstr "" +msgstr "Створити код SH4a." #: config/sh/sh.opt:163 #, no-c-format msgid "Generate SH4a FPU-less code." -msgstr "" +msgstr "Створити код SH4a без FPU." #: config/sh/sh.opt:167 #, no-c-format msgid "Generate default single-precision SH4a code." -msgstr "" +msgstr "Створити типовий код SH4a з одинарною точністю." #: config/sh/sh.opt:171 #, no-c-format msgid "Generate only single-precision SH4a code." -msgstr "" +msgstr "Генерувати лише код SH4a з одинарною точністю." #: config/sh/sh.opt:175 #, no-c-format msgid "Generate SH4al-dsp code." -msgstr "" +msgstr "Генерувати код SH4al-dsp." #: config/sh/sh.opt:183 #, no-c-format msgid "Generate code in big endian mode." -msgstr "" +msgstr "Генерувати код у режимі «Big Endian»." #: config/sh/sh.opt:187 #, no-c-format msgid "Generate 32-bit offsets in switch tables." -msgstr "" +msgstr "Генерувати 32-бітні зсуви в таблицях перемикачів." #: config/sh/sh.opt:191 #, no-c-format msgid "Generate bit instructions." -msgstr "" +msgstr "Генерувати бітові інструкції." #: config/sh/sh.opt:199 #, no-c-format msgid "Assume that zero displacement conditional branches are fast." -msgstr "" +msgstr "Припускати, що умовні гілки з нульовим зсувом є швидкими." #: config/sh/sh.opt:203 #, no-c-format msgid "Force the usage of delay slots for conditional branches." -msgstr "" +msgstr "Примусове використання слотів затримки для умовних гілок." #: config/sh/sh.opt:207 #, no-c-format msgid "Align doubles at 64-bit boundaries." -msgstr "" +msgstr "Вирівнювати подвійні числа за межами 64-бітних границь." #: config/sh/sh.opt:211 #, no-c-format msgid "Division strategy, one of: call-div1, call-fp, call-table." -msgstr "" +msgstr "Стратегія ділення, одна з: call-div1, call-fp, call-table." #: config/sh/sh.opt:215 #, no-c-format msgid "Specify name for 32 bit signed division function." -msgstr "" +msgstr "Вказати назву функції для 32-бітного знакового ділення." #: config/sh/sh.opt:219 #, no-c-format msgid "Generate ELF FDPIC code." -msgstr "" +msgstr "Створити код ELF FDPIC." #: config/sh/sh.opt:223 #, no-c-format msgid "Enable the use of 64-bit floating point registers in fmov instructions. See -mdalign if 64-bit alignment is required." -msgstr "" +msgstr "Увімкнути використання 64-бітних регістрів з плаваючою комою в інструкціях fmov. Див. -mdalign, якщо потрібна 64-бітна вирівнювання." #: config/sh/sh.opt:231 config/sh/sh.opt:269 #, no-c-format msgid "Follow Renesas (formerly Hitachi) / SuperH calling conventions." -msgstr "" +msgstr "Дотримуйтесь конвенцій виклику Renesas (раніше Hitachi) / SuperH." #: config/sh/sh.opt:235 #, no-c-format msgid "Increase the IEEE compliance for floating-point comparisons." -msgstr "" +msgstr "Збільшити відповідність до IEEE для порівнянь з плаваючою комою." #: config/sh/sh.opt:239 #, no-c-format msgid "Inline code to invalidate instruction cache entries after setting up nested function trampolines." -msgstr "" +msgstr "Вбудований код для скасування записів кешу інструкцій після налаштування вкладених функційних трамплінів." #: config/sh/sh.opt:243 config/arc/arc.opt:242 #, no-c-format msgid "Annotate assembler instructions with estimated addresses." -msgstr "" +msgstr "Анотувати асемблерні інструкції з оціненими адресами." #: config/sh/sh.opt:247 #, no-c-format msgid "Generate code in little endian mode." -msgstr "" +msgstr "Генерувати код у режимі little endian." #: config/sh/sh.opt:251 #, no-c-format msgid "Mark MAC register as call-clobbered." -msgstr "" +msgstr "Позначити регістр MAC як підданий змінам під час виклику." #: config/sh/sh.opt:257 #, no-c-format msgid "Make structs a multiple of 4 bytes (warning: ABI altered)." -msgstr "" +msgstr "Зробити структури кратними 4 байтам (попередження: змінено ABI)." #: config/sh/sh.opt:261 #, no-c-format msgid "Emit function-calls using global offset table when generating PIC." -msgstr "" +msgstr "Випускати виклики функцій, використовуючи глобальну таблицю зміщень при генерації PIC." #: config/sh/sh.opt:265 #, no-c-format msgid "Shorten address references during linking." -msgstr "" +msgstr "Скорочувати посилання на адреси під час звʼязування." #: config/sh/sh.opt:273 #, no-c-format msgid "Specify the model for atomic operations." -msgstr "" +msgstr "Вказати модель для атомних операцій." #: config/sh/sh.opt:277 #, no-c-format msgid "Use tas.b instruction for __atomic_test_and_set." -msgstr "" +msgstr "Використовувати інструкцію tas.b для __atomic_test_and_set." #: config/sh/sh.opt:281 #, no-c-format msgid "Cost to assume for a multiply insn." -msgstr "" +msgstr "Вартість, яку слід вважати для множення insn." #: config/sh/sh.opt:285 #, no-c-format msgid "Don't generate privileged-mode only code; implies -mno-inline-ic_invalidate if the inline code would not work in user mode." -msgstr "" +msgstr "Не генерувати код тільки в привілейованому режимі; передбачає -mno-inline-ic_invalidate, якщо код в режимі вбудованого коду не працюватиме в режимі користувача." #: config/sh/sh.opt:291 #, no-c-format msgid "Pretend a branch-around-a-move is a conditional move." -msgstr "" +msgstr "Припускати, що гілка навколо переміщення є умовним переміщенням." #: config/sh/sh.opt:295 #, no-c-format msgid "Enable the use of the fsca instruction." -msgstr "" +msgstr "Увімкнути використання інструкції fsca." #: config/sh/sh.opt:299 #, no-c-format msgid "Enable the use of the fsrra instruction." -msgstr "" +msgstr "Увімкнути використання інструкції fsrra." #: config/gcn/gcn.opt:26 #, no-c-format msgid "GCN GPU type to use:" -msgstr "" +msgstr "Тип GPU GCN, який слід використовувати:" #: config/gcn/gcn.opt:45 config/gcn/gcn.opt:49 #, no-c-format msgid "Specify the name of the target GPU." -msgstr "" +msgstr "Вказати назву цільового GPU." #: config/gcn/gcn.opt:53 #, no-c-format msgid "Generate code for a 32-bit ABI." -msgstr "" +msgstr "Генерувати код для 32-бітної ABI." #: config/gcn/gcn.opt:57 #, no-c-format msgid "Generate code for a 64-bit ABI." -msgstr "" +msgstr "Генерувати код для 64-бітного ABI." #: config/gcn/gcn.opt:61 #, no-c-format msgid "Enable OpenMP GPU offloading." -msgstr "" +msgstr "Увімкнути віддалене виконання OpenMP на GPU." #: config/gcn/gcn.opt:72 #, no-c-format msgid "Obsolete; use GCN_STACK_SIZE at runtime." -msgstr "" +msgstr "Застаріле; використовуйте GCN_STACK_SIZE під час виконання." #: config/gcn/gcn.opt:78 #, no-c-format msgid "Amount of local data-share (LDS) memory to reserve for gang-private variables." -msgstr "" +msgstr "Кількість локальної памʼяті для спільного використання даних (LDS), яку слід зарезервувати для приватних змінних групи." #: config/gcn/gcn.opt:82 #, no-c-format msgid "Warn about invalid OpenACC dimensions." -msgstr "." +msgstr "Попереджати про недійсні розміри OpenACC." #: config/gcn/gcn.opt:86 #, no-c-format msgid "Compile for devices requiring XNACK enabled. Default off." -msgstr "" +msgstr "Компілювати для пристроїв, які вимагають увімкнення XNACK. За замовчуванням вимкнено." #: config/gcn/gcn.opt:90 #, no-c-format msgid "SRAM-ECC modes:" -msgstr "" +msgstr "Режими SRAM-ECC:" #: config/gcn/gcn.opt:103 #, no-c-format msgid "Compile for devices with the SRAM ECC feature enabled, or not. Default \"any\"." -msgstr "" +msgstr "Компілювати для пристроїв з увімкненою функцією SRAM ECC або без неї. За замовчуванням «будь-який»." #: config/fr30/fr30.opt:23 #, no-c-format msgid "Assume small address space." -msgstr "" +msgstr "Припустити малий адресний простір." #: config/bpf/bpf.opt:28 #, no-c-format msgid "Generate eBPF for the given Linux kernel version." -msgstr "" +msgstr "Створити eBPF для вказаної версії ядра Linux." #: config/bpf/bpf.opt:115 #, no-c-format msgid "Generate xBPF." -msgstr "" +msgstr "Створити xBPF." #: config/bpf/bpf.opt:121 #, no-c-format msgid "Generate big-endian eBPF." -msgstr "" +msgstr "Створити big-endian eBPF." #: config/bpf/bpf.opt:125 #, no-c-format msgid "Generate little-endian eBPF." -msgstr "" +msgstr "Створити little-endian eBPF." #: config/bpf/bpf.opt:129 #, no-c-format msgid "Set a hard limit for the size of each stack frame, in bytes." -msgstr "" +msgstr "Встановити жорстку межу для розміру кожного рамки стеку, в байтах." #: config/bpf/bpf.opt:133 #, no-c-format msgid "Generate all necessary information for BPF Compile Once - Run Everywhere." -msgstr "" +msgstr "Згенерувати всю необхідну інформацію для BPF Compile Once - Run Everywhere." #: config/bpf/bpf.opt:139 #, no-c-format msgid "Enable extra conditional-branch instructions j(s)lt and j(s)le." -msgstr "" +msgstr "Увімкнути додаткові умовні гілкові інструкції j(s)lt та j(s)le." #: config/bpf/bpf.opt:143 #, no-c-format msgid "Enable 32-bit ALU instructions." -msgstr "Увімкнути 32-бітові інструкції ALU." +msgstr "Увімкнути 32-бітні ALU-інструкції." #: config/bpf/bpf.opt:147 #, no-c-format msgid "Enable 32-bit jump instructions." -msgstr "Увімкнути 32-бітові інструкції переходу." +msgstr "Увімкнути 32-бітні інструкції переходу." #: config/mips/mips.opt:32 #, no-c-format msgid "-mabi=ABI\tGenerate code that conforms to the given ABI." -msgstr "" +msgstr "-mabi=ABI\tГенерувати код, який відповідає вказаному ABI." #: config/mips/mips.opt:36 #, no-c-format msgid "Known MIPS ABIs (for use with the -mabi= option):" -msgstr "" +msgstr "Відомі MIPS ABI (для використання з опцією -mabi=):" #: config/mips/mips.opt:55 #, no-c-format msgid "Generate code that can be used in SVR4-style dynamic objects." -msgstr "" +msgstr "Генерувати код, який може бути використаний у динамічних обʼєктах у стилі SVR4." #: config/mips/mips.opt:59 #, no-c-format msgid "Use PMC-style 'mad' instructions." -msgstr "" +msgstr "Використовувати інструкції 'mad' у стилі PMC." #: config/mips/mips.opt:63 #, no-c-format msgid "Use integer madd/msub instructions." -msgstr "" +msgstr "Використовувати цілочисельні інструкції madd/msub." #: config/mips/mips.opt:67 #, no-c-format msgid "-march=ISA\tGenerate code for the given ISA." -msgstr "" +msgstr "-march=ISA\tГенерувати код для заданого ISA." #: config/mips/mips.opt:75 #, no-c-format msgid "Use Branch Likely instructions, overriding the architecture default." -msgstr "" +msgstr "Використовувати інструкції Branch Likely, перевищуючи архітектурний типовий." #: config/mips/mips.opt:79 #, no-c-format msgid "Switch on/off MIPS16 ASE on alternating functions for compiler testing." -msgstr "" +msgstr "Увімкнути/вимкнути MIPS16 ASE на чергових функціях для тестування компілятора." #: config/mips/mips.opt:87 #, no-c-format msgid "-mcode-readable=SETTING\tSpecify when instructions are allowed to access code." -msgstr "" +msgstr "-mcode-readable=SETTING\tВказати, коли дозволено інструкціям отримувати доступ до коду." #: config/mips/mips.opt:91 #, no-c-format msgid "Valid arguments to -mcode-readable=:" -msgstr "" +msgstr "Допустимі аргументи для -mcode-readable=:" #: config/mips/mips.opt:104 #, no-c-format msgid "Use branch-and-break sequences to check for integer divide by zero." -msgstr "" +msgstr "Використовувати послідовності гілок та переривань для перевірки цілочисельного ділення на нуль." #: config/mips/mips.opt:108 #, no-c-format msgid "Use trap instructions to check for integer divide by zero." -msgstr "" +msgstr "Використовувати інструкції trap для перевірки цілочисельного ділення на нуль." #: config/mips/mips.opt:112 #, no-c-format msgid "Allow the use of MDMX instructions." -msgstr "" +msgstr "Дозволити використання інструкцій MDMX." #: config/mips/mips.opt:120 #, no-c-format msgid "Use MIPS-DSP instructions." -msgstr "" +msgstr "Використовувати інструкції MIPS-DSP." #: config/mips/mips.opt:124 #, no-c-format msgid "Use MIPS-DSP REV 2 instructions." -msgstr "" +msgstr "Використовувати інструкції MIPS-DSP REV 2." #: config/mips/mips.opt:146 #, no-c-format msgid "Use Enhanced Virtual Addressing instructions." -msgstr "" +msgstr "Використовуйте інструкції покращеного віртуального адресування." #: config/mips/mips.opt:150 #, no-c-format msgid "Use NewABI-style %reloc() assembly operators." -msgstr "" +msgstr "Використовуйте оператори збірки %reloc() у стилі NewABI." #: config/mips/mips.opt:154 #, no-c-format msgid "Use -G for data that is not defined by the current object." -msgstr "" +msgstr "Використовуйте -G для даних, які не визначені поточним обʼєктом." #: config/mips/mips.opt:158 #, no-c-format msgid "Work around certain 24K errata." -msgstr "" +msgstr "Обійти певні помилки 24K." #: config/mips/mips.opt:162 #, no-c-format msgid "Work around certain R4000 errata." -msgstr "" +msgstr "Обійти певні помилки R4000." #: config/mips/mips.opt:166 #, no-c-format msgid "Work around certain R4400 errata." -msgstr "" +msgstr "Обійти певні помилки R4400." #: config/mips/mips.opt:170 #, no-c-format msgid "Work around the R5900 short loop erratum." -msgstr "" +msgstr "Обійдіть помилку короткого циклу R5900." #: config/mips/mips.opt:174 #, no-c-format msgid "Work around certain RM7000 errata." -msgstr "" +msgstr "Обійти певні помилки RM7000." #: config/mips/mips.opt:178 #, no-c-format msgid "Work around certain R10000 errata." -msgstr "" +msgstr "Обійдіть певні помилки R10000." #: config/mips/mips.opt:182 #, no-c-format msgid "Work around errata for early SB-1 revision 2 cores." -msgstr "" +msgstr "Обійдіть помилки для ранніх ядер SB-1 ревізії 2." #: config/mips/mips.opt:186 #, no-c-format msgid "Work around certain VR4120 errata." -msgstr "" +msgstr "Обійдіть певні помилки VR4120." #: config/mips/mips.opt:190 #, no-c-format msgid "Work around VR4130 mflo/mfhi errata." -msgstr "" +msgstr "Обійдіть помилки mflo/mfhi VR4130." #: config/mips/mips.opt:194 #, no-c-format msgid "Work around an early 4300 hardware bug." -msgstr "" +msgstr "Обійдіть ранню апаратну помилку 4300." #: config/mips/mips.opt:198 #, no-c-format msgid "FP exceptions are enabled." -msgstr "" +msgstr "Ввімкнено винятки FP." #: config/mips/mips.opt:202 #, no-c-format msgid "Use 32-bit floating-point registers." -msgstr "" +msgstr "Використовуйте 32-бітні регістри з плаваючою комою." #: config/mips/mips.opt:206 #, no-c-format msgid "Conform to the o32 FPXX ABI." -msgstr "" +msgstr "Відповідність ABI o32 FPXX." #: config/mips/mips.opt:210 #, no-c-format msgid "Use 64-bit floating-point registers." -msgstr "" +msgstr "Використовуйте 64-бітні регістри з плаваючою комою." #: config/mips/mips.opt:214 #, no-c-format msgid "-mflush-func=FUNC\tUse FUNC to flush the cache before calling stack trampolines." -msgstr "" +msgstr "-mflush-func=FUNC\tВикористовуйте FUNC для очищення кешу перед викликом стекових трамплінів." #: config/mips/mips.opt:218 #, no-c-format msgid "-mabs=MODE\tSelect the IEEE 754 ABS/NEG instruction execution mode." -msgstr "" +msgstr "-mabs=MODE\tВиберіть режим виконання інструкцій ABS/NEG IEEE 754." #: config/mips/mips.opt:222 #, no-c-format msgid "-mnan=ENCODING\tSelect the IEEE 754 NaN data encoding." -msgstr "" +msgstr "-mnan=ENCODING\tВиберіть кодування даних NaN (Not a Number) згідно з IEEE 754." #: config/mips/mips.opt:226 #, no-c-format msgid "Known MIPS IEEE 754 settings (for use with the -mabs= and -mnan= options):" -msgstr "" +msgstr "Відомі налаштування MIPS IEEE 754 (для використання з опціями -mabs= та -mnan=):" #: config/mips/mips.opt:236 #, no-c-format msgid "Use 32-bit general registers." -msgstr "" +msgstr "Використовуйте 32-бітні загальні регістри." #: config/mips/mips.opt:240 #, no-c-format msgid "Use 64-bit general registers." -msgstr "" +msgstr "Використовуйте 64-бітні загальні регістри." #: config/mips/mips.opt:244 #, no-c-format msgid "Use GP-relative addressing to access small data." -msgstr "" +msgstr "Використовуйте GP-відносну адресацію для доступу до невеликих даних." #: config/mips/mips.opt:248 #, no-c-format msgid "When generating -mabicalls code, allow executables to use PLTs and copy relocations." -msgstr "" +msgstr "При генерації коду -mabicalls, дозволяє виконуваним файлам використовувати PLT та копіювати перерозташування." #: config/mips/mips.opt:252 #, no-c-format msgid "Allow the use of hardware floating-point ABI and instructions." -msgstr "" +msgstr "Дозволити використання апаратного ABI та інструкцій з плаваючою комою." #: config/mips/mips.opt:256 #, no-c-format msgid "Generate code that is link-compatible with MIPS16 and microMIPS code." -msgstr "" +msgstr "Генерувати код, який сумісний з кодом MIPS16 та microMIPS при звʼязуванні." #: config/mips/mips.opt:260 #, no-c-format msgid "An alias for minterlink-compressed provided for backward-compatibility." -msgstr "" +msgstr "Псевдонім для minterlink-compressed, наданий для забезпечення зворотної сумісності." #: config/mips/mips.opt:264 #, no-c-format msgid "-mipsN\tGenerate code for ISA level N." -msgstr "" +msgstr "-mipsN\tГенерувати код для рівня ISA N." #: config/mips/mips.opt:268 #, no-c-format msgid "Generate MIPS16 code." -msgstr "" +msgstr "Генерувати код для MIPS16." #: config/mips/mips.opt:272 #, no-c-format msgid "Use MIPS-3D instructions." -msgstr "" +msgstr "Використовувати інструкції MIPS-3D." #: config/mips/mips.opt:276 #, no-c-format msgid "Use ll, sc and sync instructions." -msgstr "" +msgstr "Використовувати інструкції ll, sc та sync." #: config/mips/mips.opt:280 #, no-c-format msgid "Use -G for object-local data." -msgstr "" +msgstr "Використовувати -G для локальних даних обʼєкта." #: config/mips/mips.opt:284 #, no-c-format msgid "Use indirect calls." -msgstr "" +msgstr "Використовувати непрямі виклики." #: config/mips/mips.opt:288 #, no-c-format msgid "Use a 32-bit long type." -msgstr "" +msgstr "Використовувати тип long з 32 бітами." #: config/mips/mips.opt:292 #, no-c-format msgid "Use a 64-bit long type." -msgstr "" +msgstr "Використовувати тип long з 64 бітами." #: config/mips/mips.opt:296 #, no-c-format msgid "Pass the address of the ra save location to _mcount in $12." -msgstr "" +msgstr "Передати адресу місця збереження ra в _mcount в $12." #: config/mips/mips.opt:300 #, no-c-format msgid "Don't optimize block moves." -msgstr "" +msgstr "Не оптимізовувати переміщення блоків." #: config/mips/mips.opt:304 #, no-c-format msgid "Use microMIPS instructions." -msgstr "" +msgstr "Використовувати інструкції microMIPS." #: config/mips/mips.opt:308 #, no-c-format msgid "Use MIPS MSA Extension instructions." -msgstr "" +msgstr "Використовуйте інструкції розширення MIPS MSA." #: config/mips/mips.opt:312 #, no-c-format msgid "Allow the use of MT instructions." -msgstr "" +msgstr "Дозволити використання інструкцій MT." #: config/mips/mips.opt:316 #, no-c-format msgid "Prevent the use of all floating-point operations." -msgstr "" +msgstr "Заборонити використання всіх операцій з плаваючою комою." #: config/mips/mips.opt:320 #, no-c-format msgid "Use MCU instructions." -msgstr "" +msgstr "Використовуйте інструкції МКП." #: config/mips/mips.opt:324 #, no-c-format msgid "Do not use a cache-flushing function before calling stack trampolines." -msgstr "" +msgstr "Не використовуйте функцію очищення кешу перед викликом стекових трамплінів." #: config/mips/mips.opt:328 #, no-c-format msgid "Do not use MDMX instructions." -msgstr "" +msgstr "Не використовуйте інструкції MDMX." #: config/mips/mips.opt:332 #, no-c-format msgid "Generate normal-mode code." -msgstr "" +msgstr "Генерувати код у нормальному режимі." #: config/mips/mips.opt:336 #, no-c-format msgid "Do not use MIPS-3D instructions." -msgstr "" +msgstr "Не використовуйте інструкції MIPS-3D." #: config/mips/mips.opt:340 #, no-c-format msgid "Use paired-single floating-point instructions." -msgstr "" +msgstr "Використовуйте інструкції з плаваючою комою одинарної точності в парах (paired-single)." #: config/mips/mips.opt:344 #, no-c-format msgid "-mr10k-cache-barrier=SETTING\tSpecify when r10k cache barriers should be inserted." -msgstr "" +msgstr "-mr10k-cache-barrier=НАЛАГОДЖЕННЯ\tВказати, коли слід вставляти барʼєри кешу r10k." #: config/mips/mips.opt:348 #, no-c-format msgid "Valid arguments to -mr10k-cache-barrier=:" -msgstr "" +msgstr "Допустимі аргументи для -mr10k-cache-barrier=:" #: config/mips/mips.opt:361 #, no-c-format msgid "Try to allow the linker to turn PIC calls into direct calls." -msgstr "" +msgstr "Спробуйте дозволити лінкеру перетворити виклики PIC на прямі виклики." #: config/mips/mips.opt:365 #, no-c-format msgid "When generating -mabicalls code, make the code suitable for use in shared libraries." -msgstr "" +msgstr "При генерації коду -mabicalls зробіть код придатним для використання в спільних бібліотеках." #: config/mips/mips.opt:373 #, no-c-format msgid "Use SmartMIPS instructions." -msgstr "" +msgstr "Використовуйте інструкції SmartMIPS." #: config/mips/mips.opt:381 #, no-c-format msgid "Optimize lui/addiu address loads." -msgstr "" +msgstr "Оптимізуйте завантаження адреси lui/addiu." #: config/mips/mips.opt:385 #, no-c-format msgid "Assume all symbols have 32-bit values." -msgstr "" +msgstr "Припустимо, що всі символи мають значення 32 біти." #: config/mips/mips.opt:389 #, no-c-format msgid "Use synci instruction to invalidate i-cache." -msgstr "" +msgstr "Використовуйте інструкцію synci для недійсного i-кешу." #: config/mips/mips.opt:397 #, no-c-format msgid "Use lwxc1/swxc1/ldxc1/sdxc1 instructions where applicable." -msgstr "" +msgstr "Використовуйте інструкції lwxc1/swxc1/ldxc1/sdxc1 там, де це можливо." #: config/mips/mips.opt:401 #, no-c-format msgid "Use 4-operand madd.s/madd.d and related instructions where applicable." -msgstr "" +msgstr "Використовуйте 4-операндні інструкції madd.s/madd.d та повʼязані інструкції там, де це можливо." #: config/mips/mips.opt:409 #, no-c-format msgid "Generate code with unaligned load store, valid for MIPS R6." -msgstr "" +msgstr "Генерувати код з незбалансованим завантаженням та зберіганням, дійсним для MIPS R6." #: config/mips/mips.opt:417 #, no-c-format msgid "Use Virtualization (VZ) instructions." -msgstr "" +msgstr "Використовувати інструкції віртуалізації (VZ)." #: config/mips/mips.opt:421 #, no-c-format msgid "Use eXtended Physical Address (XPA) instructions." -msgstr "" +msgstr "Використовувати інструкції розширеної фізичної адреси (XPA)." #: config/mips/mips.opt:425 #, no-c-format msgid "Use Cyclic Redundancy Check (CRC) instructions." -msgstr "" +msgstr "Використовувати інструкції циклічного контролю зайвості (CRC)." #: config/mips/mips.opt:429 #, no-c-format msgid "Use Global INValidate (GINV) instructions." -msgstr "" +msgstr "Використовувати інструкції глобальної недійсності (GINV)." #: config/mips/mips.opt:433 #, no-c-format msgid "Perform VR4130-specific alignment optimizations." -msgstr "" +msgstr "Виконувати оптимізацію вирівнювання, специфічну для VR4130." #: config/mips/mips.opt:437 #, no-c-format msgid "Lift restrictions on GOT size." -msgstr "" +msgstr "Скасувати обмеження на розмір GOT." #: config/mips/mips.opt:441 #, no-c-format msgid "Enable use of odd-numbered single-precision registers." -msgstr "" +msgstr "Дозволити використання регістрів з непарними номерами для одинарної точності." #: config/mips/mips.opt:445 #, no-c-format msgid "Optimize frame header." -msgstr "" +msgstr "Оптимізувати заголовок фрейму." #: config/mips/mips.opt:452 #, no-c-format msgid "Enable load/store bonding." -msgstr "" +msgstr "Увімкнути звʼязок завантаження/зберігання." #: config/mips/mips.opt:456 #, no-c-format msgid "Specify the compact branch usage policy." -msgstr "" +msgstr "Вказати політику використання компактних гілок." #: config/mips/mips.opt:460 #, no-c-format msgid "Policies available for use with -mcompact-branches=:" -msgstr "" +msgstr "Доступні політики для використання з -mcompact-branches=:" #: config/mips/mips.opt:473 #, no-c-format msgid "Use Loongson MultiMedia extensions Instructions (MMI) instructions." -msgstr "" +msgstr "Використовуйте інструкції розширень MultiMedia Loongson (MMI)." #: config/mips/mips.opt:477 #, no-c-format msgid "Use Loongson EXTension (EXT) instructions." -msgstr "." +msgstr "Використовуйте інструкції розширень Loongson (EXT)." #: config/mips/mips.opt:481 #, no-c-format msgid "Use Loongson EXTension R2 (EXT2) instructions." -msgstr "" +msgstr "Використовуйте інструкції розширень Loongson R2 (EXT2)." #: config/mips/mips-tables.opt:24 #, no-c-format msgid "Known MIPS CPUs (for use with the -march= and -mtune= options):" -msgstr "" +msgstr "Відомі процесори MIPS (для використання з опціями -march= та -mtune=):" #: config/mips/mips-tables.opt:28 #, no-c-format msgid "Known MIPS ISA levels (for use with the -mips option):" -msgstr "" +msgstr "Відомі рівні ISA MIPS (для використання з опцією -mips):" #: config/arc/arc-tables.opt:25 #, no-c-format msgid "Known ARC CPUs (for use with the -mcpu= option):" -msgstr "" +msgstr "Відомі процесори ARC (для використання з опцією -mcpu=):" #: config/arc/arc.opt:26 #, no-c-format msgid "Compile code for big endian mode." -msgstr "" +msgstr "Компілювати код для режиму великого порядку байтів." #: config/arc/arc.opt:30 #, no-c-format msgid "Compile code for little endian mode. This is the default." -msgstr "" +msgstr "Компілювати код для режиму малого порядку байтів. Це значення за замовчуванням." #: config/arc/arc.opt:34 #, no-c-format msgid "Disable ARCompact specific pass to generate conditional execution instructions." -msgstr "" +msgstr "Вимкнути спеціальний прохід ARCompact для генерації умовних інструкцій виконання." #: config/arc/arc.opt:38 #, no-c-format msgid "Generate ARCompact 32-bit code for ARC600 processor." -msgstr "" +msgstr "Генерувати 32-бітний код ARCompact для процесора ARC600." #: config/arc/arc.opt:42 #, no-c-format msgid "Same as -mA6." -msgstr "" +msgstr "Те саме, що й -mA6." #: config/arc/arc.opt:46 #, no-c-format msgid "Generate ARCompact 32-bit code for ARC601 processor." -msgstr "" +msgstr "Генерувати 32-бітний код ARCompact для процесора ARC601." #: config/arc/arc.opt:50 #, no-c-format msgid "Generate ARCompact 32-bit code for ARC700 processor." -msgstr "" +msgstr "Генерувати 32-бітний код ARCompact для процесора ARC700." #: config/arc/arc.opt:54 #, no-c-format msgid "Same as -mA7." -msgstr "" +msgstr "Те саме, що й -mA7." #: config/arc/arc.opt:58 #, no-c-format msgid "Force all calls to be made via a jli instruction." -msgstr "" +msgstr "Примусово здійснювати всі виклики через інструкцію jli." #: config/arc/arc.opt:62 #, no-c-format msgid "-mmpy-option=MPY\tCompile ARCv2 code with a multiplier design option." -msgstr "" +msgstr "-mmpy-option=MPY\tКомпілювати код ARCv2 з опцією дизайну множника." #: config/arc/arc.opt:132 #, no-c-format msgid "Enable DIV-REM instructions for ARCv2." -msgstr "" +msgstr "Увімкнути інструкції DIV-REM для ARCv2." #: config/arc/arc.opt:136 #, no-c-format msgid "Enable code density instructions for ARCv2." -msgstr "" +msgstr "Увімкнути інструкції з кодовою щільністю для ARCv2." #: config/arc/arc.opt:146 #, no-c-format msgid "Use ordinarily cached memory accesses for volatile references." -msgstr "" +msgstr "Використовувати звичайні кешовані доступи до памʼяті для волатильних посилань." #: config/arc/arc.opt:150 #, no-c-format msgid "Enable cache bypass for volatile references." -msgstr "" +msgstr "Увімкнути обхід кешу для волатильних посилань." #: config/arc/arc.opt:154 #, no-c-format msgid "Generate instructions supported by barrel shifter." -msgstr "" +msgstr "Генерувати інструкції, підтримувані револьверним зсувом." #: config/arc/arc.opt:158 #, no-c-format msgid "Generate norm instruction." -msgstr "" +msgstr "Створити команду нормалізації." #: config/arc/arc.opt:162 #, no-c-format msgid "Generate swap instruction." -msgstr "" +msgstr "Створити команду обміну." #: config/arc/arc.opt:166 #, no-c-format msgid "Generate mul64 and mulu64 instructions." -msgstr "" +msgstr "Створити команди mul64 та mulu64." #: config/arc/arc.opt:170 #, no-c-format msgid "Do not generate mpy instructions for ARC700." -msgstr "" +msgstr "Не створювати команди mpy для ARC700." #: config/arc/arc.opt:174 #, no-c-format msgid "Generate extended arithmetic instructions, only valid for ARC700." -msgstr "" +msgstr "Генерувати розширені арифметичні інструкції, дійсні лише для ARC700." #: config/arc/arc.opt:178 #, no-c-format msgid "Dummy flag. This is the default unless FPX switches are provided explicitly." -msgstr "" +msgstr "Фіктивний прапорець. Це значення за замовчуванням, якщо FPX-перемикачі не вказані явно." #: config/arc/arc.opt:182 #, no-c-format msgid "Generate call insns as register indirect calls." -msgstr "" +msgstr "Генерувати виклики інструкцій як опосередковані виклики регістрів." #: config/arc/arc.opt:186 #, no-c-format msgid "Do no generate BRcc instructions in arc_reorg." -msgstr "" +msgstr "Не генерувати інструкції BRcc в arc_reorg." #: config/arc/arc.opt:190 #, no-c-format msgid "Generate sdata references. This is the default, unless you compile for PIC." -msgstr "" +msgstr "Генерувати посилання на sdata. Це значення за замовчуванням, якщо ви компілюєте для PIC." #: config/arc/arc.opt:194 #, no-c-format msgid "Generate millicode thunks." -msgstr "" +msgstr "Генерувати мілікодові тунки." #: config/arc/arc.opt:198 config/arc/arc.opt:202 #, no-c-format msgid "FPX: Generate Single Precision FPX (compact) instructions." -msgstr "" +msgstr "FPX: Генерувати інструкції FPX з одинарною точністю (компактні)." #: config/arc/arc.opt:206 #, no-c-format msgid "FPX: Generate Single Precision FPX (fast) instructions." -msgstr "" +msgstr "FPX: Генерувати інструкції FPX з одинарною точністю (швидкі)." #: config/arc/arc.opt:210 #, no-c-format msgid "FPX: Enable Argonaut ARC CPU Double Precision Floating Point extensions." -msgstr "" +msgstr "FPX: Увімкнути розширення з подвійною точністю чисел з плаваючою комою для процесора ARC Argonaut." #: config/arc/arc.opt:214 config/arc/arc.opt:218 #, no-c-format msgid "FPX: Generate Double Precision FPX (compact) instructions." -msgstr "" +msgstr "FPX: Генерувати інструкції FPX подвійної точності (компактні)." #: config/arc/arc.opt:222 #, no-c-format msgid "FPX: Generate Double Precision FPX (fast) instructions." -msgstr "" +msgstr "FPX: Генерувати інструкції FPX подвійної точності (швидкі)." #: config/arc/arc.opt:226 #, no-c-format msgid "Disable LR and SR instructions from using FPX extension aux registers." -msgstr "" +msgstr "Вимкнути використання реєстрів FPX розширення для інструкцій LR та SR." #: config/arc/arc.opt:230 #, no-c-format msgid "Enable generation of ARC SIMD instructions via target-specific builtins." -msgstr "" +msgstr "Увімкнути генерацію інструкцій ARC SIMD за допомогою вбудованих функцій, специфічних для цілей." #: config/arc/arc.opt:234 #, no-c-format msgid "-mcpu=CPU\tCompile code for ARC variant CPU." -msgstr "" +msgstr "-mcpu=CPU\tКомпілювати код для варіанту процесора ARC." #: config/arc/arc.opt:238 #, no-c-format msgid "Size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os." -msgstr "" +msgstr "Рівень оптимізації розміру: 0:відсутній 1:можливості 2:розподіл регістрів 3:відмова від вирівнювання, -Os." #: config/arc/arc.opt:246 #, no-c-format msgid "Cost to assume for a multiply instruction, with 4 being equal to a normal insn." -msgstr "" +msgstr "Вартість, яку слід припустити для множення, де 4 дорівнює звичайній інструкції." #: config/arc/arc.opt:250 #, no-c-format msgid "-mtune=TUNE\tTune code for given ARC variant." -msgstr "" +msgstr "-mtune=TUNE\tНалаштувати код для вказаної варіанту ARC." #: config/arc/arc.opt:284 #, no-c-format msgid "Enable the use of indexed loads." -msgstr "" +msgstr "Увімкнути використання індексованого завантаження." #: config/arc/arc.opt:288 #, no-c-format msgid "Enable the use of pre/post modify with register displacement." -msgstr "" +msgstr "Увімкнути використання попередньої/післяповторної модифікації з відхиленням регістра." #: config/arc/arc.opt:292 #, no-c-format msgid "Generate 32x16 multiply and mac instructions." -msgstr "" +msgstr "Генерувати інструкції множення та mac розміром 32x16." #: config/arc/arc.opt:300 #, no-c-format msgid "Don't use less than 25 bit addressing range for calls." -msgstr "" +msgstr "Не використовувати діапазон адресації менше 25 біт для викликів." #: config/arc/arc.opt:304 #, no-c-format msgid "Explain what alignment considerations lead to the decision to make an insn short or long." -msgstr "" +msgstr "Пояснити, які врахування вирівнювання призводять до рішення зробити інструкцію короткою або довгою." #: config/arc/arc.opt:322 #, no-c-format msgid "Enable pre-reload use of cbranchsi pattern." -msgstr "" +msgstr "Увімкнути попереднє завантаження використання шаблону cbranchsi." #: config/arc/arc.opt:326 #, no-c-format msgid "Enable bbit peephole2." -msgstr "" +msgstr "Увімкнути bbit peephole2." #: config/arc/arc.opt:330 #, no-c-format msgid "Use pc-relative switch case tables - this enables case table shortening." -msgstr "" +msgstr "Використовувати таблиці випадків перемикача, що відносяться до pc - це дозволяє скорочувати таблиці випадків." #: config/arc/arc.opt:334 #, no-c-format msgid "Enable compact casesi pattern." -msgstr "" +msgstr "Увімкнути компактний шаблон casesi." #: config/arc/arc.opt:338 #, no-c-format msgid "Enable 'q' instruction alternatives." -msgstr "" +msgstr "Увімкнути альтернативи інструкції 'q'." #: config/arc/arc.opt:342 #, no-c-format msgid "Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc." -msgstr "" +msgstr "Розгорнути adddi3 та subdi3 під час генерації rtl в add.f / adc тощо." #: config/arc/arc.opt:349 #, no-c-format msgid "Enable variable polynomial CRC extension." -msgstr "" +msgstr "Увімкнути розширення змінного поліноміального CRC." #: config/arc/arc.opt:353 #, no-c-format msgid "Enable DSP 3.1 Pack A extensions." -msgstr "" +msgstr "Увімкнути розширення DSP 3.1 Pack A." #: config/arc/arc.opt:357 #, no-c-format msgid "Enable dual viterbi butterfly extension." -msgstr "" +msgstr "Увімкнути розширення подвійного витербі-метелика." #: config/arc/arc.opt:367 #, no-c-format msgid "Enable Dual and Single Operand Instructions for Telephony." -msgstr "" +msgstr "Увімкнути дво- та однооперандні інструкції для телефонії." #: config/arc/arc.opt:371 #, no-c-format msgid "Enable XY Memory extension (DSP version 3)." -msgstr "" +msgstr "Увімкнути розширення памʼяті XY (версія DSP 3)." #: config/arc/arc.opt:376 #, no-c-format msgid "Enable Locked Load/Store Conditional extension." -msgstr "" +msgstr "Увімкнути розширення заблокованого завантаження/збереження умовного." #: config/arc/arc.opt:380 #, no-c-format msgid "Enable swap byte ordering extension instruction." -msgstr "" +msgstr "Увімкнути інструкцію розширення заміни порядку байтів." #: config/arc/arc.opt:384 #, no-c-format msgid "Enable 64-bit Time-Stamp Counter extension instruction." -msgstr "" +msgstr "Увімкнути інструкцію розширення лічильника часових міток 64 біти." #: config/arc/arc.opt:388 #, no-c-format msgid "Pass -EB option through to linker." -msgstr "" +msgstr "Передати опцію -EB до лінкера." #: config/arc/arc.opt:392 #, no-c-format msgid "Pass -EL option through to linker." -msgstr "" +msgstr "Передати опцію -EL до лінкера." #: config/arc/arc.opt:396 #, no-c-format msgid "Pass -marclinux option through to linker." -msgstr "" +msgstr "Передавати опцію -marclinux до лінкера." #: config/arc/arc.opt:400 #, no-c-format msgid "Pass -marclinux_prof option through to linker." -msgstr "" +msgstr "Передавати опцію -marclinux_prof до лінкера." #: config/arc/arc.opt:409 #, no-c-format msgid "Don't indicate any priority with TARGET_REGISTER_PRIORITY." -msgstr "" +msgstr "Не вказувати жодної пріоритетності з TARGET_REGISTER_PRIORITY." #: config/arc/arc.opt:413 #, no-c-format msgid "Indicate priority for r0..r3 / r12..r15 with TARGET_REGISTER_PRIORITY." -msgstr "" +msgstr "Вказати пріоритет для r0..r3 / r12..r15 з TARGET_REGISTER_PRIORITY." #: config/arc/arc.opt:417 #, no-c-format msgid "Reduce priority for r0..r3 / r12..r15 with TARGET_REGISTER_PRIORITY." -msgstr "" +msgstr "Зменшити пріоритет для r0..r3 / r12..r15 з TARGET_REGISTER_PRIORITY." #: config/arc/arc.opt:429 #, no-c-format msgid "Enable atomic instructions." -msgstr "" +msgstr "Увімкнути атомарні інструкції." #: config/arc/arc.opt:433 #, no-c-format msgid "Enable double load/store instructions for ARC HS." -msgstr "" +msgstr "Увімкнути подвійні інструкції завантаження/збереження для ARC HS." #: config/arc/arc.opt:437 #, no-c-format msgid "Specify the name of the target floating point configuration." -msgstr "" +msgstr "Вказати назву конфігурації плаваючої коми цільової платформи." #: config/arc/arc.opt:480 #, no-c-format msgid "Specify thread pointer register number." -msgstr "" +msgstr "Вказати номер реєстра вказівника потоку." #: config/arc/arc.opt:487 #, no-c-format msgid "Enable use of NPS400 bit operations." -msgstr "" +msgstr "Увімкнути використання бітових операцій NPS400." #: config/arc/arc.opt:491 #, no-c-format msgid "Enable use of NPS400 xld/xst extension." -msgstr "" +msgstr "Увімкнути використання розширення xld/xst для NPS400." #: config/arc/arc.opt:499 #, no-c-format msgid "Specifies the registers that the processor saves on an interrupt entry and exit." -msgstr "" +msgstr "Вказує регістри, які процесор зберігає при вході та виході з переривання." #: config/arc/arc.opt:503 #, no-c-format msgid "Specifies the number of registers replicated in second register bank on entry to fast interrupt." -msgstr "" +msgstr "Вказує кількість регістрів, які реплікуються в другому банку регістрів при вході в швидке переривання." #: config/arc/arc.opt:507 #, no-c-format msgid "Sets LP_COUNT register width. Possible values are 8, 16, 20, 24, 28, and 32." -msgstr "" +msgstr "Встановлює ширину регістра LP_COUNT. Можливі значення: 8, 16, 20, 24, 28 та 32." #: config/arc/arc.opt:532 #, no-c-format msgid "Enable 16-entry register file." -msgstr "" +msgstr "Увімкнути регістр з 16 записами." #: config/arc/arc.opt:536 #, no-c-format msgid "Enable use of BI/BIH instructions when available." -msgstr "" +msgstr "Увімкнути використання інструкцій BI/BIH, якщо вони доступні." #: config/arc/arc.opt:540 #, no-c-format msgid "Enable ENTER_S and LEAVE_S opcodes for ARCv2." -msgstr "" +msgstr "Увімкнути опкоди ENTER_S та LEAVE_S для ARCv2." #: lto/lang.opt:50 #, no-c-format msgid "Set linker output type (used internally during LTO optimization)." -msgstr "" +msgstr "Встановити тип виводу лінкера (використовується внутрішньо під час оптимізації LTO)." #: lto/lang.opt:54 #, no-c-format msgid "Run the link-time optimizer in local transformation (LTRANS) mode." -msgstr "" +msgstr "Запустити оптимізатор часу звʼязування в режимі локальної трансформації (LTRANS)." #: lto/lang.opt:58 #, no-c-format msgid "Specify a file to which a list of files output by LTRANS is written." -msgstr "" +msgstr "Вказати файл, до якого буде записано список файлів, що виводяться LTRANS." #: lto/lang.opt:62 #, no-c-format msgid "The resolution file." -msgstr "" +msgstr "Файл резолюції." #: lto/lang.opt:66 #, no-c-format msgid "Run the link-time optimizer in whole program analysis (WPA) mode." -msgstr "" +msgstr "Запустити оптимізатор часу звʼязування в режимі аналізу всього програмного коду (WPA)." #: lto/lang.opt:70 #, no-c-format msgid "Whole program analysis (WPA) mode with number of parallel jobs specified." -msgstr "" +msgstr "Режим аналізу всього програмного коду (WPA) з вказаною кількістю паралельних задач." #: lto/lang.opt:78 #, no-c-format msgid "Call the dump function for variables and function in IL." -msgstr "" +msgstr "Викликати функцію виведення для змінних та функцій в IL." #: lto/lang.opt:82 #, no-c-format msgid "Dump the demangled output." -msgstr "" +msgstr "Вивести роздекорований вихід." #: lto/lang.opt:86 #, no-c-format msgid "Dump only the defined symbols." -msgstr "" +msgstr "Вивести лише визначені символи." #: lto/lang.opt:90 #, no-c-format msgid "Print the initial values of the variables." -msgstr "" +msgstr "Вивести початкові значення змінних." #: lto/lang.opt:94 #, no-c-format msgid "Sort the symbols alphabetically." -msgstr "" +msgstr "Відсортувати символи за алфавітом." #: lto/lang.opt:98 #, no-c-format msgid "Sort the symbols according to size." -msgstr "" +msgstr "Відсортувати символи за розміром." #: lto/lang.opt:102 #, no-c-format msgid "Display the symbols in reverse order." -msgstr "" +msgstr "Вивести символи у зворотному порядку." #: lto/lang.opt:109 #, no-c-format msgid "Dump the details of LTO objects." -msgstr "" +msgstr "Вивести деталі LTO-обʼєктів." #: lto/lang.opt:113 #, no-c-format msgid "Dump the statistics of tree types." -msgstr "" +msgstr "Вивести статистику типів дерев." #: lto/lang.opt:117 #, no-c-format msgid "Dump the statistics of trees." -msgstr "" +msgstr "Вивести статистику дерев." #: lto/lang.opt:121 #, no-c-format msgid "Dump the statistics of gimple statements." -msgstr "" +msgstr "Вивести статистику gimple-виразів." #: lto/lang.opt:131 #, no-c-format msgid "Dump the dump tool command line options." -msgstr "" +msgstr "Вивести параметри командного рядка інструменту dump." #: lto/lang.opt:135 #, no-c-format msgid "Dump the symtab callgraph." -msgstr "" +msgstr "Вивести callgraph symtab." #: common.opt:243 #, no-c-format msgid "Provide bash completion for options starting with provided string." -msgstr "" +msgstr "Надати bash-завершення для параметрів, що починаються з заданого рядка." #: common.opt:295 #, no-c-format msgid "Display this information." -msgstr "" +msgstr "Показувати цю інформацію." #: common.opt:299 #, no-c-format msgid "--help=\tDisplay descriptions of a specific class of options. is one or more of optimizers, target, warnings, undocumented, params." -msgstr "" +msgstr "--help=<клас>\tПоказувати описи для певного класу параметрів. <клас> може бути одним або декількома з оптимізаторів, цілей, попереджень, недокументованих, параметрів." #: common.opt:420 #, no-c-format msgid "Display target specific command line options (including assembler and linker options)." -msgstr "" +msgstr "Показувати специфічні для цілі параметри командного рядка (включаючи опції асемблера та лінкера)." #: common.opt:466 #, no-c-format msgid "-O\tSet optimization level to ." -msgstr "" +msgstr "-O<число>\tВстановити рівень оптимізації на <число>." #: common.opt:470 #, no-c-format msgid "Optimize for space rather than speed." -msgstr "" +msgstr "Оптимізувати під простір, а не під швидкість." #: common.opt:474 #, no-c-format msgid "Optimize for speed disregarding exact standards compliance." -msgstr "" +msgstr "Оптимізувати для швидкості, нехтуючи точним відповіданням стандартам." #: common.opt:478 #, no-c-format msgid "Optimize for debugging experience rather than speed or size." -msgstr "" +msgstr "Оптимізувати для зручності відлагодження, а не для швидкості або розміру." #: common.opt:482 #, no-c-format msgid "Optimize for space aggressively rather than speed." -msgstr "" +msgstr "Оптимізувати для економії місця, агресивно, а не для швидкості." #: common.opt:522 #, no-c-format msgid "This switch is deprecated; use -Wextra instead." -msgstr "" +msgstr "Цей перемикач застарів; використовуйте -Wextra замість нього." #: common.opt:535 #, no-c-format msgid "Warn about returning structures, unions or arrays." -msgstr "" +msgstr "Попереджати про повернення структур, обʼєднань або масивів." #: common.opt:539 #, no-c-format msgid "Warn if a loop with constant number of iterations triggers undefined behavior." -msgstr "" +msgstr "Попереджати, якщо цикл з постійною кількістю ітерацій викликає невизначену поведінку." #: common.opt:546 #, no-c-format msgid "Warn if an array is accessed out of bounds." -msgstr "" +msgstr "Попереджати, якщо здійснюється доступ до масиву за межами його розміру." #: common.opt:550 common.opt:554 #, no-c-format msgid "Warn for uses of pointers to deallocated storage." -msgstr "" +msgstr "Попереджати про використання вказівників на звільнену памʼять." #: common.opt:558 #, no-c-format msgid "Warn about inappropriate attribute usage." -msgstr "" +msgstr "Попереджати про неприпустиме використання атрибутів." #: common.opt:562 #, no-c-format msgid "Do not warn about specified attributes." -msgstr "" +msgstr "Не попереджати про вказані атрибути." #: common.opt:566 common.opt:570 #, no-c-format msgid "Warn about type safety and similar errors and mismatches in declarations with alias attributes." -msgstr "" +msgstr "Попереджати про проблеми з безпекою типів та подібні помилки і несумісності в оголошеннях з атрибутами псевдоніма." #: common.opt:574 #, no-c-format msgid "Warn when profiling instrumentation was requested, but could not be applied to a certain function." -msgstr "" +msgstr "Попереджати, коли запитувалася інструментальна профілювання, але не може бути застосована до певної функції." #: common.opt:579 common.opt:583 #, no-c-format msgid "Warn about pointer casts which increase alignment." -msgstr "" +msgstr "Попереджати про приведення вказівників, які збільшують вирівнювання." #: common.opt:587 #, no-c-format msgid "Complain when a command-line option is valid, but not applicable to the current front end." -msgstr "" +msgstr "Скаржитися, коли командна опція є дійсною, але не застосовується до поточного фронтенду." #: common.opt:591 #, no-c-format msgid "Warn when a #warning directive is encountered." -msgstr "" +msgstr "Попереджати, коли зустрічається директива #warning." #: common.opt:595 #, no-c-format msgid "Warn about uses of __attribute__((warning)) declarations." -msgstr "." +msgstr "Попереджати про використання декларацій з __attribute__((warning))." #: common.opt:599 #, no-c-format msgid "Warn if a deprecated compiler feature, class, method, or field is used." -msgstr "Попереджати щодо використання застарілої можливості компілятора, застарілого класу, методу або поля." +msgstr "Попереджати, якщо використовується застаріла функція компілятора, клас, метод або поле." #: common.opt:603 #, no-c-format msgid "Warn about uses of __attribute__((deprecated)) declarations." -msgstr "" +msgstr "Попереджати про використання декларацій з __attribute__((deprecated))." #: common.opt:607 #, no-c-format msgid "Warn when an optimization pass is disabled." -msgstr "" +msgstr "Попереджати, коли вимкнено прохід оптимізації." #: common.opt:611 #, no-c-format msgid "Treat all warnings as errors." -msgstr "Вважати усі попередження помилками." +msgstr "Трактувати всі попередження як помилки." #: common.opt:615 #, no-c-format msgid "Treat specified warning as error." -msgstr "" +msgstr "Трактувати вказане попередження як помилку." #: common.opt:619 #, no-c-format msgid "Print extra (possibly unwanted) warnings." -msgstr "" +msgstr "Виводити додаткові (можливо, небажані) попередження." #: common.opt:623 #, no-c-format msgid "Exit on the first error occurred." -msgstr "" +msgstr "Вийти при першій виявленій помилці." #: common.opt:627 #, no-c-format msgid "-Wframe-larger-than=\tWarn if a function's stack frame requires in excess of ." -msgstr "" +msgstr "-Wframe-larger-than=<розмір-байтів>\tПопереджати, якщо стековий фрейм функції потребує більше, ніж <розмір-байтів>." #: common.opt:631 #, no-c-format msgid "Disable -Wframe-larger-than= warning. Equivalent to -Wframe-larger-than= or larger." -msgstr "" +msgstr "Вимкнути попередження -Wframe-larger-than=. Еквівалентно -Wframe-larger-than= або більше." #: common.opt:635 #, no-c-format msgid "Warn when attempting to free a non-heap object." -msgstr "" +msgstr "Попереджати, коли намагаєтесь звільнити обʼєкт, який не знаходиться в купі." #: common.opt:646 #, no-c-format msgid "Warn when a switch case falls through." -msgstr "" +msgstr "Попереджати, коли випадок в операторі switch не виконується." #: common.opt:654 #, no-c-format msgid "Warn when an inlined function cannot be inlined." -msgstr "" +msgstr "Попереджати, коли не вдається вбудувати функцію." #: common.opt:658 #, no-c-format msgid "Warn when an atomic memory model parameter is known to be outside the valid range." -msgstr "" +msgstr "Попереджати, коли параметр атомарної моделі памʼяті відомо, що перебуває поза дійсним діапазоном." #: common.opt:665 #, no-c-format msgid "-Wlarger-than=\tWarn if an object's size exceeds ." -msgstr "" +msgstr "-Wlarger-than=<розмір-байтів>\tПопереджати, якщо розмір обʼєкта перевищує <розмір-байтів>." #: common.opt:669 #, no-c-format msgid "Disable -Wlarger-than= warning. Equivalent to -Wlarger-than= or larger." -msgstr "" +msgstr "Вимкнути попередження -Wlarger-than=. Еквівалентно -Wlarger-than= або більше." #: common.opt:673 #, no-c-format msgid "Warn if comparing pointer parameter with nonnull attribute with NULL." -msgstr "" +msgstr "Попереджати, якщо порівнюється вказівниковий параметр з атрибутом nonnull з NULL." #: common.opt:677 #, no-c-format msgid "Warn if dereferencing a NULL pointer may lead to erroneous or undefined behavior." -msgstr "" +msgstr "Попереджати, якщо розіменування NULL-вказівника може призвести до помилкової або невизначеної поведінки." #: common.opt:688 #, no-c-format msgid "Warn about some C++ One Definition Rule violations during link time optimization." -msgstr "" +msgstr "Попереджати про деякі порушення правила однозначного визначення в C++ під час оптимізації часу звʼязування." #: common.opt:692 #, no-c-format msgid "Warn about overflow in arithmetic expressions." -msgstr "" +msgstr "Попереджати про переповнення в арифметичних виразах." #: common.opt:696 #, no-c-format msgid "During link time optimization warn about mismatched types of global declarations." -msgstr "" +msgstr "Попереджати про несумісні типи глобальних оголошень під час оптимізації часу звʼязування." #: common.opt:700 #, no-c-format msgid "Warn when the packed attribute has no effect on struct layout." -msgstr "" +msgstr "Попереджати, коли атрибут packed не має впливу на розташування структури." #: common.opt:704 #, no-c-format msgid "Warn when padding is required to align structure members." -msgstr "" +msgstr "Попереджати, коли потрібне додавання допоміжних байтів для вирівнювання елементів структури." #: common.opt:708 #, no-c-format msgid "Issue warnings needed for strict compliance to the standard." -msgstr "" +msgstr "Видавати попередження, необхідні для строгого дотримання стандарту." #: common.opt:712 #, no-c-format msgid "Warn about returning a pointer/reference to a local or temporary variable." -msgstr "" +msgstr "Попереджати про повернення вказівника/посилання на локальну або тимчасову змінну." #: common.opt:716 #, no-c-format msgid "Warn when one variable shadows another. Same as -Wshadow=global." -msgstr "" +msgstr "Попереджати, коли одна змінна затіняє іншу. Те саме, що й -Wshadow=global." #: common.opt:720 #, no-c-format msgid "Warn when one variable shadows another (globally)." -msgstr "" +msgstr "Попереджати, коли одна змінна затіняє іншу (глобально)." #: common.opt:724 #, no-c-format msgid "Warn when one local variable shadows another local variable or parameter." -msgstr "" +msgstr "Попереджати, коли одна локальна змінна затіняє іншу локальну змінну або параметр." #: common.opt:731 #, no-c-format msgid "Warn when one local variable shadows another local variable or parameter of compatible type." -msgstr "" +msgstr "Попереджати, коли одна локальна змінна затіняє іншу локальну змінну або параметр сумісного типу." #: common.opt:738 #, no-c-format msgid "Warn when not issuing stack smashing protection for some reason." -msgstr "" +msgstr "Попереджати, якщо з якоїсь причини не видається захист від руйнування стеку." #: common.opt:742 #, no-c-format msgid "-Wstack-usage=\tWarn if stack usage might exceed ." -msgstr "" +msgstr "-Wstack-usage=<розмір-байтів>\tПопереджати, якщо використання стеку може перевищувати <розмір-байт>." #: common.opt:746 #, no-c-format msgid "Disable Wstack-usage= warning. Equivalent to Wstack-usage= or larger." -msgstr "" +msgstr "Вимкнути попередження -Wstack-usage=. Еквівалентно -Wstack-usage= або більше." #: common.opt:750 common.opt:754 #, no-c-format msgid "Warn about code which might break strict aliasing rules." -msgstr "" +msgstr "Попереджати про код, який може порушувати правила строгого псевдоніма." #: common.opt:758 common.opt:762 #, no-c-format msgid "Warn about optimizations that assume that signed overflow is undefined." -msgstr "" +msgstr "Попереджати про оптимізації, які припускають, що переповнення знакових чисел є невизначеним." #: common.opt:766 #, no-c-format msgid "Warn about functions which might be candidates for __attribute__((cold))." -msgstr "" +msgstr "Попереджати про функції, які можуть бути кандидатами для __attribute__((cold))." #: common.opt:770 #, no-c-format msgid "Warn about functions which might be candidates for __attribute__((const))." -msgstr "" +msgstr "Попереджати про функції, які можуть бути кандидатами для __attribute__((const))." #: common.opt:774 #, no-c-format msgid "Warn about functions which might be candidates for __attribute__((pure))." -msgstr "" +msgstr "Попереджати про функції, які можуть бути кандидатами на __attribute__((pure))." #: common.opt:778 #, no-c-format msgid "Warn about functions which might be candidates for __attribute__((noreturn))." -msgstr "" +msgstr "Попереджати про функції, які можуть бути кандидатами на __attribute__((noreturn))." #: common.opt:782 #, no-c-format msgid "Warn about functions which might be candidates for __attribute__((malloc))." -msgstr "" +msgstr "Попереджати про функції, які можуть бути кандидатами на __attribute__((malloc))." #: common.opt:786 #, no-c-format msgid "Warn about C++ polymorphic types where adding final keyword would improve code quality." -msgstr "" +msgstr "Попереджати про поліморфні типи C++, де додавання ключового слова final покращило б якість коду." #: common.opt:790 #, no-c-format msgid "Warn about C++ virtual methods where adding final keyword would improve code quality." -msgstr "" +msgstr "Попереджати про віртуальні методи C++, де додавання ключового слова final покращило б якість коду." #: common.opt:794 #, no-c-format msgid "Warn about statements between switch's controlling expression and the first case." -msgstr "" +msgstr "Попереджувати про оператори між виразом управління switch і першим випадком." #: common.opt:799 #, no-c-format msgid "Do not suppress warnings from system headers." -msgstr "" +msgstr "Не пригнічувати попередження з системних заголовків." #: common.opt:803 #, no-c-format msgid "Warn whenever a trampoline is generated." -msgstr "" +msgstr "Попереджувати, коли генерується трамплін." #: common.opt:807 #, no-c-format msgid "Warn about cases where -ftrivial-auto-var-init cannot initialize an auto variable." -msgstr "" +msgstr "Попереджувати про випадки, коли -ftrivial-auto-var-init не може ініціалізувати автоматичну змінну." #: common.opt:811 #, no-c-format msgid "Warn if a comparison is always true or always false due to the limited range of the data type." -msgstr "" +msgstr "Попереджувати, якщо порівняння завжди є істинним або завжди хибним через обмежений діапазон типу даних." #: common.opt:815 #, no-c-format msgid "Warn about uninitialized automatic variables." -msgstr "" +msgstr "Попереджувати про неініціалізовані автоматичні змінні." #: common.opt:819 #, no-c-format msgid "Warn about maybe uninitialized automatic variables." -msgstr "" +msgstr "Попереджувати про можливо неініціалізовані автоматичні змінні." #: common.opt:827 #, no-c-format msgid "Enable all -Wunused- warnings." -msgstr "" +msgstr "Увімкнути всі попередження -Wunused-." #: common.opt:831 #, no-c-format msgid "Warn when a function parameter is only set, otherwise unused." -msgstr "" +msgstr "Попереджувати, коли параметр функції лише встановлюється, а інакше не використовується." #: common.opt:835 #, no-c-format msgid "Warn when a variable is only set, otherwise unused." -msgstr "" +msgstr "Попереджувати, коли змінна лише встановлюється, а інакше не використовується." #: common.opt:839 #, no-c-format msgid "Warn when a function is unused." -msgstr "" +msgstr "Попереджувати, коли функція не використовується." #: common.opt:843 #, no-c-format msgid "Warn when a label is unused." -msgstr "" +msgstr "Попереджувати, коли мітка не використовується." #: common.opt:847 #, no-c-format msgid "Warn when a function parameter is unused." -msgstr "" +msgstr "Попереджувати, коли параметр функції не використовується." #: common.opt:851 #, no-c-format msgid "Warn when an expression value is unused." -msgstr "" +msgstr "Попереджувати, коли значення виразу не використовується." #: common.opt:855 #, no-c-format msgid "Warn when a variable is unused." -msgstr "" +msgstr "Попереджувати, коли змінна не використовується." #: common.opt:859 #, no-c-format msgid "Warn in case profiles in -fprofile-use do not match." -msgstr "" +msgstr "Попереджувати, якщо профілі в -fprofile-use не збігаються." #: common.opt:863 #, no-c-format msgid "Warn in case a function ends earlier than it begins due to an invalid linenum macros." -msgstr "" +msgstr "Попереджувати, якщо функція закінчується раніше, ніж починається через недійсні макроси linenum." #: common.opt:867 #, no-c-format msgid "Warn in case profiles in -fprofile-use do not exist." -msgstr "" +msgstr "Попереджати, якщо профілі в -fprofile-use не існують." #: common.opt:871 #, no-c-format msgid "Warn when a vector operation is compiled outside the SIMD." -msgstr "" +msgstr "Попереджати, коли векторна операція компілюється поза SIMD." #: common.opt:875 #, no-c-format msgid "Warn about unsupported features in ThreadSanitizer." -msgstr "" +msgstr "Попереджати про непідтримувані функції в ThreadSanitizer." #: common.opt:891 #, no-c-format msgid "-aux-info \tEmit declaration information into ." -msgstr "" +msgstr "-aux-info <файл>\tВиводити інформацію про декларації в <файл>." #: common.opt:904 #, no-c-format msgid "-d\tEnable dumps from specific passes of the compiler." -msgstr "" +msgstr "-d<літери>\tУвімкнути вивід дампів з конкретних проходів компілятора." #: common.opt:908 #, no-c-format msgid "-dumpbase \tSet the file basename to be used for dumps." -msgstr "" +msgstr "-dumpbase <файл>\tВстановити базове імʼя файлу для виведення дампів." #: common.opt:912 #, no-c-format msgid "-dumpbase-ext . Drop a trailing . from the dump basename to name auxiliary output files." -msgstr "" +msgstr "-dumpbase-ext . Видалити крапку та розширення . з базового імені дампу, щоб назвати допоміжні вихідні файли." #: common.opt:916 #, no-c-format msgid "-dumpdir \tSet the directory name to be used for dumps." -msgstr "" +msgstr "-dumpdir <каталог>\tВстановити імʼя каталогу, яке буде використовуватися для дампів." #: common.opt:1017 #, no-c-format msgid "The version of the C++ ABI in use." -msgstr "" +msgstr "Версія використовуваного C++ ABI." #: common.opt:1021 #, no-c-format msgid "Aggressively optimize loops using language constraints." -msgstr "" +msgstr "Агресивно оптимізувати цикли з використанням обмежень мови." #: common.opt:1025 #, no-c-format msgid "Align the start of functions." -msgstr "" +msgstr "Вирівняти початок функцій." #: common.opt:1035 #, no-c-format msgid "Align labels which are only reached by jumping." -msgstr "" +msgstr "Вирівняти мітки, до яких можна дістатися лише за допомогою переходів." #: common.opt:1042 #, no-c-format msgid "Align all labels." -msgstr "" +msgstr "Вирівняти всі мітки." #: common.opt:1049 #, no-c-format msgid "Align the start of loops." -msgstr "" +msgstr "Вирівняти початок циклів." #: common.opt:1056 #, no-c-format msgid "Allow the compiler to introduce new data races on stores." -msgstr "" +msgstr "Дозволити компілятору вводити нові гонки даних при зберіганні." #: common.opt:1060 #, no-c-format msgid "Enable static analysis pass." -msgstr "" +msgstr "Увімкнути прохід статичного аналізу." #: common.opt:1080 #, no-c-format msgid "Select what to sanitize." -msgstr "" +msgstr "Вибрати, що очищувати." #: common.opt:1084 #, no-c-format msgid "Select type of coverage sanitization." -msgstr "" +msgstr "Вибрати тип санітизації покриття." #: common.opt:1097 #, no-c-format msgid "-fasan-shadow-offset=\tUse custom shadow memory offset." -msgstr "" +msgstr "-fasan-shadow-offset=<число>\tВикористовуйте власний зсув памʼяті тіні." #: common.opt:1101 #, no-c-format msgid "-fsanitize-sections=\tSanitize global variables in user-defined sections." -msgstr "" +msgstr "-fsanitize-sections=\tСанітизувати глобальні змінні в користувацьких розділах." #: common.opt:1106 #, no-c-format msgid "After diagnosing undefined behavior attempt to continue execution." -msgstr "" +msgstr "Після діагностики невизначеного поведінки спробуйте продовжити виконання." #: common.opt:1110 #, no-c-format msgid "This switch is deprecated; use -fsanitize-recover= instead." -msgstr "" +msgstr "Цей перемикач застарів; використовуйте -fsanitize-recover= замість цього." #: common.opt:1114 #, no-c-format msgid "Use traps instead of diagnostics of undefined behavior sanitizers." -msgstr "" +msgstr "Використовуйте пастки замість діагностики санітизаторів невизначеного поведінки." #: common.opt:1124 -#, fuzzy, no-c-format -#| msgid "This switch is deprecated; use -Werror=implicit-function-declaration instead." +#, no-c-format msgid "This switch is deprecated; use -fsanitize-trap= instead." -msgstr "Цей перемикач вважається застарілим; скористайтеся замість нього перемикачем -Werror=implicit-function-declaration." +msgstr "Цей перемикач застарів; використовуйте -fsanitize-trap= замість цього." #: common.opt:1128 #, no-c-format msgid "Generate unwind tables that are exact at each instruction boundary." -msgstr "" +msgstr "Генерувати таблиці розгортання, які є точними на кожній межі інструкцій." #: common.opt:1132 #, no-c-format msgid "Generate auto-inc/dec instructions." -msgstr "" +msgstr "Генерувати інструкції автоматичного збільшення/зменшення." #: common.opt:1136 #, no-c-format msgid "Use sample profile information for call graph node weights. The default profile file is fbdata.afdo in 'pwd'." -msgstr "" +msgstr "Використовуйте зразкову інформацію про профіль для ваг вузлів графа викликів. Файл профілю за замовчуванням - fbdata.afdo в 'pwd'." #: common.opt:1141 #, no-c-format msgid "Use sample profile information for call graph node weights. The profile file is specified in the argument." -msgstr "" +msgstr "Використовуйте зразкову інформацію про профіль для ваг вузлів графа викликів. Файл профілю вказується в аргументі." #: common.opt:1150 #, no-c-format msgid "Generate code to check bounds before indexing arrays." -msgstr "" +msgstr "Генерувати код для перевірки меж перед індексацією масивів." #: common.opt:1154 #, no-c-format msgid "Replace add, compare, branch with branch on count register." -msgstr "" +msgstr "Замінити додавання, порівняння, гілкування на гілкування за рахунковим регістром." #: common.opt:1158 #, no-c-format msgid "Use profiling information for branch probabilities." -msgstr "" +msgstr "Використовуйте інформацію про профілювання для ймовірностей гілок." #: common.opt:1174 #, no-c-format msgid "Output callgraph information on a per-file basis." -msgstr "" +msgstr "Виведіть інформацію про граф викликів для кожного файлу." #: common.opt:1178 #, no-c-format msgid "Output callgraph information on a per-file basis with decorations." -msgstr "" +msgstr "Виведіть інформацію про граф викликів для кожного файлу з прикрасами." #: common.opt:1182 #, no-c-format msgid "-fcall-saved-\tMark as being preserved across functions." -msgstr "" +msgstr "-fcall-saved-\tПозначити як збережений між функціями." #: common.opt:1186 #, no-c-format msgid "-fcall-used-\tMark as being corrupted by function calls." -msgstr "" +msgstr "-fcall-used-\tПозначити як пошкоджений викликами функцій." #: common.opt:1193 #, no-c-format msgid "Save registers around function calls." -msgstr "" +msgstr "Збережіть регістри навколо викликів функцій." #: common.opt:1197 #, no-c-format msgid "This switch is deprecated; do not use." -msgstr "" +msgstr "Цей перемикач застарілий; не використовуйте його." #: common.opt:1201 #, no-c-format msgid "Check the return value of new in C++." -msgstr "Перевіряти повернуте значення new у C++." +msgstr "Перевірте значення, що повертається, у new в C++." #: common.opt:1205 common.opt:1209 #, no-c-format msgid "Perform internal consistency checkings." -msgstr "Виконувати внутрішні перевірки сумісності." +msgstr "Виконувати внутрішні перевірки на відповідність." #: common.opt:1213 #, no-c-format msgid "For -f*-prefix-map= options compare canonicalized pathnames rather than just strings." -msgstr "" +msgstr "Для параметрів -f*-prefix-map= порівнюйте канонізовані шляхи, а не просто рядки." #: common.opt:1217 #, no-c-format @@ -13575,2147 +13549,2147 @@ msgstr "Увімкнути підняття коду." #: common.opt:1221 #, no-c-format msgid "Looks for opportunities to reduce stack adjustments and stack references." -msgstr "" +msgstr "Шукає можливості зменшити коригування стеку та посилання на стек." #: common.opt:1225 #, no-c-format msgid "Put uninitialized globals in the common section." -msgstr "" +msgstr "Розмістіть незавершені глобальні змінні в загальному розділі." #: common.opt:1233 #, no-c-format msgid "-fcompare-debug[=]\tCompile with and without e.g. -gtoggle, and compare the final-insns dump." -msgstr "" +msgstr "-fcompare-debug[=]\tКомпілювати з і без, наприклад, -gtoggle, і порівнювати вихідний дамп final-insns." #: common.opt:1237 #, no-c-format msgid "Run only the second compilation of -fcompare-debug." -msgstr "" +msgstr "Виконати лише другу компіляцію з -fcompare-debug." #: common.opt:1241 #, no-c-format msgid "Perform comparison elimination after register allocation has finished." -msgstr "" +msgstr "Виконати усунення порівнянь після завершення розподілу реєстрів." #: common.opt:1245 #, no-c-format msgid "Do not perform optimizations increasing noticeably stack usage." -msgstr "" +msgstr "Не виконувати оптимізації, які помітно збільшують використання стеку." #: common.opt:1249 #, no-c-format msgid "Perform a register copy-propagation optimization pass." -msgstr "" +msgstr "Виконати оптимізацію копіювання реєстру." #: common.opt:1253 #, no-c-format msgid "Perform cross-jumping optimization." -msgstr "" +msgstr "Виконати оптимізацію перехрестних стрибків." #: common.opt:1257 #, no-c-format msgid "When running CSE, follow jumps to their targets." -msgstr "" +msgstr "При виконанні CSE слідкуйте за стрибками до їх цілей." #: common.opt:1265 #, no-c-format msgid "Omit range reduction step when performing complex division." -msgstr "" +msgstr "Пропустити крок зменшення діапазону при виконанні складної ділення." #: common.opt:1269 #, no-c-format msgid "Complex multiplication and division follow Fortran rules." -msgstr "" +msgstr "Множення та ділення комплексних чисел відповідають правилам Fortran." #: common.opt:1273 #, no-c-format msgid "Place data items into their own section." -msgstr "" +msgstr "Розмістити елементи даних у власному розділі." #: common.opt:1277 #, no-c-format msgid "List all available debugging counters with their limits and counts." -msgstr "" +msgstr "Вивести список всіх доступних лічильників відлагодження з їх обмеженнями та значеннями." #: common.opt:1281 #, no-c-format msgid "-fdbg-cnt=[:-][:-:...][,:...]\tSet the debug counter limit." -msgstr "" +msgstr "-fdbg-cnt=<лічильник>[:<нижня_межа1>-]<верхня_межа1>[:<нижня_межа2>-<верхня_межа2>:...][,<лічильник>:...]\tВстановити обмеження для лічильника відлагодження." #: common.opt:1285 #, no-c-format msgid "-fdebug-prefix-map==\tMap one directory name to another in debug information." -msgstr "" +msgstr "-fdebug-prefix-map=<старий>=<новий>\tВідображення одного імені каталогу на інше в інформації для налагодження." #: common.opt:1289 #, no-c-format msgid "-ffile-prefix-map==\tMap one directory name to another in compilation result." -msgstr "" +msgstr "-ffile-prefix-map=<старий>=<новий>\tВідображення одного імені каталогу на інше в результаті компіляції." #: common.opt:1293 #, no-c-format msgid "Output .debug_types section when using DWARF v4 debuginfo." -msgstr "" +msgstr "Виводити розділ .debug_types при використанні відлагоджувальної інформації DWARF v4." #: common.opt:1299 #, no-c-format msgid "Defer popping functions args from stack until later." -msgstr "" +msgstr "Відкласти видалення аргументів функцій зі стеку до пізнішого часу." #: common.opt:1303 #, no-c-format msgid "Attempt to fill delay slots of branch instructions." -msgstr "" +msgstr "Спроба заповнити слоти затримки інструкцій гілок." #: common.opt:1307 #, no-c-format msgid "Delete dead instructions that may throw exceptions." -msgstr "" +msgstr "Видаляти мертві інструкції, які можуть викликати винятки." #: common.opt:1311 #, no-c-format msgid "Delete useless null pointer checks." -msgstr "" +msgstr "Видалити непотрібні перевірки нульових вказівників." #: common.opt:1315 #, no-c-format msgid "Stream extra data to support more aggressive devirtualization in LTO local transformation mode." -msgstr "" +msgstr "Потокова передача додаткових даних для підтримки більш агресивної девіртуалізації в режимі локальної трансформації LTO." #: common.opt:1319 #, no-c-format msgid "Perform speculative devirtualization." -msgstr "" +msgstr "Виконувати спекулятивну девіртуалізацію." #: common.opt:1323 #, no-c-format msgid "Try to convert virtual calls to direct ones." -msgstr "" +msgstr "Спробуйте перетворити віртуальні виклики на прямі." #: common.opt:1327 #, no-c-format msgid "-fdiagnostics-show-location=[once|every-line]\tHow often to emit source location at the beginning of line-wrapped diagnostics." -msgstr "" +msgstr "-fdiagnostics-show-location=[once|every-line]\tЯк часто виводити початкове розташування джерела на початку діагностики, обгорнутої по рядках." #: common.opt:1344 #, no-c-format msgid "Show the source line with a caret indicating the column." -msgstr "" +msgstr "Показати рядок джерела з вказівником на стовпчик." #: common.opt:1348 #, no-c-format msgid "Show labels annotating ranges of source code when showing source." -msgstr "" +msgstr "Показати мітки, що анотують діапазони вихідного коду при показі джерела." #: common.opt:1352 #, no-c-format msgid "Show line numbers in the left margin when showing source." -msgstr "" +msgstr "Показати номери рядків у лівому полі, коли показується джерело." #: common.opt:1360 #, no-c-format msgid "-fdiagnostics-color=[never|always|auto]\tColorize diagnostics." -msgstr "" +msgstr "-fdiagnostics-color=[never|always|auto]\tКолірувати діагностику." #: common.opt:1380 #, no-c-format msgid "-fdiagnostics-urls=[never|always|auto]\tEmbed URLs in diagnostics." -msgstr "" +msgstr "-fdiagnostics-urls=[never|always|auto]\tВбудовувати URL-адреси в діагностику." #: common.opt:1400 #, no-c-format msgid "-fdiagnostics-column-unit=[display|byte]\tSelect whether column numbers are output as display columns (default) or raw bytes." -msgstr "" +msgstr "-fdiagnostics-column-unit=[display|byte]\tВибрати, чи виводити номери стовпців як стовпці відображення (за замовчуванням) або як сирі байти." #: common.opt:1404 #, no-c-format msgid "-fdiagnostics-column-origin=\tSet the number of the first column. The default is 1-based as per GNU style, but some utilities may expect 0-based, for example." -msgstr "" +msgstr "-fdiagnostics-column-origin=<число>\tВстановити номер першого стовпця. За замовчуванням використовується нумерація з 1 відповідно до стилю GNU, але деякі утиліти можуть очікувати нумерацію з 0, наприклад." #: common.opt:1408 #, no-c-format msgid "-fdiagnostics-format=[text|sarif-stderr|sarif-file|json|json-stderr|json-file]\tSelect output format." -msgstr "" +msgstr "-fdiagnostics-format=[текст|sarif-stderr|sarif-file|json|json-stderr|json-file]\tВибрати формат виводу." #: common.opt:1412 #, no-c-format msgid "-fdiagnostics-escape-format=[unicode|bytes]\tSelect how to escape non-printable-ASCII bytes in the source for diagnostics that suggest it." -msgstr "" +msgstr "-fdiagnostics-escape-format=[unicode|bytes]\tВибрати, як екранувати не друковані ASCII-байти у вихідному коді для діагностики, яка це пропонує." #: common.opt:1459 #, no-c-format msgid "Print fix-it hints in machine-readable form." -msgstr "" +msgstr "Вивести підказки для виправлення у машинночитаному форматі." #: common.opt:1463 #, no-c-format msgid "Print fix-it hints to stderr in unified diff format." -msgstr "" +msgstr "Вивести підказки для виправлення на stderr у форматі обʼєднаного diff." #: common.opt:1467 #, no-c-format msgid "Amend appropriate diagnostic messages with the command line option that controls them." -msgstr "" +msgstr "Виправити відповідні діагностичні повідомлення з параметром командного рядка, який їх контролює." #: common.opt:1471 #, no-c-format msgid "Print CWE identifiers for diagnostic messages, where available." -msgstr "" +msgstr "Вивести ідентифікатори CWE для діагностичних повідомлень, якщо вони доступні." #: common.opt:1475 #, no-c-format msgid "Print any rules associated with diagnostic messages." -msgstr "" +msgstr "Вивести будь-які правила, повʼязані з діагностичними повідомленнями." #: common.opt:1479 #, no-c-format msgid "Specify how to print any control-flow path associated with a diagnostic." -msgstr "" +msgstr "Вказати, як друкувати будь-який шлях керування потоком, повʼязаний з діагностикою." #: common.opt:1483 #, no-c-format msgid "Turn off any diagnostics features that complicate the output, such as line numbers, color, and warning URLs." -msgstr "" +msgstr "Вимкнути будь-які функції діагностики, які ускладнюють вивід, такі як номери рядків, кольори та URL-адреси попереджень." #: common.opt:1487 #, no-c-format msgid "-ftabstop= Distance between tab stops for column reporting." -msgstr "" +msgstr "-ftabstop=<число> Відстань між табуляціями для звітування про стовпці." #: common.opt:1503 #, no-c-format msgid "Show stack depths of events in paths." -msgstr "" +msgstr "Показати глибину стеку подій у шляхах." #: common.opt:1507 #, no-c-format msgid "Set minimum width of left margin of source code when showing source." -msgstr "" +msgstr "Встановити мінімальну ширину лівого поля вихідного коду при показуванні джерела." #: common.opt:1511 #, no-c-format msgid "-fdisable-[tree|rtl|ipa]-=range1+range2\tDisable an optimization pass." -msgstr "" +msgstr "-fdisable-[tree|rtl|ipa]-<прохід>=діапазон1+діапазон2\tВимкнути прохід оптимізації." #: common.opt:1515 #, no-c-format msgid "-fenable-[tree|rtl|ipa]-=range1+range2\tEnable an optimization pass." -msgstr "" +msgstr "-fenable-[tree|rtl|ipa]-<прохід>=діапазон1+діапазон2\tУвімкнути прохід оптимізації." #: common.opt:1519 #, no-c-format msgid "-fdump-\tDump various compiler internals to a file." -msgstr "" +msgstr "-fdump-<тип>\tЗберегти різні внутрішні компілятора дані у файл." #: common.opt:1526 #, no-c-format msgid "-fdump-final-insns=filename\tDump to filename the insns at the end of translation." -msgstr "" +msgstr "-fdump-final-insns=<імʼя_файлу>\tЗберегти вказані інструкції в кінці перекладу у файл." #: common.opt:1530 #, no-c-format msgid "-fdump-go-spec=filename\tWrite all declarations to file as Go code." -msgstr "" +msgstr "-fdump-go-spec=<імʼя_файлу>\tЗаписати всі оголошення у файл у вигляді коду Go." #: common.opt:1534 #, no-c-format msgid "Suppress output of addresses in debugging dumps." -msgstr "" +msgstr "Приховати вивід адрес у відлагоджувальних дампах." #: common.opt:1538 #, no-c-format msgid "Collect and dump debug information into temporary file if ICE in C/C++ compiler occurred." -msgstr "" +msgstr "Збирати та виводити відлагоджувальну інформацію у тимчасовий файл, якщо виникла внутрішня помилка у компіляторі C/C++." #: common.opt:1543 #, no-c-format msgid "Dump detailed information on GCC's internal representation of source code locations." -msgstr "" +msgstr "Вивести детальну інформацію про внутрішнє представлення GCC місцезнаходження вихідного коду." #: common.opt:1547 #, no-c-format msgid "Dump optimization passes." -msgstr "" +msgstr "Вивести проходи оптимізації." #: common.opt:1551 #, no-c-format msgid "Suppress output of instruction numbers, line number notes and addresses in debugging dumps." -msgstr "" +msgstr "Приховати вивід номерів інструкцій, приміток з номерами рядків та адрес у відлагоджувальних дампах." #: common.opt:1555 #, no-c-format msgid "Suppress output of previous and next insn numbers in debugging dumps." -msgstr "" +msgstr "Приховати вивід номерів попередніх та наступних інструкцій у відлагоджувальних дампах." #: common.opt:1559 #, no-c-format msgid "Enable CFI tables via GAS assembler directives." -msgstr "" +msgstr "Увімкнути таблиці CFI за допомогою директив асемблера GAS." #: common.opt:1563 #, no-c-format msgid "Perform early inlining." -msgstr "" +msgstr "Виконати раннє вбудовування." #: common.opt:1571 #, no-c-format msgid "Perform interprocedural reduction of aggregates." -msgstr "" +msgstr "Виконати міжпроцедурну редукцію агрегатів." #: common.opt:1575 #, no-c-format msgid "Perform unused symbol elimination in debug info." -msgstr "" +msgstr "Виконати видалення невикористаних символів у відлагоджувальній інформації." #: common.opt:1579 #, no-c-format msgid "Perform unused type elimination in debug info." -msgstr "" +msgstr "Виконати видалення невикористаних типів у відлагоджувальній інформації." #: common.opt:1583 #, no-c-format msgid "Do not suppress C++ class debug information." -msgstr "" +msgstr "Не приховувати відлагоджувальну інформацію про класи C++." #: common.opt:1587 #, no-c-format msgid "Enable exception handling." -msgstr "" +msgstr "Увімкнути обробку винятків." #: common.opt:1591 #, no-c-format msgid "Perform a number of minor, expensive optimizations." -msgstr "" +msgstr "Виконати кілька незначних, дорогих оптимізацій." #: common.opt:1595 #, no-c-format msgid "-fexcess-precision=[fast|standard|16]\tSpecify handling of excess floating-point precision." -msgstr "" +msgstr "-fexcess-precision=[fast|standard|16]\tВказати обробку зайвої точності з плаваючою комою." #: common.opt:1613 #, no-c-format msgid "-fpermitted-flt-eval-methods=[c11|ts-18661]\tSpecify which values of FLT_EVAL_METHOD are permitted." -msgstr "" +msgstr "-fpermitted-flt-eval-methods=[c11|ts-18661]\tВказати, які значення FLT_EVAL_METHOD дозволені." #: common.opt:1629 #, no-c-format msgid "Output lto objects containing both the intermediate language and binary output." -msgstr "" +msgstr "Вивести обʼєкти lto, що містять як проміжну мову, так і бінарний вихід." #: common.opt:1633 #, no-c-format msgid "Assume no NaNs or infinities are generated." -msgstr "" +msgstr "Припускати, що NaN або нескінченності не генеруються." #: common.opt:1637 #, no-c-format msgid "Assume that loops with an exit will terminate and not loop indefinitely." -msgstr "" +msgstr "Припускати, що цикли з виходом завершаться і не будуть безкінечно повторюватися." #: common.opt:1641 #, no-c-format msgid "-ffixed-\tMark as being unavailable to the compiler." -msgstr "" +msgstr "-ffixed-<регістр>\tПозначити <регістр> як недоступний для компілятора." #: common.opt:1645 #, no-c-format msgid "Don't allocate floats and doubles in extended-precision registers." -msgstr "" +msgstr "Не виділяти плаваючі точки і подвійні в розширених регістрах точності." #: common.opt:1653 #, no-c-format msgid "Perform a forward propagation pass on RTL." -msgstr "" +msgstr "Виконати прохід вперед по RTL." #: common.opt:1657 #, no-c-format msgid "-ffp-contract=[off|on|fast]\tPerform floating-point expression contraction." -msgstr "" +msgstr "-ffp-contract=[off|on|fast]\tВиконати скорочення виразів з плаваючою комою." #: common.opt:1674 #, no-c-format msgid "Allow built-in functions ceil, floor, round, trunc to raise \"inexact\" exceptions." -msgstr "" +msgstr "Дозволити вбудованим функціям ceil, floor, round, trunc викликати винятки «неточності»." #: common.opt:1681 #, no-c-format msgid "Allow function addresses to be held in registers." -msgstr "" +msgstr "Дозволити зберігати адреси функцій у регістрах." #: common.opt:1685 #, no-c-format msgid "Place each function into its own section." -msgstr "" +msgstr "Розміщувати кожну функцію в власному розділі." #: common.opt:1689 #, no-c-format msgid "Perform global common subexpression elimination." -msgstr "" +msgstr "Виконувати глобальну елімінацію спільних підвиразів." #: common.opt:1693 #, no-c-format msgid "Perform enhanced load motion during global common subexpression elimination." -msgstr "" +msgstr "Виконувати покращене переміщення завантажень під час глобальної елімінації спільних підвиразів." #: common.opt:1697 #, no-c-format msgid "Perform store motion after global common subexpression elimination." -msgstr "" +msgstr "Виконувати переміщення збереження після глобальної елімінації спільних підвиразів." #: common.opt:1701 #, no-c-format msgid "Perform redundant load after store elimination in global common subexpression elimination." -msgstr "" +msgstr "Виконати зайве завантаження після усунення збереження в глобальному спільному підвиразі." #: common.opt:1706 #, no-c-format msgid "Perform global common subexpression elimination after register allocation has finished." -msgstr "" +msgstr "Виконати глобальну елімінацію спільних підвиразів після завершення розподілу регістрів." #: common.opt:1723 #, no-c-format msgid "-fgnat-encodings=[all|gdb|minimal]\tSelect the balance between GNAT encodings and standard DWARF emitted in the debug information." -msgstr "" +msgstr "-fgnat-encodings=[all|gdb|minimal]\tВиберіть баланс між кодуваннями GNAT та стандартним DWARF, які випускаються в інформації для налагодження." #: common.opt:1728 #, no-c-format msgid "Enable in and out of Graphite representation." -msgstr "" +msgstr "Увімкнути вхід та вихід з представлення Graphite." #: common.opt:1732 #, no-c-format msgid "Enable Graphite Identity transformation." -msgstr "" +msgstr "Увімкнути перетворення ідентичності Graphite." #: common.opt:1736 #, no-c-format msgid "Enable hoisting adjacent loads to encourage generating conditional move instructions." -msgstr "" +msgstr "Увімкнути підняття суміжних завантажень, щоб сприяти генерації умовних інструкцій переміщення." #: common.opt:1745 #, no-c-format msgid "Improve GCC's ability to track column numbers in large source files, at the expense of slower compilation." -msgstr "" +msgstr "Покращити здатність GCC відстежувати номери стовпців у великих вихідних файлах за рахунок повільнішої компіляції." #: common.opt:1750 #, no-c-format msgid "Mark all loops as parallel." -msgstr "" +msgstr "Позначити всі цикли як паралельні." #: common.opt:1754 common.opt:1762 common.opt:2979 #, no-c-format msgid "Enable loop nest transforms. Same as -floop-nest-optimize." -msgstr "" +msgstr "Увімкнути перетворення вкладених циклів. Те саме, що й -floop-nest-optimize." #: common.opt:1758 #, no-c-format msgid "Enable loop interchange on trees." -msgstr "" +msgstr "Увімкнути обмін циклів на деревах." #: common.opt:1766 #, no-c-format msgid "Perform unroll-and-jam on loops." -msgstr "" +msgstr "Виконати розгортання і злиття циклів." #: common.opt:1770 #, no-c-format msgid "Enable support for GNU transactional memory." -msgstr "" +msgstr "Увімкнути підтримку GNU транзакційної памʼяті." #: common.opt:1774 #, no-c-format msgid "Use STB_GNU_UNIQUE if supported by the assembler." -msgstr "" +msgstr "Використовуйте STB_GNU_UNIQUE, якщо підтримується збирачем." #: common.opt:1782 #, no-c-format msgid "Enable the loop nest optimizer." -msgstr "" +msgstr "Увімкнути оптимізатор вкладених циклів." #: common.opt:1786 #, no-c-format msgid "Force bitfield accesses to match their type width." -msgstr "" +msgstr "Примусово зробити доступ до бітових полів такими ж ширинами, як їх типи." #: common.opt:1790 #, no-c-format msgid "Merge adjacent stores." -msgstr "" +msgstr "Обʼєднати суміжні зберігання." #: common.opt:1794 #, no-c-format msgid "Enable guessing of branch probabilities." -msgstr "" +msgstr "Увімкнути вгадування ймовірностей гілок." #: common.opt:1798 #, no-c-format msgid "Harden conditionals not used in branches, checking reversed conditions." -msgstr "" +msgstr "Посилити умови, які не використовуються в гілках, перевіряючи зворотні умови." #: common.opt:1802 #, no-c-format msgid "Harden conditional branches by checking reversed conditions." -msgstr "" +msgstr "Посилити умовні гілки, перевіряючи зворотні умови." #: common.opt:1810 #, no-c-format msgid "Process #ident directives." -msgstr "" +msgstr "Обробка директив #ident." #: common.opt:1814 #, no-c-format msgid "Perform conversion of conditional jumps to branchless equivalents." -msgstr "" +msgstr "Виконати перетворення умовних переходів на еквіваленти без гілок." #: common.opt:1818 #, no-c-format msgid "Perform conversion of conditional jumps to conditional execution." -msgstr "" +msgstr "Виконати перетворення умовних переходів на умовне виконання." #: common.opt:1822 #, no-c-format msgid "-fstack-reuse=[all|named_vars|none]\tSet stack reuse level for local variables." -msgstr "" +msgstr "-fstack-reuse=[all|named_vars|none]\tВстановити рівень повторного використання стеку для локальних змінних." #: common.opt:1838 #, no-c-format msgid "Convert conditional jumps in innermost loops to branchless equivalents." -msgstr "" +msgstr "Перетворити умовні переходи в найвнутрішніших циклах на еквіваленти без гілок." #: common.opt:1850 #, no-c-format msgid "Do not generate .size directives." -msgstr "" +msgstr "Не генерувати директиви .size." #: common.opt:1854 #, no-c-format msgid "Perform indirect inlining." -msgstr "" +msgstr "Виконувати непряму вставку." #: common.opt:1860 #, no-c-format msgid "Enable inlining of function declared \"inline\", disabling disables all inlining." -msgstr "" +msgstr "Увімкнути вбудовування функції, оголошеної як «inline», вимкнення вимикає всі вбудовування." #: common.opt:1864 #, no-c-format msgid "Integrate functions into their callers when code size is known not to grow." -msgstr "" +msgstr "Інтегрувати функції в їх викликачів, коли розмір коду відомо, що не зростає." #: common.opt:1868 #, no-c-format msgid "Integrate functions not declared \"inline\" into their callers when profitable." -msgstr "" +msgstr "Інтегрувати функції, не оголошені як «inline», в їх викликачів, коли це прибутково." #: common.opt:1872 #, no-c-format msgid "Integrate functions only required by their single caller." -msgstr "" +msgstr "Інтегруйте функції, які потрібні лише їх єдиному викликачу." #: common.opt:1879 #, no-c-format msgid "-finline-limit=\tLimit the size of inlined functions to ." -msgstr "" +msgstr "-finline-limit=<число>\tОбмежте розмір вбудованих функцій до <число>." #: common.opt:1883 #, no-c-format msgid "Inline __atomic operations when a lock free instruction sequence is available." -msgstr "" +msgstr "Вбудовувати операції __atomic, коли є послідовність без блокування." #: common.opt:1890 #, no-c-format msgid "-fcf-protection=[full|branch|return|none|check]\tInstrument functions with checks to verify jump/call/return control-flow transfer instructions have valid targets." -msgstr "" +msgstr "-fcf-protection=[full|branch|return|none|check]\tІнструменти функцій з перевірками для перевірки того, що інструкції переходу/виклику/повернення мають дійсні цілі." #: common.opt:1913 #, no-c-format msgid "Instrument function entry and exit with profiling calls." -msgstr "" +msgstr "Інструментувати вхід та вихід функції з дзвінками профілювання." #: common.opt:1917 #, no-c-format msgid "Instrument function entry and exit with profiling calls invoked once." -msgstr "" +msgstr "Інструментувати вхід та вихід функції з одноразовими дзвінками профілювання." #: common.opt:1921 #, no-c-format msgid "-finstrument-functions-exclude-function-list=name,...\tDo not instrument listed functions." -msgstr "" +msgstr "-finstrument-functions-exclude-function-list=імʼя,...\tНе інструментувати перелічовані функції." #: common.opt:1925 #, no-c-format msgid "-finstrument-functions-exclude-file-list=filename,...\tDo not instrument functions listed in files." -msgstr "" +msgstr "-finstrument-functions-exclude-file-list=імʼя_файлу,...\tНе інструментувати функції, перелічовані у файлах." #: common.opt:1929 #, no-c-format msgid "Perform interprocedural constant propagation." -msgstr "" +msgstr "Виконати міжпроцедурну поширення констант." #: common.opt:1933 #, no-c-format msgid "Perform cloning to make Interprocedural constant propagation stronger." -msgstr "" +msgstr "Виконати клонування для зміцнення міжпроцедурного поширення констант." #: common.opt:1941 #, no-c-format msgid "Perform interprocedural bitwise constant propagation." -msgstr "" +msgstr "Виконати міжпроцедурне поширення констант за допомогою побітових операцій." #: common.opt:1945 #, no-c-format msgid "Perform interprocedural modref analysis." -msgstr "" +msgstr "Виконати міжпроцедурний аналіз модифікацій та посилань." #: common.opt:1949 #, no-c-format msgid "Perform interprocedural profile propagation." -msgstr "" +msgstr "Виконати міжпроцедурне поширення профілів." #: common.opt:1953 #, no-c-format msgid "Perform interprocedural points-to analysis." -msgstr "" +msgstr "Виконати міжпроцедурний аналіз вказівників та посилань." #: common.opt:1957 #, no-c-format msgid "Discover pure and const functions." -msgstr "" +msgstr "Виявити чисті та константні функції." #: common.opt:1961 #, no-c-format msgid "Perform Identical Code Folding for functions and read-only variables." -msgstr "" +msgstr "Виконати згортання ідентичного коду для функцій та змінних, доступних тільки для читання." #: common.opt:1965 #, no-c-format msgid "Perform Identical Code Folding for functions." -msgstr "" +msgstr "Виконати згортання ідентичного коду для функцій." #: common.opt:1969 #, no-c-format msgid "Perform Identical Code Folding for variables." -msgstr "" +msgstr "Виконати згортання ідентичного коду для змінних." #: common.opt:1973 #, no-c-format msgid "Discover read-only and non addressable static variables." -msgstr "" +msgstr "Виявити змінні, доступні тільки для читання та недоступні для адресації." #: common.opt:1977 #, no-c-format msgid "Discover read-only, write-only and non-addressable static variables." -msgstr "" +msgstr "Виявити змінні, доступні тільки для читання, тільки для запису та недоступні для адресації." #: common.opt:1981 #, no-c-format msgid "Reduce stack alignment on call sites if possible." -msgstr "" +msgstr "Зменшити вирівнювання стеку на місцях виклику, якщо це можливо." #: common.opt:1993 #, no-c-format msgid "Perform IPA Value Range Propagation." -msgstr "" +msgstr "Виконати поширення діапазону значень IPA." #: common.opt:1997 #, no-c-format msgid "-fira-algorithm=[CB|priority]\tSet the used IRA algorithm." -msgstr "" +msgstr "-fira-algorithm=[CB|priority]\tВстановити використовуваний алгоритм IRA." #: common.opt:2001 #, no-c-format msgid "Assume strict aliasing rules apply across (uninlined) function boundaries." -msgstr "" +msgstr "Припустити, що суворі правила псевдонімів застосовуються між межами функцій (не вбудованих)." #: common.opt:2014 #, no-c-format msgid "-fira-region=[one|all|mixed]\tSet regions for IRA." -msgstr "" +msgstr "-fira-region=[one|all|mixed]\tВстановити регіони для IRA." #: common.opt:2030 #, no-c-format msgid "Use IRA based register pressure calculation in RTL hoist optimizations." -msgstr "" +msgstr "Використовувати IRA-заснований розрахунок тиску на реєстри в оптимізаціях підняття RTL." #: common.opt:2035 #, no-c-format msgid "Use IRA based register pressure calculation in RTL loop optimizations." -msgstr "" +msgstr "Використовуйте розрахунок тиску на реєстр на основі IRA в оптимізаціях циклів RTL." #: common.opt:2040 #, no-c-format msgid "Share slots for saving different hard registers." -msgstr "" +msgstr "Поділитися слотами для збереження різних жорстких регістрів." #: common.opt:2044 #, no-c-format msgid "Share stack slots for spilled pseudo-registers." -msgstr "" +msgstr "Поділитися слотами стеку для витікших псевдо-регістрів." #: common.opt:2048 #, no-c-format msgid "-fira-verbose=\tControl IRA's level of diagnostic messages." -msgstr "" +msgstr "-fira-verbose=<число>\tКонтролювати рівень діагностичних повідомлень IRA." #: common.opt:2052 #, no-c-format msgid "Optimize induction variables on trees." -msgstr "" +msgstr "Оптимізувати змінні індукції на деревах." #: common.opt:2056 #, no-c-format msgid "Use jump tables for sufficiently large switch statements." -msgstr "" +msgstr "Використовувати таблиці переходів для достатньо великих операторів вибору." #: common.opt:2060 #, no-c-format msgid "Use bit tests for sufficiently large switch statements." -msgstr "" +msgstr "Використовувати бітові тести для достатньо великих операторів вибору." #: common.opt:2064 #, no-c-format msgid "Generate code for functions even if they are fully inlined." -msgstr "" +msgstr "Генерувати код для функцій навіть якщо вони повністю вбудовані." #: common.opt:2068 #, no-c-format msgid "Generate code for static functions even if they are never called." -msgstr "" +msgstr "Генерувати код для статичних функцій навіть якщо вони ніколи не викликаються." #: common.opt:2072 #, no-c-format msgid "Emit static const variables even if they are not used." -msgstr "" +msgstr "Видавати статичні константні змінні навіть якщо вони не використовуються." #: common.opt:2076 #, no-c-format msgid "Give external symbols a leading underscore." -msgstr "" +msgstr "Додати перед зовнішніми символами підкреслення." #: common.opt:2084 #, no-c-format msgid "Do CFG-sensitive rematerialization in LRA." -msgstr "" +msgstr "Виконувати CFG-чутливу перематеріалізацію в LRA." #: common.opt:2088 #, no-c-format msgid "Enable link-time optimization." -msgstr "" +msgstr "Увімкнути оптимізацію на етапі звʼязування." #: common.opt:2092 #, no-c-format msgid "Link-time optimization with number of parallel jobs or jobserver." -msgstr "" +msgstr "Оптимізація на етапі звʼязування з кількістю паралельних задач або сервером задач." #: common.opt:2114 #, no-c-format msgid "Specify the algorithm to partition symbols and vars at linktime." -msgstr "" +msgstr "Вказати алгоритм для розбиття символів та змінних на етапі звʼязування." #: common.opt:2119 #, no-c-format msgid "Use zlib/zstd compression level for IL." -msgstr "" +msgstr "Використовуйте рівень стиснення zlib/zstd <число> для IL." #: common.opt:2127 #, no-c-format msgid "Report various link-time optimization statistics." -msgstr "" +msgstr "Повідомляти різні статистичні дані про оптимізацію на етапі звʼязування." #: common.opt:2131 #, no-c-format msgid "Report various link-time optimization statistics for WPA only." -msgstr "" +msgstr "Повідомляти різні статистичні дані про оптимізацію на етапі звʼязування тільки для WPA." #: common.opt:2135 #, no-c-format msgid "Set errno after built-in math functions." -msgstr "" +msgstr "Встановити errno після вбудованих математичних функцій." #: common.opt:2139 #, no-c-format msgid "-fmax-errors=\tMaximum number of errors to report." -msgstr "" +msgstr "-fmax-errors=<кількість>\tМаксимальна кількість помилок для звіту." #: common.opt:2143 #, no-c-format msgid "Report on permanent memory allocation." -msgstr "" +msgstr "Звіт про постійне виділення памʼяті." #: common.opt:2147 #, no-c-format msgid "Report on permanent memory allocation in WPA only." -msgstr "" +msgstr "Звіт про постійне виділення памʼяті тільки в режимі WPA." #: common.opt:2154 #, no-c-format msgid "Attempt to merge identical constants and constant variables." -msgstr "" +msgstr "Спроба обʼєднати однакові константи та константні змінні." #: common.opt:2158 #, no-c-format msgid "Attempt to merge identical constants across compilation units." -msgstr "" +msgstr "Спроба обʼєднати однакові константи між компіляційними одиницями." #: common.opt:2162 #, no-c-format msgid "Attempt to merge identical debug strings across compilation units." -msgstr "" +msgstr "Спроба обʼєднати однакові рядки для налагодження між компіляційними одиницями." #: common.opt:2166 #, no-c-format msgid "-fmessage-length=\tLimit diagnostics to characters per line. 0 suppresses line-wrapping." -msgstr "" +msgstr "-fmessage-length=<кількість>\tОбмежити діагностику до <кількості> символів на рядок. 0 пригнічує перенесення рядків." #: common.opt:2170 #, no-c-format msgid "Perform SMS based modulo scheduling before the first scheduling pass." -msgstr "" +msgstr "Виконати модульне планування на основі SMS перед першим проходом планування." #: common.opt:2174 #, no-c-format msgid "Perform SMS based modulo scheduling with register moves allowed." -msgstr "" +msgstr "Виконати модульне планування на основі SMS з дозволеними переміщеннями регістрів." #: common.opt:2178 #, no-c-format msgid "Move loop invariant computations out of loops." -msgstr "" +msgstr "Перемістити обчислення незмінних у петлях за межі петель." #: common.opt:2182 #, no-c-format msgid "Move stores out of loops." -msgstr "" +msgstr "Перемістити зберігання за межі петель." #: common.opt:2186 #, no-c-format msgid "Building block for specs-based multilib-aware TFLAGS." -msgstr "" +msgstr "Будівельний блок для TFLAGS, що підтримує специфікації та багатобібліотечність." #: common.opt:2190 #, no-c-format msgid "Use the RTL dead code elimination pass." -msgstr "" +msgstr "Використовувати прохід RTL для видалення мертвого коду." #: common.opt:2194 #, no-c-format msgid "Use the RTL dead store elimination pass." -msgstr "" +msgstr "Використовувати прохід RTL для видалення мертвих зберігань." #: common.opt:2198 #, no-c-format msgid "Enable/Disable the traditional scheduling in loops that already passed modulo scheduling." -msgstr "" +msgstr "Увімкнути/вимкнути традиційне планування в петлях, які вже пройшли модульне планування." #: common.opt:2202 #, no-c-format msgid "Support synchronous non-call exceptions." -msgstr "" +msgstr "Підтримка синхронних не-викликових винятків." #: common.opt:2209 #, no-c-format msgid "-foffload-options==\tSpecify options for the offloading targets." -msgstr "" +msgstr "-foffload-options=<цілі>=<опції>\tВказати опції для цілей віддалення." #: common.opt:2213 #, no-c-format msgid "-foffload-abi=[lp64|ilp32]\tSet the ABI to use in an offload compiler." -msgstr "" +msgstr "-foffload-abi=[lp64|ilp32]\tВстановити ABI, який буде використовуватися в компіляторі віддалення." #: common.opt:2226 #, no-c-format msgid "When possible do not generate stack frames." -msgstr "" +msgstr "Якщо можливо, не генерувати рамки стеку." #: common.opt:2233 #, no-c-format msgid "Generate SIMD clones for functions with the OpenMP declare target directive." -msgstr "" +msgstr "Генерувати клони SIMD для функцій з директивою OpenMP declare target." #: common.opt:2252 #, no-c-format msgid "Enable all optimization info dumps on stderr." -msgstr "" +msgstr "Увімкнути всі виведення інформації про оптимізацію на stderr." #: common.opt:2256 #, no-c-format msgid "-fopt-info[-=filename]\tDump compiler optimization details." -msgstr "" +msgstr "-fopt-info[-<тип>=імʼя_файлу]\tВивести деталі оптимізації компілятора." #: common.opt:2260 #, no-c-format msgid "Write a SRCFILE.opt-record.json file detailing what optimizations were performed." -msgstr "" +msgstr "Створити файл SRCFILE.opt-record.json, в якому будуть детально описані проведені оптимізації." #: common.opt:2268 #, no-c-format msgid "Optimize sibling and tail recursive calls." -msgstr "" +msgstr "Оптимізувати виклики рекурсії між братніми функціями та хвостовою рекурсією." #: common.opt:2272 #, no-c-format msgid "Perform partial inlining." -msgstr "" +msgstr "Виконати часткове вбудовування." #: common.opt:2276 common.opt:2280 #, no-c-format msgid "Report on memory allocation before interprocedural optimization." -msgstr "" +msgstr "Повідомляти про розподіл памʼяті перед міжпроцедурною оптимізацією." #: common.opt:2284 #, no-c-format msgid "Pack structure members together without holes." -msgstr "" +msgstr "Упаковувати елементи структури разом без прогалин." #: common.opt:2288 #, no-c-format msgid "-fpack-struct=\tSet initial maximum structure member alignment." -msgstr "" +msgstr "-fpack-struct=<число>\tВстановити початкове максимальне вирівнювання елементів структури." #: common.opt:2292 #, no-c-format msgid "Return small aggregates in memory, not registers." -msgstr "" +msgstr "Повертати невеликі агрегати в памʼяті, а не в регістрах." #: common.opt:2296 #, no-c-format msgid "Perform loop peeling." -msgstr "" +msgstr "Виконувати розгортання циклів." #: common.opt:2300 #, no-c-format msgid "Enable machine specific peephole optimizations." -msgstr "" +msgstr "Увімкнути машинно-специфічні оптимізації глядача." #: common.opt:2304 #, no-c-format msgid "Enable an RTL peephole pass before sched2." -msgstr "" +msgstr "Увімкнути прохід глядача RTL перед sched2." #: common.opt:2308 #, no-c-format msgid "Generate position-independent code if possible (large mode)." -msgstr "" +msgstr "Генерувати код, який не залежить від положення, якщо це можливо (large mode)." #: common.opt:2312 #, no-c-format msgid "Generate position-independent code for executables if possible (large mode)." -msgstr "" +msgstr "Генерувати код, який не залежить від положення, якщо це можливо (large mode)." #: common.opt:2316 #, no-c-format msgid "Generate position-independent code if possible (small mode)." -msgstr "Створити виконуваний файл з незалежним позиціюванням, якщо можливо (малий режим)" +msgstr "Генерувати код, який не залежить від положення, якщо це можливо (small mode)." #: common.opt:2320 #, no-c-format msgid "Generate position-independent code for executables if possible (small mode)." -msgstr "" +msgstr "Генерувати код, який не залежить від положення, якщо це можливо (small mode)." #: common.opt:2324 #, no-c-format msgid "Use PLT for PIC calls (-fno-plt: load the address from GOT at call site)." -msgstr "" +msgstr "Використовувати PLT для PIC-викликів (-fno-plt: завантажувати адресу з GOT на місці виклику)." #: common.opt:2328 #, no-c-format msgid "Specify a plugin to load." -msgstr "" +msgstr "Вказати плагін для завантаження." #: common.opt:2332 #, no-c-format msgid "-fplugin-arg--[=]\tSpecify argument = for plugin ." -msgstr "" +msgstr "-fplugin-arg--[=]\tВказати аргумент = для плагіна ." #: common.opt:2336 #, no-c-format msgid "Run predictive commoning optimization." -msgstr "" +msgstr "Виконати передбачувану оптимізацію спільного використання." #: common.opt:2340 #, no-c-format msgid "Generate prefetch instructions, if available, for arrays in loops." -msgstr "" +msgstr "Генерувати інструкції попереднього завантаження, якщо це можливо, для масивів у циклах." #: common.opt:2344 #, no-c-format msgid "Enable basic program profiling code." -msgstr "" +msgstr "Увімкнути базовий код профілювання програми." #: common.opt:2348 #, no-c-format msgid "Generate absolute source path names for gcov." -msgstr "" +msgstr "Генерувати абсолютні шляхи до вихідних файлів для gcov." #: common.opt:2352 #, no-c-format msgid "Insert arc-based program profiling code." -msgstr "" +msgstr "Вставити код профілювання програми на основі дуг." #: common.opt:2356 #, no-c-format msgid "Set the top-level directory for storing the profile data. The default is 'pwd'." -msgstr "" +msgstr "Встановити верхній рівень каталогу для зберігання даних профілю. За замовчуванням - 'pwd'." #: common.opt:2361 #, no-c-format msgid "Select the name for storing the profile note file." -msgstr "" +msgstr "Виберати імʼя для зберігання файлу з примітками профілю." #: common.opt:2365 #, no-c-format msgid "Enable correction of flow inconsistent profile data input." -msgstr "" +msgstr "Увімкнути корекцію непослідовного вводу даних профілю." #: common.opt:2369 #, no-c-format msgid "-fprofile-update=[single|atomic|prefer-atomic]\tSet the profile update method." -msgstr "" +msgstr "-fprofile-update=[single|atomic|prefer-atomic]\tВстановити метод оновлення профілю." #: common.opt:2373 #, no-c-format msgid "Instrument only functions from files whose name matches any of the regular expressions (separated by semi-colons)." -msgstr "" +msgstr "Інструментувати лише функції з файлів, імена яких відповідають будь-якому з регулярних виразів (розділені крапкою з комою)." #: common.opt:2377 #, no-c-format msgid "Instrument only functions from files whose name does not match any of the regular expressions (separated by semi-colons)." -msgstr "" +msgstr "Інструментувати лише функції з файлів, імена яких не відповідають жодному з регулярних виразів (розділені крапкою з комою)." #: common.opt:2393 #, no-c-format msgid "-fprofile-reproducible=[serial|parallel-runs|multithreaded]\tControl level of reproducibility of profile gathered by -fprofile-generate." -msgstr "" +msgstr "-fprofile-reproducible=[serial|parallel-runs|multithreaded]\tКонтролювати рівень відтворюваності профілю, зібраного за допомогою -fprofile-generate." #: common.opt:2409 #, no-c-format msgid "Remove prefix from absolute path before mangling name for -fprofile-generate= and -fprofile-use=." -msgstr "" +msgstr "Видалити префікс з абсолютного шляху перед декоруванням імені для -fprofile-generate= та -fprofile-use=." #: common.opt:2413 #, no-c-format msgid "-fprofile-prefix-map==\tMap one directory name to another in GCOV coverage result." -msgstr "" +msgstr "-fprofile-prefix-map==\tВідображення одного імені директорії на інше в результаті покриття GCOV." #: common.opt:2417 #, no-c-format msgid "Enable common options for generating profile info for profile feedback directed optimizations." -msgstr "" +msgstr "Увімкнути загальні параметри для генерації інформації про профіль для оптимізацій, спрямованих на зворотний звʼязок профілю." #: common.opt:2421 #, no-c-format msgid "Enable common options for generating profile info for profile feedback directed optimizations, and set -fprofile-dir=." -msgstr "" +msgstr "Увімкнути загальні параметри для генерації інформації профілю для оптимізацій, спрямованих на зворотний звʼязок профілю, та встановити -fprofile-dir=." #: common.opt:2425 #, no-c-format msgid "Register the profile information in the .gcov_info section instead of using a constructor/destructor." -msgstr "" +msgstr "Зареєструвати інформацію профілю в розділі .gcov_info замість використання конструктора/деструктора." #: common.opt:2429 #, no-c-format msgid "Register the profile information in the specified section instead of using a constructor/destructor." -msgstr "" +msgstr "Зареєструвати інформацію профілю в вказаному розділі замість використання конструктора/деструктора." #: common.opt:2433 #, no-c-format msgid "Do not assume that functions never executed during the train run are cold." -msgstr "" +msgstr "Не припускайте, що функції, які не виконуються під час тренування, є холодними." #: common.opt:2437 #, no-c-format msgid "Enable common options for performing profile feedback directed optimizations." -msgstr "" +msgstr "Увімкнути загальні параметри для виконання оптимізацій, спрямованих на зворотний звʼязок профілю." #: common.opt:2441 #, no-c-format msgid "Enable common options for performing profile feedback directed optimizations, and set -fprofile-dir=." -msgstr "" +msgstr "Увімкнути загальні параметри для виконання оптимізацій, спрямованих на зворотний звʼязок профілю, та встановити -fprofile-dir=." #: common.opt:2445 #, no-c-format msgid "Insert code to profile values of expressions." -msgstr "" +msgstr "Вставте код для профілювання значень виразів." #: common.opt:2449 #, no-c-format msgid "Report on consistency of profile." -msgstr "" +msgstr "Повідомити про послідовність профілювання." #: common.opt:2453 #, no-c-format msgid "Enable function reordering that improves code placement." -msgstr "" +msgstr "Увімкнути перестановку функцій, що поліпшує розміщення коду." #: common.opt:2457 #, no-c-format msgid "Insert NOP instructions at each function entry." -msgstr "" +msgstr "Вставити NOP-інструкції на кожному вході функції." #: common.opt:2464 #, no-c-format msgid "-frandom-seed=\tMake compile reproducible using ." -msgstr "" +msgstr "-frandom-seed=<рядок>\tЗробити компіляцію відтворюваною за допомогою <рядка>." #: common.opt:2474 #, no-c-format msgid "Record gcc command line switches in the object file." -msgstr "" +msgstr "Записати перемикачі командного рядка gcc у файл обʼєкту." #: common.opt:2478 #, no-c-format msgid "Return small aggregates in registers." -msgstr "" +msgstr "Повертати невеликі агрегати в регістрах." #: common.opt:2486 #, no-c-format msgid "Tell DSE that the storage for a C++ object is dead when the constructor starts and when the destructor finishes." -msgstr "" +msgstr "Сказати DSE, що зберігання для обʼєкта C++ є мертвим, коли починається конструктор і коли закінчується деструктор." #: common.opt:2497 #, no-c-format msgid "-flive-patching=[inline-only-static|inline-clone]\tControl IPA optimizations to provide a safe compilation for live-patching. At the same time, provides multiple-level control on the enabled IPA optimizations." -msgstr "" +msgstr "-flive-patching=[inline-only-static|inline-clone]\tКонтролюйте оптимізації IPA для забезпечення безпечної компіляції для живого латання. Водночас забезпечує багаторівневий контроль над увімкненими оптимізаціями IPA." #: common.opt:2512 #, no-c-format msgid "Tell DCE to remove unused C++ allocations." -msgstr "" +msgstr "Сповістити DCE про видалення невикористаних виділення C++." #: common.opt:2516 #, no-c-format msgid "Relief of register pressure through live range shrinkage." -msgstr "" +msgstr "Зменшення тиску на реєстри шляхом зменшення живого діапазону." #: common.opt:2520 #, no-c-format msgid "Perform a register renaming optimization pass." -msgstr "" +msgstr "Виконати прохід оптимізації перейменування реєстрів." #: common.opt:2524 #, no-c-format msgid "Perform a target dependent instruction fusion optimization pass." -msgstr "" +msgstr "Виконати прохід оптимізації злиття інструкцій, залежний від цілі." #: common.opt:2528 #, no-c-format msgid "Reorder basic blocks to improve code placement." -msgstr "" +msgstr "Переставити базові блоки для покращення розміщення коду." #: common.opt:2532 #, no-c-format msgid "-freorder-blocks-algorithm=[simple|stc]\tSet the used basic block reordering algorithm." -msgstr "" +msgstr "-freorder-blocks-algorithm=[simple|stc]\tВстановити використовуваний алгоритм перестановки базових блоків." #: common.opt:2545 #, no-c-format msgid "Reorder basic blocks and partition into hot and cold sections." -msgstr "" +msgstr "Переставити базові блоки та розбити на гарячі та холодні секції." #: common.opt:2549 #, no-c-format msgid "Reorder functions to improve code placement." -msgstr "" +msgstr "Переставити функції для поліпшення розміщення коду." #: common.opt:2553 #, no-c-format msgid "Add a common subexpression elimination pass after loop optimizations." -msgstr "" +msgstr "Додати прохід по видаленню спільних підвиразів після оптимізації циклів." #: common.opt:2561 #, no-c-format msgid "Disable optimizations that assume default FP rounding behavior." -msgstr "" +msgstr "Вимкнути оптимізації, які припускають поведінку округлення FP за замовчуванням." #: common.opt:2565 #, no-c-format msgid "Enable scheduling across basic blocks." -msgstr "" +msgstr "Увімкнути планування між базовими блоками." #: common.opt:2569 #, no-c-format msgid "Enable register pressure sensitive insn scheduling." -msgstr "" +msgstr "Увімкнути планування інструкцій, чутливе до тиску на реєстри." #: common.opt:2573 #, no-c-format msgid "Allow speculative motion of non-loads." -msgstr "" +msgstr "Дозволити спекулятивний рух не завантажувати." #: common.opt:2577 #, no-c-format msgid "Allow speculative motion of some loads." -msgstr "" +msgstr "Дозволити спекулятивний рух деяких завантажень." #: common.opt:2581 #, no-c-format msgid "Allow speculative motion of more loads." -msgstr "" +msgstr "Дозволити спекулятивний рух більшої кількості завантажень." #: common.opt:2585 #, no-c-format msgid "-fsched-verbose=\tSet the verbosity level of the scheduler." -msgstr "" +msgstr "-fsched-verbose=<число>\tВстановити рівень докладності планувальника." #: common.opt:2589 #, no-c-format msgid "If scheduling post reload, do superblock scheduling." -msgstr "" +msgstr "Якщо планування після перезавантаження, виконати планування суперблоків." #: common.opt:2597 #, no-c-format msgid "Reschedule instructions before register allocation." -msgstr "" +msgstr "Перепланувати інструкції перед розподілом реєстрів." #: common.opt:2601 #, no-c-format msgid "Reschedule instructions after register allocation." -msgstr "" +msgstr "Перепланувати інструкції після розподілу реєстрів." #: common.opt:2608 #, no-c-format msgid "Schedule instructions using selective scheduling algorithm." -msgstr "" +msgstr "Розкладання інструкцій з використанням алгоритму вибіркового планування." #: common.opt:2612 #, no-c-format msgid "Run selective scheduling after reload." -msgstr "" +msgstr "Виконати вибіркове планування після перезавантаження." #: common.opt:2616 #, no-c-format msgid "Run self-tests, using the given path to locate test files." -msgstr "" +msgstr "Виконати самоперевірку, використовуючи заданий шлях для пошуку файлів тестів." #: common.opt:2620 #, no-c-format msgid "Perform software pipelining of inner loops during selective scheduling." -msgstr "" +msgstr "Виконати програмне підпорядкування внутрішніх циклів під час вибіркового планування." #: common.opt:2624 #, no-c-format msgid "Perform software pipelining of outer loops during selective scheduling." -msgstr "" +msgstr "Виконати програмне підпорядкування зовнішніх циклів під час вибіркового планування." #: common.opt:2628 #, no-c-format msgid "Reschedule pipelined regions without pipelining." -msgstr "" +msgstr "Перепланувати області з підпорядкуванням без підпорядкування." #: common.opt:2632 #, no-c-format msgid "Allow interposing function (or variables) by ones with different semantics (or initializer) respectively by dynamic linker." -msgstr "" +msgstr "Дозволити взаємозаміну функцій (або змінних) тими, що мають різну семантику (або ініціалізатор), відповідно, за допомогою динамічного звʼязувача." #: common.opt:2638 #, no-c-format msgid "Allow premature scheduling of queued insns." -msgstr "" +msgstr "Дозволити передчасне планування в черзі інструкцій." #: common.opt:2642 #, no-c-format msgid "-fsched-stalled-insns=\tSet number of queued insns that can be prematurely scheduled." -msgstr "" +msgstr "-fsched-stalled-insns=<кількість>\tВстановити кількість інструкцій в черзі, які можуть бути передчасно заплановані." #: common.opt:2650 #, no-c-format msgid "Set dependence distance checking in premature scheduling of queued insns." -msgstr "" +msgstr "Встановити перевірку відстані залежності при передчасному плануванні інструкцій в черзі." #: common.opt:2654 #, no-c-format msgid "-fsched-stalled-insns-dep=\tSet dependence distance checking in premature scheduling of queued insns." -msgstr "" +msgstr "-fsched-stalled-insns-dep=<число>\tВстановити перевірку відстані залежності при передчасному плануванні інструкцій в черзі." #: common.opt:2658 #, no-c-format msgid "Enable the group heuristic in the scheduler." -msgstr "" +msgstr "Увімкнути групову евристику в планувальнику." #: common.opt:2662 #, no-c-format msgid "Enable the critical path heuristic in the scheduler." -msgstr "" +msgstr "Увімкнути евристику критичного шляху в планувальнику." #: common.opt:2666 #, no-c-format msgid "Enable the speculative instruction heuristic in the scheduler." -msgstr "" +msgstr "Увімкнути евристику спекулятивних інструкцій в планувальнику." #: common.opt:2670 #, no-c-format msgid "Enable the rank heuristic in the scheduler." -msgstr "" +msgstr "Увімкнути рангову евристику в планувальнику." #: common.opt:2674 #, no-c-format msgid "Enable the last instruction heuristic in the scheduler." -msgstr "" +msgstr "Увімкнути евристику останньої інструкції в планувальнику." #: common.opt:2678 #, no-c-format msgid "Enable the dependent count heuristic in the scheduler." -msgstr "" +msgstr "Увімкнути евристику підрахунку залежностей в планувальнику." #: common.opt:2682 #, no-c-format msgid "Access data in the same section from shared anchor points." -msgstr "" +msgstr "Отримання доступу до даних в одному розділі зі спільних точок якоря." #: common.opt:2694 #, no-c-format msgid "Turn on Redundant Extensions Elimination pass." -msgstr "" +msgstr "Увімкнути прохід для видалення зайвих розширень." #: common.opt:2698 #, no-c-format msgid "Show column numbers in diagnostics, when available. Default on." -msgstr "" +msgstr "Показувати номери стовпців у діагностиці, якщо доступно. За замовчуванням увімкнено." #: common.opt:2702 #, no-c-format msgid "Emit function prologues only before parts of the function that need it, rather than at the top of the function." -msgstr "" +msgstr "Видавати прологи функцій лише перед частинами функції, які цього потребують, а не на початку функції." #: common.opt:2707 #, no-c-format msgid "Shrink-wrap parts of the prologue and epilogue separately." -msgstr "" +msgstr "Зменшити розмір частин прологу та епілогу окремо." #: common.opt:2711 #, no-c-format msgid "Disable optimizations observable by IEEE signaling NaNs." -msgstr "" +msgstr "Вимкнути оптимізації, які можна спостерігати за допомогою IEEE сигнальних NaN." #: common.opt:2715 #, no-c-format msgid "Disable floating point optimizations that ignore the IEEE signedness of zero." -msgstr "" +msgstr "Вимкнути оптимізації з плаваючою комою, які не враховують знаковість нуля за стандартом IEEE." #: common.opt:2719 #, no-c-format msgid "Convert floating point constants to single precision constants." -msgstr "" +msgstr "Перетворити константи з плаваючою комою на константи одинарної точності." #: common.opt:2723 #, no-c-format msgid "Split lifetimes of induction variables when loops are unrolled." -msgstr "" +msgstr "Розділити тривалість індукційних змінних при розгортанні циклів." #: common.opt:2727 #, no-c-format msgid "Generate discontiguous stack frames." -msgstr "" +msgstr "Генерувати неперервні рамки стеку." #: common.opt:2731 #, no-c-format msgid "Split wide types into independent registers." -msgstr "" +msgstr "Розбити широкі типи на незалежні регістри." #: common.opt:2735 #, no-c-format msgid "Split wide types into independent registers earlier." -msgstr "" +msgstr "Розбити широкі типи на незалежні регістри раніше." #: common.opt:2739 #, no-c-format msgid "Enable backward propagation of use properties at the SSA level." -msgstr "" +msgstr "Увімкнути зворотне поширення властивостей використання на рівні SSA." #: common.opt:2743 #, no-c-format msgid "Optimize conditional patterns using SSA PHI nodes." -msgstr "" +msgstr "Оптимізувати умовні шаблони, використовуючи вузли SSA PHI." #: common.opt:2747 #, no-c-format msgid "Optimize amount of stdarg registers saved to stack at start of function." -msgstr "" +msgstr "Оптимізувати кількість регістрів stdarg, збережених у стеку на початку функції." #: common.opt:2751 #, no-c-format msgid "Apply variable expansion when loops are unrolled." -msgstr "" +msgstr "Застосувати розширення змінних при розгортанні циклів." #: common.opt:2755 #, no-c-format msgid "-fstack-check=[no|generic|specific]\tInsert stack checking code into the program." -msgstr "" +msgstr "-fstack-check=[no|generic|specific]\tВставити код перевірки стеку в програму." #: common.opt:2759 #, no-c-format msgid "Insert stack checking code into the program. Same as -fstack-check=specific." -msgstr "" +msgstr "Вставити код перевірки стеку в програму. Те саме, що й -fstack-check=specific." #: common.opt:2763 #, no-c-format msgid "Insert code to probe each page of stack space as it is allocated to protect from stack-clash style attacks." -msgstr "" +msgstr "Вставити код для перевірки кожної сторінки простору стеку під час його виділення, щоб захистити від атак типу stack-clash." #: common.opt:2771 #, no-c-format msgid "-fstack-limit-register=\tTrap if the stack goes past ." -msgstr "" +msgstr "-fstack-limit-register=<регістр>\tПерехопити, якщо стек виходить за межі <регістра>." #: common.opt:2775 #, no-c-format msgid "-fstack-limit-symbol=\tTrap if the stack goes past symbol ." -msgstr "" +msgstr "-fstack-limit-symbol=<імʼя>\tПерехопити, якщо стек виходить за межі символу <імʼя>." #: common.opt:2779 #, no-c-format msgid "Use propolice as a stack protection method." -msgstr "" +msgstr "Використовуйте propolice як метод захисту стеку." #: common.opt:2783 #, no-c-format msgid "Use a stack protection method for every function." -msgstr "" +msgstr "Використовуйте метод захисту стеку для кожної функції." #: common.opt:2787 #, no-c-format msgid "Use a smart stack protection method for certain functions." -msgstr "" +msgstr "Використовуйте розумний метод захисту стеку для певних функцій." #: common.opt:2791 #, no-c-format msgid "Use stack protection method only for functions with the stack_protect attribute." -msgstr "" +msgstr "Використовуйте метод захисту стеку лише для функцій з атрибутом stack_protect." #: common.opt:2795 #, no-c-format msgid "Output stack usage information on a per-function basis." -msgstr "" +msgstr "Виводити інформацію про використання стеку для кожної функції." #: common.opt:2807 #, no-c-format msgid "Assume strict aliasing rules apply." -msgstr "" +msgstr "Припустити, що застосовуються строгі правила псевдонімів." #: common.opt:2811 #, no-c-format msgid "Treat signed overflow as undefined. Negated as -fwrapv -fwrapv-pointer." -msgstr "" +msgstr "Трактувати переповнення зі знаком як невизначене. Заперечується як -fwrapv -fwrapv-pointer." #: common.opt:2815 #, no-c-format msgid "Implement __atomic operations via libcalls to legacy __sync functions." -msgstr "" +msgstr "Реалізувати операції __atomic через виклики libcalls до старих функцій __sync." #: common.opt:2819 #, no-c-format msgid "Check for syntax errors, then stop." -msgstr "" +msgstr "Перевірити наявність синтаксичних помилок, потім зупинитися." #: common.opt:2823 #, no-c-format msgid "Create data files needed by \"gcov\"." -msgstr "" +msgstr "Створити файли даних, необхідні для «gcov»." #: common.opt:2827 #, no-c-format msgid "Perform jump threading optimizations." -msgstr "" +msgstr "Виконати оптимізацію переходів." #: common.opt:2831 #, no-c-format msgid "Report the time taken by each compiler pass." -msgstr "" +msgstr "Повідомити час, затрачений на кожний прохід компілятора." #: common.opt:2835 #, no-c-format msgid "Record times taken by sub-phases separately." -msgstr "" +msgstr "Записувати час, затрачений окремо для підфаз." #: common.opt:2839 #, no-c-format msgid "-ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec]\tSet the default thread-local storage code generation model." -msgstr "" +msgstr "-ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec]\tВстановити модель генерації коду локального потокового сховища за замовчуванням." #: common.opt:2858 #, no-c-format msgid "Reorder top level functions, variables, and asms." -msgstr "" +msgstr "Переупорядкувати функції, змінні та asms верхнього рівня." #: common.opt:2862 #, no-c-format msgid "Perform superblock formation via tail duplication." -msgstr "" +msgstr "Виконати формування суперблоку за допомогою дублювання хвоста." #: common.opt:2866 #, no-c-format msgid "For targets that normally need trampolines for nested functions, always generate them instead of using descriptors." -msgstr "" +msgstr "Для цілей, які зазвичай потребують трампліни для вкладених функцій, завжди генерувати їх замість використання дескрипторів." #: common.opt:2874 #, no-c-format msgid "Assume floating-point operations can trap." -msgstr "" +msgstr "Припускати, що операції з плаваючою комою можуть спрацювати пасткою." #: common.opt:2878 #, no-c-format msgid "Trap for signed overflow in addition, subtraction and multiplication." -msgstr "" +msgstr "Ставити пастку на відʼємне переповнення при додаванні, відніманні та множенні." #: common.opt:2882 #, no-c-format msgid "Enable SSA-CCP optimization on trees." -msgstr "" +msgstr "Увімкнути оптимізацію SSA-CCP на деревах." #: common.opt:2886 #, no-c-format msgid "Enable SSA-BIT-CCP optimization on trees." -msgstr "" +msgstr "Увімкнути оптимізацію SSA-BIT-CCP на деревах." #: common.opt:2894 #, no-c-format msgid "Enable loop header copying on trees." -msgstr "" +msgstr "Увімкнути копіювання заголовка циклу на деревах." #: common.opt:2902 #, no-c-format msgid "Enable SSA coalescing of user variables." -msgstr "" +msgstr "Увімкнути злиття користувацьких змінних під час SSA-проходу." #: common.opt:2910 #, no-c-format msgid "Enable copy propagation on trees." -msgstr "" +msgstr "Увімкнути розповсюдження копій на деревах." #: common.opt:2918 #, no-c-format msgid "Transform condition stores into unconditional ones." -msgstr "" +msgstr "Перетворити умовні збереження в безумовні." #: common.opt:2922 #, no-c-format msgid "Perform conversions of switch initializations." -msgstr "" +msgstr "Виконати перетворення ініціалізацій перемикача." #: common.opt:2926 #, no-c-format msgid "Enable SSA dead code elimination optimization on trees." -msgstr "" +msgstr "Увімкнути оптимізацію видалення мертвого коду SSA на деревах." #: common.opt:2930 #, no-c-format msgid "Enable dominator optimizations." -msgstr "" +msgstr "Увімкнути оптимізацію домінаторів." #: common.opt:2934 #, no-c-format msgid "Enable tail merging on trees." -msgstr "" +msgstr "Увімкнути злиття хвостів на деревах." #: common.opt:2938 #, no-c-format msgid "Enable dead store elimination." -msgstr "" +msgstr "Увімкнути видалення мертвих збережень." #: common.opt:2942 #, no-c-format msgid "Enable forward propagation on trees." -msgstr "" +msgstr "Увімкнути пряме розповсюдження на деревах." #: common.opt:2946 #, no-c-format msgid "Enable Full Redundancy Elimination (FRE) on trees." -msgstr "" +msgstr "Увімкнути повне усунення зайвості (FRE) на деревах." #: common.opt:2950 #, no-c-format msgid "Enable string length optimizations on trees." -msgstr "" +msgstr "Увімкнути оптимізацію довжини рядків на деревах." #: common.opt:2954 #, no-c-format msgid "Detect paths that trigger erroneous or undefined behavior due to dereferencing a null pointer. Isolate those paths from the main control flow and turn the statement with erroneous or undefined behavior into a trap." -msgstr "" +msgstr "Виявляти шляхи, які спричиняють помилкову або невизначену поведінку через розіменування нульового вказівника. Відокремлюйте ці шляхи від основного потоку управління та перетворюйте оператор з помилковою або невизначеною поведінкою в пастку." #: common.opt:2960 #, no-c-format msgid "Detect paths that trigger erroneous or undefined behavior due to a null value being used in a way forbidden by a returns_nonnull or nonnull attribute. Isolate those paths from the main control flow and turn the statement with erroneous or undefined behavior into a trap." -msgstr "" +msgstr "Виявити шляхи, які спричиняють помилкову або невизначену поведінку через використання нульового значення таким чином, який заборонений атрибутом returns_nonnull або nonnull. Відокремити ці шляхи від основного потоку керування та перетворити оператор з помилковою або невизначеною поведінкою в пастку." #: common.opt:2967 #, no-c-format msgid "Enable loop distribution on trees." -msgstr "" +msgstr "Увімкнути розподіл петель на деревах." #: common.opt:2971 #, no-c-format msgid "Enable loop distribution for patterns transformed into a library call." -msgstr "" +msgstr "Увімкнути розподіл петель для шаблонів, перетворених у виклик бібліотеки." #: common.opt:2975 #, no-c-format msgid "Enable loop invariant motion on trees." -msgstr "" +msgstr "Увімкнути переміщення незмінних петель на деревах." #: common.opt:2983 #, no-c-format msgid "Create canonical induction variables in loops." -msgstr "" +msgstr "Створити канонічні змінні індукції в петлях." #: common.opt:2987 #, no-c-format msgid "Enable loop optimizations on tree level." -msgstr "" +msgstr "Увімкнути оптимізацію петель на рівні дерева." #: common.opt:2991 #, no-c-format msgid "-ftree-parallelize-loops=\tEnable automatic parallelization of loops." -msgstr "" +msgstr "-ftree-parallelize-loops=<кількість>\tУвімкнути автоматичну паралелізацію петель." #: common.opt:2995 #, no-c-format msgid "Enable hoisting loads from conditional pointers." -msgstr "" +msgstr "Увімкнути підняття завантажень з умовних вказівників." #: common.opt:2999 #, no-c-format msgid "Enable SSA-PRE optimization on trees." -msgstr "" +msgstr "Увімкнути оптимізацію SSA-PRE на деревах." #: common.opt:3003 #, no-c-format msgid "In SSA-PRE optimization on trees, enable partial-partial redundancy elimination." -msgstr "" +msgstr "У оптимізації SSA-PRE на деревах увімкнути часткову елімінацію часткової зайвості." #: common.opt:3007 #, no-c-format msgid "Perform function-local points-to analysis on trees." -msgstr "" +msgstr "Виконати аналіз точок доступу на рівні функцій для дерев." #: common.opt:3011 #, no-c-format msgid "Enable reassociation on tree level." -msgstr "" +msgstr "Увімкнути переасоціацію на рівні дерева." #: common.opt:3019 #, no-c-format msgid "Enable SSA code sinking on trees." -msgstr "" +msgstr "Увімкнути опускання коду SSA на деревах." #: common.opt:3023 #, no-c-format msgid "Perform straight-line strength reduction." -msgstr "" +msgstr "Виконати зменшення сили прямолінійного рядка." #: common.opt:3027 #, no-c-format msgid "Perform scalar replacement of aggregates." -msgstr "" +msgstr "Виконати заміну агрегатів скалярами." #: common.opt:3031 #, no-c-format msgid "Replace temporary expressions in the SSA->normal pass." -msgstr "" +msgstr "Замінити тимчасові вирази у проході SSA->normal." #: common.opt:3035 #, no-c-format msgid "Perform live range splitting during the SSA->normal pass." -msgstr "" +msgstr "Виконати розбиття активного діапазону під час проходу SSA->normal." #: common.opt:3039 #, no-c-format msgid "Perform Value Range Propagation on trees." -msgstr "" +msgstr "Виконати поширення діапазону значень на деревах." #: common.opt:3043 #, no-c-format msgid "Split paths leading to loop backedges." -msgstr "" +msgstr "Розбити шляхи, що ведуть до зворотних ребер циклу." #: common.opt:3047 #, no-c-format msgid "Assume common declarations may be overridden with ones with a larger trailing array." -msgstr "" +msgstr "Припустити, що загальні оголошення можуть бути перекриті тими, що мають більший заключний масив." #: common.opt:3052 #, no-c-format msgid "Compile whole compilation unit at a time." -msgstr "" +msgstr "Компілювати цілу одиницю компіляції за один раз." #: common.opt:3056 #, no-c-format msgid "Trap on __builtin_unreachable instead of using it for optimization." -msgstr "" +msgstr "Перехоплювати __builtin_unreachable замість використання його для оптимізації." #: common.opt:3060 #, no-c-format msgid "Perform loop unrolling when iteration count is known." -msgstr "" +msgstr "Виконувати розгортання циклу, коли відома кількість ітерацій." #: common.opt:3064 #, no-c-format msgid "Perform loop unrolling for all loops." -msgstr "" +msgstr "Виконувати розгортання циклу для всіх циклів." #: common.opt:3079 #, no-c-format msgid "Allow optimization for floating-point arithmetic which may change the result of the operation due to rounding." -msgstr "" +msgstr "Дозволити оптимізацію для арифметики з плаваючою комою, яка може змінити результат операції через округлення." #: common.opt:3084 #, no-c-format msgid "Same as -fassociative-math for expressions which include division." -msgstr "" +msgstr "Те саме, що й -fassociative-math для виразів, які включають ділення." #: common.opt:3092 #, no-c-format msgid "Allow math optimizations that may violate IEEE or ISO standards." -msgstr "" +msgstr "Дозволити математичні оптимізації, які можуть порушувати стандарти IEEE або ISO." #: common.opt:3096 #, no-c-format msgid "Perform loop unswitching." -msgstr "" +msgstr "Виконати розгалуження циклу." #: common.opt:3100 #, no-c-format msgid "Perform loop splitting." -msgstr "" +msgstr "Виконати розбиття циклу." #: common.opt:3104 #, no-c-format msgid "Version loops based on whether indices have a stride of one." -msgstr "" +msgstr "Версіонувати цикли в залежності від того, чи мають індекси крок одиниці." #: common.opt:3108 #, no-c-format msgid "Just generate unwind tables for exception handling." -msgstr "" +msgstr "Просто генерувати таблиці розгортання для обробки винятків." #: common.opt:3112 #, no-c-format msgid "Use the bfd linker instead of the default linker." -msgstr "" +msgstr "Використовувати лінкер bfd замість лінкера за замовчуванням." #: common.opt:3116 #, no-c-format msgid "Use the gold linker instead of the default linker." -msgstr "" +msgstr "Використовувати лінкер gold замість лінкера за замовчуванням." #: common.opt:3120 #, no-c-format msgid "Use the lld LLVM linker instead of the default linker." -msgstr "" +msgstr "Використовувати лінкер lld LLVM замість лінкера за замовчуванням." #: common.opt:3124 #, no-c-format msgid "Use the Modern linker (MOLD) linker instead of the default linker." -msgstr "" +msgstr "Використовувати лінкер Modern (MOLD) замість лінкера за замовчуванням." #: common.opt:3134 #, no-c-format msgid "Perform variable tracking." -msgstr "" +msgstr "Виконувати відстеження змінних." #: common.opt:3141 #, no-c-format msgid "Perform variable tracking by annotating assignments." -msgstr "" +msgstr "Виконувати відстеження змінних, анотуючи присвоєння." #: common.opt:3147 #, no-c-format msgid "Toggle -fvar-tracking-assignments." -msgstr "" +msgstr "Перемикнути -fvar-tracking-assignments." #: common.opt:3154 #, no-c-format msgid "Perform variable tracking and also tag variables that are uninitialized." -msgstr "" +msgstr "Виконувати відстеження змінних та позначати також змінні, які не ініціалізовані." #: common.opt:3159 #, no-c-format msgid "Enable vectorization on trees." -msgstr "" +msgstr "Увімкнути векторизацію на деревах." #: common.opt:3167 #, no-c-format msgid "Enable loop vectorization on trees." -msgstr "" +msgstr "Увімкнути векторизацію циклів на деревах." #: common.opt:3171 #, no-c-format msgid "Enable basic block vectorization (SLP) on trees." -msgstr "" +msgstr "Увімкнути векторизацію базових блоків (SLP) на деревах." #: common.opt:3175 #, no-c-format msgid "-fvect-cost-model=[unlimited|dynamic|cheap|very-cheap]\tSpecifies the cost model for vectorization." -msgstr "" +msgstr "-fvect-cost-model=[unlimited|dynamic|cheap|very-cheap]\tВказує модель вартості для векторизації." #: common.opt:3179 #, no-c-format msgid "-fsimd-cost-model=[unlimited|dynamic|cheap|very-cheap]\tSpecifies the vectorization cost model for code marked with a simd directive." -msgstr "" +msgstr "-fsimd-cost-model=[unlimited|dynamic|cheap|very-cheap]\tВказує модель вартості векторизації для коду, позначеного директивою simd." #: common.opt:3198 #, no-c-format msgid "Enables the dynamic vectorizer cost model. Preserved for backward compatibility." -msgstr "" +msgstr "Увімкнути динамічну модель вартості векторизатора. Зберігається для забезпечення сумісності з попередніми версіями." #: common.opt:3206 #, no-c-format msgid "Enable copy propagation of scalar-evolution information." -msgstr "" +msgstr "Увімкнути копіювання інформації про скалярну еволюцію." #: common.opt:3210 #, no-c-format msgid "-ftrivial-auto-var-init=[uninitialized|pattern|zero]\tAdd initializations to automatic variables." -msgstr "" +msgstr "-ftrivial-auto-var-init=[uninitialized|pattern|zero]\tДодати ініціалізацію до автоматичних змінних." #: common.opt:3232 #, no-c-format msgid "Add extra commentary to assembler output." -msgstr "" +msgstr "Додати додаткові коментарі до вихідного коду асемблера." #: common.opt:3236 #, no-c-format msgid "-fvisibility=[default|internal|hidden|protected]\tSet the default symbol visibility." -msgstr "" +msgstr "-fvisibility=[default|internal|hidden|protected]\tВстановити типову видимість символів." #: common.opt:3255 #, no-c-format msgid "Validate vtable pointers before using them." -msgstr "" +msgstr "Перевіряти вказівники на vtable перед використанням." #: common.opt:3271 #, no-c-format msgid "Output vtable verification counters." -msgstr "" +msgstr "Вивести лічильники перевірки vtable." #: common.opt:3275 #, no-c-format msgid "Output vtable verification pointer sets information." -msgstr "" +msgstr "Виведення інформації про набори вказівників перевірки vtable." #: common.opt:3279 #, no-c-format msgid "Use expression value profiles in optimizations." -msgstr "" +msgstr "Використовувати профілі значень виразів при оптимізації." #: common.opt:3283 #, no-c-format msgid "Construct webs and split unrelated uses of single variable." -msgstr "" +msgstr "Створення мереж та розбиття неспоріднених використань однієї змінної." #: common.opt:3287 #, no-c-format msgid "Enable conditional dead code elimination for builtin calls." -msgstr "" +msgstr "Увімкнути умовне видалення мертвого коду для викликів вбудованих функцій." #: common.opt:3291 #, no-c-format msgid "Perform whole program optimizations." -msgstr "" +msgstr "Виконати оптимізацію всього програмного коду." #: common.opt:3295 #, no-c-format msgid "Assume pointer overflow wraps around." -msgstr "" +msgstr "Припустити, що переповнення вказівника обгортається." #: common.opt:3299 #, no-c-format msgid "Assume signed arithmetic overflow wraps around." -msgstr "" +msgstr "Припустити, що переповнення знакової арифметики обгортається." #: common.opt:3303 #, no-c-format msgid "Put zero initialized data in the bss section." -msgstr "Розташувати ініціалізовані нулями дані у розділі bss." +msgstr "Розмістити дані з нульовою ініціалізацією в розділі bss." #: common.opt:3307 #, no-c-format msgid "Clear call-used registers upon function return." -msgstr "" +msgstr "Очищати використані регістри після повернення з функції." #: common.opt:3311 #, no-c-format msgid "Generate debug information in default format." -msgstr "Створити діагностичні дані у типовому форматі." +msgstr "Генерувати інформацію для налагодження у форматі за замовчуванням." #: common.opt:3315 #, no-c-format msgid "Assume assembler support for (DWARF2+) .loc directives." -msgstr "" +msgstr "Припускати підтримку асемблером директив .loc (DWARF2+)." #: common.opt:3319 #, no-c-format msgid "Assume assembler support for view in (DWARF2+) .loc directives." -msgstr "" +msgstr "Припускати підтримку асемблером перегляду в директивах .loc (DWARF2+)." #: common.opt:3339 #, no-c-format msgid "Record DW_AT_decl_column and DW_AT_call_column in DWARF." -msgstr "" +msgstr "Записати DW_AT_decl_column та DW_AT_call_column в DWARF." #: common.opt:3345 #, no-c-format msgid "Generate CTF debug information at default level." -msgstr "" +msgstr "Генерувати інформацію для налагодження CTF на рівні за замовчуванням." #: common.opt:3349 #, no-c-format msgid "Generate BTF debug information at default level." -msgstr "" +msgstr "Генерувати інформацію для налагодження BTF на рівні за замовчуванням." #: common.opt:3353 #, no-c-format msgid "Generate debug information in default version of DWARF format." -msgstr "" +msgstr "Генерувати інформацію для налагодження у форматі DWARF за замовчуванням." #: common.opt:3357 #, no-c-format msgid "Generate debug information in DWARF v2 (or later) format." -msgstr "" +msgstr "Генерувати інформацію для налагодження у форматі DWARF v2 (або пізніше)." #: common.opt:3361 #, no-c-format msgid "Use 32-bit DWARF format when emitting DWARF debug information." -msgstr "" +msgstr "Використовувати 32-бітний формат DWARF при випуску інформації для налагодження DWARF." #: common.opt:3365 #, no-c-format msgid "Use 64-bit DWARF format when emitting DWARF debug information." -msgstr "" +msgstr "Використовувати 64-бітний формат DWARF при випуску інформації для налагодження DWARF." #: common.opt:3369 #, no-c-format msgid "Generate debug information in default extended format." -msgstr "" +msgstr "Генерувати інформацію для налагодження у форматі за замовчуванням." #: common.opt:3373 #, no-c-format msgid "Generate extended entry point information for inlined functions." -msgstr "" +msgstr "Генерувати розширену інформацію про точки входу для вбудованих функцій." #: common.opt:3377 #, no-c-format msgid "Compute locview reset points based on insn length estimates." -msgstr "" +msgstr "Обчислювати точки скидання locview на основі оцінок довжини інструкцій." #: common.opt:3385 #, no-c-format msgid "Don't generate DWARF pubnames and pubtypes sections." -msgstr "" +msgstr "Не генерувати розділи DWARF pubnames та pubtypes." #: common.opt:3389 #, no-c-format msgid "Generate DWARF pubnames and pubtypes sections." -msgstr "" +msgstr "Генерувати розділи pubnames та pubtypes у форматі DWARF." #: common.opt:3393 #, no-c-format msgid "Generate DWARF pubnames and pubtypes sections with GNU extensions." -msgstr "" +msgstr "Генерувати розділи pubnames та pubtypes у форматі DWARF з розширеннями GNU." #: common.opt:3397 #, no-c-format msgid "Record gcc command line switches in DWARF DW_AT_producer." -msgstr "" +msgstr "Записати командні рядки gcc в DWARF DW_AT_producer." #: common.opt:3401 #, no-c-format msgid "Generate debug information in separate .dwo files." -msgstr "" +msgstr "Генерувати інформацію для налагодження у окремих файлах .dwo." #: common.opt:3413 #, no-c-format msgid "Emit progressive recommended breakpoint locations." -msgstr "" +msgstr "Виводити прогресивні рекомендовані місця зупинки." #: common.opt:3417 #, no-c-format msgid "Don't emit DWARF additions beyond selected version." -msgstr "" +msgstr "Не виводити додатки DWARF поза вибраною версією." #: common.opt:3421 #, no-c-format msgid "Add description attributes to some DWARF DIEs that have no name attribute." -msgstr "" +msgstr "Додавати атрибути опису до деяких DWARF DIE, які не мають атрибуту імені." #: common.opt:3425 #, no-c-format msgid "Toggle debug information generation." -msgstr "" +msgstr "Перемикнути генерацію інформації для налагодження." #: common.opt:3429 #, no-c-format msgid "Augment variable location lists with progressive views." -msgstr "" +msgstr "Розширити списки місцезнаходження змінних з прогресивними переглядами." #: common.opt:3436 #, no-c-format msgid "Generate debug information in VMS format." -msgstr "" +msgstr "Створити відлагоджувальну інформацію у форматі VMS." #: common.opt:3465 #, no-c-format msgid "Generate compressed debug sections." -msgstr "" +msgstr "Створити стиснуті розділи відлагоджувальної інформації." #: common.opt:3469 #, no-c-format msgid "-gz=\tGenerate compressed debug sections in format ." -msgstr "" +msgstr "-gz=<формат>\tСтворити стиснуті розділи відлагоджувальної інформації у форматі <формат>." #: common.opt:3476 #, no-c-format msgid "-iplugindir=\tSet to be the default plugin directory." -msgstr "" +msgstr "-iplugindir=<кат>\tВстановити <кат> як каталог за замовчуванням для плагінів." #: common.opt:3480 #, no-c-format msgid "-imultiarch \tSet to be the multiarch include subdirectory." -msgstr "" +msgstr "-imultiarch <кат>\tВстановити <кат> як підкаталог multiarch для включення." #: common.opt:3508 #, no-c-format msgid "-o \tPlace output into ." -msgstr "" +msgstr "-o <файл>\tЗберегти вихідні дані у файл <файл>." #: common.opt:3512 #, no-c-format msgid "Enable function profiling." -msgstr "" +msgstr "Увімкнути профілювання функцій." #: common.opt:3522 #, no-c-format msgid "Like -pedantic but issue them as errors." -msgstr "" +msgstr "Аналогічно -pedantic, але видає їх як помилки." #: common.opt:3562 #, no-c-format msgid "Do not display functions compiled or elapsed time." -msgstr "" +msgstr "Не показувати скомпільовані функції або час, що пройшов." #: common.opt:3594 #, no-c-format msgid "Enable verbose output." -msgstr "Увімкнути докладне виведення." +msgstr "Увімкнути розширений вивід." #: common.opt:3598 #, no-c-format msgid "Display the compiler's version." -msgstr "" +msgstr "Показувати версію компілятора." #: common.opt:3602 #, no-c-format msgid "Suppress warnings." -msgstr "Придушити попередження." +msgstr "Приглушити попередження." #: common.opt:3612 #, no-c-format msgid "Create a shared library." -msgstr "Створити бібліотеку спільного використання." +msgstr "Створити спільну бібліотеку." #: common.opt:3672 #, no-c-format msgid "Don't create a dynamically linked position independent executable." -msgstr "Не створювати динамічно скомпонований виконуваний файл з незалежним позиціюванням." +msgstr "Не створювати динамічно звʼязаний виконуваний файл з незалежним від положення кодом." #: common.opt:3676 #, no-c-format msgid "Create a dynamically linked position independent executable." -msgstr "Створити динамічно скомпонований виконуваний файл з незалежним позиціюванням." +msgstr "Створити динамічно звʼязаний виконуваний файл з незалежним від положення кодом." #: common.opt:3680 #, no-c-format msgid "Create a static position independent executable." -msgstr "Створити статичний виконуваний файл з незалежним позиціюванням." +msgstr "Створити статичний виконуваний файл з незалежним від положення кодом." #: common.opt:3687 #, no-c-format msgid "Use caller save register across calls if possible." -msgstr "" +msgstr "Використовувати реєстр збереження викликача під час викликів, якщо це можливо." #: params.opt:27 #, no-c-format msgid "Loops iterating at least selected number of iterations will get loop alignment." -msgstr "" +msgstr "Цикли, які ітерують принаймні вибрану кількість разів, отримають вирівнювання циклу." #: params.opt:31 #, no-c-format msgid "Select fraction of the maximal frequency of executions of basic block in function given basic block get alignment." -msgstr "" +msgstr "Виберати частку максимальної частоти виконання базового блоку в функції, якщо базовий блок отримує вирівнювання." #: params.opt:35 #, no-c-format msgid "Enable asan globals protection." -msgstr "" +msgstr "Увімкнути захист глобальних змінних asan." #: params.opt:39 #, no-c-format msgid "Enable asan allocas/VLAs protection." -msgstr "" +msgstr "Увімкнути захист asan для allocas/VLAs." #: params.opt:43 #, no-c-format msgid "Enable asan load operations protection." -msgstr "" +msgstr "Увімкнути захист asan для операцій завантаження." #: params.opt:47 #, no-c-format msgid "Enable asan store operations protection." -msgstr "" +msgstr "Увімкнути захист операцій збереження asan." #: params.opt:51 #, no-c-format msgid "Use callbacks instead of inline code if number of accesses in function becomes greater or equal to this number." -msgstr "" +msgstr "Використовувати зворотні виклики замість вбудованого коду, якщо кількість доступів у функції стає більшою або рівною цьому числу." #: params.opt:55 #, no-c-format msgid "Prefix calls to memcpy, memset and memmove with __asan_ or __hwasan_ for -fsanitize=kernel-address or -fsanitize=kernel-hwaddress." -msgstr "" +msgstr "Додати префікс __asan_ або __hwasan_ до викликів memcpy, memset та memmove для -fsanitize=kernel-address або -fsanitize=kernel-hwaddress." #: params.opt:59 #, no-c-format msgid "Enable asan builtin functions protection." -msgstr "" +msgstr "Увімкнути захист вбудованих функцій asan." #: params.opt:63 #, no-c-format msgid "Enable asan stack protection." -msgstr "" +msgstr "Увімкнути захист стеку asan." #: params.opt:67 #, no-c-format msgid "Enable asan detection of use-after-return bugs." -msgstr "" +msgstr "Увімкнути виявлення помилок використання після повернення asan." #: params.opt:71 #, no-c-format msgid "Enable hwasan instrumentation of statically sized stack-allocated variables." -msgstr "" +msgstr "Увімкнути інструменталізацію hwasan для статично розміщених змінних, виділених у стеку." #: params.opt:75 #, no-c-format msgid "Use random base tag for each frame, as opposed to base always zero." -msgstr "" +msgstr "Використовувати випадковий базовий тег для кожної фрейму, на відміну від постійного значення нуль." #: params.opt:79 #, no-c-format msgid "Enable hwasan instrumentation of allocas/VLAs." -msgstr "" +msgstr "Увімкнути інструменталізацію hwasan для allocas/VLAs." #: params.opt:83 #, no-c-format msgid "Enable hwasan instrumentation of load operations." -msgstr "" +msgstr "Увімкнути інструменталізацію hwasan для операцій завантаження." #: params.opt:87 #, no-c-format msgid "Enable hwasan instrumentation of store operations." -msgstr "" +msgstr "Увімкнути інструменталізацію hwasan для операцій збереження." #: params.opt:91 #, no-c-format msgid "Enable hwasan instrumentation of builtin functions." -msgstr "Увімкнути укомплектування HWASAN для вбудованих функцій." +msgstr "Увімкнути інструментування вбудованих функцій hwasan." #: params.opt:95 #, no-c-format @@ -15725,1264 +15699,1264 @@ msgstr "Середня кількість ітерацій циклу." #: params.opt:99 #, no-c-format msgid "Maximum number of bits for which we avoid creating FMAs." -msgstr "" +msgstr "Максимальна кількість бітів, для яких ми уникнемо створення FMAs." #: params.opt:103 #, no-c-format msgid "Set the estimated probability in percentage for builtin expect. The default value is 90% probability." -msgstr "" +msgstr "Встановити приблизну ймовірність у відсотках для вбудованої функції expect. Значення за замовчуванням - ймовірність 90%." #: params.opt:107 #, no-c-format msgid "The maximum length of a constant string for a builtin string cmp call eligible for inlining. The default value is 3." -msgstr "" +msgstr "Максимальна довжина константного рядка для вбудованого виклику порівняння рядків, який може бути вбудованим. Значення за замовчуванням - 3." #: params.opt:111 #, no-c-format msgid "The smallest number of different values for which it is best to use a jump-table instead of a tree of conditional branches, if 0, use the default for the machine." -msgstr "" +msgstr "Мінімальна кількість різних значень, для яких краще використовувати таблицю переходів замість дерева умовних гілок, якщо 0, використовувати значення за замовчуванням для машини." #: params.opt:115 #, no-c-format msgid "Probability that COMDAT function will be shared with different compilation unit." -msgstr "" +msgstr "Ймовірність, що функція COMDAT буде спільно використовуватися з різними одиницями компіляції." #: params.opt:119 #, no-c-format msgid "Maximum number of namespaces to search for alternatives when name lookup fails." -msgstr "" +msgstr "Максимальна кількість просторів імен для пошуку альтернатив, коли пошук імені не вдається." #: params.opt:123 #, no-c-format msgid "Maximum number of queries into the alias oracle per store." -msgstr "" +msgstr "Максимальна кількість запитів до оракула псевдонімів на один обʼєкт зберігання." #: params.opt:127 #, no-c-format msgid "Maximum size (in bytes) of objects tracked bytewise by dead store elimination." -msgstr "" +msgstr "Максимальний розмір (у байтах) обʼєктів, відстежуваних по байтах при видаленні мертвих зберігань." #: params.opt:131 #, no-c-format msgid "Maximal estimated growth of function body caused by early inlining of single call." -msgstr "" +msgstr "Максимальне приблизне збільшення тіла функції, спричинене раннім включенням одного виклику." #: params.opt:135 #, no-c-format msgid "Maximum number of basic blocks before EVRP uses a sparse cache." -msgstr "" +msgstr "Максимальна кількість базових блоків, перед тим як EVRP використовує розріджений кеш." #: params.opt:139 #, no-c-format msgid "Maximum number of outgoing edges in a switch before EVRP will not process it." -msgstr "" +msgstr "Максимальна кількість вихідних ребер у перемикачі, перед тим як EVRP не буде обробляти його." #: params.opt:143 #, no-c-format msgid "Scale factor to apply to the number of statements in a threading path crossing a loop backedge when comparing to max-jump-thread-duplication-stmts." -msgstr "" +msgstr "Коефіцієнт масштабування, який застосовується до кількості операторів у шляху потоку, який перетинає зворотнє ребро петлі при порівнянні з max-jump-thread-duplication-stmts." #: params.opt:147 #, no-c-format msgid "The threshold ratio of critical edges execution count that permit performing redundancy elimination after reload." -msgstr "" +msgstr "Порогове співвідношення кількості виконання критичних ребер, яке дозволяє виконувати усунення зайвості після перезавантаження." #: params.opt:151 #, no-c-format msgid "The threshold ratio for performing partial redundancy elimination after reload." -msgstr "" +msgstr "Порогове співвідношення для виконання часткового усунення зайвості після перезавантаження." #: params.opt:155 #, no-c-format msgid "Scaling factor in calculation of maximum distance an expression can be moved by GCSE optimizations." -msgstr "" +msgstr "Коефіцієнт масштабування при розрахунку максимальної відстані, на яку вираз може бути переміщений оптимізаціями GCSE." #: params.opt:159 #, no-c-format msgid "Cost at which GCSE optimizations will not constraint the distance an expression can travel." -msgstr "" +msgstr "Вартість, при якій оптимізації GCSE не обмежуватимуть відстань, на яку може переміститися вираз." #: params.opt:163 #, no-c-format msgid "Minimum heap expansion to trigger garbage collection, as a percentage of the total size of the heap." -msgstr "" +msgstr "Мінімальне розширення купи, щоб спровокувати збірку сміття, відсоток від загального розміру купи." #: params.opt:167 #, no-c-format msgid "Minimum heap size before we start collecting garbage, in kilobytes." -msgstr "" +msgstr "Мінімальний розмір купи перед початком збору сміття, у кілобайтах." #: params.opt:171 #, no-c-format msgid "The number of executions of a basic block which is considered hot. The parameter is used only in GIMPLE FE." -msgstr "" +msgstr "Кількість виконань базового блоку, який вважається гарячим. Параметр використовується лише в GIMPLE FE." #: params.opt:175 #, no-c-format msgid "Whether codegen errors should be ICEs when -fchecking." -msgstr "" +msgstr "Чи повинні помилки codegen бути ICE, коли -fchecking." #: params.opt:179 #, no-c-format msgid "Maximum number of arrays per SCoP." -msgstr "" +msgstr "Максимальна кількість масивів на один SCoP." #: params.opt:183 #, no-c-format msgid "Maximum number of parameters in a SCoP." -msgstr "" +msgstr "Максимальна кількість параметрів в SCoP." #: params.opt:187 #, no-c-format msgid "The number of elements for which hash table verification is done for each searched element." -msgstr "" +msgstr "Кількість елементів, для яких виконується перевірка хеш-таблиці для кожного шуканого елемента." #: params.opt:191 #, no-c-format msgid "The denominator n of fraction 1/n of the maximal execution count of a basic block in the entire program that a basic block needs to at least have in order to be considered hot (used in non-LTO mode)." -msgstr "" +msgstr "Знаменник n дробу 1/n максимальної кількості виконань базового блоку в усій програмі, який базовий блок повинен мати, щоб вважатися гарячим (використовується в режимі non-LTO)." #: params.opt:195 #, no-c-format msgid "The number of most executed permilles of the profiled execution of the entire program to which the execution count of a basic block must be part of in order to be considered hot (used in LTO mode)." -msgstr "" +msgstr "Кількість найбільш виконуваних промілеїв профільованого виконання всієї програми, до яких повинна належати кількість виконань базового блоку, щоб вважати його гарячим (використовується в режимі LTO)." #: params.opt:199 #, no-c-format msgid "The denominator n of fraction 1/n of the execution frequency of the entry block of a function that a basic block of this function needs to at least have in order to be considered hot." -msgstr "" +msgstr "Знаменник n дробу 1/n частоти виконання вхідного блоку функції, який базовий блок цієї функції повинен мати принаймні, щоб вважатися гарячим." #: params.opt:203 #, no-c-format msgid "The scale (in percents) applied to inline-insns-single and auto limits when heuristics hints that inlining is very profitable." -msgstr "" +msgstr "Масштаб (у відсотках), який застосовується до лімітів inline-insns-single та auto, коли евристика натякає на те, що вбудовування є дуже прибутковим." #: params.opt:207 #, no-c-format msgid "The minimal estimated speedup allowing inliner to ignore inline-insns-single and inline-insns-auto." -msgstr "" +msgstr "Мінімальне приблизне прискорення, яке дозволяє інлайнеру ігнорувати inline-insns-single та inline-insns-auto." #: params.opt:211 #, no-c-format msgid "How much can given compilation unit grow because of the inlining (in percent)." -msgstr "" +msgstr "На скільки може зрости дана компіляційна одиниця через вбудовування (у відсотках)." #: params.opt:215 #, no-c-format msgid "The upper bound for sharing integer constants." -msgstr "" +msgstr "Верхня межа для спільного використання цілих констант." #: params.opt:219 #, no-c-format msgid "Threshold ipa-cp opportunity evaluation that is still considered beneficial to clone." -msgstr "" +msgstr "Поріг оцінки можливості ipa-cp, який все ще вважається корисним для клонування." #: params.opt:223 #, no-c-format msgid "Compile-time bonus IPA-CP assigns to candidates which make loop bounds or strides known." -msgstr "" +msgstr "Бонус на етапі компіляції, який IPA-CP надає кандидатам, які роблять межі циклу або кроки відомими." #: params.opt:227 #, no-c-format msgid "Maximum depth of recursive cloning for self-recursive function." -msgstr "" +msgstr "Максимальна глибина рекурсивного клонування для саморекурсивної функції." #: params.opt:231 #, no-c-format msgid "Recursive cloning only when the probability of call being executed exceeds the parameter." -msgstr "" +msgstr "Рекурсивне клонування тільки тоді, коли ймовірність виконання виклику перевищує параметр." #: params.opt:235 #, no-c-format msgid "When propagating IPA-CP effect estimates, multiply frequencies of recursive edges that bring back an unchanged value by this factor." -msgstr "" +msgstr "При поширенні оцінок ефекту IPA-CP, множте частоти рекурсивних ребер, які повертають незмінне значення, на цей множник." #: params.opt:239 #, no-c-format msgid "Percentage penalty the recursive functions will receive when they are evaluated for cloning." -msgstr "" +msgstr "Відсоткове покарання, яке рекурсивні функції отримають при оцінці для клонування." #: params.opt:243 #, no-c-format msgid "Percentage penalty functions containing a single call to another function will receive when they are evaluated for cloning." -msgstr "" +msgstr "Відсоткове покарання, яке функції, що містять один виклик іншої функції, отримають при оцінці для клонування." #: params.opt:247 #, no-c-format msgid "How much can given compilation unit grow because of the interprocedural constant propagation (in percent)." -msgstr "" +msgstr "На скільки може збільшитися задана компіляційна одиниця через міжпроцедурну поширення констант (у відсотках)." #: params.opt:251 #, no-c-format msgid "The size of translation unit that IPA-CP pass considers large." -msgstr "" +msgstr "Розмір перекладної одиниці, який прохід IPA-CP вважає великим." #: params.opt:255 #, no-c-format msgid "Maximum size of a list of values associated with each parameter for interprocedural constant propagation." -msgstr "" +msgstr "Максимальний розмір списку значень, повʼязаних з кожним параметром для міжпроцедурного поширення констант." #: params.opt:259 #, no-c-format msgid "When using profile feedback, use the edge at this percentage position in frequncy histogram as the bases for IPA-CP heuristics." -msgstr "" +msgstr "При використанні профілю зворотного звʼязку, використовуйте ребро на цій відсотковій позиції в гістограмі частот як основу для евристик IPA-CP." #: params.opt:263 #, no-c-format msgid "Maximum number of statements visited during jump function offset discovery." -msgstr "" +msgstr "Максимальна кількість відвідуваних операторів під час виявлення зміщення функції переходу." #: params.opt:267 #, no-c-format msgid "Maximum number of statements that will be visited by IPA formal parameter analysis based on alias analysis in any given function." -msgstr "" +msgstr "Максимальна кількість операторів, які будуть відвідані аналізом формальних параметрів IPA на основі аналізу псевдонімів у будь-якій заданій функції." #: params.opt:271 #, no-c-format msgid "Maximum number of aggregate content items for a parameter in jump functions and lattices." -msgstr "" +msgstr "Максимальна кількість елементів агрегатного вмісту для параметра в функціях переходу та решітках." #: params.opt:275 #, no-c-format msgid "Maximum number of operations in a parameter expression that can be handled by IPA analysis." -msgstr "" +msgstr "Максимальна кількість операцій у виразі параметра, які можуть бути оброблені аналізом IPA." #: params.opt:279 #, no-c-format msgid "Maximum number of different predicates used to track properties of loops in IPA analysis." -msgstr "" +msgstr "Максимальна кількість різних предикатів, що використовуються для відстеження властивостей циклів у аналізі IPA." #: params.opt:283 #, no-c-format msgid "Maximal number of boundary endpoints of case ranges of switch statement used during IPA function summary generation." -msgstr "" +msgstr "Максимальна кількість кінцевих точок границь діапазонів вказівок «case» в операторі «switch», які використовуються під час генерації підсумку функції IPA." #: params.opt:287 #, no-c-format msgid "Minimum probability (in percent) of dereferencing of a function pointer parameter for it to be considered for replacement with simple values." -msgstr "" +msgstr "Мінімальна ймовірність (у відсотках) розіменування параметра вказівника на функцію, щоб вважати його для заміни простими значеннями." #: params.opt:291 #, no-c-format msgid "Maximum pieces that IPA-SRA tracks per formal parameter, as a consequence, also the maximum number of replacements of a formal parameter." -msgstr "" +msgstr "Максимальна кількість шматків, які відстежує IPA-SRA для кожного формального параметра, внаслідок чого також максимальна кількість замін формального параметра." #: params.opt:295 #, no-c-format msgid "Maximum allowed growth of total size of new parameters that ipa-sra replaces a pointer to an aggregate with." -msgstr "" +msgstr "Максимально допустиме збільшення загального розміру нових параметрів, які ipa-sra замінює вказівником на агрегат." #: params.opt:299 #, no-c-format msgid "Additional maximum allowed growth of total size of new parameters that ipa-sra replaces a pointer to an aggregate with, if it points to a local variable that the caller only writes to and passes it as an argument to functions." -msgstr "" +msgstr "Додаткове максимально допустиме збільшення загального розміру нових параметрів, які ipa-sra замінює вказівником на агрегат, якщо він вказує на локальну змінну, яку викликач тільки записує і передає як аргумент до функцій." #: params.opt:303 #, no-c-format msgid "The number of registers in each class kept unused by loop invariant motion." -msgstr "" +msgstr "Кількість регістрів у кожному класі, які залишаються не використаними при руху незмінних циклів." #: params.opt:307 #, no-c-format msgid "Max size of conflict table in MB." -msgstr "" +msgstr "Максимальний розмір таблиці конфліктів в МБ." #: params.opt:311 #, no-c-format msgid "Approximate function insn number in 1K units triggering simple local RA." -msgstr "" +msgstr "Приблизна кількість інструкцій функції в одиницях 1K, що спричиняє просту локальну RA." #: params.opt:315 #, no-c-format msgid "Max loops number for regional RA." -msgstr "" +msgstr "Максимальна кількість циклів для регіональної RA." #: params.opt:319 #, no-c-format msgid "Control ira to consider matching constraint (duplicated operand number) heavily in all available alternatives for preferred register class. If it is set as zero, it means ira only respects the matching constraint when it's in the only available alternative with an appropriate register class. Otherwise, it means ira will check all available alternatives for preferred register class even if it has found some choice with an appropriate register class and respect the found qualified matching constraint." -msgstr "" +msgstr "Контролює, щоб IRA сильно враховувала відповідні обмеження (повторюване число операндів) у всіх доступних альтернативах для пріоритетного класу регістрів. Якщо встановлено значення нуль, це означає, що IRA враховує відповідні обмеження лише тоді, коли вона є єдиною доступною альтернативою з відповідним класом регістрів. В іншому випадку це означає, що IRA перевірить всі доступні альтернативи для пріоритетного класу регістрів, навіть якщо вона знайшла деякий вибір з відповідним класом регістрів і врахує знайдене відповідне обмеження." #: params.opt:323 #, no-c-format msgid "If number of candidates in the set is smaller, we always try to remove unused ivs during its optimization." -msgstr "" +msgstr "Якщо кількість кандидатів у наборі менша, ми завжди намагаємося видалити невикористані ivs під час їх оптимізації." #: params.opt:327 #, no-c-format msgid "Bound on number of candidates below that all candidates are considered in iv optimizations." -msgstr "" +msgstr "Межа кількості кандидатів, нижче якої всі кандидати вважаються в оптимізації iv." #: params.opt:331 #, no-c-format msgid "Bound on number of iv uses in loop optimized in iv optimizations." -msgstr "" +msgstr "Межа кількості використань iv в оптимізованій петлі в оптимізації iv." #: params.opt:335 #, no-c-format msgid "The maximum code size growth ratio when expanding into a jump table (in percent). The parameter is used when optimizing for size." -msgstr "" +msgstr "Максимальний відсоток зростання розміру коду при розширенні в таблицю переходів. Параметр використовується при оптимізації за розміром." #: params.opt:339 #, no-c-format msgid "The maximum code size growth ratio when expanding into a jump table (in percent). The parameter is used when optimizing for speed." -msgstr "" +msgstr "Максимальний відсоток зростання розміру коду при розширенні в таблицю переходів. Параметр використовується при оптимізації за швидкістю." #: params.opt:343 #, no-c-format msgid "The size of L1 cache line." -msgstr "" +msgstr "Розмір лінії кешу L1." #: params.opt:347 #, no-c-format msgid "The minimum recommended offset between two concurrently-accessed objects to avoid additional performance degradation due to contention introduced by the implementation. Typically the L1 cache line size, but can be larger to accommodate a variety of target processors with different cache line sizes. C++17 code might use this value in structure layout, but is strongly discouraged from doing so in public ABIs." -msgstr "" +msgstr "Мінімально рекомендований зсув між двома обʼєктами, на які одночасно здійснюється доступ, щоб уникнути додаткового зниження продуктивності через конфлікти, викликані реалізацією. Зазвичай це розмір лінії кешу L1, але може бути більшим, щоб врахувати різні розміри ліній кешу для різних цільових процесорів. Код C++17 може використовувати це значення в структурному розташуванні, але це настійно не рекомендується робити в публічних ABIs." #: params.opt:356 #, no-c-format msgid "The maximum recommended size of contiguous memory occupied by two objects accessed with temporal locality by concurrent threads. Typically the L1 cache line size, but can be smaller to accommodate a variety of target processors with different cache line sizes." -msgstr "" +msgstr "Максимально рекомендований розмір послідовної памʼяті, яку займають два обʼєкти, на які одночасно здійснюється доступ з тимчасовою локальністю потоків. Зазвичай це розмір лінії кешу L1, але може бути меншим, щоб врахувати різні розміри ліній кешу для різних цільових процесорів." #: params.opt:363 #, no-c-format msgid "The size of L1 cache." -msgstr "" +msgstr "Розмір кешу L1." #: params.opt:367 #, no-c-format msgid "The size of L2 cache." -msgstr "" +msgstr "Розмір кешу L2." #: params.opt:371 #, no-c-format msgid "Maximal growth due to inlining of large function (in percent)." -msgstr "" +msgstr "Максимальне зростання внаслідок вбудовування великої функції (у відсотках)." #: params.opt:375 #, no-c-format msgid "The size of function body to be considered large." -msgstr "" +msgstr "Розмір тіла функції, яке вважається великим." #: params.opt:379 #, no-c-format msgid "The size of stack frame to be considered large." -msgstr "" +msgstr "Розмір стекової рамки, який вважається великим." #: params.opt:383 #, no-c-format msgid "Maximal stack frame growth due to inlining (in percent)." -msgstr "" +msgstr "Максимальне зростання стекової рамки внаслідок вбудовування (у відсотках)." #: params.opt:387 #, no-c-format msgid "The size of translation unit to be considered large." -msgstr "" +msgstr "Розмір одиниці перекладу, який вважається великим." #: params.opt:391 #, no-c-format msgid "Maximum number of concurrently open C++ module files when lazy loading." -msgstr "" +msgstr "Максимальна кількість одночасно відкритих файлів модулів C++ при лінивому завантаженні." #: params.opt:395 #, no-c-format msgid "The minimum cost of an expensive expression in the loop invariant motion." -msgstr "" +msgstr "Мінімальна вартість дорогого виразу в незмінному русі циклу." #: params.opt:399 #, no-c-format msgid "True if a non-short-circuit operation is optimal." -msgstr "" +msgstr "True, якщо некороткозамкнена операція є оптимальною." #: params.opt:403 #, no-c-format msgid "Size of tiles for loop blocking." -msgstr "" +msgstr "Розмір блоків для блокування циклу." #: params.opt:407 #, no-c-format msgid "The maximum number of stmts in loop nest for loop interchange." -msgstr "" +msgstr "Максимальна кількість операторів у вкладеному циклі для обміну циклів." #: params.opt:411 #, no-c-format msgid "The minimum stride ratio for loop interchange to be profitable." -msgstr "" +msgstr "Мінімальне співвідношення кроків, за якого обмін циклів є прибутковим." #: params.opt:415 #, no-c-format msgid "Max basic blocks number in loop for loop invariant motion." -msgstr "" +msgstr "Максимальна кількість основних блоків у циклі для переміщення незмінних частин циклу." #: params.opt:419 #, no-c-format msgid "Maximum number of datarefs in loop for building loop data dependencies." -msgstr "" +msgstr "Максимальна кількість посилань на дані у циклі для побудови залежностей даних циклу." #: params.opt:423 #, no-c-format msgid "The maximum number of instructions in an inner loop that is being considered for versioning." -msgstr "" +msgstr "Максимальна кількість інструкцій у внутрішньому циклі, який розглядається для версіювання." #: params.opt:427 #, no-c-format msgid "The maximum number of instructions in an outer loop that is being considered for versioning, on top of the instructions in inner loops." -msgstr "" +msgstr "Максимальна кількість інструкцій у зовнішній петлі, яка розглядається для версіонування, на основі інструкцій у внутрішніх петлях." #: params.opt:431 #, no-c-format msgid "Minimal fall-through edge probability in percentage used to add BB to inheritance EBB in LRA." -msgstr "" +msgstr "Мінімальна ймовірність падіння краю у відсотках, яка використовується для додавання BB до успадкованого EBB у LRA." #: params.opt:435 #, no-c-format msgid "The max number of reload pseudos which are considered during spilling a non-reload pseudo." -msgstr "" +msgstr "Максимальна кількість псевдо-перезавантажень, які враховуються під час виливання псевдо-перезавантаження, яке не є перезавантаженням." #: params.opt:439 #, no-c-format msgid "Maximal size of a partition for LTO (in estimated instructions)." -msgstr "" +msgstr "Максимальний розмір розділу для LTO (у приблизних інструкціях)." #: params.opt:443 #, no-c-format msgid "maximal number of LTO partitions streamed in parallel." -msgstr "" +msgstr "максимальна кількість паралельно транслюваних розділів LTO." #: params.opt:447 #, no-c-format msgid "Minimal size of a partition for LTO (in estimated instructions)." -msgstr "" +msgstr "Мінімальний розмір розділу для LTO (у приблизних інструкціях)." #: params.opt:451 #, no-c-format msgid "Number of partitions the program should be split to." -msgstr "" +msgstr "Кількість розділів, на які програма повинна бути розбита." #: params.opt:455 #, no-c-format msgid "The maximum number of instructions to consider to unroll in a loop on average." -msgstr "" +msgstr "Максимальна кількість інструкцій, які слід розглянути для розгортання в середньому в циклі." #: params.opt:459 #, no-c-format msgid "The maximum number of insns combine tries to combine." -msgstr "" +msgstr "Максимальна кількість спроб комбінування інструкцій." #: params.opt:463 #, no-c-format msgid "The maximum depth of a loop nest we completely peel." -msgstr "" +msgstr "Максимальна глибина вкладеного циклу, який ми повністю розгортаємо." #: params.opt:467 #, no-c-format msgid "The maximum number of peelings of a single loop that is peeled completely." -msgstr "" +msgstr "Максимальна кількість розгортань одного циклу, який повністю розгортається." #: params.opt:471 #, no-c-format msgid "The maximum number of insns of a completely peeled loop." -msgstr "" +msgstr "Максимальна кількість інструкцій повністю розгорнутого циклу." #: params.opt:475 #, no-c-format msgid "The maximum number of incoming edges to consider for crossjumping." -msgstr "" +msgstr "Максимальна кількість вхідних ребер, які слід враховувати для перескоку." #: params.opt:479 #, no-c-format msgid "The maximum instructions CSE process before flushing." -msgstr "" +msgstr "Максимальна кількість інструкцій, яку CSE обробляє перед очищенням." #: params.opt:483 #, no-c-format msgid "The maximum length of path considered in cse." -msgstr "" +msgstr "Максимальна довжина шляху, який розглядається в cse." #: params.opt:487 #, no-c-format msgid "The maximum memory locations recorded by cselib." -msgstr "" +msgstr "Максимальна кількість місць памʼяті, які записуються cselib." #: params.opt:491 #, no-c-format msgid "Max. count of debug markers to expand or inline." -msgstr "" +msgstr "Максимальна кількість маркерів відлагодження для розширення або вбудовування." #: params.opt:495 #, no-c-format msgid "The maximum number of instructions to consider to fill a delay slot." -msgstr "" +msgstr "Максимальна кількість інструкцій, яку слід враховувати для заповнення затримки." #: params.opt:499 #, no-c-format msgid "The maximum number of instructions to consider to find accurate live register information." -msgstr "" +msgstr "Максимальна кількість інструкцій, яку слід враховувати для пошуку точної інформації про живі реєстри." #: params.opt:503 #, no-c-format msgid "Maximum number of active local stores in RTL dead store elimination." -msgstr "" +msgstr "Максимальна кількість активних локальних зберігань у видаленні RTL мертвих зберігань." #: params.opt:507 #, no-c-format msgid "The maximum number of nested indirect inlining performed by early inliner." -msgstr "" +msgstr "Максимальна кількість вкладених операцій непрямого вбудовування, виконаних раннім вбудовувачем." #: params.opt:511 #, no-c-format msgid "Maximum number of fields in a structure before pointer analysis treats the structure as a single variable." -msgstr "" +msgstr "Максимальна кількість полів у структурі, перед тим як аналіз вказівників розглядатиме структуру як одну змінну." #: params.opt:515 #, no-c-format msgid "Maximum number of instructions to copy when duplicating blocks on a finite state automaton jump thread path." -msgstr "" +msgstr "Максимальна кількість інструкцій для копіювання при дублюванні блоків на шляху переходу потоку скінченного автомата станів." #: params.opt:519 #, no-c-format msgid "The maximum ratio of insertions to deletions of expressions in GCSE." -msgstr "" +msgstr "Максимальне співвідношення вставок до видалень виразів у GCSE." #: params.opt:523 #, no-c-format msgid "The maximum amount of memory to be allocated by GCSE, in kilobytes." -msgstr "" +msgstr "Максимальний обсяг памʼяті, який буде виділено GCSE, в кілобайтах." #: params.opt:527 #, no-c-format msgid "The maximum number of insns to duplicate when unfactoring computed gotos." -msgstr "" +msgstr "Максимальна кількість інструкцій для дублювання при розкритті обчислених переходів." #: params.opt:531 #, no-c-format msgid "The maximum expansion factor when copying basic blocks." -msgstr "" +msgstr "Максимальний коефіцієнт розширення при копіюванні базових блоків." #: params.opt:535 #, no-c-format msgid "Maximum depth of search in the dominator tree for expressions to hoist." -msgstr "" +msgstr "Максимальна глибина пошуку в дереві домінаторів для виносу виразів." #: params.opt:539 #, no-c-format msgid "Maximum loop depth of a call which is considered for inlining functions called once." -msgstr "" +msgstr "Максимальна глибина циклу виклику, яка враховується при включенні функцій, які викликаються один раз." #: params.opt:543 #, no-c-format msgid "Maximum combined size of caller and callee which is inlined if callee is called once." -msgstr "" +msgstr "Максимальний комбінований розмір викликаючого та викликаного, який включається, якщо викликана функція викликається один раз." #: params.opt:547 #, no-c-format msgid "The maximum number of instructions when automatically inlining." -msgstr "" +msgstr "Максимальна кількість інструкцій при автоматичному включенні." #: params.opt:551 #, no-c-format msgid "The maximum number of instructions inline function can grow to via recursive inlining." -msgstr "" +msgstr "Максимальна кількість інструкцій, до якої може зрости включена функція за допомогою рекурсивного включення." #: params.opt:555 #, no-c-format msgid "The maximum number of instructions non-inline function can grow to via recursive inlining." -msgstr "" +msgstr "Максимальна кількість інструкцій, на яку може збільшитися невбудована функція за допомогою рекурсивного вбудовування." #: params.opt:559 #, no-c-format msgid "The maximum number of instructions in a single function eligible for inlining." -msgstr "" +msgstr "Максимальна кількість інструкцій у одній функції, яка може бути вбудована." #: params.opt:563 #, no-c-format msgid "The maximum number of instructions when inlining for size." -msgstr "" +msgstr "Максимальна кількість інструкцій при вбудовуванні для зменшення розміру." #: params.opt:567 #, no-c-format msgid "The maximum number of instructions when automatically inlining small functions." -msgstr "" +msgstr "Максимальна кількість інструкцій при автоматичному вбудовуванні невеликих функцій." #: params.opt:571 #, no-c-format msgid "The maximum depth of recursive inlining for inline functions." -msgstr "" +msgstr "Максимальна глибина рекурсивного вбудовування для вбудованих функцій." #: params.opt:575 #, no-c-format msgid "The maximum depth of recursive inlining for non-inline functions." -msgstr "" +msgstr "Максимальна глибина рекурсивного вбудовування для невбудованих функцій." #: params.opt:579 #, no-c-format msgid "Maximum number of isl operations, 0 means unlimited." -msgstr "" +msgstr "Максимальна кількість операцій ISL, 0 означає необмежено." #: params.opt:583 #, no-c-format msgid "Bound on the cost of an expression to compute the number of iterations." -msgstr "" +msgstr "Обмеження на вартість виразу для обчислення кількості ітерацій." #: params.opt:587 #, no-c-format msgid "Bound on the number of iterations the brute force # of iterations analysis algorithm evaluates." -msgstr "" +msgstr "Обмеження на кількість ітерацій, яку алгоритм аналізу кількості ітерацій методом грубої сили оцінює." #: params.opt:591 #, no-c-format msgid "Maximum number of statements allowed in a block that needs to be duplicated when threading jumps." -msgstr "" +msgstr "Максимальна кількість операторів, дозволених у блоку, який потрібно дублювати при звʼязуванні стрибків." #: params.opt:595 #, no-c-format msgid "Search space limit for the backwards jump threader." -msgstr "" +msgstr "Обмеження простору пошуку для зворотнього розгалужувача переходів." #: params.opt:599 #, no-c-format msgid "The maximum number of RTL nodes that can be recorded as combiner's last value." -msgstr "" +msgstr "Максимальна кількість вузлів RTL, які можуть бути записані як останнє значення комбінатора." #: params.opt:603 #, no-c-format msgid "The maximum number of insns in loop header duplicated by the copy loop headers pass." -msgstr "" +msgstr "Максимальна кількість інструкцій в заголовку циклу, які дублюються за допомогою проходу копіювання заголовків циклів." #: params.opt:607 #, no-c-format msgid "The maximum number of backtrack attempts the scheduler should make when modulo scheduling a loop." -msgstr "" +msgstr "Максимальна кількість спроб повернення назад, яку планувальник повинен зробити при модульному плануванні циклу." #: params.opt:611 #, no-c-format msgid "Minimum page size for warning purposes." -msgstr "" +msgstr "Мінімальний розмір сторінки для цілей попередження." #: params.opt:615 #, no-c-format msgid "Maximum length of partial antic set when performing tree pre optimization." -msgstr "" +msgstr "Максимальна довжина часткового набору ANTIC при виконанні попередньої оптимізації дерева." #: params.opt:619 #, no-c-format msgid "The maximum number of branches on the path through the peeled sequence." -msgstr "" +msgstr "Максимальна кількість гілок на шляху через розгорнуту послідовність." #: params.opt:623 #, no-c-format msgid "The maximum number of peelings of a single loop." -msgstr "" +msgstr "Максимальна кількість розгортань одного циклу." #: params.opt:627 #, no-c-format msgid "The maximum number of insns of a peeled loop." -msgstr "" +msgstr "Максимальна кількість інструкцій в розгорнутій петлі." #: params.opt:631 #, no-c-format msgid "The maximum length of scheduling's pending operations list." -msgstr "" +msgstr "Максимальна довжина списку очікуваних операцій планування." #: params.opt:635 params.opt:679 #, no-c-format msgid "The maximum number of blocks in a region to be considered for interblock scheduling." -msgstr "" +msgstr "Максимальна кількість блоків у регіоні, які будуть враховуватися при міжблоковому плануванні." #: params.opt:639 params.opt:683 #, no-c-format msgid "The maximum number of insns in a region to be considered for interblock scheduling." -msgstr "" +msgstr "Максимальна кількість інструкцій у регіоні, які будуть враховуватися при міжблоковому плануванні." #: params.opt:643 #, no-c-format msgid "Maximum depth of sqrt chains to use when synthesizing exponentiation by a real constant." -msgstr "" +msgstr "Максимальна глибина ланцюгів квадратних коренів, яку слід використовувати при синтезуванні піднесення до степеня за допомогою дійсної константи." #: params.opt:647 #, no-c-format msgid "The maximum number of loop iterations we predict statically." -msgstr "" +msgstr "Максимальна кількість ітерацій циклу, яку ми прогнозуємо статично." #: params.opt:651 #, no-c-format msgid "The maximum number of instructions to search backward when looking for equivalent reload." -msgstr "" +msgstr "Максимальна кількість інструкцій для пошуку назад при пошуку еквівалентного перезавантаження." #: params.opt:655 #, no-c-format msgid "Maximum number of insns in a basic block to consider for RTL if-conversion." -msgstr "" +msgstr "Максимальна кількість інструкцій у базовому блоку, які слід враховувати для RTL-перетворення if." #: params.opt:659 #, no-c-format msgid "Maximum permissible cost for the sequence that would be generated by the RTL if-conversion pass for a branch that is considered predictable." -msgstr "" +msgstr "Максимально допустима вартість послідовності, яка буде створена проходом RTL-конвертації if для гілки, яка вважається передбачуваною." #: params.opt:663 #, no-c-format msgid "Maximum permissible cost for the sequence that would be generated by the RTL if-conversion pass for a branch that is considered unpredictable." -msgstr "" +msgstr "Максимально допустима вартість послідовності, яка буде створена проходом RTL-конвертації if для гілки, яка вважається непередбачуваною." #: params.opt:667 #, no-c-format msgid "The maximum number of iterations through CFG to extend regions." -msgstr "" +msgstr "Максимальна кількість ітерацій через CFG для розширення регіонів." #: params.opt:671 #, no-c-format msgid "The maximum conflict delay for an insn to be considered for speculative motion." -msgstr "" +msgstr "Максимальна затримка конфлікту для інструкції, яка розглядається для спекулятивного переміщення." #: params.opt:675 #, no-c-format msgid "The maximum number of instructions ready to be issued to be considered by the scheduler during the first scheduling pass." -msgstr "" +msgstr "Максимальна кількість інструкцій, готових до виконання, які розглядаються планувальником під час першого проходу планування." #: params.opt:687 #, no-c-format msgid "Maximum length of candidate scans for straight-line strength reduction." -msgstr "" +msgstr "Максимальна довжина кандидатського сканування для зменшення сили прямолінійного редукції." #: params.opt:691 #, no-c-format msgid "Maximum number of may-defs visited when devirtualizing speculatively." -msgstr "" +msgstr "Максимальна кількість відвідуваних may-defs при спекулятивній девіртуалізації." #: params.opt:695 #, no-c-format msgid "Maximum recursion depth allowed when querying a property of an SSA name." -msgstr "" +msgstr "Максимальна глибина рекурсії, дозволена при запиті властивості імені SSA." #: params.opt:699 #, no-c-format msgid "Maximum number of constant stores to merge in the store merging pass." -msgstr "" +msgstr "Максимальна кількість константних сховищ для злиття в проході злиття сховищ." #: params.opt:703 #, no-c-format msgid "Maximum number of conditional store pairs that can be sunk." -msgstr "" +msgstr "Максимальна кількість умовних пар зберігань, які можуть бути занурені." #: params.opt:707 params.opt:711 #, no-c-format msgid "Maximum number of store chains to track at the same time in the store merging pass." -msgstr "" +msgstr "Максимальна кількість ланцюжків зберігань, які слідкуватимуть одночасно в проході обʼєднання зберігань." #: params.opt:715 #, no-c-format msgid "Maximum amount of similar bbs to compare a bb with." -msgstr "" +msgstr "Максимальна кількість схожих базових блоків для порівняння з базовим блоком." #: params.opt:719 #, no-c-format msgid "Maximum amount of iterations of the pass over a function." -msgstr "" +msgstr "Максимальна кількість ітерацій проходу через функцію." #: params.opt:723 #, no-c-format msgid "Maximum number of strings for which strlen optimization pass will track string lengths." -msgstr "" +msgstr "Максимальна кількість рядків, для яких прохід оптимізації strlen відстежує довжини рядків." #: params.opt:727 #, no-c-format msgid "Maximum number of arguments in a PHI supported by TREE if-conversion unless the loop is marked with simd pragma." -msgstr "" +msgstr "Максимальна кількість аргументів в PHI, підтримуваному TREE if-конвертацією, якщо цикл не позначений simd pragma." #: params.opt:731 #, no-c-format msgid "The maximum number of unrollings of a single loop." -msgstr "" +msgstr "Максимальна кількість розгортань однієї петлі." #: params.opt:735 #, no-c-format msgid "The maximum number of instructions to consider to unroll in a loop." -msgstr "" +msgstr "Максимальна кількість інструкцій, які слід розгортати в петлі." #: params.opt:739 #, no-c-format msgid "The maximum number of insns of an unswitched loop." -msgstr "" +msgstr "Максимальна кількість інструкцій нерозгорнутої петлі." #: params.opt:743 #, no-c-format msgid "The maximum depth of a loop nest to be unswitched." -msgstr "" +msgstr "Максимальна глибина вкладеного циклу, який буде переключений." #: params.opt:747 #, no-c-format msgid "If -fvariable-expansion-in-unroller is used, the maximum number of times that an individual variable will be expanded during loop unrolling." -msgstr "" +msgstr "Якщо використовується -fvariable-expansion-in-unroller, максимальна кількість разів, коли окрема змінна буде розгорнута під час розгортання циклу." #: params.opt:751 #, no-c-format msgid "Max. recursion depth for expanding var tracking expressions." -msgstr "" +msgstr "Максимальна глибина рекурсії для розгортання виразів відстеження змінних." #: params.opt:755 #, no-c-format msgid "Max. size of loc list for which reverse ops should be added." -msgstr "" +msgstr "Максимальний розмір списку loc, для якого слід додавати зворотні операції." #: params.opt:759 #, no-c-format msgid "Max. size of var tracking hash tables." -msgstr "" +msgstr "Максимальний розмір хеш-таблиць відстеження змінних." #: params.opt:763 #, no-c-format msgid "Maximum number of VALUEs handled during a single find_base_term call." -msgstr "" +msgstr "Максимальна кількість значень, оброблених під час одного виклику find_base_term." #: params.opt:767 #, no-c-format msgid "The minimum number of matching instructions to consider for crossjumping." -msgstr "" +msgstr "Мінімальна кількість відповідних інструкцій для розгляду при перескакуванні." #: params.opt:771 #, no-c-format msgid "Inline recursively only when the probability of call being executed exceeds the parameter." -msgstr "" +msgstr "Вбудовувати рекурсивно лише тоді, коли ймовірність виконання виклику перевищує параметр." #: params.opt:775 #, no-c-format msgid "Min. ratio of insns to prefetches to enable prefetching for a loop with an unknown trip count." -msgstr "" +msgstr "Мінімальне співвідношення інструкцій до попередніх завантажень, щоб увімкнути попереднє завантаження для петлі з невідомим лічильником проходів." #: params.opt:779 #, no-c-format msgid "The minimum threshold for probability of semi-invariant condition statement to trigger loop split." -msgstr "" +msgstr "Мінімальний поріг ймовірності умовного оператора напівнезмінності для спрацювання розбиття петлі." #: params.opt:783 #, no-c-format msgid "The minimum UID to be used for a nondebug insn." -msgstr "" +msgstr "Мінімальний UID, який слід використовувати для не відлагоджувальної інструкції." #: params.opt:787 #, no-c-format msgid "The minimum size of variables taking part in stack slot sharing when not optimizing." -msgstr "" +msgstr "Мінімальний розмір змінних, які беруть участь у спільному використанні слотів стеку при відсутності оптимізації." #: params.opt:791 #, no-c-format msgid "The minimum probability of reaching a source block for interblock speculative scheduling." -msgstr "" +msgstr "Мінімальна ймовірність досягнення початкового блоку для міжблочного спекулятивного планування." #: params.opt:795 #, no-c-format msgid "If -ftree-vectorize is used, the minimal loop bound of a loop to be considered for vectorization." -msgstr "" +msgstr "Якщо використовується -ftree-vectorize, мінімальна межа циклу циклу, який буде розглядатися для векторизації." #: params.opt:799 #, no-c-format msgid "--param=openacc-kernels=[decompose|parloops]\tSpecify mode of OpenACC 'kernels' constructs handling." -msgstr "" +msgstr "--param=openacc-kernels=[decompose|parloops]\tВказати режим обробки конструкцій OpenACC 'kernels'." #: params.opt:812 #, no-c-format msgid "--param=openacc-privatization=[quiet|noisy]\tSpecify mode of OpenACC privatization diagnostics." -msgstr "" +msgstr "--param=openacc-privatization=[quiet|noisy]\tВказати режим діагностики приватизації OpenACC." #: params.opt:825 #, no-c-format msgid "Chunk size of omp schedule for loops parallelized by parloops." -msgstr "" +msgstr "Розмір порції розкладу omp для циклів, які паралелізуються за допомогою parloops." #: params.opt:829 #, no-c-format msgid "Minimum number of iterations per thread of an innermost parallelized loop." -msgstr "" +msgstr "Мінімальна кількість ітерацій на потік найвнутрішньої паралельної петлі." #: params.opt:833 #, no-c-format msgid "--param=parloops-schedule=[static|dynamic|guided|auto|runtime]\tSchedule type of omp schedule for loops parallelized by parloops." -msgstr "" +msgstr "--param=parloops-schedule=[static|dynamic|guided|auto|runtime]\tТип розкладу omp для петель, які паралелізуються за допомогою parloops." #: params.opt:855 #, no-c-format msgid "Maximum probability of the entry BB of split region (in percent relative to entry BB of the function) to make partial inlining happen." -msgstr "" +msgstr "Максимальна ймовірність входу BB розділеної області (у відсотках відносно входу BB функції), щоб відбулося часткове вбудовування." #: params.opt:859 #, no-c-format msgid "Maximal estimated outcome of branch considered predictable." -msgstr "" +msgstr "Максимально оціненний результат розгалуження, вважається передбачуваним." #: params.opt:863 #, no-c-format msgid "Whether software prefetch hints should be issued for non-constant strides." -msgstr "" +msgstr "Чи слід видавати підказки про програмне попереднє завантаження для несталої кроку." #: params.opt:867 #, no-c-format msgid "The number of insns executed before prefetch is completed." -msgstr "" +msgstr "Кількість виконаних інструкцій до завершення попереднього завантаження." #: params.opt:871 #, no-c-format msgid "Min. ratio of insns to mem ops to enable prefetching in a loop." -msgstr "" +msgstr "Мінімальне співвідношення інструкцій до операцій з памʼяттю для включення попереднього завантаження в циклі." #: params.opt:875 #, no-c-format msgid "The minimum constant stride beyond which we should use prefetch hints for." -msgstr "" +msgstr "Мінімальний константний крок, після якого ми повинні використовувати підказки для попереднього завантаження." #: params.opt:879 #, no-c-format msgid "Use internal function id in profile lookup." -msgstr "" +msgstr "Використовувати внутрішній ідентифікатор функції при пошуку в профілі." #: params.opt:883 #, no-c-format msgid "--param=ranger-debug=[none|trace|gori|cache|tracegori|all] Specifies the output mode for debugging ranger." -msgstr "" +msgstr "--param=ranger-debug=[none|trace|gori|cache|tracegori|all] Вказує режим виведення для налагодження рейнджера." #: params.opt:908 #, no-c-format msgid "Maximum depth of logical expression evaluation ranger will look through when evaluating outgoing edge ranges." -msgstr "" +msgstr "Максимальна глибина оцінки логічних виразів, яку рейнджер буде розглядати при оцінці діапазонів вихідних ребер." #: params.opt:913 #, no-c-format msgid "Maximum depth of instruction chains to consider for recomputation in the outgoing range calculator." -msgstr "" +msgstr "Максимальна глибина ланцюжків інструкцій, яку слід враховувати для повторного обчислення в калькуляторі діапазону вихідних значень." #: params.opt:918 #, no-c-format msgid "Maximum number of relations the oracle will register in a basic block." -msgstr "" +msgstr "Максимальна кількість відношень, які оракул зареєструє в базовому блоку." #: params.opt:922 #, no-c-format msgid "Maximum depth of a loop nest to fully value-number optimistically." -msgstr "" +msgstr "Максимальна глибина вкладеності циклу для повного оптимізму числових значень." #: params.opt:926 #, no-c-format msgid "Maximum number of disambiguations to perform per memory access." -msgstr "" +msgstr "Максимальна кількість розрізнень, які потрібно виконати для кожного доступу до памʼяті." #: params.opt:930 #, no-c-format msgid "Bound on the complexity of the expressions in the scalar evolutions analyzer." -msgstr "" +msgstr "Обмеження на складність виразів в аналізаторі еволюцій скалярів." #: params.opt:934 #, no-c-format msgid "Bound on size of expressions used in the scalar evolutions analyzer." -msgstr "" +msgstr "Обмеження на розмір виразів, що використовуються в аналізаторі еволюцій скалярів." #: params.opt:938 #, no-c-format msgid "Hardware autoprefetcher scheduler model control flag. Number of lookahead cycles the model looks into, at '0' only enable instruction sorting heuristic. Disabled by default." -msgstr "" +msgstr "Прапорець керування моделлю планувальника автоматичної передвантаження апаратного забезпечення. Кількість циклів попереднього перегляду, які модель розглядає, при значенні «0» активує лише евристику сортування інструкцій. За замовчуванням вимкнено." #: params.opt:942 #, no-c-format msgid "Minimal distance between possibly conflicting store and load." -msgstr "" +msgstr "Мінімальна відстань між можливо конфліктуючими командами store та load." #: params.opt:946 #, no-c-format msgid "Which -fsched-pressure algorithm to apply." -msgstr "" +msgstr "Який алгоритм -fsched-pressure застосувати." #: params.opt:950 #, no-c-format msgid "The minimal probability of speculation success (in percents), so that speculative insn will be scheduled." -msgstr "" +msgstr "Мінімальна ймовірність успішної спекуляції (у відсотках), щоб спекулятивна інструкція була запланована." #: params.opt:954 #, no-c-format msgid "The minimum probability an edge must have for the scheduler to save its state across it." -msgstr "" +msgstr "Мінімальна ймовірність, яку має мати ребро, щоб планувальник зберігав свій стан через нього." #: params.opt:958 #, no-c-format msgid "Maximum number of instructions in the ready list that are considered eligible for renaming." -msgstr "" +msgstr "Максимальна кількість інструкцій у списку готових, які вважаються придатними для перейменування." #: params.opt:962 #, no-c-format msgid "The maximum size of the lookahead window of selective scheduling." -msgstr "" +msgstr "Максимальний розмір вікна попереднього перегляду вибіркового планування." #: params.opt:966 #, no-c-format msgid "Maximum number of times that an insn could be scheduled." -msgstr "" +msgstr "Максимальна кількість разів, коли можна запланувати інструкцію." #: params.opt:970 #, no-c-format msgid "The number of prefetches that can run at the same time." -msgstr "" +msgstr "Кількість попередніх завантажень, які можуть працювати одночасно." #: params.opt:974 #, no-c-format msgid "Target block's relative execution frequency (as a percentage) required to sink a statement." -msgstr "" +msgstr "Відносна частота виконання цільового блоку (у відсотках), необхідна для занурення оператора." #: params.opt:978 #, no-c-format msgid "The number of cycles the swing modulo scheduler considers when checking conflicts using DFA." -msgstr "" +msgstr "Кількість циклів, які розглядає планувальник модуля Swing при перевірці конфліктів за допомогою DFA." #: params.opt:982 #, no-c-format msgid "A threshold on the average loop count considered by the swing modulo scheduler." -msgstr "" +msgstr "Поріг середнього лічильника циклів, який враховує планувальник модуляції качеля." #: params.opt:986 #, no-c-format msgid "A factor for tuning the upper bound that swing modulo scheduler uses for scheduling a loop." -msgstr "" +msgstr "Фактор для налаштування верхньої межі, яку використовує планувальник модуляції Swing для планування циклу." #: params.opt:990 #, no-c-format msgid "The minimum value of stage count that swing modulo scheduler will generate." -msgstr "" +msgstr "Мінімальне значення кількості етапів, яку згенерує планувальник модуляції качеля." #: params.opt:994 #, no-c-format msgid "Maximum size, in storage units, of an aggregate which should be considered for scalarization when compiling for size." -msgstr "" +msgstr "Максимальний розмір, в одиницях зберігання, агрегату, який слід враховувати для скаляризації при компіляції для розміру." #: params.opt:998 #, no-c-format msgid "Maximum size, in storage units, of an aggregate which should be considered for scalarization when compiling for speed." -msgstr "" +msgstr "Максимальний розмір, в одиницях зберігання, агрегату, який слід враховувати для скаляризації при компіляції для швидкості." #: params.opt:1002 #, no-c-format msgid "Maximum number of artificial accesses to enable forward propagation that Scalar Replacement of Aggregates will keep for one local variable." -msgstr "" +msgstr "Максимальна кількість штучних доступів, яку Scalar Replacement of Aggregates збереже для однієї локальної змінної для активації прямого поширення." #: params.opt:1006 #, no-c-format msgid "The maximum number of SSA_NAME assignments to follow in determining a value." -msgstr "" +msgstr "Максимальна кількість присвоєнь SSA_NAME, які слід виконати для визначення значення." #: params.opt:1010 #, no-c-format msgid "The lower bound for a buffer to be considered for stack smashing protection." -msgstr "" +msgstr "Нижня межа буфера, який розглядається для захисту від руйнування стеку." #: params.opt:1014 #, no-c-format msgid "Size of the stack guard expressed as a power of two in bytes." -msgstr "" +msgstr "Розмір захисника стеку, виражений як степінь двійки в байтах." #: params.opt:1018 #, no-c-format msgid "Interval in which to probe the stack expressed as a power of two in bytes." -msgstr "" +msgstr "Інтервал, в якому проводиться перевірка стеку, виражений як степінь двійки в байтах." #: params.opt:1022 #, no-c-format msgid "Allow the store merging pass to introduce unaligned stores if it is legal to do so." -msgstr "" +msgstr "Дозволити прохід з обʼєднанням зберігання вводити незбалансовані зберігання, якщо це юридично допустимо." #: params.opt:1026 #, no-c-format msgid "Maximum size of a single store merging region in bytes." -msgstr "" +msgstr "Максимальний розмір одного обʼєднаного регіону зберігання в байтах." #: params.opt:1030 #, no-c-format msgid "The maximum ratio between array size and switch branches for a switch conversion to take place." -msgstr "Максимальне значення відношення розміру масиву до кількості відгалужень перемикання для перетворення на перемикання." +msgstr "Максимальне співвідношення між розміром масиву та гілками перемикача, при якому відбувається конвертація перемикача." #: params.opt:1034 #, no-c-format msgid "Maximum number of bases stored in each modref tree." -msgstr "" +msgstr "Максимальна кількість баз, збережених у кожному дереві modref." #: params.opt:1038 #, no-c-format msgid "Maximum number of references stored in each modref base." -msgstr "" +msgstr "Максимальна кількість посилань, збережених у кожній базі modref." #: params.opt:1042 #, no-c-format msgid "Maximum number of accesses stored in each modref reference." -msgstr "" +msgstr "Максимальна кількість доступів, збережених у кожному посиланні modref." #: params.opt:1046 #, no-c-format msgid "Maximum number of tests performed by modref query." -msgstr "" +msgstr "Максимальна кількість тестів, виконаних запитом modref." #: params.opt:1050 #, no-c-format msgid "Maximum depth of DFS walk used by modref escape analysis." -msgstr "" +msgstr "Максимальна глибина DFS-проходу, використовуваного аналізом уникнення modref." #: params.opt:1054 #, no-c-format msgid "Maximum number of escape points tracked by modref per SSA-name." -msgstr "" +msgstr "Максимальна кількість точок виходу, відстежуваних модульним посиланням на кожне SSA-імʼя." #: params.opt:1058 #, no-c-format msgid "Maximum number of times a given range is adjusted during the dataflow." -msgstr "" +msgstr "Максимальна кількість разів, коли вказаний діапазон налаштовується під час потоку даних." #: params.opt:1062 #, no-c-format msgid "--param=threader-debug=[none|all] Enables verbose dumping of the threader solver." -msgstr "" +msgstr "--param=threader-debug=[none|all] Увімкнути докладний вивід розвʼязувача потоку." #: params.opt:1075 #, no-c-format msgid "Size in bytes after which thread-local aggregates should be instrumented with the logging functions instead of save/restore pairs." -msgstr "" +msgstr "Розмір у байтах, після якого потокові агрегати повинні бути інструментовані функціями журналізації замість пар збереження/відновлення." #: params.opt:1079 #, no-c-format msgid "The percentage of function, weighted by execution frequency, that must be covered by trace formation. Used when profile feedback is not available." -msgstr "" +msgstr "Відсоток функції, зважений за частотою виконання, який повинен бути покритий формуванням сліду. Використовується, коли профільний зворотний звʼязок недоступний." #: params.opt:1083 #, no-c-format msgid "The percentage of function, weighted by execution frequency, that must be covered by trace formation. Used when profile feedback is available." -msgstr "" +msgstr "Відсоток функції, зважений за частотою виконання, який повинен бути покритий формуванням траси. Використовується, коли доступний профільний зворотний звʼязок." #: params.opt:1087 #, no-c-format msgid "Maximal code growth caused by tail duplication (in percent)." -msgstr "" +msgstr "Максимальний ріст коду, спричинений дублюванням хвоста (у відсотках)." #: params.opt:1091 #, no-c-format msgid "Stop forward growth if the probability of best edge is less than this threshold (in percent). Used when profile feedback is not available." -msgstr "" +msgstr "Зупинити передній ріст, якщо ймовірність найкращого ребра менше цього порогу (у відсотках). Використовується, коли профільний зворотний звʼязок недоступний." #: params.opt:1095 #, no-c-format msgid "Stop forward growth if the probability of best edge is less than this threshold (in percent). Used when profile feedback is available." -msgstr "" +msgstr "Зупинити передній ріст, якщо ймовірність найкращого ребра менше цього порогу (у відсотках). Використовується, коли доступний профільний зворотний звʼязок." #: params.opt:1099 #, no-c-format msgid "Stop reverse growth if the reverse probability of best edge is less than this threshold (in percent)." -msgstr "" +msgstr "Зупинити зворотний ріст, якщо зворотна ймовірність найкращого ребра менша за цей поріг (у відсотках)." #: params.opt:1103 #, no-c-format msgid "Set the maximum number of instructions executed in parallel in reassociated tree. If 0, use the target dependent heuristic." -msgstr "" +msgstr "Встановити максимальну кількість виконуваних інструкцій паралельно в переасоційованому дереві. Якщо 0, використовуйте залежну від цільової платформи евристику." #: params.opt:1107 #, no-c-format msgid "Emit special instrumentation for accesses to volatiles." -msgstr "" +msgstr "Видавати спеціальну інструментальну підтримку для доступу до волатильних обʼєктів." #: params.opt:1111 #, no-c-format msgid "Emit instrumentation calls to __tsan_func_entry() and __tsan_func_exit()." -msgstr "" +msgstr "Видавати виклики інструментальної підтримки для __tsan_func_entry() та __tsan_func_exit()." #: params.opt:1115 #, no-c-format msgid "Maximum number of nested calls to search for control dependencies during uninitialized variable analysis." -msgstr "" +msgstr "Максимальна кількість вкладених викликів для пошуку залежностей в управлінні під час аналізу неініціалізованих змінних." #: params.opt:1119 #, no-c-format msgid "Instruction accounted for function prologue, epilogue and other overhead." -msgstr "" +msgstr "Інструкції, які враховуються для прологу, епілогу та іншого накладного витрат." #: params.opt:1123 #, no-c-format msgid "Time accounted for function prologue, epilogue and other overhead." -msgstr "" +msgstr "Час, який враховується для прологу, епілогу та іншого накладного витрат." #: params.opt:1127 #, no-c-format msgid "Instruction accounted for function thunk overhead." -msgstr "" +msgstr "Інструкції, які враховуються для накладних витрат тунку функції." #: params.opt:1131 #, no-c-format msgid "Time accounted for function thunk overhead." -msgstr "" +msgstr "Час, врахований для накладних витрат тунку функції." #: params.opt:1135 #, no-c-format msgid "The denominator n of fraction 1/n of the number of profiled runs of the entire program below which the execution count of a basic block must be in order for the basic block to be considered unlikely." -msgstr "" +msgstr "Знаменник n дробу 1/n кількості профільованих запусків всієї програми, нижче якого кількість виконань базового блоку повинна бути, щоб базовий блок вважався малоймовірним." #: params.opt:1139 #, no-c-format msgid "Maximum unroll factor for the unroll-and-jam transformation." -msgstr "" +msgstr "Максимальний коефіцієнт розгортання для трансформації розгортання та злиття." #: params.opt:1143 #, no-c-format msgid "Minimum percentage of memrefs that must go away for unroll-and-jam to be considered profitable." -msgstr "" +msgstr "Мінімальний відсоток memrefs, які повинні зникнути, щоб розгортання та злиття вважалося прибутковим." #: params.opt:1147 #, no-c-format msgid "Use direct poisoning/unpoisoning instructions for variables smaller or equal to this number." -msgstr "" +msgstr "Використовувати прямі інструкції отруєння/розтруєння для змінних, які менші або рівні цьому числу." #: params.opt:1151 #, no-c-format msgid "Whether to use canonical types." -msgstr "" +msgstr "Чи використовувати канонічні типи." #: params.opt:1155 #, no-c-format msgid "Enable loop epilogue vectorization using smaller vector size." -msgstr "" +msgstr "Увімкнути векторизацію епілогу циклу з використанням меншого розміру вектора." #: params.opt:1159 #, no-c-format msgid "Maximum number of possible vector layouts (such as permutations) to consider when optimizing to-be-vectorized code." -msgstr "" +msgstr "Максимальна кількість можливих розташувань векторів (таких як перестановки), які слід враховувати при оптимізації коду для векторизації." #: params.opt:1163 #, no-c-format msgid "Maximum number of loop peels to enhance alignment of data references in a loop." -msgstr "" +msgstr "Максимальна кількість розгортань циклу для покращення вирівнювання посилань на дані в циклі." #: params.opt:1167 #, no-c-format msgid "Bound on number of runtime checks inserted by the vectorizer's loop versioning for alias check." -msgstr "" +msgstr "Обмеження на кількість перевірок часу виконання, вставлених версіюванням циклу векторизатора для перевірки псевдонімів." #: params.opt:1171 #, no-c-format msgid "Bound on number of runtime checks inserted by the vectorizer's loop versioning for alignment check." -msgstr "" +msgstr "Обмеження на кількість перевірок часу виконання, вставлених версіюванням циклу векторизатора для перевірки вирівнювання." #: params.opt:1175 #, no-c-format msgid "Controls how loop vectorizer uses partial vectors. 0 means never, 1 means only for loops whose need to iterate can be removed, 2 means for all loops. The default value is 2." -msgstr "" +msgstr "Контролює, як векторизатор циклу використовує часткові вектори. 0 означає ніколи, 1 означає тільки для циклів, у яких можна видалити необхідність в ітерації, 2 означає для всіх циклів. Значення за замовчуванням - 2." #: params.opt:1179 #, no-c-format msgid "The maximum factor which the loop vectorizer applies to the cost of statements in an inner loop relative to the loop being vectorized." -msgstr "" +msgstr "Максимальний множник, який векторизатор петлі застосовує до вартості операторів у внутрішній петлі відносно векторизованої петлі." #: params.opt:1183 #, no-c-format msgid "Enable loop vectorization of floating point inductions." -msgstr "Увімкнути векторизацію циклів для індукцій із рухомою крапкою." +msgstr "Увімкнути векторизацію петлі для плаваючої точки." #: cfgrtl.cc:2797 msgid "flow control insn inside a basic block" -msgstr "інструкція з керування потоком у основному блоці" +msgstr "інструкція керування потоком в межах базового блоку" #: cfgrtl.cc:3086 msgid "insn outside basic block" -msgstr "інструкція поза основним блоком" +msgstr "інструкція поза базовим блоком" #: cfgrtl.cc:3094 msgid "return not followed by barrier" -msgstr "за return немає barrier" +msgstr "return не слідує за барʼєром" #: collect-utils.cc:206 #, c-format @@ -16992,36 +16966,36 @@ msgstr "[не вдалося знайти %s]" #: collect2.cc:1557 #, c-format msgid "collect2 version %s\n" -msgstr "collect2 версії %s\n" +msgstr "версія collect2 %s\n" #: collect2.cc:1662 #, c-format msgid "%d constructor found\n" msgid_plural "%d constructors found\n" -msgstr[0] "знайдено %d конструктор\n" -msgstr[1] "знайдено %d конструктори\n" -msgstr[2] "знайдено %d конструкторів\n" +msgstr[0] "%d конструктор знайдено\n" +msgstr[1] "%d конструктори знайдено\n" +msgstr[2] "%d конструкторів знайдено\n" #: collect2.cc:1666 #, c-format msgid "%d destructor found\n" msgid_plural "%d destructors found\n" -msgstr[0] "знайдено %d деструктор\n" -msgstr[1] "знайдено %d деструктори\n" -msgstr[2] "знайдено %d деструкторів\n" +msgstr[0] "%d деструктор знайдено\n" +msgstr[1] "%d деструктори знайдено\n" +msgstr[2] "%d деструкторів знайдено\n" #: collect2.cc:1670 #, c-format msgid "%d frame table found\n" msgid_plural "%d frame tables found\n" -msgstr[0] "знайдено %d таблицю кадрів\n" -msgstr[1] "знайдено %d таблиці кадрів\n" -msgstr[2] "знайдено %d таблиць кадрів\n" +msgstr[0] "%d рамкова таблиця знайдено\n" +msgstr[1] "%d таблиці кадри знайдено\n" +msgstr[2] "%d таблиці кадрів знайдено\n" #: collect2.cc:1825 #, c-format msgid "[Leaving %s]\n" -msgstr "[Полишаємо %s]\n" +msgstr "[Вихід з %s]\n" #: collect2.cc:2055 #, c-format @@ -17030,7 +17004,7 @@ msgid "" "write_c_file - output name is %s, prefix is %s\n" msgstr "" "\n" -"write_c_file - назвою результату є %s, префіксом є %s\n" +"write_c_file - імʼя вихідного файлу: %s, префікс: %s\n" #: collect2.cc:2579 #, c-format @@ -17039,16 +17013,16 @@ msgid "" "ldd output with constructors/destructors.\n" msgstr "" "\n" -"Виведені ldd дані з конструкторами та деструкторами.\n" +"Вихід ldd з конструкторами/деструкторами.\n" #: cprop.cc:1753 msgid "const/copy propagation disabled" -msgstr "передавання const/copy вимкнено" +msgstr "Вимкнено поширення констант/копій" #: diagnostic-format-json.cc:317 diagnostic-format-sarif.cc:1605 #, c-format msgid "error: unable to open '%s' for writing: %s\n" -msgstr "" +msgstr "помилка: неможливо відкрити '%s' для запису: %s\n" #. Print a header for the remaining output to stderr, and #. return, attempting to print the usual ICE messages to @@ -17056,55 +17030,54 @@ msgstr "" #. indicating what's gone wrong (also for DejaGnu, for pruning #. those messages). #: diagnostic-format-sarif.cc:1630 -#, fuzzy, c-format -#| msgid "internal compiler error: " +#, c-format msgid "Internal compiler error:\n" -msgstr "внутрішня помилка компілятора: " +msgstr "Внутрішня помилка компілятора:\n" #: diagnostic.cc:160 #, c-format msgid "%s: all warnings being treated as errors" -msgstr "%s: усі попередження вважаються помилками" +msgstr "%s: всі попередження розглядаються як помилки" #: diagnostic.cc:165 #, c-format msgid "%s: some warnings being treated as errors" -msgstr "%s: деякі попередження вважаються помилками" +msgstr "%s: деякі попередження розглядаються як помилки" #: diagnostic.cc:632 #, c-format msgid "compilation terminated due to -fmax-errors=%u.\n" -msgstr "компіляцію перервано через -fmax-errors=%u.\n" +msgstr "компіляцію припинено через -fmax-errors=%u.\n" #: diagnostic.cc:660 #, c-format msgid "compilation terminated due to -Wfatal-errors.\n" -msgstr "компіляцію перервано через -Wfatal-errors.\n" +msgstr "компіляція припинена через -Wfatal-errors.\n" #: diagnostic.cc:693 #, c-format msgid "Please submit a full bug report, with preprocessed source.\n" -msgstr "Будь ласка, надішліть повний звіт щодо вади із попередньо обробленим початковим кодом.\n" +msgstr "Будь ласка, надішліть повний звіт про помилку з попередньо обробленим початковим кодом.\n" #: diagnostic.cc:696 #, c-format msgid "Please submit a full bug report, with preprocessed source (by using -freport-bug).\n" -msgstr "Будь ласка, надішліть повний звіт щодо вади із попередньо обробленим початковим кодом (за допомогою -freport-bug).\n" +msgstr "Будь ласка, надішліть повний звіт про помилку з попередньо обробленим початковим кодом (за допомогою -freport-bug).\n" #: diagnostic.cc:700 #, c-format msgid "Please include the complete backtrace with any bug report.\n" -msgstr "" +msgstr "Будь ласка, включіть повний стек викликів у будь-якому звіті про помилку.\n" #: diagnostic.cc:702 #, c-format msgid "See %s for instructions.\n" -msgstr "Див. настанови у %s.\n" +msgstr "Дивіться %s для отримання інструкцій.\n" #: diagnostic.cc:711 #, c-format msgid "compilation terminated.\n" -msgstr "компіляцію перервано.\n" +msgstr "Компіляцію припинено.\n" #: diagnostic.cc:805 msgid " from" @@ -17112,12 +17085,12 @@ msgstr " з" #: diagnostic.cc:806 msgid "In file included from" -msgstr "У файлі, який включено у" +msgstr "У файлі, включеному з" #. 2 #: diagnostic.cc:807 msgid " included from" -msgstr " включено у" +msgstr " включено з" #: diagnostic.cc:808 msgid "In module" @@ -17130,69 +17103,69 @@ msgstr "модуля" #: diagnostic.cc:810 msgid "In module imported at" -msgstr "У модулі, імпортованому у" +msgstr "У модулі, імпортованому в" #. 6 #: diagnostic.cc:811 msgid "imported at" -msgstr "імпортовано у" +msgstr "імпортованому в" #: diagnostic.cc:1570 #, c-format msgid "%s:%d: confused by earlier errors, bailing out\n" -msgstr "%s:%d: заплуталися із попередніми помилками, вимушено припиняємо обробку\n" +msgstr "%s:%d: збитий з пантелику через попередні помилки, вихід\n" #: diagnostic.cc:2205 #, c-format msgid "internal compiler error: error reporting routines re-entered.\n" -msgstr "внутрішня помилка компілятора: повторний вхід до процедур сповіщення про помилки.\n" +msgstr "внутрішня помилка компілятора: повторний вхід у процедури повідомлення про помилку.\n" #: diagnostic.cc:2236 diagnostic.cc:2255 #, gcc-internal-format, gfc-internal-format msgid "in %s, at %s:%d" -msgstr "у %s, %s:%d" +msgstr "у %s, на %s:%d" #: final.cc:1096 msgid "negative insn length" -msgstr "від’ємна довжина інструкції" +msgstr "відʼємна довжина інструкції" #: final.cc:2808 msgid "could not split insn" -msgstr "не вдалося розділити інструкцію" +msgstr "не вдалося розбити інструкцію" #: final.cc:3183 msgid "invalid 'asm': " -msgstr "некоректна asm: " +msgstr "недійсний 'asm': " #: final.cc:3316 #, c-format msgid "nested assembly dialect alternatives" -msgstr "вкладені варіанти діалектів асемблера" +msgstr "вкладені альтернативи діалекту асемблера" #: final.cc:3344 final.cc:3356 #, c-format msgid "unterminated assembly dialect alternative" -msgstr "незавершена вставка діалектом асемблера" +msgstr "незавершена альтернатива діалекту асемблера" #: final.cc:3498 #, c-format msgid "operand number missing after %%-letter" -msgstr "пропущено операнд після %%-літери" +msgstr "відсутній номер операнду після %%-літери" #: final.cc:3501 final.cc:3542 #, c-format msgid "operand number out of range" -msgstr "кількість операндів поза межами припустимого діапазону" +msgstr "номер операнду поза діапазоном" #: final.cc:3559 #, c-format msgid "invalid %%-code" -msgstr "некоректний %%-код" +msgstr "неправильний %%-код" #: final.cc:3593 #, c-format msgid "'%%l' operand isn't a label" -msgstr "операнд «%%l» не є міткою" +msgstr "операнд '%%l' не є міткою" #. We can't handle floating point constants; #. PRINT_OPERAND must handle them. @@ -17201,13 +17174,13 @@ msgstr "операнд «%%l» не є міткою" #: final.cc:3729 config/arc/arc.cc:6430 config/i386/i386.cc:12318 #, c-format msgid "floating constant misused" -msgstr "помилкове використання сталої із рухомою крапкою" +msgstr "неправильне використання плаваючої константи" #: final.cc:3787 config/arc/arc.cc:6527 config/i386/i386.cc:12409 #: config/pdp11/pdp11.cc:1871 #, c-format msgid "invalid expression as operand" -msgstr "некоректний вираз операнда" +msgstr "неправильний вираз як операнд" #: gcc.cc:122 #, c-format @@ -17217,7 +17190,7 @@ msgstr "%s\n" #: gcc.cc:1840 #, c-format msgid "Using built-in specs.\n" -msgstr "Використовуємо вбудовані специфікації.\n" +msgstr "Використання вбудованих специфікацій.\n" #: gcc.cc:2085 #, c-format @@ -17225,13 +17198,13 @@ msgid "" "Setting spec %s to '%s'\n" "\n" msgstr "" -"Встановлюємо специфікацію %s у значення «%s»\n" +"Встановлення специфікації %s на '%s'\n" "\n" #: gcc.cc:2290 #, c-format msgid "Reading specs from %s\n" -msgstr "Читаємо специфікації з %s\n" +msgstr "Читання специфікацій з %s\n" #: gcc.cc:2422 #, c-format @@ -17249,7 +17222,7 @@ msgid "" "spec is '%s'\n" "\n" msgstr "" -"специфікація — «%s»\n" +"специфікація - '%s'\n" "\n" #: gcc.cc:3360 @@ -17259,7 +17232,7 @@ msgid "" "Go ahead? (y or n) " msgstr "" "\n" -"Продовжувати? (y — так або n — ні) " +"Продовжити? (так або ні) " #: gcc.cc:3532 #, c-format @@ -17269,11 +17242,11 @@ msgstr "# %s %.2f %.2f\n" #: gcc.cc:3712 #, c-format msgid "Usage: %s [options] file...\n" -msgstr "Використання: %s [параметри] файл…\n" +msgstr "Використання: %s [опції] файл...\n" #: gcc.cc:3713 msgid "Options:\n" -msgstr "Параметри:\n" +msgstr "Опції:\n" #: gcc.cc:3715 msgid " -pass-exit-codes Exit with highest error code from a phase.\n" @@ -17289,7 +17262,7 @@ msgstr " --target-help Вивести параметри коман #: gcc.cc:3719 msgid " --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].\n" -msgstr " --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].\n" +msgstr " --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]\n" #: gcc.cc:3720 msgid " Display specific types of command line options.\n" @@ -17317,7 +17290,7 @@ msgstr " -dumpmachine Вивести дані щодо процес #: gcc.cc:3727 msgid " -foffload= Specify offloading targets.\n" -msgstr "" +msgstr " -foffload=<цілі> Вказати цілі для вивантаження.\n" #: gcc.cc:3728 msgid " -print-search-dirs Display the directories in the compiler's search path.\n" @@ -17352,7 +17325,7 @@ msgid "" " -print-multi-lib Display the mapping between command line options and\n" " multiple library search directories.\n" msgstr "" -" -print-multi-lib Вивести прив'язку між параметрами командного рядка і\n" +" -print-multi-lib Вивести привʼязку між параметрами командного рядка і\n" " і каталогами пошуку мультибібліотек.\n" #: gcc.cc:3739 @@ -17361,7 +17334,7 @@ msgstr " -print-multi-os-directory Вивести відносний шлях #: gcc.cc:3740 msgid " -print-sysroot Display the target libraries directory.\n" -msgstr " -print-sysroot Вивести каталог призначення бібліотек.\n" +msgstr " -print-sysroot Вивести каталог бібліотек цільової системи.\n" #: gcc.cc:3741 msgid " -print-sysroot-headers-suffix Display the sysroot suffix used to find headers.\n" @@ -17369,51 +17342,51 @@ msgstr " -print-sysroot-headers-suffix Вивести суфікс sysroot, я #: gcc.cc:3742 msgid " -Wa, Pass comma-separated on to the assembler.\n" -msgstr " -Wa,<параметри> Передати асемблеру список відокремлених комами параметрів.\n" +msgstr " -Wa, Передати кома-розділені асемблеру.\n" #: gcc.cc:3743 msgid " -Wp, Pass comma-separated on to the preprocessor.\n" -msgstr " -Wp,<параметри> Передати засобу попередньої обробки список відокремлених комами параметрів.\n" +msgstr " -Wp, Передати кома-розділені препроцесору.\n" #: gcc.cc:3744 msgid " -Wl, Pass comma-separated on to the linker.\n" -msgstr " -Wl,<параметри> Передати компонувальнику список відокремлених комами параметрів.\n" +msgstr " -Wl,<опції> Передати комами розділені <опції> лінкеру.\n" #: gcc.cc:3745 msgid " -Xassembler Pass on to the assembler.\n" -msgstr " -Xassembler <арг> Передати аргумент <арг> асемблеру.\n" +msgstr " -Xassembler <арг> Передати <арг> асемблеру.\n" #: gcc.cc:3746 msgid " -Xpreprocessor Pass on to the preprocessor.\n" -msgstr " -Xpreprocessor <арг> Передати аргумент <арг> засобу попередньої обробки.\n" +msgstr " -Xpreprocessor <арг> Передати <арг> препроцесору.\n" #: gcc.cc:3747 msgid " -Xlinker Pass on to the linker.\n" -msgstr " -Xlinker <арг> Передати аргумент <арг> компонувальнику.\n" +msgstr " -Xlinker <арг> Передати <арг> лінкеру.\n" #: gcc.cc:3748 msgid " -save-temps Do not delete intermediate files.\n" -msgstr " -save-temps Не вилучати проміжні файли.\n" +msgstr " -save-temps Не видаляти проміжні файли.\n" #: gcc.cc:3749 msgid " -save-temps= Do not delete intermediate files.\n" -msgstr " -save-temps=<арг> Не вилучати проміжні файли.\n" +msgstr " -save-temps=<арг> Не видаляти проміжні файли.\n" #: gcc.cc:3750 msgid "" " -no-canonical-prefixes Do not canonicalize paths when building relative\n" " prefixes to other gcc components.\n" msgstr "" -" -no-canonical-prefixes Не перетворювати до канонічної форми шляхи під час\n" -" побудови відносних префіксів до інших компонент gcc.\n" +" -no-canonical-prefixes Не канонізувати шляхи при побудові відносних\n" +" префіксів до інших компонентів gcc.\n" #: gcc.cc:3753 msgid " -pipe Use pipes rather than intermediate files.\n" -msgstr " -pipe Використовувати канали передавання даних замість проміжних файлів.\n" +msgstr " -pipe Використовувати канали замість проміжних файлів.\n" #: gcc.cc:3754 msgid " -time Time the execution of each subprocess.\n" -msgstr " -time Вимірювати час виконання кожного з підпроцесів.\n" +msgstr " -time Вимірювати час виконання кожного підпроцесу.\n" #: gcc.cc:3755 msgid " -specs= Override built-in specs with the contents of .\n" @@ -17421,15 +17394,15 @@ msgstr " -specs=<файл> Перевизначити вбудова #: gcc.cc:3756 msgid " -std= Assume that the input sources are for .\n" -msgstr " -std=<стандарт> Припускати для вхідних кодів відповідність вказаному стандарту.\n" +msgstr " -std=<стандарт> Припускати, що вхідні джерела призначені для <стандарту>.\n" #: gcc.cc:3757 msgid "" " --sysroot= Use as the root directory for headers\n" " and libraries.\n" msgstr "" -" --sysroot=<каталог> Використовувати <каталог> як кореневий для заголовків\n" -" і бібліотек.\n" +" --sysroot=<каталог> Використовувати <каталог> як кореневий каталог для заголовків\n" +" та бібліотек.\n" #: gcc.cc:3760 msgid " -B Add to the compiler's search paths.\n" @@ -17441,7 +17414,7 @@ msgstr " -v Виводити назви програм, #: gcc.cc:3762 msgid " -### Like -v but options quoted and commands not executed.\n" -msgstr " -### Подібне до -v, але із лапками для параметрів і без виконання команд.\n" +msgstr " -### Подібно до -v, але опції взяті в лапки і команди не виконуються.\n" #: gcc.cc:3763 msgid " -E Preprocess only; do not compile, assemble or link.\n" @@ -17453,23 +17426,23 @@ msgstr " -S Лише скомпілювати; не зб #: gcc.cc:3765 msgid " -c Compile and assemble, but do not link.\n" -msgstr " -c Скомпілювати і зібрати, але не компонувати.\n" +msgstr " -c Компілювати і збирати, але не звʼязувати.\n" #: gcc.cc:3766 msgid " -o Place the output into .\n" -msgstr " -o <файл> Вивести результати до файла <файл>.\n" +msgstr " -o <файл> Зберегти результат у файл <файл>.\n" #: gcc.cc:3767 msgid "" " -pie Create a dynamically linked position independent\n" " executable.\n" msgstr "" -" -pie створити динамічно скомпонований виконуваний файл з\n" -" незалежним позиціюванням\n" +" -pie Створити виконуваний файл з динамічними звʼязками та незалежними від позиції\n" +" кодом.\n" #: gcc.cc:3769 msgid " -shared Create a shared library.\n" -msgstr " -shared створити бібліотеку спільного використання\n" +msgstr " -shared Створити спільну бібліотеку.\n" #: gcc.cc:3770 msgid "" @@ -17478,10 +17451,10 @@ msgid "" " 'none' means revert to the default behavior of\n" " guessing the language based on the file's extension.\n" msgstr "" -" -x <мова> Вказати мову для наступних файлів вхідних даних.\n" -" Можливі варіанти мов: c c++ assembler none\n" -" «none» означає «повернутися до типової поведінки\n" -" із визначенням мови на основі суфікса назви файла».\n" +" -x <мова> Вказати мову наступних вхідних файлів.\n" +" Допустимі мови: c c++ assembler none\n" +" 'none' означає повернення до типової поведінки,\n" +" коли мова визначається на підставі розширення файлу.\n" #: gcc.cc:3777 #, c-format @@ -17544,12 +17517,12 @@ msgstr "Версія драйвера gcc %s %sвиконуємо версію g #: gcc.cc:7634 gcc.cc:7844 #, c-format msgid "The bug is not reproducible, so it is likely a hardware or OS problem.\n" -msgstr "Ваду не вдається відтворити. Ймовірно, її пов'язано із обладнанням або операційною системою.\n" +msgstr "Помилку не вдається відтворити, тому це, ймовірно, проблема з апаратним забезпеченням або операційною системою.\n" #: gcc.cc:7768 #, c-format msgid "Preprocessed source stored into %s file, please attach this to your bugreport.\n" -msgstr "Попередньо оброблений код збережено до файла %s. Будь ласка, долучіть цей файл до вашого звіту щодо вади.\n" +msgstr "Попередньо оброблений вихідний код збережено у файлі %s, будь ласка, додайте його до вашого звіту про помилку.\n" #: gcc.cc:8619 #, c-format @@ -17573,7 +17546,7 @@ msgid "" "For bug reporting instructions, please see:\n" msgstr "" "\n" -"Настанови щодо звітування про вади наведено тут:\n" +"Інструкції з повідомлення про помилку дивіться за посиланням:\n" #: gcc.cc:8757 gcov-tool.cc:594 #, c-format @@ -17582,7 +17555,7 @@ msgstr "%s %s%s\n" #: gcc.cc:8760 gcov-tool.cc:596 gcov.cc:968 fortran/gfortranspec.cc:282 msgid "(C)" -msgstr "©" +msgstr "(C)" #: gcc.cc:8761 gcov-tool.cc:598 gcov.cc:970 fortran/gfortranspec.cc:283 #, c-format @@ -17591,10 +17564,9 @@ msgid "" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" "\n" msgstr "" -"Це програмне забезпечення є вільним, умови копіювання викладено у його\n" -"початкових кодах.\n" -"Умовами ліцензування програми НЕ передбачено жодних гарантій, зокрема\n" -"гарантій працездатності або придатності для певної мети.\n" +"Це вільне програмне забезпечення; дивіться вихідний код для умов копіювання. НЕМАЄ\n" +"гарантії; навіть не для ПРИДАТНОСТІ ДЛЯ ПРОДАЖУ або ПРИДАТНОСТІ ДЛЯ ПЕВНОГО\n" +"ПРИЗНАЧЕННЯ.\n" "\n" #: gcc.cc:9104 @@ -17642,12 +17614,12 @@ msgstr "" #: gcov-tool.cc:157 gcov-tool.cc:300 #, c-format msgid "no profile files were merged\n" -msgstr "" +msgstr "не було обʼєднано жодного файлу профілю\n" #: gcov-tool.cc:169 #, c-format msgid " merge [options] Merge coverage file contents\n" -msgstr " merge [параметри] <кат1> <кат2> об'єднати вміст файлів покриття\n" +msgstr " merge [параметри] <кат1> <кат2> обʼєднати вміст файлів покриття\n" #: gcov-tool.cc:170 gcov-tool.cc:337 #, c-format @@ -17665,28 +17637,23 @@ msgid " -w, --weight Set weights (float point values)\ msgstr " -w, --weight встановити ваги (значення із рухомою крапкою)\n" #: gcov-tool.cc:188 -#, fuzzy, c-format -#| msgid "Merge subcomand usage:" +#, c-format msgid "Merge subcommand usage:" -msgstr "Користування підкомандою merge:" +msgstr "Використання підкоманди злиття:" #: gcov-tool.cc:240 -#, fuzzy, c-format -#| msgid "" -#| " -l, --long-file-names Use long output file names for included\n" -#| " source files\n" +#, c-format msgid "" " merge-stream [options] [] Merge coverage stream file (or stdin)\n" " and coverage file contents\n" msgstr "" -" -l, --long-file-names використовувати довгі назви файлів виведення для\n" -" включених файлів початкового коду\n" +" merge-stream [параметри] [<файл>] Обʼєднати файл потоку покриття (або stdin)\n" +" та вміст файлу покриття\n" #: gcov-tool.cc:258 -#, fuzzy, c-format -#| msgid "Merge subcomand usage:" +#, c-format msgid "Merge-stream subcommand usage:" -msgstr "Користування підкомандою merge:" +msgstr "Використання підкоманди злиття потоку:" #: gcov-tool.cc:335 #, c-format @@ -17701,52 +17668,52 @@ msgstr " -n, --normalize Нормалізувати пр #: gcov-tool.cc:338 #, c-format msgid " -s, --scale Scale the profile counters\n" -msgstr " -s, --scale масштабувати лічильники профілювання\n" +msgstr " -s, --scale <дробове число або проста дріб> Масштабувати лічильники профілів\n" #: gcov-tool.cc:356 #, c-format msgid "Rewrite subcommand usage:" -msgstr "Користування підкомандою rewrite:" +msgstr "Використання підкоманди перезапису:" #: gcov-tool.cc:395 #, c-format msgid "scaling cannot co-exist with normalization, skipping\n" -msgstr "масштабування не може співіснувати зі нормалізацією, пропускаємо\n" +msgstr "Масштабування не може співіснувати з нормалізацією, пропускаю\n" #: gcov-tool.cc:408 gcov-tool.cc:418 #, c-format msgid "incorrect format in scaling, using 1/1\n" -msgstr "помилковий формат у масштабуванні, використовуємо 1/1\n" +msgstr "Неправильний формат масштабування, використовується 1/1\n" #: gcov-tool.cc:428 #, c-format msgid "normalization cannot co-exist with scaling\n" -msgstr "нормалізація не може співіснувати із масштабуванням\n" +msgstr "Нормалізація не може співіснувати з масштабуванням\n" #: gcov-tool.cc:485 #, c-format msgid " overlap [options] Compute the overlap of two profiles\n" -msgstr " overlap [параметри] <каталог1> <каталог2> визначити перекриття двох провілів\n" +msgstr " перекриття [параметри] <кат1> <кат2> Обчислити перекриття двох профілів\n" #: gcov-tool.cc:486 #, c-format msgid " -f, --function Print function level info\n" -msgstr " -f, --function Вивести дані щодо рівня функції\n" +msgstr " -f, --function Вивести інформацію на рівні функцій\n" #: gcov-tool.cc:487 #, c-format msgid " -F, --fullname Print full filename\n" -msgstr " -F, --fullname Вивести назву файла повністю\n" +msgstr " -F, --fullname Вивести повне імʼя файлу\n" #: gcov-tool.cc:488 #, c-format msgid " -h, --hotonly Only print info for hot objects/functions\n" -msgstr " -h, --hotonly виводити дані лише для «гарячих» об'єктів або функцій\n" +msgstr " -h, --hotonly виводити дані лише для «гарячих» обʼєктів або функцій\n" #: gcov-tool.cc:489 #, c-format msgid " -o, --object Print object level info\n" -msgstr " -o, --object Вивести дані щодо рівня об'єкта\n" +msgstr " -o, --object Вивести дані щодо рівня обʼєкта\n" #: gcov-tool.cc:490 #, c-format @@ -17754,10 +17721,9 @@ msgid " -t , --hot_threshold Set the threshold for hotness\n" msgstr " -t , --hot_threshold встановити порогове значення «гарячості»\n" #: gcov-tool.cc:510 -#, fuzzy, c-format -#| msgid "Overlap subcomand usage:" +#, c-format msgid "Overlap subcommand usage:" -msgstr "Користування підкомандою overlap:" +msgstr "Використання підкоманди перекриття:" #: gcov-tool.cc:576 #, c-format @@ -17765,7 +17731,7 @@ msgid "" "Usage: %s [OPTION]... SUB_COMMAND [OPTION]...\n" "\n" msgstr "" -"Користування: %s [ПАРАМЕТР]... ПІДКОМАНДА [ПАРАМЕТР]...\n" +"Використання: %s [ПАРАМЕТР]... ПІДКОМАНДА [ПАРАМЕТР]...\n" "\n" #: gcov-tool.cc:577 @@ -17774,7 +17740,7 @@ msgid "" "Offline tool to handle gcda counts\n" "\n" msgstr "" -"Автономний інструмент для обробки лічильників gcda\n" +"Офлайн-інструмент для обробки лічильників gcda\n" "\n" #: gcov-tool.cc:578 @@ -17795,14 +17761,14 @@ msgid "" "%s.\n" msgstr "" "\n" -"Настанови щодо звітування про вади наведено тут:\n" +"Щоб отримати інструкції з повідомлення про помилки, див.:\n" "%s.\n" +"\n" #: gcov-tool.cc:595 -#, fuzzy, c-format -#| msgid "Copyright %s 2022 Free Software Foundation, Inc.\n" +#, c-format msgid "Copyright %s 2023 Free Software Foundation, Inc.\n" -msgstr "© %s Free Software Foundation, Inc., 2022\n" +msgstr "Авторське право %s 2023 Free Software Foundation, Inc.\n" #: gcov.cc:925 #, c-format @@ -17810,7 +17776,7 @@ msgid "" "Usage: gcov [OPTION...] SOURCE|OBJ...\n" "\n" msgstr "" -"Користування: gcov [ПАРАМЕТР...] ПОЧАТКОВИЙ_КОД|OBJ...\n" +"Використання: gcov [ПАРАМЕТР...] ДЖЕРЕЛО|OBJ...\n" "\n" #: gcov.cc:926 @@ -17819,18 +17785,18 @@ msgid "" "Print code coverage information.\n" "\n" msgstr "" -"Виводить дані щодо покриття коду.\n" +"Вивести інформацію про покриття коду.\n" "\n" #: gcov.cc:927 #, c-format msgid " -a, --all-blocks Show information for every basic block\n" -msgstr " -a, --all-blocks Вивести дані щодо кожного базового блоку\n" +msgstr " -a, --all-blocks Показати інформацію для кожного базового блоку\n" #: gcov.cc:928 #, c-format msgid " -b, --branch-probabilities Include branch probabilities in output\n" -msgstr " -b, --branch-probabilities Включити ймовірності розгалужень до виведених даних\n" +msgstr " -b, --branch-probabilities Включити ймовірності гілок у вихідні дані\n" #: gcov.cc:929 #, c-format @@ -17838,45 +17804,49 @@ msgid "" " -c, --branch-counts Output counts of branches taken\n" " rather than percentages\n" msgstr "" -" -c, --branch-counts Виводити кількість гілок,\n" -" а не частку\n" +" -c, --branch-counts Вивести кількість виконаних гілок\n" +" замість відсотків\n" +" -c, --branch-counts Виводити кількість виконаних гілок,\n" +" а не відсотки\n" #: gcov.cc:931 #, c-format msgid " -d, --display-progress Display progress information\n" -msgstr " -d, --display-progress Виводити дані щодо поступу\n" +msgstr " -d, --display-progress Показувати інформацію про прогрес\n" #: gcov.cc:932 #, c-format msgid " -D, --debug\t\t\t Display debugging dumps\n" -msgstr " -D, --debug\t\t\t Виводити діагностичні дані\n" +msgstr " -D, --debug\t\t\t Показувати відлагоджувальні дампи\n" #: gcov.cc:933 #, c-format msgid " -f, --function-summaries Output summaries for each function\n" -msgstr " -f, --function-summaries Виводити резюме щодо кожної функції\n" +msgstr " -f, --function-summaries Виводити підсумки для кожної функції\n" #: gcov.cc:934 #, c-format msgid " -h, --help Print this help, then exit\n" -msgstr " -h, --help Вивести ці довідкові дані, потім вийти\n" +msgstr " -h, --help Вивести цю довідку, а потім вийти\n" #: gcov.cc:935 #, c-format msgid "" " -j, --json-format Output JSON intermediate format\n" " into .gcov.json.gz file\n" -msgstr " -j, --json-format вивести дані у проміжному форматі JSON до файла .gcov.json.gz\n" +msgstr "" +" -j, --json-format Вивід JSON проміжного формату\n" +" у файл .gcov.json.gz\n" #: gcov.cc:937 #, c-format msgid " -H, --human-readable Output human readable numbers\n" -msgstr " -H, --human-readable Виводити зручні для читання числа\n" +msgstr " -H, --human-readable Вивід чисел у зрозумілому форматі\n" #: gcov.cc:938 #, c-format msgid " -k, --use-colors Emit colored output\n" -msgstr " -k, --use-colors Розфарбувати виведені дані\n" +msgstr " -k, --use-colors Вивід кольорового тексту\n" #: gcov.cc:939 #, c-format @@ -17884,68 +17854,68 @@ msgid "" " -l, --long-file-names Use long output file names for included\n" " source files\n" msgstr "" -" -l, --long-file-names використовувати довгі назви файлів виведення для\n" -" включених файлів початкового коду\n" +" -l, --long-file-names Використовувати довгі імена вихідних файлів\n" +" для включених файлів\n" #: gcov.cc:941 #, c-format msgid " -m, --demangled-names Output demangled function names\n" -msgstr " -m, --demangled-names виводити розшифровані назви функцій\n" +msgstr " -m, --demangled-names Вивід роздекорованих назв функцій\n" #: gcov.cc:942 #, c-format msgid " -n, --no-output Do not create an output file\n" -msgstr " -n, --no-output не створювати файла виведених даних\n" +msgstr " -n, --no-output Не створювати вихідний файл\n" #: gcov.cc:943 #, c-format msgid " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n" -msgstr " -o, --object-directory КАТ|ФАЙЛ Шукати об'єктні файли у каталозі КАТ або із назвою ФАЙЛ\n" +msgstr " -o, --object-directory DIR|FILE Пошук обʼєктних файлів у каталозі DIR або з назвою FILE\n" #: gcov.cc:944 #, c-format msgid " -p, --preserve-paths Preserve all pathname components\n" -msgstr " -p, --preserve-paths зберігати компоненти шляхів\n" +msgstr " -p, --preserve-paths Зберігати всі компоненти шляху\n" #: gcov.cc:945 #, c-format msgid " -q, --use-hotness-colors Emit perf-like colored output for hot lines\n" -msgstr " -q, --use-hotness-colors виводити результати із розфарбовуванням подібним до perf для «гарячих» рядків\n" +msgstr " -q, --use-hotness-colors Виводити кольоровий результат для гарячих рядків, схожий на perf\n" #: gcov.cc:946 #, c-format msgid " -r, --relative-only Only show data for relative sources\n" -msgstr " -r, --relative-only вивести дані лише для відносних джерел\n" +msgstr " -r, --relative-only Показувати дані тільки для відносних джерел\n" #: gcov.cc:947 #, c-format msgid " -s, --source-prefix DIR Source prefix to elide\n" -msgstr " -s, --source-prefix КАТ префікс коду для пропускання\n" +msgstr " -s, --source-prefix DIR Префікс джерела для видалення\n" #: gcov.cc:948 #, c-format msgid " -t, --stdout Output to stdout instead of a file\n" -msgstr " -t, --stdout вивести дані до стандартного виведення, а не до файла\n" +msgstr " -t, --stdout Вивід на stdout замість файлу\n" #: gcov.cc:949 #, c-format msgid " -u, --unconditional-branches Show unconditional branch counts too\n" -msgstr " -u, --unconditional-branches показувати і кількість безумовних гілок\n" +msgstr " -u, --unconditional-branches Показувати також кількість безумовних гілок\n" #: gcov.cc:950 #, c-format msgid " -v, --version Print version number, then exit\n" -msgstr " -v, --version Вивести дані щодо версії, далі вийти\n" +msgstr " -v, --version Вивести номер версії і вийти\n" #: gcov.cc:951 #, c-format msgid " -w, --verbose Print verbose informations\n" -msgstr " -w, --verbose Режим докладних повідомлень\n" +msgstr " -w, --verbose Вивести докладну інформацію\n" #: gcov.cc:952 #, c-format msgid " -x, --hash-filenames Hash long pathnames\n" -msgstr " -x, --hash-filenames хешувати довгі шляхи\n" +msgstr " -x, --hash-filenames Хешувати довгі шляхи до файлів\n" #: gcov.cc:953 #, c-format @@ -17974,102 +17944,102 @@ msgstr "gcov %s%s\n" #: gcov.cc:1354 #, c-format msgid "'%s' file is already processed\n" -msgstr "Файл «%s» вже оброблено\n" +msgstr "Файл '%s' вже оброблено\n" #: gcov.cc:1470 gcov.cc:1599 #, c-format msgid "Creating '%s'\n" -msgstr "Створюємо «%s»\n" +msgstr "Створення '%s'\n" #: gcov.cc:1474 #, c-format msgid "Error writing output file '%s'\n" -msgstr "Помилка під час спроби записати файл «%s»\n" +msgstr "Помилка запису у вихідний файл '%s'\n" #: gcov.cc:1482 #, c-format msgid "Could not open output file '%s'\n" -msgstr "Не вдалося відкрити файл результатів «%s»\n" +msgstr "Не вдалося відкрити вихідний файл '%s'\n" #: gcov.cc:1489 #, c-format msgid "Removing '%s'\n" -msgstr "Вилучаємо «%s»\n" +msgstr "Видалення '%s'\n" #: gcov.cc:1604 #, c-format msgid "Cannot open JSON output file %s\n" -msgstr "Не вдалося відкрити файл зі виведеними даними JSON %s\n" +msgstr "Не вдалося відкрити JSON-файл виводу %s\n" #: gcov.cc:1613 #, c-format msgid "Error writing JSON output file %s\n" -msgstr "Помилка під час спроби записати файл із виведеними даними JSON %s\n" +msgstr "Помилка запису у JSON-файл виводу %s\n" #: gcov.cc:1778 #, c-format msgid "%s:source file is newer than notes file '%s'\n" -msgstr "%s:файл початкового коду є новішим за файл нотаток «%s»\n" +msgstr "%s:Вихідний файл новіший за файл приміток '%s'\n" #: gcov.cc:1783 #, c-format msgid "(the message is displayed only once per source file)\n" -msgstr "(повідомлення буде показано лише один раз на один файл з кодом)\n" +msgstr "(повідомлення показується лише один раз для кожного вихідного файлу)\n" #: gcov.cc:1803 #, c-format msgid "%s:cannot open notes file\n" -msgstr "%s:не вдалося відкрити файл нотаток\n" +msgstr "%s:не вдається відкрити файл заміток\n" #: gcov.cc:1810 #, c-format msgid "%s:not a gcov notes file\n" -msgstr "%s:не є файлом нотаток gcov\n" +msgstr "%s:не є файлом заміток gcov\n" #: gcov.cc:1824 #, c-format msgid "%s:version '%.4s', prefer '%.4s'\n" -msgstr "" +msgstr "%s:версія '%.4s', бажано '%.4s'\n" #: gcov.cc:1877 #, c-format msgid "%s:already seen blocks for '%s'\n" -msgstr "" +msgstr "%s:вже бачені блоки для '%s'\n" #: gcov.cc:1993 gcov.cc:2107 #, c-format msgid "%s:corrupted\n" -msgstr "" +msgstr "%s:пошкоджено\n" #: gcov.cc:2001 #, c-format msgid "%s:no functions found\n" -msgstr "" +msgstr "%s:не знайдено функцій\n" #: gcov.cc:2019 #, c-format msgid "%s:cannot open data file, assuming not executed\n" -msgstr "" +msgstr "%s:не вдається відкрити файл даних, припускаю, що не виконується\n" #: gcov.cc:2026 #, c-format msgid "%s:not a gcov data file\n" -msgstr "" +msgstr "%s:не є файлом даних gcov\n" #: gcov.cc:2040 #, c-format msgid "%s:version '%.4s', prefer version '%.4s'\n" -msgstr "" +msgstr "%s:версія '%.4s', бажано версію '%.4s'\n" #: gcov.cc:2047 #, c-format msgid "%s:stamp mismatch with notes file\n" -msgstr "" +msgstr "%s:неспівпадіння штампу з файлом заміток\n" #: gcov.cc:2084 #, c-format msgid "%s:profile mismatch for '%s'\n" -msgstr "%s:невідповідність профілів для «%s»\n" +msgstr "%s:неспівпадіння профілю для '%s'\n" #: gcov.cc:2106 #, c-format @@ -18079,27 +18049,27 @@ msgstr "%s:переповнено\n" #: gcov.cc:2154 #, c-format msgid "%s:'%s' lacks entry and/or exit blocks\n" -msgstr "" +msgstr "%s:у '%s' відсутні блоки входу та/або виходу\n" #: gcov.cc:2159 #, c-format msgid "%s:'%s' has arcs to entry block\n" -msgstr "" +msgstr "%s:у '%s' є дуги до блоку входу\n" #: gcov.cc:2167 #, c-format msgid "%s:'%s' has arcs from exit block\n" -msgstr "" +msgstr "%s:у '%s' є дуги з блоку виходу\n" #: gcov.cc:2376 #, c-format msgid "%s:graph is unsolvable for '%s'\n" -msgstr "" +msgstr "%s:граф не має розвʼязку для '%s'\n" #: gcov.cc:2492 #, c-format msgid "Lines executed:%s of %d\n" -msgstr "Виконаних рядків:%s з %d\n" +msgstr "Виконано рядків:%s з %d\n" #: gcov.cc:2495 #, c-format @@ -18109,22 +18079,22 @@ msgstr "Немає виконуваних рядків\n" #: gcov.cc:2503 gcov.cc:2512 #, c-format msgid "%s '%s'\n" -msgstr "%s «%s»\n" +msgstr "%s '%s'\n" #: gcov.cc:2519 #, c-format msgid "Branches executed:%s of %d\n" -msgstr "" +msgstr "Виконано гілок:%s з %d\n" #: gcov.cc:2523 #, c-format msgid "Taken at least once:%s of %d\n" -msgstr "" +msgstr "Виконано хоча б один раз:%s з %d\n" #: gcov.cc:2529 #, c-format msgid "No branches\n" -msgstr "Немає відгалужень\n" +msgstr "Немає гілок\n" #: gcov.cc:2531 #, c-format @@ -18139,28 +18109,27 @@ msgstr "Немає викликів\n" #: gcov.cc:2755 #, c-format msgid "%s:no lines for '%s'\n" -msgstr "%s: немає рядків з «%s»\n" +msgstr "%s: немає рядків для '%s'\n" #: gcov.cc:2881 #, c-format msgid "call %2d returned %s\n" -msgstr "" +msgstr "виклик %2d повернув %s\n" #: gcov.cc:2886 #, c-format msgid "call %2d never executed\n" -msgstr "виклик %2d ніколи не виконувався\n" +msgstr "виклик %2d ніколи не виконувався\n" #: gcov.cc:2891 #, c-format msgid "branch %2d taken %s%s" -msgstr "" +msgstr "гілка %2d виконана %s%s" #: gcov.cc:2896 -#, fuzzy, c-format -#| msgid "branch %2d never executed" +#, c-format msgid "branch %2d never executed%s" -msgstr "гілка %2d ніколи не виконувалася" +msgstr "гілка %2d ніколи не виконувалась%s" #: gcov.cc:2901 #, c-format @@ -18170,69 +18139,69 @@ msgstr " (BB %d)" #: gcov.cc:2908 #, c-format msgid "unconditional %2d taken %s\n" -msgstr "" +msgstr "безумовний %2d виконаний %s\n" #: gcov.cc:2911 #, c-format msgid "unconditional %2d never executed\n" -msgstr "" +msgstr "безумовний %2d ніколи не виконувався\n" #: gcov.cc:3163 #, c-format msgid "Cannot open source file %s\n" -msgstr "Не вдалося відкрити файл початкового коду %s\n" +msgstr "Не вдалося відкрити вихідний файл %s\n" #: gcse.cc:2578 msgid "PRE disabled" -msgstr "" +msgstr "PRE вимкнено" #: gcse.cc:3505 msgid "GCSE disabled" -msgstr "" +msgstr "GCSE вимкнено" #: incpath.cc:77 #, c-format msgid "ignoring duplicate directory \"%s\"\n" -msgstr "" +msgstr "ігнорується дублюючий каталог «%s»\n" #: incpath.cc:80 #, c-format msgid " as it is a non-system directory that duplicates a system directory\n" -msgstr "" +msgstr " оскільки це несистемний каталог, який дублює системний каталог\n" #: incpath.cc:84 #, c-format msgid "ignoring nonexistent directory \"%s\"\n" -msgstr "" +msgstr "ігнорується неіснуючий каталог «%s»\n" #: incpath.cc:391 #, c-format msgid "#include \"...\" search starts here:\n" -msgstr "" +msgstr "Пошук «#include \"...\"» починається тут:\n" #: incpath.cc:395 #, c-format msgid "#include <...> search starts here:\n" -msgstr "" +msgstr "Пошук «#include <...>» починається тут:\n" #: incpath.cc:400 #, c-format msgid "End of search list.\n" -msgstr "" +msgstr "Кінець списку пошуку.\n" #: input.cc:35 msgid "" -msgstr "<вбудоване>" +msgstr "<вбудований>" #. Opening quotation mark. #: intl.cc:62 msgid "`" -msgstr "" +msgstr "«" #. Closing quotation mark. #: intl.cc:65 msgid "'" -msgstr "" +msgstr "»" #: langhooks.cc:384 msgid "At top level:" @@ -18250,16 +18219,16 @@ msgstr "У функції %qs" #: langhooks.cc:449 msgid " inlined from %qs at %r%s:%d:%d%R" -msgstr "" +msgstr " вбудовано з %qs в %r%s:%d:%d%R" #: langhooks.cc:454 msgid " inlined from %qs at %r%s:%d%R" -msgstr "" +msgstr " вбудовано з %qs в %r%s:%d%R" #: langhooks.cc:460 #, c-format msgid " inlined from %qs" -msgstr "" +msgstr " вбудовано з %qs" #: lra-assigns.cc:1871 reload1.cc:2073 msgid "this is the insn:" @@ -18267,53 +18236,53 @@ msgstr "це інструкція:" #: lra-constraints.cc:3144 msgid "unable to generate reloads for impossible constraints:" -msgstr "" +msgstr "неможливо згенерувати перезавантаження для неможливих обмежень:" #: lra-constraints.cc:4170 reload.cc:3844 msgid "unable to generate reloads for:" -msgstr "" +msgstr "не вдалося згенерувати перезавантаження для:" #. What to print when a switch has no documentation. #: opts.cc:325 msgid "This option lacks documentation." -msgstr "Цей перемикач не документовано." +msgstr "Ця опція не має документації." #: opts.cc:326 msgid "Uses of this option are diagnosed." -msgstr "" +msgstr "Використання цієї опції діагностується." #: opts.cc:1652 #, c-format msgid "Same as %s%s (or, in negated form, %s%s)." -msgstr "" +msgstr "Те саме, що й %s%s (або, у заперечній формі, %s%s)." #: opts.cc:1657 #, c-format msgid "Same as %s%s." -msgstr "" +msgstr "Те саме, що й %s%s." #: opts.cc:1662 #, c-format msgid "Same as %s." -msgstr "Те саме, що і %s" +msgstr "Те саме, що й %s." #: opts.cc:1670 #, c-format msgid "%s Same as %s." -msgstr "" +msgstr "%s Те саме, що й %s." #: opts.cc:1733 msgid "[available in " -msgstr "[доступний у " +msgstr "[доступно в " #: opts.cc:1765 msgid "[default]" -msgstr "[типовий]" +msgstr "[за замовчуванням]" #: opts.cc:1774 #, c-format msgid "%llu bytes" -msgstr "" +msgstr "%llu байт" #: opts.cc:1811 msgid "[enabled]" @@ -18326,17 +18295,17 @@ msgstr "[вимкнено]" #: opts.cc:1849 #, c-format msgid " No options with the desired characteristics were found\n" -msgstr "" +msgstr " Не знайдено жодних параметрів з бажаними характеристиками\n" #: opts.cc:1858 #, c-format msgid " None found. Use --help=%s to show *all* the options supported by the %s front-end.\n" -msgstr "" +msgstr " Не знайдено жодного. Використовуйте --help=%s, щоб показати *всі* параметри, підтримувані %s інтерфейсом.\n" #: opts.cc:1864 #, c-format msgid " All options with the desired characteristics have already been displayed\n" -msgstr "" +msgstr " Всі параметри з бажаними характеристиками вже були показані\n" #: opts.cc:1909 #, c-format @@ -18344,62 +18313,62 @@ msgid "" " Known valid arguments for %s option:\n" " " msgstr "" -" Відомі коректні аргументи для параметра %s:\n" +" Відомі дійсні аргументи для параметра %s:\n" " " #: opts.cc:1959 msgid "The following options are target specific" -msgstr "" +msgstr "Наступні параметри специфічні для цілей" #: opts.cc:1962 msgid "The following options control compiler warning messages" -msgstr "" +msgstr "Наступні параметри керують повідомленнями про попередження компілятора" #: opts.cc:1965 msgid "The following options control optimizations" -msgstr "" +msgstr "Наступні параметри керують оптимізаціями" #: opts.cc:1968 opts.cc:2008 msgid "The following options are language-independent" -msgstr "" +msgstr "Наступні параметри не залежать від мови" #: opts.cc:1971 msgid "The following options control parameters" -msgstr "" +msgstr "Наступні параметри керують параметрами" #: opts.cc:1977 msgid "The following options are specific to just the language " -msgstr "" +msgstr "Наступні параметри специфічні лише для мови " #: opts.cc:1979 msgid "The following options are supported by the language " -msgstr "" +msgstr "Наступні параметри підтримуються мовою " #: opts.cc:1990 msgid "The following options are not documented" -msgstr "" +msgstr "Наступні параметри не задокументовані" #: opts.cc:1992 msgid "The following options take separate arguments" -msgstr "" +msgstr "Наступні параметри приймають окремі аргументи" #: opts.cc:1994 msgid "The following options take joined arguments" -msgstr "" +msgstr "Наступні параметри приймають обʼєднані аргументи" #: opts.cc:2006 msgid "The following options are language-related" -msgstr "" +msgstr "Наступні параметри повʼязані з мовою" #: passes.cc:1839 #, c-format msgid "during %s pass: %s\n" -msgstr "" +msgstr "під час %s проходу: %s\n" #: passes.cc:1844 #, c-format msgid "dump file: %s\n" -msgstr "" +msgstr "файл дампу: %s\n" #: plugin.cc:965 msgid "Event" @@ -18407,56 +18376,56 @@ msgstr "Подія" #: plugin.cc:965 msgid "Plugins" -msgstr "Додатки" +msgstr "Плагіни" #: plugin.cc:997 #, c-format msgid "*** WARNING *** there are active plugins, do not report this as a bug unless you can reproduce it without enabling any plugins.\n" -msgstr "" +msgstr "*** ПОПЕРЕДЖЕННЯ *** є активні плагіни, не повідомляйте це як помилку, якщо ви не можете відтворити це без включення будь-яких плагінів.\n" #: postreload-gcse.cc:1355 msgid "using simple load CSE after register allocation" -msgstr "" +msgstr "використання простого завантаження CSE після розподілу реєстрів" #. It's the compiler's fault. #: reload1.cc:5994 msgid "could not find a spill register" -msgstr "" +msgstr "не вдалося знайти реєстр переповнення" #. It's the compiler's fault. #: reload1.cc:7876 msgid "VOIDmode on an output" -msgstr "" +msgstr "VOIDmode на виході" #: reload1.cc:8609 msgid "failure trying to reload:" -msgstr "" +msgstr "помилка під час спроби перезавантаження:" #: rtl-error.cc:116 msgid "unrecognizable insn:" -msgstr "" +msgstr "нерозпізнаваний insn:" #: rtl-error.cc:118 msgid "insn does not satisfy its constraints:" -msgstr "" +msgstr "insn не задовольняє свої обмеження:" #: targhooks.cc:2274 #, c-format msgid "created and used with differing settings of '%s'" -msgstr "" +msgstr "створено і використовується з різними налаштуваннями «%s»" #: targhooks.cc:2289 msgid "created and used with different settings of %<-fpic%>" -msgstr "" +msgstr "створено і використано з різними налаштуваннями %<-fpic%>" #: targhooks.cc:2291 msgid "created and used with different settings of %<-fpie%>" -msgstr "" +msgstr "створено і використано з різними налаштуваннями %<-fpie%>" #: toplev.cc:310 #, c-format msgid "unrecoverable error" -msgstr "критична помилка" +msgstr "непоправна помилка" #: toplev.cc:603 #, c-format @@ -18464,32 +18433,34 @@ msgid "" "%s%s%s %sversion %s (%s)\n" "%s\tcompiled by GNU C version %s, " msgstr "" +"%s%s%s %sверсія %s (%s)\n" +"%s\tскомпільовано за допомогою GNU C версії %s, " #: toplev.cc:605 #, c-format msgid "%s%s%s %sversion %s (%s) compiled by CC, " -msgstr "" +msgstr "%s%s%s %sверсія %s (%s) скомпільовано за допомогою CC, " #: toplev.cc:609 #, c-format msgid "GMP version %s, MPFR version %s, MPC version %s, isl version %s\n" -msgstr "" +msgstr "Версія GMP %s, версія MPFR %s, версія MPC %s, версія isl %s\n" #: toplev.cc:611 #, c-format msgid "%s%swarning: %s header version %s differs from library version %s.\n" -msgstr "" +msgstr "%s%sпопередження: версія заголовка %s %s відрізняється від версії бібліотеки %s.\n" #: toplev.cc:613 #, c-format msgid "%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n" -msgstr "" +msgstr "%s%sГеуритика GGC: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n" #: tree-diagnostic-path.cc:255 tree-diagnostic.cc:294 c/c-decl.cc:6349 #: c/c-typeck.cc:8058 cp/error.cc:1181 c-family/c-pretty-print.cc:426 #, gcc-internal-format msgid "" -msgstr "" +msgstr "<анонімний>" #: c-family/c-format.cc:432 msgid "format" @@ -18497,90 +18468,90 @@ msgstr "формат" #: c-family/c-format.cc:433 msgid "field width specifier" -msgstr "" +msgstr "специфікатор ширини поля" #: c-family/c-format.cc:434 msgid "field precision specifier" -msgstr "" +msgstr "специфікатор точності поля" #: c-family/c-format.cc:569 c-family/c-format.cc:593 #: config/i386/msformat-c.cc:45 msgid "' ' flag" -msgstr "прапорець ' '" +msgstr "прапорець «пробіл»" #: c-family/c-format.cc:569 c-family/c-format.cc:593 #: config/i386/msformat-c.cc:45 msgid "the ' ' printf flag" -msgstr "прапорець printf ' '" +msgstr "прапорець «пробіл» у printf" #: c-family/c-format.cc:570 c-family/c-format.cc:594 c-family/c-format.cc:625 #: c-family/c-format.cc:691 config/i386/msformat-c.cc:46 msgid "'+' flag" -msgstr "прапорець '+'" +msgstr "прапорець «+»" #: c-family/c-format.cc:570 c-family/c-format.cc:594 c-family/c-format.cc:625 #: config/i386/msformat-c.cc:46 msgid "the '+' printf flag" -msgstr "прапорець printf «+»" +msgstr "прапорець «+» у printf" #: c-family/c-format.cc:571 c-family/c-format.cc:595 c-family/c-format.cc:626 #: c-family/c-format.cc:666 config/i386/msformat-c.cc:47 #: config/i386/msformat-c.cc:82 msgid "'#' flag" -msgstr "прапорець '#'" +msgstr "прапорець «#»" #: c-family/c-format.cc:571 c-family/c-format.cc:595 c-family/c-format.cc:626 #: config/i386/msformat-c.cc:47 msgid "the '#' printf flag" -msgstr "прапорець printf '#'" +msgstr "прапорець «#» у printf" #: c-family/c-format.cc:572 c-family/c-format.cc:596 c-family/c-format.cc:664 #: config/i386/msformat-c.cc:48 msgid "'0' flag" -msgstr "прапорець '0'" +msgstr "прапорець «0»" #: c-family/c-format.cc:572 c-family/c-format.cc:596 #: config/i386/msformat-c.cc:48 msgid "the '0' printf flag" -msgstr "прапорець printf '0'" +msgstr "прапорець «0» у printf" #: c-family/c-format.cc:573 c-family/c-format.cc:597 c-family/c-format.cc:663 #: c-family/c-format.cc:694 config/i386/msformat-c.cc:49 msgid "'-' flag" -msgstr "прапорець '-'" +msgstr "прапорець «-»" #: c-family/c-format.cc:573 c-family/c-format.cc:597 #: config/i386/msformat-c.cc:49 msgid "the '-' printf flag" -msgstr "прапорець printf «-»" +msgstr "прапорець «-» у printf" #: c-family/c-format.cc:574 c-family/c-format.cc:646 #: config/i386/msformat-c.cc:50 config/i386/msformat-c.cc:70 msgid "''' flag" -msgstr "прапорець '''" +msgstr "прапорець «'»" #: c-family/c-format.cc:574 config/i386/msformat-c.cc:50 msgid "the ''' printf flag" -msgstr "прапорець printf '''" +msgstr "прапорець «'» у printf" #: c-family/c-format.cc:575 c-family/c-format.cc:647 msgid "'I' flag" -msgstr "прапорець 'I'" +msgstr "прапорець «I»" #: c-family/c-format.cc:575 msgid "the 'I' printf flag" -msgstr "" +msgstr "прапорець «I» у printf" #: c-family/c-format.cc:576 c-family/c-format.cc:598 c-family/c-format.cc:644 #: c-family/c-format.cc:667 c-family/c-format.cc:695 config/sol2-c.cc:43 #: config/i386/msformat-c.cc:51 config/i386/msformat-c.cc:68 msgid "field width" -msgstr "" +msgstr "ширина поля" #: c-family/c-format.cc:576 c-family/c-format.cc:598 config/sol2-c.cc:43 #: config/i386/msformat-c.cc:51 msgid "field width in printf format" -msgstr "" +msgstr "ширина поля у форматі printf" #: c-family/c-format.cc:577 c-family/c-format.cc:599 c-family/c-format.cc:628 #: config/i386/msformat-c.cc:52 @@ -18590,66 +18561,66 @@ msgstr "точність" #: c-family/c-format.cc:577 c-family/c-format.cc:599 c-family/c-format.cc:628 #: config/i386/msformat-c.cc:52 msgid "precision in printf format" -msgstr "" +msgstr "точність у форматі printf" #: c-family/c-format.cc:578 c-family/c-format.cc:600 c-family/c-format.cc:629 #: c-family/c-format.cc:645 c-family/c-format.cc:698 config/sol2-c.cc:44 #: config/i386/msformat-c.cc:53 config/i386/msformat-c.cc:69 msgid "length modifier" -msgstr "" +msgstr "модифікатор довжини" #: c-family/c-format.cc:578 c-family/c-format.cc:600 c-family/c-format.cc:629 #: config/sol2-c.cc:44 config/i386/msformat-c.cc:53 msgid "length modifier in printf format" -msgstr "" +msgstr "модифікатор довжини у форматі printf" #: c-family/c-format.cc:627 msgid "'q' flag" -msgstr "" +msgstr "прапорець 'q'" #: c-family/c-format.cc:627 msgid "the 'q' diagnostic flag" -msgstr "" +msgstr "прапорець 'q' для діагностики" #: c-family/c-format.cc:641 config/i386/msformat-c.cc:66 msgid "assignment suppression" -msgstr "" +msgstr "пригнічення присвоєння" #: c-family/c-format.cc:641 config/i386/msformat-c.cc:66 msgid "the assignment suppression scanf feature" -msgstr "" +msgstr "функція пригнічення присвоєння scanf" #: c-family/c-format.cc:642 config/i386/msformat-c.cc:67 msgid "'a' flag" -msgstr "" +msgstr "прапорець 'a'" #: c-family/c-format.cc:642 config/i386/msformat-c.cc:67 msgid "the 'a' scanf flag" -msgstr "" +msgstr "прапорець 'a' для scanf" #: c-family/c-format.cc:643 msgid "'m' flag" -msgstr "" +msgstr "прапорець 'm'" #: c-family/c-format.cc:643 msgid "the 'm' scanf flag" -msgstr "" +msgstr "прапорець 'm' для scanf" #: c-family/c-format.cc:644 config/i386/msformat-c.cc:68 msgid "field width in scanf format" -msgstr "" +msgstr "ширина поля у форматі scanf" #: c-family/c-format.cc:645 config/i386/msformat-c.cc:69 msgid "length modifier in scanf format" -msgstr "" +msgstr "модифікатор довжини у форматі scanf" #: c-family/c-format.cc:646 config/i386/msformat-c.cc:70 msgid "the ''' scanf flag" -msgstr "" +msgstr "прапорець ''' для scanf" #: c-family/c-format.cc:647 msgid "the 'I' scanf flag" -msgstr "" +msgstr "прапорець 'I' для scanf" #: c-family/c-format.cc:662 msgid "'_' flag" @@ -18657,15 +18628,15 @@ msgstr "прапорець '_'" #: c-family/c-format.cc:662 msgid "the '_' strftime flag" -msgstr "" +msgstr "прапорець '_' у форматі strftime" #: c-family/c-format.cc:663 msgid "the '-' strftime flag" -msgstr "" +msgstr "прапорець '-' у форматі strftime" #: c-family/c-format.cc:664 msgid "the '0' strftime flag" -msgstr "" +msgstr "прапорець '0' у форматі strftime" #: c-family/c-format.cc:665 c-family/c-format.cc:690 msgid "'^' flag" @@ -18673,51 +18644,51 @@ msgstr "прапорець '^'" #: c-family/c-format.cc:665 msgid "the '^' strftime flag" -msgstr "" +msgstr "прапорець '^' у форматі strftime" #: c-family/c-format.cc:666 config/i386/msformat-c.cc:82 msgid "the '#' strftime flag" -msgstr "" +msgstr "прапорець '#' у форматі strftime" #: c-family/c-format.cc:667 msgid "field width in strftime format" -msgstr "" +msgstr "ширина поля у форматі strftime" #: c-family/c-format.cc:668 msgid "'E' modifier" -msgstr "" +msgstr "модифікатор 'E'" #: c-family/c-format.cc:668 msgid "the 'E' strftime modifier" -msgstr "" +msgstr "модифікатор 'E' у форматі strftime" #: c-family/c-format.cc:669 msgid "'O' modifier" -msgstr "" +msgstr "модифікатор 'O'" #: c-family/c-format.cc:669 msgid "the 'O' strftime modifier" -msgstr "" +msgstr "модифікатор 'O' у форматі strftime" #: c-family/c-format.cc:670 c-family/c-format.cc:671 msgid "the 'O' modifier" -msgstr "" +msgstr "модифікатор 'O'" #: c-family/c-format.cc:689 msgid "fill character" -msgstr "" +msgstr "символ заповнення" #: c-family/c-format.cc:689 msgid "fill character in strfmon format" -msgstr "" +msgstr "символ заповнення у форматі strfmon" #: c-family/c-format.cc:690 msgid "the '^' strfmon flag" -msgstr "прапорець strfmon «^»" +msgstr "прапорець '^' у форматі strfmon" #: c-family/c-format.cc:691 msgid "the '+' strfmon flag" -msgstr "прапорець strfmon '+'" +msgstr "прапорець '+' у форматі strfmon" #: c-family/c-format.cc:692 msgid "'(' flag" @@ -18725,7 +18696,7 @@ msgstr "прапорець '('" #: c-family/c-format.cc:692 msgid "the '(' strfmon flag" -msgstr "прапорець strfmon '('" +msgstr "прапорець '(' у форматі strfmon" #: c-family/c-format.cc:693 msgid "'!' flag" @@ -18733,45 +18704,45 @@ msgstr "прапорець '!'" #: c-family/c-format.cc:693 msgid "the '!' strfmon flag" -msgstr "прапорець strfmon «!»" +msgstr "прапорець '!' у форматі strfmon" #: c-family/c-format.cc:694 msgid "the '-' strfmon flag" -msgstr "прапорець strfmon «-»" +msgstr "прапорець '-' у форматі strfmon" #: c-family/c-format.cc:695 msgid "field width in strfmon format" -msgstr "" +msgstr "ширина поля у форматі strfmon" #: c-family/c-format.cc:696 msgid "left precision" -msgstr "" +msgstr "ліва точність" #: c-family/c-format.cc:696 msgid "left precision in strfmon format" -msgstr "" +msgstr "ліва точність у форматі strfmon" #: c-family/c-format.cc:697 msgid "right precision" -msgstr "" +msgstr "права точність" #: c-family/c-format.cc:697 msgid "right precision in strfmon format" -msgstr "" +msgstr "права точність у форматі strfmon" #: c-family/c-format.cc:698 msgid "length modifier in strfmon format" -msgstr "" +msgstr "модифікатор довжини у форматі strfmon" #. Handle deferred options from command-line. #: c-family/c-opts.cc:1504 fortran/cpp.cc:621 msgid "" -msgstr "" +msgstr "<командний рядок>" #: config/aarch64/aarch64.cc:11892 config/loongarch/loongarch.cc:4992 #, c-format msgid "unsupported operand for code '%c'" -msgstr "" +msgstr "непідтримуваний операнд для коду '%c'" #: config/aarch64/aarch64.cc:11901 config/aarch64/aarch64.cc:11914 #: config/aarch64/aarch64.cc:11926 config/aarch64/aarch64.cc:11937 @@ -18782,7 +18753,7 @@ msgstr "" #: config/pru/pru.cc:1760 config/pru/pru.cc:1771 config/pru/pru.cc:1843 #, c-format msgid "invalid operand for '%%%c'" -msgstr "некоректний операнд для «%%%c»" +msgstr "недійсний операнд для '%%%c'" #: config/aarch64/aarch64.cc:12005 config/aarch64/aarch64.cc:12016 #: config/aarch64/aarch64.cc:12171 config/aarch64/aarch64.cc:12182 @@ -18791,125 +18762,125 @@ msgstr "некоректний операнд для «%%%c»" #: config/riscv/riscv.cc:4468 config/riscv/riscv.cc:4487 #, c-format msgid "invalid vector constant" -msgstr "некоректна векторна константа" +msgstr "недійсна векторна константа" #: config/aarch64/aarch64.cc:12028 config/aarch64/aarch64.cc:12040 #, c-format msgid "incompatible floating point / vector register operand for '%%%c'" -msgstr "" +msgstr "несумісний операнд з регістром з плаваючою комою / векторним для '%%%c'" #: config/aarch64/aarch64.cc:12057 #, c-format msgid "incompatible register operand for '%%%c'" -msgstr "несумісний операнд регістру для «%%%c»" +msgstr "несумісний операнд з регістром для '%%%c'" #: config/aarch64/aarch64.cc:12123 config/arm/arm.cc:24721 #, c-format msgid "missing operand" -msgstr "пропущено операнд" +msgstr "відсутній операнд" #: config/aarch64/aarch64.cc:12208 #, c-format msgid "invalid constant" -msgstr "некоректна константа" +msgstr "недійсна константа" #: config/aarch64/aarch64.cc:12211 #, c-format msgid "invalid operand" -msgstr "некоректний операнд" +msgstr "недійсний операнд" #: config/aarch64/aarch64.cc:12339 config/aarch64/aarch64.cc:12344 #, c-format msgid "invalid operand prefix '%%%c'" -msgstr "некоректний префікс операнда «%%%c»" +msgstr "неприпустимий префікс операнда '%%%c'" #: config/aarch64/aarch64.cc:12364 #, c-format msgid "invalid address mode" -msgstr "некоректний режим адресування" +msgstr "неприпустимий режим адреси" #: config/aarch64/aarch64.cc:27161 msgid "cannot combine GNU and SVE vectors in a binary operation" -msgstr "" +msgstr "не можна комбінувати вектори GNU та SVE в бінарній операції" #: config/alpha/alpha.cc:5076 config/i386/i386.cc:13585 #: config/rs6000/rs6000.cc:14364 config/sparc/sparc.cc:9370 #, c-format msgid "'%%&' used without any local dynamic TLS references" -msgstr "'%%&' використано без будь-яких локальних динамічних посилань TLS" +msgstr "'%%&' використовується без будь-яких локальних динамічних посилань TLS" #: config/alpha/alpha.cc:5134 config/bfin/bfin.cc:1428 #, c-format msgid "invalid %%J value" -msgstr "некоректне значення %%J" +msgstr "неприпустиме значення %%J" #: config/alpha/alpha.cc:5164 config/ia64/ia64.cc:5578 #: config/or1k/or1k.cc:1249 #, c-format msgid "invalid %%r value" -msgstr "некоректне значення %%r" +msgstr "неприпустиме значення %%r" #: config/alpha/alpha.cc:5174 config/ia64/ia64.cc:5532 #: config/rs6000/rs6000.cc:14059 config/xtensa/xtensa.cc:3008 #, c-format msgid "invalid %%R value" -msgstr "некоректне значення %%R" +msgstr "неприпустиме значення %%R" #: config/alpha/alpha.cc:5180 config/rs6000/rs6000.cc:13979 #: config/xtensa/xtensa.cc:2981 #, c-format msgid "invalid %%N value" -msgstr "некоректне значення %%N" +msgstr "неприпустиме значення %%N" #: config/alpha/alpha.cc:5188 config/rs6000/rs6000.cc:14007 #, c-format msgid "invalid %%P value" -msgstr "некоректне значення %%P" +msgstr "недійсне значення %%P" #: config/alpha/alpha.cc:5196 #, c-format msgid "invalid %%h value" -msgstr "некоректне значення %%h" +msgstr "недійсне значення %%h" #: config/alpha/alpha.cc:5204 config/xtensa/xtensa.cc:3001 #, c-format msgid "invalid %%L value" -msgstr "некоректне значення %%L" +msgstr "недійсне значення %%L" #: config/alpha/alpha.cc:5223 #, c-format msgid "invalid %%m value" -msgstr "некоректне значення %%m" +msgstr "недійсне значення %%m" #: config/alpha/alpha.cc:5229 #, c-format msgid "invalid %%M value" -msgstr "некоректне значення %%M" +msgstr "недійсне значення %%M" #: config/alpha/alpha.cc:5266 #, c-format msgid "invalid %%U value" -msgstr "некоректне значення %%U" +msgstr "недійсне значення %%U" #: config/alpha/alpha.cc:5274 config/rs6000/rs6000.cc:14067 #, c-format msgid "invalid %%s value" -msgstr "некоректне значення %%s" +msgstr "недійсне значення %%s" #: config/alpha/alpha.cc:5285 #, c-format msgid "invalid %%C value" -msgstr "некоректне значення %%C" +msgstr "недійсне значення %%C" #: config/alpha/alpha.cc:5322 config/rs6000/rs6000.cc:13843 #, c-format msgid "invalid %%E value" -msgstr "некоректне значення %%E" +msgstr "недійсне значення %%E" #: config/alpha/alpha.cc:5347 config/alpha/alpha.cc:5397 #, c-format msgid "unknown relocation unspec" -msgstr "" +msgstr "невідома перерозташування unspec" #: config/alpha/alpha.cc:5356 config/gcn/gcn.cc:6940 config/gcn/gcn.cc:6949 #: config/gcn/gcn.cc:7009 config/gcn/gcn.cc:7017 config/gcn/gcn.cc:7033 @@ -18917,67 +18888,67 @@ msgstr "" #: config/gcn/gcn.cc:7332 config/rs6000/rs6000.cc:14369 #, c-format msgid "invalid %%xn code" -msgstr "" +msgstr "недійсний код %%xn" #: config/alpha/alpha.cc:5462 #, c-format msgid "invalid operand address" -msgstr "" +msgstr "недійсна адреса операнда" #: config/arc/arc.cc:4545 #, c-format msgid "invalid operand to %%Z code" -msgstr "" +msgstr "недійсний операнд для коду %%Z" #: config/arc/arc.cc:4553 #, c-format msgid "invalid operand to %%z code" -msgstr "" +msgstr "недійсний операнд для коду %%z" #: config/arc/arc.cc:4561 #, c-format msgid "invalid operands to %%c code" -msgstr "некоректні операнди для коду %%c" +msgstr "недійсні операнди для коду %%c" #: config/arc/arc.cc:4569 #, c-format msgid "invalid operand to %%M code" -msgstr "" +msgstr "недійсний операнд для коду %%M" #: config/arc/arc.cc:4577 config/m32r/m32r.cc:2090 #, c-format msgid "invalid operand to %%p code" -msgstr "" +msgstr "недійсний операнд для коду %%p" #: config/arc/arc.cc:4588 config/m32r/m32r.cc:2083 #, c-format msgid "invalid operand to %%s code" -msgstr "" +msgstr "недійсний операнд для коду %%s" #: config/arc/arc.cc:4736 config/m32r/m32r.cc:2116 #, c-format msgid "invalid operand to %%R code" -msgstr "" +msgstr "недійсний операнд для коду %%R" #: config/arc/arc.cc:4812 config/m32r/m32r.cc:2139 #, c-format msgid "invalid operand to %%H/%%L code" -msgstr "" +msgstr "недійсний операнд для коду %%H/%%L" #: config/arc/arc.cc:4880 config/m32r/m32r.cc:2210 #, c-format msgid "invalid operand to %%U code" -msgstr "" +msgstr "недійсний операнд для коду %%U" #: config/arc/arc.cc:4892 #, c-format msgid "invalid operand to %%V code" -msgstr "" +msgstr "недійсний операнд для коду %%V" #: config/arc/arc.cc:4949 #, c-format msgid "invalid operand to %%O code" -msgstr "" +msgstr "недійсний операнд для коду %%O" #. Unknown flag. #. Undocumented flag. @@ -18986,38 +18957,38 @@ msgstr "" #: config/sparc/sparc.cc:9649 #, c-format msgid "invalid operand output code" -msgstr "" +msgstr "недійсний код виводу операнду" #: config/arc/arc.cc:6515 #, c-format msgid "invalid UNSPEC as operand: %d" -msgstr "" +msgstr "недійсний UNSPEC як операнд: %d" #: config/arc/arc.cc:6731 msgid "unrecognized supposed constant" -msgstr "" +msgstr "нерозпізнана припущена константа" #: config/arm/arm.cc:21009 config/arm/arm.cc:21034 config/arm/arm.cc:21044 #: config/arm/arm.cc:21053 config/arm/arm.cc:21062 #, c-format msgid "invalid shift operand" -msgstr "" +msgstr "недійсний операнд зсуву" #: config/arm/arm.cc:23971 config/arm/arm.cc:23989 #, c-format msgid "predicated Thumb instruction" -msgstr "" +msgstr "умовна інструкція Thumb" #: config/arm/arm.cc:23977 #, c-format msgid "predicated instruction in conditional sequence" -msgstr "" +msgstr "умовна інструкція в умовній послідовності" #: config/arm/arm.cc:24098 config/arm/arm.cc:24111 config/arm/arm.cc:24136 #: config/nios2/nios2.cc:3084 #, c-format msgid "Unsupported operand for code '%c'" -msgstr "" +msgstr "Непідтримуваний операнд для коду '%c'" #: config/arm/arm.cc:24213 config/arm/arm.cc:24235 config/arm/arm.cc:24245 #: config/arm/arm.cc:24255 config/arm/arm.cc:24265 config/arm/arm.cc:24304 @@ -19032,97 +19003,97 @@ msgstr "" #: config/nds32/nds32.cc:3546 #, c-format msgid "invalid operand for code '%c'" -msgstr "" +msgstr "недійсний операнд для коду '%c'" #: config/arm/arm.cc:24317 #, c-format msgid "instruction never executed" -msgstr "" +msgstr "інструкція ніколи не виконується" #. Former Maverick support, removed after GCC-4.7. #: config/arm/arm.cc:24358 #, c-format msgid "obsolete Maverick format code '%c'" -msgstr "" +msgstr "застарілий код формату Maverick '%c'" #: config/arm/arm.cc:34270 msgid "invalid conversion from type %" -msgstr "некоректне перетворення з типу %" +msgstr "недійсне перетворення з типу %" #: config/arm/arm.cc:34272 msgid "invalid conversion to type %" -msgstr "некоректне перетворення до типу %" +msgstr "недійсне перетворення до типу %" #: config/arm/arm.cc:34287 config/arm/arm.cc:34303 msgid "operation not permitted on type %" -msgstr "" +msgstr "операція не дозволена для типу %" #: config/avr/avr.cc:2642 #, c-format msgid "address operand requires constraint for X, Y, or Z register" -msgstr "" +msgstr "операнд адреси потребує обмеження для регістра X, Y або Z" #: config/avr/avr.cc:2825 msgid "operands to %T/%t must be reg + const_int:" -msgstr "" +msgstr "операнди для %T/%t повинні бути reg + const_int:" #: config/avr/avr.cc:2875 config/avr/avr.cc:2942 msgid "bad address, not an I/O address:" -msgstr "" +msgstr "погана адреса, не адреса введення/виведення:" #: config/avr/avr.cc:2884 msgid "bad address, not a constant:" -msgstr "" +msgstr "погана адреса, не константа:" #: config/avr/avr.cc:2902 config/avr/avr.cc:2909 msgid "bad address, not (reg+disp):" -msgstr "" +msgstr "погана адреса, не (reg+disp):" #: config/avr/avr.cc:2916 msgid "bad address, not post_inc or pre_dec:" -msgstr "" +msgstr "неправильна адреса, не post_inc або pre_dec:" #: config/avr/avr.cc:2928 msgid "internal compiler error. Bad address:" -msgstr "" +msgstr "внутрішня помилка компілятора. Погана адреса:" #: config/avr/avr.cc:2961 #, c-format msgid "Unsupported code '%c' for fixed-point:" -msgstr "" +msgstr "Непідтримуваний код '%c' для фіксованої точки:" #: config/avr/avr.cc:2969 msgid "internal compiler error. Unknown mode:" -msgstr "" +msgstr "внутрішня помилка компілятора. Невідомий режим:" #: config/avr/avr.cc:3866 config/avr/avr.cc:4810 config/avr/avr.cc:5257 msgid "invalid insn:" -msgstr "" +msgstr "неправильна інструкція:" #: config/avr/avr.cc:3920 config/avr/avr.cc:4032 config/avr/avr.cc:4090 #: config/avr/avr.cc:4142 config/avr/avr.cc:4161 config/avr/avr.cc:4353 #: config/avr/avr.cc:4661 config/avr/avr.cc:4946 config/avr/avr.cc:5150 #: config/avr/avr.cc:5314 config/avr/avr.cc:5407 config/avr/avr.cc:5606 msgid "incorrect insn:" -msgstr "" +msgstr "неправильна інструкція:" #: config/avr/avr.cc:4177 config/avr/avr.cc:4452 config/avr/avr.cc:4732 #: config/avr/avr.cc:5018 config/avr/avr.cc:5196 config/avr/avr.cc:5463 #: config/avr/avr.cc:5664 msgid "unknown move insn:" -msgstr "" +msgstr "невідома інструкція переміщення:" #: config/avr/avr.cc:6131 msgid "bad shift insn:" -msgstr "" +msgstr "неправильна інструкція зсуву:" #: config/avr/avr.cc:6239 config/avr/avr.cc:6722 config/avr/avr.cc:7139 msgid "internal compiler error. Incorrect shift:" -msgstr "" +msgstr "внутрішня помилка компілятора. Неправильний зсув:" #: config/avr/avr.cc:8547 msgid "unsupported fixed-point conversion" -msgstr "" +msgstr "непідтримуване перетворення з фіксованою точкою" #: config/avr/avr.cc:9916 msgid "variable" @@ -19138,7 +19109,7 @@ msgstr "поле структури" #: config/avr/avr.cc:9932 msgid "return type of function" -msgstr "тип значення, яке повертає функція" +msgstr "тип повернення функції" #: config/avr/avr.cc:9937 msgid "pointer" @@ -19150,20 +19121,22 @@ msgid "" "Running spec function '%s' with %d args\n" "\n" msgstr "" +"Виконання функції spec '%s' з %d аргументами\n" +"\n" #: config/bfin/bfin.cc:1390 #, c-format msgid "invalid %%j value" -msgstr "некоректне значення %%j" +msgstr "недійсне значення %%j" #: config/bfin/bfin.cc:1583 config/c6x/c6x.cc:2279 #, c-format msgid "invalid const_double operand" -msgstr "" +msgstr "недійсний операнд const_double" #: config/bpf/bpf.cc:953 msgid "invalid address in operand" -msgstr "некоректна адреса в операнді" +msgstr "недійсна адреса в операнді" #. Fallthrough. #: config/bpf/bpf.cc:960 @@ -19188,390 +19161,388 @@ msgstr "%s" #: config/cris/cris.cc:826 msgid "unexpected index-type in cris_print_index" -msgstr "" +msgstr "неочікуваний тип індексу в cris_print_index" #: config/cris/cris.cc:840 msgid "unexpected base-type in cris_print_base" -msgstr "" +msgstr "неочікуваний базовий тип в cris_print_base" #: config/cris/cris.cc:895 msgid "invalid operand for 'b' modifier" -msgstr "" +msgstr "недійсний операнд для модифікатора 'b'" #: config/cris/cris.cc:912 msgid "invalid operand for 'o' modifier" -msgstr "" +msgstr "недійсний операнд для модифікатора 'o'" #: config/cris/cris.cc:931 msgid "invalid operand for 'O' modifier" -msgstr "" +msgstr "недійсний операнд для модифікатора 'O'" #: config/cris/cris.cc:964 msgid "invalid operand for 'p' modifier" -msgstr "" +msgstr "недійсний операнд для модифікатора 'p'" #: config/cris/cris.cc:1003 msgid "invalid operand for 'z' modifier" -msgstr "" +msgstr "недійсний операнд для модифікатора 'z'" #: config/cris/cris.cc:1050 config/cris/cris.cc:1084 msgid "invalid operand for 'H' modifier" -msgstr "" +msgstr "неприпустимий операнд для модифікатора 'H'" #: config/cris/cris.cc:1060 msgid "bad register" -msgstr "помилковий регістр" +msgstr "неправильний регістр" #: config/cris/cris.cc:1104 msgid "invalid operand for 'e' modifier" -msgstr "" +msgstr "неприпустимий операнд для модифікатора 'e'" #: config/cris/cris.cc:1121 msgid "invalid operand for 'm' modifier" -msgstr "" +msgstr "неприпустимий операнд для модифікатора 'm'" #: config/cris/cris.cc:1146 msgid "invalid operand for 'A' modifier" -msgstr "" +msgstr "неприпустимий операнд для модифікатора 'A'" #: config/cris/cris.cc:1201 msgid "invalid operand for 'D' modifier" -msgstr "" +msgstr "неприпустимий операнд для модифікатора 'D'" #: config/cris/cris.cc:1218 config/cris/cris.cc:1223 msgid "invalid operand for 'T' modifier" -msgstr "" +msgstr "неприпустимий операнд для модифікатора 'T'" #: config/cris/cris.cc:1234 config/ft32/ft32.cc:236 config/moxie/moxie.cc:178 msgid "invalid operand modifier letter" -msgstr "" +msgstr "неприпустима літера модифікатора операнду" #: config/cris/cris.cc:1286 msgid "unexpected multiplicative operand" -msgstr "" +msgstr "неочікуваний множниковий операнд" #: config/cris/cris.cc:1306 config/ft32/ft32.cc:259 config/moxie/moxie.cc:203 msgid "unexpected operand" -msgstr "" +msgstr "неочікуваний операнд" #: config/cris/cris.cc:1345 config/cris/cris.cc:1355 msgid "unrecognized address" -msgstr "" +msgstr "невпізнана адреса" #: config/cris/cris.cc:2556 config/cris/cris.cc:2609 msgid "unexpected side-effects in address" -msgstr "" +msgstr "неочікувані побічні ефекти в адресі" #: config/fr30/fr30.cc:513 #, c-format msgid "fr30_print_operand_address: unhandled address" -msgstr "" +msgstr "fr30_print_operand_address: неврахована адреса" #: config/fr30/fr30.cc:537 #, c-format msgid "fr30_print_operand: unrecognized %%p code" -msgstr "" +msgstr "fr30_print_operand: невизнаний код %%p" #: config/fr30/fr30.cc:557 #, c-format msgid "fr30_print_operand: unrecognized %%b code" -msgstr "" +msgstr "fr30_print_operand: невизнаний код %%b" #: config/fr30/fr30.cc:578 #, c-format msgid "fr30_print_operand: unrecognized %%B code" -msgstr "" +msgstr "fr30_print_operand: невизнаний код %%B" #: config/fr30/fr30.cc:586 #, c-format msgid "fr30_print_operand: invalid operand to %%A code" -msgstr "" +msgstr "fr30_print_operand: недійсний операнд для коду %%A" #: config/fr30/fr30.cc:603 #, c-format msgid "fr30_print_operand: invalid %%x code" -msgstr "" +msgstr "fr30_print_operand: недійсний код %%x" #: config/fr30/fr30.cc:610 #, c-format msgid "fr30_print_operand: invalid %%F code" -msgstr "" +msgstr "fr30_print_operand: недійсний код %%F" #: config/fr30/fr30.cc:627 #, c-format msgid "fr30_print_operand: unknown code" -msgstr "" +msgstr "fr30_print_operand: невідомий код" #: config/fr30/fr30.cc:655 config/fr30/fr30.cc:664 config/fr30/fr30.cc:675 #: config/fr30/fr30.cc:688 #, c-format msgid "fr30_print_operand: unhandled MEM" -msgstr "" +msgstr "fr30_print_operand: невиконана MEM" #: config/frv/frv.cc:2491 msgid "bad insn to frv_print_operand_address:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand_address:" #: config/frv/frv.cc:2502 msgid "bad register to frv_print_operand_memory_reference_reg:" -msgstr "" +msgstr "неправильний регістр для frv_print_operand_memory_reference_reg:" #: config/frv/frv.cc:2541 config/frv/frv.cc:2551 config/frv/frv.cc:2560 #: config/frv/frv.cc:2581 config/frv/frv.cc:2586 msgid "bad insn to frv_print_operand_memory_reference:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand_memory_reference:" #: config/frv/frv.cc:2671 #, c-format msgid "bad condition code" -msgstr "" +msgstr "неправильний код умови" #: config/frv/frv.cc:2745 msgid "bad insn in frv_print_operand, bad const_double" -msgstr "" +msgstr "неправильна інструкція в frv_print_operand, поганий const_double" #: config/frv/frv.cc:2806 msgid "bad insn to frv_print_operand, 'e' modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «e»:" #: config/frv/frv.cc:2814 msgid "bad insn to frv_print_operand, 'F' modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «F»:" #: config/frv/frv.cc:2830 msgid "bad insn to frv_print_operand, 'f' modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «f»:" #: config/frv/frv.cc:2844 msgid "bad insn to frv_print_operand, 'g' modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «g»:" #: config/frv/frv.cc:2892 msgid "bad insn to frv_print_operand, 'L' modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «L»:" #: config/frv/frv.cc:2905 msgid "bad insn to frv_print_operand, 'M/N' modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «M/N»:" #: config/frv/frv.cc:2926 msgid "bad insn to frv_print_operand, 'O' modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «O»:" #: config/frv/frv.cc:2944 msgid "bad insn to frv_print_operand, P modifier:" -msgstr "" +msgstr "неправильна інструкція для frv_print_operand, модифікатор «P»:" #: config/frv/frv.cc:2964 msgid "bad insn in frv_print_operand, z case" -msgstr "" +msgstr "неправильна інструкція в frv_print_operand, випадок «z»" #: config/frv/frv.cc:2995 msgid "bad insn in frv_print_operand, 0 case" -msgstr "" +msgstr "неправильна інструкція в frv_print_operand, випадок «0»" #: config/frv/frv.cc:3000 msgid "frv_print_operand: unknown code" -msgstr "" +msgstr "frv_print_operand: невідомий код" #: config/frv/frv.cc:4374 msgid "bad output_move_single operand" -msgstr "" +msgstr "неправильний операнд для output_move_single" #: config/frv/frv.cc:4501 msgid "bad output_move_double operand" -msgstr "помилковий операнд output_move_double" +msgstr "неправильний операнд для output_move_double" #: config/frv/frv.cc:4643 msgid "bad output_condmove_single operand" -msgstr "помилковий операнд output_condmove_single" +msgstr "неправильний операнд для output_condmove_single" #: config/gcn/gcn.cc:6626 config/gcn/gcn.cc:6646 config/gcn/gcn.cc:6650 #: config/gcn/gcn.cc:6982 config/gcn/gcn.cc:6993 config/gcn/gcn.cc:6996 #, c-format msgid "bad ADDR_SPACE_GLOBAL address" -msgstr "помилкова адреса ADDR_SPACE_GLOBAL" +msgstr "неправильна адреса ADDR_SPACE_GLOBAL" #: config/gcn/gcn.cc:6762 config/gcn/gcn.cc:6785 config/gcn/gcn.cc:6817 #: config/gcn/gcn.cc:6833 config/gcn/gcn.cc:6848 config/gcn/gcn.cc:6867 #: config/gcn/gcn.cc:6931 config/gcn/gcn.cc:7127 config/gcn/gcn.cc:7242 #, c-format msgid "invalid operand %%xn code" -msgstr "некоректний код операнда %%xn" +msgstr "недійсний код операнда %%xn" #: config/gcn/gcn.cc:7230 #, c-format msgid "operand %%xn code invalid for QImode" -msgstr "" +msgstr "недійсний код операнда %%xn для QImode" #: config/gcn/gcn.cc:7312 #, c-format msgid "invalid fp constant" -msgstr "некоректна константа з рухомою крапкою" +msgstr "неприпустима константа з плаваючою комою" #: config/h8300/h8300.cc:1628 config/h8300/h8300.cc:1636 #: config/h8300/h8300.cc:1644 config/h8300/h8300.cc:1652 #: config/h8300/h8300.cc:1660 config/h8300/h8300.cc:1668 #, c-format msgid "Expected register or constant integer." -msgstr "Мало бути використано регістр або стале ціле число." +msgstr "Очікувався регістр або константне цілочисельне." #: config/i386/i386.cc:12403 #, c-format msgid "invalid UNSPEC as operand" -msgstr "" +msgstr "неприпустиме UNSPEC як операнд" #: config/i386/i386.cc:12942 #, c-format msgid "invalid use of register '%s'" -msgstr "некоректне використання регістру «%s»" +msgstr "неприпустиме використання регістра '%s'" #: config/i386/i386.cc:12947 #, c-format msgid "invalid use of asm flag output" -msgstr "" +msgstr "неприпустиме використання виводу прапорця asm" #: config/i386/i386.cc:13180 #, c-format msgid "invalid operand size for operand code 'O'" -msgstr "" +msgstr "неприпустимий розмір операнду для коду операнду 'O'" #: config/i386/i386.cc:13215 #, c-format msgid "invalid operand size for operand code 'z'" -msgstr "" +msgstr "неприпустимий розмір операнду для коду операнду 'z'" #: config/i386/i386.cc:13290 -#, fuzzy, c-format -#| msgid "invalid operand type %qT for %qs" +#, c-format msgid "invalid operand type used with operand code '%c'" -msgstr "некоректний тип операнда %qT %qs" +msgstr "неприпустимий тип операнду, використаний з кодом операнду '%c'" #: config/i386/i386.cc:13295 -#, fuzzy, c-format -#| msgid "invalid operand for '%%%c'" +#, c-format msgid "invalid operand size for operand code '%c'" -msgstr "некоректний операнд для «%%%c»" +msgstr "неприпустимий розмір операнду для коду операнду '%c'" #: config/i386/i386.cc:13373 #, c-format msgid "operand is not a condition code, invalid operand code 'Y'" -msgstr "" +msgstr "операнд не є кодом умови, неприпустимий код операнду 'Y'" #: config/i386/i386.cc:13452 #, c-format msgid "operand is not a condition code, invalid operand code 'D'" -msgstr "" +msgstr "операнд не є кодом умови, неприпустимий код операнду 'D'" #: config/i386/i386.cc:13470 #, c-format msgid "operand is not a condition code, invalid operand code '%c'" -msgstr "" +msgstr "операнд не є кодом умови, недійсний код операнду '%c'" #: config/i386/i386.cc:13483 #, c-format msgid "operand is not an offsettable memory reference, invalid operand code 'H'" -msgstr "" +msgstr "операнд не є памʼяті зі зсувом, недійсний код операнду 'H'" #: config/i386/i386.cc:13498 #, c-format msgid "operand is not an integer, invalid operand code 'K'" -msgstr "" +msgstr "операнд не є цілочисельним, недійсний код операнду 'K'" #: config/i386/i386.cc:13526 #, c-format msgid "operand is not a specific integer, invalid operand code 'r'" -msgstr "" +msgstr "операнд не є конкретним цілочисельним, недійсний код операнду 'r'" #: config/i386/i386.cc:13544 #, c-format msgid "operand is not an integer, invalid operand code 'R'" -msgstr "" +msgstr "операнд не є цілочисельним, недійсний код операнду 'R'" #: config/i386/i386.cc:13567 #, c-format msgid "operand is not a specific integer, invalid operand code 'R'" -msgstr "" +msgstr "операнд не є конкретним цілочисельним, недійсний код операнду 'R'" #: config/i386/i386.cc:13671 #, c-format msgid "invalid operand code '%c'" -msgstr "" +msgstr "недійсний код операнду '%c'" #: config/i386/i386.cc:13733 config/i386/i386.cc:14122 #, c-format msgid "invalid constraints for operand" -msgstr "" +msgstr "недійсні обмеження для операнду" #: config/i386/i386.cc:13834 #, c-format msgid "invalid vector immediate" -msgstr "некоректна векторна константа" +msgstr "недійсне векторне негайне значення" #: config/i386/i386.cc:16911 msgid "unknown insn mode" -msgstr "" +msgstr "невідомий режим інструкції" #: config/ia64/ia64.cc:5460 #, c-format msgid "invalid %%G mode" -msgstr "" +msgstr "недійсний режим %%G" #: config/ia64/ia64.cc:5631 #, c-format msgid "ia64_print_operand: unknown code" -msgstr "" +msgstr "ia64_print_operand: невідомий код" #: config/ia64/ia64.cc:11255 msgid "invalid conversion from %<__fpreg%>" -msgstr "" +msgstr "недійсне перетворення з %<__fpreg%>" #: config/ia64/ia64.cc:11258 msgid "invalid conversion to %<__fpreg%>" -msgstr "некоректне перетворення до %<__fpreg%>" +msgstr "недійсне перетворення до %<__fpreg%>" #: config/ia64/ia64.cc:11271 config/ia64/ia64.cc:11282 msgid "invalid operation on %<__fpreg%>" -msgstr "" +msgstr "недійсна операція на %<__fpreg%>" #: config/iq2000/iq2000.cc:3126 #, c-format msgid "invalid %%P operand" -msgstr "" +msgstr "недійсний операнд %%P" #: config/iq2000/iq2000.cc:3134 config/rs6000/rs6000.cc:13997 #, c-format msgid "invalid %%p value" -msgstr "некоректне значення %%p" +msgstr "недійсне значення %%p" #: config/iq2000/iq2000.cc:3193 #, c-format msgid "invalid use of %%d, %%x, or %%X" -msgstr "" +msgstr "неприпустиме використання %%d, %%x або %%X" #: config/lm32/lm32.cc:524 #, c-format msgid "only 0.0 can be loaded as an immediate" -msgstr "" +msgstr "тільки 0.0 може бути завантажено як негайне значення" #: config/lm32/lm32.cc:594 msgid "bad operand" -msgstr "помилковий операнд" +msgstr "неправильний операнд" #: config/lm32/lm32.cc:606 msgid "can't use non gp relative absolute address" -msgstr "" +msgstr "не можна використовувати неглобальну відносну абсолютну адресу" #: config/lm32/lm32.cc:610 msgid "invalid addressing mode" -msgstr "некоректний режим адресування" +msgstr "неприпустимий режим адресації" #: config/loongarch/loongarch.cc:4754 config/loongarch/loongarch.cc:4776 #: config/loongarch/loongarch.cc:5120 config/mips/mips.cc:9066 #: config/mips/mips.cc:9093 config/mips/mips.cc:9276 #, c-format msgid "'%%%c' is not a valid operand prefix" -msgstr "" +msgstr "«%%%c» не є дійсним префіксом операнда" #: config/loongarch/loongarch.cc:5004 config/loongarch/loongarch.cc:5042 #: config/loongarch/loongarch.cc:5077 config/loongarch/loongarch.cc:5080 @@ -19588,47 +19559,47 @@ msgstr "" #: config/riscv/riscv.cc:4547 config/riscv/riscv.cc:4556 #, c-format msgid "invalid use of '%%%c'" -msgstr "" +msgstr "неприпустиме використання '%%%c'" #: config/m32r/m32r.cc:2148 msgid "bad insn for 'A'" -msgstr "" +msgstr "неправильна інструкція для 'A'" #: config/m32r/m32r.cc:2195 #, c-format msgid "invalid operand to %%T/%%B code" -msgstr "" +msgstr "недійсний операнд для коду %%T/%%B" #: config/m32r/m32r.cc:2218 #, c-format msgid "invalid operand to %%N code" -msgstr "" +msgstr "неправильний операнд для коду %%N" #: config/m32r/m32r.cc:2251 msgid "pre-increment address is not a register" -msgstr "" +msgstr "адреса з попереднім інкрементом не є регістром" #: config/m32r/m32r.cc:2258 msgid "pre-decrement address is not a register" -msgstr "" +msgstr "адреса з попереднім декрементом не є регістром" #: config/m32r/m32r.cc:2265 msgid "post-increment address is not a register" -msgstr "" +msgstr "адреса з постінкрементом не є регістром" #: config/m32r/m32r.cc:2340 config/m32r/m32r.cc:2355 #: config/rs6000/rs6000.cc:20711 msgid "bad address" -msgstr "помилкова адреса" +msgstr "неправильна адреса" #: config/m32r/m32r.cc:2360 msgid "lo_sum not of register" -msgstr "" +msgstr "lo_sum не є регістром" #: config/microblaze/microblaze.cc:2299 #, c-format msgid "unknown punctuation '%c'" -msgstr "" +msgstr "невідомий знак пунктуації '%c'" #: config/microblaze/microblaze.cc:2308 #, c-format @@ -19638,507 +19609,506 @@ msgstr "нульовий вказівник" #: config/microblaze/microblaze.cc:2343 #, c-format msgid "PRINT_OPERAND, invalid insn for %%C" -msgstr "" +msgstr "PRINT_OPERAND, неправильна інструкція для %%C" #: config/microblaze/microblaze.cc:2372 #, c-format msgid "PRINT_OPERAND, invalid insn for %%N" -msgstr "" +msgstr "PRINT_OPERAND, неправильна інструкція для %%N" #: config/microblaze/microblaze.cc:2392 config/microblaze/microblaze.cc:2568 msgid "insn contains an invalid address !" -msgstr "" +msgstr "інструкція містить неправильну адресу!" #: config/microblaze/microblaze.cc:2408 config/microblaze/microblaze.cc:2638 #: config/xtensa/xtensa.cc:3105 msgid "invalid address" -msgstr "некоректна адреса" +msgstr "неправильна адреса" #: config/microblaze/microblaze.cc:2511 #, c-format msgid "letter %c was found & insn was not CONST_INT" -msgstr "" +msgstr "було знайдено літеру %c, а інструкція не була CONST_INT" #: config/mmix/mmix.cc:1636 config/mmix/mmix.cc:1757 msgid "MMIX Internal: Expected a CONST_INT, not this" -msgstr "" +msgstr "MMIX Internal: Очікувався CONST_INT, а не це" #: config/mmix/mmix.cc:1715 msgid "MMIX Internal: Bad value for 'm', not a CONST_INT" -msgstr "" +msgstr "MMIX Internal: Погане значення для 'm', не CONST_INT" #: config/mmix/mmix.cc:1725 msgid "MMIX Internal: Expected a register, not this" -msgstr "" +msgstr "MMIX Internal: Очікувався регістр, а не це" #: config/mmix/mmix.cc:1735 msgid "MMIX Internal: Expected a constant, not this" -msgstr "" +msgstr "MMIX Internal: Очікувалась константа, а не це" #. We need the original here. #: config/mmix/mmix.cc:1819 msgid "MMIX Internal: Cannot decode this operand" -msgstr "" +msgstr "MMIX Internal: Неможливо декодувати цей операнд" #: config/mmix/mmix.cc:1878 msgid "MMIX Internal: This is not a recognized address" -msgstr "" +msgstr "MMIX Internal: Це не визнана адреса" #: config/mmix/mmix.cc:2770 msgid "MMIX Internal: Trying to output invalidly reversed condition:" -msgstr "" +msgstr "MMIX Internal: Спроба вивести неправильно зворотню умову:" #: config/mmix/mmix.cc:2777 msgid "MMIX Internal: What's the CC of this?" -msgstr "" +msgstr "MMIX Internal: Який CC цього?" #: config/mmix/mmix.cc:2781 msgid "MMIX Internal: What is the CC of this?" -msgstr "" +msgstr "MMIX Internal: Який CC цього?" #: config/mmix/mmix.cc:2823 msgid "MMIX Internal: This is not a constant:" -msgstr "" +msgstr "MMIX Internal: Це не константа:" #: config/msp430/msp430.cc:4229 #, c-format msgid "%%d, %%e, %%f, %%g operand modifiers are for memory references or constant values only" -msgstr "" +msgstr "Модифікатори операндів %%d, %%e, %%f, %%g призначені тільки для посилань на памʼять або константних значень" #: config/msp430/msp430.cc:4342 #, c-format msgid "invalid operand prefix" -msgstr "" +msgstr "недійсний префікс операнду" #: config/msp430/msp430.cc:4376 #, c-format msgid "invalid zero extract" -msgstr "" +msgstr "недійсне виділення нуля" #: config/or1k/or1k.cc:1154 config/or1k/or1k.cc:1162 #, c-format msgid "invalid relocation" -msgstr "некоректне пересування" +msgstr "недійсна перевстановлення" #: config/or1k/or1k.cc:1256 #, c-format msgid "invalid %%H value" -msgstr "некоректне значення %%H" +msgstr "недійсне значення %%H" #: config/or1k/or1k.cc:1269 config/xtensa/xtensa.cc:3022 #, c-format msgid "invalid %%d value" -msgstr "некоректне значення %%d" +msgstr "недійсне значення %%d" #: config/or1k/or1k.cc:1317 #, c-format msgid "unknown operand letter: '%c'" -msgstr "невідома літера операнда: «%c»" +msgstr "невідома літера операнду: '%c'" #: config/pru/pru.cc:1711 config/pru/pru.cc:1722 #, c-format msgid "I/O register operand for '%%%c'" -msgstr "" +msgstr "Операнд реєстру введення/виведення для '%%%c'" #: config/pru/pru.cc:1728 #, c-format msgid "non 32 bit register operand for '%%%c'" -msgstr "" +msgstr "операнд регістру не на 32 біти для '%%%c'" #: config/pru/pru.cc:1813 #, c-format msgid "unsupported code '%c' for fixed-point:" -msgstr "" +msgstr "непідтримуваний код '%c' для фіксованої точки:" #: config/pru/pru.cc:1827 #, c-format msgid "double constants not supported" -msgstr "підтримки сталих подвійної точності не передбачено" +msgstr "подвійні константи не підтримуються" #: config/pru/pru.cc:1910 #, c-format msgid "unsupported operand %s for code '%c'" -msgstr "" +msgstr "непідтримуваний операнд %s для коду '%c'" #: config/pru/pru.cc:1920 #, c-format msgid "unexpected text address:" -msgstr "неочікувана текстова адреса:" +msgstr "неочікувана адреса тексту:" #: config/pru/pru.cc:1939 #, c-format msgid "unsupported constant address:" -msgstr "" +msgstr "непідтримувана адреса константи:" #: config/pru/pru.cc:2000 #, c-format msgid "unsupported memory expression:" -msgstr "непідтримуваний вираз пам'яті:" +msgstr "непідтримуваний вираз памʼяті:" #: config/riscv/riscv.cc:4384 -#, fuzzy, c-format -#| msgid "invalid %%r operand" +#, c-format msgid "invalid vector operand" -msgstr "некоректний операнд %%r" +msgstr "недійсний операнд вектора" #: config/rl78/rl78.cc:1998 config/rl78/rl78.cc:2084 #, c-format msgid "q/Q modifiers invalid for symbol references" -msgstr "" +msgstr "модифікатори q/Q недійсні для посилань на символи" #: config/rs6000/host-darwin.cc:96 #, c-format msgid "Out of stack space.\n" -msgstr "" +msgstr "Недостатньо місця в стеку.\n" #: config/rs6000/host-darwin.cc:117 #, c-format msgid "Try running '%s' in the shell to raise its limit.\n" -msgstr "" +msgstr "Спробуйте запустити '%s' в оболонці, щоб збільшити його обмеження.\n" #: config/rs6000/rs6000.cc:3807 msgid "%<-mvsx%> requires hardware floating point" -msgstr "" +msgstr "%<-mvsx%> потребує апаратного з плаваючою комою" #: config/rs6000/rs6000.cc:3815 msgid "%<-mvsx%> needs indexed addressing" -msgstr "%<-mvsx%> потребує індексованого адресування." +msgstr "%<-mvsx%> потребує індексованої адресації" #: config/rs6000/rs6000.cc:3820 msgid "%<-mvsx%> and %<-mno-altivec%> are incompatible" -msgstr "" +msgstr "%<-mvsx%> та %<-mno-altivec%> несумісні" #: config/rs6000/rs6000.cc:3822 msgid "%<-mno-altivec%> disables vsx" -msgstr "" +msgstr "%<-mno-altivec%> вимикає vsx" #: config/rs6000/rs6000.cc:3971 msgid "%<-mquad-memory%> requires 64-bit mode" -msgstr "" +msgstr "%<-mquad-memory%> потребує 64-бітний режим" #: config/rs6000/rs6000.cc:3974 msgid "%<-mquad-memory-atomic%> requires 64-bit mode" -msgstr "" +msgstr "%<-mquad-memory-atomic%> потребує 64-бітний режим" #: config/rs6000/rs6000.cc:3986 msgid "%<-mquad-memory%> is not available in little endian mode" -msgstr "" +msgstr "%<-mquad-memory%> недоступний в режимі little endian" #: config/rs6000/rs6000.cc:11087 msgid "bad move" -msgstr "" +msgstr "неправильний хід" #: config/rs6000/rs6000.cc:13627 msgid "Bad 128-bit move" -msgstr "Помилкове 128-бітове пересування" +msgstr "Неправильний 128-бітний хід" #: config/rs6000/rs6000.cc:13807 #, c-format msgid "invalid %%A value" -msgstr "некоректне значення %%A" +msgstr "неправильне значення %%A" #: config/rs6000/rs6000.cc:13816 config/xtensa/xtensa.cc:2957 #, c-format msgid "invalid %%D value" -msgstr "некоректне значення %%D" +msgstr "неправильне значення %%D" #: config/rs6000/rs6000.cc:13831 #, c-format msgid "invalid %%e value" -msgstr "некоректне значення %%e" +msgstr "неправильне значення %%e" #: config/rs6000/rs6000.cc:13852 #, c-format msgid "invalid %%f value" -msgstr "некоректне значення %%f" +msgstr "неправильне значення %%f" #: config/rs6000/rs6000.cc:13861 #, c-format msgid "invalid %%F value" -msgstr "некоректне значення %%F" +msgstr "неправильне значення %%F" #: config/rs6000/rs6000.cc:13870 #, c-format msgid "invalid %%G value" -msgstr "некоректне значення %%G" +msgstr "неправильне значення %%G" #: config/rs6000/rs6000.cc:13905 #, c-format msgid "invalid %%j code" -msgstr "" +msgstr "неправильний код %%j" #: config/rs6000/rs6000.cc:13915 #, c-format msgid "invalid %%J code" -msgstr "" +msgstr "неправильний код %%J" #: config/rs6000/rs6000.cc:13925 #, c-format msgid "invalid %%k value" -msgstr "" +msgstr "неправильне значення %%k" #: config/rs6000/rs6000.cc:13940 config/xtensa/xtensa.cc:2994 #, c-format msgid "invalid %%K value" -msgstr "" +msgstr "неправильне значення %%K" #: config/rs6000/rs6000.cc:13987 #, c-format msgid "invalid %%O value" -msgstr "" +msgstr "недійсне значення %%O" #: config/rs6000/rs6000.cc:14034 #, c-format msgid "invalid %%q value" -msgstr "" +msgstr "недійсне значення %%q" #: config/rs6000/rs6000.cc:14076 #, c-format msgid "invalid %%t value" -msgstr "некоректне значення %%t" +msgstr "недійсне значення %%t" #: config/rs6000/rs6000.cc:14093 #, c-format msgid "invalid %%T value" -msgstr "некоректне значення %%T" +msgstr "недійсне значення %%T" #: config/rs6000/rs6000.cc:14105 #, c-format msgid "invalid %%u value" -msgstr "некоректне значення %%u" +msgstr "недійсне значення %%u" #: config/rs6000/rs6000.cc:14119 config/xtensa/xtensa.cc:2969 #, c-format msgid "invalid %%v value" -msgstr "некоректне значення %%v" +msgstr "недійсне значення %%v" #: config/rs6000/rs6000.cc:14169 #, c-format msgid "invalid %%V value" -msgstr "некоректне значення %%V" +msgstr "недійсне значення %%V" #: config/rs6000/rs6000.cc:14185 config/xtensa/xtensa.cc:3015 #, c-format msgid "invalid %%x value" -msgstr "" +msgstr "недійсне значення %%x" #: config/rs6000/rs6000.cc:14242 #, c-format msgid "invalid %%z value" -msgstr "некоректне значення %%z" +msgstr "недійсне значення %%z" #: config/rs6000/rs6000.cc:14311 #, c-format msgid "invalid %%y value, try using the 'Z' constraint" -msgstr "" +msgstr "недійсне значення %%y, спробуйте використати обмеження 'Z'" #: config/rs6000/rs6000.cc:15241 msgid "Invalid mixing of IEEE 128-bit and IBM 128-bit floating point types" -msgstr "" +msgstr "Неприпустиме змішування типів з плаваючою комою IEEE 128 біт та IBM 128 біт" #: config/rs6000/rs6000.cc:24108 msgid "AltiVec argument passed to unprototyped function" -msgstr "" +msgstr "Аргумент AltiVec, переданий у функцію без прототипу" #: config/rs6000/rs6000.cc:27730 msgid "Could not generate addis value for fusion" -msgstr "" +msgstr "Не вдалося згенерувати значення addis для злиття" #: config/rs6000/rs6000.cc:27799 msgid "Unable to generate load/store offset for fusion" -msgstr "" +msgstr "Не вдалося згенерувати зсув завантаження/збереження для злиття" #: config/rs6000/rs6000.cc:27875 msgid "Bad GPR fusion" -msgstr "" +msgstr "Погане злиття GPR" #: config/rs6000/rs6000.cc:28477 msgid "invalid conversion from type %<__vector_quad%>" -msgstr "некоректне перетворення з типу %<__vector_quad%>" +msgstr "недійсне перетворення з типу %<__vector_quad%>" #: config/rs6000/rs6000.cc:28479 msgid "invalid conversion to type %<__vector_quad%>" -msgstr "некоректне перетворення до типу %<__vector_quad%>" +msgstr "недійсне перетворення на тип %<__vector_quad%>" #: config/rs6000/rs6000.cc:28481 msgid "invalid conversion from type %<__vector_pair%>" -msgstr "некоректне перетворення з типу %<__vector_pair%>" +msgstr "недійсне перетворення з типу %<__vector_pair%>" #: config/rs6000/rs6000.cc:28483 msgid "invalid conversion to type %<__vector_pair%>" -msgstr "некоректне перетворення до %<__vector_pair%>" +msgstr "недійсне перетворення на тип %<__vector_pair%>" #: config/s390/s390.cc:8072 #, c-format msgid "symbolic memory references are only supported on z10 or later" -msgstr "" +msgstr "символічні посилання на памʼять підтримуються лише на z10 або пізніше" #: config/s390/s390.cc:8083 #, c-format msgid "cannot decompose address" -msgstr "" +msgstr "не вдається розкласти адресу" #: config/s390/s390.cc:8165 #, c-format msgid "invalid comparison operator for 'E' output modifier" -msgstr "" +msgstr "недійсний оператор порівняння для модифікатора виводу «E»" #: config/s390/s390.cc:8188 #, c-format msgid "invalid reference for 'J' output modifier" -msgstr "" +msgstr "недійсне посилання для модифікатора виводу «J»" #: config/s390/s390.cc:8206 #, c-format msgid "invalid address for 'O' output modifier" -msgstr "" +msgstr "неправильна адреса для модифікатора виводу 'O'" #: config/s390/s390.cc:8228 #, c-format msgid "invalid address for 'R' output modifier" -msgstr "" +msgstr "неправильна адреса для модифікатора виводу 'R'" #: config/s390/s390.cc:8246 #, c-format msgid "memory reference expected for 'S' output modifier" -msgstr "" +msgstr "очікується посилання на памʼять для модифікатора виводу 'S'" #: config/s390/s390.cc:8256 #, c-format msgid "invalid address for 'S' output modifier" -msgstr "" +msgstr "неправильна адреса для модифікатора виводу 'S'" #: config/s390/s390.cc:8277 #, c-format msgid "register or memory expression expected for 'N' output modifier" -msgstr "" +msgstr "очікується регістр або вираз памʼяті для модифікатора виводу 'N'" #: config/s390/s390.cc:8288 #, c-format msgid "register or memory expression expected for 'M' output modifier" -msgstr "" +msgstr "очікується регістр або вираз памʼяті для модифікатора виводу 'M'" #: config/s390/s390.cc:8397 config/s390/s390.cc:8418 #, c-format msgid "invalid constant for output modifier '%c'" -msgstr "" +msgstr "неправильна константа для модифікатора виводу '%c'" #: config/s390/s390.cc:8415 #, c-format msgid "invalid constant - try using an output modifier" -msgstr "" +msgstr "неправильна константа - спробуйте використати модифікатор виводу" #: config/s390/s390.cc:8452 #, c-format msgid "invalid constant vector for output modifier '%c'" -msgstr "" +msgstr "неправильний вектор констант для модифікатора виводу '%c'" #: config/s390/s390.cc:8459 #, c-format msgid "invalid expression - try using an output modifier" -msgstr "" +msgstr "неприпустимий вираз - спробуйте використати модифікатор виводу" #: config/s390/s390.cc:8462 #, c-format msgid "invalid expression for output modifier '%c'" -msgstr "некоректний вираз для модифікатора виведення «%c»" +msgstr "неприпустимий вираз для модифікатора виводу '%c'" #: config/s390/s390.cc:12310 msgid "vector argument passed to unprototyped function" -msgstr "" +msgstr "векторний аргумент переданий до функції без прототипу" #: config/s390/s390.cc:16742 msgid "types differ in signedness" -msgstr "" +msgstr "типи відрізняються за знаком" #: config/s390/s390.cc:16752 msgid "binary operator does not support two vector bool operands" -msgstr "" +msgstr "бінарний оператор не підтримує два векторних операнди типу bool" #: config/s390/s390.cc:16755 msgid "binary operator does not support vector bool operand" -msgstr "" +msgstr "бінарний оператор не підтримує векторний операнд типу bool" #: config/s390/s390.cc:16763 msgid "binary operator does not support mixing vector bool with floating point vector operands" -msgstr "" +msgstr "бінарний оператор не підтримує змішування векторного операнду типу bool з векторним операндом типу з плаваючою точкою" #: config/sh/sh.cc:1222 #, c-format msgid "invalid operand to %%R" -msgstr "некоректний операнд %%R" +msgstr "неприпустимий операнд для %%R" #: config/sh/sh.cc:1249 #, c-format msgid "invalid operand to %%S" -msgstr "некоректний операнд %%S" +msgstr "неприпустимий операнд для %%S" #: config/sh/sh.cc:8667 msgid "created and used with different architectures / ABIs" -msgstr "" +msgstr "створено та використано з різними архітектурами / ABIs" #: config/sh/sh.cc:8669 msgid "created and used with different ABIs" -msgstr "" +msgstr "створено та використано з різними ABIs" #: config/sh/sh.cc:8671 msgid "created and used with different endianness" -msgstr "" +msgstr "створено та використано з різним порядком байтів" #: config/sparc/sparc.cc:9379 config/sparc/sparc.cc:9385 #, c-format msgid "invalid %%Y operand" -msgstr "некоректний операнд %%Y" +msgstr "недійсний операнд %%Y" #: config/sparc/sparc.cc:9472 #, c-format msgid "invalid %%A operand" -msgstr "некоректний операнд %%A" +msgstr "недійсний операнд %%A" #: config/sparc/sparc.cc:9492 #, c-format msgid "invalid %%B operand" -msgstr "некоректний операнд %%B" +msgstr "недійсний операнд %%B" #: config/sparc/sparc.cc:9572 #, c-format msgid "invalid %%C operand" -msgstr "некоректний операнд %%C" +msgstr "недійсний операнд %%C" #: config/sparc/sparc.cc:9604 #, c-format msgid "invalid %%D operand" -msgstr "некоректний операнд %%D" +msgstr "недійсний операнд %%D" #: config/sparc/sparc.cc:9623 #, c-format msgid "invalid %%f operand" -msgstr "некоректний операнд %%f" +msgstr "недійсний операнд %%f" #: config/sparc/sparc.cc:9635 #, c-format msgid "invalid %%s operand" -msgstr "некоректний операнд %%s" +msgstr "недійсний операнд %%s" #: config/sparc/sparc.cc:9680 #, c-format msgid "floating-point constant not a valid immediate operand" -msgstr "" +msgstr "константа з плаваючою точкою не є дійсним негайним операндом" #: config/stormy16/stormy16.cc:1751 config/stormy16/stormy16.cc:1822 #, c-format msgid "'B' operand is not constant" -msgstr "операнд «B» не є сталою" +msgstr "операнд 'B' не є константою" #: config/stormy16/stormy16.cc:1778 #, c-format msgid "'B' operand has multiple bits set" -msgstr "" +msgstr "операнд 'B' має встановлено кілька бітів" #: config/stormy16/stormy16.cc:1804 #, c-format msgid "'o' operand is not constant" -msgstr "операнд «o» не є сталою" +msgstr "операнд 'o' не є константою" #: config/stormy16/stormy16.cc:1836 #, c-format @@ -20147,26 +20117,26 @@ msgstr "xstormy16_print_operand: невідомий код" #: config/v850/v850.cc:271 msgid "const_double_split got a bad insn:" -msgstr "" +msgstr "const_double_split отримав неправильну інструкцію:" #: config/v850/v850.cc:885 msgid "output_move_single:" -msgstr "" +msgstr "output_move_single:" #: config/vax/vax.cc:481 #, c-format msgid "symbol used with both base and indexed registers" -msgstr "" +msgstr "символ використовується з базовими та індексованими регістрами" #: config/vax/vax.cc:490 #, c-format msgid "symbol with offset used in PIC mode" -msgstr "" +msgstr "символ з зсувом використовується в режимі PIC" #: config/vax/vax.cc:578 #, c-format msgid "symbol used as immediate operand" -msgstr "" +msgstr "символ використовується як негайний операнд" #: config/vax/vax.cc:1680 msgid "illegal operand detected" @@ -20178,44 +20148,44 @@ msgstr "неприпустимий операнд " #: config/visium/visium.cc:3416 msgid "illegal operand address (1)" -msgstr "некоректна адреса операнда (1)" +msgstr "неприпустима адреса операнда (1)" #: config/visium/visium.cc:3423 msgid "illegal operand address (2)" -msgstr "некоректна адреса операнда (2)" +msgstr "неприпустима адреса операнда (2)" #: config/visium/visium.cc:3438 msgid "illegal operand address (3)" -msgstr "некоректна адреса операнда (3)" +msgstr "неприпустима адреса операнда (3)" #: config/visium/visium.cc:3446 msgid "illegal operand address (4)" -msgstr "некоректна адреса операнда (4)" +msgstr "неприпустима адреса операнда (4)" #: config/xtensa/xtensa-dynconfig.cc:63 msgid "Unable to load DLL." -msgstr "" +msgstr "Не вдалося завантажити DLL." #: config/xtensa/xtensa.cc:831 config/xtensa/xtensa.cc:869 msgid "bad test" -msgstr "помилкова перевірка" +msgstr "неправильний тест" #: config/xtensa/xtensa.cc:2989 msgid "invalid mask" -msgstr "некоректна маска" +msgstr "неприпустима маска" #: config/xtensa/xtensa.cc:3041 config/xtensa/xtensa.cc:3051 #, c-format msgid "invalid %%t/%%b value" -msgstr "некоректне значення %%t/%%b" +msgstr "недійсне значення %%t/%%b" #: config/xtensa/xtensa.cc:3130 msgid "no register in address" -msgstr "немає регістру у адресі" +msgstr "немає реєстра в адресі" #: config/xtensa/xtensa.cc:3138 msgid "address offset not a constant" -msgstr "зсув адреси не є сталою величиною" +msgstr "зсув адреси не є константою" #: c/c-objc-common.cc:193 msgid "{erroneous}" @@ -20223,7 +20193,7 @@ msgstr "{помилковий}" #: c/c-objc-common.cc:234 msgid "aka" -msgstr "або" +msgstr "також відомий як" #: c/c-objc-common.cc:326 msgid "({anonymous})" @@ -20253,7 +20223,7 @@ msgstr "({анонімний})" #: cp/parser.cc:15350 cp/parser.cc:33085 cp/parser.cc:33721 #, gcc-internal-format msgid "expected %<;%>" -msgstr "мало бути %<;%>" +msgstr "очікувався %<;%>" #: c/c-parser.cc:3355 c/c-parser.cc:4460 c/c-parser.cc:4655 c/c-parser.cc:4713 #: c/c-parser.cc:4771 c/c-parser.cc:5153 c/c-parser.cc:5176 c/c-parser.cc:5185 @@ -20274,7 +20244,7 @@ msgstr "мало бути %<;%>" #: c/c-parser.cc:7642 cp/parser.cc:33769 #, gcc-internal-format msgid "expected %<)%>" -msgstr "мало бути %<)%>" +msgstr "очікувався %<)%>" #: c/c-parser.cc:4549 c/c-parser.cc:5296 c/c-parser.cc:5448 c/c-parser.cc:5474 #: c/c-parser.cc:5475 c/c-parser.cc:5915 c/c-parser.cc:5959 c/c-parser.cc:7741 @@ -20282,11 +20252,11 @@ msgstr "мало бути %<)%>" #: c/c-parser.cc:13949 c/gimple-parser.cc:1755 cp/parser.cc:33733 #, gcc-internal-format msgid "expected %<]%>" -msgstr "мало бути %<]%>" +msgstr "очікувався %<]%>" #: c/c-parser.cc:4751 msgid "expected %<;%>, %<,%> or %<)%>" -msgstr "мало бути %<;%>, %<,%> або %<)%>" +msgstr "очікувався %<;%>, %<,%> або %<)%>" #. Look for the two `(' tokens. #: c/c-parser.cc:5205 c/c-parser.cc:5210 c/c-parser.cc:14529 @@ -20300,13 +20270,13 @@ msgstr "мало бути %<;%>, %<,%> або %<)%>" #: c/gimple-parser.cc:2331 c/c-parser.cc:14351 cp/parser.cc:33724 #, gcc-internal-format msgid "expected %<(%>" -msgstr "мало бути %<(%>" +msgstr "очікувався %<(%>" #: c/c-parser.cc:5444 c/c-parser.cc:5446 c/c-parser.cc:13853 #: cp/parser.cc:33736 cp/parser.cc:37504 go/gofrontend/embed.cc:439 #, gcc-internal-format msgid "expected %<[%>" -msgstr "мало бути %<[%>" +msgstr "очікувався %<[%>" #: c/c-parser.cc:6096 c/c-parser.cc:12391 c/c-parser.cc:19374 #: c/c-parser.cc:19460 c/c-parser.cc:20118 c/c-parser.cc:20990 @@ -20315,7 +20285,7 @@ msgstr "мало бути %<[%>" #: cp/parser.cc:21039 cp/parser.cc:33730 go/gofrontend/embed.cc:370 #, gcc-internal-format msgid "expected %<{%>" -msgstr "мало бути %<{%>" +msgstr "очікувався %<{%>" #: c/c-parser.cc:6391 c/c-parser.cc:6400 c/c-parser.cc:8188 c/c-parser.cc:9328 #: c/c-parser.cc:12155 c/c-parser.cc:12552 c/c-parser.cc:12616 @@ -20330,12 +20300,12 @@ msgstr "мало бути %<{%>" #: go/gofrontend/embed.cc:403 #, gcc-internal-format msgid "expected %<:%>" -msgstr "мало бути %<:%>" +msgstr "очікувався %<:%>" #: c/c-parser.cc:7199 cp/parser.cc:33650 #, gcc-internal-format msgid "expected %" -msgstr "мало бути %" +msgstr "очікувався %" #: c/c-parser.cc:9086 c/c-parser.cc:9279 c/c-parser.cc:9750 c/c-parser.cc:9793 #: c/c-parser.cc:9934 c/c-parser.cc:10681 c/c-parser.cc:15354 @@ -20344,27 +20314,27 @@ msgstr "мало бути %" #: c/gimple-parser.cc:1540 cp/parser.cc:33083 cp/parser.cc:33739 #, gcc-internal-format msgid "expected %<,%>" -msgstr "мало бути %<,%>" +msgstr "очікувався %<,%>" #: c/c-parser.cc:9647 msgid "expected %<.%>" -msgstr "мало бути %<.%>" +msgstr "очікувався %<.%>" #: c/c-parser.cc:11614 c/c-parser.cc:11646 c/c-parser.cc:11886 #: cp/parser.cc:36039 cp/parser.cc:36060 #, gcc-internal-format msgid "expected %<@end%>" -msgstr "мало бути %<@end%>" +msgstr "очікувався %<@end%>" #: c/c-parser.cc:12304 c/gimple-parser.cc:1370 cp/parser.cc:33748 #, gcc-internal-format msgid "expected %<>%>" -msgstr "мало бути %<>%>" +msgstr "очікувався %<>%>" #: c/c-parser.cc:15890 c/c-parser.cc:17306 cp/parser.cc:33772 #, gcc-internal-format msgid "expected %<,%> or %<)%>" -msgstr "мало бути %<,%> або %<)%>" +msgstr "очікувався %<,%> або %<)%>" #. All following cases are statements with LHS. #: c/c-parser.cc:16758 c/c-parser.cc:19267 c/c-parser.cc:19314 @@ -20374,7 +20344,7 @@ msgstr "мало бути %<,%> або %<)%>" #: cp/parser.cc:33751 cp/parser.cc:42079 cp/parser.cc:42252 #, gcc-internal-format msgid "expected %<=%>" -msgstr "мало бути %<=%>" +msgstr "очікувалось %<=%>" #: c/c-parser.cc:19402 c/c-parser.cc:19482 c/c-parser.cc:19835 #: c/c-parser.cc:20169 c/gimple-parser.cc:1588 c/gimple-parser.cc:1620 @@ -20382,21 +20352,21 @@ msgstr "мало бути %<=%>" #: cp/parser.cc:36249 #, gcc-internal-format msgid "expected %<}%>" -msgstr "мало бути %<}%>" +msgstr "очікувалось %<}%>" #: c/c-parser.cc:19495 cp/parser.cc:42177 #, gcc-internal-format msgid "expected %" -msgstr "мало бути %" +msgstr "очікувалось %" #: c/c-parser.cc:21035 c/c-parser.cc:21024 cp/parser.cc:44437 #, gcc-internal-format msgid "expected %<#pragma omp section%> or %<}%>" -msgstr "мало бути %<#pragma omp section%> або %<}%>" +msgstr "очікувалось %<#pragma omp section%> або %<}%>" #: c/c-parser.cc:24023 cp/parser.cc:48282 msgid "" -msgstr "" +msgstr "<повідомлення невідоме на етапі компіляції>" #: c/c-typeck.cc:8855 msgid "(anonymous)" @@ -20405,13 +20375,13 @@ msgstr "(анонімний)" #: c/gimple-parser.cc:1359 cp/parser.cc:18387 cp/parser.cc:33745 #, gcc-internal-format msgid "expected %<<%>" -msgstr "мало бути %<<%>" +msgstr "очікувалось %<<%>" #: c/gimple-parser.cc:2381 c/gimple-parser.cc:2408 c/gimple-parser.cc:2247 #: c/gimple-parser.cc:2284 #, gcc-internal-format msgid "expected label" -msgstr "мало бути вказано мітку" +msgstr "очікувалася мітка" #: cp/call.cc:4059 msgid "candidate:" @@ -20419,14 +20389,14 @@ msgstr "кандидат:" #: cp/call.cc:8193 msgid " after user-defined conversion:" -msgstr "" +msgstr " після користувацького перетворення:" #: cp/call.cc:8357 cp/pt.cc:2022 cp/pt.cc:26138 msgid "candidate is:" msgid_plural "candidates are:" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "кандидат є:" +msgstr[1] "кандидати є:" +msgstr[2] "кандидати є:" #: cp/call.cc:12792 cp/call.cc:13184 msgid "candidate 1:" @@ -20438,23 +20408,23 @@ msgstr "кандидат 2:" #: cp/decl.cc:3588 msgid "jump to label %qD" -msgstr "" +msgstr "перехід до мітки %qD" #: cp/decl.cc:3589 msgid "jump to case label" -msgstr "" +msgstr "перехід до мітки case" #: cp/error.cc:462 msgid "" -msgstr "<пропущено>" +msgstr "<відсутнє>" #: cp/error.cc:564 msgid "" -msgstr "" +msgstr "<список ініціалізаторів у фігурних дужках>" #: cp/error.cc:566 msgid "" -msgstr "<невизначений перевантажений тип функції>" +msgstr "<нерозрішений перевантажений тип функції>" #: cp/error.cc:733 msgid "" @@ -20463,44 +20433,44 @@ msgstr "<помилка типу>" #. A lambda's "type" is essentially its signature. #: cp/error.cc:840 msgid "" -msgstr "<неназваний>" +msgstr "<безіменний>" #: cp/error.cc:852 #, c-format msgid "" -msgstr "<неназваний %s>" +msgstr "<безіменний %s>" #: cp/error.cc:990 msgid "" -msgstr "" +msgstr "<помилка префіксу типу>" #: cp/error.cc:1131 #, c-format msgid "(static initializers for %s)" -msgstr "" +msgstr "(статичні ініціалізатори для %s)" #: cp/error.cc:1133 #, c-format msgid "(static destructors for %s)" -msgstr "" +msgstr "(статичні деструктори для %s)" #: cp/error.cc:1179 msgid "" -msgstr "<структуровані прив'язки>" +msgstr "<структуровані привʼязки>" #: cp/error.cc:1303 msgid "vtable for " -msgstr "" +msgstr "vtable для " #: cp/error.cc:1327 msgid " " -msgstr "" +msgstr "<значення повернення> " #: cp/error.cc:1342 msgid "{anonymous}" @@ -20508,50 +20478,50 @@ msgstr "{анонімний}" #: cp/error.cc:1344 msgid "(anonymous namespace)" -msgstr "" +msgstr "(анонімний простір імен)" #: cp/error.cc:1444 msgid "