diff options
author | Thomas Schwinge <tschwinge@baylibre.com> | 2024-03-11 00:59:26 +0100 |
---|---|---|
committer | Thomas Schwinge <tschwinge@baylibre.com> | 2024-03-11 00:59:26 +0100 |
commit | ec26db53513f9de267b85c1c8f8db838dcd09d36 (patch) | |
tree | f3df366d23091e1a526a2569f7d6e6c1f8ae4fe1 /gcc | |
parent | 333fe5b0f141b3cf2fa1890e72fbc0d2551742cc (diff) | |
parent | 9b5b2c9f95056f97cf95f0e8d970015aa586497b (diff) | |
download | gcc-ec26db53513f9de267b85c1c8f8db838dcd09d36.zip gcc-ec26db53513f9de267b85c1c8f8db838dcd09d36.tar.gz gcc-ec26db53513f9de267b85c1c8f8db838dcd09d36.tar.bz2 |
Merge commit 'b1c06fd9723453dd2b2ec306684cb806dc2b4fbb^' into HEAD
Diffstat (limited to 'gcc')
433 files changed, 12811 insertions, 2666 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a78b16..3968cf2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,518 @@ +2023-09-20 Andrew MacLeod <amacleod@redhat.com> + + * gimple-range-cache.cc (ssa_cache::merge_range): Change meaning + of the return value. + (ssa_cache::dump): Don't print GLOBAL RANGE header. + (ssa_lazy_cache::merge_range): Adjust return value meaning. + (ranger_cache::dump): Print GLOBAL RANGE header. + +2023-09-20 Aldy Hernandez <aldyh@redhat.com> + + * range-op-float.cc (foperator_unordered_ge::fold_range): Remove + special casing. + (foperator_unordered_gt::fold_range): Same. + (foperator_unordered_lt::fold_range): Same. + (foperator_unordered_le::fold_range): Same. + +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + * builtins.h (type_to_class): Declare. + * builtins.cc (type_to_class): No longer static. Return + int rather than enum. + * doc/extend.texi (__builtin_classify_type): Document. + +2023-09-20 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/110751 + * internal-fn.cc (expand_fn_using_insn): Support undefined rtx value. + * optabs.cc (maybe_legitimize_operand): Ditto. + (can_reuse_operands_p): Ditto. + * optabs.h (enum expand_operand_type): Ditto. + (create_undefined_input_operand): Ditto. + +2023-09-20 Tobias Burnus <tobias@codesourcery.com> + + * gimplify.cc (gimplify_bind_expr): Call GOMP_alloc/free for + 'omp allocate' variables; move stack cleanup after other + cleanup. + (omp_notice_variable): Process original decl when decl + of the value-expression for a 'omp allocate' variable is passed. + * omp-low.cc (scan_omp_1_op): Handle 'omp allocate' variables + +2023-09-20 Yanzhang Wang <yanzhang.wang@intel.com> + + * simplify-rtx.cc (simplify_context::simplify_binary_operation_1): + support simplifying vector int not only scalar int. + +2023-09-20 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/vector-iterators.md: Extend VLS floating-point. + +2023-09-20 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-vsetvl.cc (vector_insn_info::operator==): Fix bug. + +2023-09-20 Iain Sandoe <iain@sandoe.co.uk> + + * config/darwin.h: + (SUBTARGET_DRIVER_SELF_SPECS): Move handling of 'shared' into the same + specs as 'dynamiclib'. (STARTFILE_SPEC): Handle 'shared'. + +2023-09-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111489 + * params.opt (-param uninit-max-chain-len=): Raise default to 8. + +2023-09-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111489 + * doc/invoke.texi (--param uninit-max-chain-len): Document. + (--param uninit-max-num-chains): Likewise. + * params.opt (-param=uninit-max-chain-len=): New. + (-param=uninit-max-num-chains=): Likewise. + * gimple-predicate-analysis.cc (MAX_NUM_CHAINS): Define to + param_uninit_max_num_chains. + (MAX_CHAIN_LEN): Define to param_uninit_max_chain_len. + (uninit_analysis::init_use_preds): Avoid VLA. + (uninit_analysis::init_from_phi_def): Likewise. + (compute_control_dep_chain): Avoid using MAX_CHAIN_LEN in + template parameter. + +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + * match.pd ((x << c) >> c): Use MAX_FIXED_MODE_SIZE instead of + GET_MODE_PRECISION of TImode or DImode depending on whether + TImode is supported scalar mode. + * gimple-lower-bitint.cc (bitint_precision_kind): Likewise. + * expr.cc (expand_expr_real_1): Likewise. + * tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_stmt): Likewise. + * ubsan.cc (ubsan_encode_value, ubsan_type_descriptor): Likewise. + +2023-09-20 Lehua Ding <lehua.ding@rivai.ai> + + * config/riscv/autovec-opt.md (*<optab>not<mode>): Move and rename. + (*n<optab><mode>): Ditto. + (*v<any_shiftrt:optab><any_extend:optab>trunc<mode>): Ditto. + (*<any_shiftrt:optab>trunc<mode>): Ditto. + (*narrow_<any_shiftrt:optab><any_extend:optab><mode>): Ditto. + (*narrow_<any_shiftrt:optab><mode>_scalar): Ditto. + (*single_widen_mult<any_extend:su><mode>): Ditto. + (*single_widen_mul<any_extend:su><mode>): Ditto. + (*single_widen_mult<mode>): Ditto. + (*single_widen_mul<mode>): Ditto. + (*dual_widen_fma<mode>): Ditto. + (*dual_widen_fma<su><mode>): Ditto. + (*single_widen_fma<mode>): Ditto. + (*single_widen_fma<su><mode>): Ditto. + (*dual_fma<mode>): Ditto. + (*single_fma<mode>): Ditto. + (*dual_fnma<mode>): Ditto. + (*dual_widen_fnma<mode>): Ditto. + (*single_fnma<mode>): Ditto. + (*single_widen_fnma<mode>): Ditto. + (*dual_fms<mode>): Ditto. + (*dual_widen_fms<mode>): Ditto. + (*single_fms<mode>): Ditto. + (*single_widen_fms<mode>): Ditto. + (*dual_fnms<mode>): Ditto. + (*dual_widen_fnms<mode>): Ditto. + (*single_fnms<mode>): Ditto. + (*single_widen_fnms<mode>): Ditto. + +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + PR c++/111392 + * attribs.cc (decl_attributes): Don't warn on omp::directive attribute + on vars or function decls if -fopenmp or -fopenmp-simd. + +2023-09-20 Lehua Ding <lehua.ding@rivai.ai> + + PR target/111488 + * config/riscv/autovec-opt.md: Add missed operand. + +2023-09-20 Omar Sandoval <osandov@osandov.com> + + PR debug/111409 + * dwarf2out.cc (output_macinfo): Don't call optimize_macinfo_range if + dwarf_split_debug_info. + +2023-09-20 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-v.cc (can_find_related_mode_p): New function. + (vectorize_related_mode): Add VLS related modes. + * config/riscv/vector-iterators.md: Extend VLS modes. + +2023-09-20 Surya Kumari Jangala <jskumari@linux.ibm.com> + + PR rtl-optimization/110071 + * ira-color.cc (improve_allocation): Consider cost of callee + save registers. + +2023-09-20 mengqinggang <mengqinggang@loongson.cn> + Xi Ruoyao <xry111@xry111.site> + + * configure: Regenerate. + * configure.ac: Checking assembler for -mno-relax support. + Disable relaxation when probing leb128 support. + +2023-09-20 Lulu Cheng <chenglulu@loongson.cn> + + * config.in: Regenerate. + * config/loongarch/genopts/loongarch.opt.in: Add compilation option + mrelax. And set the initial value of explicit-relocs according to the + detection status. + * config/loongarch/gnu-user.h: When compiling with -mno-relax, pass the + --no-relax option to the linker. + * config/loongarch/loongarch-driver.h (ASM_SPEC): When compiling with + -mno-relax, pass the -mno-relax option to the assembler. + * config/loongarch/loongarch-opts.h (HAVE_AS_MRELAX_OPTION): Define macro. + * config/loongarch/loongarch.opt: Regenerate. + * configure: Regenerate. + * configure.ac: Add detection of support for binutils relax function. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * doc/invoke.texi: Document -fdeps-format=, -fdeps-file=, and + -fdeps-target= flags. + * gcc.cc: add defaults for -fdeps-target= and -fdeps-file= when + only -fdeps-format= is specified. + * json.h: Add a TODO item to refactor out to share with + `libcpp/mkdeps.cc`. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + Jason Merrill <jason@redhat.com> + + * gcc.cc (join_spec_func): Add a spec function to join all + arguments. + +2023-09-19 Patrick O'Neill <patrick@rivosinc.com> + + * config/riscv/riscv.cc (riscv_legitimize_const_move): Eliminate + src_op_0 var to avoid rtl check error. + +2023-09-19 Aldy Hernandez <aldyh@redhat.com> + + * range-op-float.cc (frelop_early_resolve): Clean-up and remove + special casing. + (operator_not_equal::fold_range): Handle VREL_EQ. + (operator_lt::fold_range): Remove special casing for VREL_EQ. + (operator_gt::fold_range): Same. + (foperator_unordered_equal::fold_range): Same. + +2023-09-19 Javier Martinez <javier.martinez.bugzilla@gmail.com> + + * doc/extend.texi: Document attributes hot, cold on C++ types. + +2023-09-19 Pat Haugen <pthaugen@linux.ibm.com> + + * config/rs6000/rs6000.cc (rs6000_rtx_costs): Check whether the + modulo instruction is disabled. + * config/rs6000/rs6000.h (RS6000_DISABLE_SCALAR_MODULO): New. + * config/rs6000/rs6000.md (mod<mode>3, *mod<mode>3): Check it. + (define_expand umod<mode>3): New. + (define_insn umod<mode>3): Rename to *umod<mode>3 and check if the modulo + instruction is disabled. + (umodti3, modti3): Check if the modulo instruction is disabled. + +2023-09-19 Gaius Mulley <gaiusmod2@gmail.com> + + * doc/gm2.texi (fdebug-builtins): Correct description. + +2023-09-19 Jeff Law <jlaw@ventanamicro.com> + + * config/iq2000/predicates.md (uns_arith_constant): New predicate. + * config/iq2000/iq2000.md (rotrsi3): Use it. + +2023-09-19 Aldy Hernandez <aldyh@redhat.com> + + * range-op-float.cc (operator_lt::op1_range): Remove known_isnan check. + (operator_lt::op2_range): Same. + (operator_le::op1_range): Same. + (operator_le::op2_range): Same. + (operator_gt::op1_range): Same. + (operator_gt::op2_range): Same. + (operator_ge::op1_range): Same. + (operator_ge::op2_range): Same. + (foperator_unordered_lt::op1_range): Same. + (foperator_unordered_lt::op2_range): Same. + (foperator_unordered_le::op1_range): Same. + (foperator_unordered_le::op2_range): Same. + (foperator_unordered_gt::op1_range): Same. + (foperator_unordered_gt::op2_range): Same. + (foperator_unordered_ge::op1_range): Same. + (foperator_unordered_ge::op2_range): Same. + +2023-09-19 Aldy Hernandez <aldyh@redhat.com> + + * value-range.h (frange::update_nan): New. + +2023-09-19 Aldy Hernandez <aldyh@redhat.com> + + * range-op-float.cc (operator_not_equal::op2_range): New. + * range-op-mixed.h: Add operator_not_equal::op2_range. + +2023-09-19 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/110080 + PR tree-optimization/110249 + * tree-vrp.cc (remove_unreachable::final_p): New. + (remove_unreachable::maybe_register): Rename from + maybe_register_block and call early or final routine. + (fully_replaceable): New. + (remove_unreachable::handle_early): New. + (remove_unreachable::remove_and_update_globals): Remove + non-final processing. + (rvrp_folder::rvrp_folder): Add final flag to constructor. + (rvrp_folder::post_fold_bb): Remove unreachable registration. + (rvrp_folder::pre_fold_stmt): Move unreachable processing to here. + (execute_ranger_vrp): Adjust some call parameters. + +2023-09-19 Richard Biener <rguenther@suse.de> + + PR c/111468 + * tree-pretty-print.h (op_symbol_code): Add defaulted flags + argument. + * tree-pretty-print.cc (op_symbol): Likewise. + (op_symbol_code): Print TDF_GIMPLE variant if requested. + * gimple-pretty-print.cc (dump_binary_rhs): Pass flags to + op_symbol_code. + (dump_gimple_cond): Likewise. + +2023-09-19 Thomas Schwinge <thomas@codesourcery.com> + Pan Li <pan2.li@intel.com> + + * tree-streamer.h (bp_unpack_machine_mode): If + 'ib->file_data->mode_table' not available, apply 1-to-1 mapping. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv.cc (riscv_can_change_mode_class): Block unordered VLA and VLS modes. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec.md: Extend VLS modes. + * config/riscv/vector.md: Ditto. + +2023-09-19 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111465 + * tree-ssa-threadupdate.cc (fwd_jt_path_registry::thread_block_1): + Cancel the path when a EDGE_NO_COPY_SRC_BLOCK became non-empty. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec.md: Extend VLS floating-point modes. + * config/riscv/vector.md: Ditto. + +2023-09-19 Jakub Jelinek <jakub@redhat.com> + + * match.pd ((x << c) >> c): Don't call build_nonstandard_integer_type + nor check type_has_mode_precision_p for width larger than [TD]Imode + precision. + (a ? CST1 : CST2): Don't use build_nonstandard_type, just convert + to type. Use boolean_true_node instead of + constant_boolean_node (true, boolean_type_node). Formatting fixes. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec.md: Add VLS modes. + * config/riscv/vector.md: Ditto. + +2023-09-19 Jakub Jelinek <jakub@redhat.com> + + * tree.cc (build_bitint_type): Assert precision is not 0, or + for signed types 1. + (signed_or_unsigned_type_for): Return INTEGER_TYPE for signed variant + of unsigned _BitInt(1). + +2023-09-19 Lehua Ding <lehua.ding@rivai.ai> + + * config/riscv/autovec-opt.md (*<optab>_fma<mode>): + Removed old combine patterns. + (*single_<optab>mult_plus<mode>): Ditto. + (*double_<optab>mult_plus<mode>): Ditto. + (*sign_zero_extend_fma): Ditto. + (*zero_sign_extend_fma): Ditto. + (*double_widen_fma<mode>): Ditto. + (*single_widen_fma<mode>): Ditto. + (*double_widen_fnma<mode>): Ditto. + (*single_widen_fnma<mode>): Ditto. + (*double_widen_fms<mode>): Ditto. + (*single_widen_fms<mode>): Ditto. + (*double_widen_fnms<mode>): Ditto. + (*single_widen_fnms<mode>): Ditto. + (*reduc_plus_scal_<mode>): Adjust name. + (*widen_reduc_plus_scal_<mode>): Adjust name. + (*dual_widen_fma<mode>): New combine pattern. + (*dual_widen_fmasu<mode>): Ditto. + (*dual_widen_fmaus<mode>): Ditto. + (*dual_fma<mode>): Ditto. + (*single_fma<mode>): Ditto. + (*dual_fnma<mode>): Ditto. + (*single_fnma<mode>): Ditto. + (*dual_fms<mode>): Ditto. + (*single_fms<mode>): Ditto. + (*dual_fnms<mode>): Ditto. + (*single_fnms<mode>): Ditto. + * config/riscv/autovec.md (fma<mode>4): + Reafctor fma pattern. + (*fma<VI:mode><P:mode>): Removed. + (fnma<mode>4): Reafctor. + (*fnma<VI:mode><P:mode>): Removed. + (*fma<VF:mode><P:mode>): Removed. + (*fnma<VF:mode><P:mode>): Removed. + (fms<mode>4): Reafctor. + (*fms<VF:mode><P:mode>): Removed. + (fnms<mode>4): Reafctor. + (*fnms<VF:mode><P:mode>): Removed. + * config/riscv/riscv-protos.h (prepare_ternary_operands): + Adjust prototype. + * config/riscv/riscv-v.cc (prepare_ternary_operands): Refactor. + * config/riscv/vector.md (*pred_mul_plus<mode>_undef): New pattern. + (*pred_mul_plus<mode>): Removed. + (*pred_mul_plus<mode>_scalar): Removed. + (*pred_mul_plus<mode>_extended_scalar): Removed. + (*pred_minus_mul<mode>_undef): New pattern. + (*pred_minus_mul<mode>): Removed. + (*pred_minus_mul<mode>_scalar): Removed. + (*pred_minus_mul<mode>_extended_scalar): Removed. + (*pred_mul_<optab><mode>_undef): New pattern. + (*pred_mul_<optab><mode>): Removed. + (*pred_mul_<optab><mode>_scalar): Removed. + (*pred_mul_neg_<optab><mode>_undef): New pattern. + (*pred_mul_neg_<optab><mode>): Removed. + (*pred_mul_neg_<optab><mode>_scalar): Removed. + +2023-09-19 Tsukasa OI <research_trasio@irq.a4lg.com> + + * config/riscv/riscv-vector-builtins.cc + (builtin_decl, expand_builtin): Replace SVE with RVV. + +2023-09-19 Tsukasa OI <research_trasio@irq.a4lg.com> + + * config/riscv/t-riscv: Add dependencies for riscv-builtins.cc, + riscv-cmo.def and riscv-scalar-crypto.def. + +2023-09-18 Pan Li <pan2.li@intel.com> + + * config/riscv/autovec.md: Extend to vls mode. + +2023-09-18 Pan Li <pan2.li@intel.com> + + * config/riscv/autovec.md: Bugfix. + * config/riscv/riscv-protos.h (SCALAR_MOVE_MERGED_OP): New enum. + +2023-09-18 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111442 + * match.pd (zero_one_valued_p): Have the bit_and match not be + recursive. + +2023-09-18 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111435 + * match.pd (zero_one_valued_p): Don't do recursion + on converts. + +2023-09-18 Iain Sandoe <iain@sandoe.co.uk> + + * config/darwin-protos.h (enum darwin_external_toolchain): New. + * config/darwin.cc (DSYMUTIL_VERSION): New. + (darwin_override_options): Choose the default debug DWARF version + depending on the configured dsymutil version. + +2023-09-18 Iain Sandoe <iain@sandoe.co.uk> + + * configure: Regenerate. + * configure.ac: Handle explict disable of stdlib option, set + defaults for Darwin. + +2023-09-18 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111431 + * match.pd (`(a == CST) & a`): New pattern. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-selftests.cc (run_broadcast_selftests): Adapt selftests. + * config/riscv/vector.md (@vec_duplicate<mode>): Remove. + +2023-09-18 Wilco Dijkstra <wilco.dijkstra@arm.com> + + PR target/105928 + * config/aarch64/aarch64.cc (aarch64_internal_mov_immediate) + Add support for immediates using shifted ORR/BIC. + (aarch64_split_dimode_const_store): Apply if we save one instruction. + * config/aarch64/aarch64.md (<LOGICAL:optab>_<SHIFT:optab><mode>3): + Make pattern global. + +2023-09-18 Wilco Dijkstra <wilco.dijkstra@arm.com> + + * config/aarch64/aarch64-cores.def (neoverse-n1): Place before ares. + (neoverse-v1): Place before zeus. + (neoverse-v2): Place before demeter. + * config/aarch64/aarch64-tune.md: Regenerate. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec.md: Add VLS modes. + * config/riscv/vector-iterators.md: Ditto. + * config/riscv/vector.md: Ditto. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-vsetvl.cc (vlmul_for_greatest_sew_second_ratio): New function. + * config/riscv/riscv-vsetvl.def (DEF_SEW_LMUL_FUSE_RULE): Fix bug. + +2023-09-18 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111294 + * tree-ssa-threadbackward.cc (back_threader_profitability::m_name): + Remove + (back_threader::find_paths_to_names): Adjust. + (back_threader::maybe_thread_block): Likewise. + (back_threader_profitability::possibly_profitable_path_p): Remove + code applying extra costs to copies PHIs. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec.md: Extend VLS modes. + * config/riscv/vector.md: Ditto. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/vector.md (mov<mode>): New pattern. + (*mov<mode>_mem_to_mem): Ditto. + (*mov<mode>): Ditto. + (@mov<VLS_AVL_REG:mode><P:mode>_lra): Ditto. + (*mov<VLS_AVL_REG:mode><P:mode>_lra): Ditto. + (*mov<mode>_vls): Ditto. + (movmisalign<mode>): Ditto. + (@vec_duplicate<mode>): Ditto. + * config/riscv/autovec-vls.md: Removed. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/111153 + * config/riscv/autovec.md: Add VLS modes. + +2023-09-18 Jason Merrill <jason@redhat.com> + + * doc/gty.texi: Add discussion of cache vs. deletable. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec-vls.md (<optab><mode>3): Deleted. + (copysign<mode>3): Ditto. + (xorsign<mode>3): Ditto. + (<optab><mode>2): Ditto. + * config/riscv/autovec.md: Extend VLS modes. + +2023-09-18 Jiufu Guo <guojiufu@linux.ibm.com> + + PR middle-end/111303 + * match.pd ((t * 2) / 2): Update pattern. + 2023-09-17 Ajit Kumar Agarwal <aagarwa1@linux.ibm.com> * config/rs6000/vsx.md (*vctzlsbb_zext_<mode>): New define_insn. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 844ee2e..707983c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230918 +20230921 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 231ce8b..056adce 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,33 @@ +2023-09-19 Richard Wai <richard@annexi-strayline.com> + + * exp_ch3.adb (Expand_Freeze_Class_Wide_Type): Expanded comments + explaining why TSS Finalize_Address is not generated for + concurrent class-wide types. + * exp_ch7.adb (Make_Finalize_Address_Stmts): Handle cases where the + underlying non-constrained parent type is a concurrent type, and + adjust the designated type to be the corresponding record’s + class-wide type. + +2023-09-19 Richard Wai <richard@annexi-strayline.com> + + * sem_ch3.adb (Build_Derived_Record_Type): Treat presence of + keyword "synchronized" the same as "limited" when determining if a + private extension is limited. + +2023-09-19 Marc Poulhiès <poulhies@adacore.com> + + * gcc-interface/utils.cc (max_value): New. + * gcc-interface/gigi.h (max_value): New. + * gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Subtype>: + When computing gnu_min/gnu_max, try to use max_value if there is + an initial expression. + +2023-09-19 Javier Miranda <miranda@adacore.com> + + * contracts.adb + (Has_Public_Visibility_Of_Subprogram): Add missing support for + child subprograms. + 2023-09-15 Eric Botcazou <ebotcazou@adacore.com> * gcc-interface/utils.cc (finish_record_type): Round the size in diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb index 77578da..4aaa276 100644 --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -2484,7 +2484,7 @@ package body Contracts is -- declarations of the package containing the type, or in the -- visible declaration of a child unit of that package. - else + elsif Is_List_Member (Subp_Decl) then declare Decls : constant List_Id := List_Containing (Subp_Decl); @@ -2508,6 +2508,29 @@ package body Contracts is (Specification (Unit_Declaration_Node (Subp_Scope)))); end; + + -- Determine whether the subprogram is a child subprogram of + -- of the package containing the type. + + else + pragma Assert + (Nkind (Parent (Subp_Decl)) = N_Compilation_Unit); + + declare + Subp_Scope : constant Entity_Id := + Scope (Defining_Entity (Subp_Decl)); + Typ_Scope : constant Entity_Id := Scope (Typ); + + begin + return + Ekind (Subp_Scope) = E_Package + and then + (Typ_Scope = Subp_Scope + or else + (Is_Child_Unit (Subp_Scope) + and then Is_Ancestor_Package + (Typ_Scope, Subp_Scope))); + end; end if; end Has_Public_Visibility_Of_Subprogram; diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index 04c3ad8..bb01598 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -5000,6 +5000,10 @@ package body Exp_Ch3 is -- Do not create TSS routine Finalize_Address for concurrent class-wide -- types. Ignore C, C++, CIL and Java types since it is assumed that the -- non-Ada side will handle their destruction. + -- + -- Concurrent Ada types are functionally represented by an associated + -- "corresponding record type" (typenameV), which owns the actual TSS + -- finalize bodies for the type (and technically class-wide type). elsif Is_Concurrent_Type (Root) or else Is_C_Derivation (Root) diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index aa16c70..4ea5e6e 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -8512,7 +8512,8 @@ package body Exp_Ch7 is Is_Empty_Elmt_List (Discriminant_Constraint (Root_Type (Typ))) then declare - Parent_Typ : Entity_Id; + Parent_Typ : Entity_Id; + Parent_Utyp : Entity_Id; begin -- Climb the parent type chain looking for a non-constrained type @@ -8533,7 +8534,30 @@ package body Exp_Ch7 is Parent_Typ := Underlying_Record_View (Parent_Typ); end if; - Desig_Typ := Class_Wide_Type (Underlying_Type (Parent_Typ)); + Parent_Utyp := Underlying_Type (Parent_Typ); + + -- Handle views created for a synchronized private extension with + -- known, non-defaulted discriminants. In that case, parent_typ + -- will be the private extension, as it is the first "non + -- -constrained" type in the parent chain. Unfortunately, the + -- underlying type, being a protected or task type, is not the + -- "real" type needing finalization. Rather, the "corresponding + -- record type" should be the designated type here. In fact, TSS + -- finalizer generation is specifically skipped for the nominal + -- class-wide type of (the full view of) a concurrent type (see + -- exp_ch7.Expand_Freeze_Class_Wide_Type). If we don't designate + -- the underlying record (Tprot_typeVC), we will end up trying to + -- dispatch to prot_typeVDF from an incorrectly designated + -- Tprot_typeC, which is, of course, not actually a member of + -- prot_typeV'Class, and thus incompatible. + + if Ekind (Parent_Utyp) in Concurrent_Kind + and then Present (Corresponding_Record_Type (Parent_Utyp)) + then + Parent_Utyp := Corresponding_Record_Type (Parent_Utyp); + end if; + + Desig_Typ := Class_Wide_Type (Parent_Utyp); end; -- General case diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index 0cf7d3c..5e16b56 100644 --- a/gcc/ada/gcc-interface/decl.cc +++ b/gcc/ada/gcc-interface/decl.cc @@ -2551,6 +2551,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) else gnu_min = gnu_orig_min; + if (DECL_P (gnu_min) + && DECL_INITIAL (gnu_min) != NULL_TREE + && (TREE_CODE (gnu_min) != INTEGER_CST + || TREE_OVERFLOW (gnu_min))) + { + tree tmp = max_value (DECL_INITIAL(gnu_min), false); + if (TREE_CODE (tmp) == INTEGER_CST + && !TREE_OVERFLOW (tmp)) + gnu_min = tmp; + } + if (TREE_CODE (gnu_min) != INTEGER_CST || TREE_OVERFLOW (gnu_min)) gnu_min = TYPE_MIN_VALUE (TREE_TYPE (gnu_min)); @@ -2560,6 +2571,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) else gnu_max = gnu_orig_max; + if (DECL_P (gnu_max) + && DECL_INITIAL (gnu_max) != NULL_TREE + && (TREE_CODE (gnu_max) != INTEGER_CST + || TREE_OVERFLOW (gnu_max))) + { + tree tmp = max_value (DECL_INITIAL(gnu_max), true); + if (TREE_CODE (tmp) == INTEGER_CST + && !TREE_OVERFLOW (tmp)) + gnu_max = tmp; + } + if (TREE_CODE (gnu_max) != INTEGER_CST || TREE_OVERFLOW (gnu_max)) gnu_max = TYPE_MAX_VALUE (TREE_TYPE (gnu_max)); diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index ec85ce4..eb5496f 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -763,6 +763,12 @@ extern void update_pointer_to (tree old_type, tree new_type); minimum (if !MAX_P) possible value of the discriminant. */ extern tree max_size (tree exp, bool max_p); +/* Try to compute the maximum (if MAX_P) or minimum (if !MAX_P) value for the + expression EXP, for very simple expressions. Substitute variable references + with their respective type's min/max values. Return the computed value if + any, or EXP if no value can be computed. */ +extern tree max_value (tree exp, bool max_p); + /* Remove all conversions that are done in EXP. This includes converting from a padded type or to a left-justified modular type. If TRUE_ADDRESS is true, always return the address of the containing object even if diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index f720f3a..4e2ed17 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -3830,6 +3830,100 @@ fntype_same_flags_p (const_tree t, tree cico_list, bool return_by_direct_ref_p, && TREE_ADDRESSABLE (t) == return_by_invisi_ref_p; } +/* Try to compute the maximum (if MAX_P) or minimum (if !MAX_P) value for the + expression EXP, for very simple expressions. Substitute variable references + with their respective type's min/max values. Return the computed value if + any, or EXP if no value can be computed. */ + +tree +max_value (tree exp, bool max_p) +{ + enum tree_code code = TREE_CODE (exp); + tree type = TREE_TYPE (exp); + tree op0, op1, op2; + + switch (TREE_CODE_CLASS (code)) + { + case tcc_declaration: + if (VAR_P (exp)) + return fold_convert (type, + max_p + ? TYPE_MAX_VALUE (type) : TYPE_MIN_VALUE (type)); + break; + + case tcc_vl_exp: + if (code == CALL_EXPR) + { + tree t; + + t = maybe_inline_call_in_expr (exp); + if (t) + return max_value (t, max_p); + } + break; + + case tcc_comparison: + return build_int_cst (type, max_p ? 1 : 0); + + case tcc_unary: + op0 = TREE_OPERAND (exp, 0); + + if (code == NON_LVALUE_EXPR) + return max_value (op0, max_p); + + if (code == NEGATE_EXPR) + return max_value (op0, !max_p); + + if (code == NOP_EXPR) + return fold_convert (type, max_value (op0, max_p)); + + break; + + case tcc_binary: + op0 = TREE_OPERAND (exp, 0); + op1 = TREE_OPERAND (exp, 1); + + switch (code) { + case PLUS_EXPR: + case MULT_EXPR: + return fold_build2 (code, type, max_value(op0, max_p), + max_value (op1, max_p)); + case MINUS_EXPR: + case TRUNC_DIV_EXPR: + return fold_build2 (code, type, max_value(op0, max_p), + max_value (op1, !max_p)); + default: + break; + } + break; + + case tcc_expression: + if (code == COND_EXPR) + { + op0 = TREE_OPERAND (exp, 0); + op1 = TREE_OPERAND (exp, 1); + op2 = TREE_OPERAND (exp, 2); + + if (!op1 || !op2) + break; + + op1 = max_value (op1, max_p); + op2 = max_value (op2, max_p); + + if (op1 == TREE_OPERAND (exp, 1) && op2 == TREE_OPERAND (exp, 2)) + break; + + return fold_build2 (max_p ? MAX_EXPR : MIN_EXPR, type, op1, op2); + } + break; + + default: + break; + } + return exp; +} + + /* EXP is an expression for the size of an object. If this size contains discriminant references, replace them with the maximum (if MAX_P) or minimum (if !MAX_P) possible value of the discriminant. @@ -3867,6 +3961,7 @@ max_size (tree exp, bool max_p) n = call_expr_nargs (exp); gcc_assert (n > 0); argarray = XALLOCAVEC (tree, n); + /* This is used to remove possible placeholder in call args. */ for (i = 0; i < n; i++) argarray[i] = max_size (CALL_EXPR_ARG (exp, i), max_p); return build_call_array (type, CALL_EXPR_FN (exp), n, argarray); diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 3262236..92902a7 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -9599,9 +9599,15 @@ package body Sem_Ch3 is -- AI-419: Limitedness is not inherited from an interface parent, so to -- be limited in that case the type must be explicitly declared as - -- limited. However, task and protected interfaces are always limited. - - if Limited_Present (Type_Def) then + -- limited, or synchronized. While task and protected interfaces are + -- always limited, a synchronized private extension might not inherit + -- from such interfaces, and so we also need to recognize the + -- explicit limitedness implied by a synchronized private extension + -- that does not derive from a synchronized interface (see RM-7.3(6/2)). + + if Limited_Present (Type_Def) + or else Synchronized_Present (Type_Def) + then Set_Is_Limited_Record (Derived_Type); elsif Is_Limited_Record (Parent_Type) diff --git a/gcc/attribs.cc b/gcc/attribs.cc index b8cb55b..229d8b3 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -719,6 +719,12 @@ decl_attributes (tree *node, tree attributes, int flags, if (ns == NULL_TREE || !cxx11_attr_p) warning (OPT_Wattributes, "%qE attribute directive ignored", name); + else if ((flag_openmp || flag_openmp_simd) + && is_attribute_p ("omp", ns) + && is_attribute_p ("directive", name) + && (VAR_P (*node) + || TREE_CODE (*node) == FUNCTION_DECL)) + continue; else warning (OPT_Wattributes, "%<%E::%E%> scoped attribute directive ignored", diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 3b453b3..6e4274b 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -113,7 +113,6 @@ static rtx expand_builtin_apply_args (void); static rtx expand_builtin_apply_args_1 (void); static rtx expand_builtin_apply (rtx, rtx, rtx); static void expand_builtin_return (rtx); -static enum type_class type_to_class (tree); static rtx expand_builtin_classify_type (tree); static rtx expand_builtin_mathfn_3 (tree, rtx, rtx); static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx); @@ -1853,7 +1852,7 @@ expand_builtin_return (rtx result) /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */ -static enum type_class +int type_to_class (tree type) { switch (TREE_CODE (type)) diff --git a/gcc/builtins.h b/gcc/builtins.h index 6a43de4..3b5c34c 100644 --- a/gcc/builtins.h +++ b/gcc/builtins.h @@ -156,5 +156,6 @@ extern internal_fn associated_internal_fn (tree); extern internal_fn replacement_internal_fn (gcall *); extern bool builtin_with_linkage_p (tree); +extern int type_to_class (tree); #endif /* GCC_BUILTINS_H */ diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 61720c1..30ce662 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,27 @@ +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + PR c++/111392 + * c-omp.cc (c_omp_directives): Add commented out groupprivate + directive entry. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * c-opts.cc (c_common_handle_option): Add fdeps_file variable and + -fdeps-format=, -fdeps-file=, and -fdeps-target= parsing. + * c.opt: Add -fdeps-format=, -fdeps-file=, and -fdeps-target= + flags. + +2023-09-19 Javier Martinez <javier.martinez.bugzilla@gmail.com> + + * c-attribs.cc (handle_hot_attribute): remove warning on + RECORD_TYPE and UNION_TYPE when in c_dialect_xx. + (handle_cold_attribute): Likewise. + +2023-09-19 Jakub Jelinek <jakub@redhat.com> + + * c-common.cc (c_common_signed_or_unsigned_type): Return INTEGER_TYPE + for signed variant of unsigned _BitInt(1). + 2023-09-06 Jakub Jelinek <jakub@redhat.com> PR c/102989 diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index e0c4259..dca7548 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -452,10 +452,10 @@ const struct attribute_spec c_common_attribute_table[] = { "alloc_size", 1, 2, false, true, true, false, handle_alloc_size_attribute, attr_alloc_exclusions }, - { "cold", 0, 0, true, false, false, false, + { "cold", 0, 0, false, false, false, false, handle_cold_attribute, attr_cold_hot_exclusions }, - { "hot", 0, 0, true, false, false, false, + { "hot", 0, 0, false, false, false, false, handle_hot_attribute, attr_cold_hot_exclusions }, { "no_address_safety_analysis", @@ -1110,6 +1110,29 @@ handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args), { /* Attribute hot processing is done later with lookup_attribute. */ } + else if ((TREE_CODE (*node) == RECORD_TYPE + || TREE_CODE (*node) == UNION_TYPE) + && c_dialect_cxx () + && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) + { + /* Check conflict here as decl_attributes will otherwise only catch + it late at the function when the attribute is used on a class. */ + tree cold_attr = lookup_attribute ("cold", TYPE_ATTRIBUTES (*node)); + if (cold_attr) + { + warning (OPT_Wattributes, "ignoring attribute %qE because it " + "conflicts with attribute %qs", name, "cold"); + *no_add_attrs = true; + } + } + else if (flags & ((int) ATTR_FLAG_FUNCTION_NEXT + | (int) ATTR_FLAG_DECL_NEXT)) + { + /* Avoid applying the attribute to a function return type when + used as: void __attribute ((hot)) foo (void). It will be + passed to the function. */ + *no_add_attrs = true; + } else { warning (OPT_Wattributes, "%qE attribute ignored", name); @@ -1131,6 +1154,29 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args), { /* Attribute cold processing is done later with lookup_attribute. */ } + else if ((TREE_CODE (*node) == RECORD_TYPE + || TREE_CODE (*node) == UNION_TYPE) + && c_dialect_cxx () + && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) + { + /* Check conflict here as decl_attributes will otherwise only catch + it late at the function when the attribute is used on a class. */ + tree hot_attr = lookup_attribute ("hot", TYPE_ATTRIBUTES (*node)); + if (hot_attr) + { + warning (OPT_Wattributes, "ignoring attribute %qE because it " + "conflicts with attribute %qs", name, "hot"); + *no_add_attrs = true; + } + } + else if (flags & ((int) ATTR_FLAG_FUNCTION_NEXT + | (int) ATTR_FLAG_DECL_NEXT)) + { + /* Avoid applying the attribute to a function return type when + used as: void __attribute ((cold)) foo (void). It will be + passed to the function. */ + *no_add_attrs = true; + } else { warning (OPT_Wattributes, "%qE attribute ignored", name); diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 73e739c..aae5726 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -2739,7 +2739,9 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type) || TYPE_UNSIGNED (type) == unsignedp) return type; - if (TREE_CODE (type) == BITINT_TYPE) + if (TREE_CODE (type) == BITINT_TYPE + /* signed _BitInt(1) is invalid, avoid creating that. */ + && (unsignedp || TYPE_PRECISION (type) > 1)) return build_bitint_type (TYPE_PRECISION (type), unsignedp); #define TYPE_OK(node) \ diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc index 9b7d7f7..95b6c1e 100644 --- a/gcc/c-family/c-omp.cc +++ b/gcc/c-family/c-omp.cc @@ -3306,6 +3306,8 @@ const struct c_omp_directive c_omp_directives[] = { C_OMP_DIR_STANDALONE, false }, { "for", nullptr, nullptr, PRAGMA_OMP_FOR, C_OMP_DIR_CONSTRUCT, true }, + /* { "groupprivate", nullptr, nullptr, PRAGMA_OMP_GROUPPRIVATE, + C_OMP_DIR_DECLARATIVE, false }, */ /* { "interop", nullptr, nullptr, PRAGMA_OMP_INTEROP, C_OMP_DIR_STANDALONE, false }, */ { "loop", nullptr, nullptr, PRAGMA_OMP_LOOP, diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index d9f55f4..fe2d143 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -77,6 +77,9 @@ static bool verbose; /* Dependency output file. */ static const char *deps_file; +/* Structured dependency output file. */ +static const char *fdeps_file; + /* The prefix given by -iprefix, if any. */ static const char *iprefix; @@ -361,6 +364,24 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, deps_file = arg; break; + case OPT_fdeps_format_: + /* https://wg21.link/p1689r5 */ + if (!strcmp (arg, "p1689r5")) + cpp_opts->deps.fdeps_format = FDEPS_FMT_P1689R5; + else + error ("%<-fdeps-format=%> unknown format %<%s%>", arg); + break; + + case OPT_fdeps_file_: + deps_seen = true; + fdeps_file = arg; + break; + + case OPT_fdeps_target_: + deps_seen = true; + defer_opt (code, arg); + break; + case OPT_MF: deps_seen = true; deps_file = arg; @@ -1281,6 +1302,7 @@ void c_common_finish (void) { FILE *deps_stream = NULL; + FILE *fdeps_stream = NULL; /* Note that we write the dependencies even if there are errors. This is useful for handling outdated generated headers that now trigger errors @@ -1309,9 +1331,27 @@ c_common_finish (void) locations with input_location, which would be incorrect now. */ override_libcpp_locations = false; + if (cpp_opts->deps.fdeps_format != FDEPS_FMT_NONE) + { + if (!fdeps_file) + fdeps_stream = out_stream; + else if (fdeps_file[0] == '-' && fdeps_file[1] == '\0') + fdeps_stream = stdout; + else + { + fdeps_stream = fopen (fdeps_file, "w"); + if (!fdeps_stream) + fatal_error (input_location, "opening dependency file %s: %m", + fdeps_file); + } + if (fdeps_stream == deps_stream && fdeps_stream != stdout) + fatal_error (input_location, "%<-MF%> and %<-fdeps-file=%> cannot share an output file %s: %m", + fdeps_file); + } + /* For performance, avoid tearing down cpplib's internal structures with cpp_destroy (). */ - cpp_finish (parse_in, deps_stream); + cpp_finish (parse_in, deps_stream, fdeps_stream); if (deps_stream && deps_stream != out_stream && deps_stream != stdout && (ferror (deps_stream) || fclose (deps_stream))) @@ -1383,6 +1423,8 @@ handle_deferred_opts (void) if (opt->code == OPT_MT || opt->code == OPT_MQ) deps_add_target (deps, opt->arg, opt->code == OPT_MQ); + else if (opt->code == OPT_fdeps_target_) + fdeps_add_target (deps, opt->arg, true); } } diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 7348ad4..44b9c86 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -256,6 +256,18 @@ MT C ObjC C++ ObjC++ Joined Separate MissingArgError(missing makefile target after %qs) -MT <target> Add a target that does not require quoting. +fdeps-format= +C ObjC C++ ObjC++ NoDriverArg Joined MissingArgError(missing format after %qs) +Structured format for output dependency information. Supported (\"p1689r5\"). + +fdeps-file= +C ObjC C++ ObjC++ NoDriverArg Joined MissingArgError(missing output path after %qs) +File for output dependency information. + +fdeps-target= +C ObjC C++ ObjC++ NoDriverArg Joined MissingArgError(missing path after %qs) +-fdeps-target=obj.o Output file for the compile step. + P C ObjC C++ ObjC++ Do not generate #line directives. diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index b2fbf3c..c23f756 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,24 @@ +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + * c-parser.cc (c_parser_postfix_expression_after_primary): Parse + __builtin_classify_type call with typename as argument. + +2023-09-19 Richard Biener <rguenther@suse.de> + + PR c/111468 + * gimple-parser.cc (c_parser_gimple_binary_expression): Handle __LTGT. + +2023-09-19 Richard Biener <rguenther@suse.de> + + PR c/111468 + * gimple-parser.cc (c_parser_gimple_binary_expression): Add + return type argument. + (c_parser_gimple_statement): Adjust. + (c_parser_gimple_paren_condition): Likewise. + (c_parser_gimple_binary_expression): Use passed in return type, + add support for - as POINTER_DIFF_EXPR, __UN{LT,LE,GT,GE,EQ}, + __UNORDERED and __ORDERED. + 2023-09-12 Tobias Burnus <tobias@codesourcery.com> * c-parser.cc (struct c_omp_loc_tree): New. diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index b9a1b75..0d468b8 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -11606,6 +11606,29 @@ c_parser_postfix_expression_after_primary (c_parser *parser, literal_zero_mask = 0; if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) exprlist = NULL; + else if (TREE_CODE (expr.value) == FUNCTION_DECL + && fndecl_built_in_p (expr.value, BUILT_IN_CLASSIFY_TYPE) + && c_parser_next_tokens_start_typename (parser, + cla_prefer_id)) + { + /* __builtin_classify_type (type) */ + c_inhibit_evaluation_warnings++; + in_alignof++; + struct c_type_name *type = c_parser_type_name (parser); + c_inhibit_evaluation_warnings--; + in_alignof--; + struct c_typespec ret; + ret.expr = NULL_TREE; + ret.spec = error_mark_node; + ret.expr_const_operands = false; + if (type != NULL) + ret.spec = groktypename (type, &ret.expr, + &ret.expr_const_operands); + parens.skip_until_found_close (parser); + expr.value = build_int_cst (integer_type_node, + type_to_class (ret.spec)); + break; + } else exprlist = c_parser_expr_list (parser, true, false, &origtypes, sizeof_arg_loc, sizeof_arg, diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc index cc3a889..f43c039 100644 --- a/gcc/c/gimple-parser.cc +++ b/gcc/c/gimple-parser.cc @@ -108,7 +108,7 @@ gimple_parser::push_edge (int src, int dest, int flags, static bool c_parser_gimple_compound_statement (gimple_parser &, gimple_seq *); static void c_parser_gimple_label (gimple_parser &, gimple_seq *); static void c_parser_gimple_statement (gimple_parser &, gimple_seq *); -static struct c_expr c_parser_gimple_binary_expression (gimple_parser &); +static struct c_expr c_parser_gimple_binary_expression (gimple_parser &, tree); static struct c_expr c_parser_gimple_unary_expression (gimple_parser &); static struct c_expr c_parser_gimple_postfix_expression (gimple_parser &); static struct c_expr c_parser_gimple_postfix_expression_after_primary @@ -869,7 +869,7 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq) return; } - rhs = c_parser_gimple_binary_expression (parser); + rhs = c_parser_gimple_binary_expression (parser, TREE_TYPE (lhs.value)); if (lhs.value != error_mark_node && rhs.value != error_mark_node) { @@ -930,7 +930,7 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq) */ static c_expr -c_parser_gimple_binary_expression (gimple_parser &parser) +c_parser_gimple_binary_expression (gimple_parser &parser, tree ret_type) { /* Location of the binary operator. */ struct c_expr ret, lhs, rhs; @@ -939,7 +939,6 @@ c_parser_gimple_binary_expression (gimple_parser &parser) lhs = c_parser_gimple_postfix_expression (parser); if (c_parser_error (parser)) return ret; - tree ret_type = TREE_TYPE (lhs.value); switch (c_parser_peek_token (parser)->type) { case CPP_MULT: @@ -958,7 +957,10 @@ c_parser_gimple_binary_expression (gimple_parser &parser) code = PLUS_EXPR; break; case CPP_MINUS: - code = MINUS_EXPR; + if (POINTER_TYPE_P (TREE_TYPE (lhs.value))) + code = POINTER_DIFF_EXPR; + else + code = MINUS_EXPR; break; case CPP_LSHIFT: code = LSHIFT_EXPR; @@ -968,27 +970,21 @@ c_parser_gimple_binary_expression (gimple_parser &parser) break; case CPP_LESS: code = LT_EXPR; - ret_type = boolean_type_node; break; case CPP_GREATER: code = GT_EXPR; - ret_type = boolean_type_node; break; case CPP_LESS_EQ: code = LE_EXPR; - ret_type = boolean_type_node; break; case CPP_GREATER_EQ: code = GE_EXPR; - ret_type = boolean_type_node; break; case CPP_EQ_EQ: code = EQ_EXPR; - ret_type = boolean_type_node; break; case CPP_NOT_EQ: code = NE_EXPR; - ret_type = boolean_type_node; break; case CPP_AND: code = BIT_AND_EXPR; @@ -1006,14 +1002,54 @@ c_parser_gimple_binary_expression (gimple_parser &parser) c_parser_error (parser, "%<||%> not valid in GIMPLE"); return ret; case CPP_NAME: - { - tree id = c_parser_peek_token (parser)->value; - if (strcmp (IDENTIFIER_POINTER (id), "__MULT_HIGHPART") == 0) - { - code = MULT_HIGHPART_EXPR; - break; - } - } + { + tree id = c_parser_peek_token (parser)->value; + if (strcmp (IDENTIFIER_POINTER (id), "__MULT_HIGHPART") == 0) + { + code = MULT_HIGHPART_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__UNLT") == 0) + { + code = UNLT_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__UNLE") == 0) + { + code = UNLE_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__UNGT") == 0) + { + code = UNGT_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__UNGE") == 0) + { + code = UNGE_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__UNEQ") == 0) + { + code = UNEQ_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__UNORDERED") == 0) + { + code = UNORDERED_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__ORDERED") == 0) + { + code = ORDERED_EXPR; + break; + } + else if (strcmp (IDENTIFIER_POINTER (id), "__LTGT") == 0) + { + code = LTGT_EXPR; + break; + } + } /* Fallthru. */ default: /* Not a binary expression. */ @@ -2158,7 +2194,8 @@ c_parser_gimple_paren_condition (gimple_parser &parser) { if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return error_mark_node; - tree cond = c_parser_gimple_binary_expression (parser).value; + tree cond + = c_parser_gimple_binary_expression (parser, boolean_type_node).value; if (cond != error_mark_node && ! COMPARISON_CLASS_P (cond) && ! CONSTANT_CLASS_P (cond) diff --git a/gcc/config.in b/gcc/config.in index f007145..d04718a 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -634,6 +634,12 @@ #endif +/* Define if your assembler supports -mrelax option. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_MRELAX_OPTION +#endif + + /* Define if your assembler supports .mspabi_attribute. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_MSPABI_ATTRIBUTE diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h index 747745f..9df358e 100644 --- a/gcc/config/darwin-protos.h +++ b/gcc/config/darwin-protos.h @@ -129,4 +129,15 @@ extern void darwin_patch_builtins (void); extern void darwin_rename_builtins (void); extern bool darwin_libc_has_function (enum function_class fn_class, tree); +/* For this port, there are several possible sources for external toolchain + components (e.g. as, ld, dsymutil) and we have to alter the allowable + output in response to which version and source is in use. */ +enum darwin_external_toolchain { + DET_UNKNOWN=0, + CCTOOLS, + DWARFUTILS, + LLVM, + CLANG +}; + #endif /* CONFIG_DARWIN_PROTOS_H */ diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc index 154a2b2..d8c8607 100644 --- a/gcc/config/darwin.cc +++ b/gcc/config/darwin.cc @@ -114,6 +114,19 @@ static bool ld_needs_eh_markers = false; /* Emit a section-start symbol for mod init and term sections. */ static bool ld_init_term_start_labels = false; +/* The source and version of dsymutil in use. */ +#ifndef DSYMUTIL_VERSION +# warning Darwin toolchain without a defined dsymutil. +# define DSYMUTIL_VERSION DET_UNKNOWN,0,0,0 +#endif + +struct { + darwin_external_toolchain kind; /* cctools, llvm, clang etc. */ + int major; /* version number. */ + int minor; + int tiny; +} dsymutil_version = {DSYMUTIL_VERSION}; + /* Section names. */ section * darwin_sections[NUM_DARWIN_SECTIONS]; @@ -3357,14 +3370,26 @@ darwin_override_options (void) global_options.x_flag_objc_abi); } - /* Don't emit DWARF3/4 unless specifically selected. This is a - workaround for tool bugs. */ + /* Limit DWARF to the chosen version, the linker and debug linker might not + be able to consume newer structures. */ if (!OPTION_SET_P (dwarf_strict)) dwarf_strict = 1; + if (!OPTION_SET_P (dwarf_version)) - dwarf_version = 2; + { + /* External toolchains based on LLVM or clang 7+ have support for + dwarf-4. */ + if ((dsymutil_version.kind == LLVM && dsymutil_version.major >= 7) + || (dsymutil_version.kind == CLANG && dsymutil_version.major >= 7)) + dwarf_version = 4; + else if (dsymutil_version.kind == DWARFUTILS + && dsymutil_version.major >= 121) + dwarf_version = 3; /* From XC 6.4. */ + else + dwarf_version = 2; /* Older cannot safely exceed dwarf-2. */ + } - if (OPTION_SET_P (dwarf_split_debug_info)) + if (OPTION_SET_P (dwarf_split_debug_info) && dwarf_split_debug_info) { inform (input_location, "%<-gsplit-dwarf%> is not supported on this platform, ignored"); diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index b7cfab6..61e46f7 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -133,10 +133,9 @@ extern GTY(()) int darwin_ms_struct; cases where these driver opts are used multiple times, or to control operations on more than one command (e.g. dynamiclib). These are handled specially and we then add %<xxxx specs for the commands that _don't_ need - them. NOTE: the order of 'shared' and 'dynamiclib' is significant, hence - they are placed out of alphabetical order at the start. Likewise, we keep - a couple of cases where a negative option originally appeared after the - positive alternate, potentially overriding it. + them. + We keep a couple of cases where a negative option originally appeared after + the positive alternate, potentially overriding it. When we report an error with %e, it seems necessary to strip the option before doing so, otherwise it survives to the cc1 command line (%e doesn't appear to abort the program before this). @@ -147,9 +146,9 @@ extern GTY(()) int darwin_ms_struct; #undef SUBTARGET_DRIVER_SELF_SPECS #define SUBTARGET_DRIVER_SELF_SPECS \ - "%{shared:%{!dynamiclib:-dynamiclib}} %<shared", \ - "%{static:%{dynamic|dynamiclib:%econflicting code generation switches}}",\ - "%{dynamiclib:-Xlinker -dylib \ + "%{static|fapple-kext|mkernel:%{shared|dynamic|dynamiclib: \ + %econflicting code generation switches}}",\ + "%{shared|dynamiclib:-Xlinker -dylib \ %{allowable_client*:-Xlinker -allowable_client -Xlinker %*} \ %<allowable_client* \ %{bundle_loader*: %<bundle_loader* \ @@ -167,8 +166,8 @@ extern GTY(()) int darwin_ms_struct; %e-keep_private_externs not allowed with -dynamiclib} \ %{private_bundle: %<private_bundle \ %e-private_bundle not allowed with -dynamiclib} \ - }", \ - "%{!dynamiclib: \ + }", \ + "%{!dynamiclib:%{!shared: \ %{bundle_loader*:-Xlinker -bundle_loader -Xlinker %*} \ %<bundle_loader* \ %{client_name*:-Xlinker -client_name -Xlinker %*} \ @@ -183,13 +182,14 @@ extern GTY(()) int darwin_ms_struct; %<keep_private_externs \ %{private_bundle:-Xlinker -private_bundle} \ %<private_bundle \ - }", \ + }}", \ "%{all_load:-Xlinker -all_load} %<all_load", \ "%{arch_errors_fatal:-Xlinker -arch_errors_fatal} \ %<arch_errors_fatal", \ "%{bind_at_load:-Xlinker -bind_at_load} %<bind_at_load", \ - "%{bundle:%{!dynamiclib:-Xlinker -bundle; \ - :%e-bundle not allowed with -dynamiclib}}", \ + "%{bundle:%{!dynamiclib:%{!shared: -Xlinker -bundle; \ + :%e-bundle not allowed with -shared}; \ + :%e-bundle not allowed with -dynamiclib}}", \ "%{dead_strip:-Xlinker -dead_strip} %<dead_strip", \ "%{dylib_file*:-Xlinker -dylib_file -Xlinker %*} %<dylib_file*", \ "%{dylinker:-Xlinker -dylinker} %<dylinker", \ @@ -307,7 +307,7 @@ extern GTY(()) int darwin_ms_struct; %:version-compare(>= 10.7 mmacosx-version-min= -no_pie) }" #define DARWIN_CC1_SPEC \ - "%<dynamic %<dynamiclib %<force_cpusubtype_ALL %<multiply_defined* " + "%<dynamic %<force_cpusubtype_ALL %<multiply_defined* " #define SUBSUBTARGET_OVERRIDE_OPTIONS \ do { \ @@ -530,8 +530,8 @@ extern GTY(()) int darwin_ms_struct; #undef STARTFILE_SPEC #define STARTFILE_SPEC \ -"%{dynamiclib: %(darwin_dylib1) %{fgnu-tm: -lcrttms.o}} \ - %{!dynamiclib:%{bundle:%(darwin_bundle1)} \ +"%{dynamiclib|shared: %(darwin_dylib1) %{fgnu-tm: -lcrttms.o}} \ + %{!dynamiclib:%{!shared:%{bundle:%(darwin_bundle1)} \ %{!bundle:%{pg:%{static:-lgcrt0.o} \ %{!static:%{object:-lgcrt0.o} \ %{!object:%{preload:-lgcrt0.o} \ @@ -542,8 +542,8 @@ extern GTY(()) int darwin_ms_struct; %{!static:%{object:-lcrt0.o} \ %{!object:%{preload:-lcrt0.o} \ %{!preload: %(darwin_crt1) \ - %(darwin_crt2)}}}}}} \ - %(darwin_crt3) %<dynamiclib " + %(darwin_crt2)}}}}}}} \ + %(darwin_crt3) " /* We want a destructor last in the list. */ #define TM_DESTRUCTOR "%{fgnu-tm: -lcrttme.o}" diff --git a/gcc/config/iq2000/iq2000.md b/gcc/config/iq2000/iq2000.md index aaeda39..f157a82 100644 --- a/gcc/config/iq2000/iq2000.md +++ b/gcc/config/iq2000/iq2000.md @@ -988,7 +988,7 @@ (define_insn "rotrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (rotatert:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "uns_arith_operand" "O")))] + (match_operand:SI 2 "uns_arith_constant" "O")))] "" "ram %0,%1,%2,0x0,0x0" [(set_attr "type" "arith")]) diff --git a/gcc/config/iq2000/predicates.md b/gcc/config/iq2000/predicates.md index 1330f7d6..38857e1 100644 --- a/gcc/config/iq2000/predicates.md +++ b/gcc/config/iq2000/predicates.md @@ -17,6 +17,15 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +;; Return 1 if OP can be used as an operand where a 16-bit +;; unsigned integer is needed. + +(define_predicate "uns_arith_constant" + (match_code "const_int") +{ + return SMALL_INT_UNSIGNED (op); +}) + ;; Return 1 if OP can be used as an operand where a register or 16-bit ;; unsigned integer is needed. diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in index 78a27da..9f98f2d 100644 --- a/gcc/config/loongarch/genopts/loongarch.opt.in +++ b/gcc/config/loongarch/genopts/loongarch.opt.in @@ -175,7 +175,7 @@ Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init -mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024. mexplicit-relocs -Target Var(TARGET_EXPLICIT_RELOCS) Init(HAVE_AS_EXPLICIT_RELOCS) +Target Var(TARGET_EXPLICIT_RELOCS) Init(HAVE_AS_EXPLICIT_RELOCS & !HAVE_AS_MRELAX_OPTION) Use %reloc() assembly operators. ; The code model option names for -mcmodel. @@ -208,3 +208,8 @@ Specify the code model. mdirect-extern-access Target Var(TARGET_DIRECT_EXTERN_ACCESS) Init(0) Avoid using the GOT to access external symbols. + +mrelax +Target Var(loongarch_mrelax) Init(HAVE_AS_MRELAX_OPTION) +Take advantage of linker relaxations to reduce the number of instructions +required to materialize symbol addresses. diff --git a/gcc/config/loongarch/gnu-user.h b/gcc/config/loongarch/gnu-user.h index fa1a521..9616d6e 100644 --- a/gcc/config/loongarch/gnu-user.h +++ b/gcc/config/loongarch/gnu-user.h @@ -48,7 +48,8 @@ along with GCC; see the file COPYING3. If not see "%{!shared: %{static} " \ "%{!static: %{!static-pie: %{rdynamic:-export-dynamic} " \ "-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} " \ - "%{static-pie: -static -pie --no-dynamic-linker -z text}}" + "%{static-pie: -static -pie --no-dynamic-linker -z text}}" \ + "%{mno-relax: --no-relax}" /* Similar to standard Linux, but adding -ffast-math support. */ diff --git a/gcc/config/loongarch/loongarch-driver.h b/gcc/config/loongarch/loongarch-driver.h index d917fca..d859afc 100644 --- a/gcc/config/loongarch/loongarch-driver.h +++ b/gcc/config/loongarch/loongarch-driver.h @@ -53,7 +53,7 @@ along with GCC; see the file COPYING3. If not see #undef ASM_SPEC #define ASM_SPEC \ - "%{mabi=*} %(subtarget_asm_spec)" + "%{mabi=*} %{mno-relax} %(subtarget_asm_spec)" extern const char* diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h index 3c6ff2e..2756939 100644 --- a/gcc/config/loongarch/loongarch-opts.h +++ b/gcc/config/loongarch/loongarch-opts.h @@ -97,4 +97,8 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target, #define HAVE_AS_EXPLICIT_RELOCS 0 #endif +#ifndef HAVE_AS_MRELAX_OPTION +#define HAVE_AS_MRELAX_OPTION 0 +#endif + #endif /* LOONGARCH_OPTS_H */ diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt index b06b58b..e1b085a 100644 --- a/gcc/config/loongarch/loongarch.opt +++ b/gcc/config/loongarch/loongarch.opt @@ -182,7 +182,7 @@ Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init -mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024. mexplicit-relocs -Target Var(TARGET_EXPLICIT_RELOCS) Init(HAVE_AS_EXPLICIT_RELOCS) +Target Var(TARGET_EXPLICIT_RELOCS) Init(HAVE_AS_EXPLICIT_RELOCS & !HAVE_AS_MRELAX_OPTION) Use %reloc() assembly operators. ; The code model option names for -mcmodel. @@ -215,3 +215,8 @@ Specify the code model. mdirect-extern-access Target Var(TARGET_DIRECT_EXTERN_ACCESS) Init(0) Avoid using the GOT to access external symbols. + +mrelax +Target Var(loongarch_mrelax) Init(HAVE_AS_MRELAX_OPTION) +Take advantage of linker relaxations to reduce the number of instructions +required to materialize symbol addresses. diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index b47bae1..a97a095 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@ -59,264 +59,6 @@ ) ;; ------------------------------------------------------------------------- -;; ---- [BOOL] Binary logical operations (inverted second input) -;; ------------------------------------------------------------------------- -;; Includes: -;; - vmandnot.mm -;; - vmornot.mm -;; ------------------------------------------------------------------------- - -(define_insn_and_split "*<optab>not<mode>" - [(set (match_operand:VB_VLS 0 "register_operand" "=vr") - (bitmanip_bitwise:VB_VLS - (not:VB_VLS (match_operand:VB_VLS 2 "register_operand" " vr")) - (match_operand:VB_VLS 1 "register_operand" " vr")))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - insn_code icode = code_for_pred_not (<CODE>, <MODE>mode); - riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_MASK_OP, operands); - DONE; - } - [(set_attr "type" "vmalu") - (set_attr "mode" "<MODE>")]) - -;; ------------------------------------------------------------------------- -;; ---- [BOOL] Binary logical operations (inverted result) -;; ------------------------------------------------------------------------- -;; Includes: -;; - vmnand.mm -;; - vmnor.mm -;; - vmxnor.mm -;; ------------------------------------------------------------------------- - -(define_insn_and_split "*n<optab><mode>" - [(set (match_operand:VB_VLS 0 "register_operand" "=vr") - (not:VB_VLS - (any_bitwise:VB_VLS - (match_operand:VB_VLS 1 "register_operand" " vr") - (match_operand:VB_VLS 2 "register_operand" " vr"))))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - insn_code icode = code_for_pred_n (<CODE>, <MODE>mode); - riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_MASK_OP, operands); - DONE; - } - [(set_attr "type" "vmalu") - (set_attr "mode" "<MODE>")]) - -;; ========================================================================= -;; == Widening Ternary arithmetic -;; ========================================================================= - -;; ------------------------------------------------------------------------- -;; ---- [INT] VWMACC -;; ------------------------------------------------------------------------- -;; Includes: -;; - vwmacc.vv -;; - vwmaccu.vv -;; ------------------------------------------------------------------------- - -;; Combine ext + ext + fma ===> widen fma. -;; Most of circumstantces, LoopVectorizer will generate the following IR: -;; vect__8.64_40 = (vector([4,4]) int) vect__7.63_41; -;; vect__11.68_35 = (vector([4,4]) int) vect__10.67_36; -;; vect__13.70_33 = .FMA (vect__11.68_35, vect__8.64_40, vect__4.60_45); -(define_insn_and_split "*<optab>_fma<mode>" - [(set (match_operand:VWEXTI 0 "register_operand") - (plus:VWEXTI - (mult:VWEXTI - (any_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (any_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) - (match_operand:VWEXTI 1 "register_operand")))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plus (<CODE>, <MODE>mode), - riscv_vector::WIDEN_TERNARY_OP, operands); - DONE; - } - [(set_attr "type" "viwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>")]) - -;; This helps to match ext + fma. -(define_insn_and_split "*single_<optab>mult_plus<mode>" - [(set (match_operand:VWEXTI 0 "register_operand") - (plus:VWEXTI - (mult:VWEXTI - (any_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (match_operand:VWEXTI 3 "register_operand")) - (match_operand:VWEXTI 1 "register_operand")))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - insn_code icode = code_for_pred_vf2 (<CODE>, <MODE>mode); - rtx tmp = gen_reg_rtx (<MODE>mode); - rtx ext_ops[] = {tmp, operands[2]}; - riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); - - rtx dst = expand_ternary_op (<MODE>mode, fma_optab, tmp, operands[3], - operands[1], operands[0], 0); - emit_move_insn (operands[0], dst); - DONE; - } - [(set_attr "type" "viwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>")]) - -;; Combine ext + ext + mult + plus ===> widen fma. -;; We have some special cases generated by LoopVectorizer: -;; vect__8.18_46 = (vector([8,8]) signed short) vect__7.17_47; -;; vect__11.22_41 = (vector([8,8]) signed short) vect__10.21_42; -;; vect__12.23_40 = vect__11.22_41 * vect__8.18_46; -;; vect__14.25_38 = vect__13.24_39 + vect__5.14_51; -;; This situation doesn't generate FMA IR. -(define_insn_and_split "*double_<optab>mult_plus<mode>" - [(set (match_operand:VWEXTI 0 "register_operand") - (if_then_else:VWEXTI - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand") - (match_operand 6 "vector_length_operand") - (match_operand 7 "const_int_operand") - (match_operand 8 "const_int_operand") - (match_operand 9 "const_int_operand") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VWEXTI - (if_then_else:VWEXTI - (unspec:<VM> - [(match_dup 1) - (match_dup 6) - (match_dup 7) - (match_dup 8) - (match_dup 9) - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (mult:VWEXTI - (any_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand")) - (any_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 5 "register_operand"))) - (match_operand:VWEXTI 2 "vector_undef_operand")) - (match_operand:VWEXTI 3 "register_operand")) - (match_dup 2)))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - emit_insn (gen_pred_widen_mul_plus (<CODE>, <MODE>mode, operands[0], - operands[1], operands[3], operands[4], - operands[5], operands[6], operands[7], - operands[8], operands[9])); - DONE; - } - [(set_attr "type" "viwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>")]) - -;; Combine sign_extend + zero_extend + fma ===> widen fma (su). -(define_insn_and_split "*sign_zero_extend_fma" - [(set (match_operand:VWEXTI 0 "register_operand") - (plus:VWEXTI - (mult:VWEXTI - (sign_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (zero_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) - (match_operand:VWEXTI 1 "register_operand")))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu (<MODE>mode), - riscv_vector::WIDEN_TERNARY_OP, operands); - DONE; - } - [(set_attr "type" "viwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>")]) - -;; This helps to match zero_extend + sign_extend + fma. -(define_insn_and_split "*zero_sign_extend_fma" - [(set (match_operand:VWEXTI 0 "register_operand") - (plus:VWEXTI - (mult:VWEXTI - (zero_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (sign_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) - (match_operand:VWEXTI 1 "register_operand")))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - rtx ops[] = {operands[0], operands[1], operands[3], operands[2]}; - riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu (<MODE>mode), - riscv_vector::WIDEN_TERNARY_OP, ops); - DONE; - } - [(set_attr "type" "viwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>")]) - -;; ------------------------------------------------------------------------- -;; ---- [INT] Binary narrow shifts. -;; ------------------------------------------------------------------------- -;; Includes: -;; - vnsrl.wv/vnsrl.wx/vnsrl.wi -;; - vnsra.wv/vnsra.wx/vnsra.wi -;; ------------------------------------------------------------------------- - -(define_insn_and_split "*v<any_shiftrt:optab><any_extend:optab>trunc<mode>" - [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vr,vr") - (truncate:<V_DOUBLE_TRUNC> - (any_shiftrt:VWEXTI - (match_operand:VWEXTI 1 "register_operand" " vr,vr") - (any_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 2 "vector_shift_operand" " vr,vk")))))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] -{ - insn_code icode = code_for_pred_narrow (<any_shiftrt:CODE>, <MODE>mode); - riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands); - DONE; -} - [(set_attr "type" "vnshift") - (set_attr "mode" "<V_DOUBLE_TRUNC>")]) - -(define_insn_and_split "*<any_shiftrt:optab>trunc<mode>" - [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vr") - (truncate:<V_DOUBLE_TRUNC> - (any_shiftrt:VWEXTI - (match_operand:VWEXTI 1 "register_operand" " vr") - (match_operand:<VEL> 2 "csr_operand" " rK"))))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] -{ - operands[2] = gen_lowpart (Pmode, operands[2]); - insn_code icode = code_for_pred_narrow_scalar (<any_shiftrt:CODE>, <MODE>mode); - riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands); - DONE; -} - [(set_attr "type" "vnshift") - (set_attr "mode" "<V_DOUBLE_TRUNC>")]) - -;; ------------------------------------------------------------------------- ;; ---- Sign-extension for vmv.x.s. ;; ------------------------------------------------------------------------- (define_insn "*pred_extract_first_sextdi<mode>" @@ -345,269 +87,9 @@ [(set_attr "type" "vimovvx") (set_attr "mode" "<MODE>")]) -;; ------------------------------------------------------------------------- -;; ---- [FP] VFWMACC -;; ------------------------------------------------------------------------- -;; Includes: -;; - vfwmacc.vv -;; ------------------------------------------------------------------------- - -;; Combine ext + ext + fma ===> widen fma. -;; Most of circumstantces, LoopVectorizer will generate the following IR: -;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41; -;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36; -;; vect__13.182_33 = .FMA (vect__11.180_35, vect__8.176_40, vect__4.172_45); -(define_insn_and_split "*double_widen_fma<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")) - (match_operand:VWEXTF 1 "register_operand")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (PLUS, <MODE>mode), - riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -;; This helps to match ext + fma. -(define_insn_and_split "*single_widen_fma<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (match_operand:VWEXTF 3 "register_operand") - (match_operand:VWEXTF 1 "register_operand")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - insn_code icode = code_for_pred_extend (<MODE>mode); - rtx tmp = gen_reg_rtx (<MODE>mode); - rtx ext_ops[] = {tmp, operands[2]}; - riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); - - rtx dst = expand_ternary_op (<MODE>mode, fma_optab, tmp, operands[3], - operands[1], operands[0], 0); - emit_move_insn (operands[0], dst); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -;; ------------------------------------------------------------------------- -;; ---- [FP] VFWNMSAC -;; ------------------------------------------------------------------------- -;; Includes: -;; - vfwnmsac.vv -;; ------------------------------------------------------------------------- - -;; Combine ext + ext + fnma ===> widen fnma. -;; Most of circumstantces, LoopVectorizer will generate the following IR: -;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41; -;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36; -;; vect__13.182_33 = .FNMA (vect__11.180_35, vect__8.176_40, vect__4.172_45); -(define_insn_and_split "*double_widen_fnma<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (neg:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")) - (match_operand:VWEXTF 1 "register_operand")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg (PLUS, <MODE>mode), - riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -;; This helps to match ext + fnma. -(define_insn_and_split "*single_widen_fnma<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (neg:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) - (match_operand:VWEXTF 3 "register_operand") - (match_operand:VWEXTF 1 "register_operand")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - insn_code icode = code_for_pred_extend (<MODE>mode); - rtx tmp = gen_reg_rtx (<MODE>mode); - rtx ext_ops[] = {tmp, operands[2]}; - riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); - - rtx dst = expand_ternary_op (<MODE>mode, fnma_optab, tmp, operands[3], - operands[1], operands[0], 0); - emit_move_insn (operands[0], dst); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -;; ------------------------------------------------------------------------- -;; ---- [FP] VFWMSAC -;; ------------------------------------------------------------------------- -;; Includes: -;; - vfwmsac.vv -;; ------------------------------------------------------------------------- - -;; Combine ext + ext + fms ===> widen fms. -;; Most of circumstantces, LoopVectorizer will generate the following IR: -;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41; -;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36; -;; vect__13.182_33 = .FMS (vect__11.180_35, vect__8.176_40, vect__4.172_45); -(define_insn_and_split "*double_widen_fms<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")) - (neg:VWEXTF - (match_operand:VWEXTF 1 "register_operand"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (MINUS, <MODE>mode), - riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -;; This helps to match ext + fms. -(define_insn_and_split "*single_widen_fms<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) - (match_operand:VWEXTF 3 "register_operand") - (neg:VWEXTF - (match_operand:VWEXTF 1 "register_operand"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - insn_code icode = code_for_pred_extend (<MODE>mode); - rtx tmp = gen_reg_rtx (<MODE>mode); - rtx ext_ops[] = {tmp, operands[2]}; - riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); - - rtx dst = expand_ternary_op (<MODE>mode, fms_optab, tmp, operands[3], - operands[1], operands[0], 0); - emit_move_insn (operands[0], dst); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -;; ------------------------------------------------------------------------- -;; ---- [FP] VFWNMACC -;; ------------------------------------------------------------------------- -;; Includes: -;; - vfwnmacc.vv -;; ------------------------------------------------------------------------- - -;; Combine ext + ext + fnms ===> widen fnms. -;; Most of circumstantces, LoopVectorizer will generate the following IR: -;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41; -;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36; -;; vect__13.182_33 = .FNMS (vect__11.180_35, vect__8.176_40, vect__4.172_45); -(define_insn_and_split "*double_widen_fnms<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (neg:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")) - (neg:VWEXTF - (match_operand:VWEXTF 1 "register_operand"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg (MINUS, <MODE>mode), - riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -;; This helps to match ext + fnms. -(define_insn_and_split "*single_widen_fnms<mode>" - [(set (match_operand:VWEXTF 0 "register_operand") - (unspec:VWEXTF - [(fma:VWEXTF - (neg:VWEXTF - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) - (match_operand:VWEXTF 3 "register_operand") - (neg:VWEXTF - (match_operand:VWEXTF 1 "register_operand"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - insn_code icode = code_for_pred_extend (<MODE>mode); - rtx tmp = gen_reg_rtx (<MODE>mode); - rtx ext_ops[] = {tmp, operands[2]}; - riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); - - rtx dst = expand_ternary_op (<MODE>mode, fnms_optab, tmp, operands[3], - operands[1], operands[0], 0); - emit_move_insn (operands[0], dst); - DONE; - } - [(set_attr "type" "vfwmuladd") - (set_attr "mode" "<V_DOUBLE_TRUNC>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) +;; ============================================================================= +;; All combine patterns for combine pass. +;; ============================================================================= ;; ============================================================================= ;; Combine op + vmerge to cond_op @@ -995,6 +477,48 @@ [(set_attr "type" "vector")]) ;; ============================================================================= +;; Combine binop + trunc to narrow_binop +;; ============================================================================= + +;; Combine vsr[la].vv + trunc to vnsr[la].wv +(define_insn_and_split "*narrow_<any_shiftrt:optab><any_extend:optab><mode>" + [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vr,vr") + (truncate:<V_DOUBLE_TRUNC> + (any_shiftrt:VWEXTI + (match_operand:VWEXTI 1 "register_operand" " vr,vr") + (any_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 2 "vector_shift_operand" " vr,vk")))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] +{ + insn_code icode = code_for_pred_narrow (<any_shiftrt:CODE>, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands); + DONE; +} + [(set_attr "type" "vnshift")]) + +;; Combine vsr[la].w[xi] + trunc to vnsr[la].w[xi] +(define_insn_and_split "*narrow_<any_shiftrt:optab><mode>_scalar" + [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vr") + (truncate:<V_DOUBLE_TRUNC> + (any_shiftrt:VWEXTI + (match_operand:VWEXTI 1 "register_operand" " vr") + (match_operand:<VEL> 2 "csr_operand" " rK"))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] +{ + operands[2] = gen_lowpart (Pmode, operands[2]); + insn_code icode = code_for_pred_narrow_scalar (<any_shiftrt:CODE>, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands); + DONE; +} + [(set_attr "type" "vnshift")]) + +;; ============================================================================= ;; Combine extend + binop to widen_binop ;; ============================================================================= @@ -1058,7 +582,7 @@ ;; i.e. there is no vwmul.wv instruction. This is a temporary pattern ;; produced by a combine pass and if there is no further combine into ;; vwmul.vv pattern, then fall back to extend pattern and vmul.vv pattern. -(define_insn_and_split "*single_widen_mult<any_extend:su><mode>" +(define_insn_and_split "*single_widen_mul<any_extend:su><mode>" [(set (match_operand:VWEXTI 0 "register_operand") (mult:VWEXTI (any_extend:VWEXTI @@ -1173,7 +697,7 @@ ;; i.e. there is no vfwmul.wv instruction. This is a temporary pattern ;; produced by a combine pass and if there is no further combine into ;; vfwmul.vv pattern, then fall back to extend pattern and vfmul.vv pattern. -(define_insn_and_split "*single_widen_mult<mode>" +(define_insn_and_split "*single_widen_mul<mode>" [(set (match_operand:VWEXTF 0 "register_operand") (mult:VWEXTF (float_extend:VWEXTF @@ -1197,7 +721,7 @@ [(set_attr "type" "vfwmul")]) ;; Combine extend + vredsum to vwredsum[u] -(define_insn_and_split "*reduc_plus_scal_<mode>" +(define_insn_and_split "*widen_reduc_plus_scal_<mode>" [(set (match_operand:<V_DOUBLE_EXTEND_VEL> 0 "register_operand") (unspec:<V_DOUBLE_EXTEND_VEL> [ (any_extend:<V_DOUBLE_EXTEND> @@ -1216,7 +740,7 @@ [(set_attr "type" "vector")]) ;; Combine extend + vfredusum to vfwredusum -(define_insn_and_split "*reduc_plus_scal_<mode>" +(define_insn_and_split "*widen_reduc_plus_scal_<mode>" [(set (match_operand:<V_DOUBLE_EXTEND_VEL> 0 "register_operand") (unspec:<V_DOUBLE_EXTEND_VEL> [ (float_extend:<V_DOUBLE_EXTEND> @@ -1285,10 +809,321 @@ [(set_attr "type" "vector")]) ;; ============================================================================= +;; Combine extend + ternop to widen_ternop +;; ============================================================================= + +;; Combine ext + fma(vmacc,vmadd) to widen_fma (vwmacc[u]) +(define_insn_and_split "*dual_widen_fma<su><mode>" + [(set (match_operand:VWEXTI 0 "register_operand") + (plus:VWEXTI + (mult:VWEXTI + (any_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (any_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) + (match_operand:VWEXTI 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plus (<CODE>, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP, ops); + DONE; + } + [(set_attr "type" "viwmuladd")]) + +;; Combine sign_extend + zero_extend + fma to widen_fma (vwmaccsu) +(define_insn_and_split "*dual_widen_fmasu<mode>" + [(set (match_operand:VWEXTI 0 "register_operand") + (plus:VWEXTI + (mult:VWEXTI + (sign_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (zero_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) + (match_operand:VWEXTI 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu (<MODE>mode), + riscv_vector::WIDEN_TERNARY_OP, ops); + DONE; + } + [(set_attr "type" "viwmuladd")]) + +;; Combine zero_extend + sign_extend + fma to widen_fma (vwmaccsu) +(define_insn_and_split "*dual_widen_fmaus<mode>" + [(set (match_operand:VWEXTI 0 "register_operand") + (plus:VWEXTI + (mult:VWEXTI + (zero_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")) + (sign_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) + (match_operand:VWEXTI 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu (<MODE>mode), + riscv_vector::WIDEN_TERNARY_OP, ops); + DONE; + } + [(set_attr "type" "viwmuladd")]) + +;; This combine pattern does not correspond to an single instruction. +;; This is a temporary pattern produced by a combine pass and if there +;; is no further combine into widen pattern, then fall back to extend +;; pattern and non-widen fma pattern. +(define_insn_and_split "*single_widen_fma<su><mode>" + [(set (match_operand:VWEXTI 0 "register_operand") + (plus:VWEXTI + (mult:VWEXTI + (any_extend:VWEXTI + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (match_operand:VWEXTI 3 "register_operand")) + (match_operand:VWEXTI 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code extend_icode = code_for_pred_vf2 (<CODE>, <MODE>mode); + rtx tmp = gen_reg_rtx (<MODE>mode); + rtx extend_ops[] = {tmp, operands[2]}; + riscv_vector::emit_vlmax_insn (extend_icode, riscv_vector::UNARY_OP, + extend_ops); + + rtx ops[] = {operands[0], tmp, operands[3], operands[1], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_plus (<MODE>mode), + riscv_vector::TERNARY_OP, ops); + DONE; + } + [(set_attr "type" "viwmuladd")]) + +;; Combine extend + fma to widen_fma (vfwmacc) +(define_insn_and_split "*dual_widen_fma<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (plus:VWEXTF + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (PLUS, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; This combine pattern does not correspond to an single instruction. +;; This is a temporary pattern produced by a combine pass and if there +;; is no further combine into widen pattern, then fall back to extend +;; pattern and non-widen fma pattern. +(define_insn_and_split "*single_widen_fma<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (plus:VWEXTF + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (match_operand:VWEXTF 3 "register_operand")) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code icode = code_for_pred_extend (<MODE>mode); + rtx tmp = gen_reg_rtx (<MODE>mode); + rtx ext_ops[] = {tmp, operands[2]}; + riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); + + rtx ops[] = {operands[0], tmp, operands[3], operands[1], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul (PLUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; Combine extend + fnma to widen_fnma (vfwnmsac) +(define_insn_and_split "*dual_widen_fnma<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (match_operand:VWEXTF 1 "register_operand") + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg (PLUS, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; This combine pattern does not correspond to an single instruction. +;; This is a temporary pattern produced by a combine pass and if there +;; is no further combine into widen pattern, then fall back to extend +;; pattern and non-widen fnma pattern. +(define_insn_and_split "*single_widen_fnma<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (match_operand:VWEXTF 1 "register_operand") + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (match_operand:VWEXTF 3 "register_operand"))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code icode = code_for_pred_extend (<MODE>mode); + rtx tmp = gen_reg_rtx (<MODE>mode); + rtx ext_ops[] = {tmp, operands[2]}; + riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); + + rtx ops[] = {operands[0], tmp, operands[3], operands[1], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (PLUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; Combine extend + fms to widen_fms (vfwmsac) +(define_insn_and_split "*dual_widen_fms<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (MINUS, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; This combine pattern does not correspond to an single instruction. +;; This is a temporary pattern produced by a combine pass and if there +;; is no further combine into widen pattern, then fall back to extend +;; pattern and non-widen fms pattern. +(define_insn_and_split "*single_widen_fms<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")) + (match_operand:VWEXTF 3 "register_operand")) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code icode = code_for_pred_extend (<MODE>mode); + rtx tmp = gen_reg_rtx (<MODE>mode); + rtx ext_ops[] = {tmp, operands[2]}; + riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); + + rtx ops[] = {operands[0], tmp, operands[3], operands[1], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul (MINUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; Combine extend + fnms to widen_fnms (vfwnmacc) +(define_insn_and_split "*dual_widen_fnms<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (mult:VWEXTF + (neg:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg (MINUS, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; This combine pattern does not correspond to an single instruction. +;; This is a temporary pattern produced by a combine pass and if there +;; is no further combine into widen pattern, then fall back to extend +;; pattern and non-widen fnms pattern. +(define_insn_and_split "*single_widen_fnms<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (mult:VWEXTF + (neg:VWEXTF + (match_operand:VWEXTF 3 "register_operand")) + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code icode = code_for_pred_extend (<MODE>mode); + rtx tmp = gen_reg_rtx (<MODE>mode); + rtx ext_ops[] = {tmp, operands[2]}; + riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ext_ops); + + rtx ops[] = {operands[0], tmp, operands[3], operands[1], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (MINUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")]) + +;; ============================================================================= ;; Misc combine patterns ;; ============================================================================= -;; Combine vlmax neg and UNSPEC_VCOPYSIGN +;; Combine neg + vfsgnj to vfsgnjn (define_insn_and_split "*copysign<mode>_neg" [(set (match_operand:VF 0 "register_operand") (neg:VF @@ -1306,3 +1141,38 @@ DONE; } [(set_attr "type" "vector")]) + +;; Combine vmand/vmor + vmnot to vmandnot/vmornot +(define_insn_and_split "*<optab>not<mode>" + [(set (match_operand:VB_VLS 0 "register_operand" "=vr") + (bitmanip_bitwise:VB_VLS + (not:VB_VLS (match_operand:VB_VLS 2 "register_operand" " vr")) + (match_operand:VB_VLS 1 "register_operand" " vr")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code icode = code_for_pred_not (<CODE>, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_MASK_OP, operands); + DONE; + } + [(set_attr "type" "vmalu")]) + +;; Combine vmnot + vmand/vmor/vmxor to vmnand/vmnor/vmxnor +(define_insn_and_split "*n<optab><mode>" + [(set (match_operand:VB_VLS 0 "register_operand" "=vr") + (not:VB_VLS + (any_bitwise:VB_VLS + (match_operand:VB_VLS 1 "register_operand" " vr") + (match_operand:VB_VLS 2 "register_operand" " vr"))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code icode = code_for_pred_n (<CODE>, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_MASK_OP, operands); + DONE; + } + [(set_attr "type" "vmalu")]) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 493d574..f0f1abc 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -847,7 +847,7 @@ (define_insn_and_split "<optab><mode><vconvert>2" [(set (match_operand:<VCONVERT> 0 "register_operand") (any_fix:<VCONVERT> - (match_operand:VF 1 "register_operand")))] + (match_operand:V_VLSF 1 "register_operand")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" "&& 1" @@ -868,8 +868,8 @@ ;; ------------------------------------------------------------------------- (define_insn_and_split "<float_cvt><vconvert><mode>2" - [(set (match_operand:VF 0 "register_operand") - (any_float:VF + [(set (match_operand:V_VLSF 0 "register_operand") + (any_float:V_VLSF (match_operand:<VCONVERT> 1 "register_operand")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" @@ -916,8 +916,8 @@ ;; - vfwcvt.f.x.v ;; ------------------------------------------------------------------------- (define_insn_and_split "<float_cvt><vnconvert><mode>2" - [(set (match_operand:VF 0 "register_operand") - (any_float:VF + [(set (match_operand:V_VLSF 0 "register_operand") + (any_float:V_VLSF (match_operand:<VNCONVERT> 1 "register_operand")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" @@ -940,7 +940,7 @@ (define_insn_and_split "<optab><mode><vnconvert>2" [(set (match_operand:<VNCONVERT> 0 "register_operand") (any_fix:<VNCONVERT> - (match_operand:VF 1 "register_operand")))] + (match_operand:V_VLSF 1 "register_operand")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" "&& 1" @@ -1031,9 +1031,9 @@ ;; - vfneg.v/vfabs.v ;; ------------------------------------------------------------------------------- (define_insn_and_split "<optab><mode>2" - [(set (match_operand:VF 0 "register_operand") - (any_float_unop_nofrm:VF - (match_operand:VF 1 "register_operand")))] + [(set (match_operand:V_VLSF 0 "register_operand") + (any_float_unop_nofrm:V_VLSF + (match_operand:V_VLSF 1 "register_operand")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" "&& 1" @@ -1052,9 +1052,9 @@ ;; - vfsqrt.v ;; ------------------------------------------------------------------------------- (define_insn_and_split "<optab><mode>2" - [(set (match_operand:VF 0 "register_operand") - (any_float_unop:VF - (match_operand:VF 1 "register_operand")))] + [(set (match_operand:V_VLSF 0 "register_operand") + (any_float_unop:V_VLSF + (match_operand:V_VLSF 1 "register_operand")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" "&& 1" @@ -1078,57 +1078,25 @@ ;; - vmadd ;; ------------------------------------------------------------------------- -;; We can't expand FMA for the following reasons: -;; 1. Before RA, we don't know which multiply-add instruction is the ideal one. -;; The vmacc is the ideal instruction when operands[3] overlaps operands[0]. -;; The vmadd is the ideal instruction when operands[1|2] overlaps operands[0]. -;; 2. According to vector.md, the multiply-add patterns has 'merge' operand which -;; is the operands[5]. Since operands[5] should overlap operands[0], this operand -;; should be allocated the same regno as operands[1|2|3]. -;; 3. The 'merge' operand is always a real merge operand and we don't allow undefined -;; operand. -;; 4. The operation of FMA pattern needs VLMAX vsetlvi which needs a VL operand. -;; -;; In this situation, we design the codegen of FMA as follows: -;; 1. clobber a scratch in the expand pattern of FMA. -;; 2. Let's RA decide which input operand (operands[1|2|3]) overlap operands[0]. -;; 3. Generate instructions (vmacc or vmadd) according to the register allocation -;; result after reload_completed. -(define_expand "fma<mode>4" - [(parallel - [(set (match_operand:VI 0 "register_operand") - (plus:VI - (mult:VI - (match_operand:VI 1 "register_operand") - (match_operand:VI 2 "register_operand")) - (match_operand:VI 3 "register_operand"))) - (clobber (match_dup 4))])] - "TARGET_VECTOR" - { - operands[4] = gen_reg_rtx (Pmode); - }) - -(define_insn_and_split "*fma<VI:mode><P:mode>" - [(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr") - (plus:VI - (mult:VI - (match_operand:VI 1 "register_operand" " %0, vr, vr") - (match_operand:VI 2 "register_operand" " vr, vr, vr")) - (match_operand:VI 3 "register_operand" " vr, 0, vr"))) - (clobber (match_operand:P 4 "register_operand" "=r,r,r"))] - "TARGET_VECTOR" +(define_insn_and_split "fma<mode>4" + [(set (match_operand:V_VLSI 0 "register_operand") + (plus:V_VLSI + (mult:V_VLSI + (match_operand:V_VLSI 1 "register_operand") + (match_operand:V_VLSI 2 "register_operand")) + (match_operand:V_VLSI 3 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" "#" - "&& reload_completed" + "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]); - rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]}; - riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul_plus (<VI:MODE>mode), - riscv_vector::TERNARY_OP, ops, operands[4]); + rtx ops[] = {operands[0], operands[1], operands[2], operands[3], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_plus (<MODE>mode), + riscv_vector::TERNARY_OP, ops); DONE; } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<VI:MODE>")]) + [(set_attr "type" "vector")]) ;; ------------------------------------------------------------------------- ;; ---- [INT] VNMSAC and VNMSUB @@ -1138,41 +1106,25 @@ ;; - vnmsub ;; ------------------------------------------------------------------------- -(define_expand "fnma<mode>4" - [(parallel - [(set (match_operand:VI 0 "register_operand") - (minus:VI - (match_operand:VI 3 "register_operand") - (mult:VI - (match_operand:VI 1 "register_operand") - (match_operand:VI 2 "register_operand")))) - (clobber (match_dup 4))])] - "TARGET_VECTOR" - { - operands[4] = gen_reg_rtx (Pmode); - }) - -(define_insn_and_split "*fnma<VI:mode><P:mode>" - [(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr") - (minus:VI - (match_operand:VI 3 "register_operand" " vr, 0, vr") - (mult:VI - (match_operand:VI 1 "register_operand" " %0, vr, vr") - (match_operand:VI 2 "register_operand" " vr, vr, vr")))) - (clobber (match_operand:P 4 "register_operand" "=r,r,r"))] - "TARGET_VECTOR" +(define_insn_and_split "fnma<mode>4" + [(set (match_operand:V_VLSI 0 "register_operand") + (minus:V_VLSI + (match_operand:V_VLSI 3 "register_operand") + (mult:V_VLSI + (match_operand:V_VLSI 1 "register_operand") + (match_operand:V_VLSI 2 "register_operand"))))] + "TARGET_VECTOR && can_create_pseudo_p ()" "#" - "&& reload_completed" + "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]); - rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]}; - riscv_vector::emit_vlmax_insn_lra (code_for_pred_minus_mul (<VI:MODE>mode), - riscv_vector::TERNARY_OP, ops, operands[4]); + rtx ops[] = {operands[0], operands[1], operands[2], operands[3], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_minus_mul (<MODE>mode), + riscv_vector::TERNARY_OP, ops); DONE; } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<VI:MODE>")]) + [(set_attr "type" "vector")]) ;; ------------------------------------------------------------------------- ;; ---- [FP] VFMACC and VFMADD @@ -1182,45 +1134,25 @@ ;; - vfmadd ;; ------------------------------------------------------------------------- -(define_expand "fma<mode>4" - [(parallel - [(set (match_operand:VF 0 "register_operand") - (unspec:VF - [(fma:VF - (match_operand:VF 1 "register_operand") - (match_operand:VF 2 "register_operand") - (match_operand:VF 3 "register_operand")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_dup 4))])] - "TARGET_VECTOR" - { - operands[4] = gen_reg_rtx (Pmode); - } - [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -(define_insn_and_split "*fma<VF:mode><P:mode>" - [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr") - (unspec:VF - [(fma:VF - (match_operand:VF 1 "register_operand" " %0, vr, vr") - (match_operand:VF 2 "register_operand" " vr, vr, vr") - (match_operand:VF 3 "register_operand" " vr, 0, vr")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_operand:P 4 "register_operand" "=r,r,r"))] - "TARGET_VECTOR" +(define_insn_and_split "fma<mode>4" + [(set (match_operand:V_VLSF 0 "register_operand") + (plus:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 1 "register_operand") + (match_operand:V_VLSF 2 "register_operand")) + (match_operand:V_VLSF 3 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" "#" - "&& reload_completed" + "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]); - rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]}; - riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul (PLUS, <VF:MODE>mode), - riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]); + rtx ops[] = {operands[0], operands[1], operands[2], operands[3], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul (PLUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); DONE; } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<VF:MODE>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) + [(set_attr "type" "vector")]) ;; ------------------------------------------------------------------------- ;; ---- [FP] VFNMSAC and VFNMSUB @@ -1230,47 +1162,25 @@ ;; - vfnmsub ;; ------------------------------------------------------------------------- -(define_expand "fnma<mode>4" - [(parallel - [(set (match_operand:VF 0 "register_operand") - (unspec:VF - [(fma:VF - (neg:VF - (match_operand:VF 1 "register_operand")) - (match_operand:VF 2 "register_operand") - (match_operand:VF 3 "register_operand")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_dup 4))])] - "TARGET_VECTOR" - { - operands[4] = gen_reg_rtx (Pmode); - } - [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -(define_insn_and_split "*fnma<VF:mode><P:mode>" - [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr") - (unspec:VF - [(fma:VF - (neg:VF - (match_operand:VF 1 "register_operand" " %0, vr, vr")) - (match_operand:VF 2 "register_operand" " vr, vr, vr") - (match_operand:VF 3 "register_operand" " vr, 0, vr")) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_operand:P 4 "register_operand" "=r,r,r"))] - "TARGET_VECTOR" +(define_insn_and_split "fnma<mode>4" + [(set (match_operand:V_VLSF 0 "register_operand") + (minus:V_VLSF + (match_operand:V_VLSF 3 "register_operand") + (mult:V_VLSF + (match_operand:V_VLSF 1 "register_operand") + (match_operand:V_VLSF 2 "register_operand"))))] + "TARGET_VECTOR && can_create_pseudo_p ()" "#" - "&& reload_completed" + "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]); - rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]}; - riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul_neg (PLUS, <VF:MODE>mode), - riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]); + rtx ops[] = {operands[0], operands[1], operands[2], operands[3], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (PLUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); DONE; } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<VF:MODE>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) + [(set_attr "type" "vector")]) ;; ------------------------------------------------------------------------- ;; ---- [FP] VFMSAC and VFMSUB @@ -1280,47 +1190,25 @@ ;; - vfmsub ;; ------------------------------------------------------------------------- -(define_expand "fms<mode>4" - [(parallel - [(set (match_operand:VF 0 "register_operand") - (unspec:VF - [(fma:VF - (match_operand:VF 1 "register_operand") - (match_operand:VF 2 "register_operand") - (neg:VF - (match_operand:VF 3 "register_operand"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_dup 4))])] - "TARGET_VECTOR" - { - operands[4] = gen_reg_rtx (Pmode); - } - [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -(define_insn_and_split "*fms<VF:mode><P:mode>" - [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr") - (unspec:VF - [(fma:VF - (match_operand:VF 1 "register_operand" " %0, vr, vr") - (match_operand:VF 2 "register_operand" " vr, vr, vr") - (neg:VF - (match_operand:VF 3 "register_operand" " vr, 0, vr"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_operand:P 4 "register_operand" "=r,r,r"))] - "TARGET_VECTOR" +(define_insn_and_split "fms<mode>4" + [(set (match_operand:V_VLSF 0 "register_operand") + (minus:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 1 "register_operand") + (match_operand:V_VLSF 2 "register_operand")) + (match_operand:V_VLSF 3 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" "#" - "&& reload_completed" + "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]); - rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]}; - riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul (MINUS, <VF:MODE>mode), - riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]); + rtx ops[] = {operands[0], operands[1], operands[2], operands[3], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul (MINUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); DONE; } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<VF:MODE>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) + [(set_attr "type" "vector")]) ;; ------------------------------------------------------------------------- ;; ---- [FP] VFNMACC and VFNMADD @@ -1330,49 +1218,26 @@ ;; - vfnmadd ;; ------------------------------------------------------------------------- -(define_expand "fnms<mode>4" - [(parallel - [(set (match_operand:VF 0 "register_operand") - (unspec:VF - [(fma:VF - (neg:VF - (match_operand:VF 1 "register_operand")) - (match_operand:VF 2 "register_operand") - (neg:VF - (match_operand:VF 3 "register_operand"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_dup 4))])] - "TARGET_VECTOR" - { - operands[4] = gen_reg_rtx (Pmode); - } - [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) - -(define_insn_and_split "*fnms<VF:mode><P:mode>" - [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr") - (unspec:VF - [(fma:VF - (neg:VF - (match_operand:VF 1 "register_operand" " %0, vr, vr")) - (match_operand:VF 2 "register_operand" " vr, vr, vr") - (neg:VF - (match_operand:VF 3 "register_operand" " vr, 0, vr"))) - (reg:SI FRM_REGNUM)] UNSPEC_VFFMA)) - (clobber (match_operand:P 4 "register_operand" "=r,r,r"))] - "TARGET_VECTOR" +(define_insn_and_split "fnms<mode>4" + [(set (match_operand:V_VLSF 0 "register_operand") + (minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 1 "register_operand") + (match_operand:V_VLSF 2 "register_operand"))) + (match_operand:V_VLSF 3 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" "#" - "&& reload_completed" + "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]); - rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]}; - riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul_neg (MINUS, <VF:MODE>mode), - riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]); + rtx ops[] = {operands[0], operands[1], operands[2], operands[3], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (MINUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); DONE; } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<VF:MODE>") - (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) + [(set_attr "type" "vector")]) ;; ========================================================================= ;; == SELECT_VL @@ -1393,17 +1258,17 @@ ;; ------------------------------------------------------------------------- (define_expand "vec_set<mode>" - [(match_operand:V 0 "register_operand") + [(match_operand:V_VLS 0 "register_operand") (match_operand:<VEL> 1 "register_operand") - (match_operand 2 "nonmemory_operand")] + (match_operand 2 "nonmemory_operand")] "TARGET_VECTOR" { /* If we set the first element, emit an v(f)mv.s.[xf]. */ if (operands[2] == const0_rtx) { - rtx ops[] = {operands[0], operands[1]}; + rtx ops[] = {operands[0], operands[0], operands[1]}; riscv_vector::emit_nonvlmax_insn (code_for_pred_broadcast (<MODE>mode), - riscv_vector::SCALAR_MOVE_OP, ops, CONST1_RTX (Pmode)); + riscv_vector::SCALAR_MOVE_MERGED_OP, ops, CONST1_RTX (Pmode)); } else { @@ -1631,7 +1496,7 @@ (match_operand:<VM> 1 "vector_mask_operand") (any_int_unop:VI (match_operand:VI 2 "register_operand")) - (match_operand:VI 3 "register_operand")] + (match_operand:VI 3 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1647,7 +1512,7 @@ (match_operand:<VM> 1 "vector_mask_operand") (any_int_unop:VI (match_operand:VI 2 "register_operand")) - (match_operand:VI 3 "register_operand") + (match_operand:VI 3 "autovec_else_operand") (match_operand 4 "autovec_length_operand") (match_operand 5 "const_0_operand")] "TARGET_VECTOR" @@ -1669,7 +1534,7 @@ (match_operand:<VM> 1 "vector_mask_operand") (any_float_unop_nofrm:VF (match_operand:VF 2 "register_operand")) - (match_operand:VF 3 "register_operand")] + (match_operand:VF 3 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1685,7 +1550,7 @@ (match_operand:<VM> 1 "vector_mask_operand") (any_float_unop_nofrm:VF (match_operand:VF 2 "register_operand")) - (match_operand:VF 3 "register_operand") + (match_operand:VF 3 "autovec_else_operand") (match_operand 4 "autovec_length_operand") (match_operand 5 "const_0_operand")] "TARGET_VECTOR" @@ -1708,7 +1573,7 @@ (any_shift:VI (match_operand:VI 2 "register_operand") (match_operand:VI 3 "vector_shift_operand")) - (match_operand:VI 4 "register_operand")] + (match_operand:VI 4 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1725,7 +1590,7 @@ (any_shift:VI (match_operand:VI 2 "register_operand") (match_operand:VI 3 "vector_shift_operand")) - (match_operand:VI 4 "register_operand") + (match_operand:VI 4 "autovec_else_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand")] "TARGET_VECTOR" @@ -1749,7 +1614,7 @@ (any_int_binop_no_shift:VI (match_operand:VI 2 "<binop_rhs1_predicate>") (match_operand:VI 3 "<binop_rhs2_predicate>")) - (match_operand:VI 4 "register_operand")] + (match_operand:VI 4 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1766,7 +1631,7 @@ (any_int_binop_no_shift:VI (match_operand:VI 2 "<binop_rhs1_predicate>") (match_operand:VI 3 "<binop_rhs2_predicate>")) - (match_operand:VI 4 "register_operand") + (match_operand:VI 4 "autovec_else_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand")] "TARGET_VECTOR" @@ -1790,7 +1655,7 @@ (any_float_binop:VF (match_operand:VF 2 "register_operand") (match_operand:VF 3 "register_operand")) - (match_operand:VF 4 "register_operand")] + (match_operand:VF 4 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1807,7 +1672,7 @@ (any_float_binop:VF (match_operand:VF 2 "register_operand") (match_operand:VF 3 "register_operand")) - (match_operand:VF 4 "register_operand") + (match_operand:VF 4 "autovec_else_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand")] "TARGET_VECTOR" @@ -1829,7 +1694,7 @@ (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:VF 4 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1846,7 +1711,7 @@ (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:VF 4 "autovec_else_operand") (match_operand 5 "autovec_length_operand") (match_operand 6 "const_0_operand")] "TARGET_VECTOR" @@ -1869,7 +1734,7 @@ (match_operand:VI 2 "register_operand") (match_operand:VI 3 "register_operand") (match_operand:VI 4 "register_operand") - (match_operand:VI 5 "register_operand")] + (match_operand:VI 5 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1886,7 +1751,7 @@ (match_operand:VI 2 "register_operand") (match_operand:VI 3 "register_operand") (match_operand:VI 4 "register_operand") - (match_operand:VI 5 "register_operand") + (match_operand:VI 5 "autovec_else_operand") (match_operand 6 "autovec_length_operand") (match_operand 7 "const_0_operand")] "TARGET_VECTOR" @@ -1902,7 +1767,7 @@ (match_operand:VI 2 "register_operand") (match_operand:VI 3 "register_operand") (match_operand:VI 4 "register_operand") - (match_operand:VI 5 "register_operand")] + (match_operand:VI 5 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1919,7 +1784,7 @@ (match_operand:VI 2 "register_operand") (match_operand:VI 3 "register_operand") (match_operand:VI 4 "register_operand") - (match_operand:VI 5 "register_operand") + (match_operand:VI 5 "autovec_else_operand") (match_operand 6 "autovec_length_operand") (match_operand 7 "const_0_operand")] "TARGET_VECTOR" @@ -1942,7 +1807,7 @@ (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:VF 5 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1959,7 +1824,7 @@ (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:VF 5 "autovec_else_operand") (match_operand 6 "autovec_length_operand") (match_operand 7 "const_0_operand")] "TARGET_VECTOR" @@ -1975,7 +1840,7 @@ (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:VF 5 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -1992,7 +1857,7 @@ (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:VF 5 "autovec_else_operand") (match_operand 6 "autovec_length_operand") (match_operand 7 "const_0_operand")] "TARGET_VECTOR" @@ -2008,7 +1873,7 @@ (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:VF 5 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -2025,7 +1890,7 @@ (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:VF 5 "autovec_else_operand") (match_operand 6 "autovec_length_operand") (match_operand 7 "const_0_operand")] "TARGET_VECTOR" @@ -2041,7 +1906,7 @@ (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:VF 5 "autovec_else_operand")] "TARGET_VECTOR" { /* Normalize into cond_len_* operations. */ @@ -2058,7 +1923,7 @@ (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:VF 5 "autovec_else_operand") (match_operand 6 "autovec_length_operand") (match_operand 7 "const_0_operand")] "TARGET_VECTOR" diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 3f52bc7..964fdd4 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -45,6 +45,26 @@ (and (match_code "const_int") (match_test "ival == 0"))) +(define_constraint "c01" + "Constant value 1." + (and (match_code "const_int") + (match_test "ival == 1"))) + +(define_constraint "c02" + "Constant value 2" + (and (match_code "const_int") + (match_test "ival == 2"))) + +(define_constraint "c04" + "Constant value 4" + (and (match_code "const_int") + (match_test "ival == 4"))) + +(define_constraint "c08" + "Constant value 8" + (and (match_code "const_int") + (match_test "ival == 8"))) + (define_constraint "K" "A 5-bit unsigned immediate for CSR access instructions." (and (match_code "const_int") diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 4bc7ff2..6b72a5f 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -70,6 +70,14 @@ (and (match_code "const_int,const_wide_int,const_vector") (match_test "op == CONST1_RTX (GET_MODE (op))"))) +(define_predicate "const_1_or_2_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 || INTVAL (op) == 2"))) + +(define_predicate "const_1_or_4_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 || INTVAL (op) == 4"))) + (define_predicate "reg_or_0_operand" (ior (match_operand 0 "const_0_operand") (match_operand 0 "register_operand"))) @@ -444,6 +452,10 @@ (ior (match_operand 0 "register_operand") (match_operand 0 "vector_undef_operand"))) +(define_predicate "autovec_else_operand" + (ior (match_operand 0 "register_operand") + (match_operand 0 "scratch_operand"))) + (define_predicate "vector_arith_operand" (ior (match_operand 0 "register_operand") (and (match_code "const_vector") @@ -463,14 +475,6 @@ (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)"))) @@ -514,6 +518,24 @@ (ior (match_operand 0 "const_0_operand") (match_operand 0 "pmode_register_operand"))) +;; [1, 2, 4, 8] means strided load/store with stride == element width +(define_special_predicate "vector_eew8_stride_operand" + (ior (match_operand 0 "pmode_register_operand") + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 || INTVAL (op) == 0")))) +(define_special_predicate "vector_eew16_stride_operand" + (ior (match_operand 0 "pmode_register_operand") + (and (match_code "const_int") + (match_test "INTVAL (op) == 2 || INTVAL (op) == 0")))) +(define_special_predicate "vector_eew32_stride_operand" + (ior (match_operand 0 "pmode_register_operand") + (and (match_code "const_int") + (match_test "INTVAL (op) == 4 || INTVAL (op) == 0")))) +(define_special_predicate "vector_eew64_stride_operand" + (ior (match_operand 0 "pmode_register_operand") + (and (match_code "const_int") + (match_test "INTVAL (op) == 8 || INTVAL (op) == 0")))) + ;; A special predicate that doesn't match a particular mode. (define_special_predicate "vector_any_register_operand" (match_code "reg")) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 5a2d218..9ea0bcf 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -345,6 +345,10 @@ enum insn_type : unsigned int SCALAR_MOVE_OP = HAS_DEST_P | HAS_MASK_P | USE_ONE_TRUE_MASK_P | HAS_MERGE_P | USE_VUNDEF_MERGE_P | TDEFAULT_POLICY_P | MDEFAULT_POLICY_P | UNARY_OP_P, + + SCALAR_MOVE_MERGED_OP = HAS_DEST_P | HAS_MASK_P | USE_ONE_TRUE_MASK_P + | HAS_MERGE_P | TDEFAULT_POLICY_P | MDEFAULT_POLICY_P + | UNARY_OP_P, }; enum vlmul_type @@ -455,7 +459,7 @@ void expand_select_vl (rtx *); void expand_load_store (rtx *, bool); void expand_gather_scatter (rtx *, bool); void expand_cond_len_ternop (unsigned, rtx *); -void prepare_ternary_operands (rtx *, bool = false); +void prepare_ternary_operands (rtx *); void expand_lanes_load_store (rtx *, bool); void expand_fold_extract_last (rtx *); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index a9287e5..366f065 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2211,6 +2211,25 @@ autovectorize_vector_modes (vector_modes *modes, bool) return VECT_COMPARE_COSTS; } +/* Return true if we can find the related MODE according to default LMUL. */ +static bool +can_find_related_mode_p (machine_mode vector_mode, scalar_mode element_mode, + poly_uint64 *nunits) +{ + if (!autovec_use_vlmax_p ()) + return false; + int lmul = riscv_autovec_lmul == RVV_DYNAMIC ? RVV_M8 : riscv_autovec_lmul; + if (riscv_v_ext_vector_mode_p (vector_mode) + && multiple_p (BYTES_PER_RISCV_VECTOR * lmul, + GET_MODE_SIZE (element_mode), nunits)) + return true; + if (riscv_v_ext_vls_mode_p (vector_mode) + && multiple_p (TARGET_MIN_VLEN * lmul, GET_MODE_SIZE (element_mode), + nunits)) + return true; + return false; +} + /* If the given VECTOR_MODE is an RVV mode, first get the largest number of units that fit into a full vector at the given ELEMENT_MODE. We will have the vectorizer call us with a successively decreasing @@ -2222,10 +2241,7 @@ vectorize_related_mode (machine_mode vector_mode, scalar_mode element_mode, { /* TODO: We will support RVV VLS auto-vectorization mode in the future. */ poly_uint64 min_units; - int lmul = riscv_autovec_lmul == RVV_DYNAMIC ? RVV_M8 : riscv_autovec_lmul; - if (autovec_use_vlmax_p () && riscv_v_ext_vector_mode_p (vector_mode) - && multiple_p (BYTES_PER_RISCV_VECTOR * lmul, - GET_MODE_SIZE (element_mode), &min_units)) + if (can_find_related_mode_p (vector_mode, element_mode, &min_units)) { machine_mode rvv_mode; if (maybe_ne (nunits, 0U)) @@ -3008,6 +3024,13 @@ expand_cond_len_op (unsigned icode, insn_flags op_type, rtx *ops, rtx len) emit_nonvlmax_insn (icode, insn_flags, ops, len); } +/* Return RVV_VUNDEF if the ELSE value is scratch rtx. */ +static rtx +get_else_operand (rtx op) +{ + return GET_CODE (op) == SCRATCH ? RVV_VUNDEF (GET_MODE (op)) : op; +} + /* Expand unary ops COND_LEN_*. */ void expand_cond_len_unop (unsigned icode, rtx *ops) @@ -3015,7 +3038,7 @@ expand_cond_len_unop (unsigned icode, rtx *ops) rtx dest = ops[0]; rtx mask = ops[1]; rtx src = ops[2]; - rtx merge = ops[3]; + rtx merge = get_else_operand (ops[3]); rtx len = ops[4]; rtx cond_ops[] = {dest, mask, merge, src}; @@ -3030,7 +3053,7 @@ expand_cond_len_binop (unsigned icode, rtx *ops) rtx mask = ops[1]; rtx src1 = ops[2]; rtx src2 = ops[3]; - rtx merge = ops[4]; + rtx merge = get_else_operand (ops[4]); rtx len = ops[5]; rtx cond_ops[] = {dest, mask, merge, src1, src2}; @@ -3202,7 +3225,7 @@ expand_cond_len_ternop (unsigned icode, rtx *ops) rtx src1 = ops[2]; rtx src2 = ops[3]; rtx src3 = ops[4]; - rtx merge = ops[5]; + rtx merge = get_else_operand (ops[5]); rtx len = ops[6]; rtx cond_ops[] = {dest, mask, src1, src2, src3, merge}; @@ -3246,15 +3269,15 @@ expand_reduction (unsigned unspec, unsigned insn_flags, rtx *ops, rtx init) /* Prepare ops for ternary operations. It can be called before or after RA. */ void -prepare_ternary_operands (rtx *ops, bool split_p) +prepare_ternary_operands (rtx *ops) { machine_mode mode = GET_MODE (ops[0]); - if (split_p - || (!rtx_equal_p (ops[2], ops[5]) - && !rtx_equal_p (ops[3], ops[5]) - && !rtx_equal_p (ops[4], ops[5]) - && riscv_get_v_regno_alignment (mode) == 8)) + if (!rtx_equal_p (ops[5], RVV_VUNDEF (mode)) + && (VECTOR_MODE_P (GET_MODE (ops[2])) + && !rtx_equal_p (ops[2], ops[5])) + && !rtx_equal_p (ops[3], ops[5]) + && !rtx_equal_p (ops[4], ops[5])) { /* RA will fail to find vector REG and report ICE, so we pre-merge the ops for LMUL = 8. */ @@ -3279,6 +3302,8 @@ prepare_ternary_operands (rtx *ops, bool split_p) /* TODO: ??? Maybe we could support splitting FMA (a, 4, b) into PLUS (ASHIFT (a, 2), b) according to uarchs. */ } + gcc_assert (rtx_equal_p (ops[5], RVV_VUNDEF (mode)) + || rtx_equal_p (ops[5], ops[2]) || rtx_equal_p (ops[5], ops[4])); } /* Expand VEC_MASK_LEN_{LOAD_LANES,STORE_LANES}. */ diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 5318651..5d4dc26 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -4172,7 +4172,7 @@ builtin_decl (unsigned int code, bool) return (*registered_functions)[code]->decl; } -/* Attempt to fold STMT, given that it's a call to the SVE function +/* Attempt to fold STMT, given that it's a call to the RVV function with subcode CODE. Return the new statement on success and null on failure. Insert any other new statements at GSI. */ gimple * @@ -4192,7 +4192,7 @@ expand_builtin (unsigned int code, tree exp, rtx target) return function_expander (rfn.instance, rfn.decl, exp, target).expand (); } -/* Perform any semantic checks needed for a call to the SVE function +/* Perform any semantic checks needed for a call to the RVV function with subcode CODE, such as testing for integer constant expressions. The call occurs at location LOCATION and has NARGS arguments, given by ARGS. FNDECL is the original function decl, before diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index df980b6..e0f6114 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -1799,10 +1799,11 @@ vector_insn_info::operator== (const vector_insn_info &other) const if (m_demands[i] != other.demand_p ((enum demand_type) i)) return false; - if (vector_config_insn_p (m_insn->rtl ()) - || vector_config_insn_p (other.get_insn ()->rtl ())) - if (m_insn != other.get_insn ()) - return false; + /* We should consider different INSN demands as different + expression. Otherwise, we will be doing incorrect vsetvl + elimination. */ + if (m_insn != other.get_insn ()) + return false; if (!same_avl_p (other)) return false; diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 8c766e2..6e7a719 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-expr.h" #include "tree-vectorizer.h" #include "gcse.h" +#include "tree-dfa.h" /* This file should be included last. */ #include "target-def.h" @@ -2173,16 +2174,14 @@ riscv_legitimize_const_move (machine_mode mode, rtx dest, rtx src) (const_poly_int:DI [16, 16]) // <- op_1 )) */ - rtx src_op_0 = XEXP (src, 0); - - if (GET_CODE (src) == CONST && GET_CODE (src_op_0) == PLUS - && CONST_POLY_INT_P (XEXP (src_op_0, 1))) + if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS + && CONST_POLY_INT_P (XEXP (XEXP (src, 0), 1))) { rtx dest_tmp = gen_reg_rtx (mode); rtx tmp = gen_reg_rtx (mode); - riscv_emit_move (dest, XEXP (src_op_0, 0)); - riscv_legitimize_poly_move (mode, dest_tmp, tmp, XEXP (src_op_0, 1)); + riscv_emit_move (dest, XEXP (XEXP (src, 0), 0)); + riscv_legitimize_poly_move (mode, dest_tmp, tmp, XEXP (XEXP (src, 0), 1)); emit_insn (gen_rtx_SET (dest, gen_rtx_PLUS (mode, dest, dest_tmp))); return; @@ -2527,7 +2526,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src) machine_mode vmode = GET_MODE (SUBREG_REG (src)); unsigned int mode_size = GET_MODE_SIZE (mode).to_constant (); unsigned int vmode_size = GET_MODE_SIZE (vmode).to_constant (); - unsigned int nunits = vmode_size / mode_size; + /* We should be able to handle both partial and paradoxical subreg. */ + unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1; scalar_mode smode = as_a<scalar_mode> (mode); unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size; unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1; @@ -8536,12 +8536,26 @@ riscv_slow_unaligned_access (machine_mode, unsigned int) /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */ static bool -riscv_can_change_mode_class (machine_mode, machine_mode, reg_class_t rclass) -{ +riscv_can_change_mode_class (machine_mode from, machine_mode to, + reg_class_t rclass) +{ + /* We have RVV VLS modes and VLA modes sharing same REG_CLASS. + In 'cprop_hardreg' stage, we will try to do hard reg copy propagation + between wider mode (FROM) and narrow mode (TO). + + E.g. We should not allow copy propagation + - RVVMF8BI (precision = [16, 16]) -> V32BI (precision = [32, 0]) + since we can't order their size which will cause ICE in regcprop. + + TODO: Even though they are have different size, they always change + the whole register. We may enhance such case in regcprop to optimize + it in the future. */ + if (reg_classes_intersect_p (V_REGS, rclass) + && !ordered_p (GET_MODE_PRECISION (from), GET_MODE_PRECISION (to))) + return false; return !reg_classes_intersect_p (FP_REGS, rclass); } - /* Implement TARGET_CONSTANT_ALIGNMENT. */ static HOST_WIDE_INT @@ -9572,6 +9586,18 @@ riscv_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar) return new vector_costs (vinfo, costing_for_scalar); } +/* Implement TARGET_PREFERRED_ELSE_VALUE. */ + +static tree +riscv_preferred_else_value (unsigned ifn, tree vectype, unsigned int nops, + tree *ops) +{ + if (riscv_v_ext_mode_p (TYPE_MODE (vectype))) + return get_or_create_ssa_default_def (cfun, create_tmp_var (vectype)); + + return default_preferred_else_value (ifn, vectype, nops, ops); +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -9888,6 +9914,9 @@ riscv_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar) #undef TARGET_VECTORIZE_CREATE_COSTS #define TARGET_VECTORIZE_CREATE_COSTS riscv_vectorize_create_costs +#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/config/riscv/t-riscv b/gcc/config/riscv/t-riscv index 104f85c..f137e1f 100644 --- a/gcc/config/riscv/t-riscv +++ b/gcc/config/riscv/t-riscv @@ -8,7 +8,9 @@ riscv-builtins.o: $(srcdir)/config/riscv/riscv-builtins.cc $(CONFIG_H) \ $(DIAGNOSTIC_CORE_H) $(OPTABS_H) $(RISCV_BUILTINS_H) \ $(srcdir)/config/riscv/riscv-ftypes.def \ $(srcdir)/config/riscv/riscv-vector-builtins-types.def \ - $(srcdir)/config/riscv/riscv-modes.def + $(srcdir)/config/riscv/riscv-modes.def \ + $(srcdir)/config/riscv/riscv-cmo.def \ + $(srcdir)/config/riscv/riscv-scalar-crypto.def $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/riscv/riscv-builtins.cc diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 0b395e6..5c4b433 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -948,6 +948,40 @@ (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (V1HI "TARGET_VECTOR_VLS") + (V2HI "TARGET_VECTOR_VLS") + (V4HI "TARGET_VECTOR_VLS") + (V8HI "TARGET_VECTOR_VLS") + (V16HI "TARGET_VECTOR_VLS") + (V32HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V64HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V128HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V256HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V512HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V1024HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V2048HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096") + (V1SI "TARGET_VECTOR_VLS") + (V2SI "TARGET_VECTOR_VLS") + (V4SI "TARGET_VECTOR_VLS") + (V8SI "TARGET_VECTOR_VLS") + (V16SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V32SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V64SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V128SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V256SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V512SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V1024SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096") + (V1DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V2DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V4DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V8DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 64") + (V16DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (V32DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 256") + (V64DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 512") + (V128DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 1024") + (V256DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 2048") + (V512DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096") ]) ;; Same iterator split reason as VF_ZVFHMIN and VF. @@ -960,6 +994,28 @@ (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") + + (V1SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (V2SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (V4SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (V8SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32") + (V16SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") + (V32SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + (V64SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 256") + (V128SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 512") + (V256SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 1024") + (V512SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 2048") + (V1024SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 4096") + (V1DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V2DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V4DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V8DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 64") + (V16DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (V32DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 256") + (V64DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 512") + (V128DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 1024") + (V256DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 2048") + (V512DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096") ]) (define_mode_iterator VWEXTF [ @@ -981,6 +1037,28 @@ (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") + + (V1SI "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V2SI "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V4SI "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V8SI "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V16SI "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 64") + (V32SI "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 128") + (V64SI "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 256") + (V128SI "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 512") + (V256SI "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 1024") + (V512SI "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 2048") + (V1024SI "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 4096") + (V1DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") + (V2DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") + (V4DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32") + (V8DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") + (V16DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + (V32DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 256") + (V64DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 512") + (V128DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 1024") + (V256DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 2048") + (V512DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 4096") ]) (define_mode_iterator VQEXTI [ @@ -988,16 +1066,60 @@ (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (V1SI "TARGET_VECTOR_VLS") + (V2SI "TARGET_VECTOR_VLS") + (V4SI "TARGET_VECTOR_VLS") + (V8SI "TARGET_VECTOR_VLS") + (V16SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V32SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V64SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V128SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V256SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V512SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V1024SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096") + (V1DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V2DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V4DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V8DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 64") + (V16DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (V32DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 256") + (V64DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 512") + (V128DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 1024") + (V256DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 2048") + (V512DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096") ]) (define_mode_iterator VQEXTF [ (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") + + (V1DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V2DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V4DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V8DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 64") + (V16DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (V32DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 256") + (V64DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 512") + (V128DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 1024") + (V256DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 2048") + (V512DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096") ]) (define_mode_iterator VOEXTI [ (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + + (V1DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V2DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V4DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V8DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 64") + (V16DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (V32DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 256") + (V64DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 512") + (V128DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 1024") + (V256DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 2048") + (V512DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096") ]) (define_mode_iterator VT [ @@ -2242,6 +2364,61 @@ (RVVM8DI "RVVM4SI") (RVVM4DI "RVVM2SI") (RVVM2DI "RVVM1SI") (RVVM1DI "RVVMF2SI") (RVVM8DF "RVVM4SF") (RVVM4DF "RVVM2SF") (RVVM2DF "RVVM1SF") (RVVM1DF "RVVMF2SF") + + (V1HI "V1QI") + (V2HI "V2QI") + (V4HI "V4QI") + (V8HI "V8QI") + (V16HI "V16QI") + (V32HI "V32QI") + (V64HI "V64QI") + (V128HI "V128QI") + (V256HI "V256QI") + (V512HI "V512QI") + (V1024HI "V1024QI") + (V2048HI "V2048QI") + (V1SI "V1HI") + (V2SI "V2HI") + (V4SI "V4HI") + (V8SI "V8HI") + (V16SI "V16HI") + (V32SI "V32HI") + (V64SI "V64HI") + (V128SI "V128HI") + (V256SI "V256HI") + (V512SI "V512HI") + (V1024SI "V1024HI") + (V1DI "V1SI") + (V2DI "V2SI") + (V4DI "V4SI") + (V8DI "V8SI") + (V16DI "V16SI") + (V32DI "V32SI") + (V64DI "V64SI") + (V128DI "V128SI") + (V256DI "V256SI") + (V512DI "V512SI") + (V1SF "V1HF") + (V2SF "V2HF") + (V4SF "V4HF") + (V8SF "V8HF") + (V16SF "V16HF") + (V32SF "V32HF") + (V64SF "V64HF") + (V128SF "V128HF") + (V256SF "V256HF") + (V512SF "V512HF") + (V1024SF "V1024HF") + (V1DF "V1SF") + (V2DF "V2SF") + (V4DF "V4SF") + (V8DF "V8SF") + (V16DF "V16SF") + (V32DF "V32SF") + (V64DF "V64SF") + (V128DF "V128SF") + (V256DF "V256SF") + (V512DF "V512SF") ]) (define_mode_attr V_QUAD_TRUNC [ @@ -2250,10 +2427,53 @@ (RVVM8DI "RVVM2HI") (RVVM4DI "RVVM1HI") (RVVM2DI "RVVMF2HI") (RVVM1DI "RVVMF4HI") (RVVM8DF "RVVM2HF") (RVVM4DF "RVVM1HF") (RVVM2DF "RVVMF2HF") (RVVM1DF "RVVMF4HF") + + (V1SI "V1QI") + (V2SI "V2QI") + (V4SI "V4QI") + (V8SI "V8QI") + (V16SI "V16QI") + (V32SI "V32QI") + (V64SI "V64QI") + (V128SI "V128QI") + (V256SI "V256QI") + (V512SI "V512QI") + (V1024SI "V1024QI") + (V1DI "V1HI") + (V2DI "V2HI") + (V4DI "V4HI") + (V8DI "V8HI") + (V16DI "V16HI") + (V32DI "V32HI") + (V64DI "V64HI") + (V128DI "V128HI") + (V256DI "V256HI") + (V512DI "V512HI") + (V1DF "V1HF") + (V2DF "V2HF") + (V4DF "V4HF") + (V8DF "V8HF") + (V16DF "V16HF") + (V32DF "V32HF") + (V64DF "V64HF") + (V128DF "V128HF") + (V256DF "V256HF") + (V512DF "V512HF") ]) (define_mode_attr V_OCT_TRUNC [ (RVVM8DI "RVVM1QI") (RVVM4DI "RVVMF2QI") (RVVM2DI "RVVMF4QI") (RVVM1DI "RVVMF8QI") + + (V1DI "V1QI") + (V2DI "V2QI") + (V4DI "V4QI") + (V8DI "V8QI") + (V16DI "V16QI") + (V32DI "V32QI") + (V64DI "V64QI") + (V128DI "V128QI") + (V256DI "V256QI") + (V512DI "V512QI") ]) ; Again in lower case. @@ -2267,6 +2487,61 @@ (RVVM8DI "rvvm4si") (RVVM4DI "rvvm2si") (RVVM2DI "rvvm1si") (RVVM1DI "rvvmf2si") (RVVM8DF "rvvm4sf") (RVVM4DF "rvvm2sf") (RVVM2DF "rvvm1sf") (RVVM1DF "rvvmf2sf") + + (V1HI "v1qi") + (V2HI "v2qi") + (V4HI "v4qi") + (V8HI "v8qi") + (V16HI "v16qi") + (V32HI "v32qi") + (V64HI "v64qi") + (V128HI "v128qi") + (V256HI "v256qi") + (V512HI "v512qi") + (V1024HI "v1024qi") + (V2048HI "v2048qi") + (V1SI "v1hi") + (V2SI "v2hi") + (V4SI "v4hi") + (V8SI "v8hi") + (V16SI "v16hi") + (V32SI "v32hi") + (V64SI "v64hi") + (V128SI "v128hi") + (V256SI "v256hi") + (V512SI "v512hi") + (V1024SI "v1024hi") + (V1DI "v1si") + (V2DI "v2si") + (V4DI "v4si") + (V8DI "v8si") + (V16DI "v16si") + (V32DI "v32si") + (V64DI "v64si") + (V128DI "v128si") + (V256DI "v256si") + (V512DI "v512si") + (V1SF "v1hf") + (V2SF "v2hf") + (V4SF "v4hf") + (V8SF "v8hf") + (V16SF "v16hf") + (V32SF "v32hf") + (V64SF "v64hf") + (V128SF "v128hf") + (V256SF "v256hf") + (V512SF "v512hf") + (V1024SF "v1024hf") + (V1DF "v1sf") + (V2DF "v2sf") + (V4DF "v4sf") + (V8DF "v8sf") + (V16DF "v16sf") + (V32DF "v32sf") + (V64DF "v64sf") + (V128DF "v128sf") + (V256DF "v256sf") + (V512DF "v512sf") ]) (define_mode_attr v_quad_trunc [ @@ -2275,10 +2550,53 @@ (RVVM8DI "rvvm2hi") (RVVM4DI "rvvm1hi") (RVVM2DI "rvvmf2hi") (RVVM1DI "rvvmf4hi") (RVVM8DF "rvvm2hf") (RVVM4DF "rvvm1hf") (RVVM2DF "rvvmf2hf") (RVVM1DF "rvvmf4hf") + + (V1SI "v1qi") + (V2SI "v2qi") + (V4SI "v4qi") + (V8SI "v8qi") + (V16SI "v16qi") + (V32SI "v32qi") + (V64SI "v64qi") + (V128SI "v128qi") + (V256SI "v256qi") + (V512SI "v512qi") + (V1024SI "v1024qi") + (V1DI "v1hi") + (V2DI "v2hi") + (V4DI "v4hi") + (V8DI "v8hi") + (V16DI "v16hi") + (V32DI "v32hi") + (V64DI "v64hi") + (V128DI "v128hi") + (V256DI "v256hi") + (V512DI "v512hi") + (V1DF "v1hf") + (V2DF "v2hf") + (V4DF "v4hf") + (V8DF "v8hf") + (V16DF "v16hf") + (V32DF "v32hf") + (V64DF "v64hf") + (V128DF "v128hf") + (V256DF "v256hf") + (V512DF "v512hf") ]) (define_mode_attr v_oct_trunc [ (RVVM8DI "rvvm1qi") (RVVM4DI "rvvmf2qi") (RVVM2DI "rvvmf4qi") (RVVM1DI "rvvmf8qi") + + (V1DI "v1qi") + (V2DI "v2qi") + (V4DI "v4qi") + (V8DI "v8qi") + (V16DI "v16qi") + (V32DI "v32qi") + (V64DI "v64qi") + (V128DI "v128qi") + (V256DI "v256qi") + (V512DI "v512qi") ]) (define_mode_attr VINDEX_DOUBLE_TRUNC [ @@ -2339,12 +2657,80 @@ (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") + + (V1HF "V1HI") + (V2HF "V2HI") + (V4HF "V4HI") + (V8HF "V8HI") + (V16HF "V16HI") + (V32HF "V32HI") + (V64HF "V64HI") + (V128HF "V128HI") + (V256HF "V256HI") + (V512HF "V512HI") + (V1024HF "V1024HI") + (V2048HF "V2048HI") + (V1SF "V1SI") + (V2SF "V2SI") + (V4SF "V4SI") + (V8SF "V8SI") + (V16SF "V16SI") + (V32SF "V32SI") + (V64SF "V64SI") + (V128SF "V128SI") + (V256SF "V256SI") + (V512SF "V512SI") + (V1024SF "V1024SI") + (V1DF "V1DI") + (V2DF "V2DI") + (V4DF "V4DI") + (V8DF "V8DI") + (V16DF "V16DI") + (V32DF "V32DI") + (V64DF "V64DI") + (V128DF "V128DI") + (V256DF "V256DI") + (V512DF "V512DI") ]) (define_mode_attr vconvert [ (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") + + (V1HF "v1hi") + (V2HF "v2hi") + (V4HF "v4hi") + (V8HF "v8hi") + (V16HF "v16hi") + (V32HF "v32hi") + (V64HF "v64hi") + (V128HF "v128hi") + (V256HF "v256hi") + (V512HF "v512hi") + (V1024HF "v1024hi") + (V2048HF "v2048hi") + (V1SF "v1si") + (V2SF "v2si") + (V4SF "v4si") + (V8SF "v8si") + (V16SF "v16si") + (V32SF "v32si") + (V64SF "v64si") + (V128SF "v128si") + (V256SF "v256si") + (V512SF "v512si") + (V1024SF "v1024si") + (V1DF "v1di") + (V2DF "v2di") + (V4DF "v4di") + (V8DF "v8di") + (V16DF "v16di") + (V32DF "v32di") + (V64DF "v64di") + (V128DF "v128di") + (V256DF "v256di") + (V512DF "v512di") ]) (define_mode_attr VNCONVERT [ @@ -2355,6 +2741,62 @@ (RVVM8DI "RVVM4SF") (RVVM4DI "RVVM2SF") (RVVM2DI "RVVM1SF") (RVVM1DI "RVVMF2SF") (RVVM8DF "RVVM4SI") (RVVM4DF "RVVM2SI") (RVVM2DF "RVVM1SI") (RVVM1DF "RVVMF2SI") + + (V1SI "V1HF") + (V2SI "V2HF") + (V4SI "V4HF") + (V8SI "V8HF") + (V16SI "V16HF") + (V32SI "V32HF") + (V64SI "V64HF") + (V128SI "V128HF") + (V256SI "V256HF") + (V512SI "V512HF") + (V1024SI "V1024HF") + (V1DI "V1SF") + (V2DI "V2SF") + (V4DI "V4SF") + (V8DI "V8SF") + (V16DI "V16SF") + (V32DI "V32SF") + (V64DI "V64SF") + (V128DI "V128SF") + (V256DI "V256SF") + (V512DI "V512SF") + + (V1HF "V1QI") + (V2HF "V2QI") + (V4HF "V4QI") + (V8HF "V8QI") + (V16HF "V16QI") + (V32HF "V32QI") + (V64HF "V64QI") + (V128HF "V128QI") + (V256HF "V256QI") + (V512HF "V512QI") + (V1024HF "V1024QI") + (V2048HF "V2048QI") + (V1SF "V1HI") + (V2SF "V2HI") + (V4SF "V4HI") + (V8SF "V8HI") + (V16SF "V16HI") + (V32SF "V32HI") + (V64SF "V64HI") + (V128SF "V128HI") + (V256SF "V256HI") + (V512SF "V512HI") + (V1024SF "V1024HI") + (V1DF "V1SI") + (V2DF "V2SI") + (V4DF "V4SI") + (V8DF "V8SI") + (V16DF "V16SI") + (V32DF "V32SI") + (V64DF "V64SI") + (V128DF "V128SI") + (V256DF "V256SI") + (V512DF "V512SI") ]) (define_mode_attr vnconvert [ @@ -2365,6 +2807,62 @@ (RVVM8DI "rvvm4sf") (RVVM4DI "rvvm2sf") (RVVM2DI "rvvm1sf") (RVVM1DI "rvvmf2sf") (RVVM8DF "rvvm4si") (RVVM4DF "rvvm2si") (RVVM2DF "rvvm1si") (RVVM1DF "rvvmf2si") + + (V1SI "v1hf") + (V2SI "v2hf") + (V4SI "v4hf") + (V8SI "v8hf") + (V16SI "v16hf") + (V32SI "v32hf") + (V64SI "v64hf") + (V128SI "v128hf") + (V256SI "v256hf") + (V512SI "v512hf") + (V1024SI "v1024hf") + (V1DI "v1sf") + (V2DI "v2sf") + (V4DI "v4sf") + (V8DI "v8sf") + (V16DI "v16sf") + (V32DI "v32sf") + (V64DI "v64sf") + (V128DI "v128sf") + (V256DI "v256sf") + (V512DI "v512sf") + + (V1HF "v1qi") + (V2HF "v2qi") + (V4HF "v4qi") + (V8HF "v8qi") + (V16HF "v16qi") + (V32HF "v32qi") + (V64HF "v64qi") + (V128HF "v128qi") + (V256HF "v256qi") + (V512HF "v512qi") + (V1024HF "v1024qi") + (V2048HF "v2048qi") + (V1SF "v1hi") + (V2SF "v2hi") + (V4SF "v4hi") + (V8SF "v8hi") + (V16SF "v16hi") + (V32SF "v32hi") + (V64SF "v64hi") + (V128SF "v128hi") + (V256SF "v256hi") + (V512SF "v512hi") + (V1024SF "v1024hi") + (V1DF "v1si") + (V2DF "v2si") + (V4DF "v4si") + (V8DF "v8si") + (V16DF "v16si") + (V32DF "v32si") + (V64DF "v64si") + (V128DF "v128si") + (V256DF "v256si") + (V512DF "v512si") ]) (define_mode_attr VDEMOTE [ @@ -2395,6 +2893,93 @@ (V512DI "V512BI") ]) +(define_mode_attr stride_predicate [ + (RVVM8QI "vector_eew8_stride_operand") (RVVM4QI "vector_eew8_stride_operand") + (RVVM2QI "vector_eew8_stride_operand") (RVVM1QI "vector_eew8_stride_operand") + (RVVMF2QI "vector_eew8_stride_operand") (RVVMF4QI "vector_eew8_stride_operand") + (RVVMF8QI "vector_eew8_stride_operand") + + (RVVM8HI "vector_eew16_stride_operand") (RVVM4HI "vector_eew16_stride_operand") + (RVVM2HI "vector_eew16_stride_operand") (RVVM1HI "vector_eew16_stride_operand") + (RVVMF2HI "vector_eew16_stride_operand") (RVVMF4HI "vector_eew16_stride_operand") + + (RVVM8HF "vector_eew16_stride_operand") (RVVM4HF "vector_eew16_stride_operand") + (RVVM2HF "vector_eew16_stride_operand") (RVVM1HF "vector_eew16_stride_operand") + (RVVMF2HF "vector_eew16_stride_operand") (RVVMF4HF "vector_eew16_stride_operand") + + (RVVM8SI "vector_eew32_stride_operand") (RVVM4SI "vector_eew32_stride_operand") + (RVVM2SI "vector_eew32_stride_operand") (RVVM1SI "vector_eew32_stride_operand") + (RVVMF2SI "vector_eew32_stride_operand") + + (RVVM8SF "vector_eew32_stride_operand") (RVVM4SF "vector_eew32_stride_operand") + (RVVM2SF "vector_eew32_stride_operand") (RVVM1SF "vector_eew32_stride_operand") + (RVVMF2SF "vector_eew32_stride_operand") + + (RVVM8DI "vector_eew64_stride_operand") (RVVM4DI "vector_eew64_stride_operand") + (RVVM2DI "vector_eew64_stride_operand") (RVVM1DI "vector_eew64_stride_operand") + + (RVVM8DF "vector_eew64_stride_operand") (RVVM4DF "vector_eew64_stride_operand") + (RVVM2DF "vector_eew64_stride_operand") (RVVM1DF "vector_eew64_stride_operand") +]) + +(define_mode_attr stride_load_constraint [ + (RVVM8QI "rJ,rJ,rJ,c01,c01,c01") (RVVM4QI "rJ,rJ,rJ,c01,c01,c01") + (RVVM2QI "rJ,rJ,rJ,c01,c01,c01") (RVVM1QI "rJ,rJ,rJ,c01,c01,c01") + (RVVMF2QI "rJ,rJ,rJ,c01,c01,c01") (RVVMF4QI "rJ,rJ,rJ,c01,c01,c01") + (RVVMF8QI "rJ,rJ,rJ,c01,c01,c01") + + (RVVM8HI "rJ,rJ,rJ,c02,c02,c02") (RVVM4HI "rJ,rJ,rJ,c02,c02,c02") + (RVVM2HI "rJ,rJ,rJ,c02,c02,c02") (RVVM1HI "rJ,rJ,rJ,c02,c02,c02") + (RVVMF2HI "rJ,rJ,rJ,c02,c02,c02") (RVVMF4HI "rJ,rJ,rJ,c02,c02,c02") + + (RVVM8HF "rJ,rJ,rJ,c02,c02,c02") (RVVM4HF "rJ,rJ,rJ,c02,c02,c02") + (RVVM2HF "rJ,rJ,rJ,c02,c02,c02") (RVVM1HF "rJ,rJ,rJ,c02,c02,c02") + (RVVMF2HF "rJ,rJ,rJ,c02,c02,c02") (RVVMF4HF "rJ,rJ,rJ,c02,c02,c02") + + (RVVM8SI "rJ,rJ,rJ,c04,c04,c04") (RVVM4SI "rJ,rJ,rJ,c04,c04,c04") + (RVVM2SI "rJ,rJ,rJ,c04,c04,c04") (RVVM1SI "rJ,rJ,rJ,c04,c04,c04") + (RVVMF2SI "rJ,rJ,rJ,c04,c04,c04") + + (RVVM8SF "rJ,rJ,rJ,c04,c04,c04") (RVVM4SF "rJ,rJ,rJ,c04,c04,c04") + (RVVM2SF "rJ,rJ,rJ,c04,c04,c04") (RVVM1SF "rJ,rJ,rJ,c04,c04,c04") + (RVVMF2SF "rJ,rJ,rJ,c04,c04,c04") + + (RVVM8DI "rJ,rJ,rJ,c08,c08,c08") (RVVM4DI "rJ,rJ,rJ,c08,c08,c08") + (RVVM2DI "rJ,rJ,rJ,c08,c08,c08") (RVVM1DI "rJ,rJ,rJ,c08,c08,c08") + + (RVVM8DF "rJ,rJ,rJ,c08,c08,c08") (RVVM4DF "rJ,rJ,rJ,c08,c08,c08") + (RVVM2DF "rJ,rJ,rJ,c08,c08,c08") (RVVM1DF "rJ,rJ,rJ,c08,c08,c08") +]) + +(define_mode_attr stride_store_constraint [ + (RVVM8QI "rJ,c01") (RVVM4QI "rJ,c01") + (RVVM2QI "rJ,c01") (RVVM1QI "rJ,c01") + (RVVMF2QI "rJ,c01") (RVVMF4QI "rJ,c01") + (RVVMF8QI "rJ,c01") + + (RVVM8HI "rJ,c02") (RVVM4HI "rJ,c02") + (RVVM2HI "rJ,c02") (RVVM1HI "rJ,c02") + (RVVMF2HI "rJ,c02") (RVVMF4HI "rJ,c02") + + (RVVM8HF "rJ,c02") (RVVM4HF "rJ,c02") + (RVVM2HF "rJ,c02") (RVVM1HF "rJ,c02") + (RVVMF2HF "rJ,c02") (RVVMF4HF "rJ,c02") + + (RVVM8SI "rJ,c04") (RVVM4SI "rJ,c04") + (RVVM2SI "rJ,c04") (RVVM1SI "rJ,c04") + (RVVMF2SI "rJ,c04") + + (RVVM8SF "rJ,c04") (RVVM4SF "rJ,c04") + (RVVM2SF "rJ,c04") (RVVM1SF "rJ,c04") + (RVVMF2SF "rJ,c04") + + (RVVM8DI "rJ,c08") (RVVM4DI "rJ,c08") + (RVVM2DI "rJ,c08") (RVVM1DI "rJ,c08") + + (RVVM8DF "rJ,c08") (RVVM4DF "rJ,c08") + (RVVM2DF "rJ,c08") (RVVM1DF "rJ,c08") +]) + (define_mode_attr gs_extension [ (RVVM8QI "const_1_operand") (RVVM4QI "vector_gs_extension_operand") (RVVM2QI "immediate_operand") (RVVM1QI "immediate_operand") (RVVMF2QI "immediate_operand") @@ -2427,18 +3012,18 @@ (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") + (RVVM2HI "const_1_or_2_operand") (RVVM1HI "const_1_or_2_operand") + (RVVMF2HI "const_1_or_2_operand") (RVVMF4HI "const_1_or_2_operand") (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") + (RVVM2HF "const_1_or_2_operand") (RVVM1HF "const_1_or_2_operand") + (RVVMF2HF "const_1_or_2_operand") (RVVMF4HF "const_1_or_2_operand") - (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") + (RVVM8SI "vector_gs_scale_operand_32_rv32") (RVVM4SI "const_1_or_4_operand") (RVVM2SI "const_1_or_4_operand") + (RVVM1SI "const_1_or_4_operand") (RVVMF2SI "const_1_or_4_operand") - (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") + (RVVM8SF "vector_gs_scale_operand_32_rv32") (RVVM4SF "const_1_or_4_operand") (RVVM2SF "const_1_or_4_operand") + (RVVM1SF "const_1_or_4_operand") (RVVMF2SF "const_1_or_4_operand") (RVVM8DI "vector_gs_scale_operand_64") (RVVM4DI "vector_gs_scale_operand_64") (RVVM2DI "vector_gs_scale_operand_64") (RVVM1DI "vector_gs_scale_operand_64") diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 6d3c43e..36f0256 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -2083,40 +2083,48 @@ ;; ------------------------------------------------------------------------------- (define_insn "@pred_strided_load<mode>" - [(set (match_operand:V 0 "register_operand" "=vr, vr, vd") + [(set (match_operand:V 0 "register_operand" "=vr, vr, vd, vr, vr, vd") (if_then_else:V (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1, Wc1, vm") - (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") + [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1, Wc1, vm, vmWc1, Wc1, vm") + (match_operand 5 "vector_length_operand" " rK, rK, rK, rK, rK, rK") + (match_operand 6 "const_int_operand" " i, i, i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (unspec:V - [(match_operand:V 3 "memory_operand" " m, m, m") - (match_operand 4 "pmode_reg_or_0_operand" " rJ, rJ, rJ")] UNSPEC_STRIDED) - (match_operand:V 2 "vector_merge_operand" " 0, vu, vu")))] + [(match_operand:V 3 "memory_operand" " m, m, m, m, m, m") + (match_operand 4 "<V:stride_predicate>" "<V:stride_load_constraint>")] UNSPEC_STRIDED) + (match_operand:V 2 "vector_merge_operand" " 0, vu, vu, 0, vu, vu")))] "TARGET_VECTOR" - "vlse<sew>.v\t%0,%3,%z4%p1" + "@ + vlse<sew>.v\t%0,%3,%z4%p1 + vlse<sew>.v\t%0,%3,%z4 + vlse<sew>.v\t%0,%3,%z4,%1.t + vle<sew>.v\t%0,%3%p1 + vle<sew>.v\t%0,%3 + vle<sew>.v\t%0,%3,%1.t" [(set_attr "type" "vlds") (set_attr "mode" "<MODE>")]) (define_insn "@pred_strided_store<mode>" - [(set (match_operand:V 0 "memory_operand" "+m") + [(set (match_operand:V 0 "memory_operand" "+m, m") (if_then_else:V (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 4 "vector_length_operand" " rK") - (match_operand 5 "const_int_operand" " i") + [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1, vmWc1") + (match_operand 4 "vector_length_operand" " rK, rK") + (match_operand 5 "const_int_operand" " i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (unspec:V - [(match_operand 2 "pmode_reg_or_0_operand" " rJ") - (match_operand:V 3 "register_operand" " vr")] UNSPEC_STRIDED) + [(match_operand 2 "<V:stride_predicate>" "<V:stride_store_constraint>") + (match_operand:V 3 "register_operand" " vr, vr")] UNSPEC_STRIDED) (match_dup 0)))] "TARGET_VECTOR" - "vsse<sew>.v\t%3,%0,%z2%p1" + "@ + vsse<sew>.v\t%3,%0,%z2%p1 + vse<sew>.v\t%3,%0%p1" [(set_attr "type" "vsts") (set_attr "mode" "<MODE>") (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) @@ -5144,8 +5152,8 @@ ;; ------------------------------------------------------------------------------- (define_expand "@pred_mul_plus<mode>" - [(set (match_operand:VI 0 "register_operand") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -5154,20 +5162,48 @@ (match_operand 9 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI - (mult:VI - (match_operand:VI 2 "register_operand") - (match_operand:VI 3 "register_operand")) - (match_operand:VI 4 "register_operand")) - (match_operand:VI 5 "register_operand")))] + (plus:V_VLSI + (mult:V_VLSI + (match_operand:V_VLSI 2 "register_operand") + (match_operand:V_VLSI 3 "register_operand")) + (match_operand:V_VLSI 4 "register_operand")) + (match_operand:V_VLSI 5 "vector_merge_operand")))] "TARGET_VECTOR" { riscv_vector::prepare_ternary_operands (operands); }) +(define_insn "*pred_mul_plus<mode>_undef" + [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vd,?&vd, vr, vr,?&vr") + (if_then_else:V_VLSI + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm, vm,Wc1,Wc1, Wc1") + (match_operand 6 "vector_length_operand" " rK, rK, rK, rK, rK, rK") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i, i, i") + (match_operand 9 "const_int_operand" " i, i, i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (plus:V_VLSI + (mult:V_VLSI + (match_operand:V_VLSI 3 "register_operand" " 0, vr, vr, 0, vr, vr") + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr, vr, vr")) + (match_operand:V_VLSI 5 "register_operand" " vr, 0, vr, vr, 0, vr")) + (match_operand:V_VLSI 2 "vector_undef_operand")))] + "TARGET_VECTOR" + "@ + vmadd.vv\t%0,%4,%5%p1 + vmacc.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%4\;vmacc.vv\t%0,%3,%4%p1 + vmadd.vv\t%0,%4,%5%p1 + vmacc.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%5\;vmacc.vv\t%0,%3,%4%p1" + [(set_attr "type" "vimuladd") + (set_attr "mode" "<MODE>")]) + (define_insn "*pred_madd<mode>" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5176,11 +5212,11 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI - (mult:VI - (match_operand:VI 2 "register_operand" " 0, vr, 0, vr") - (match_operand:VI 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VI 4 "register_operand" " vr, vr, vr, vr")) + (plus:V_VLSI + (mult:V_VLSI + (match_operand:V_VLSI 2 "register_operand" " 0, vr, 0, vr") + (match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr")) (match_dup 2)))] "TARGET_VECTOR" "@ @@ -5197,8 +5233,8 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) (define_insn "*pred_macc<mode>" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5207,11 +5243,11 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI - (mult:VI - (match_operand:VI 2 "register_operand" " vr, vr, vr, vr") - (match_operand:VI 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VI 4 "register_operand" " 0, vr, 0, vr")) + (plus:V_VLSI + (mult:V_VLSI + (match_operand:V_VLSI 2 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSI 4 "register_operand" " 0, vr, 0, vr")) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -5227,38 +5263,9 @@ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) -(define_insn_and_rewrite "*pred_mul_plus<mode>" - [(set (match_operand:VI 0 "register_operand" "=&vr") - (if_then_else:VI - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI - (mult:VI - (match_operand:VI 2 "register_operand" " vr") - (match_operand:VI 3 "register_operand" " vr")) - (match_operand:VI 4 "register_operand" " vr")) - (match_operand:VI 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[2], operands[5]) - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<MODE>")]) - (define_expand "@pred_mul_plus<mode>_scalar" - [(set (match_operand:VI_QHS 0 "register_operand") - (if_then_else:VI_QHS + [(set (match_operand:V_VLSI_QHS 0 "register_operand") + (if_then_else:V_VLSI_QHS (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -5267,19 +5274,19 @@ (match_operand 9 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI_QHS - (mult:VI_QHS - (vec_duplicate:VI_QHS + (plus:V_VLSI_QHS + (mult:V_VLSI_QHS + (vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 2 "register_operand")) - (match_operand:VI_QHS 3 "register_operand")) - (match_operand:VI_QHS 4 "register_operand")) - (match_operand:VI_QHS 5 "register_operand")))] + (match_operand:V_VLSI_QHS 3 "register_operand")) + (match_operand:V_VLSI_QHS 4 "register_operand")) + (match_operand:V_VLSI_QHS 5 "register_operand")))] "TARGET_VECTOR" {}) (define_insn "*pred_madd<mode>_scalar" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5288,12 +5295,12 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI - (mult:VI - (vec_duplicate:VI + (plus:V_VLSI + (mult:V_VLSI + (vec_duplicate:V_VLSI (match_operand:<VEL> 2 "register_operand" " r, r, r, r")) - (match_operand:VI 3 "register_operand" " 0, vr, 0, vr")) - (match_operand:VI 4 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSI 3 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr")) (match_dup 3)))] "TARGET_VECTOR" "@ @@ -5310,8 +5317,8 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) (define_insn "*pred_macc<mode>_scalar" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5320,12 +5327,12 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI - (mult:VI - (vec_duplicate:VI + (plus:V_VLSI + (mult:V_VLSI + (vec_duplicate:V_VLSI (match_operand:<VEL> 2 "register_operand" " r, r, r, r")) - (match_operand:VI 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VI 4 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSI 4 "register_operand" " 0, vr, 0, vr")) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -5341,38 +5348,9 @@ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) -(define_insn_and_rewrite "*pred_mul_plus<mode>_scalar" - [(set (match_operand:VI 0 "register_operand" "=&vr") - (if_then_else:VI - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI - (mult:VI - (vec_duplicate:VI - (match_operand:<VEL> 2 "register_operand" " r")) - (match_operand:VI 3 "register_operand" " vr")) - (match_operand:VI 4 "vector_arith_operand" " vr")) - (match_operand:VI 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<MODE>")]) - (define_expand "@pred_mul_plus<mode>_scalar" - [(set (match_operand:VI_D 0 "register_operand") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -5381,13 +5359,13 @@ (match_operand 9 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI_D - (mult:VI_D - (vec_duplicate:VI_D + (plus:V_VLSI_D + (mult:V_VLSI_D + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 2 "reg_or_int_operand")) - (match_operand:VI_D 3 "register_operand")) - (match_operand:VI_D 4 "register_operand")) - (match_operand:VI_D 5 "register_operand")))] + (match_operand:V_VLSI_D 3 "register_operand")) + (match_operand:V_VLSI_D 4 "register_operand")) + (match_operand:V_VLSI_D 5 "register_operand")))] "TARGET_VECTOR" { if (riscv_vector::sew64_scalar_helper ( @@ -5405,8 +5383,8 @@ }) (define_insn "*pred_madd<mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5415,13 +5393,13 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI_D - (mult:VI_D - (vec_duplicate:VI_D + (plus:V_VLSI_D + (mult:V_VLSI_D + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 2 "register_operand" " r, r, r, r"))) - (match_operand:VI_D 3 "register_operand" " 0, vr, 0, vr")) - (match_operand:VI_D 4 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSI_D 3 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSI_D 4 "register_operand" " vr, vr, vr, vr")) (match_dup 3)))] "TARGET_VECTOR" "@ @@ -5438,8 +5416,8 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) (define_insn "*pred_macc<mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5448,13 +5426,13 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI_D - (mult:VI_D - (vec_duplicate:VI_D + (plus:V_VLSI_D + (mult:V_VLSI_D + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 2 "register_operand" " r, r, r, r"))) - (match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VI_D 4 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSI_D 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSI_D 4 "register_operand" " 0, vr, 0, vr")) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -5470,39 +5448,9 @@ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) -(define_insn_and_rewrite "*pred_mul_plus<mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=&vr") - (if_then_else:VI_D - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (plus:VI_D - (mult:VI_D - (vec_duplicate:VI_D - (sign_extend:<VEL> - (match_operand:<VSUBEL> 2 "register_operand" " r"))) - (match_operand:VI_D 3 "register_operand" " vr")) - (match_operand:VI_D 4 "register_operand" " vr")) - (match_operand:VI_D 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<MODE>")]) - (define_expand "@pred_minus_mul<mode>" - [(set (match_operand:VI 0 "register_operand") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -5511,20 +5459,48 @@ (match_operand 9 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI - (match_operand:VI 4 "register_operand") - (mult:VI - (match_operand:VI 2 "register_operand") - (match_operand:VI 3 "register_operand"))) - (match_operand:VI 5 "register_operand")))] + (minus:V_VLSI + (match_operand:V_VLSI 4 "register_operand") + (mult:V_VLSI + (match_operand:V_VLSI 2 "register_operand") + (match_operand:V_VLSI 3 "register_operand"))) + (match_operand:V_VLSI 5 "vector_merge_operand")))] "TARGET_VECTOR" { riscv_vector::prepare_ternary_operands (operands); }) +(define_insn "*pred_minus_mul<mode>_undef" + [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vd,?&vd, vr, vr,?&vr") + (if_then_else:V_VLSI + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm, vm,Wc1,Wc1, Wc1") + (match_operand 6 "vector_length_operand" " rK, rK, rK, rK, rK, rK") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i, i, i") + (match_operand 9 "const_int_operand" " i, i, i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (minus:V_VLSI + (match_operand:V_VLSI 5 "register_operand" " vr, 0, vr, vr, 0, vr") + (mult:V_VLSI + (match_operand:V_VLSI 3 "register_operand" " 0, vr, vr, 0, vr, vr") + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr, vr, vr"))) + (match_operand:V_VLSI 2 "vector_undef_operand")))] + "TARGET_VECTOR" + "@ + vnmsub.vv\t%0,%4,%5%p1 + vnmsac.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%3\;vnmsub.vv\t%0,%4,%5%p1 + vnmsub.vv\t%0,%4,%5%p1 + vnmsac.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%3\;vnmsub.vv\t%0,%4,%5%p1" + [(set_attr "type" "vimuladd") + (set_attr "mode" "<MODE>")]) + (define_insn "*pred_nmsub<mode>" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5533,11 +5509,11 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI - (match_operand:VI 4 "register_operand" " vr, vr, vr, vr") - (mult:VI - (match_operand:VI 2 "register_operand" " 0, vr, 0, vr") - (match_operand:VI 3 "register_operand" " vr, vr, vr, vr"))) + (minus:V_VLSI + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr") + (mult:V_VLSI + (match_operand:V_VLSI 2 "register_operand" " 0, vr, 0, vr") + (match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr"))) (match_dup 2)))] "TARGET_VECTOR" "@ @@ -5554,8 +5530,8 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) (define_insn "*pred_nmsac<mode>" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5564,11 +5540,11 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI - (match_operand:VI 4 "register_operand" " 0, vr, 0, vr") - (mult:VI - (match_operand:VI 2 "register_operand" " vr, vr, vr, vr") - (match_operand:VI 3 "register_operand" " vr, vr, vr, vr"))) + (minus:V_VLSI + (match_operand:V_VLSI 4 "register_operand" " 0, vr, 0, vr") + (mult:V_VLSI + (match_operand:V_VLSI 2 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr"))) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -5584,38 +5560,9 @@ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) -(define_insn_and_rewrite "*pred_minus_mul<mode>" - [(set (match_operand:VI 0 "register_operand" "=&vr") - (if_then_else:VI - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI - (match_operand:VI 4 "vector_arith_operand" " vr") - (mult:VI - (match_operand:VI 2 "register_operand" " vr") - (match_operand:VI 3 "register_operand" " vr"))) - (match_operand:VI 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[2], operands[5]) - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<MODE>")]) - (define_expand "@pred_minus_mul<mode>_scalar" - [(set (match_operand:VI_QHS 0 "register_operand") - (if_then_else:VI_QHS + [(set (match_operand:V_VLSI_QHS 0 "register_operand") + (if_then_else:V_VLSI_QHS (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -5624,19 +5571,19 @@ (match_operand 9 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI_QHS - (match_operand:VI_QHS 4 "register_operand") - (mult:VI_QHS - (vec_duplicate:VI_QHS + (minus:V_VLSI_QHS + (match_operand:V_VLSI_QHS 4 "register_operand") + (mult:V_VLSI_QHS + (vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 2 "register_operand")) - (match_operand:VI_QHS 3 "register_operand"))) - (match_operand:VI_QHS 5 "register_operand")))] + (match_operand:V_VLSI_QHS 3 "register_operand"))) + (match_operand:V_VLSI_QHS 5 "register_operand")))] "TARGET_VECTOR" {}) (define_insn "*pred_nmsub<mode>_scalar" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5645,12 +5592,12 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI - (match_operand:VI 4 "register_operand" " vr, vr, vr, vr") - (mult:VI - (vec_duplicate:VI + (minus:V_VLSI + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr") + (mult:V_VLSI + (vec_duplicate:V_VLSI (match_operand:<VEL> 2 "register_operand" " r, r, r, r")) - (match_operand:VI 3 "register_operand" " 0, vr, 0, vr"))) + (match_operand:V_VLSI 3 "register_operand" " 0, vr, 0, vr"))) (match_dup 3)))] "TARGET_VECTOR" "@ @@ -5667,8 +5614,8 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) (define_insn "*pred_nmsac<mode>_scalar" - [(set (match_operand:VI 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5677,12 +5624,12 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI - (match_operand:VI 4 "register_operand" " 0, vr, 0, vr") - (mult:VI - (vec_duplicate:VI + (minus:V_VLSI + (match_operand:V_VLSI 4 "register_operand" " 0, vr, 0, vr") + (mult:V_VLSI + (vec_duplicate:V_VLSI (match_operand:<VEL> 2 "register_operand" " r, r, r, r")) - (match_operand:VI 3 "register_operand" " vr, vr, vr, vr"))) + (match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr"))) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -5698,38 +5645,9 @@ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) -(define_insn_and_rewrite "*pred_minus_mul<mode>_scalar" - [(set (match_operand:VI 0 "register_operand" "=&vr") - (if_then_else:VI - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI - (match_operand:VI 4 "vector_arith_operand" " vr") - (mult:VI - (vec_duplicate:VI - (match_operand:<VEL> 2 "register_operand" " r")) - (match_operand:VI 3 "register_operand" " vr"))) - (match_operand:VI 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<MODE>")]) - (define_expand "@pred_minus_mul<mode>_scalar" - [(set (match_operand:VI_D 0 "register_operand") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -5738,13 +5656,13 @@ (match_operand 9 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI_D - (match_operand:VI_D 4 "register_operand") - (mult:VI_D - (vec_duplicate:VI_D + (minus:V_VLSI_D + (match_operand:V_VLSI_D 4 "register_operand") + (mult:V_VLSI_D + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 2 "reg_or_int_operand")) - (match_operand:VI_D 3 "register_operand"))) - (match_operand:VI_D 5 "register_operand")))] + (match_operand:V_VLSI_D 3 "register_operand"))) + (match_operand:V_VLSI_D 5 "register_operand")))] "TARGET_VECTOR" { if (riscv_vector::sew64_scalar_helper ( @@ -5762,8 +5680,8 @@ }) (define_insn "*pred_nmsub<mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5772,13 +5690,13 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI_D - (match_operand:VI_D 4 "register_operand" " vr, vr, vr, vr") - (mult:VI_D - (vec_duplicate:VI_D + (minus:V_VLSI_D + (match_operand:V_VLSI_D 4 "register_operand" " vr, vr, vr, vr") + (mult:V_VLSI_D + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 2 "register_operand" " r, r, r, r"))) - (match_operand:VI_D 3 "register_operand" " 0, vr, 0, vr"))) + (match_operand:V_VLSI_D 3 "register_operand" " 0, vr, 0, vr"))) (match_dup 3)))] "TARGET_VECTOR" "@ @@ -5795,8 +5713,8 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) (define_insn "*pred_nmsac<mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd,?&vd, vr,?&vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -5805,13 +5723,13 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI_D - (match_operand:VI_D 4 "register_operand" " 0, vr, 0, vr") - (mult:VI_D - (vec_duplicate:VI_D + (minus:V_VLSI_D + (match_operand:V_VLSI_D 4 "register_operand" " 0, vr, 0, vr") + (mult:V_VLSI_D + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 2 "register_operand" " r, r, r, r"))) - (match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr"))) + (match_operand:V_VLSI_D 3 "register_operand" " vr, vr, vr, vr"))) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -5827,36 +5745,6 @@ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))]) -(define_insn_and_rewrite "*pred_minus_mul<mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=&vr") - (if_then_else:VI_D - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (minus:VI_D - (match_operand:VI_D 4 "vector_arith_operand" " vr") - (mult:VI_D - (vec_duplicate:VI_D - (sign_extend:<VEL> - (match_operand:<VSUBEL> 2 "register_operand" " r"))) - (match_operand:VI_D 3 "register_operand" " vr"))) - (match_operand:VI_D 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vimuladd") - (set_attr "mode" "<MODE>")]) - ;; ------------------------------------------------------------------------------- ;; ---- Predicated widen integer ternary operations ;; ------------------------------------------------------------------------------- @@ -6416,8 +6304,8 @@ ;; ------------------------------------------------------------------------------- (define_expand "@pred_mul_<optab><mode>" - [(set (match_operand:VF 0 "register_operand") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -6428,20 +6316,52 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (match_operand:VF 2 "register_operand") - (match_operand:VF 3 "register_operand")) - (match_operand:VF 4 "register_operand")) - (match_operand:VF 5 "register_operand")))] + (plus_minus:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 2 "register_operand") + (match_operand:V_VLSF 3 "register_operand")) + (match_operand:V_VLSF 4 "register_operand")) + (match_operand:V_VLSF 5 "vector_merge_operand")))] "TARGET_VECTOR" { riscv_vector::prepare_ternary_operands (operands); }) +(define_insn "*pred_mul_<optab><mode>_undef" + [(set (match_operand:V_VLSF 0 "register_operand" "=vd,vd,?&vd, vr, vr,?&vr") + (if_then_else:V_VLSF + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm,vm, vm,Wc1,Wc1, Wc1") + (match_operand 6 "vector_length_operand" " rK,rK, rK, rK, rK, rK") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i, i, i") + (match_operand 9 "const_int_operand" " i, i, i, i, i, i") + (match_operand 10 "const_int_operand" " i, i, i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (plus_minus:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 3 "register_operand" " 0,vr, vr, 0, vr, vr") + (match_operand:V_VLSF 4 "register_operand" " vr,vr, vr, vr, vr, vr")) + (match_operand:V_VLSF 5 "register_operand" " vr, 0, vr, vr, 0, vr")) + (match_operand:V_VLSF 2 "vector_undef_operand")))] + "TARGET_VECTOR" + "@ + vf<madd_msub>.vv\t%0,%4,%5%p1 + vf<macc_msac>.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%3\;vf<madd_msub>.vv\t%0,%4,%5%p1 + vf<madd_msub>.vv\t%0,%4,%5%p1 + vf<macc_msac>.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%3\;vf<madd_msub>.vv\t%0,%4,%5%p1" + [(set_attr "type" "vfmuladd") + (set_attr "mode" "<MODE>") + (set (attr "frm_mode") + (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) + (define_insn "*pred_<madd_msub><mode>" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6452,11 +6372,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (match_operand:VF 2 "register_operand" " 0, vr, 0, vr") - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VF 4 "register_operand" " vr, vr, vr, vr")) + (plus_minus:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 2 "register_operand" " 0, vr, 0, vr") + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")) (match_dup 2)))] "TARGET_VECTOR" "@ @@ -6475,8 +6395,8 @@ (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) (define_insn "*pred_<macc_msac><mode>" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6487,11 +6407,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (match_operand:VF 2 "register_operand" " vr, vr, vr, vr") - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VF 4 "register_operand" " 0, vr, 0, vr")) + (plus_minus:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 2 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 4 "register_operand" " 0, vr, 0, vr")) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -6509,42 +6429,9 @@ (set (attr "frm_mode") (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) -(define_insn_and_rewrite "*pred_mul_<optab><mode>" - [(set (match_operand:VF 0 "register_operand" "=&vr") - (if_then_else:VF - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (match_operand 10 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (match_operand:VF 2 "register_operand" " vr") - (match_operand:VF 3 "register_operand" " vr")) - (match_operand:VF 4 "register_operand" " vr")) - (match_operand:VF 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[2], operands[5]) - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<MODE>") - (set (attr "frm_mode") - (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) - (define_expand "@pred_mul_<optab><mode>_scalar" - [(set (match_operand:VF 0 "register_operand") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -6555,19 +6442,19 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (vec_duplicate:VF + (plus_minus:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF (match_operand:<VEL> 2 "register_operand")) - (match_operand:VF 3 "register_operand")) - (match_operand:VF 4 "register_operand")) - (match_operand:VF 5 "register_operand")))] + (match_operand:V_VLSF 3 "register_operand")) + (match_operand:V_VLSF 4 "register_operand")) + (match_operand:V_VLSF 5 "register_operand")))] "TARGET_VECTOR" {}) (define_insn "*pred_<madd_msub><mode>_scalar" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6578,12 +6465,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (vec_duplicate:VF + (plus_minus:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF (match_operand:<VEL> 2 "register_operand" " f, f, f, f")) - (match_operand:VF 3 "register_operand" " 0, vr, 0, vr")) - (match_operand:VF 4 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 3 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")) (match_dup 3)))] "TARGET_VECTOR" "@ @@ -6602,8 +6489,8 @@ (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) (define_insn "*pred_<macc_msac><mode>_scalar" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6614,12 +6501,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (vec_duplicate:VF + (plus_minus:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF (match_operand:<VEL> 2 "register_operand" " f, f, f, f")) - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VF 4 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 4 "register_operand" " 0, vr, 0, vr")) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -6637,42 +6524,9 @@ (set (attr "frm_mode") (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) -(define_insn_and_rewrite "*pred_mul_<optab><mode>_scalar" - [(set (match_operand:VF 0 "register_operand" "=&vr") - (if_then_else:VF - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (match_operand 10 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (mult:VF - (vec_duplicate:VF - (match_operand:<VEL> 2 "register_operand" " f")) - (match_operand:VF 3 "register_operand" " vr")) - (match_operand:VF 4 "vector_arith_operand" " vr")) - (match_operand:VF 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<MODE>") - (set (attr "frm_mode") - (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) - (define_expand "@pred_mul_neg_<optab><mode>" - [(set (match_operand:VF 0 "register_operand") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -6683,21 +6537,54 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (match_operand:VF 2 "register_operand") - (match_operand:VF 3 "register_operand"))) - (match_operand:VF 4 "register_operand")) - (match_operand:VF 5 "register_operand")))] + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 2 "register_operand") + (match_operand:V_VLSF 3 "register_operand"))) + (match_operand:V_VLSF 4 "register_operand")) + (match_operand:V_VLSF 5 "vector_merge_operand")))] "TARGET_VECTOR" { riscv_vector::prepare_ternary_operands (operands); }) +(define_insn "*pred_mul_neg_<optab><mode>_undef" + [(set (match_operand:V_VLSF 0 "register_operand" "=vd,vd,?&vd, vr, vr,?&vr") + (if_then_else:V_VLSF + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm,vm, vm,Wc1,Wc1, Wc1") + (match_operand 6 "vector_length_operand" " rK,rK, rK, rK, rK, rK") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i, i, i") + (match_operand 9 "const_int_operand" " i, i, i, i, i, i") + (match_operand 10 "const_int_operand" " i, i, i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 3 "register_operand" " 0,vr, vr, 0, vr, vr") + (match_operand:V_VLSF 4 "register_operand" " vr,vr, vr, vr, vr, vr"))) + (match_operand:V_VLSF 5 "register_operand" " vr, 0, vr, vr, 0, vr")) + (match_operand:V_VLSF 2 "vector_undef_operand")))] + "TARGET_VECTOR" + "@ + vf<nmsub_nmadd>.vv\t%0,%4,%5%p1 + vf<nmsac_nmacc>.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%3\;vf<nmsub_nmadd>.vv\t%0,%4,%5%p1 + vf<nmsub_nmadd>.vv\t%0,%4,%5%p1 + vf<nmsac_nmacc>.vv\t%0,%3,%4%p1 + vmv.v.v\t%0,%3\;vf<nmsub_nmadd>.vv\t%0,%4,%5%p1" + [(set_attr "type" "vfmuladd") + (set_attr "mode" "<MODE>") + (set (attr "frm_mode") + (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) + (define_insn "*pred_<nmsub_nmadd><mode>" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6708,12 +6595,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (match_operand:VF 2 "register_operand" " 0, vr, 0, vr") - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr"))) - (match_operand:VF 4 "register_operand" " vr, vr, vr, vr")) + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 2 "register_operand" " 0, vr, 0, vr") + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr"))) + (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")) (match_dup 2)))] "TARGET_VECTOR" "@ @@ -6732,8 +6619,8 @@ (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) (define_insn "*pred_<nmsac_nmacc><mode>" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6744,12 +6631,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (match_operand:VF 2 "register_operand" " vr, vr, vr, vr") - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr"))) - (match_operand:VF 4 "register_operand" " 0, vr, 0, vr")) + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (match_operand:V_VLSF 2 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr"))) + (match_operand:V_VLSF 4 "register_operand" " 0, vr, 0, vr")) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -6767,43 +6654,9 @@ (set (attr "frm_mode") (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) -(define_insn_and_rewrite "*pred_mul_neg_<optab><mode>" - [(set (match_operand:VF 0 "register_operand" "=&vr") - (if_then_else:VF - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (match_operand 10 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (match_operand:VF 2 "register_operand" " vr") - (match_operand:VF 3 "register_operand" " vr"))) - (match_operand:VF 4 "vector_arith_operand" " vr")) - (match_operand:VF 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[2], operands[5]) - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<MODE>") - (set (attr "frm_mode") - (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) - (define_expand "@pred_mul_neg_<optab><mode>_scalar" - [(set (match_operand:VF 0 "register_operand") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 6 "vector_length_operand") @@ -6814,20 +6667,20 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (vec_duplicate:VF + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF (match_operand:<VEL> 2 "register_operand")) - (match_operand:VF 3 "register_operand"))) - (match_operand:VF 4 "register_operand")) - (match_operand:VF 5 "register_operand")))] + (match_operand:V_VLSF 3 "register_operand"))) + (match_operand:V_VLSF 4 "register_operand")) + (match_operand:V_VLSF 5 "register_operand")))] "TARGET_VECTOR" {}) (define_insn "*pred_<nmsub_nmadd><mode>_scalar" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6838,13 +6691,13 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (vec_duplicate:VF + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF (match_operand:<VEL> 2 "register_operand" " f, f, f, f")) - (match_operand:VF 3 "register_operand" " 0, vr, 0, vr"))) - (match_operand:VF 4 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 3 "register_operand" " 0, vr, 0, vr"))) + (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")) (match_dup 3)))] "TARGET_VECTOR" "@ @@ -6863,8 +6716,8 @@ (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) (define_insn "*pred_<nmsac_nmacc><mode>_scalar" - [(set (match_operand:VF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, ?&vd, vr, ?&vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1, Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -6875,13 +6728,13 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (vec_duplicate:VF + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF (match_operand:<VEL> 2 "register_operand" " f, f, f, f")) - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr"))) - (match_operand:VF 4 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr"))) + (match_operand:V_VLSF 4 "register_operand" " 0, vr, 0, vr")) (match_dup 4)))] "TARGET_VECTOR" "@ @@ -6899,40 +6752,6 @@ (set (attr "frm_mode") (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))]) -(define_insn_and_rewrite "*pred_mul_neg_<optab><mode>_scalar" - [(set (match_operand:VF 0 "register_operand" "=&vr") - (if_then_else:VF - (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1") - (match_operand 6 "vector_length_operand" " rK") - (match_operand 7 "const_int_operand" " i") - (match_operand 8 "const_int_operand" " i") - (match_operand 9 "const_int_operand" " i") - (match_operand 10 "const_int_operand" " i") - (reg:SI VL_REGNUM) - (reg:SI VTYPE_REGNUM) - (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (plus_minus:VF - (neg:VF - (mult:VF - (vec_duplicate:VF - (match_operand:<VEL> 2 "register_operand" " f")) - (match_operand:VF 3 "register_operand" " vr"))) - (match_operand:VF 4 "vector_arith_operand" " vr")) - (match_operand:VF 5 "register_operand" " vr")))] - "TARGET_VECTOR - && !rtx_equal_p (operands[3], operands[5]) - && !rtx_equal_p (operands[4], operands[5])" - "#" - "&& reload_completed" - { - riscv_vector::prepare_ternary_operands (operands, true); - } - [(set_attr "type" "vfmuladd") - (set_attr "mode" "<MODE>") - (set (attr "frm_mode") - (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) - ;; ------------------------------------------------------------------------------- ;; ---- Predicated floating-point unary operations ;; ------------------------------------------------------------------------------- @@ -6945,8 +6764,8 @@ ;; ------------------------------------------------------------------------------- (define_insn "@pred_<optab><mode>" - [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 4 "vector_length_operand" " rK, rK, rK, rK") @@ -6957,9 +6776,9 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (any_float_unop:VF - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (any_float_unop:V_VLSF + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "vf<insn>.v\t%0,%3%p1" [(set_attr "type" "<float_insn_type>") @@ -6972,8 +6791,8 @@ (symbol_ref "riscv_vector::get_frm_mode (operands[8])"))]) (define_insn "@pred_<optab><mode>" - [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 4 "vector_length_operand" " rK, rK, rK, rK") @@ -6982,9 +6801,9 @@ (match_operand 7 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (any_float_unop_nofrm:VF - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (any_float_unop_nofrm:V_VLSF + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "vf<insn>.v\t%0,%3%p1" [(set_attr "type" "<float_insn_type>") @@ -7640,7 +7459,7 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (any_fix:<VCONVERT> - (match_operand:VF 3 "register_operand" " vr, vr, vr, vr")) + (match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")) (match_operand:<VCONVERT> 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "vfcvt.rtz.x<u>.f.v\t%0,%3%p1" @@ -7648,8 +7467,8 @@ (set_attr "mode" "<MODE>")]) (define_insn "@pred_<float_cvt><mode>" - [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 4 "vector_length_operand" " rK, rK, rK, rK") @@ -7660,9 +7479,9 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) - (any_float:VF + (any_float:V_VLSF (match_operand:<VCONVERT> 3 "register_operand" " vr, vr, vr, vr")) - (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "vfcvt.f.x<u>.v\t%0,%3%p1" [(set_attr "type" "vfcvtitof") @@ -7720,8 +7539,8 @@ (set_attr "mode" "<VNCONVERT>")]) (define_insn "@pred_widen_<float_cvt><mode>" - [(set (match_operand:VF 0 "register_operand" "=&vr, &vr") - (if_then_else:VF + [(set (match_operand:V_VLSF 0 "register_operand" "=&vr, &vr") + (if_then_else:V_VLSF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1") (match_operand 4 "vector_length_operand" " rK, rK") @@ -7730,9 +7549,9 @@ (match_operand 7 "const_int_operand" " i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (any_float:VF + (any_float:V_VLSF (match_operand:<VNCONVERT> 3 "register_operand" " vr, vr")) - (match_operand:VF 2 "vector_merge_operand" " vu, 0")))] + (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" "vfwcvt.f.x<u>.v\t%0,%3%p1" [(set_attr "type" "vfwcvtitof") @@ -7799,7 +7618,7 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (any_fix:<VNCONVERT> - (match_operand:VF 3 "register_operand" " 0, 0, 0, 0, vr, vr")) + (match_operand:V_VLSF 3 "register_operand" " 0, 0, 0, 0, vr, vr")) (match_operand:<VNCONVERT> 2 "vector_merge_operand" " vu, 0, vu, 0, vu, 0")))] "TARGET_VECTOR" "vfncvt.rtz.x<u>.f.w\t%0,%3%p1" diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index efe9adc..caf9eee 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -22164,7 +22164,9 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, *total = rs6000_cost->divsi; } /* Add in shift and subtract for MOD unless we have a mod instruction. */ - if (!TARGET_MODULO && (code == MOD || code == UMOD)) + if ((!TARGET_MODULO + || (RS6000_DISABLE_SCALAR_MODULO && SCALAR_INT_MODE_P (mode))) + && (code == MOD || code == UMOD)) *total += COSTS_N_INSNS (2); return false; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 3503614..22595f6 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2492,3 +2492,9 @@ while (0) rs6000_asm_output_opcode (STREAM); \ } \ while (0) + +/* Disable generation of scalar modulo instructions due to performance issues + with certain input values. This can be removed in the future when the + issues have been resolved. */ +#define RS6000_DISABLE_SCALAR_MODULO 1 + diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 1a9a7b1..7b583d7 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -3424,6 +3424,17 @@ FAIL; operands[2] = force_reg (<MODE>mode, operands[2]); + + if (RS6000_DISABLE_SCALAR_MODULO) + { + temp1 = gen_reg_rtx (<MODE>mode); + temp2 = gen_reg_rtx (<MODE>mode); + + emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); + emit_insn (gen_mul<mode>3 (temp2, temp1, operands[2])); + emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); + DONE; + } } else { @@ -3443,17 +3454,36 @@ [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r,r") (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") (match_operand:GPR 2 "gpc_reg_operand" "r,r")))] - "TARGET_MODULO" + "TARGET_MODULO && !RS6000_DISABLE_SCALAR_MODULO" "mods<wd> %0,%1,%2" [(set_attr "type" "div") (set_attr "size" "<bits>")]) +;; This define_expand can be removed when RS6000_DISABLE_SCALAR_MODULO is +;; removed. +(define_expand "umod<mode>3" + [(set (match_operand:GPR 0 "gpc_reg_operand") + (umod:GPR (match_operand:GPR 1 "gpc_reg_operand") + (match_operand:GPR 2 "gpc_reg_operand")))] + "TARGET_MODULO" +{ + if (RS6000_DISABLE_SCALAR_MODULO) + { + rtx temp1 = gen_reg_rtx (<MODE>mode); + rtx temp2 = gen_reg_rtx (<MODE>mode); + + emit_insn (gen_udiv<mode>3 (temp1, operands[1], operands[2])); + emit_insn (gen_mul<mode>3 (temp2, temp1, operands[2])); + emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); + DONE; + } +}) -(define_insn "umod<mode>3" +(define_insn "*umod<mode>3" [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r,r") (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") (match_operand:GPR 2 "gpc_reg_operand" "r,r")))] - "TARGET_MODULO" + "TARGET_MODULO && !RS6000_DISABLE_SCALAR_MODULO" "modu<wd> %0,%1,%2" [(set_attr "type" "div") (set_attr "size" "<bits>")]) @@ -3510,7 +3540,7 @@ [(set (match_operand:TI 0 "altivec_register_operand" "=v") (umod:TI (match_operand:TI 1 "altivec_register_operand" "v") (match_operand:TI 2 "altivec_register_operand" "v")))] - "TARGET_POWER10 && TARGET_POWERPC64" + "TARGET_POWER10 && TARGET_POWERPC64 && !RS6000_DISABLE_SCALAR_MODULO" "vmoduq %0,%1,%2" [(set_attr "type" "vecdiv") (set_attr "size" "128")]) @@ -3519,7 +3549,7 @@ [(set (match_operand:TI 0 "altivec_register_operand" "=v") (mod:TI (match_operand:TI 1 "altivec_register_operand" "v") (match_operand:TI 2 "altivec_register_operand" "v")))] - "TARGET_POWER10 && TARGET_POWERPC64" + "TARGET_POWER10 && TARGET_POWERPC64 && !RS6000_DISABLE_SCALAR_MODULO" "vmodsq %0,%1,%2" [(set_attr "type" "vecdiv") (set_attr "size" "128")]) diff --git a/gcc/configure b/gcc/configure index ee0a12a..307a3e0 100755 --- a/gcc/configure +++ b/gcc/configure @@ -24713,6 +24713,46 @@ _ACEOF +# Some assemblers (GNU as for LoongArch) generates relocations for +# leb128 symbol arithmetic for relaxation, we need to disable relaxation +# probing leb128 support then. +case $target in + loongarch*-*-*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -mno-relax support" >&5 +$as_echo_n "checking assembler for -mno-relax support... " >&6; } +if ${gcc_cv_as_mno_relax+:} false; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_mno_relax=no + if test x$gcc_cv_as != x; then + $as_echo '.text' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -mno-relax -o conftest.o conftest.s >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + gcc_cv_as_mno_relax=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mno_relax" >&5 +$as_echo "$gcc_cv_as_mno_relax" >&6; } +if test $gcc_cv_as_mno_relax = yes; then + check_leb128_asflags=-mno-relax +fi + + ;; + *) + check_leb128_asflags= + ;; +esac + # Check if we have .[us]leb128, and support symbol arithmetic with it. # Older versions of GAS and some non-GNU assemblers, have a bugs handling # these directives, even when they appear to accept them. @@ -24731,7 +24771,7 @@ L1: L2: .uleb128 0x8000000000000000 ' > conftest.s - if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5' + if { ac_try='$gcc_cv_as $gcc_cv_as_flags $check_leb128_asflags -o conftest.o conftest.s >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -29112,6 +29152,37 @@ $as_echo "#define HAVE_AS_EH_FRAME_PCREL_ENCODING_SUPPORT 1" >>confdefs.h fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -mrelax option" >&5 +$as_echo_n "checking assembler for -mrelax option... " >&6; } +if ${gcc_cv_as_loongarch_relax+:} false; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_loongarch_relax=no + if test x$gcc_cv_as != x; then + $as_echo '.text' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -mrelax -o conftest.o conftest.s >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + gcc_cv_as_loongarch_relax=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_loongarch_relax" >&5 +$as_echo "$gcc_cv_as_loongarch_relax" >&6; } +if test $gcc_cv_as_loongarch_relax = yes; then + +$as_echo "#define HAVE_AS_MRELAX_OPTION 1" >>confdefs.h + +fi + ;; s390*-*-*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .gnu_attribute support" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index 89ec291..9b35c0f 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3262,10 +3262,25 @@ AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix) gcc_AC_INITFINI_ARRAY +# Some assemblers (GNU as for LoongArch) generates relocations for +# leb128 symbol arithmetic for relaxation, we need to disable relaxation +# probing leb128 support then. +case $target in + loongarch*-*-*) + gcc_GAS_CHECK_FEATURE([-mno-relax support], + gcc_cv_as_mno_relax,[-mno-relax],[.text],, + [check_leb128_asflags=-mno-relax]) + ;; + *) + check_leb128_asflags= + ;; +esac + # Check if we have .[us]leb128, and support symbol arithmetic with it. # Older versions of GAS and some non-GNU assemblers, have a bugs handling # these directives, even when they appear to accept them. -gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128,, +gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128, +[$check_leb128_asflags], [ .data .uleb128 L2 - L1 L1: @@ -5381,6 +5396,10 @@ x: .cfi_endproc],, [AC_DEFINE(HAVE_AS_EH_FRAME_PCREL_ENCODING_SUPPORT, 1, [Define if your assembler supports eh_frame pcrel encoding.])]) + gcc_GAS_CHECK_FEATURE([-mrelax option], gcc_cv_as_loongarch_relax, + [-mrelax], [.text],, + [AC_DEFINE(HAVE_AS_MRELAX_OPTION, 1, + [Define if your assembler supports -mrelax option.])]) ;; s390*-*-*) gcc_GAS_CHECK_FEATURE([.gnu_attribute support], diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ea73753..66adfcd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,176 @@ +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + * parser.cc (cp_parser_postfix_expression): Parse + __builtin_classify_type call with typename as argument. + * pt.cc (tsubst_copy_and_build): Handle __builtin_classify_type + with dependent typename as argument. + +2023-09-20 Patrick Palka <ppalka@redhat.com> + + PR c++/111471 + * cxx-pretty-print.cc (cxx_pretty_printer::expression) + <case VAR_DECL>: Handle class NTTP objects by printing + their type and value. + <case VIEW_CONVERT_EXPR>: Strip const VIEW_CONVERT_EXPR + wrappers for class NTTPs. + (pp_cxx_template_argument_list): Don't handle class NTTP + objects here. + +2023-09-20 Patrick Palka <ppalka@redhat.com> + + * pt.cc (tsubst_function_decl): Don't bother computing 'argvec' + when 'lambda_fntype' is set. + (tsubst_template_decl): Make sure we return a TEMPLATE_DECL + during specialization lookup. In the non-class non-function + template case, use tsubst_decl directly with use_spec_table=false, + update DECL_TI_ARGS and call register_specialization like + tsubst_decl would have done if use_spec_table=true. + +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + PR c++/111392 + * parser.h (struct cp_lexer): Add in_omp_decl_attribute member. + * cp-tree.h (cp_maybe_parse_omp_decl): Declare. + * parser.cc (cp_parser_handle_statement_omp_attributes): Diagnose + omp::decl attribute on statements. Adjust diagnostic wording for + omp::decl. + (cp_parser_omp_directive_args): Add DECL_P argument, set TREE_PUBLIC + to it on the DEFERRED_PARSE tree. + (cp_parser_omp_sequence_args): Adjust caller. + (cp_parser_std_attribute): Handle omp::decl attribute. + (cp_parser_omp_var_list): If parser->lexer->in_omp_decl_attribute + don't expect any arguments, instead create clause or TREE_LIST for + that decl. + (cp_parser_late_parsing_omp_declare_simd): Adjust diagnostic wording + for omp::decl. + (cp_maybe_parse_omp_decl): New function. + (cp_parser_omp_declare_target): If + parser->lexer->in_omp_decl_attribute and first token isn't name or + comma invoke cp_parser_omp_var_list. + * decl2.cc (cplus_decl_attributes): Adjust diagnostic wording for + omp::decl. Handle omp::decl on declarations. + * name-lookup.cc (finish_using_directive): Adjust diagnostic wording + for omp::decl. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * mapper-client.cc, mapper-client.h (open_module_client): Accept + dependency tracking and track module mapper files as + dependencies. + * module.cc (make_mapper, get_mapper): Pass the dependency + tracking class down. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * module.cc (do_import): Report imported CMI files as + dependencies. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * module.cc (preprocessed_module): Pass whether the module is + exported to dependency tracking. + +2023-09-19 Javier Martinez <javier.martinez.bugzilla@gmail.com> + + * class.cc (propagate_class_warmth_attribute): New function. + (check_bases_and_members): propagate hot and cold attributes + to all FUNCTION_DECL when the record is marked hot or cold. + * cp-tree.h (maybe_propagate_warmth_attributes): New function. + * decl2.cc (maybe_propagate_warmth_attributes): New function. + * method.cc (lazily_declare_fn): propagate hot and cold + attributes to lazily declared functions when the record is + marked hot or cold. + +2023-09-19 Patrick Palka <ppalka@redhat.com> + + * ptree.cc (cxx_print_type): Remove TYPE_LANG_SPECIFIC + test guarding TYPE_TEMPLATE_INFO. + +2023-09-19 Jason Merrill <jason@redhat.com> + + DR 2799 + * class.cc (add_implicit_default_ctor): Split out... + (add_implicitly_declared_members): ...from here. + Also call it when inheriting a default ctor. + +2023-09-19 Marek Polacek <polacek@redhat.com> + + * call.cc (build_over_call): Set ADDR_EXPR_DENOTES_CALL_P. Don't handle + immediate_invocation_p here. + * constexpr.cc (cxx_eval_call_expression): Use mce_true for + DECL_IMMEDIATE_FUNCTION_P. + (cxx_eval_conditional_expression): Call cp_fold_immediate. + * cp-gimplify.cc (enum fold_flags): Add ff_fold_immediate. + (maybe_replace_decl): Make static. + (cp_fold_r): Expand immediate invocations. + (cp_fold_immediate_r): New. + (cp_fold_immediate): New. + * cp-tree.h (ADDR_EXPR_DENOTES_CALL_P): Define. + (cp_fold_immediate): Declare. + * tree.cc (bot_replace): Don't handle immediate invocations here. + +2023-09-19 Patrick Palka <ppalka@redhat.com> + + PR c++/111419 + * cvt.cc (convert_to_void) <case INDIRECT_REF>: Only call + complete_type if the type is volatile. + <case VAR_DECL>: Likewise. + +2023-09-19 Patrick Palka <ppalka@redhat.com> + + PR c++/99631 + * semantics.cc (finish_decltype_type): For an NTTP object, + return its type modulo cv-quals. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + PR c++/89231 + * pt.cc (try_class_unification): Strengthen TI_TEMPLATE equality + test by not calling most_general_template. Only unify the + innermost levels of template arguments. + (unify) <case CLASS_TYPE>: Only unify the innermost levels of + template arguments, and only if the template is primary. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + PR c++/63198 + PR c++/18474 + * semantics.cc (maybe_convert_cond): Look through implicit + INDIRECT_REF when deciding whether to issue a -Wparentheses + warning, and consider templated assignment expressions as well. + (finish_parenthesized_expr): Look through implicit INDIRECT_REF + when suppressing -Wparentheses warning. + * typeck.cc (build_x_modify_expr): Check simple assignments + ahead time too, not just compound assignments. Give the second + operand of MODOP_EXPR a non-null type so that it's not considered + always instantiation-dependent. Don't call suppress_warning. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + PR c++/108347 + * pt.cc (unify): Return unify_success for identical dependent + DECL_P 'arg' and 'parm'. + <case CONST_DECL>: Remove handling. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + * call.cc (add_template_candidate_real): Check arity even + when there are no explicit template arguments. Combine the + two adjacent '!obj' tests into one. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + * pt.cc (register_specialization): Remove now-unnecessary + early exit for FUNCTION_DECL partial instantiation. + (tsubst_template_decl): Pass use_spec_table=false to + tsubst_function_decl. Set DECL_TI_ARGS of a non-lambda + FUNCTION_DECL specialization to the full set of arguments. + Simplify register_specialization call accordingly. + +2023-09-18 Jason Merrill <jason@redhat.com> + + * class.cc (check_subobject_offset): Use similar_type_p. + 2023-09-12 Jason Merrill <jason@redhat.com> PR c++/111357 diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 3993453..e8dafbd 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -3535,13 +3535,13 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, } gcc_assert (ia == nargs_without_in_chrg); - if (!obj && explicit_targs) + if (!obj) { /* Check that there's no obvious arity mismatch before proceeding with deduction. This avoids substituting explicit template arguments - into the template (which could result in an error outside the - immediate context) when the resulting candidate would be unviable - anyway. */ + into the template or e.g. derived-to-base parm/arg unification + (which could result in an error outside the immediate context) when + the resulting candidate would be unviable anyway. */ int min_arity = 0, max_arity = 0; tree parms = TYPE_ARG_TYPES (TREE_TYPE (tmpl)); parms = skip_artificial_parms_for (tmpl, parms); @@ -3571,11 +3571,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, reason = arity_rejection (NULL_TREE, max_arity, ia); goto fail; } - } - errs = errorcount+sorrycount; - if (!obj) - { convs = alloc_conversions (nargs); if (shortcut_bad_convs @@ -3602,6 +3598,8 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, } } } + + errs = errorcount+sorrycount; fn = fn_type_unification (tmpl, explicit_targs, targs, args_without_in_chrg, nargs_without_in_chrg, @@ -10436,6 +10434,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) fn = build_addr_func (fn, complain); if (fn == error_mark_node) return error_mark_node; + + /* We're actually invoking the function. (Immediate functions get an + & when invoking it even though the user didn't use &.) */ + ADDR_EXPR_DENOTES_CALL_P (fn) = true; } tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag); @@ -10453,41 +10455,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (TREE_CODE (c) == CALL_EXPR) suppress_warning (c /* Suppress all warnings. */); } - if (TREE_CODE (fn) == ADDR_EXPR) - { - tree fndecl = STRIP_TEMPLATE (TREE_OPERAND (fn, 0)); - if (immediate_invocation_p (fndecl)) - { - tree obj_arg = NULL_TREE; - /* Undo convert_from_reference called by build_cxx_call. */ - if (REFERENCE_REF_P (call)) - call = TREE_OPERAND (call, 0); - if (DECL_CONSTRUCTOR_P (fndecl)) - obj_arg = cand->first_arg ? cand->first_arg : (*args)[0]; - if (obj_arg && is_dummy_object (obj_arg)) - { - call = build_cplus_new (DECL_CONTEXT (fndecl), call, complain); - obj_arg = NULL_TREE; - } - /* Look through *(const T *)&obj. */ - else if (obj_arg && INDIRECT_REF_P (obj_arg)) - { - tree addr = TREE_OPERAND (obj_arg, 0); - STRIP_NOPS (addr); - if (TREE_CODE (addr) == ADDR_EXPR) - { - tree typeo = TREE_TYPE (obj_arg); - tree typei = TREE_TYPE (TREE_OPERAND (addr, 0)); - if (same_type_ignoring_top_level_qualifiers_p (typeo, typei)) - obj_arg = TREE_OPERAND (addr, 0); - } - } - call = cxx_constant_value (call, obj_arg, complain); - if (obj_arg && !error_operand_p (call)) - call = cp_build_init_expr (obj_arg, call); - call = convert_from_reference (call); - } - } + return call; } diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index d270dcbb1..b71333a 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -205,6 +205,7 @@ static tree get_vcall_index (tree, tree); static bool type_maybe_constexpr_default_constructor (tree); static bool type_maybe_constexpr_destructor (tree); static bool field_poverlapping_p (tree); +static void propagate_class_warmth_attribute (tree); /* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */ @@ -3292,6 +3293,22 @@ one_inherited_ctor (tree ctor, tree t, tree using_decl) } } +/* Implicitly declare T(). */ + +static void +add_implicit_default_ctor (tree t) +{ + TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; + CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; + if (cxx_dialect >= cxx11) + TYPE_HAS_CONSTEXPR_CTOR (t) + /* Don't force the declaration to get a hard answer; if the + definition would have made the class non-literal, it will still be + non-literal because of the base or member in question, and that + gives a better diagnostic. */ + = type_maybe_constexpr_default_constructor (t); +} + /* Create default constructors, assignment operators, and so forth for the type indicated by T, if they are needed. CANT_HAVE_CONST_CTOR, and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason, @@ -3320,17 +3337,7 @@ add_implicitly_declared_members (tree t, tree* access_decls, If there is no user-declared constructor for a class, a default constructor is implicitly declared. */ if (! TYPE_HAS_USER_CONSTRUCTOR (t)) - { - TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; - CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; - if (cxx_dialect >= cxx11) - TYPE_HAS_CONSTEXPR_CTOR (t) - /* Don't force the declaration to get a hard answer; if the - definition would have made the class non-literal, it will still be - non-literal because of the base or member in question, and that - gives a better diagnostic. */ - = type_maybe_constexpr_default_constructor (t); - } + add_implicit_default_ctor (t); /* [class.ctor] @@ -3394,7 +3401,13 @@ add_implicitly_declared_members (tree t, tree* access_decls, location_t loc = input_location; input_location = DECL_SOURCE_LOCATION (using_decl); for (tree fn : ovl_range (ctor_list)) - one_inherited_ctor (fn, t, using_decl); + { + if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t) && default_ctor_p (fn)) + /* CWG2799: Inheriting a default constructor gives us a default + constructor, not just an inherited constructor. */ + add_implicit_default_ctor (t); + one_inherited_ctor (fn, t, using_decl); + } *access_decls = TREE_CHAIN (*access_decls); input_location = loc; } @@ -6277,6 +6290,12 @@ check_bases_and_members (tree t) allocating an array of this type. */ LANG_TYPE_CLASS_CHECK (t)->vec_new_uses_cookie = type_requires_array_cookie (t); + + /* Classes marked hot or cold propagate the attribute to all members. We + may do this now that methods are declared. This does miss some lazily + declared special member functions (CLASSTYPE_LAZY_*), which are handled + in lazily_declare_fn later on. */ + propagate_class_warmth_attribute (t); } /* If T needs a pointer to its virtual function table, set TYPE_VFIELD @@ -7757,6 +7776,28 @@ unreverse_member_declarations (tree t) } } +/* Classes, structs or unions T marked with hotness attributes propagate + the attribute to all methods. */ + +void +propagate_class_warmth_attribute (tree t) +{ + if (t == NULL_TREE + || !(TREE_CODE (t) == RECORD_TYPE + || TREE_CODE (t) == UNION_TYPE)) + return; + + tree class_has_cold_attr + = lookup_attribute ("cold", TYPE_ATTRIBUTES (t)); + tree class_has_hot_attr + = lookup_attribute ("hot", TYPE_ATTRIBUTES (t)); + + if (class_has_cold_attr || class_has_hot_attr) + for (tree f = TYPE_FIELDS (t); f; f = DECL_CHAIN (f)) + if (TREE_CODE (f) == FUNCTION_DECL) + maybe_propagate_warmth_attributes (f, t); +} + tree finish_struct (tree t, tree attributes) { diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 0ca4370..a673a60 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -3135,6 +3135,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, unsigned save_heap_alloc_count = ctx->global->heap_vars.length (); unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count; + /* Make sure we fold std::is_constant_evaluated to true in an + immediate function. */ + if (DECL_IMMEDIATE_FUNCTION_P (fun)) + call_ctx.manifestly_const_eval = mce_true; + /* If this is a constexpr destructor, the object's const and volatile semantics are no longer in effect; see [class.dtor]p5. */ if (new_obj && DECL_DESTRUCTOR_P (fun)) @@ -3807,8 +3812,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, } /* Subroutine of cxx_eval_constant_expression. - Attempt to evaluate condition expressions. Dead branches are not - looked into. */ + Attempt to evaluate condition expressions. */ static tree cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, @@ -3837,12 +3841,25 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, boolean_type_node); } /* Don't VERIFY_CONSTANT the other operands. */ - if (integer_zerop (val)) + const bool zero_p = integer_zerop (val); + if (zero_p) val = TREE_OPERAND (t, 2); else val = TREE_OPERAND (t, 1); if (TREE_CODE (t) == IF_STMT && !val) val = void_node; + + /* P2564: a subexpression of a manifestly constant-evaluated expression + or conversion is an immediate function context. */ + if (ctx->manifestly_const_eval != mce_true + && !in_immediate_context () + && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2), + ctx->manifestly_const_eval)) + { + *non_constant_p = true; + return t; + } + /* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still serve as the initializer for the same object as the outer TARGET_EXPR, as in diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index 206e791..bdf6e5f 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -53,6 +53,8 @@ enum fold_flags { definitely not in a manifestly constant-evaluated context. */ ff_mce_false = 1 << 1, + /* Whether we're being called from cp_fold_immediate. */ + ff_fold_immediate = 1 << 2, }; using fold_flags_t = int; @@ -1000,7 +1002,7 @@ cp_genericize_target_expr (tree *stmt_p) replacement when cp_folding TARGET_EXPR to preserve the invariant that AGGR_INIT_EXPR_SLOT agrees with the enclosing TARGET_EXPR_SLOT. */ -bool +static bool maybe_replace_decl (tree *tp, tree decl, tree replacement) { if (!*tp || !VOID_TYPE_P (TREE_TYPE (*tp))) @@ -1029,44 +1031,95 @@ struct cp_genericize_data bool handle_invisiref_parm_p; }; -/* Perform any pre-gimplification folding of C++ front end trees to - GENERIC. - Note: The folding of non-omp cases is something to move into - the middle-end. As for now we have most foldings only on GENERIC - in fold-const, we need to perform this before transformation to - GIMPLE-form. */ +/* A subroutine of cp_fold_r to handle immediate functions. */ static tree -cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) +cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, void *data_) { - cp_fold_data *data = (cp_fold_data*)data_; + auto data = static_cast<cp_fold_data *>(data_); tree stmt = *stmt_p; - enum tree_code code = TREE_CODE (stmt); + /* The purpose of this is not to emit errors for mce_unknown. */ + const tsubst_flags_t complain = (data->flags & ff_mce_false + ? tf_error : tf_none); - switch (code) + /* No need to look into types or unevaluated operands. + NB: This affects cp_fold_r as well. */ + if (TYPE_P (stmt) || unevaluated_p (TREE_CODE (stmt))) + { + *walk_subtrees = 0; + return NULL_TREE; + } + + switch (TREE_CODE (stmt)) { + /* Unfortunately we must handle code like + false ? bar () : 42 + where we have to check bar too. The cp_fold call in cp_fold_r could + fold the ?: into a constant before we see it here. */ + case COND_EXPR: + /* If we are called from cp_fold_immediate, we don't need to worry about + cp_fold folding away the COND_EXPR. */ + if (data->flags & ff_fold_immediate) + break; + if (TREE_OPERAND (stmt, 1) + && cp_walk_tree (&TREE_OPERAND (stmt, 1), cp_fold_immediate_r, data, + nullptr)) + return error_mark_node; + if (TREE_OPERAND (stmt, 2) + && cp_walk_tree (&TREE_OPERAND (stmt, 2), cp_fold_immediate_r, data, + nullptr)) + return error_mark_node; + /* We're done here. Don't clear *walk_subtrees here though: we're called + from cp_fold_r and we must let it recurse on the expression with + cp_fold. */ + break; case PTRMEM_CST: if (TREE_CODE (PTRMEM_CST_MEMBER (stmt)) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (stmt))) { - if (!data->pset.add (stmt)) - error_at (PTRMEM_CST_LOCATION (stmt), - "taking address of an immediate function %qD", - PTRMEM_CST_MEMBER (stmt)); - stmt = *stmt_p = build_zero_cst (TREE_TYPE (stmt)); - break; + if (!data->pset.add (stmt) && (complain & tf_error)) + { + error_at (PTRMEM_CST_LOCATION (stmt), + "taking address of an immediate function %qD", + PTRMEM_CST_MEMBER (stmt)); + *stmt_p = build_zero_cst (TREE_TYPE (stmt)); + } + return error_mark_node; } break; + /* Expand immediate invocations. */ + case CALL_EXPR: + case AGGR_INIT_EXPR: + if (tree fn = cp_get_callee (stmt)) + if (TREE_CODE (fn) != ADDR_EXPR || ADDR_EXPR_DENOTES_CALL_P (fn)) + if (tree fndecl = cp_get_fndecl_from_callee (fn, /*fold*/false)) + if (DECL_IMMEDIATE_FUNCTION_P (fndecl)) + { + stmt = cxx_constant_value (stmt, complain); + if (stmt == error_mark_node) + { + if (complain & tf_error) + *stmt_p = error_mark_node; + return error_mark_node; + } + *stmt_p = stmt; + } + break; + case ADDR_EXPR: if (TREE_CODE (TREE_OPERAND (stmt, 0)) == FUNCTION_DECL - && DECL_IMMEDIATE_FUNCTION_P (TREE_OPERAND (stmt, 0))) + && DECL_IMMEDIATE_FUNCTION_P (TREE_OPERAND (stmt, 0)) + && !ADDR_EXPR_DENOTES_CALL_P (stmt)) { - error_at (EXPR_LOCATION (stmt), - "taking address of an immediate function %qD", - TREE_OPERAND (stmt, 0)); - stmt = *stmt_p = build_zero_cst (TREE_TYPE (stmt)); - break; + if (complain & tf_error) + { + error_at (EXPR_LOCATION (stmt), + "taking address of an immediate function %qD", + TREE_OPERAND (stmt, 0)); + *stmt_p = build_zero_cst (TREE_TYPE (stmt)); + } + return error_mark_node; } break; @@ -1074,6 +1127,44 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) break; } + return NULL_TREE; +} + +/* A wrapper around cp_fold_immediate_r. Return true if we found + a non-constant immediate function, or taking the address of an + immediate function. */ + +bool +cp_fold_immediate (tree *tp, mce_value manifestly_const_eval) +{ + if (cxx_dialect <= cxx17) + return false; + + fold_flags_t flags = ff_fold_immediate; + if (manifestly_const_eval == mce_false) + flags |= ff_mce_false; + + cp_fold_data data (flags); + return !!cp_walk_tree_without_duplicates (tp, cp_fold_immediate_r, &data); +} + +/* Perform any pre-gimplification folding of C++ front end trees to + GENERIC. + Note: The folding of non-omp cases is something to move into + the middle-end. As for now we have most foldings only on GENERIC + in fold-const, we need to perform this before transformation to + GIMPLE-form. */ + +static tree +cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) +{ + cp_fold_data *data = (cp_fold_data*)data_; + tree stmt = *stmt_p; + enum tree_code code = TREE_CODE (stmt); + + if (cxx_dialect > cxx17) + cp_fold_immediate_r (stmt_p, walk_subtrees, data); + *stmt_p = stmt = cp_fold (*stmt_p, data->flags); if (data->pset.add (stmt)) @@ -1084,7 +1175,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) always the same tree, which the first time cp_fold_r has been called on it had the subtrees walked. */ *walk_subtrees = 0; - return NULL; + return NULL_TREE; } code = TREE_CODE (stmt); @@ -1136,7 +1227,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) } cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL); *walk_subtrees = 0; - return NULL; + return NULL_TREE; case IF_STMT: if (IF_STMT_CONSTEVAL_P (stmt)) @@ -1146,7 +1237,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_r, data, NULL); cp_walk_tree (&IF_SCOPE (stmt), cp_fold_r, data, NULL); *walk_subtrees = 0; - return NULL; + return NULL_TREE; } break; @@ -1183,7 +1274,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) break; } - return NULL; + return NULL_TREE; } /* Fold ALL the trees! FIXME we should be able to remove this, but diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3ca011c..6e34952 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4784,6 +4784,11 @@ get_vec_init_expr (tree t) #define PTRMEM_OK_P(NODE) \ TREE_LANG_FLAG_0 (TREE_CHECK3 ((NODE), ADDR_EXPR, OFFSET_REF, SCOPE_REF)) +/* True if this ADDR_EXPR denotes a function call; that is, it's + fn() rather than &fn. */ +#define ADDR_EXPR_DENOTES_CALL_P(NODE) \ + (ADDR_EXPR_CHECK(NODE)->base.protected_flag) + /* Get the POINTER_TYPE to the METHOD_TYPE associated with this pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true, before using this macro. */ @@ -6580,6 +6585,24 @@ extern int class_dump_id; extern int module_dump_id; extern int raw_dump_id; +/* Whether the current context is manifestly constant-evaluated. + Used by the constexpr machinery to control folding of + __builtin_is_constant_evaluated. */ + +enum class mce_value +{ + /* Unknown, so treat __builtin_is_constant_evaluated as non-constant. */ + mce_unknown = 0, + /* Fold it to true. */ + mce_true = 1, + /* Fold it to false. Primarily used during cp_fold_function and + cp_fully_fold_init. */ + mce_false = -1, +}; +constexpr mce_value mce_unknown = mce_value::mce_unknown; +constexpr mce_value mce_true = mce_value::mce_true; +constexpr mce_value mce_false = mce_value::mce_false; + /* in call.cc */ extern bool check_dtor_name (tree, tree); int magic_varargs_p (tree); @@ -7035,6 +7058,7 @@ extern int parm_index (tree); extern tree vtv_start_verification_constructor_init_function (void); extern tree vtv_finish_verification_constructor_init_function (tree); extern void cp_check_const_attributes (tree); +extern void maybe_propagate_warmth_attributes (tree, tree); /* in error.cc */ extern const char *type_as_string (tree, int); @@ -7317,6 +7341,7 @@ extern tree cp_convert_range_for (tree, tree, tree, cp_decomp *, bool, extern void cp_convert_omp_range_for (tree &, tree &, tree &, tree &, tree &, tree &, tree &, tree &); extern void cp_finish_omp_range_for (tree, tree); +extern bool cp_maybe_parse_omp_decl (tree, tree); extern bool parsing_nsdmi (void); extern bool parsing_function_declarator (); extern bool parsing_default_capturing_generic_lambda_in_template (void); @@ -8354,6 +8379,7 @@ extern tree process_stmt_assume_attribute (tree, tree, location_t); extern bool simple_empty_class_p (tree, tree, tree_code); extern tree fold_builtin_source_location (const_tree); extern tree get_source_location_impl_type (); +extern bool cp_fold_immediate (tree *, mce_value); /* in name-lookup.cc */ extern tree strip_using_decl (tree); @@ -8515,24 +8541,6 @@ struct GTY((for_user)) constexpr_fundef { tree result; }; -/* Whether the current context is manifestly constant-evaluated. - Used by the constexpr machinery to control folding of - __builtin_is_constant_evaluated. */ - -enum class mce_value -{ - /* Unknown, so treat __builtin_is_constant_evaluated as non-constant. */ - mce_unknown = 0, - /* Fold it to true. */ - mce_true = 1, - /* Fold it to false. Primarily used during cp_fold_function and - cp_fully_fold_init. */ - mce_false = -1, -}; -constexpr mce_value mce_unknown = mce_value::mce_unknown; -constexpr mce_value mce_true = mce_value::mce_true; -constexpr mce_value mce_false = mce_value::mce_false; - extern void fini_constexpr (void); extern bool literal_type_p (tree); extern void maybe_save_constexpr_fundef (tree); diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc index c6b52f0..96abfae 100644 --- a/gcc/cp/cvt.cc +++ b/gcc/cp/cvt.cc @@ -1252,7 +1252,9 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) tree type = TREE_TYPE (expr); int is_reference = TYPE_REF_P (TREE_TYPE (TREE_OPERAND (expr, 0))); int is_volatile = TYPE_VOLATILE (type); - int is_complete = COMPLETE_TYPE_P (complete_type (type)); + if (is_volatile) + complete_type (type); + int is_complete = COMPLETE_TYPE_P (type); /* Can't load the value if we don't know the type. */ if (is_volatile && !is_complete) @@ -1412,9 +1414,10 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) { /* External variables might be incomplete. */ tree type = TREE_TYPE (expr); - int is_complete = COMPLETE_TYPE_P (complete_type (type)); - if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning)) + if (TYPE_VOLATILE (type) + && !COMPLETE_TYPE_P (complete_type (type)) + && (complain & tf_warning)) switch (implicit) { case ICV_CAST: diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc index 909a9dc..eb16e63 100644 --- a/gcc/cp/cxx-pretty-print.cc +++ b/gcc/cp/cxx-pretty-print.cc @@ -1121,6 +1121,15 @@ cxx_pretty_printer::expression (tree t) t = OVL_FIRST (t); /* FALLTHRU */ case VAR_DECL: + if (DECL_NTTP_OBJECT_P (t)) + { + /* Print the type followed by the CONSTRUCTOR value of the + NTTP object. */ + simple_type_specifier (cv_unqualified (TREE_TYPE (t))); + expression (DECL_INITIAL (t)); + break; + } + /* FALLTHRU */ case PARM_DECL: case FIELD_DECL: case CONST_DECL: @@ -1261,6 +1270,14 @@ cxx_pretty_printer::expression (tree t) pp_cxx_right_paren (this); break; + case VIEW_CONVERT_EXPR: + if (TREE_CODE (TREE_OPERAND (t, 0)) == TEMPLATE_PARM_INDEX) + { + /* Strip const VIEW_CONVERT_EXPR wrappers for class NTTPs. */ + expression (TREE_OPERAND (t, 0)); + break; + } + /* FALLTHRU */ default: c_pretty_printer::expression (t); break; @@ -1966,8 +1983,6 @@ pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t) if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL && TYPE_P (DECL_TEMPLATE_RESULT (arg)))) pp->type_id (arg); - else if (VAR_P (arg) && DECL_NTTP_OBJECT_P (arg)) - pp->expression (DECL_INITIAL (arg)); else pp->expression (arg); } diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index b402bef..113b031 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -1604,6 +1604,50 @@ cp_check_const_attributes (tree attributes) } } +/* Copies hot or cold attributes to a function FN if present on the + encapsulating class, struct, or union TYPE. */ + +void +maybe_propagate_warmth_attributes (tree fn, tree type) +{ + if (fn == NULL_TREE || type == NULL_TREE + || !(TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE)) + return; + + tree has_cold_attr = lookup_attribute ("cold", TYPE_ATTRIBUTES (type)); + tree has_hot_attr = lookup_attribute ("hot", TYPE_ATTRIBUTES (type)); + + if (has_cold_attr || has_hot_attr) + { + /* Transparently ignore the new warmth attribute if it + conflicts with a present function attribute. Otherwise + decl_attribute would still honour the present attribute, + but producing an undesired warning in the process. */ + + if (has_cold_attr) + { + if (lookup_attribute ("hot", DECL_ATTRIBUTES (fn)) == NULL) + { + tree cold_cons + = tree_cons (get_identifier ("cold"), NULL, NULL); + + decl_attributes (&fn, cold_cons, 0); + } + } + else if (has_hot_attr) + { + if (lookup_attribute ("cold", DECL_ATTRIBUTES (fn)) == NULL) + { + tree hot_cons + = tree_cons (get_identifier ("hot"), NULL, NULL); + + decl_attributes (&fn, hot_cons, 0); + } + } + } +} + /* Return the last pushed declaration for the symbol DECL or NULL when no such declaration exists. */ @@ -1738,16 +1782,34 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) { tree name = get_attribute_name (*pa); if (is_attribute_p ("directive", name) - || is_attribute_p ("sequence", name)) + || is_attribute_p ("sequence", name) + || is_attribute_p ("decl", name)) { - if (!diagnosed) + const char *p = NULL; + if (TREE_VALUE (*pa) == NULL_TREE) + p = IDENTIFIER_POINTER (name); + for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a)) + { + tree d = TREE_VALUE (a); + gcc_assert (TREE_CODE (d) == DEFERRED_PARSE); + if (TREE_PUBLIC (d) + && (VAR_P (*decl) + || TREE_CODE (*decl) == FUNCTION_DECL) + && cp_maybe_parse_omp_decl (*decl, d)) + continue; + p = TREE_PUBLIC (d) ? "decl" : "directive"; + } + if (p && !diagnosed) { - error ("%<omp::%E%> not allowed to be specified in this " - "context", name); + error ("%<omp::%s%> not allowed to be specified in " + "this context", p); diagnosed = true; } - *pa = TREE_CHAIN (*pa); - continue; + if (p) + { + *pa = TREE_CHAIN (*pa); + continue; + } } } pa = &TREE_CHAIN (*pa); diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc index 39e80df..9272719 100644 --- a/gcc/cp/mapper-client.cc +++ b/gcc/cp/mapper-client.cc @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-core.h" #include "mapper-client.h" #include "intl.h" +#include "mkdeps.h" #include "../../c++tools/resolver.h" @@ -132,6 +133,7 @@ spawn_mapper_program (char const **errmsg, std::string &name, module_client * module_client::open_module_client (location_t loc, const char *o, + class mkdeps *deps, void (*set_repo) (const char *), char const *full_program_name) { @@ -285,6 +287,9 @@ module_client::open_module_client (location_t loc, const char *o, errmsg = "opening"; else { + /* Add the mapper file to the dependency tracking. */ + if (deps) + deps_add_dep (deps, name.c_str ()); if (int l = r->read_tuple_file (fd, ident, false)) { if (l > 0) diff --git a/gcc/cp/mapper-client.h b/gcc/cp/mapper-client.h index b32723c..a3b0b8a 100644 --- a/gcc/cp/mapper-client.h +++ b/gcc/cp/mapper-client.h @@ -55,6 +55,7 @@ public: public: static module_client *open_module_client (location_t loc, const char *option, + class mkdeps *, void (*set_repo) (const char *), char const *); static void close_module_client (location_t loc, module_client *); diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 4ba0017..a70dd5d 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -3592,6 +3592,12 @@ lazily_declare_fn (special_function_kind sfk, tree type) /* Create appropriate clones. */ clone_cdtor (fn, /*update_methods=*/true); + /* Classes, structs or unions TYPE marked with hotness attributes propagate + the attribute to all methods. This is typically done in + check_bases_and_members, but we must also inject them here for deferred + lazily-declared functions. */ + maybe_propagate_warmth_attributes (fn, type); + return fn; } diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index ea362bd..77c9edc 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -3969,12 +3969,12 @@ static GTY(()) vec<tree, va_gc> *partial_specializations; /* Our module mapper (created lazily). */ module_client *mapper; -static module_client *make_mapper (location_t loc); -inline module_client *get_mapper (location_t loc) +static module_client *make_mapper (location_t loc, class mkdeps *deps); +inline module_client *get_mapper (location_t loc, class mkdeps *deps) { auto *res = mapper; if (!res) - res = make_mapper (loc); + res = make_mapper (loc, deps); return res; } @@ -14033,7 +14033,7 @@ get_module (const char *ptr) /* Create a new mapper connecting to OPTION. */ module_client * -make_mapper (location_t loc) +make_mapper (location_t loc, class mkdeps *deps) { timevar_start (TV_MODULE_MAPPER); const char *option = module_mapper_name; @@ -14041,7 +14041,7 @@ make_mapper (location_t loc) option = getenv ("CXX_MODULE_MAPPER"); mapper = module_client::open_module_client - (loc, option, &set_cmi_repo, + (loc, option, deps, &set_cmi_repo, (save_decoded_options[0].opt_index == OPT_SPECIAL_program_name) && save_decoded_options[0].arg != progname ? save_decoded_options[0].arg : nullptr); @@ -18968,6 +18968,9 @@ module_state::do_import (cpp_reader *reader, bool outermost) dump () && dump ("CMI is %s", file); if (note_module_cmi_yes || inform_cmi_p) inform (loc, "reading CMI %qs", file); + /* Add the CMI file to the dependency tracking. */ + if (cpp_get_deps (reader)) + deps_add_dep (cpp_get_deps (reader), file); fd = open (file, O_RDONLY | O_CLOEXEC | O_BINARY); e = errno; } @@ -19503,7 +19506,7 @@ maybe_translate_include (cpp_reader *reader, line_maps *lmaps, location_t loc, dump.push (NULL); dump () && dump ("Checking include translation '%s'", path); - auto *mapper = get_mapper (cpp_main_loc (reader)); + auto *mapper = get_mapper (cpp_main_loc (reader), cpp_get_deps (reader)); size_t len = strlen (path); path = canonicalize_header_name (NULL, loc, true, path, len); @@ -19619,7 +19622,7 @@ module_begin_main_file (cpp_reader *reader, line_maps *lmaps, static void name_pending_imports (cpp_reader *reader) { - auto *mapper = get_mapper (cpp_main_loc (reader)); + auto *mapper = get_mapper (cpp_main_loc (reader), cpp_get_deps (reader)); if (!vec_safe_length (pending_imports)) /* Not doing anything. */ @@ -19834,7 +19837,8 @@ preprocessed_module (cpp_reader *reader) && (module->is_interface () || module->is_partition ())) deps_add_module_target (deps, module->get_flatname (), maybe_add_cmi_prefix (module->filename), - module->is_header()); + module->is_header (), + module->is_exported ()); else deps_add_module_dep (deps, module->get_flatname ()); } @@ -20088,7 +20092,7 @@ init_modules (cpp_reader *reader) if (!flag_module_lazy) /* Get the mapper now, if we're not being lazy. */ - get_mapper (cpp_main_loc (reader)); + get_mapper (cpp_main_loc (reader), cpp_get_deps (reader)); if (!flag_preprocess_only) { @@ -20298,7 +20302,7 @@ late_finish_module (cpp_reader *reader, module_processing_cookie *cookie, if (!errorcount) { - auto *mapper = get_mapper (cpp_main_loc (reader)); + auto *mapper = get_mapper (cpp_main_loc (reader), cpp_get_deps (reader)); mapper->ModuleCompiled (state->get_flatname ()); } else if (cookie->cmi_name) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index e776bb8..a8b9229 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -8402,12 +8402,24 @@ finish_using_directive (tree target, tree attribs) else if ((flag_openmp || flag_openmp_simd) && get_attribute_namespace (a) == omp_identifier && (is_attribute_p ("directive", name) - || is_attribute_p ("sequence", name))) + || is_attribute_p ("sequence", name) + || is_attribute_p ("decl", name))) { if (!diagnosed) - error ("%<omp::%E%> not allowed to be specified in this " - "context", name); - diagnosed = true; + { + if (tree ar = TREE_VALUE (a)) + { + tree d = TREE_VALUE (ar); + gcc_assert (TREE_CODE (d) == DEFERRED_PARSE); + error ("%<omp::%s%> not allowed to be specified in " + "this context", + TREE_PUBLIC (d) ? "decl" : "directive"); + } + else + error ("%<omp::%E%> not allowed to be specified in this " + "context", name); + diagnosed = true; + } } else warning (OPT_Wattributes, "%qD attribute directive ignored", name); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 8808da3..0e1cbbf 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "c-family/known-headers.h" #include "contracts.h" #include "bitmap.h" +#include "builtins.h" /* The lexer. */ @@ -7906,6 +7907,47 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, = parser->non_integral_constant_expression_p; parser->integral_constant_expression_p = false; } + else if (TREE_CODE (stripped_expression) == FUNCTION_DECL + && fndecl_built_in_p (stripped_expression, + BUILT_IN_CLASSIFY_TYPE)) + { + /* __builtin_classify_type (type) */ + auto cl1 = make_temp_override + (parser->type_definition_forbidden_message, + G_("types may not be defined in " + "%<__builtin_classify_type%> calls")); + auto cl2 = make_temp_override + (parser->type_definition_forbidden_message_arg, + NULL); + auto cl3 = make_temp_override (parser->in_type_id_in_expr_p, + true); + cp_unevaluated uev; + cp_parser_parse_tentatively (parser); + matching_parens parens; + parens.consume_open (parser); + tree type = cp_parser_type_id (parser); + parens.require_close (parser); + if (cp_parser_parse_definitely (parser)) + { + if (dependent_type_p (type)) + { + postfix_expression = build_vl_exp (CALL_EXPR, 4); + CALL_EXPR_FN (postfix_expression) + = stripped_expression; + CALL_EXPR_STATIC_CHAIN (postfix_expression) = type; + CALL_EXPR_ARG (postfix_expression, 0) + = build_min (SIZEOF_EXPR, size_type_node, type); + TREE_TYPE (postfix_expression) = integer_type_node; + } + else + { + postfix_expression + = build_int_cst (integer_type_node, + type_to_class (type)); + } + break; + } + } args = (cp_parser_parenthesized_expression_list (parser, non_attr, /*cast_p=*/false, /*allow_expansion_p=*/true, @@ -12001,6 +12043,12 @@ cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs) parser->omp_attrs_forbidden_p = false; bad = true; } + else if (TREE_PUBLIC (d)) + { + error_at (first->location, + "OpenMP %<omp::decl%> attribute on a statement"); + bad = true; + } const char *directive[3] = {}; for (int i = 0; i < 3; i++) { @@ -12022,8 +12070,9 @@ cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs) if (dir == NULL) { error_at (first->location, - "unknown OpenMP directive name in %<omp::directive%>" - " attribute argument"); + "unknown OpenMP directive name in %qs attribute " + "argument", + TREE_PUBLIC (d) ? "omp::decl" : "omp::directive"); continue; } c_omp_directive_kind kind = dir->kind; @@ -29366,7 +29415,7 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */) parsing. */ static void -cp_parser_omp_directive_args (cp_parser *parser, tree attribute) +cp_parser_omp_directive_args (cp_parser *parser, tree attribute, bool decl_p) { cp_token *first = cp_lexer_peek_nth_token (parser->lexer, 2); if (first->type == CPP_CLOSE_PAREN) @@ -29393,6 +29442,8 @@ cp_parser_omp_directive_args (cp_parser *parser, tree attribute) tree arg = make_node (DEFERRED_PARSE); DEFPARSE_TOKENS (arg) = cp_token_cache_new (first, last); DEFPARSE_INSTANTIATIONS (arg) = nullptr; + if (decl_p) + TREE_PUBLIC (arg) = 1; TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute)); } @@ -29440,7 +29491,7 @@ cp_parser_omp_sequence_args (cp_parser *parser, tree attribute) cp_parser_required_error (parser, RT_OPEN_PAREN, false, UNKNOWN_LOCATION); else if (directive) - cp_parser_omp_directive_args (parser, attribute); + cp_parser_omp_directive_args (parser, attribute, false); else cp_parser_omp_sequence_args (parser, attribute); if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) @@ -29592,7 +29643,8 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns) if ((flag_openmp || flag_openmp_simd) && attr_ns == omp_identifier && (is_attribute_p ("directive", attr_id) - || is_attribute_p ("sequence", attr_id))) + || is_attribute_p ("sequence", attr_id) + || is_attribute_p ("decl", attr_id))) { error_at (token->location, "%<omp::%E%> attribute requires argument", attr_id); @@ -29636,7 +29688,14 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns) { if (is_attribute_p ("directive", attr_id)) { - cp_parser_omp_directive_args (parser, attribute); + cp_parser_omp_directive_args (parser, attribute, false); + return attribute; + } + else if (is_attribute_p ("decl", attr_id)) + { + TREE_VALUE (TREE_PURPOSE (attribute)) + = get_identifier ("directive"); + cp_parser_omp_directive_args (parser, attribute, true); return attribute; } else if (is_attribute_p ("sequence", attr_id)) @@ -37912,6 +37971,21 @@ static tree cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list, bool allow_deref = false) { + if (parser->lexer->in_omp_decl_attribute) + { + if (kind) + { + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + tree u = build_omp_clause (loc, kind); + OMP_CLAUSE_DECL (u) = parser->lexer->in_omp_decl_attribute; + OMP_CLAUSE_CHAIN (u) = list; + return u; + } + else + return tree_cons (parser->lexer->in_omp_decl_attribute, NULL_TREE, + list); + } + if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return cp_parser_omp_var_list_no_open (parser, kind, list, NULL, allow_deref); @@ -47843,7 +47917,9 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs) { error_at (first->location, "unknown OpenMP directive name in " - "%<omp::directive%> attribute argument"); + "%qs attribute argument", + TREE_PUBLIC (d) + ? "omp::decl" : "omp::directive"); continue; } if (dir->id != PRAGMA_OMP_DECLARE @@ -47949,6 +48025,89 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs) return attrs; } +/* D should be DEFERRED_PARSE from omp::decl attribute. If it contains + a threadprivate, groupprivate, allocate or declare target directive, + return true and parse it for DECL. */ + +bool +cp_maybe_parse_omp_decl (tree decl, tree d) +{ + gcc_assert (TREE_CODE (d) == DEFERRED_PARSE); + cp_token *first = DEFPARSE_TOKENS (d)->first; + cp_token *last = DEFPARSE_TOKENS (d)->last; + const char *directive[3] = {}; + for (int j = 0; j < 3; j++) + { + tree id = NULL_TREE; + if (first + j == last) + break; + if (first[j].type == CPP_NAME) + id = first[j].u.value; + else if (first[j].type == CPP_KEYWORD) + id = ridpointers[(int) first[j].keyword]; + else + break; + directive[j] = IDENTIFIER_POINTER (id); + } + const c_omp_directive *dir = NULL; + if (directive[0]) + dir = c_omp_categorize_directive (directive[0], directive[1], + directive[2]); + if (dir == NULL) + { + error_at (first->location, + "unknown OpenMP directive name in " + "%qs attribute argument", "omp::decl"); + return false; + } + if (dir->id != PRAGMA_OMP_THREADPRIVATE + /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */ + && dir->id != PRAGMA_OMP_ALLOCATE + && (dir->id != PRAGMA_OMP_DECLARE + || strcmp (directive[1], "target") != 0)) + return false; + + if (!flag_openmp && !dir->simd) + return true; + + cp_parser *parser = the_parser; + cp_lexer *lexer = cp_lexer_alloc (); + lexer->debugging_p = parser->lexer->debugging_p; + lexer->in_omp_decl_attribute = decl; + vec_safe_reserve (lexer->buffer, last - first + 3, true); + cp_token tok = {}; + tok.type = CPP_PRAGMA; + tok.keyword = RID_MAX; + tok.u.value = build_int_cst (NULL, dir->id); + tok.location = first->location; + lexer->buffer->quick_push (tok); + while (++first < last) + lexer->buffer->quick_push (*first); + tok = {}; + tok.type = CPP_PRAGMA_EOL; + tok.keyword = RID_MAX; + tok.location = last->location; + lexer->buffer->quick_push (tok); + tok = {}; + tok.type = CPP_EOF; + tok.keyword = RID_MAX; + tok.location = last->location; + lexer->buffer->quick_push (tok); + lexer->next = parser->lexer; + lexer->next_token = lexer->buffer->address (); + lexer->last_token = lexer->next_token + + lexer->buffer->length () + - 1; + lexer->in_omp_attribute_pragma = true; + parser->lexer = lexer; + /* Move the current source position to that of the first token in the + new lexer. */ + cp_lexer_set_source_position_from_token (lexer->next_token); + cp_parser_pragma (parser, pragma_external, NULL); + + return true; +} + /* Helper for cp_parser_omp_declare_target, handle one to or link clause on #pragma omp declare target. Return false if errors were reported. */ @@ -48048,7 +48207,8 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok) clauses = cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK, "#pragma omp declare target", pragma_tok); - else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + else if (parser->lexer->in_omp_decl_attribute + || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) { clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER, clauses); diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index 6cbb9a8..9ba8021 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -107,6 +107,10 @@ struct GTY (()) cp_lexer { /* The next lexer in a linked list of lexers. */ struct cp_lexer *next; + /* Set for omp::decl attribute parsing to the decl to which it + appertains. */ + tree in_omp_decl_attribute; + /* True if we should output debugging information. */ bool debugging_p; diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index a40b895..5c300f4 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "gcc-rich-location.h" #include "selftest.h" #include "target.h" +#include "builtins.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ @@ -14370,7 +14371,7 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, /* Calculate the complete set of arguments used to specialize R. */ - if (use_spec_table) + if (use_spec_table && !lambda_fntype) { argvec = tsubst_template_args (DECL_TI_ARGS (DECL_TEMPLATE_RESULT @@ -14380,14 +14381,11 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, 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); - } + 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; @@ -14704,6 +14702,8 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, /* Type partial instantiations are stored as the type by lookup_template_class_1, not here as the template. */ spec = CLASSTYPE_TI_TEMPLATE (spec); + else if (TREE_CODE (spec) != TEMPLATE_DECL) + spec = DECL_TI_TEMPLATE (spec); return spec; } } @@ -14754,7 +14754,7 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, inner = tsubst_aggr_type (inner, args, complain, in_decl, /*entering*/1); else - inner = tsubst (inner, args, complain, in_decl); + inner = tsubst_decl (inner, args, complain, /*use_spec_table=*/false); } --processing_template_decl; if (inner == error_mark_node) @@ -14780,12 +14780,11 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, } else { - if (TREE_CODE (inner) == FUNCTION_DECL) - /* Set DECL_TI_ARGS to the full set of template arguments, which - tsubst_function_decl didn't do due to use_spec_table=false. */ - DECL_TI_ARGS (inner) = full_args; - DECL_TI_TEMPLATE (inner) = r; + /* Set DECL_TI_ARGS to the full set of template arguments, + which tsubst_function_decl / tsubst_decl didn't do due to + use_spec_table=false. */ + DECL_TI_ARGS (inner) = full_args; DECL_TI_ARGS (r) = DECL_TI_ARGS (inner); } @@ -14813,9 +14812,17 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, if (PRIMARY_TEMPLATE_P (t)) DECL_PRIMARY_TEMPLATE (r) = r; - if (TREE_CODE (decl) == FUNCTION_DECL && !lambda_fntype) - /* Record this non-type partial instantiation. */ - register_specialization (r, t, full_args, false, hash); + if (!lambda_fntype && !class_p) + { + /* Record this non-type partial instantiation. */ + /* FIXME we'd like to always register the TEMPLATE_DECL, or always + the DECL_TEMPLATE_RESULT, but it seems the modules code relies + on this current behavior. */ + if (TREE_CODE (inner) == FUNCTION_DECL) + register_specialization (r, t, full_args, false, hash); + else + register_specialization (inner, t, full_args, false, hash); + } return r; } @@ -21031,6 +21038,25 @@ tsubst_copy_and_build (tree t, /*done=*/false, /*address_p=*/false); } + else if (CALL_EXPR_STATIC_CHAIN (t) + && TREE_CODE (function) == FUNCTION_DECL + && fndecl_built_in_p (function, BUILT_IN_CLASSIFY_TYPE)) + { + tree type = tsubst (CALL_EXPR_STATIC_CHAIN (t), args, complain, + in_decl); + if (dependent_type_p (type)) + { + ret = build_vl_exp (CALL_EXPR, 4); + CALL_EXPR_FN (ret) = function; + CALL_EXPR_STATIC_CHAIN (ret) = type; + CALL_EXPR_ARG (ret, 0) + = build_min (SIZEOF_EXPR, size_type_node, type); + TREE_TYPE (ret) = integer_type_node; + } + else + ret = build_int_cst (integer_type_node, type_to_class (type)); + RETURN (ret); + } else if (koenig_p && (identifier_p (function) || (TREE_CODE (function) == TEMPLATE_ID_EXPR @@ -23990,8 +24016,7 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg, return NULL_TREE; else if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM) /* Matches anything. */; - else if (most_general_template (CLASSTYPE_TI_TEMPLATE (arg)) - != most_general_template (CLASSTYPE_TI_TEMPLATE (parm))) + else if (CLASSTYPE_TI_TEMPLATE (arg) != CLASSTYPE_TI_TEMPLATE (parm)) return NULL_TREE; /* We need to make a new template argument vector for the call to @@ -24032,8 +24057,10 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg, if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM) err = unify_bound_ttp_args (tparms, targs, parm, arg, explain_p); else - err = unify (tparms, targs, CLASSTYPE_TI_ARGS (parm), - CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE, explain_p); + err = unify (tparms, targs, + INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (parm)), + INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (arg)), + UNIFY_ALLOW_NONE, explain_p); return err ? NULL_TREE : arg; } @@ -24559,7 +24586,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, even if ARG == PARM, since we won't record unifications for the template parameters. We might need them if we're trying to figure out which of two things is more specialized. */ - if (arg == parm && !uses_template_parms (parm)) + if (arg == parm + && (DECL_P (parm) || !uses_template_parms (parm))) return unify_success (explain_p); /* Handle init lists early, so the rest of the function can assume @@ -25158,8 +25186,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, /* There's no chance of unification succeeding. */ return unify_type_mismatch (explain_p, parm, arg); - return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm), - CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE, explain_p); + if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))) + return unify (tparms, targs, + INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (parm)), + INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (t)), + UNIFY_ALLOW_NONE, explain_p); + else + return unify_success (explain_p); } else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg)) return unify_type_mismatch (explain_p, parm, arg); @@ -25278,11 +25311,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, strict, explain_p); case CONST_DECL: - if (DECL_TEMPLATE_PARM_P (parm)) - return unify (tparms, targs, DECL_INITIAL (parm), arg, strict, explain_p); - if (arg != scalar_constant_value (parm)) - return unify_template_argument_mismatch (explain_p, parm, arg); - return unify_success (explain_p); + /* CONST_DECL should already have been folded to its DECL_INITIAL. */ + gcc_unreachable (); case FIELD_DECL: case TEMPLATE_DECL: diff --git a/gcc/cp/ptree.cc b/gcc/cp/ptree.cc index b400148..32c5b52 100644 --- a/gcc/cp/ptree.cc +++ b/gcc/cp/ptree.cc @@ -141,9 +141,8 @@ cxx_print_decl (FILE *file, tree node, int indent) void cxx_print_type (FILE *file, tree node, int indent) { - if (TYPE_LANG_SPECIFIC (node) - && TYPE_TEMPLATE_INFO (node)) - print_node (file, "template-info", TYPE_TEMPLATE_INFO (node), indent + 4); + if (tree ti = TYPE_TEMPLATE_INFO (node)) + print_node (file, "template-info", ti, indent + 4); switch (TREE_CODE (node)) { diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 0f7f4e8..80ef136 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -881,13 +881,17 @@ maybe_convert_cond (tree cond) /* Do the conversion. */ cond = convert_from_reference (cond); - if ((TREE_CODE (cond) == MODIFY_EXPR || is_assignment_op_expr_p (cond)) + tree inner = REFERENCE_REF_P (cond) ? TREE_OPERAND (cond, 0) : cond; + if ((TREE_CODE (inner) == MODIFY_EXPR + || (TREE_CODE (inner) == MODOP_EXPR + && TREE_CODE (TREE_OPERAND (inner, 1)) == NOP_EXPR) + || is_assignment_op_expr_p (inner)) && warn_parentheses - && !warning_suppressed_p (cond, OPT_Wparentheses) - && warning_at (cp_expr_loc_or_input_loc (cond), + && !warning_suppressed_p (inner, OPT_Wparentheses) + && warning_at (cp_expr_loc_or_input_loc (inner), OPT_Wparentheses, "suggest parentheses around " "assignment used as truth value")) - suppress_warning (cond, OPT_Wparentheses); + suppress_warning (inner, OPT_Wparentheses); return condition_conversion (cond); } @@ -2155,8 +2159,11 @@ cp_expr finish_parenthesized_expr (cp_expr expr) { if (EXPR_P (expr)) - /* This inhibits warnings in c_common_truthvalue_conversion. */ - suppress_warning (expr, OPT_Wparentheses); + { + /* This inhibits warnings in c_common_truthvalue_conversion. */ + tree inner = REFERENCE_REF_P (expr) ? TREE_OPERAND (expr, 0) : *expr; + suppress_warning (inner, OPT_Wparentheses); + } if (TREE_CODE (expr) == OFFSET_REF || TREE_CODE (expr) == SCOPE_REF) @@ -11599,6 +11606,14 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, case TEMPLATE_PARM_INDEX: expr = mark_type_use (expr); type = TREE_TYPE (expr); + if (VAR_P (expr) && DECL_NTTP_OBJECT_P (expr)) + { + /* decltype of an NTTP object is the type of the template + parameter, which is the object type modulo cv-quals. */ + int quals = cp_type_quals (type); + gcc_checking_assert (quals & TYPE_QUAL_CONST); + type = cv_unqualified (type); + } break; case ERROR_MARK: diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 799183d..eaf882f 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -3254,7 +3254,7 @@ bot_manip (tree* tp, int* walk_subtrees, void* data_) variables. */ static tree -bot_replace (tree* t, int* walk_subtrees, void* data_) +bot_replace (tree* t, int */*walk_subtrees*/, void* data_) { bot_data &data = *(bot_data*)data_; splay_tree target_remap = data.target_remap; @@ -3284,27 +3284,6 @@ bot_replace (tree* t, int* walk_subtrees, void* data_) /*check_access=*/false, /*nonnull=*/true, tf_warning_or_error); } - else if (cxx_dialect >= cxx20 - && (TREE_CODE (*t) == CALL_EXPR - || TREE_CODE (*t) == AGGR_INIT_EXPR) - && !in_immediate_context ()) - { - /* Expand immediate invocations. */ - if (tree fndecl = cp_get_callee_fndecl_nofold (*t)) - if (DECL_IMMEDIATE_FUNCTION_P (fndecl)) - { - /* Make in_immediate_context true within the args. */ - in_consteval_if_p_temp_override ito; - in_consteval_if_p = true; - int nargs = call_expr_nargs (*t); - for (int i = 0; i < nargs; ++i) - cp_walk_tree (&get_nth_callarg (*t, i), bot_replace, data_, NULL); - *t = cxx_constant_value (*t); - if (*t == error_mark_node) - return error_mark_node; - *walk_subtrees = 0; - } - } return NULL_TREE; } diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 459739d..8132bd7 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -9721,13 +9721,13 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, if (lhs == error_mark_node || rhs == error_mark_node) return cp_expr (error_mark_node, loc); + tree op = build_min (modifycode, void_type_node, NULL_TREE, NULL_TREE); + if (processing_template_decl) { - if (modifycode == NOP_EXPR - || type_dependent_expression_p (lhs) + if (type_dependent_expression_p (lhs) || type_dependent_expression_p (rhs)) { - tree op = build_min_nt_loc (loc, modifycode, NULL_TREE, NULL_TREE); tree rval = build_min_nt_loc (loc, MODOP_EXPR, lhs, op, rhs); if (modifycode != NOP_EXPR) TREE_TYPE (rval) @@ -9739,29 +9739,24 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, rhs = build_non_dependent_expr (rhs); } - if (modifycode != NOP_EXPR) + tree rval; + if (modifycode == NOP_EXPR) + rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, complain); + else + rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL, + lhs, rhs, op, lookups, &overload, complain); + if (rval == error_mark_node) + return error_mark_node; + if (processing_template_decl) { - tree op = build_nt (modifycode, NULL_TREE, NULL_TREE); - tree rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL, - lhs, rhs, op, lookups, &overload, complain); - if (rval) - { - if (rval == error_mark_node) - return rval; - suppress_warning (rval /* What warning? */); - if (processing_template_decl) - { - if (overload != NULL_TREE) - return (build_min_non_dep_op_overload - (MODIFY_EXPR, rval, overload, orig_lhs, orig_rhs)); + if (overload != NULL_TREE) + return (build_min_non_dep_op_overload + (MODIFY_EXPR, rval, overload, orig_lhs, orig_rhs)); - return (build_min_non_dep - (MODOP_EXPR, rval, orig_lhs, op, orig_rhs)); - } - return rval; - } + return (build_min_non_dep + (MODOP_EXPR, rval, orig_lhs, op, orig_rhs)); } - return cp_build_modify_expr (loc, lhs, modifycode, rhs, complain); + return rval; } /* Helper function for get_delta_difference which assumes FROM is a base diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 947c05b..b4770f1 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2874,7 +2874,10 @@ improving code locality of non-cold parts of program. The paths leading to calls of cold functions within code are marked as unlikely by the branch prediction mechanism. It is thus useful to mark functions used to handle unlikely conditions, such as @code{perror}, as cold to improve optimization -of hot functions that do call marked functions in rare occasions. +of hot functions that do call marked functions in rare occasions. In C++, +the @code{cold} attribute can be applied to types with the effect of being +propagated to member functions. See +@ref{C++ Attributes}. When profile feedback is available, via @option{-fprofile-use}, cold functions are automatically detected and this attribute is ignored. @@ -3293,7 +3296,9 @@ The @code{hot} attribute on a function is used to inform the compiler that the function is a hot spot of the compiled program. The function is optimized more aggressively and on many targets it is placed into a special subsection of the text section so all hot functions appear close together, -improving locality. +improving locality. In C++, the @code{hot} attribute can be applied to types +with the effect of being propagated to member functions. See +@ref{C++ Attributes}. When profile feedback is available, via @option{-fprofile-use}, hot functions are automatically detected and this attribute is ignored. @@ -14555,6 +14560,30 @@ need not be a constant. @xref{Object Size Checking}, for a detailed description of the function. @enddefbuiltin +@defbuiltin{int __builtin_classify_type (@var{arg})} +@defbuiltinx{int __builtin_classify_type (@var{type})} +The @code{__builtin_classify_type} returns a small integer with a category +of @var{arg} argument's type, like void type, integer type, enumeral type, +boolean type, pointer type, reference type, offset type, real type, complex +type, function type, method type, record type, union type, array type, +string type, etc. When the argument is an expression, for +backwards compatibility reason the argument is promoted like arguments +passed to @code{...} in varargs function, so some classes are never returned +in certain languages. Alternatively, the argument of the built-in +function can be a typename, such as the @code{typeof} specifier. + +@smallexample +int a[2]; +__builtin_classify_type (a) == __builtin_classify_type (int[5]); +__builtin_classify_type (a) == __builtin_classify_type (void*); +__builtin_classify_type (typeof (a)) == __builtin_classify_type (int[5]); +@end smallexample + +The first comparison will never be true, as @var{a} is implicitly converted +to pointer. The last two comparisons will be true as they classify +pointers in the second case and arrays in the last case. +@enddefbuiltin + @defbuiltin{double __builtin_huge_val (void)} Returns a positive infinity, if supported by the floating-point format, else @code{DBL_MAX}. This function is suitable for implementing the @@ -25605,6 +25634,34 @@ control a resource, such as @code{std::lock_guard}. This attribute is also accepted in C, but it is unnecessary because C does not have constructors or destructors. +@cindex @code{cold} type attribute +@item cold + +In addition to functions and labels, GNU C++ allows the @code{cold} +attribute to be used on C++ classes, structs, or unions. Applying +the @code{cold} attribute on a type has the effect of treating every +member function of the type, including implicit special member +functions, as cold. If a member function is marked with the +@code{hot} function attribute, the @code{hot} attribute takes +precedence and the @code{cold} attribute is not propagated. + +For the effects of the @code{cold} attribute on functions, see +@ref{Common Function Attributes}. + +@cindex @code{hot} type attribute +@item hot + +In addition to functions and labels, GNU C++ allows the @code{hot} +attribute to be used on C++ classes, structs, or unions. Applying +the @code{hot} attribute on a type has the effect of treating every +member function of the type, including implicit special member +functions, as hot. If a member function is marked with the +@code{cold} function attribute, the @code{cold} attribute takes +precedence and the @code{hot} attribute is not propagated. + +For the effects of the @code{hot} attribute on functions, see +@ref{Common Function Attributes}. + @end table @node Function Multiversioning diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi index bae822f..d7bb18a 100644 --- a/gcc/doc/gm2.texi +++ b/gcc/doc/gm2.texi @@ -392,7 +392,7 @@ implementation modules which are parsed will be prepossessed by @item -fdebug-builtins call a real function, rather than the builtin equivalent. This can be useful for debugging parameter values to a builtin function as -it allows users to single step code into a real function. +it allows users to single step code into an intrinsic function. @c fd @c Modula-2 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 03d93e6..ba7984b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2830,6 +2830,33 @@ is @option{-fpermitted-flt-eval-methods=c11}. The default when in a GNU dialect (@option{-std=gnu11} or similar) is @option{-fpermitted-flt-eval-methods=ts-18661-3}. +@opindex fdeps- +The @samp{-fdeps-*} options are used to extract structured dependency +information for a source. This involves determining what resources provided by +other source files will be required to compile the source as well as what +resources are provided by the source. This information can be used to add +required dependencies between compilation rules of dependent sources based on +their contents rather than requiring such information be reflected within the +build tools as well. + +@opindex fdeps-file +@item -fdeps-file=@var{file} +Where to write structured dependency information. + +@opindex fdeps-format +@item -fdeps-format=@var{format} +The format to use for structured dependency information. @samp{p1689r5} is the +only supported format right now. Note that when this argument is specified, the +output of @samp{-MF} is stripped of some information (namely C++ modules) so +that it does not use extended makefile syntax not understood by most tools. + +@opindex fdeps-target +@item -fdeps-target=@var{file} +Analogous to @option{-MT} but for structured dependency information. This +indicates the target which will ultimately need any required resources and +provide any resources extracted from the source that may be required by other +sources. + @opindex fplan9-extensions @item -fplan9-extensions Accept some non-standard constructs used in Plan 9 code. @@ -16321,6 +16348,13 @@ crossing a loop backedge when comparing to Maximum number of nested calls to search for control dependencies during uninitialized variable analysis. +@item uninit-max-chain-len +Maximum number of predicates anded for each predicate ored in the normalized +predicate chain. + +@item uninit-max-num-chains +Maximum number of predicates ored in the normalized predicate chain. + @item sched-autopref-queue-depth Hardware autoprefetcher scheduler model control flag. Number of lookahead cycles the model looks into; at ' diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index c4a935d..f60a065 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -29247,6 +29247,7 @@ output_macinfo (const char *debug_line_label, bool early_lto_debug) case DW_MACINFO_define: case DW_MACINFO_undef: if ((!dwarf_strict || dwarf_version >= 5) + && !dwarf_split_debug_info && HAVE_COMDAT_GROUP && vec_safe_length (files) != 1 && i > 0 diff --git a/gcc/expr.cc b/gcc/expr.cc index d5b6494..308ddc0 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -11044,17 +11044,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode); unsigned int limb_prec = GET_MODE_PRECISION (limb_mode); - if (prec > limb_prec) + if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE) { - scalar_int_mode arith_mode - = (targetm.scalar_mode_supported_p (TImode) - ? TImode : DImode); - if (prec > GET_MODE_PRECISION (arith_mode)) - { - /* Emit large/huge _BitInt INTEGER_CSTs into memory. */ - exp = tree_output_constant_def (exp); - return expand_expr (exp, target, VOIDmode, modifier); - } + /* Emit large/huge _BitInt INTEGER_CSTs into memory. */ + exp = tree_output_constant_def (exp); + return expand_expr (exp, target, VOIDmode, modifier); } } diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 0c95a3a..6e773d9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2023-09-19 Harald Anlauf <anlauf@gmx.de> + + PR fortran/70231 + * trans-array.cc (trans_array_constructor): In absence of a typespec, + use string length determined by get_array_ctor_strlen() to reasonably + initialize auxiliary variable for bounds-checking. + 2023-09-15 Harald Anlauf <anlauf@gmx.de> PR fortran/30802 diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 1640587..e0fc8eb 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -2852,6 +2852,23 @@ trans_array_constructor (gfc_ss * ss, locus * where) const_string = get_array_ctor_strlen (&outer_loop->pre, c, &ss_info->string_length); force_new_cl = true; + + /* Initialize "len" with string length for bounds checking. */ + if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) + && !typespec_chararray_ctor + && ss_info->string_length) + { + gfc_se length_se; + + gfc_init_se (&length_se, NULL); + gfc_add_modify (&length_se.pre, first_len_val, + fold_convert (TREE_TYPE (first_len_val), + ss_info->string_length)); + ss_info->string_length = gfc_evaluate_now (ss_info->string_length, + &length_se.pre); + gfc_add_block_to_block (&outer_loop->pre, &length_se.pre); + gfc_add_block_to_block (&outer_loop->post, &length_se.post); + } } /* Complex character array constructors should have been taken care of @@ -447,6 +447,7 @@ static const char *greater_than_spec_func (int, const char **); static const char *debug_level_greater_than_spec_func (int, const char **); static const char *dwarf_version_greater_than_spec_func (int, const char **); static const char *find_fortran_preinclude_file (int, const char **); +static const char *join_spec_func (int, const char **); static char *convert_white_space (char *); static char *quote_spec (char *); static char *quote_spec_arg (char *); @@ -1235,7 +1236,9 @@ static const char *cpp_unique_options = %{remap} %{%:debug-level-gt(2):-dD}\ %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\ %{H} %C %{D*&U*&A*} %{i*} %Z %i\ - %{E|M|MM:%W{o*}}"; + %{E|M|MM:%W{o*}}\ + %{fdeps-format=*:%{!fdeps-file=*:-fdeps-file=%:join(%{!o:%b.ddi}%{o*:%.ddi%*})}}\ + %{fdeps-format=*:%{!fdeps-target=*:-fdeps-target=%:join(%{!o:%b.o}%{o*:%.o%*})}}"; /* This contains cpp options which are common with cc1_options and are passed only when preprocessing only to avoid duplication. We pass the cc1 spec @@ -1772,6 +1775,7 @@ static const struct spec_function static_spec_functions[] = { "debug-level-gt", debug_level_greater_than_spec_func }, { "dwarf-version-gt", dwarf_version_greater_than_spec_func }, { "fortran-preinclude-file", find_fortran_preinclude_file}, + { "join", join_spec_func}, #ifdef EXTRA_SPEC_FUNCTIONS EXTRA_SPEC_FUNCTIONS #endif @@ -10975,6 +10979,27 @@ find_fortran_preinclude_file (int argc, const char **argv) return result; } +/* The function takes any number of arguments and joins them together. + + This seems to be necessary to build "-fjoined=foo.b" from "-fseparate foo.a" + with a %{fseparate*:-fjoined=%.b$*} rule without adding undesired spaces: + when doing $* replacement we first replace $* with the rest of the switch + (in this case ""), and then add any arguments as arguments after the result, + resulting in "-fjoined= foo.b". Using this function with e.g. + %{fseparate*:-fjoined=%:join(%.b$*)} gets multiple words as separate argv + elements instead of separated by spaces, and we paste them together. */ + +static const char * +join_spec_func (int argc, const char **argv) +{ + if (argc == 1) + return argv[0]; + for (int i = 0; i < argc; ++i) + obstack_grow (&obstack, argv[i], strlen (argv[i])); + obstack_1grow (&obstack, '\0'); + return XOBFINISH (&obstack, const char *); +} + /* If any character in ORIG fits QUOTE_P (_, P), reallocate the string so as to precede every one of them with a backslash. Return the original string or the reallocated one. */ diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index cf4bcfc..d1651a0 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -100,21 +100,19 @@ bitint_precision_kind (int prec) small_max_prec = prec; return bitint_prec_small; } - scalar_int_mode arith_mode = (targetm.scalar_mode_supported_p (TImode) - ? TImode : DImode); if (!large_min_prec - && GET_MODE_PRECISION (arith_mode) > GET_MODE_PRECISION (limb_mode)) - large_min_prec = GET_MODE_PRECISION (arith_mode) + 1; + && GET_MODE_PRECISION (limb_mode) < MAX_FIXED_MODE_SIZE) + large_min_prec = MAX_FIXED_MODE_SIZE + 1; if (!limb_prec) limb_prec = GET_MODE_PRECISION (limb_mode); if (!huge_min_prec) { - if (4 * limb_prec >= GET_MODE_PRECISION (arith_mode)) + if (4 * limb_prec >= MAX_FIXED_MODE_SIZE) huge_min_prec = 4 * limb_prec; else - huge_min_prec = GET_MODE_PRECISION (arith_mode) + 1; + huge_min_prec = MAX_FIXED_MODE_SIZE + 1; } - if (prec <= GET_MODE_PRECISION (arith_mode)) + if (prec <= MAX_FIXED_MODE_SIZE) { if (!mid_min_prec || prec < mid_min_prec) mid_min_prec = prec; diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc index 373163b..ad2c355 100644 --- a/gcc/gimple-predicate-analysis.cc +++ b/gcc/gimple-predicate-analysis.cc @@ -50,8 +50,8 @@ /* In our predicate normal form we have MAX_NUM_CHAINS or predicates and in those MAX_CHAIN_LEN (inverted) and predicates. */ -#define MAX_NUM_CHAINS 8 -#define MAX_CHAIN_LEN 5 +#define MAX_NUM_CHAINS (unsigned)param_uninit_max_num_chains +#define MAX_CHAIN_LEN (unsigned)param_uninit_max_chain_len /* Return true if X1 is the negation of X2. */ @@ -1163,11 +1163,12 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb, vec<edge> cd_chains[], unsigned *num_chains, unsigned in_region = 0) { - auto_vec<edge, MAX_CHAIN_LEN + 1> cur_cd_chain; + auto_vec<edge, 10> cur_cd_chain; unsigned num_calls = 0; unsigned depth = 0; bool complete_p = true; /* Walk the post-dominator chain. */ + cur_cd_chain.reserve (MAX_CHAIN_LEN + 1); compute_control_dep_chain_pdom (dom_bb, dep_bb, NULL, cd_chains, num_chains, cur_cd_chain, &num_calls, in_region, depth, &complete_p); @@ -2035,7 +2036,7 @@ uninit_analysis::init_use_preds (predicate &use_preds, basic_block def_bb, are logical conjunctions. Together, the DEP_CHAINS vector is used below to initialize an OR expression of the conjunctions. */ unsigned num_chains = 0; - auto_vec<edge> dep_chains[MAX_NUM_CHAINS]; + auto_vec<edge> *dep_chains = new auto_vec<edge>[MAX_NUM_CHAINS]; if (!dfs_mark_dominating_region (use_bb, cd_root, in_region, region) || !compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains, @@ -2060,6 +2061,7 @@ uninit_analysis::init_use_preds (predicate &use_preds, basic_block def_bb, Each OR subexpression is represented by one element of DEP_CHAINS, where each element consists of a series of AND subexpressions. */ use_preds.init_from_control_deps (dep_chains, num_chains, true); + delete[] dep_chains; return !use_preds.is_empty (); } @@ -2144,7 +2146,7 @@ uninit_analysis::init_from_phi_def (gphi *phi) break; unsigned num_chains = 0; - auto_vec<edge> dep_chains[MAX_NUM_CHAINS]; + auto_vec<edge> *dep_chains = new auto_vec<edge>[MAX_NUM_CHAINS]; for (unsigned i = 0; i < nedges; i++) { edge e = def_edges[i]; @@ -2175,6 +2177,7 @@ uninit_analysis::init_from_phi_def (gphi *phi) which the PHI operands are defined to values for which M_EVAL is false. */ m_phi_def_preds.init_from_control_deps (dep_chains, num_chains, false); + delete[] dep_chains; return !m_phi_def_preds.is_empty (); } diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc index 82017b9..320df91 100644 --- a/gcc/gimple-pretty-print.cc +++ b/gcc/gimple-pretty-print.cc @@ -480,7 +480,7 @@ dump_binary_rhs (pretty_printer *buffer, const gassign *gs, int spc, else dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false); pp_space (buffer); - pp_string (buffer, op_symbol_code (gimple_assign_rhs_code (gs))); + pp_string (buffer, op_symbol_code (gimple_assign_rhs_code (gs), flags)); pp_space (buffer); if (op_prio (gimple_assign_rhs2 (gs)) <= op_code_prio (code)) { @@ -1092,7 +1092,7 @@ dump_gimple_cond (pretty_printer *buffer, const gcond *gs, int spc, flags | ((flags & TDF_GIMPLE) ? TDF_GIMPLE_VAL : TDF_NONE), false); pp_space (buffer); - pp_string (buffer, op_symbol_code (gimple_cond_code (gs))); + pp_string (buffer, op_symbol_code (gimple_cond_code (gs), flags)); pp_space (buffer); dump_generic_node (buffer, gimple_cond_rhs (gs), spc, flags | ((flags & TDF_GIMPLE) ? TDF_GIMPLE_VAL : TDF_NONE), diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 5b74681..3c81993 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -606,7 +606,7 @@ ssa_cache::set_range (tree name, const vrange &r) } // If NAME has a range, intersect it with R, otherwise set it to R. -// Return TRUE if there was already a range set, otherwise false. +// Return TRUE if the range is new or changes. bool ssa_cache::merge_range (tree name, const vrange &r) @@ -616,19 +616,23 @@ ssa_cache::merge_range (tree name, const vrange &r) m_tab.safe_grow_cleared (num_ssa_names + 1); vrange_storage *m = m_tab[v]; - if (m) + // Check if this is a new value. + if (!m) + m_tab[v] = m_range_allocator->clone (r); + else { Value_Range curr (TREE_TYPE (name)); m->get_vrange (curr, TREE_TYPE (name)); - curr.intersect (r); + // If there is no change, return false. + if (!curr.intersect (r)) + return false; + if (m->fits_p (curr)) m->set_vrange (curr); else m_tab[v] = m_range_allocator->clone (curr); } - else - m_tab[v] = m_range_allocator->clone (r); - return m != NULL; + return true; } // Set the range for NAME to R in the ssa cache. @@ -656,27 +660,14 @@ ssa_cache::clear () void ssa_cache::dump (FILE *f) { - /* Cleared after the table header has been printed. */ - bool print_header = true; for (unsigned x = 1; x < num_ssa_names; x++) { if (!gimple_range_ssa_p (ssa_name (x))) continue; Value_Range r (TREE_TYPE (ssa_name (x))); - // Invoke dump_range_query which is a private virtual version of - // get_range. This avoids performance impacts on general queries, - // but allows sharing of the dump routine. + // Dump all non-varying ranges. if (get_range (r, ssa_name (x)) && !r.varying_p ()) { - if (print_header) - { - /* Print the header only when there's something else - to print below. */ - fprintf (f, "Non-varying global ranges:\n"); - fprintf (f, "=========================:\n"); - print_header = false; - } - print_generic_expr (f, ssa_name (x), TDF_NONE); fprintf (f, " : "); r.dump (f); @@ -684,8 +675,6 @@ ssa_cache::dump (FILE *f) } } - if (!print_header) - fputc ('\n', f); } // Return true if NAME has an active range in the cache. @@ -716,7 +705,7 @@ ssa_lazy_cache::set_range (tree name, const vrange &r) } // If NAME has a range, intersect it with R, otherwise set it to R. -// Return TRUE if there was already a range set, otherwise false. +// Return TRUE if the range is new or changes. bool ssa_lazy_cache::merge_range (tree name, const vrange &r) @@ -731,7 +720,7 @@ ssa_lazy_cache::merge_range (tree name, const vrange &r) if (v >= m_tab.length ()) m_tab.safe_grow (num_ssa_names + 1); m_tab[v] = m_range_allocator->clone (r); - return false; + return true; } // Return TRUE if NAME has a range, and return it in R. @@ -996,6 +985,8 @@ ranger_cache::~ranger_cache () void ranger_cache::dump (FILE *f) { + fprintf (f, "Non-varying global ranges:\n"); + fprintf (f, "=========================:\n"); m_globals.dump (f); fprintf (f, "\n"); } diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index a0e8cc2..9f4722f 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "tree-pretty-print.h" #include "diagnostic-core.h" +#include "diagnostic.h" /* For errorcount. */ #include "alias.h" #include "fold-const.h" #include "calls.h" @@ -1372,6 +1373,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t))) != NULL_TREE) { + gcc_assert (!DECL_HAS_VALUE_EXPR_P (t)); tree alloc = TREE_PURPOSE (TREE_VALUE (attr)); tree align = TREE_VALUE (TREE_VALUE (attr)); /* Allocate directives that appear in a target region must specify @@ -1396,12 +1398,56 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) error_at (DECL_SOURCE_LOCATION (t), "%<allocate%> directive for %qD inside a target " "region must specify an %<allocator%> clause", t); - else if (align != NULL_TREE - || alloc == NULL_TREE - || !integer_onep (alloc)) - sorry_at (DECL_SOURCE_LOCATION (t), - "OpenMP %<allocate%> directive, used for %qD, not " - "yet supported", t); + /* Skip for omp_default_mem_alloc (= 1), + unless align is present. */ + else if (!errorcount + && (align != NULL_TREE + || alloc == NULL_TREE + || !integer_onep (alloc))) + { + tree tmp = build_pointer_type (TREE_TYPE (t)); + tree v = create_tmp_var (tmp, get_name (t)); + DECL_IGNORED_P (v) = 0; + tmp = remove_attribute ("omp allocate", DECL_ATTRIBUTES (t)); + DECL_ATTRIBUTES (v) + = tree_cons (get_identifier ("omp allocate var"), + build_tree_list (NULL_TREE, t), tmp); + tmp = build_fold_indirect_ref (v); + TREE_THIS_NOTRAP (tmp) = 1; + SET_DECL_VALUE_EXPR (t, tmp); + DECL_HAS_VALUE_EXPR_P (t) = 1; + tree sz = TYPE_SIZE_UNIT (TREE_TYPE (t)); + if (alloc == NULL_TREE) + alloc = build_zero_cst (ptr_type_node); + if (align == NULL_TREE) + align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t)); + else + align = build_int_cst (size_type_node, + MAX (tree_to_uhwi (align), + DECL_ALIGN_UNIT (t))); + tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC); + tmp = build_call_expr_loc (DECL_SOURCE_LOCATION (t), tmp, + 3, align, sz, alloc); + tmp = fold_build2_loc (DECL_SOURCE_LOCATION (t), MODIFY_EXPR, + TREE_TYPE (v), v, + fold_convert (TREE_TYPE (v), tmp)); + gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE + && (TREE_CODE (BIND_EXPR_BODY (bind_expr)) + == STATEMENT_LIST)); + tree_stmt_iterator e = tsi_start (BIND_EXPR_BODY (bind_expr)); + while (!tsi_end_p (e)) + { + if ((TREE_CODE (*e) == DECL_EXPR + && TREE_OPERAND (*e, 0) == t) + || (TREE_CODE (*e) == CLEANUP_POINT_EXPR + && TREE_CODE (TREE_OPERAND (*e, 0)) == DECL_EXPR + && TREE_OPERAND (TREE_OPERAND (*e, 0), 0) == t)) + break; + ++e; + } + gcc_assert (!tsi_end_p (e)); + tsi_link_before (&e, tmp, TSI_SAME_STMT); + } } /* Mark variable as local. */ @@ -1486,22 +1532,6 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) cleanup = NULL; stack_save = NULL; - /* If the code both contains VLAs and calls alloca, then we cannot reclaim - the stack space allocated to the VLAs. */ - if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack) - { - gcall *stack_restore; - - /* Save stack on entry and restore it on exit. Add a try_finally - block to achieve this. */ - build_stack_save_restore (&stack_save, &stack_restore); - - gimple_set_location (stack_save, start_locus); - gimple_set_location (stack_restore, end_locus); - - gimplify_seq_add_stmt (&cleanup, stack_restore); - } - /* Add clobbers for all variables that go out of scope. */ for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t)) { @@ -1509,6 +1539,17 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) && !is_global_var (t) && DECL_CONTEXT (t) == current_function_decl) { + if (flag_openmp + && DECL_HAS_VALUE_EXPR_P (t) + && TREE_USED (t) + && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t))) + { + tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE); + tmp = build_call_expr_loc (end_locus, tmp, 2, + TREE_OPERAND (DECL_VALUE_EXPR (t), 0), + build_zero_cst (ptr_type_node)); + gimplify_and_add (tmp, &cleanup); + } if (!DECL_HARD_REGISTER (t) && !TREE_THIS_VOLATILE (t) && !DECL_HAS_VALUE_EXPR_P (t) @@ -1565,6 +1606,22 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) gimplify_ctxp->live_switch_vars->remove (t); } + /* If the code both contains VLAs and calls alloca, then we cannot reclaim + the stack space allocated to the VLAs. */ + if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack) + { + gcall *stack_restore; + + /* Save stack on entry and restore it on exit. Add a try_finally + block to achieve this. */ + build_stack_save_restore (&stack_save, &stack_restore); + + gimple_set_location (stack_save, start_locus); + gimple_set_location (stack_restore, end_locus); + + gimplify_seq_add_stmt (&cleanup, stack_restore); + } + if (ret_clauses) { gomp_target *stmt; @@ -7894,6 +7951,13 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) if (error_operand_p (decl)) return false; + if (DECL_ARTIFICIAL (decl)) + { + tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl)); + if (attr) + decl = TREE_VALUE (TREE_VALUE (attr)); + } + if (ctx->region_type == ORT_NONE) return lang_hooks.decls.omp_disregard_value_expr (decl, false); diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 0fd3435..61d5a9e 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -247,6 +247,10 @@ expand_fn_using_insn (gcall *stmt, insn_code icode, unsigned int noutputs, create_convert_operand_from (&ops[opno], rhs_rtx, TYPE_MODE (rhs_type), TYPE_UNSIGNED (rhs_type)); + else if (TREE_CODE (rhs) == SSA_NAME + && SSA_NAME_IS_DEFAULT_DEF (rhs) + && VAR_P (SSA_NAME_VAR (rhs))) + create_undefined_input_operand (&ops[opno], TYPE_MODE (rhs_type)); else create_input_operand (&ops[opno], rhs_rtx, TYPE_MODE (rhs_type)); opno += 1; diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc index 5807d6d..f2e8ea3 100644 --- a/gcc/ira-color.cc +++ b/gcc/ira-color.cc @@ -3150,13 +3150,15 @@ improve_allocation (void) int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords; int check, spill_cost, min_cost, nregs, conflict_nregs, r, best; bool try_p; - enum reg_class aclass; + enum reg_class aclass, rclass; machine_mode mode; int *allocno_costs; int costs[FIRST_PSEUDO_REGISTER]; HARD_REG_SET conflicting_regs[2], profitable_hard_regs; ira_allocno_t a; bitmap_iterator bi; + int saved_nregs; + int add_cost; /* Don't bother to optimize the code with static chain pointer and non-local goto in order not to spill the chain pointer @@ -3194,6 +3196,7 @@ improve_allocation (void) conflicting_regs, &profitable_hard_regs); class_size = ira_class_hard_regs_num[aclass]; + mode = ALLOCNO_MODE (a); /* Set up cost improvement for usage of each profitable hard register for allocno A. */ for (j = 0; j < class_size; j++) @@ -3207,6 +3210,22 @@ improve_allocation (void) costs[hregno] = (allocno_costs == NULL ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]); costs[hregno] -= allocno_copy_cost_saving (a, hregno); + + if ((saved_nregs = calculate_saved_nregs (hregno, mode)) != 0) + { + /* We need to save/restore the hard register in + epilogue/prologue. Therefore we increase the cost. + Since the prolog is placed in the entry BB, the frequency + of the entry BB is considered while computing the cost. */ + rclass = REGNO_REG_CLASS (hregno); + add_cost = ((ira_memory_move_cost[mode][rclass][0] + + ira_memory_move_cost[mode][rclass][1]) + * saved_nregs / hard_regno_nregs (hregno, + mode) - 1) + * REG_FREQ_FROM_BB (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + costs[hregno] += add_cost; + } + costs[hregno] -= base_cost; if (costs[hregno] < 0) try_p = true; @@ -30,6 +30,9 @@ along with GCC; see the file COPYING3. If not see Supports creating a DOM-like tree of json::value *, and then dumping json::value * to text. */ +/* TODO: `libcpp/mkdeps.cc` wants JSON writing support for p1689r5 output; + extract this code and move to libiberty. */ + namespace json { diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 77325bd..d98880e 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,12 @@ +2023-09-19 Thomas Schwinge <thomas@codesourcery.com> + Pan Li <pan2.li@intel.com> + + * lto-common.cc (lto_mode_identity_table): Remove. + (lto_file_finalize) [!ACCEL_COMPILER]: 'NULL'-intialize + 'file_data->mode_table'. + (lto_fe_init): Don't initialize 'lto_mode_identity_table'. + * lto-common.h (lto_mode_identity_table): Remove. + 2023-07-05 Robin Dapp <rdapp@ventanamicro.com> Juzhe-Zhong <juzhe.zhong@rivai.ai> diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc index 703e665..ad6e7fd 100644 --- a/gcc/lto/lto-common.cc +++ b/gcc/lto/lto-common.cc @@ -64,8 +64,6 @@ static bool type_streaming_finished = false; GTY(()) tree first_personality_decl; -GTY(()) const unsigned char *lto_mode_identity_table; - /* Returns a hash code for P. */ static hashval_t @@ -2277,7 +2275,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file, #ifdef ACCEL_COMPILER lto_input_mode_table (file_data); #else - file_data->mode_table = lto_mode_identity_table; + file_data->mode_table = NULL; file_data->mode_bits = ceil_log2 (MAX_MACHINE_MODE); #endif @@ -3118,13 +3116,6 @@ lto_fe_init (void) memset (<o_stats, 0, sizeof (lto_stats)); bitmap_obstack_initialize (NULL); gimple_register_cfg_hooks (); -#ifndef ACCEL_COMPILER - unsigned char *table - = ggc_vec_alloc<unsigned char> (MAX_MACHINE_MODE); - for (int m = 0; m < MAX_MACHINE_MODE; m++) - table[m] = m; - lto_mode_identity_table = table; -#endif } #include "gt-lto-lto-common.h" diff --git a/gcc/lto/lto-common.h b/gcc/lto/lto-common.h index 24b2445..b9faa72 100644 --- a/gcc/lto/lto-common.h +++ b/gcc/lto/lto-common.h @@ -26,7 +26,6 @@ void print_lto_report_1 (void); extern tree lto_eh_personality_decl; extern GTY(()) vec<tree, va_gc> *tree_with_vars; -extern const unsigned char *lto_mode_identity_table; extern tree first_personality_decl; #endif diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 453daa2..41165cc 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,156 @@ +2023-09-19 Gaius Mulley <gaiusmod2@gmail.com> + + * Make-lang.in (host_mc_longreal): Detect hosting on powerpc64le + and if so use __float128 for longreal in mc. + (MC_ARGS): Append host_mc_longreal. + * config-make.in (TEST_TARGET_CPU_DEFAULT): New variable. + (TEST_HOST_CPU_DEFAULT): New variable. + * configure: Regenerate. + * configure.ac (M2C_LONGREAL_FLOAT128): New define set if target + is powerpc64le. + (M2C_LONGREAL_PPC64LE): New define set if target is powerpc64le. + * gm2-compiler/M2GCCDeclare.mod: Correct comment case. + * gm2-compiler/M2GenGCC.mod (MaybeDebugBuiltinAlloca): Call + SetLastFunction for the builtin function call. + (MaybeDebugBuiltinMemcpy): Call SetLastFunction for the builtin + function call. + (MaybeDebugBuiltinMemset): New procedure function. + (MakeCopyUse): Use GNU formatting. + (UseBuiltin): Rewrite to check BuiltinExists. + (CodeDirectCall): Rewrite to check BuiltinExists and call + SetLastFunction. + (CodeMakeAdr): Re-format. + * gm2-compiler/M2Options.def (SetDebugBuiltins): New procedure. + * gm2-compiler/M2Options.mod (SetUninitVariableChecking): Allow + "cond" to switch UninitVariableConditionalChecking separately. + (SetDebugBuiltins): New procedure. + * gm2-compiler/M2Quads.def (BuildFunctionCall): Add parameter + ConstExpr. + * gm2-compiler/M2Quads.mod (BuildRealProcedureCall): Add parameter + to BuildRealFuncProcCall. + (BuildRealFuncProcCall): Add ConstExpr parameter. Pass ConstExpr + to BuildFunctionCall. + (BuildFunctionCall): Add parameter ConstExpr. Pass ConstExpr to + BuildRealFunctionCall. + (BuildConstFunctionCall): Add parameter ConstExpr. Pass ConstExpr to + BuildFunctionCall. + (BuildRealFunctionCall): Add parameter ConstExpr. Pass ConstExpr to + BuildRealFuncProcCall. + * gm2-compiler/P3Build.bnf (SetOrDesignatorOrFunction): Pass FALSE + to BuildFunctionCall. + (AssignmentOrProcedureCall): Pass FALSE to BuildFunctionCall. + * gm2-compiler/SymbolTable.def (IsProcedureBuiltinAvailable): New + procedure function. + * gm2-compiler/SymbolTable.mod (CanUseBuiltin): New procedure + function. + (IsProcedureBuiltinAvailable): New procedure function. + * gm2-gcc/m2builtins.cc (DEBUGGING): Undef. + (bf_category): New enum type. + (struct builtin_function_entry): New field function_avail. + (m2builtins_BuiltInMemCopy): Rename from ... + (m2builtins_BuiltinMemCopy): ... this. + (DoBuiltinMemSet): New function. + (m2builtins_BuiltinMemSet): New function. + (do_target_support_exists): New function. + (target_support_exists): New function. + (m2builtins_BuiltinExists): Return true or false. + (m2builtins_BuildBuiltinTree): Rename local variables. + Replace long_double_type_node with GetM2LongRealType. + (m2builtins_init): Use GetM2LongRealType rather than + long_double_type_node. + * gm2-gcc/m2builtins.def (BuiltInMemCopy): Rename to ... + (BuiltinMemCopy): ... this. + (BuiltinMemSet): New procedure function. + * gm2-gcc/m2builtins.h (m2builtins_BuiltInMemCopy): Rename to ... + (m2builtins_BuiltinMemCopy): ... this. + (m2builtins_BuiltinMemSet): New procedure function. + * gm2-gcc/m2configure.cc (m2configure_M2CLongRealFloat128): New + procedure function. + (m2configure_M2CLongRealIBM128): New procedure function. + (m2configure_M2CLongRealLongDouble): New procedure function. + (m2configure_M2CLongRealLongDoublePPC64LE): New procedure function. + * gm2-gcc/m2configure.def (M2CLongRealFloat128): New procedure function. + (M2CLongRealIBM128): New procedure function. + (M2CLongRealLongDouble): New procedure function. + (M2CLongRealLongDoublePPC64LE): New procedure function. + * gm2-gcc/m2configure.h (m2configure_FullPathCPP): New procedure function. + (m2configure_M2CLongRealFloat128): New procedure function. + (m2configure_M2CLongRealIBM128): New procedure function. + (m2configure_M2CLongRealLongDouble): New procedure function. + (m2configure_M2CLongRealLongDoublePPC64LE): New procedure function. + * gm2-gcc/m2convert.cc (m2convert_BuildConvert): Use convert_loc. + * gm2-gcc/m2options.h (M2Options_SetDebugBuiltins): New function. + * gm2-gcc/m2statement.cc (m2statement_BuildAssignmentTree): Set + TREE_USED to true. + (m2statement_BuildGoto):Set TREE_USED to true. + (m2statement_BuildParam): Set TREE_USED to true. + (m2statement_BuildBuiltinCallTree): New function. + (m2statement_BuildFunctValue): Set TREE_USED to true. + * gm2-gcc/m2statement.def (BuildBuiltinCallTree): New procedure function. + * gm2-gcc/m2statement.h (m2statement_BuildBuiltinCallTree): New + procedure function. + * gm2-gcc/m2treelib.cc (m2treelib_DoCall0): Remove spacing. + (m2treelib_DoCall1): Remove spacing. + (m2treelib_DoCall2): Remove spacing. + (m2treelib_DoCall3): Remove spacing. + (add_stmt): Rename parameter. + * gm2-gcc/m2type.cc (build_set_type): Remove spacing. + (build_m2_specific_size_type): Remove spacing. + (finish_build_pointer_type): Remove spacing. + (m2type_BuildVariableArrayAndDeclare): Remove spacing. + (build_m2_short_real_node): Remove spacing. + (build_m2_real_node): Remove spacing. + (build_m2_long_real_node): Use float128_type_node if + M2CLongRealFloat128 is set. + (build_m2_ztype_node): Remove spacing. + (build_m2_long_int_node): Remove spacing. + (build_m2_long_card_node): Remove spacing. + (build_m2_short_int_node): Remove spacing. + (build_m2_short_card_node): Remove spacing. + (build_m2_iso_loc_node): Remove spacing. + (m2type_SameRealType): New function. + (m2type_InitBaseTypes): Create m2_c_type_node using + m2_long_complex_type_node. + (m2type_SetAlignment): Tidy up comment. + * gm2-gcc/m2type.def (SameRealType): New procedure function. + * gm2-gcc/m2type.h (m2type_SameRealType): New procedure function. + * gm2-lang.cc (gm2_langhook_type_for_mode): Build long complex + node from m2 language specific long double node. + * gm2-libs-log/RealConversions.mod (IsNan): New procedure + function. + (doPowerOfTen): Re-implement. + * gm2-libs/Builtins.mod: Add newline. + * gm2-libs/DynamicStrings.def (ReplaceChar): New procedure function. + * gm2-libs/DynamicStrings.mod (ReplaceChar): New procedure function. + * gm2config.aci.in (M2C_LONGREAL_FLOAT128): New config value. + (M2C_LONGREAL_PPC64LE): New config value. + * gm2spec.cc (lang_specific_driver): New local variable + need_default_mabi set to default value depending upon + M2C_LONGREAL_PPC64LE and M2C_LONGREAL_FLOAT128. + * lang.opt (Wcase-enum): Moved to correct section. + * m2pp.cc (m2pp_real_type): New function. + (m2pp_type): Call m2pp_real_type. + (m2pp_print_mode): New function. + (m2pp_simple_type): Call m2pp_simple_type. + (m2pp_float): New function. + (m2pp_expression): Call m2pp_float. + * mc-boot/GDynamicStrings.cc: Rebuild. + * mc-boot/GDynamicStrings.h: Rebuild. + * mc-boot/GFIO.cc: Rebuild. + * mc-boot/GFIO.h: Rebuild. + * mc-boot/GIO.cc: Rebuild. + * mc-boot/GRTint.cc: Rebuild. + * mc-boot/Gdecl.cc: Rebuild. + * mc-boot/GmcOptions.cc: Rebuild. + * mc-boot/GmcOptions.h: Rebuild. + * mc/decl.mod: Rebuild. + * mc/mcOptions.def (getCRealType): New procedure function. + (getCLongRealType): New procedure function. + (getCShortRealType): New procedure function. + * mc/mcOptions.mod (getCRealType): New procedure function. + (getCLongRealType): New procedure function. + (getCShortRealType): New procedure function. + 2023-09-14 Gaius Mulley <gaiusmod2@gmail.com> * gm2-compiler/M2CaseList.mod (NewRanges): Add block diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in index 7338bfe..a541518 100644 --- a/gcc/m2/Make-lang.in +++ b/gcc/m2/Make-lang.in @@ -85,6 +85,9 @@ GM2_PROG_DEP=gm2$(exeext) xgcc$(exeext) cc1gm2$(exeext) include m2/config-make +# Determine if float128 should represent the Modula-2 type LONGREAL. +host_mc_longreal := $(if $(strip $(filter powerpc64le%,$(host))),--longreal=__float128) + LIBSTDCXX=../$(TARGET_SUBDIR)/libstdc++-v3/src/.libs/libstdc++.a PGE=m2/pge$(exeext) @@ -458,7 +461,8 @@ MC_ARGS= --olang=c++ \ -I$(srcdir)/m2/gm2-gcc \ --quiet \ $(MC_COPYRIGHT) \ - --gcc-config-system + --gcc-config-system \ + $(host_mc_longreal) MCDEPS=m2/boot-bin/mc$(exeext) diff --git a/gcc/m2/config-make.in b/gcc/m2/config-make.in index fb25ef4..5521d4f 100644 --- a/gcc/m2/config-make.in +++ b/gcc/m2/config-make.in @@ -3,4 +3,8 @@ TARGET_SUBDIR = @target_subdir@ # Python3 executable name if it exists PYTHON = @PYTHON@ # Does Python3 exist? (yes/no). -HAVE_PYTHON = @HAVE_PYTHON@
\ No newline at end of file +HAVE_PYTHON = @HAVE_PYTHON@ +# target cpu +TEST_TARGET_CPU_DEFAULT = @target@ +# host cpu +TEST_HOST_CPU_DEFAULT = @host@
\ No newline at end of file diff --git a/gcc/m2/configure b/gcc/m2/configure index de78fdd..f62f3d8 100755 --- a/gcc/m2/configure +++ b/gcc/m2/configure @@ -3645,6 +3645,25 @@ $as_echo "#define HAVE_OPENDIR 1" >>confdefs.h fi + +case $target in #( + powerpc64le*) : + +$as_echo "#define M2C_LONGREAL_FLOAT128 1" >>confdefs.h + ;; #( + *) : + ;; +esac + +case $target in #( + powerpc64le*) : + +$as_echo "#define M2C_LONGREAL_PPC64LE 1" >>confdefs.h + ;; #( + *) : + ;; +esac + ac_config_headers="$ac_config_headers gm2config.aci" cat >confcache <<\_ACEOF diff --git a/gcc/m2/configure.ac b/gcc/m2/configure.ac index 0a77cae..82b764c 100644 --- a/gcc/m2/configure.ac +++ b/gcc/m2/configure.ac @@ -29,5 +29,12 @@ AC_CHECK_FUNCS([stpcpy]) AC_CHECK_HEADERS(sys/types.h) AC_HEADER_DIRENT AC_CHECK_LIB([c],[opendir],[AC_DEFINE([HAVE_OPENDIR],[1],[found opendir])]) + +AS_CASE([$target],[powerpc64le*], + [AC_DEFINE([M2C_LONGREAL_FLOAT128],[1],[use __float128 for LONGREAL])]) + +AS_CASE([$target],[powerpc64le*], + [AC_DEFINE([M2C_LONGREAL_PPC64LE],[1],[target is ppc64le])]) + AC_CONFIG_HEADERS(gm2config.aci, [echo timestamp > stamp-h]) AC_OUTPUT diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod index 3ce9cb2..87ca0da 100644 --- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod +++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod @@ -2458,7 +2458,7 @@ BEGIN p := NoOfParam(Sym) ; i := p ; WHILE i>0 DO - (* note we dont use GetNthParam as we want the parameter that is seen by + (* Note we dont use GetNthParam as we want the parameter that is seen by the procedure block remember that this is treated exactly the same as a variable, just its position on the activation record is special (ie a parameter). *) diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod index bcef4e7..c023eda 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.mod +++ b/gcc/m2/gm2-compiler/M2GenGCC.mod @@ -52,7 +52,7 @@ FROM SymbolTable IMPORT PushSize, PopSize, PushValue, PopValue, IsExportQualified, IsExported, IsSubrange, IsPointer, - IsProcedureBuiltin, IsProcedureInline, + IsProcedureBuiltinAvailable, IsProcedureInline, IsParameter, IsParameterVar, IsValueSolved, IsSizeSolved, IsProcedureNested, IsInnerModule, IsArrayLarge, @@ -83,7 +83,7 @@ FROM SymbolTable IMPORT PushSize, PopSize, PushValue, PopValue, FROM M2Batch IMPORT MakeDefinitionSource ; FROM M2LexBuf IMPORT FindFileNameFromToken, TokenToLineNo, TokenToLocation, - MakeVirtualTok, UnknownTokenNo ; + MakeVirtualTok, UnknownTokenNo, BuiltinTokenNo ; FROM M2Code IMPORT CodeBlock ; FROM M2Debug IMPORT Assert ; @@ -158,7 +158,8 @@ FROM M2GCCDeclare IMPORT WalkAction, FROM M2Range IMPORT CodeRangeCheck, FoldRangeCheck, CodeErrorCheck, GetMinMax ; -FROM m2builtins IMPORT BuiltInMemCopy, BuiltInAlloca, +FROM m2builtins IMPORT BuiltInAlloca, + BuiltinMemSet, BuiltinMemCopy, GetBuiltinConst, GetBuiltinTypeInfo, BuiltinExists, BuildBuiltinTree ; @@ -228,6 +229,7 @@ FROM m2statement IMPORT BuildAsm, BuildProcedureCallTree, BuildParam, BuildFunct BuildReturnValueCode, SetLastFunction, BuildIncludeVarConst, BuildIncludeVarVar, BuildExcludeVarConst, BuildExcludeVarVar, + BuildBuiltinCallTree, GetParamTree, BuildCleanUp, BuildTryFinally, GetLastFunction, SetLastFunction, @@ -270,6 +272,7 @@ TYPE DoUnaryProcedure = PROCEDURE (CARDINAL) ; VAR + Memset, Memcpy : CARDINAL ; CurrentQuadToken : CARDINAL ; UnboundedLabelNo : CARDINAL ; LastLine : CARDINAL ;(* The Last Line number emitted with the *) @@ -444,6 +447,7 @@ VAR op1, op2, op3: CARDINAL ; location : location_t ; BEGIN + InitBuiltinSyms (BuiltinTokenNo) ; GetQuad(q, op, op1, op2, op3) ; IF op=StatementNoteOp THEN @@ -572,6 +576,7 @@ VAR op3pos : CARDINAL ; Changed: BOOLEAN ; BEGIN + InitBuiltinSyms (BuiltinTokenNo) ; Changed := FALSE ; REPEAT NoChange := TRUE ; @@ -1310,18 +1315,25 @@ END GetSizeOfHighFromUnbounded ; PROCEDURE MaybeDebugBuiltinAlloca (location: location_t; tok: CARDINAL; high: Tree) : Tree ; VAR - func: Tree ; + call, + memptr, + func : Tree ; BEGIN IF DebugBuiltins THEN - func := Mod2Gcc(FromModuleGetSym(tok, - MakeKey('alloca_trace'), - MakeDefinitionSource(tok, - MakeKey('Builtins')))) ; - RETURN( BuildCall2(location, func, GetPointerType(), BuiltInAlloca(location, high), high) ) + func := Mod2Gcc (FromModuleGetSym (tok, + MakeKey ('alloca_trace'), + MakeDefinitionSource (tok, + MakeKey ('Builtins')))) ; + call := BuiltInAlloca (location, high) ; + SetLastFunction (call) ; + memptr := BuildFunctValue (location, call) ; + call := BuildCall2 (location, func, GetPointerType(), memptr, high) ; ELSE - RETURN( BuiltInAlloca(location, high) ) - END + call := BuiltInAlloca (location, high) + END ; + SetLastFunction (call) ; + RETURN BuildFunctValue (location, call) END MaybeDebugBuiltinAlloca ; @@ -1331,22 +1343,44 @@ END MaybeDebugBuiltinAlloca ; PROCEDURE MaybeDebugBuiltinMemcpy (location: location_t; tok: CARDINAL; src, dest, nbytes: Tree) : Tree ; VAR + call, func: Tree ; BEGIN IF DebugBuiltins THEN - func := Mod2Gcc(FromModuleGetSym(tok, - MakeKey('memcpy'), - MakeDefinitionSource(tok, - MakeKey('Builtins')))) ; - RETURN( BuildCall3(location, func, GetPointerType(), src, dest, nbytes) ) + func := Mod2Gcc (Memcpy) ; + call := BuildCall3 (location, func, GetPointerType (), src, dest, nbytes) ; ELSE - RETURN( BuiltInMemCopy(location, src, dest, nbytes) ) - END + call := BuiltinMemCopy (location, src, dest, nbytes) + END ; + SetLastFunction (call) ; + RETURN BuildFunctValue (location, call) END MaybeDebugBuiltinMemcpy ; (* + MaybeDebugBuiltinMemset - +*) + +PROCEDURE MaybeDebugBuiltinMemset (location: location_t; tok: CARDINAL; + ptr, bytevalue, nbytes: Tree) : Tree ; +VAR + call, + func: Tree ; +BEGIN + IF DebugBuiltins + THEN + func := Mod2Gcc (Memset) ; + call := BuildCall3 (location, func, GetPointerType (), ptr, bytevalue, nbytes) ; + ELSE + call := BuiltinMemSet (location, ptr, bytevalue, nbytes) + END ; + SetLastFunction (call) ; + RETURN BuildFunctValue (location, call) +END MaybeDebugBuiltinMemset ; + + +(* MakeCopyUse - make a copy of the unbounded array and alter all references from the old unbounded array to the new unbounded array. The parameter, param, contains a RECORD @@ -1368,7 +1402,7 @@ VAR High, NewArray : Tree ; BEGIN - location := TokenToLocation(tokenno) ; + location := TokenToLocation (tokenno) ; UnboundedType := GetType (param) ; Assert (IsUnbounded (UnboundedType)) ; @@ -1397,20 +1431,20 @@ VAR sym, type: CARDINAL ; BEGIN - IF IsParameter(param) + IF IsParameter (param) THEN - type := GetType(param) ; - sym := GetLocalSym(proc, GetSymName(param)) ; - IF IsUnbounded(type) + type := GetType (param) ; + sym := GetLocalSym (proc, GetSymName (param)) ; + IF IsUnbounded (type) THEN - RETURN( GetAddressOfUnbounded(location, sym) ) + RETURN( GetAddressOfUnbounded (location, sym) ) ELSE - Assert(GetMode(sym)=LeftValue) ; - RETURN( Mod2Gcc(sym) ) + Assert (GetMode (sym) = LeftValue) ; + RETURN( Mod2Gcc (sym) ) END ELSE - Assert(IsVar(param)) ; - Assert(GetMode(param)=LeftValue) ; + Assert (IsVar (param)) ; + Assert (GetMode (param) = LeftValue) ; RETURN( Mod2Gcc(param) ) END END GetParamAddress ; @@ -1927,31 +1961,18 @@ END CodeCall ; (* - CanUseBuiltin - returns TRUE if the procedure, Sym, can be - inlined via a builtin function. -*) - -PROCEDURE CanUseBuiltin (Sym: CARDINAL) : BOOLEAN ; -BEGIN - RETURN( (NOT DebugBuiltins) AND - (BuiltinExists(KeyToCharStar(GetProcedureBuiltin(Sym))) OR - BuiltinExists(KeyToCharStar(GetSymName(Sym)))) ) -END CanUseBuiltin ; - - -(* UseBuiltin - returns a Tree containing the builtin function and parameters. It should only be called if - CanUseBuiltin returns TRUE. + CanUseBuiltin or IsProcedureBuiltinAvailable returns TRUE. *) PROCEDURE UseBuiltin (tokenno: CARDINAL; Sym: CARDINAL) : Tree ; BEGIN IF BuiltinExists(KeyToCharStar(GetProcedureBuiltin(Sym))) THEN - RETURN( BuildBuiltinTree(TokenToLocation (tokenno), KeyToCharStar(GetProcedureBuiltin(Sym))) ) + RETURN( BuildBuiltinTree(TokenToLocation (tokenno), KeyToCharStar (GetProcedureBuiltin (Sym))) ) ELSE - RETURN( BuildBuiltinTree(TokenToLocation (tokenno), KeyToCharStar(GetSymName(Sym))) ) + RETURN( BuildBuiltinTree(TokenToLocation (tokenno), KeyToCharStar (GetSymName (Sym))) ) END END UseBuiltin ; @@ -1963,19 +1984,35 @@ END UseBuiltin ; PROCEDURE CodeDirectCall (tokenno: CARDINAL; procedure: CARDINAL) : Tree ; VAR location: location_t ; + call : Tree ; BEGIN - location := TokenToLocation(tokenno) ; - IF IsProcedureBuiltin(procedure) AND CanUseBuiltin(procedure) + location := TokenToLocation (tokenno) ; + IF IsProcedureBuiltinAvailable (procedure) THEN - RETURN UseBuiltin (tokenno, procedure) + call := UseBuiltin (tokenno, procedure) ; + IF call # NIL + THEN + call := BuildBuiltinCallTree (location, call) + END ELSE - IF GetType(procedure)=NulSym + call := NIL + END ; + IF call = NIL + THEN + IF GetType (procedure) = NulSym THEN - RETURN BuildProcedureCallTree(location, Mod2Gcc(procedure), NIL) + call := BuildProcedureCallTree (location, Mod2Gcc (procedure), NIL) ELSE - RETURN BuildProcedureCallTree(location, Mod2Gcc(procedure), Mod2Gcc(GetType(procedure))) + call := BuildProcedureCallTree (location, Mod2Gcc (procedure), Mod2Gcc (GetType (procedure))) END - END + END ; + IF GetType (procedure) = NulSym + THEN + SetLastFunction (NIL) + ELSE + SetLastFunction (call) + END ; + RETURN call END CodeDirectCall ; @@ -2208,43 +2245,43 @@ BEGIN location := TokenToLocation (CurrentQuadToken) ; n := q ; REPEAT - IF op1>0 + IF op1 > 0 THEN - DeclareConstant(CurrentQuadToken, op3) + DeclareConstant (CurrentQuadToken, op3) END ; - n := GetNextQuad(n) ; - GetQuad(n, op, r, op2, op3) - UNTIL op=FunctValueOp ; + n := GetNextQuad (n) ; + GetQuad (n, op, r, op2, op3) + UNTIL op = FunctValueOp ; n := q ; - GetQuad(n, op, op1, op2, op3) ; - res := Mod2Gcc(r) ; - max := GetSizeOfInBits(Mod2Gcc(Address)) ; - bits := GetIntegerZero(location) ; - val := GetPointerZero(location) ; + GetQuad (n, op, op1, op2, op3) ; + res := Mod2Gcc (r) ; + max := GetSizeOfInBits (Mod2Gcc(Address)) ; + bits := GetIntegerZero (location) ; + val := GetPointerZero (location) ; REPEAT - location := TokenToLocation(CurrentQuadToken) ; - IF (op=ParamOp) AND (op1>0) + location := TokenToLocation (CurrentQuadToken) ; + IF (op = ParamOp) AND (op1 > 0) THEN - IF GetType(op3)=NulSym + IF GetType (op3) = NulSym THEN - WriteFormat0('must supply typed constants to MAKEADR') + WriteFormat0 ('must supply typed constants to MAKEADR') ELSE - type := GetType(op3) ; - tmp := BuildConvert(location, GetPointerType(), Mod2Gcc(op3), FALSE) ; - IF CompareTrees(bits, GetIntegerZero(location))>0 + type := GetType (op3) ; + tmp := BuildConvert (location, GetPointerType (), Mod2Gcc (op3), FALSE) ; + IF CompareTrees (bits, GetIntegerZero (location)) > 0 THEN - tmp := BuildLSL(location, tmp, bits, FALSE) + tmp := BuildLSL (location, tmp, bits, FALSE) END ; - bits := BuildAdd(location, bits, GetSizeOfInBits(Mod2Gcc(type)), FALSE) ; - val := BuildLogicalOrAddress(location, val, tmp, FALSE) + bits := BuildAdd (location, bits, GetSizeOfInBits (Mod2Gcc (type)), FALSE) ; + val := BuildLogicalOrAddress (location, val, tmp, FALSE) END END ; - SubQuad(n) ; - n := GetNextQuad(n) ; - GetQuad(n, op, op1, op2, op3) + SubQuad (n) ; + n := GetNextQuad (n) ; + GetQuad (n, op, op1, op2, op3) UNTIL op=FunctValueOp ; - IF CompareTrees(bits, max)>0 + IF CompareTrees(bits, max) > 0 THEN MetaErrorT0 (CurrentQuadToken, 'total number of bits specified as parameters to {%kMAKEADR} exceeds address width') @@ -2259,11 +2296,15 @@ END CodeMakeAdr ; inlines the SYSTEM function MAKEADR. *) -PROCEDURE CodeBuiltinFunction (q: CARDINAL; op1, op2, op3: CARDINAL) ; +PROCEDURE CodeBuiltinFunction (q: CARDINAL; nth, func, parameter: CARDINAL) ; BEGIN - IF (op1=0) AND (op3=MakeAdr) + IF nth = 0 THEN - CodeMakeAdr (q, op1, op2, op3) + InitBuiltinSyms (BuiltinTokenNo) ; + IF func = MakeAdr + THEN + CodeMakeAdr (q, nth, func, parameter) + END END END CodeBuiltinFunction ; @@ -2294,55 +2335,55 @@ BEGIN IF r>0 THEN TryDeclareConstant (tokenno, op3) ; - IF NOT GccKnowsAbout(op3) + IF NOT GccKnowsAbout (op3) THEN resolved := FALSE END END ; - n := GetNextQuad(n) ; - GetQuad(n, op, r, op2, op3) - UNTIL op=FunctValueOp ; + n := GetNextQuad (n) ; + GetQuad (n, op, r, op2, op3) + UNTIL op = FunctValueOp ; - IF resolved AND IsConst(r) + IF resolved AND IsConst (r) THEN n := q ; - GetQuad(n, op, op1, op2, op3) ; - max := GetSizeOfInBits(Mod2Gcc(Address)) ; - bits := GetIntegerZero(location) ; - val := GetPointerZero(location) ; + GetQuad (n, op, op1, op2, op3) ; + max := GetSizeOfInBits (Mod2Gcc(Address)) ; + bits := GetIntegerZero (location) ; + val := GetPointerZero (location) ; REPEAT - location := TokenToLocation(tokenno) ; - IF (op=ParamOp) AND (op1>0) + location := TokenToLocation (tokenno) ; + IF (op = ParamOp) AND (op1 > 0) THEN - IF GetType(op3)=NulSym + IF GetType (op3) = NulSym THEN MetaErrorT0 (tokenno, 'constants passed to {%kMAKEADR} must be typed') ELSE - type := GetType(op3) ; - tmp := BuildConvert(location, GetPointerType(), Mod2Gcc(op3), FALSE) ; - IF CompareTrees(bits, GetIntegerZero(location))>0 + type := GetType (op3) ; + tmp := BuildConvert (location, GetPointerType (), Mod2Gcc (op3), FALSE) ; + IF CompareTrees (bits, GetIntegerZero (location)) > 0 THEN - tmp := BuildLSL(location, tmp, bits, FALSE) + tmp := BuildLSL (location, tmp, bits, FALSE) END ; - bits := BuildAdd(location, bits, GetSizeOfInBits(Mod2Gcc(type)), FALSE) ; - val := BuildLogicalOrAddress(location, val, tmp, FALSE) + bits := BuildAdd (location, bits, GetSizeOfInBits (Mod2Gcc (type)), FALSE) ; + val := BuildLogicalOrAddress (location, val, tmp, FALSE) END END ; - SubQuad(n) ; - n := GetNextQuad(n) ; - GetQuad(n, op, op1, op2, op3) - UNTIL op=FunctValueOp ; - IF CompareTrees(bits, max)>0 + SubQuad (n) ; + n := GetNextQuad (n) ; + GetQuad (n, op, op1, op2, op3) + UNTIL op = FunctValueOp ; + IF CompareTrees (bits, max) > 0 THEN MetaErrorT0 (tokenno, 'total number of bits specified as parameters to {%kMAKEADR} exceeds address width') END ; - PutConst(r, Address) ; - AddModGcc(r, DeclareKnownConstant(location, Mod2Gcc(Address), val)) ; - p(r) ; + PutConst (r, Address) ; + AddModGcc (r, DeclareKnownConstant (location, Mod2Gcc (Address), val)) ; + p (r) ; NoChange := FALSE ; - SubQuad(n) + SubQuad (n) END END FoldMakeAdr ; @@ -2376,7 +2417,7 @@ VAR op1, op2, op3 : CARDINAL ; op : QuadOperator ; - val : Tree ; + val, call : Tree ; location : location_t ; BEGIN GetQuad (q, op, op1, op2, op3) ; @@ -2419,10 +2460,12 @@ BEGIN GetQuad(n, op, op1, op2, op3) UNTIL op=FunctValueOp ; - IF IsProcedureBuiltin(procedure) AND CanUseBuiltin(procedure) + IF IsProcedureBuiltinAvailable (procedure) THEN location := TokenToLocation(tokenno) ; - val := FoldAndStrip (UseBuiltin (tokenno, procedure)) ; + call := UseBuiltin (tokenno, procedure) ; + val := BuildFunctValue (location, call) ; + val := FoldAndStrip (val) ; PutConst(r, GetType(procedure)) ; AddModGcc(r, DeclareKnownConstant(location, Mod2Gcc(GetType(procedure)), val)) ; p(r) ; @@ -2450,7 +2493,7 @@ BEGIN IF op3=MakeAdr THEN FoldMakeAdr (tokenno, p, q, op1, op2, op3) - ELSIF IsProcedure (op3) AND IsProcedureBuiltin (op3) AND CanUseBuiltin (op3) + ELSIF IsProcedure (op3) AND IsProcedureBuiltinAvailable (op3) THEN FoldBuiltin (tokenno, p, q) END @@ -7262,7 +7305,26 @@ BEGIN END CodeXIndr ; +(* + InitBuiltinSyms - +*) + +PROCEDURE InitBuiltinSyms (tok: CARDINAL) ; +BEGIN + IF Memset = NulSym + THEN + Memset := FromModuleGetSym (tok, MakeKey ('memset'), MakeDefinitionSource (tok, MakeKey ('Builtins'))) + END ; + IF Memcpy = NulSym + THEN + Memcpy := FromModuleGetSym (tok, MakeKey ('memcpy'), MakeDefinitionSource (tok, MakeKey ('Builtins'))) + END ; +END InitBuiltinSyms ; + + BEGIN + Memset := NulSym ; + Memcpy := NulSym ; UnboundedLabelNo := 0 ; CurrentQuadToken := 0 ; ScopeStack := InitStackWord () diff --git a/gcc/m2/gm2-compiler/M2Options.def b/gcc/m2/gm2-compiler/M2Options.def index 6eefe7c..b70cd8f 100644 --- a/gcc/m2/gm2-compiler/M2Options.def +++ b/gcc/m2/gm2-compiler/M2Options.def @@ -97,7 +97,8 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck, SetGenModuleList, GetGenModuleFilename, SharedFlag, SetB, GetB, SetMD, GetMD, SetMMD, GetMMD, SetObj, GetObj, GetMQ, SetMQ, SetM2Prefix, GetM2Prefix, - SetM2PathName, GetM2PathName, SetCaseEnumChecking ; + SetM2PathName, GetM2PathName, SetCaseEnumChecking, + SetDebugBuiltins ; VAR @@ -946,6 +947,13 @@ PROCEDURE SetCaseEnumChecking (value: BOOLEAN) ; (* + SetDebugBuiltins - sets the DebugBuiltins to value. +*) + +PROCEDURE SetDebugBuiltins (value: BOOLEAN) ; + + +(* FinaliseOptions - once all options have been parsed we set any inferred values. *) diff --git a/gcc/m2/gm2-compiler/M2Options.mod b/gcc/m2/gm2-compiler/M2Options.mod index f265aa5..1a64cf0 100644 --- a/gcc/m2/gm2-compiler/M2Options.mod +++ b/gcc/m2/gm2-compiler/M2Options.mod @@ -1367,7 +1367,11 @@ END SetShared ; (* - SetUninitVariableChecking - sets the UninitVariableChecking flag to value. + SetUninitVariableChecking - sets the UninitVariableChecking and + UninitVariableConditionalChecking flags to value + depending upon arg string. The arg string + can be: "all", "known,cond", "cond,known", "known" + or "cond". *) PROCEDURE SetUninitVariableChecking (value: BOOLEAN; arg: ADDRESS) : INTEGER ; @@ -1386,8 +1390,7 @@ BEGIN s := InitStringCharStar (arg) ; IF EqualArray (s, "all") OR EqualArray (s, "known,cond") OR - EqualArray (s, "cond,known") OR - EqualArray (s, "cond") + EqualArray (s, "cond,known") THEN UninitVariableChecking := value ; UninitVariableConditionalChecking := value ; @@ -1396,7 +1399,11 @@ BEGIN ELSIF EqualArray (s, "known") THEN UninitVariableChecking := value ; - UninitVariableConditionalChecking := NOT value ; + s := KillString (s) ; + RETURN 1 + ELSIF EqualArray (s, "cond") + THEN + UninitVariableConditionalChecking := value ; s := KillString (s) ; RETURN 1 ELSE @@ -1416,6 +1423,16 @@ BEGIN END SetCaseEnumChecking ; +(* + SetDebugBuiltins - sets the DebugBuiltins to value. +*) + +PROCEDURE SetDebugBuiltins (value: BOOLEAN) ; +BEGIN + DebugBuiltins := value +END SetDebugBuiltins ; + + BEGIN cflag := FALSE ; (* -c. *) RuntimeModuleOverride := InitString (DefaultRuntimeModuleOverride) ; diff --git a/gcc/m2/gm2-compiler/M2Quads.def b/gcc/m2/gm2-compiler/M2Quads.def index 743589f..298482b 100644 --- a/gcc/m2/gm2-compiler/M2Quads.def +++ b/gcc/m2/gm2-compiler/M2Quads.def @@ -1644,7 +1644,7 @@ PROCEDURE CheckBuildFunction () : BOOLEAN ; *) -PROCEDURE BuildFunctionCall ; +PROCEDURE BuildFunctionCall (ConstExpr: BOOLEAN) ; (* diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod index be837b3..0cea540 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -117,6 +117,7 @@ FROM SymbolTable IMPORT ModeOfAddr, GetMode, PutMode, GetSymName, IsUnknown, PushSize, PushValue, PopValue, GetVariableAtAddress, IsVariableAtAddress, MakeError, UnknownReported, + IsProcedureBuiltinAvailable, IsError, IsInnerModule, IsImportStatement, IsImport, GetImportModule, GetImportDeclared, @@ -5147,9 +5148,9 @@ BEGIN END ; IF IsDefImp (GetScope (ProcSym)) AND IsDefinitionForC (GetScope (ProcSym)) THEN - BuildRealFuncProcCall (tokno, FALSE, TRUE) + BuildRealFuncProcCall (tokno, FALSE, TRUE, FALSE) ELSE - BuildRealFuncProcCall (tokno, FALSE, FALSE) + BuildRealFuncProcCall (tokno, FALSE, FALSE, FALSE) END END BuildRealProcedureCall ; @@ -5179,7 +5180,7 @@ END BuildRealProcedureCall ; |----------------| *) -PROCEDURE BuildRealFuncProcCall (tokno: CARDINAL; IsFunc, IsForC: BOOLEAN) ; +PROCEDURE BuildRealFuncProcCall (tokno: CARDINAL; IsFunc, IsForC, ConstExpr: BOOLEAN) ; VAR AllocateProc, DeallocateProc, @@ -5220,7 +5221,7 @@ BEGIN ParamConstant := FALSE ELSE Proc := ProcSym ; - ParamConstant := IsProcedureBuiltin (Proc) ; + ParamConstant := TRUE ; AllocateProc := GetSymName (Proc) = MakeKey('ALLOCATE') ; DeallocateProc := GetSymName (Proc) = MakeKey('DEALLOCATE') END ; @@ -5295,13 +5296,18 @@ BEGIN INC (pi) END ; GenQuadO (proctok, CallOp, NulSym, NulSym, ProcSym, TRUE) ; - PopN (NoOfParameters+1) ; (* Destroy arguments and procedure call *) + PopN (NoOfParameters+1) ; (* Destroy arguments and procedure call *) IF IsFunc THEN - (* ReturnVar - will have the type of the procedure *) + (* ReturnVar has the type of the procedure. *) resulttok := MakeVirtualTok (proctok, proctok, paramtok) ; - ReturnVar := MakeTemporary (resulttok, AreConstant(ParamConstant)) ; - PutVar (ReturnVar, GetSType(Proc)) ; + IF ConstExpr AND (NOT IsProcedureBuiltinAvailable (Proc)) + THEN + MetaError1('{%1d} {%1ad} cannot be used in a constant expression', Proc) ; + ParamConstant := FALSE + END ; + ReturnVar := MakeTemporary (resulttok, AreConstant (ParamConstant AND ConstExpr)) ; + PutVar (ReturnVar, GetSType (Proc)) ; GenQuadO (resulttok, FunctValueOp, ReturnVar, NulSym, Proc, TRUE) ; IF NOT ForcedFunc THEN @@ -6624,19 +6630,19 @@ BEGIN PushTFtok (TSize, Cardinal, tok) ; (* TSIZE(ParamType) *) PushTtok (ParamType, tok) ; PushT (1) ; (* 1 parameter for TSIZE() *) - BuildFunctionCall ; + BuildFunctionCall (FALSE) ; BuildBinaryOp ELSE (* SIZE(parameter) DIV TSIZE(ParamType) *) PushTFtok (TSize, Cardinal, tok) ; (* TSIZE(ArrayType) *) PushTtok (ArrayType, tok) ; PushT (1) ; (* 1 parameter for TSIZE() *) - BuildFunctionCall ; + BuildFunctionCall (TRUE) ; PushT (DivideTok) ; (* Divide by *) PushTFtok (TSize, Cardinal, tok) ; (* TSIZE(ParamType) *) PushTtok (ParamType, tok) ; PushT (1) ; (* 1 parameter for TSIZE() *) - BuildFunctionCall ; + BuildFunctionCall (TRUE) ; BuildBinaryOp END ; (* now convert from no of elements into HIGH by subtracting 1 *) @@ -6734,15 +6740,15 @@ BEGIN PushTFtok (Field, GetSType (Field), tok) ; PushT (1) ; BuildDesignatorRecord (tok) ; - PushTFtok (Adr, Address, tok) ; (* ADR(Sym) *) + PushTFtok (Adr, Address, tok) ; (* ADR (Sym). *) IF IsUnbounded (SymType) AND (dim = 0) THEN PushTFADtok (Sym, SymType, UnboundedSym, dim, tok) ELSE PushTFADtok (Sym, SymType, ArraySym, dim, tok) END ; - PushT (1) ; (* 1 parameter for ADR() *) - BuildFunctionCall ; + PushT (1) ; (* 1 parameter for ADR(). *) + BuildFunctionCall (FALSE) ; BuildAssignmentWithoutBounds (tok, FALSE, TRUE) ; AssignHighFields (tok, Sym, ArraySym, UnboundedSym, ParamType, dim) @@ -6957,7 +6963,7 @@ BEGIN (* x^ *) PushTtok (GetItemPointedTo (PtrSym), paramtok) ; PushT (1) ; (* One parameter *) - BuildFunctionCall ; + BuildFunctionCall (FALSE) ; PopT (SizeSym) ; PushTtok (ProcSym, combinedtok) ; (* ALLOCATE *) @@ -7046,7 +7052,7 @@ BEGIN (* x^ *) PushTtok (GetItemPointedTo(PtrSym), paramtok) ; PushT (1) ; (* One parameter *) - BuildFunctionCall ; + BuildFunctionCall (FALSE) ; PopT (SizeSym) ; PushTtok (ProcSym, combinedtok) ; (* DEALLOCATE *) @@ -7527,7 +7533,7 @@ END CheckBuildFunction ; |----------------| |------------| *) -PROCEDURE BuildFunctionCall ; +PROCEDURE BuildFunctionCall (ConstExpr: BOOLEAN) ; VAR paramtok, combinedtok, @@ -7540,14 +7546,15 @@ BEGIN ProcSym := OperandT (NoOfParam + 1) ; ProcSym := SkipConst (ProcSym) ; PushT (NoOfParam) ; - (* Compile time stack restored to entry state *) + (* Compile time stack restored to entry state. *) IF IsUnknown (ProcSym) THEN paramtok := OperandTtok (1) ; combinedtok := MakeVirtualTok (functok, functok, paramtok) ; MetaErrorT1 (functok, 'procedure function {%1Ea} is undefined', ProcSym) ; PopN (NoOfParam + 2) ; - PushT (MakeConstLit (combinedtok, MakeKey ('0'), NulSym)) (* fake return value to continue compiling *) + (* Fake return value to continue compiling. *) + PushT (MakeConstLit (combinedtok, MakeKey ('0'), NulSym)) ELSIF IsAModula2Type (ProcSym) THEN ManipulatePseudoCallParameters ; @@ -7558,7 +7565,7 @@ BEGIN ManipulatePseudoCallParameters ; BuildPseudoFunctionCall ELSE - BuildRealFunctionCall (functok) + BuildRealFunctionCall (functok, ConstExpr) END END BuildFunctionCall ; @@ -7607,7 +7614,7 @@ BEGIN IF CompilerDebugging THEN printf2 ('procsym = %d token = %d\n', ProcSym, functok) ; - (* ErrorStringAt (InitString ('constant function'), functok) *) + (* ErrorStringAt (InitString ('constant function'), functok). *) END ; PushT (NoOfParam) ; IF (ProcSym # Convert) AND @@ -7615,29 +7622,27 @@ BEGIN IsPseudoSystemFunctionConstExpression (ProcSym) OR (IsProcedure (ProcSym) AND IsProcedureBuiltin (ProcSym))) THEN - BuildFunctionCall + BuildFunctionCall (TRUE) ELSE IF IsAModula2Type (ProcSym) THEN - (* type conversion *) + (* Type conversion. *) IF NoOfParam = 1 THEN ConstExpression := OperandT (NoOfParam + 1) ; paramtok := OperandTtok (NoOfParam + 1) ; PopN (NoOfParam + 2) ; - (* - Build macro: CONVERT( ProcSym, ConstExpression ) - *) + (* Build macro: CONVERT( ProcSym, ConstExpression ). *) PushTFtok (Convert, NulSym, functok) ; PushTtok (ProcSym, functok) ; PushTtok (ConstExpression, paramtok) ; - PushT (2) ; (* Two parameters *) + PushT (2) ; (* Two parameters. *) BuildConvertFunction ELSE MetaErrorT0 (functok, '{%E}a constant type conversion can only have one argument') END ELSE - (* error issue message and fake return stack *) + (* Error issue message and fake return stack. *) IF Iso THEN MetaErrorT0 (functok, 'the only functions permissible in a constant expression are: {%kCAP}, {%kCHR}, {%kCMPLX}, {%kFLOAT}, {%kHIGH}, {%kIM}, {%kLENGTH}, {%kMAX}, {%kMIN}, {%kODD}, {%kORD}, {%kRE}, {%kSIZE}, {%kTSIZE}, {%kTRUNC}, {%kVAL} and gcc builtins') @@ -7652,7 +7657,7 @@ BEGIN combinedtok := functok END ; PopN (NoOfParam+2) ; - PushT (MakeConstLit (combinedtok, MakeKey('0'), NulSym)) (* fake return value to continue compiling *) + PushT (MakeConstLit (combinedtok, MakeKey('0'), NulSym)) (* Fake return value to continue compiling. *) END END END BuildConstFunctionCall ; @@ -7725,8 +7730,8 @@ BEGIN MarkAsRead (r) ; resulttok := MakeVirtualTok (proctok, proctok, exptok) ; ReturnVar := MakeTemporary (resulttok, RightValue) ; - PutVar (ReturnVar, ProcSym) ; (* Set ReturnVar's TYPE *) - PopN (1) ; (* pop procedure. *) + PutVar (ReturnVar, ProcSym) ; (* Set ReturnVar's TYPE. *) + PopN (1) ; (* Pop procedure. *) IF IsConst (exp) OR IsVar (exp) THEN GenQuad (CoerceOp, ReturnVar, ProcSym, exp) @@ -7768,7 +7773,7 @@ END BuildTypeCoercion ; |----------------| |------------| *) -PROCEDURE BuildRealFunctionCall (tokno: CARDINAL) ; +PROCEDURE BuildRealFunctionCall (tokno: CARDINAL; ConstExpr: BOOLEAN) ; VAR NoOfParam, ProcSym : CARDINAL ; @@ -7779,14 +7784,14 @@ BEGIN ProcSym := SkipConst (ProcSym) ; IF IsVar(ProcSym) THEN - (* Procedure Variable ? *) - ProcSym := SkipType(OperandF(NoOfParam+2)) + (* Procedure Variable therefore get its type to see if it is a FOR "C" call. *) + ProcSym := SkipType (OperandF (NoOfParam+2)) END ; - IF IsDefImp (GetScope (ProcSym)) AND IsDefinitionForC (GetScope(ProcSym)) + IF IsDefImp (GetScope (ProcSym)) AND IsDefinitionForC (GetScope (ProcSym)) THEN - BuildRealFuncProcCall (tokno, TRUE, TRUE) + BuildRealFuncProcCall (tokno, TRUE, TRUE, ConstExpr) ELSE - BuildRealFuncProcCall (tokno, TRUE, FALSE) + BuildRealFuncProcCall (tokno, TRUE, FALSE, ConstExpr) END END BuildRealFunctionCall ; @@ -8428,7 +8433,7 @@ BEGIN PushTtok (ProcSym, functok) ; PushTFtok (Param, Type, paramtok) ; PushT (NoOfParam) ; - BuildRealFunctionCall (functok) + BuildRealFunctionCall (functok, FALSE) END ELSE PopT (NoOfParam) ; diff --git a/gcc/m2/gm2-compiler/P3Build.bnf b/gcc/m2/gm2-compiler/P3Build.bnf index 15c31fb..7cd7ec0 100644 --- a/gcc/m2/gm2-compiler/P3Build.bnf +++ b/gcc/m2/gm2-compiler/P3Build.bnf @@ -1111,7 +1111,7 @@ SetOrDesignatorOrFunction := Qualident THEN BuildConstFunctionCall ELSE - BuildFunctionCall + BuildFunctionCall (FALSE) END % ] ] | @@ -1158,7 +1158,7 @@ AssignmentOrProcedureCall := % VAR ( ActualParameters | % BuildNulParam (* in epsilon *) % ) % IF isFunc THEN - BuildFunctionCall ; + BuildFunctionCall (FALSE) ; BuildAssignment (tokno) ELSE BuildProcedureCall (tokno - 1) diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def index e7356da..2068aa2 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.def +++ b/gcc/m2/gm2-compiler/SymbolTable.def @@ -266,6 +266,7 @@ EXPORT QUALIFIED NulSym, IsDefLink, IsModLink, IsModuleBuiltin, + IsProcedureBuiltinAvailable, ForeachProcedureDo, ProcedureParametersDefined, @@ -3667,4 +3668,12 @@ PROCEDURE GetParameterHeapVar (ParSym: CARDINAL) : CARDINAL ; PROCEDURE PutProcedureParameterHeapVars (sym: CARDINAL) ; +(* + IsProcedureBuiltinAvailable - return TRUE if procedure is available as a builtin + for the target architecture. +*) + +PROCEDURE IsProcedureBuiltinAvailable (procedure: CARDINAL) : BOOLEAN ; + + END SymbolTable. diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod index 86f896e..dc41c12 100644 --- a/gcc/m2/gm2-compiler/SymbolTable.mod +++ b/gcc/m2/gm2-compiler/SymbolTable.mod @@ -32,7 +32,7 @@ FROM Indexing IMPORT InitIndex, InBounds, LowIndice, HighIndice, PutIndice, GetI FROM Sets IMPORT Set, InitSet, IncludeElementIntoSet, IsElementInSet ; FROM m2linemap IMPORT location_t ; -FROM M2Options IMPORT Pedantic, ExtendedOpaque, DebugFunctionLineNumbers, ScaffoldDynamic ; +FROM M2Options IMPORT Pedantic, ExtendedOpaque, DebugFunctionLineNumbers, ScaffoldDynamic, DebugBuiltins ; FROM M2LexBuf IMPORT UnknownTokenNo, TokenToLineNo, FindFileNameFromToken, TokenToLocation ; @@ -80,6 +80,7 @@ FROM m2decl IMPORT ConstantStringExceedsZType ; FROM m2tree IMPORT Tree ; FROM m2linemap IMPORT BuiltinsLocation ; FROM StrLib IMPORT StrEqual ; +FROM m2builtins IMPORT BuiltinExists ; FROM M2Comp IMPORT CompilingDefinitionModule, CompilingImplementationModule ; @@ -5788,6 +5789,30 @@ END IsProcedureBuiltin ; (* + CanUseBuiltin - returns TRUE if the procedure, Sym, can be + inlined via a builtin function. +*) + +PROCEDURE CanUseBuiltin (Sym: CARDINAL) : BOOLEAN ; +BEGIN + RETURN( (NOT DebugBuiltins) AND + (BuiltinExists (KeyToCharStar (GetProcedureBuiltin (Sym))) OR + BuiltinExists (KeyToCharStar (GetSymName (Sym)))) ) +END CanUseBuiltin ; + + +(* + IsProcedureBuiltinAvailable - return TRUE if procedure is available as a builtin + for the target architecture. +*) + +PROCEDURE IsProcedureBuiltinAvailable (procedure: CARDINAL) : BOOLEAN ; +BEGIN + RETURN IsProcedureBuiltin (procedure) AND CanUseBuiltin (procedure) +END IsProcedureBuiltinAvailable ; + + +(* PutProcedureInline - determines that procedure, Sym, has been requested to be inlined. *) diff --git a/gcc/m2/gm2-gcc/m2builtins.cc b/gcc/m2/gm2-gcc/m2builtins.cc index 3d13e20..8774ee7 100644 --- a/gcc/m2/gm2-gcc/m2builtins.cc +++ b/gcc/m2/gm2-gcc/m2builtins.cc @@ -29,6 +29,9 @@ along with GNU Modula-2; see the file COPYING3. If not see #include "m2tree.h" #include "m2treelib.h" #include "m2type.h" +#include "m2configure.h" + +#undef DEBUGGING #define GM2 #define GM2_BUG_REPORT \ @@ -107,6 +110,19 @@ typedef enum { BT_FN_DOUBLE_DOUBLE_DOUBLE, } builtin_prototype; +typedef enum +{ + bf_true, + bf_false, + bf_extension_lib, + bf_default_lib, + bf_gcc, + bf_c99, + bf_c99_c90res, + bf_extension_lib_floatn, + bf_c99_compl, +} bf_category; + struct builtin_function_entry { const char *name; @@ -116,6 +132,7 @@ struct builtin_function_entry const char *library_name; tree function_node; tree return_node; + bf_category function_avail; }; /* Entries are added by examining gcc/builtins.def and copying those @@ -123,255 +140,248 @@ struct builtin_function_entry static struct builtin_function_entry list_of_builtins[] = { { "__builtin_alloca", BT_FN_PTR_SIZE, BUILT_IN_ALLOCA, BUILT_IN_NORMAL, - "alloca", NULL, NULL }, + "alloca", NULL, NULL, bf_extension_lib }, { "__builtin_memcpy", BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE, BUILT_IN_MEMCPY, - BUILT_IN_NORMAL, "memcpy", NULL, NULL }, - + BUILT_IN_NORMAL, "memcpy", NULL, NULL, bf_default_lib }, { "__builtin_isfinite", BT_FN_INT_DOUBLE, BUILT_IN_ISFINITE, BUILT_IN_NORMAL, - "isfinite", NULL, NULL }, - + "isfinite", NULL, NULL, bf_gcc }, { "__builtin_sinf", BT_FN_FLOAT_FLOAT, BUILT_IN_SINF, BUILT_IN_NORMAL, - "sinf", NULL, NULL }, + "sinf", NULL, NULL, bf_c99_c90res }, { "__builtin_sin", BT_FN_DOUBLE_DOUBLE, BUILT_IN_SIN, BUILT_IN_NORMAL, "sin", - NULL, NULL }, + NULL, NULL, bf_c99_c90res }, { "__builtin_sinl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_SINL, - BUILT_IN_NORMAL, "sinl", NULL, NULL }, + BUILT_IN_NORMAL, "sinl", NULL, NULL, bf_c99_c90res }, { "__builtin_cosf", BT_FN_FLOAT_FLOAT, BUILT_IN_SINF, BUILT_IN_NORMAL, - "cosf", NULL, NULL }, + "cosf", NULL, NULL, bf_c99_c90res }, { "__builtin_cos", BT_FN_DOUBLE_DOUBLE, BUILT_IN_COS, BUILT_IN_NORMAL, "cos", - NULL, NULL }, + NULL, NULL, bf_c99_c90res }, { "__builtin_cosl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_COSL, - BUILT_IN_NORMAL, "cosl", NULL, NULL }, + BUILT_IN_NORMAL, "cosl", NULL, NULL, bf_c99_c90res }, { "__builtin_sqrtf", BT_FN_FLOAT_FLOAT, BUILT_IN_SQRTF, BUILT_IN_NORMAL, - "sqrtf", NULL, NULL }, + "sqrtf", NULL, NULL, bf_c99_c90res }, { "__builtin_sqrt", BT_FN_DOUBLE_DOUBLE, BUILT_IN_SQRT, BUILT_IN_NORMAL, - "sqrt", NULL, NULL }, + "sqrt", NULL, NULL, bf_default_lib }, { "__builtin_sqrtl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_SQRTL, - BUILT_IN_NORMAL, "sqrtl", NULL, NULL }, + BUILT_IN_NORMAL, "sqrtl", NULL, NULL, bf_c99_c90res }, { "__builtin_fabsf", BT_FN_FLOAT_FLOAT, BUILT_IN_FABSF, BUILT_IN_NORMAL, - "fabsf", NULL, NULL }, + "fabsf", NULL, NULL, bf_c99_c90res }, { "__builtin_fabs", BT_FN_DOUBLE_DOUBLE, BUILT_IN_FABS, BUILT_IN_NORMAL, - "fabs", NULL, NULL }, + "fabs", NULL, NULL, bf_default_lib }, { "__builtin_fabsl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_FABSL, - BUILT_IN_NORMAL, "fabsl", NULL, NULL }, + BUILT_IN_NORMAL, "fabsl", NULL, NULL, bf_c99_c90res }, { "__builtin_logf", BT_FN_FLOAT_FLOAT, BUILT_IN_LOGF, BUILT_IN_NORMAL, - "logf", NULL, NULL }, + "logf", NULL, NULL, bf_c99_c90res }, { "__builtin_log", BT_FN_DOUBLE_DOUBLE, BUILT_IN_LOG, BUILT_IN_NORMAL, "log", - NULL, NULL }, + NULL, NULL, bf_extension_lib_floatn }, { "__builtin_logl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_LOGL, - BUILT_IN_NORMAL, "logl", NULL, NULL }, + BUILT_IN_NORMAL, "logl", NULL, NULL, bf_c99_c90res }, { "__builtin_expf", BT_FN_FLOAT_FLOAT, BUILT_IN_EXPF, BUILT_IN_NORMAL, - "expf", NULL, NULL }, + "expf", NULL, NULL, bf_c99_c90res }, { "__builtin_exp", BT_FN_DOUBLE_DOUBLE, BUILT_IN_EXP, BUILT_IN_NORMAL, "exp", - NULL, NULL }, + NULL, NULL, bf_extension_lib_floatn }, { "__builtin_expl", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_EXPL, - BUILT_IN_NORMAL, "expl", NULL, NULL }, + BUILT_IN_NORMAL, "expl", NULL, NULL, bf_c99_c90res }, { "__builtin_log10f", BT_FN_FLOAT_FLOAT, BUILT_IN_LOG10F, BUILT_IN_NORMAL, - "log10f", NULL, NULL }, + "log10f", NULL, NULL, bf_c99_c90res }, { "__builtin_log10", BT_FN_DOUBLE_DOUBLE, BUILT_IN_LOG10, BUILT_IN_NORMAL, - "log10", NULL, NULL }, + "log10", NULL, NULL, bf_default_lib }, { "__builtin_log10l", BT_FN_LONG_DOUBLE_LONG_DOUBLE, BUILT_IN_LOG10L, - BUILT_IN_NORMAL, "log10l", NULL, NULL }, + BUILT_IN_NORMAL, "log10l", NULL, NULL, bf_c99_c90res }, { "__builtin_ilogbf", BT_FN_INT_FLOAT, BUILT_IN_ILOGBF, BUILT_IN_NORMAL, - "ilogbf", NULL, NULL }, + "ilogbf", NULL, NULL, bf_c99 }, { "__builtin_ilogb", BT_FN_INT_DOUBLE, BUILT_IN_ILOGB, BUILT_IN_NORMAL, - "ilogb", NULL, NULL }, + "ilogb", NULL, NULL, bf_c99 }, { "__builtin_ilogbl", BT_FN_INT_LONG_DOUBLE, BUILT_IN_ILOGBL, - BUILT_IN_NORMAL, "ilogbl", NULL, NULL }, + BUILT_IN_NORMAL, "ilogbl", NULL, NULL, bf_c99 }, { "__builtin_atan2f", BT_FN_FLOAT_FLOAT_FLOAT, BUILT_IN_ATAN2F, - BUILT_IN_NORMAL, "atan2f", NULL, NULL }, + BUILT_IN_NORMAL, "atan2f", NULL, NULL, bf_c99_c90res }, { "__builtin_atan2", BT_FN_DOUBLE_DOUBLE_DOUBLE, BUILT_IN_ATAN2, - BUILT_IN_NORMAL, "atan2", NULL, NULL }, + BUILT_IN_NORMAL, "atan2", NULL, NULL, bf_default_lib }, { "__builtin_atan2l", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE, - BUILT_IN_ATAN2L, BUILT_IN_NORMAL, "atan2l", NULL, NULL }, + BUILT_IN_ATAN2L, BUILT_IN_NORMAL, "atan2l", NULL, NULL, bf_c99_c90res }, { "__builtin_signbit", BT_FN_INT_DOUBLE, BUILT_IN_SIGNBIT, BUILT_IN_NORMAL, - "signbit", NULL, NULL }, + "signbit", NULL, NULL, bf_extension_lib }, { "__builtin_signbitf", BT_FN_INT_FLOAT, BUILT_IN_SIGNBITF, BUILT_IN_NORMAL, - "signbitf", NULL, NULL }, + "signbitf", NULL, NULL, bf_extension_lib }, { "__builtin_signbitl", BT_FN_INT_LONG_DOUBLE, BUILT_IN_SIGNBITL, - BUILT_IN_NORMAL, "signbitl", NULL, NULL }, + BUILT_IN_NORMAL, "signbitl", NULL, NULL, bf_extension_lib }, { "__builtin_modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, BUILT_IN_MODF, - BUILT_IN_NORMAL, "modf", NULL, NULL }, + BUILT_IN_NORMAL, "modf", NULL, NULL, bf_default_lib }, { "__builtin_modff", BT_FN_FLOAT_FLOAT_FLOATPTR, BUILT_IN_MODFF, - BUILT_IN_NORMAL, "modff", NULL, NULL }, + BUILT_IN_NORMAL, "modff", NULL, NULL, bf_c99_c90res }, { "__builtin_modfl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLEPTR, - BUILT_IN_MODFL, BUILT_IN_NORMAL, "modfl", NULL, NULL }, + BUILT_IN_MODFL, BUILT_IN_NORMAL, "modfl", NULL, NULL, bf_c99_c90res }, { "__builtin_nextafter", BT_FN_DOUBLE_DOUBLE_DOUBLE, BUILT_IN_NEXTAFTER, - BUILT_IN_NORMAL, "nextafter", NULL, NULL }, + BUILT_IN_NORMAL, "nextafter", NULL, NULL, bf_c99 }, { "__builtin_nextafterf", BT_FN_FLOAT_FLOAT_FLOAT, BUILT_IN_NEXTAFTERF, - BUILT_IN_NORMAL, "nextafterf", NULL, NULL }, + BUILT_IN_NORMAL, "nextafterf", NULL, NULL, bf_c99 }, { "__builtin_nextafterl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE, - BUILT_IN_NEXTAFTERL, BUILT_IN_NORMAL, "nextafterl", NULL, NULL }, + BUILT_IN_NEXTAFTERL, BUILT_IN_NORMAL, "nextafterl", NULL, NULL, bf_c99 }, { "__builtin_nexttoward", BT_FN_DOUBLE_DOUBLE_LONG_DOUBLE, - BUILT_IN_NEXTTOWARD, BUILT_IN_NORMAL, "nexttoward", NULL, NULL }, + BUILT_IN_NEXTTOWARD, BUILT_IN_NORMAL, "nexttoward", NULL, NULL, bf_c99 }, { "__builtin_nexttowardf", BT_FN_FLOAT_FLOAT_LONG_DOUBLE, - BUILT_IN_NEXTTOWARDF, BUILT_IN_NORMAL, "nexttowardf", NULL, NULL }, + BUILT_IN_NEXTTOWARDF, BUILT_IN_NORMAL, "nexttowardf", NULL, NULL, bf_c99 }, { "__builtin_nexttowardl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE, - BUILT_IN_NEXTTOWARDL, BUILT_IN_NORMAL, "nexttowardl", NULL, NULL }, + BUILT_IN_NEXTTOWARDL, BUILT_IN_NORMAL, "nexttowardl", NULL, NULL, bf_c99 }, { "__builtin_scalbln", BT_FN_DOUBLE_DOUBLE_LONG, BUILT_IN_SCALBLN, - BUILT_IN_NORMAL, "scalbln", NULL, NULL }, + BUILT_IN_NORMAL, "scalbln", NULL, NULL, bf_extension_lib }, { "__builtin_scalblnf", BT_FN_FLOAT_FLOAT_LONG, BUILT_IN_SCALBLNF, - BUILT_IN_NORMAL, "scalblnf", NULL, NULL }, + BUILT_IN_NORMAL, "scalblnf", NULL, NULL, bf_extension_lib }, { "__builtin_scalblnl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG, - BUILT_IN_SCALBLNL, BUILT_IN_NORMAL, "scalblnl", NULL, NULL }, + BUILT_IN_SCALBLNL, BUILT_IN_NORMAL, "scalblnl", NULL, NULL, bf_extension_lib }, { "__builtin_scalbn", BT_FN_DOUBLE_DOUBLE_INT, BUILT_IN_SCALBN, - BUILT_IN_NORMAL, "scalbln", NULL, NULL }, + BUILT_IN_NORMAL, "scalbln", NULL, NULL, bf_extension_lib }, { "__builtin_scalbnf", BT_FN_FLOAT_FLOAT_INT, BUILT_IN_SCALBNF, - BUILT_IN_NORMAL, "scalblnf", NULL, NULL }, + BUILT_IN_NORMAL, "scalblnf", NULL, NULL, bf_extension_lib }, { "__builtin_scalbnl", BT_FN_LONG_DOUBLE_LONG_DOUBLE_INT, BUILT_IN_SCALBNL, - BUILT_IN_NORMAL, "scalblnl", NULL, NULL }, + BUILT_IN_NORMAL, "scalblnl", NULL, NULL, bf_extension_lib }, /* Complex intrinsic functions. */ { "__builtin_cabs", BT_FN_DOUBLE_DCOMPLEX, BUILT_IN_CABS, BUILT_IN_NORMAL, - "cabs", NULL, NULL }, + "cabs", NULL, NULL, bf_c99_compl }, { "__builtin_cabsf", BT_FN_FLOAT_FCOMPLEX, BUILT_IN_CABSF, BUILT_IN_NORMAL, - "cabsf", NULL, NULL }, + "cabsf", NULL, NULL, bf_c99_compl }, { "__builtin_cabsl", BT_FN_LONG_DOUBLE_LDCOMPLEX, BUILT_IN_CABSL, - BUILT_IN_NORMAL, "cabsl", NULL, NULL }, + BUILT_IN_NORMAL, "cabsl", NULL, NULL, bf_c99_compl }, { "__builtin_carg", BT_FN_DOUBLE_DCOMPLEX, BUILT_IN_CABS, BUILT_IN_NORMAL, - "carg", NULL, NULL }, + "carg", NULL, NULL, bf_c99_compl }, { "__builtin_cargf", BT_FN_FLOAT_FCOMPLEX, BUILT_IN_CABSF, BUILT_IN_NORMAL, - "cargf", NULL, NULL }, + "cargf", NULL, NULL, bf_c99_compl }, { "__builtin_cargl", BT_FN_LONG_DOUBLE_LDCOMPLEX, BUILT_IN_CABSL, - BUILT_IN_NORMAL, "cargl", NULL, NULL }, + BUILT_IN_NORMAL, "cargl", NULL, NULL, bf_c99_compl }, { "__builtin_conj", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CONJ, BUILT_IN_NORMAL, - "carg", NULL, NULL }, + "carg", NULL, NULL, bf_c99_compl }, { "__builtin_conjf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CONJF, - BUILT_IN_NORMAL, "conjf", NULL, NULL }, + BUILT_IN_NORMAL, "conjf", NULL, NULL, bf_c99_compl }, { "__builtin_conjl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CONJL, - BUILT_IN_NORMAL, "conjl", NULL, NULL }, + BUILT_IN_NORMAL, "conjl", NULL, NULL, bf_c99_compl }, { "__builtin_cpow", BT_FN_DCOMPLEX_DOUBLE_DCOMPLEX, BUILT_IN_CPOW, - BUILT_IN_NORMAL, "cpow", NULL, NULL }, + BUILT_IN_NORMAL, "cpow", NULL, NULL, bf_c99_compl }, { "__builtin_cpowf", BT_FN_FCOMPLEX_FLOAT_FCOMPLEX, BUILT_IN_CPOWF, - BUILT_IN_NORMAL, "cpowf", NULL, NULL }, + BUILT_IN_NORMAL, "cpowf", NULL, NULL, bf_c99_compl }, { "__builtin_cpowl", BT_FN_LDCOMPLEX_LONG_DOUBLE_LDCOMPLEX, BUILT_IN_CPOWL, - BUILT_IN_NORMAL, "cpowl", NULL, NULL }, + BUILT_IN_NORMAL, "cpowl", NULL, NULL, bf_c99_compl }, { "__builtin_csqrt", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CSQRT, - BUILT_IN_NORMAL, "csqrt", NULL, NULL }, + BUILT_IN_NORMAL, "csqrt", NULL, NULL, bf_c99_compl }, { "__builtin_csqrtf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CSQRTF, - BUILT_IN_NORMAL, "csqrtf", NULL, NULL }, + BUILT_IN_NORMAL, "csqrtf", NULL, NULL, bf_c99_compl }, { "__builtin_csqrtl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CSQRTL, - BUILT_IN_NORMAL, "csqrtl", NULL, NULL }, + BUILT_IN_NORMAL, "csqrtl", NULL, NULL, bf_c99_compl }, { "__builtin_cexp", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CEXP, BUILT_IN_NORMAL, - "cexp", NULL, NULL }, + "cexp", NULL, NULL, bf_c99_compl }, { "__builtin_cexpf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CEXPF, - BUILT_IN_NORMAL, "cexpf", NULL, NULL }, + BUILT_IN_NORMAL, "cexpf", NULL, NULL, bf_c99_compl }, { "__builtin_cexpl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CEXPL, - BUILT_IN_NORMAL, "cexpl", NULL, NULL }, + BUILT_IN_NORMAL, "cexpl", NULL, NULL, bf_c99_compl }, - { "__builtin_cln", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CLOG, BUILT_IN_NORMAL, - "cln", NULL, NULL }, - { "__builtin_clnf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CLOGF, BUILT_IN_NORMAL, - "clnf", NULL, NULL }, - { "__builtin_clnl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CLOGL, - BUILT_IN_NORMAL, "clnl", NULL, NULL }, + { "__builtin_clog", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CLOG, BUILT_IN_NORMAL, + "clog", NULL, NULL, bf_c99_compl }, + { "__builtin_clogf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CLOGF, BUILT_IN_NORMAL, + "clogf", NULL, NULL, bf_c99_compl }, + { "__builtin_clogl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CLOGL, + BUILT_IN_NORMAL, "clogl", NULL, NULL, bf_c99_compl }, { "__builtin_csin", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CSIN, BUILT_IN_NORMAL, - "csin", NULL, NULL }, + "csin", NULL, NULL, bf_c99_compl }, { "__builtin_csinf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CSINF, - BUILT_IN_NORMAL, "csinf", NULL, NULL }, + BUILT_IN_NORMAL, "csinf", NULL, NULL, bf_c99_compl }, { "__builtin_csinl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CSINL, - BUILT_IN_NORMAL, "csinl", NULL, NULL }, + BUILT_IN_NORMAL, "csinl", NULL, NULL, bf_c99_compl }, { "__builtin_ccos", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CCOS, BUILT_IN_NORMAL, - "ccos", NULL, NULL }, + "ccos", NULL, NULL, bf_c99_compl }, { "__builtin_ccosf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CCOSF, - BUILT_IN_NORMAL, "ccosf", NULL, NULL }, + BUILT_IN_NORMAL, "ccosf", NULL, NULL, bf_c99_compl }, { "__builtin_ccosl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CCOSL, - BUILT_IN_NORMAL, "ccosl", NULL, NULL }, + BUILT_IN_NORMAL, "ccosl", NULL, NULL, bf_c99_compl }, { "__builtin_ctan", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CTAN, BUILT_IN_NORMAL, - "ctan", NULL, NULL }, + "ctan", NULL, NULL, bf_c99_compl }, { "__builtin_ctanf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CTANF, - BUILT_IN_NORMAL, "ctanf", NULL, NULL }, + BUILT_IN_NORMAL, "ctanf", NULL, NULL, bf_c99_compl }, { "__builtin_ctanl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CTANL, - BUILT_IN_NORMAL, "ctanl", NULL, NULL }, + BUILT_IN_NORMAL, "ctanl", NULL, NULL, bf_c99_compl }, { "__builtin_casin", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CASIN, - BUILT_IN_NORMAL, "casin", NULL, NULL }, + BUILT_IN_NORMAL, "casin", NULL, NULL, bf_c99_compl }, { "__builtin_casinf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CASINF, - BUILT_IN_NORMAL, "casinf", NULL, NULL }, + BUILT_IN_NORMAL, "casinf", NULL, NULL, bf_c99_compl }, { "__builtin_casinl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CASINL, - BUILT_IN_NORMAL, "casinl", NULL, NULL }, + BUILT_IN_NORMAL, "casinl", NULL, NULL, bf_c99_compl }, { "__builtin_cacos", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CACOS, - BUILT_IN_NORMAL, "cacos", NULL, NULL }, + BUILT_IN_NORMAL, "cacos", NULL, NULL, bf_c99_compl }, { "__builtin_cacosf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CACOSF, - BUILT_IN_NORMAL, "cacosf", NULL, NULL }, + BUILT_IN_NORMAL, "cacosf", NULL, NULL, bf_c99_compl }, { "__builtin_cacosl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CACOSL, - BUILT_IN_NORMAL, "cacosl", NULL, NULL }, + BUILT_IN_NORMAL, "cacosl", NULL, NULL, bf_c99_compl }, { "__builtin_catan", BT_FN_DCOMPLEX_DCOMPLEX, BUILT_IN_CATAN, - BUILT_IN_NORMAL, "catan", NULL, NULL }, + BUILT_IN_NORMAL, "catan", NULL, NULL, bf_c99_compl }, { "__builtin_catanf", BT_FN_FCOMPLEX_FCOMPLEX, BUILT_IN_CATANF, - BUILT_IN_NORMAL, "catanf", NULL, NULL }, + BUILT_IN_NORMAL, "catanf", NULL, NULL, bf_c99_compl }, { "__builtin_catanl", BT_FN_LDCOMPLEX_LDCOMPLEX, BUILT_IN_CATANL, - BUILT_IN_NORMAL, "catanl", NULL, NULL }, + BUILT_IN_NORMAL, "catanl", NULL, NULL, bf_c99_compl }, { "__builtin_huge_val", BT_FN_DOUBLE, BUILT_IN_HUGE_VAL, BUILT_IN_NORMAL, - "huge_val", NULL, NULL }, + "huge_val", NULL, NULL, bf_gcc }, { "__builtin_huge_valf", BT_FN_FLOAT, BUILT_IN_HUGE_VALF, BUILT_IN_NORMAL, - "huge_valf", NULL, NULL }, + "huge_valf", NULL, NULL, bf_gcc }, { "__builtin_huge_vall", BT_FN_LONG_DOUBLE, BUILT_IN_HUGE_VALL, - BUILT_IN_NORMAL, "huge_vall", NULL, NULL }, + BUILT_IN_NORMAL, "huge_vall", NULL, NULL, bf_gcc }, { "__builtin_index", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_INDEX, - BUILT_IN_NORMAL, "index", NULL, NULL }, + BUILT_IN_NORMAL, "index", NULL, NULL, bf_extension_lib }, { "__builtin_rindex", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_RINDEX, - BUILT_IN_NORMAL, "rindex", NULL, NULL }, + BUILT_IN_NORMAL, "rindex", NULL, NULL, bf_extension_lib }, { "__builtin_memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, BUILT_IN_MEMCMP, - BUILT_IN_NORMAL, "memcmp", NULL, NULL }, + BUILT_IN_NORMAL, "memcmp", NULL, NULL, bf_default_lib }, { "__builtin_memmove", BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE, BUILT_IN_MEMMOVE, - BUILT_IN_NORMAL, "memmove", NULL, NULL }, + BUILT_IN_NORMAL, "memmove", NULL, NULL, bf_default_lib }, { "__builtin_memset", BT_FN_TRAD_PTR_PTR_INT_SIZE, BUILT_IN_MEMSET, - BUILT_IN_NORMAL, "memset", NULL, NULL }, + BUILT_IN_NORMAL, "memset", NULL, NULL, bf_default_lib }, { "__builtin_strcat", BT_FN_STRING_STRING_CONST_STRING, BUILT_IN_STRCAT, - BUILT_IN_NORMAL, "strcat", NULL, NULL }, + BUILT_IN_NORMAL, "strcat", NULL, NULL, bf_default_lib }, { "__builtin_strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, - BUILT_IN_STRNCAT, BUILT_IN_NORMAL, "strncat", NULL, NULL }, + BUILT_IN_STRNCAT, BUILT_IN_NORMAL, "strncat", NULL, NULL, bf_default_lib }, { "__builtin_strcpy", BT_FN_STRING_STRING_CONST_STRING, BUILT_IN_STRCPY, - BUILT_IN_NORMAL, "strcpy", NULL, NULL }, + BUILT_IN_NORMAL, "strcpy", NULL, NULL, bf_default_lib }, { "__builtin_strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, - BUILT_IN_STRNCPY, BUILT_IN_NORMAL, "strncpy", NULL, NULL }, + BUILT_IN_STRNCPY, BUILT_IN_NORMAL, "strncpy", NULL, NULL, bf_default_lib }, { "__builtin_strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, BUILT_IN_STRCMP, - BUILT_IN_NORMAL, "strcmp", NULL, NULL }, + BUILT_IN_NORMAL, "strcmp", NULL, NULL, bf_default_lib }, { "__builtin_strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, - BUILT_IN_STRNCMP, BUILT_IN_NORMAL, "strncmp", NULL, NULL }, + BUILT_IN_STRNCMP, BUILT_IN_NORMAL, "strncmp", NULL, NULL, bf_default_lib }, { "__builtin_strlen", BT_FN_INT_CONST_STRING, BUILT_IN_STRLEN, - BUILT_IN_NORMAL, "strlen", NULL, NULL }, + BUILT_IN_NORMAL, "strlen", NULL, NULL, bf_default_lib }, { "__builtin_strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, - BUILT_IN_STRSTR, BUILT_IN_NORMAL, "strstr", NULL, NULL }, + BUILT_IN_STRSTR, BUILT_IN_NORMAL, "strstr", NULL, NULL, bf_default_lib }, { "__builtin_strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, - BUILT_IN_STRPBRK, BUILT_IN_NORMAL, "strpbrk", NULL, NULL }, + BUILT_IN_STRPBRK, BUILT_IN_NORMAL, "strpbrk", NULL, NULL, bf_default_lib }, { "__builtin_strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, BUILT_IN_STRSPN, - BUILT_IN_NORMAL, "strspn", NULL, NULL }, + BUILT_IN_NORMAL, "strspn", NULL, NULL, bf_default_lib }, { "__builtin_strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, - BUILT_IN_STRCSPN, BUILT_IN_NORMAL, "strcspn", NULL, NULL }, + BUILT_IN_STRCSPN, BUILT_IN_NORMAL, "strcspn", NULL, NULL, bf_default_lib }, { "__builtin_strchr", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_STRCHR, - BUILT_IN_NORMAL, "strchr", NULL, NULL }, + BUILT_IN_NORMAL, "strchr", NULL, NULL, bf_default_lib }, { "__builtin_strrchr", BT_FN_STRING_CONST_STRING_INT, BUILT_IN_STRCHR, - BUILT_IN_NORMAL, "strrchr", NULL, NULL }, - //{ "__builtin_constant_p", BT_FN_INT_VAR, BUILT_IN_CONSTANT_P, - //BUILT_IN_NORMAL, "constant_p", NULL, NULL}, + BUILT_IN_NORMAL, "strrchr", NULL, NULL, bf_default_lib }, { "__builtin_frame_address", BT_FN_PTR_UNSIGNED, BUILT_IN_FRAME_ADDRESS, - BUILT_IN_NORMAL, "frame_address", NULL, NULL }, + BUILT_IN_NORMAL, "frame_address", NULL, NULL, bf_gcc }, { "__builtin_return_address", BT_FN_PTR_UNSIGNED, BUILT_IN_RETURN_ADDRESS, - BUILT_IN_NORMAL, "return_address", NULL, NULL }, - //{ "__builtin_aggregate_incoming_address", BT_FN_PTR_VAR, - //BUILT_IN_AGGREGATE_INCOMING_ADDRESS, BUILT_IN_NORMAL, - //"aggregate_incoming_address", NULL, NULL}, + BUILT_IN_NORMAL, "return_address", NULL, NULL, bf_gcc }, { "__builtin_longjmp", BT_FN_VOID_PTR_INT, BUILT_IN_LONGJMP, BUILT_IN_NORMAL, - "longjmp", NULL, NULL }, + "longjmp", NULL, NULL, bf_gcc }, { "__builtin_setjmp", BT_FN_INT_PTR, BUILT_IN_SETJMP, BUILT_IN_NORMAL, - "setjmp", NULL, NULL }, - { NULL, BT_FN_NONE, 0, NOT_BUILT_IN, "", NULL, NULL } + "setjmp", NULL, NULL, bf_gcc }, + { NULL, BT_FN_NONE, 0, NOT_BUILT_IN, "", NULL, NULL, bf_false} }; struct builtin_type_info @@ -396,6 +406,7 @@ static GTY (()) tree double_ftype_double; static GTY (()) tree ldouble_ftype_ldouble; static GTY (()) tree gm2_alloca_node; static GTY (()) tree gm2_memcpy_node; +static GTY (()) tree gm2_memset_node; static GTY (()) tree gm2_isfinite_node; static GTY (()) tree gm2_huge_valf_node; static GTY (()) tree gm2_huge_val_node; @@ -771,15 +782,36 @@ donModes (location_t location ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED) return m2decl_BuildIntegerConstant (1); } -/* BuiltInMemCopy - copy n bytes of memory efficiently from address +/* BuiltinMemCopy - copy n bytes of memory efficiently from address src to dest. */ tree -m2builtins_BuiltInMemCopy (location_t location, tree dest, tree src, tree n) +m2builtins_BuiltinMemCopy (location_t location, tree dest, tree src, tree n) { return DoBuiltinMemCopy (location, dest, src, n); } + +static tree +DoBuiltinMemSet (location_t location, tree ptr, tree bytevalue, tree nbytes) +{ + tree functype = TREE_TYPE (gm2_memset_node); + tree funcptr + = build1 (ADDR_EXPR, build_pointer_type (functype), gm2_memset_node); + tree call + = m2treelib_DoCall3 (location, ptr_type_node, funcptr, ptr, bytevalue, nbytes); + return call; +} + +/* BuiltinMemSet set copy n bytes of memory efficiently from address + src to dest. */ + +tree +m2builtins_BuiltinMemSet (location_t location, tree ptr, tree bytevalue, tree nbytes) +{ + return DoBuiltinMemSet (location, ptr, bytevalue, nbytes); +} + /* BuiltInAlloca - given an expression, n, allocate, n, bytes on the stack for the life of the current function. */ @@ -798,6 +830,65 @@ m2builtins_BuiltInIsfinite (location_t location, tree expression) return DoBuiltinIsfinite (location, expression); } + +/* do_target_support_exists returns true if the builting function + is supported by the target. */ + +static +bool +do_target_support_exists (struct builtin_function_entry *fe) +{ + tree type = TREE_TYPE (fe->function_node); + + switch (fe->function_avail) + { + case bf_true: + return true; + case bf_false: + return false; + case bf_extension_lib: + return true; + case bf_default_lib: + return true; + case bf_gcc: + return true; + case bf_c99: + return targetm.libc_has_function (function_c99_misc, type); + case bf_c99_c90res: + return targetm.libc_has_function (function_c99_misc, type); + case bf_extension_lib_floatn: + return true; + default: + gcc_unreachable (); + } + return false; +} + + +static +bool +target_support_exists (struct builtin_function_entry *fe) +{ +#if defined(DEBUGGING) + printf ("target_support_exists (%s): ", fe->library_name); +#endif + if (do_target_support_exists (fe)) + { +#if defined(DEBUGGING) + printf ("yes\n"); +#endif + return true; + } + else + { +#if defined(DEBUGGING) + printf ("no\n"); +#endif + return false; + } +} + + /* BuiltinExists - returns TRUE if the builtin function, name, exists for this target architecture. */ @@ -808,11 +899,13 @@ m2builtins_BuiltinExists (char *name) for (fe = &list_of_builtins[0]; fe->name != NULL; fe++) if (strcmp (name, fe->name) == 0) - return TRUE; + return true; + // return target_support_exists (fe); - return FALSE; + return false; } + /* BuildBuiltinTree - returns a Tree containing the builtin function, name. */ @@ -820,23 +913,23 @@ tree m2builtins_BuildBuiltinTree (location_t location, char *name) { struct builtin_function_entry *fe; - tree t; + tree call; m2statement_SetLastFunction (NULL_TREE); + for (fe = &list_of_builtins[0]; fe->name != NULL; fe++) - if (strcmp (name, fe->name) == 0) + if ((strcmp (name, fe->name) == 0) && target_support_exists (fe)) { tree functype = TREE_TYPE (fe->function_node); tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), fe->function_node); - - m2statement_SetLastFunction (m2treelib_DoCall ( - location, fe->return_node, funcptr, m2statement_GetParamList ())); + call = m2treelib_DoCall ( + location, fe->return_node, funcptr, m2statement_GetParamList ()); + m2statement_SetLastFunction (call); m2statement_SetParamList (NULL_TREE); - t = m2statement_GetLastFunction (); if (fe->return_node == void_type_node) m2statement_SetLastFunction (NULL_TREE); - return t; + return call; } m2statement_SetParamList (NULL_TREE); @@ -938,7 +1031,7 @@ create_function_prototype (location_t location, break; case BT_FN_LONG_DOUBLE: ftype = ldouble_ftype_void; - fe->return_node = long_double_type_node; + fe->return_node = m2type_GetM2LongRealType (); break; case BT_FN_FLOAT_FLOAT: ftype = float_ftype_float; @@ -950,7 +1043,7 @@ create_function_prototype (location_t location, break; case BT_FN_LONG_DOUBLE_LONG_DOUBLE: ftype = ldouble_ftype_ldouble; - fe->return_node = long_double_type_node; + fe->return_node = m2type_GetM2LongRealType (); break; case BT_FN_STRING_CONST_STRING_INT: ftype = build_function_type ( @@ -1032,7 +1125,7 @@ create_function_prototype (location_t location, case BT_FN_INT_LONG_DOUBLE: ftype = build_function_type ( integer_type_node, - tree_cons (NULL_TREE, long_double_type_node, endlink)); + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)); fe->return_node = integer_type_node; break; case BT_FN_FLOAT_FCOMPLEX: @@ -1049,9 +1142,9 @@ create_function_prototype (location_t location, break; case BT_FN_LONG_DOUBLE_LDCOMPLEX: ftype = build_function_type ( - long_double_type_node, - tree_cons (NULL_TREE, complex_long_double_type_node, endlink)); - fe->return_node = long_double_type_node; + m2type_GetM2LongRealType (), + tree_cons (NULL_TREE, m2type_GetM2LongComplexType (), endlink)); + fe->return_node = m2type_GetM2LongRealType (); break; case BT_FN_FCOMPLEX_FCOMPLEX: ftype = build_function_type ( @@ -1067,9 +1160,9 @@ create_function_prototype (location_t location, break; case BT_FN_LDCOMPLEX_LDCOMPLEX: ftype = build_function_type ( - complex_long_double_type_node, - tree_cons (NULL_TREE, complex_long_double_type_node, endlink)); - fe->return_node = complex_long_double_type_node; + m2type_GetM2LongComplexType (), + tree_cons (NULL_TREE, m2type_GetM2LongComplexType (), endlink)); + fe->return_node = m2type_GetM2LongComplexType (); break; case BT_FN_DCOMPLEX_DOUBLE_DCOMPLEX: ftype = build_function_type ( @@ -1087,10 +1180,10 @@ create_function_prototype (location_t location, break; case BT_FN_LDCOMPLEX_LONG_DOUBLE_LDCOMPLEX: ftype = build_function_type ( - complex_long_double_type_node, - tree_cons (NULL_TREE, complex_long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, endlink))); - fe->return_node = complex_long_double_type_node; + m2type_GetM2LongComplexType (), + tree_cons (NULL_TREE, m2type_GetM2LongComplexType (), + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink))); + fe->return_node = m2type_GetM2LongComplexType (); break; case BT_FN_FLOAT_FLOAT_FLOATPTR: ftype = build_function_type ( @@ -1108,32 +1201,32 @@ create_function_prototype (location_t location, break; case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLEPTR: ftype = build_function_type ( - long_double_type_node, + m2type_GetM2LongRealType (), tree_cons ( - NULL_TREE, long_double_type_node, + NULL_TREE, m2type_GetM2LongRealType (), tree_cons (NULL_TREE, long_doubleptr_type_node, endlink))); - fe->return_node = long_double_type_node; + fe->return_node = m2type_GetM2LongRealType (); break; case BT_FN_FLOAT_FLOAT_LONG_DOUBLE: ftype = build_function_type ( float_type_node, tree_cons (NULL_TREE, float_type_node, - tree_cons (NULL_TREE, long_double_type_node, endlink))); + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink))); fe->return_node = float_type_node; break; case BT_FN_DOUBLE_DOUBLE_LONG_DOUBLE: ftype = build_function_type ( double_type_node, tree_cons (NULL_TREE, double_type_node, - tree_cons (NULL_TREE, long_double_type_node, endlink))); + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink))); fe->return_node = double_type_node; break; case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE: ftype = build_function_type ( - long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, endlink))); - fe->return_node = long_double_type_node; + m2type_GetM2LongRealType (), + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink))); + fe->return_node = m2type_GetM2LongRealType (); break; case BT_FN_FLOAT_FLOAT_LONG: ftype = build_function_type ( @@ -1151,10 +1244,10 @@ create_function_prototype (location_t location, break; case BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG: ftype = build_function_type ( - long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, + m2type_GetM2LongRealType (), + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), tree_cons (NULL_TREE, long_integer_type_node, endlink))); - fe->return_node = long_double_type_node; + fe->return_node = m2type_GetM2LongRealType (); break; case BT_FN_FLOAT_FLOAT_INT: ftype = build_function_type ( @@ -1172,10 +1265,10 @@ create_function_prototype (location_t location, break; case BT_FN_LONG_DOUBLE_LONG_DOUBLE_INT: ftype = build_function_type ( - long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, + m2type_GetM2LongRealType (), + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), tree_cons (NULL_TREE, integer_type_node, endlink))); - fe->return_node = long_double_type_node; + fe->return_node = m2type_GetM2LongRealType (); break; case BT_FN_FLOAT_FLOAT_FLOAT: ftype = build_function_type ( @@ -1264,9 +1357,9 @@ m2builtins_init (location_t location) float_ftype_void = build_function_type (float_type_node, math_endlink); double_ftype_void = build_function_type (double_type_node, math_endlink); ldouble_ftype_void - = build_function_type (long_double_type_node, math_endlink); + = build_function_type (m2type_GetM2LongRealType (), math_endlink); - long_doubleptr_type_node = build_pointer_type (long_double_type_node); + long_doubleptr_type_node = build_pointer_type (m2type_GetM2LongRealType ()); doubleptr_type_node = build_pointer_type (double_type_node); floatptr_type_node = build_pointer_type (float_type_node); @@ -1277,8 +1370,8 @@ m2builtins_init (location_t location) double_type_node, tree_cons (NULL_TREE, double_type_node, math_endlink)); ldouble_ftype_ldouble = build_function_type ( - long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, endlink)); + m2type_GetM2LongRealType (), + tree_cons (NULL_TREE, m2type_GetM2LongRealType (), endlink)); builtin_ftype_int_var = build_function_type ( integer_type_node, tree_cons (NULL_TREE, double_type_node, endlink)); @@ -1306,6 +1399,7 @@ m2builtins_init (location_t location) gm2_alloca_node = find_builtin_tree ("__builtin_alloca"); gm2_memcpy_node = find_builtin_tree ("__builtin_memcpy"); + gm2_memset_node = find_builtin_tree ("__builtin_memset"); gm2_huge_valf_node = find_builtin_tree ("__builtin_huge_valf"); gm2_huge_val_node = find_builtin_tree ("__builtin_huge_val"); gm2_huge_vall_node = find_builtin_tree ("__builtin_huge_vall"); diff --git a/gcc/m2/gm2-gcc/m2builtins.def b/gcc/m2/gm2-gcc/m2builtins.def index bce8536..c6eefcd 100644 --- a/gcc/m2/gm2-gcc/m2builtins.def +++ b/gcc/m2/gm2-gcc/m2builtins.def @@ -28,7 +28,7 @@ FROM m2linemap IMPORT location_t ; EXPORT QUALIFIED GetBuiltinConst, GetBuiltinConstType, GetBuiltinTypeInfoType, GetBuiltinTypeInfo, BuiltinExists, BuildBuiltinTree, - BuiltInMemCopy, BuiltInAlloca, + BuiltinMemCopy, BuiltinMemSet, BuiltInAlloca, BuiltInIsfinite ; @@ -98,7 +98,14 @@ PROCEDURE BuildBuiltinTree (location: location_t; name: ADDRESS) : Tree ; BuiltinMemCopy and BuiltinAlloca - are called by M2GenGCC to implement open arrays. *) -PROCEDURE BuiltInMemCopy (location: location_t; dest, src, n: Tree) : Tree ; +PROCEDURE BuiltinMemCopy (location: location_t; dest, src, n: Tree) : Tree ; + + +(* + BuiltinMemSet is called by M2GenGCC to implement the set type. +*) + +PROCEDURE BuiltinMemSet (location: location_t; dest, bytevalue, nbytes: Tree) : Tree ; (* diff --git a/gcc/m2/gm2-gcc/m2builtins.h b/gcc/m2/gm2-gcc/m2builtins.h index 487a41a..8e2b60b 100644 --- a/gcc/m2/gm2-gcc/m2builtins.h +++ b/gcc/m2/gm2-gcc/m2builtins.h @@ -43,8 +43,10 @@ EXTERN unsigned int m2builtins_GetBuiltinConstType (char *name); EXTERN unsigned int m2builtins_GetBuiltinTypeInfoType (const char *ident); EXTERN tree m2builtins_GetBuiltinTypeInfo (location_t location, tree type, const char *ident); -EXTERN tree m2builtins_BuiltInMemCopy (location_t location, tree dest, +EXTERN tree m2builtins_BuiltinMemCopy (location_t location, tree dest, tree src, tree n); +EXTERN tree m2builtins_BuiltinMemSet (location_t location, tree dest, + tree bytevalue, tree nbytes); EXTERN tree m2builtins_BuiltInAlloca (location_t location, tree n); EXTERN tree m2builtins_BuiltInIsfinite (location_t location, tree e); EXTERN bool m2builtins_BuiltinExists (char *name); diff --git a/gcc/m2/gm2-gcc/m2configure.cc b/gcc/m2/gm2-gcc/m2configure.cc index 1c69103..46a57dd 100644 --- a/gcc/m2/gm2-gcc/m2configure.cc +++ b/gcc/m2/gm2-gcc/m2configure.cc @@ -99,3 +99,51 @@ m2configure_FullPathCPP (void) } return NULL; } + +/* Return true if M2C_LONGREAL_FLOAT128 is defined. */ + +bool +m2configure_M2CLongRealFloat128 (void) +{ +#if defined(M2C_LONGREAL_FLOAT128) + return true; +#else + return false; +#endif +} + +/* Return true if M2C_LONGREAL_IBM128 is defined. */ + +bool +m2configure_M2CLongRealIBM128 (void) +{ +#if defined(M2C_LONGREAL_IBM128) + return true; +#else + return false; +#endif +} + +/* Return true if M2C_LONGREAL_LONGDOUBLE is defined. */ + +bool +m2configure_M2CLongRealLongDouble (void) +{ +#if defined(M2C_LONGREAL_LONGDOUBLE) + return true; +#else + return false; +#endif +} + +/* Return true if the target is ppc64le. */ + +bool +m2configure_M2CLongRealLongDoublePPC64LE (void) +{ +#if defined(M2C_LONGREAL_PPC64LE) + return true; +#else + return false; +#endif +} diff --git a/gcc/m2/gm2-gcc/m2configure.def b/gcc/m2/gm2-gcc/m2configure.def index 7fe9ba6..9fc0876 100644 --- a/gcc/m2/gm2-gcc/m2configure.def +++ b/gcc/m2/gm2-gcc/m2configure.def @@ -22,7 +22,6 @@ along with GNU Modula-2; see the file COPYING3. If not see DEFINITION MODULE FOR "C" m2configure ; FROM SYSTEM IMPORT ADDRESS ; -EXPORT QUALIFIED UseUnderscoreForC, FullPathCPP ; CONST @@ -41,4 +40,39 @@ CONST PROCEDURE FullPathCPP () : ADDRESS ; +(* + M2CLongRealFloat128 - return true if M2C_LONGREAL_FLOAT128 + is defined. + Only one of M2CLongRealFloat128, + M2CLongRealIBM128, + M2CLongRealLongDouble will be set true. +*) + +PROCEDURE M2CLongRealFloat128 () : BOOLEAN ; + + +(* + M2CLongRealIBM128 - return true if M2C_LONGREAL_IBM128 + is defined. +*) + +PROCEDURE M2CLongRealIBM128 () : BOOLEAN ; + + +(* + M2CLongRealLongDouble - return true if M2C_LONGREAL_LONGDOUBLE + is defined. This is true if the LONGREAL + maps onto the default gcc long double type. +*) + +PROCEDURE M2CLongRealLongDouble () : BOOLEAN ; + + +(* + M2CLongRealLongDoublePPC64LE - return true if the target is ppc64le. +*) + +PROCEDURE M2CLongRealLongDoublePPC64LE () : BOOLEAN ; + + END m2configure. diff --git a/gcc/m2/gm2-gcc/m2configure.h b/gcc/m2/gm2-gcc/m2configure.h index 9e1a040..f98c71d 100644 --- a/gcc/m2/gm2-gcc/m2configure.h +++ b/gcc/m2/gm2-gcc/m2configure.h @@ -38,7 +38,20 @@ along with GNU Modula-2; see the file COPYING3. If not see #include "input.h" -EXTERN char *m2configure_FullPathCPP (void); +EXTERN char * +m2configure_FullPathCPP (void); + +EXTERN bool +m2configure_M2CLongRealFloat128 (void); + +EXTERN bool +m2configure_M2CLongRealIBM128 (void); + +EXTERN bool +m2configure_M2CLongRealLongDouble (void); + +EXTERN bool +m2configure_M2CLongRealLongDoublePPC64LE (void); #undef EXTERN #endif /* m2configure_h. */ diff --git a/gcc/m2/gm2-gcc/m2convert.cc b/gcc/m2/gm2-gcc/m2convert.cc index 5d35bce..7d9c722 100644 --- a/gcc/m2/gm2-gcc/m2convert.cc +++ b/gcc/m2/gm2-gcc/m2convert.cc @@ -478,7 +478,7 @@ m2convert_BuildConvert (location_t location, tree type, tree value, if (checkOverflow) return convert_and_check (location, type, value); else - return convert (type, value); + return convert_loc (location, type, value); } /* const_to_ISO_type - perform VAL (iso_type, expr). */ diff --git a/gcc/m2/gm2-gcc/m2options.h b/gcc/m2/gm2-gcc/m2options.h index 8bd820f..2ed2c9a 100644 --- a/gcc/m2/gm2-gcc/m2options.h +++ b/gcc/m2/gm2-gcc/m2options.h @@ -138,6 +138,7 @@ EXTERN void M2Options_SetM2PathName (const char *arg); EXTERN char *M2Options_GetM2PathName (void); EXTERN int M2Options_SetUninitVariableChecking (bool value, const char *arg); EXTERN void M2Options_SetCaseEnumChecking (bool value); +EXTERN void M2Options_SetDebugBuiltins (bool value); #undef EXTERN #endif /* m2options_h. */ diff --git a/gcc/m2/gm2-gcc/m2statement.cc b/gcc/m2/gm2-gcc/m2statement.cc index fa799c8..ffbe364 100644 --- a/gcc/m2/gm2-gcc/m2statement.cc +++ b/gcc/m2/gm2-gcc/m2statement.cc @@ -174,7 +174,9 @@ m2statement_BuildAssignmentTree (location_t location, tree des, tree expr) m2convert_BuildConvert (location, TREE_TYPE (des), expr, false)); } - TREE_SIDE_EFFECTS (result) = 1; + TREE_SIDE_EFFECTS (result) = true; + TREE_USED (des) = true; + TREE_USED (expr) = true; add_stmt (location, result); return des; } @@ -195,7 +197,7 @@ m2statement_BuildGoto (location_t location, char *name) tree label = m2block_getLabel (location, name); m2assert_AssertLocation (location); - TREE_USED (label) = 1; + TREE_USED (label) = true; add_stmt (location, build1 (GOTO_EXPR, void_type_node, label)); } @@ -218,6 +220,7 @@ m2statement_BuildParam (location_t location, tree param) { m2assert_AssertLocation (location); + TREE_USED (param) = true; if (TREE_CODE (param) == FUNCTION_DECL) param = m2expr_BuildAddr (location, param, false); @@ -349,6 +352,20 @@ m2statement_BuildIndirectProcedureCallTree (location_t location, } } + +/* BuildBuiltinCallTree calls the builtin procedure. */ + +tree +m2statement_BuildBuiltinCallTree (location_t location, tree func) +{ + TREE_USED (func) = true; + TREE_SIDE_EFFECTS (func) = true; + param_list + = NULL_TREE; /* Ready for the next time we call a procedure. */ + return func; +} + + /* BuildFunctValue - generates code for value := last_function(foobar); */ @@ -361,12 +378,14 @@ m2statement_BuildFunctValue (location_t location, tree value) m2assert_AssertLocation (location); ASSERT_CONDITION ( last_function - != NULL_TREE); /* No value available, possible used before. */ + != NULL_TREE); /* No value available, possible used before. */ TREE_SIDE_EFFECTS (assign) = true; TREE_USED (assign) = true; + TREE_USED (value) = true; last_function = NULL_TREE; return assign; + // return m2statement_BuildAssignmentTree (location, value, assign); } /* BuildCall2 - builds a tree representing: function (arg1, arg2). */ diff --git a/gcc/m2/gm2-gcc/m2statement.def b/gcc/m2/gm2-gcc/m2statement.def index 6c3a0ec..4ad77ec 100644 --- a/gcc/m2/gm2-gcc/m2statement.def +++ b/gcc/m2/gm2-gcc/m2statement.def @@ -309,4 +309,11 @@ PROCEDURE SetBeginLocation (location: location_t) ; PROCEDURE SetEndLocation (location: location_t) ; +(* + BuildBuiltinCallTree - calls the builtin procedure. +*) + +PROCEDURE BuildBuiltinCallTree (location: location_t; func: Tree) : Tree ; + + END m2statement. diff --git a/gcc/m2/gm2-gcc/m2statement.h b/gcc/m2/gm2-gcc/m2statement.h index 1ca70f8..b0531ed 100644 --- a/gcc/m2/gm2-gcc/m2statement.h +++ b/gcc/m2/gm2-gcc/m2statement.h @@ -103,6 +103,8 @@ EXTERN tree m2statement_GetCurrentFunction (void); EXTERN void m2statement_SetBeginLocation (location_t location); EXTERN void m2statement_SetEndLocation (location_t location); EXTERN tree m2statement_GetParamTree (tree call, unsigned int i); +EXTERN tree m2statement_BuildBuiltinCallTree (location_t location, tree func); + EXTERN tree m2statement_BuildTryFinally (location_t location, tree call, tree cleanups); EXTERN tree m2statement_BuildCleanUp (tree param); diff --git a/gcc/m2/gm2-gcc/m2treelib.cc b/gcc/m2/gm2-gcc/m2treelib.cc index 6694af6..168f9f4 100644 --- a/gcc/m2/gm2-gcc/m2treelib.cc +++ b/gcc/m2/gm2-gcc/m2treelib.cc @@ -188,7 +188,6 @@ m2treelib_DoCall0 (location_t location, tree rettype, tree funcptr) tree *argarray = XALLOCAVEC (tree, 1); argarray[0] = NULL_TREE; - return build_call_array_loc (location, rettype, funcptr, 0, argarray); } @@ -200,7 +199,6 @@ m2treelib_DoCall1 (location_t location, tree rettype, tree funcptr, tree arg0) tree *argarray = XALLOCAVEC (tree, 1); argarray[0] = arg0; - return build_call_array_loc (location, rettype, funcptr, 1, argarray); } @@ -214,7 +212,6 @@ m2treelib_DoCall2 (location_t location, tree rettype, tree funcptr, tree arg0, argarray[0] = arg0; argarray[1] = arg1; - return build_call_array_loc (location, rettype, funcptr, 2, argarray); } @@ -229,7 +226,6 @@ m2treelib_DoCall3 (location_t location, tree rettype, tree funcptr, tree arg0, argarray[0] = arg0; argarray[1] = arg1; argarray[2] = arg2; - return build_call_array_loc (location, rettype, funcptr, 3, argarray); } @@ -377,12 +373,12 @@ m2treelib_get_set_address_if_var (location_t location, tree op, bool is_lvalue, return m2treelib_get_set_address (location, op, is_lvalue); } -/* add_stmt - t is a statement. Add it to the statement-tree. */ +/* add_stmt add stmt to the statement-tree. */ tree -add_stmt (location_t location, tree t) +add_stmt (location_t location, tree stmt) { - return m2block_add_stmt (location, t); + return m2block_add_stmt (location, stmt); } /* taken from gcc/c-semantics.cc. */ diff --git a/gcc/m2/gm2-gcc/m2type.cc b/gcc/m2/gm2-gcc/m2type.cc index eeee355..86edde5 100644 --- a/gcc/m2/gm2-gcc/m2type.cc +++ b/gcc/m2/gm2-gcc/m2type.cc @@ -37,6 +37,7 @@ along with GNU Modula-2; see the file COPYING3. If not see #include "m2treelib.h" #include "m2type.h" #include "m2options.h" +#include "m2configure.h" #define USE_BOOLEAN static int broken_set_debugging_info = true; @@ -935,7 +936,6 @@ build_set_type (tree domain, tree range_type, int allow_void, int ispacked) TREE_TYPE (type) = range_type; TYPE_DOMAIN (type) = domain; TYPE_PACKED (type) = ispacked; - return type; } @@ -1104,7 +1104,6 @@ build_m2_specific_size_type (location_t location, enum tree_code base, TYPE_UNSIGNED (c) = true; } } - return c; } @@ -1153,7 +1152,6 @@ finish_build_pointer_type (tree t, tree to_type, enum machine_mode mode, /* Lay out the type. */ /* layout_type (t); */ layout_type (t); - return t; } @@ -1344,7 +1342,6 @@ m2type_BuildVariableArrayAndDeclare (location_t location, tree elementtype, gm2_finish_decl (location, indextype); gm2_finish_decl (location, arraytype); add_stmt (location, build_stmt (location, DECL_EXPR, decl)); - return decl; } @@ -1443,7 +1440,6 @@ build_m2_short_real_node (void) c = make_node (REAL_TYPE); TYPE_PRECISION (c) = FLOAT_TYPE_SIZE; layout_type (c); - return c; } @@ -1457,7 +1453,6 @@ build_m2_real_node (void) c = make_node (REAL_TYPE); TYPE_PRECISION (c) = DOUBLE_TYPE_SIZE; layout_type (c); - return c; } @@ -1468,10 +1463,17 @@ build_m2_long_real_node (void) /* Define `LONGREAL'. */ - c = make_node (REAL_TYPE); - TYPE_PRECISION (c) = LONG_DOUBLE_TYPE_SIZE; - layout_type (c); + if (m2configure_M2CLongRealFloat128 ()) + c = float128_type_node; + else if (m2configure_M2CLongRealIBM128 ()) + { + c = make_node (REAL_TYPE); + TYPE_PRECISION (c) = LONG_DOUBLE_TYPE_SIZE; + } + else + c = long_double_type_node; + layout_type (c); return c; } @@ -1487,7 +1489,6 @@ build_m2_ztype_node (void) else ztype_node = gm2_type_for_size (64, 0); layout_type (ztype_node); - return ztype_node; } @@ -1500,7 +1501,6 @@ build_m2_long_int_node (void) c = make_signed_type (LONG_LONG_TYPE_SIZE); layout_type (c); - return c; } @@ -1513,7 +1513,6 @@ build_m2_long_card_node (void) c = make_unsigned_type (LONG_LONG_TYPE_SIZE); layout_type (c); - return c; } @@ -1526,7 +1525,6 @@ build_m2_short_int_node (void) c = make_signed_type (SHORT_TYPE_SIZE); layout_type (c); - return c; } @@ -1539,7 +1537,6 @@ build_m2_short_card_node (void) c = make_unsigned_type (SHORT_TYPE_SIZE); layout_type (c); - return c; } @@ -1556,7 +1553,6 @@ build_m2_iso_loc_node (void) fixup_unsigned_type (c); TYPE_UNSIGNED (c) = 1; - return c; } @@ -1754,6 +1750,16 @@ build_m2_boolean (location_t location) TYPE_NAME (boolean_type_node) = typedecl; } + +/* Return true if real types a and b are the same. */ + +bool +m2type_SameRealType (tree a, tree b) +{ + return ((a == b) + || (TYPE_PRECISION (a) == TYPE_PRECISION (b))); +} + /* InitBaseTypes create the Modula-2 base types. */ void @@ -1797,7 +1803,7 @@ m2type_InitBaseTypes (location_t location) m2_complex_type_node = build_m2_complex_type_node (); m2_long_complex_type_node = build_m2_long_complex_type_node (); m2_short_complex_type_node = build_m2_short_complex_type_node (); - m2_c_type_node = build_m2_long_complex_type_node (); + m2_c_type_node = m2_long_complex_type_node; m2_complex32_type_node = build_m2_complex32_type_node (); m2_complex64_type_node = build_m2_complex64_type_node (); m2_complex96_type_node = build_m2_complex96_type_node (); @@ -2575,7 +2581,8 @@ gm2_start_struct (location_t location, enum tree_code code, char *name) else id = get_identifier (name); - TYPE_PACKED (s) = false; /* This maybe set true later if necessary. */ + /* This maybe set true later if necessary. */ + TYPE_PACKED (s) = false; m2block_pushDecl (build_decl (location, TYPE_DECL, id, s)); return s; @@ -2814,7 +2821,6 @@ m2type_SetAlignment (tree node, tree align) error ("requested alignment is too large"); else if (is_type) { - /* If we have a TYPE_DECL, then copy the type, so that we don't accidentally modify a builtin type. See pushdecl. */ if (decl && TREE_TYPE (decl) != error_mark_node diff --git a/gcc/m2/gm2-gcc/m2type.def b/gcc/m2/gm2-gcc/m2type.def index 1528104..257e7e1 100644 --- a/gcc/m2/gm2-gcc/m2type.def +++ b/gcc/m2/gm2-gcc/m2type.def @@ -983,4 +983,11 @@ PROCEDURE BuildStartArrayType (index_type: Tree; elt_type: Tree; type: INTEGER) PROCEDURE IsAddress (type: Tree) : BOOLEAN ; +(* + SameRealType - return true if real types a and b are the same. +*) + +PROCEDURE SameRealType (a, b: Tree) : BOOLEAN ; + + END m2type. diff --git a/gcc/m2/gm2-gcc/m2type.h b/gcc/m2/gm2-gcc/m2type.h index 7186116..949e104 100644 --- a/gcc/m2/gm2-gcc/m2type.h +++ b/gcc/m2/gm2-gcc/m2type.h @@ -219,6 +219,8 @@ EXTERN tree m2type_BuildProcTypeParameterDeclaration (location_t location, bool isreference); EXTERN int m2type_IsAddress (tree type); EXTERN tree m2type_GetCardinalAddressType (void); +EXTERN bool m2type_SameRealType (tree a, tree b); + #undef EXTERN #endif /* m2type_h */ diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc index 2b702cd..45b5fe2 100644 --- a/gcc/m2/gm2-lang.cc +++ b/gcc/m2/gm2-lang.cc @@ -427,6 +427,9 @@ gm2_langhook_handle_option ( case OPT_fd: M2Options_SetCompilerDebugging (value); return 1; + case OPT_fdebug_builtins: + M2Options_SetDebugBuiltins (value); + return 1; case OPT_fdebug_trace_quad: M2Options_SetDebugTraceQuad (value); return 1; @@ -809,14 +812,25 @@ gm2_langhook_type_for_mode (machine_mode mode, int unsignedp) if (mode == TYPE_MODE (long_double_type_node)) return long_double_type_node; + if ((float128_type_node != NULL) && (mode == TYPE_MODE (float128_type_node))) + return float128_type_node; + if (COMPLEX_MODE_P (mode)) { + machine_mode inner_mode; + tree inner_type; + if (mode == TYPE_MODE (complex_float_type_node)) return complex_float_type_node; if (mode == TYPE_MODE (complex_double_type_node)) return complex_double_type_node; if (mode == TYPE_MODE (complex_long_double_type_node)) return complex_long_double_type_node; + + inner_mode = GET_MODE_INNER (mode); + inner_type = gm2_langhook_type_for_mode (inner_mode, unsignedp); + if (inner_type != NULL_TREE) + return build_complex_type (inner_type); } #if HOST_BITS_PER_WIDE_INT >= 64 diff --git a/gcc/m2/gm2-libs-log/RealConversions.mod b/gcc/m2/gm2-libs-log/RealConversions.mod index 189096a..02e0f92 100644 --- a/gcc/m2/gm2-libs-log/RealConversions.mod +++ b/gcc/m2/gm2-libs-log/RealConversions.mod @@ -57,12 +57,29 @@ VAR #define Slice(X,Y,Z) SliceDB(X, Y, Z, __FILE__, __LINE__) *) + (* - logl10 - + IsNan - return TRUE if x is a nan (which never are equal to themselves). +*) + +PROCEDURE IsNan (x: LONGREAL) : BOOLEAN ; +BEGIN + RETURN x # x +END IsNan ; + + +(* + logl10 - this is a local implementation of log10l, currently the ppe64le + builtin log10l is broken. *) PROCEDURE logl10 (r: LONGREAL) : LONGREAL ; BEGIN + IF Debugging + THEN + printf ("logl10 (%lf) = %lf, logl/logl(10.0) = %lf\n", + r, log10l (r), logl(r)/logl(10.0)) + END ; RETURN logl(r)/logl(10.0) END logl10 ; @@ -138,18 +155,9 @@ BEGIN END ; IF c>=1.0 THEN - RETURN( VAL(INTEGER, log10l(c)) ) + RETURN VAL (INTEGER, log10l (c)) ELSE - i := 0 ; - LOOP - d := c*powl(10.0, VAL(LONGREAL, i)) ; - IF d>=1.0 - THEN - RETURN( -i ) - ELSE - INC(i) - END - END + RETURN VAL (INTEGER, log10l (c)) -1 END END END doPowerOfTen ; @@ -245,7 +253,7 @@ BEGIN ELSE ... END - *) + *) l := VAL(LONGREAL, r) ; LongRealToString(l, digits, width, str, ok) END RealToString ; @@ -397,14 +405,12 @@ VAR s : String ; powerOfTen: INTEGER ; BEGIN - (* --fixme-- *) - (* IF IsNan(r) - THEN - ok := FALSE ; - MakeNanString(str, width) ; - RETURN - END - *) + IF IsNan (r) + THEN + ok := FALSE ; + MakeNanString (str, width) ; + RETURN + END ; powerOfTen := doPowerOfTen(r) ; IF (powerOfTen=MAX(INTEGER)) OR (powerOfTen=MIN(INTEGER)) THEN diff --git a/gcc/m2/gm2-libs/Builtins.mod b/gcc/m2/gm2-libs/Builtins.mod index 70c1f8a..707f0e3 100644 --- a/gcc/m2/gm2-libs/Builtins.mod +++ b/gcc/m2/gm2-libs/Builtins.mod @@ -28,6 +28,7 @@ IMPLEMENTATION MODULE Builtins ; IMPORT cbuiltin, wrapc ; + PROCEDURE __ATTRIBUTE__ __BUILTIN__ ((__builtin_alloca)) alloca (i: CARDINAL) : ADDRESS ; BEGIN (* This routine will never be called as it allocates memory on diff --git a/gcc/m2/gm2-libs/DynamicStrings.def b/gcc/m2/gm2-libs/DynamicStrings.def index 90930a9..785c327 100644 --- a/gcc/m2/gm2-libs/DynamicStrings.def +++ b/gcc/m2/gm2-libs/DynamicStrings.def @@ -32,7 +32,7 @@ EXPORT QUALIFIED String, InitStringChar, Index, RIndex, Mark, Length, ConCat, ConCatChar, Assign, Dup, Add, Equal, EqualCharStar, EqualArray, ToUpper, ToLower, - CopyOut, Mult, Slice, + CopyOut, Mult, Slice, ReplaceChar, RemoveWhitePrefix, RemoveWhitePostfix, RemoveComment, char, string, InitStringDB, InitStringCharStarDB, InitStringCharDB, @@ -123,6 +123,14 @@ PROCEDURE Assign (a, b: String) : String ; (* + ReplaceChar - returns string s after it has changed all + occurances of from to to. +*) + +PROCEDURE ReplaceChar (s: String; from, to: CHAR) : String ; + + +(* Dup - duplicate a String, s, returning the copy of s. *) diff --git a/gcc/m2/gm2-libs/DynamicStrings.mod b/gcc/m2/gm2-libs/DynamicStrings.mod index 2c93130..b90bc3f 100644 --- a/gcc/m2/gm2-libs/DynamicStrings.mod +++ b/gcc/m2/gm2-libs/DynamicStrings.mod @@ -1135,6 +1135,31 @@ END ConCatChar ; (* + ReplaceChar - returns string s after it has changed all occurances of from to to. +*) + +PROCEDURE ReplaceChar (s: String; from, to: CHAR) : String ; +VAR + t: String ; + i: CARDINAL ; +BEGIN + t := s ; + WHILE t # NIL DO + i := 0 ; + WHILE i < t^.contents.len DO + IF t^.contents.buf[i] = from + THEN + t^.contents.buf[i] := to + END ; + INC (i) + END ; + t := t^.contents.next + END ; + RETURN s +END ReplaceChar ; + + +(* Assign - assigns the contents of, b, into, a. String, a, is returned. *) diff --git a/gcc/m2/gm2config.aci.in b/gcc/m2/gm2config.aci.in index cb9f505..5228ef0 100644 --- a/gcc/m2/gm2config.aci.in +++ b/gcc/m2/gm2config.aci.in @@ -48,6 +48,12 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* use __float128 for LONGREAL */ +#undef M2C_LONGREAL_FLOAT128 + +/* target is ppc64le */ +#undef M2C_LONGREAL_PPC64LE + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc index 75a6ed3..0da9a57 100644 --- a/gcc/m2/gm2spec.cc +++ b/gcc/m2/gm2spec.cc @@ -475,6 +475,15 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, /* True if we should set up include paths and library paths. */ bool allow_libraries = true; +#ifdef M2C_LONGREAL_PPC64LE + /* Should we add -mabi=ieeelongdouble by default? */ +#ifdef M2C_LONGREAL_FLOAT128 + bool need_default_mabi = true; +#else + bool need_default_mabi = false; +#endif +#endif + #if defined(DEBUG_ARG) printf ("argc = %d\n", argc); fprintf (stderr, "Incoming:"); @@ -580,6 +589,16 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, args[i] |= SKIPOPT; /* We will add the option if it is needed. */ push_back_Ipath (decoded_options[i].arg); break; +#if defined(OPT_mabi_ibmlongdouble) + case OPT_mabi_ibmlongdouble: + need_default_mabi = false; /* User has specified a -mabi. */ + break; +#endif +#if defined(OPT_mabi_ieeelongdouble) + case OPT_mabi_ieeelongdouble: + need_default_mabi = true; /* User has specified a -mabi. */ + break; +#endif case OPT_nostdlib: case OPT_nostdlib__: case OPT_nodefaultlibs: @@ -849,6 +868,11 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, if (need_plugin) append_option (OPT_fplugin_, "m2rte", 1); +#ifdef M2C_LONGREAL_PPC64LE + if (need_default_mabi) + append_option (OPT_mabi_ieeelongdouble, NULL, 1); +#endif + if (linking) { if (allow_libraries) diff --git a/gcc/m2/lang.opt b/gcc/m2/lang.opt index f906d4e..24f3c65 100644 --- a/gcc/m2/lang.opt +++ b/gcc/m2/lang.opt @@ -30,6 +30,10 @@ Language Modula-2 +Wcase-enum +Modula-2 +turns on case statement label compile time checking when using an expression of an enum type. + Wpedantic-param-names Modula-2 compiler checks to force definition module procedure parameter names with their implementation module counterpart @@ -46,6 +50,14 @@ Wstyle Modula-2 extra compile time semantic checking, typically tries to catch poor programming style +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. + fauto-init Modula-2 automatically initializes all pointers to NIL @@ -277,10 +289,6 @@ Wall Modula-2 ; Documented in c.opt -Wcase-enum -Modula-2 -turns on case statement label compile time checking when using an expression of an enum type. - Wpedantic Modula-2 ; Documented in common.opt @@ -297,14 +305,6 @@ Wunused-parameter Modula-2 ; Documented in c.opt -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/m2/m2pp.cc b/gcc/m2/m2pp.cc index d502c93..5677951 100644 --- a/gcc/m2/m2pp.cc +++ b/gcc/m2/m2pp.cc @@ -1308,6 +1308,33 @@ m2pp_complex (pretty *s, tree t ATTRIBUTE_UNUSED) } #endif +void +m2pp_real_type (pretty *s, tree t) +{ + if (t == m2type_GetRealType ()) + m2pp_print (s, "C double"); + else if (t == m2type_GetShortRealType ()) + m2pp_print (s, "C float"); + else if (t == m2type_GetLongRealType ()) + m2pp_print (s, "C long double"); + else if (t == m2type_GetM2RealType ()) + m2pp_print (s, "REAL"); + else if (t == m2type_GetM2ShortRealType ()) + m2pp_print (s, "SHORTREAL"); + else if (t == m2type_GetM2LongRealType ()) + m2pp_print (s, "LONGREAL"); + else if (t == m2type_GetM2Real128 ()) + m2pp_print (s, "REAL128"); + else if (t == m2type_GetM2Real64 ()) + m2pp_print (s, "REAL64"); + else if (t == m2type_GetM2Real32 ()) + m2pp_print (s, "REAL32"); + else if (t == m2type_GetM2RType ()) + m2pp_print (s, "R Type"); + else + m2pp_print (s, "unknown REAL"); +} + /* m2pp_type prints a full type. */ void @@ -1326,7 +1353,7 @@ m2pp_type (pretty *s, tree t) m2pp_integer (s, t); break; case REAL_TYPE: - m2pp_print (s, "REAL"); + m2pp_real_type (s, t); break; case ENUMERAL_TYPE: m2pp_enum (s, t); @@ -1593,6 +1620,22 @@ m2pp_union_type (pretty *s, tree t) pop (); } +/* m2pp_print_mode. */ + +static void +m2pp_print_mode (pretty *s, tree t) +{ + int mode = SCALAR_FLOAT_TYPE_MODE (t); + char buf[100]; + + snprintf (buf, sizeof (buf), "%d", mode); + m2pp_print (s, "<*"); + m2pp_needspace (s); + m2pp_print (s, buf); + m2pp_needspace (s); + m2pp_print (s, "*>"); +} + /* m2pp_simple_type. */ static void @@ -1611,7 +1654,8 @@ m2pp_simple_type (pretty *s, tree t) m2pp_integer (s, t); break; case REAL_TYPE: - m2pp_print (s, "REAL"); + m2pp_real_type (s, t); + m2pp_print_mode (s, t); break; case BOOLEAN_TYPE: m2pp_print (s, "BOOLEAN"); @@ -1642,6 +1686,19 @@ m2pp_simple_type (pretty *s, tree t) } } +/* m2pp_float issue a VAL (type, expr) expression. */ + +static void +m2pp_float (pretty *s, tree t) +{ + m2pp_needspace (s); + m2pp_print (s, "VAL ("); + m2pp_simple_type (s, TREE_TYPE (t)); + m2pp_print (s, ", "); + m2pp_expression (s, TREE_OPERAND (t, 0)); + m2pp_print (s, ")"); +} + /* m2pp_expression display an expression. */ static void @@ -1669,6 +1726,9 @@ m2pp_expression (pretty *s, tree t) case GT_EXPR: m2pp_relop (s, t, ">"); break; + case FLOAT_EXPR: + m2pp_float (s, t); + break; default: m2pp_simple_expression (s, t); } diff --git a/gcc/m2/mc-boot/GDynamicStrings.cc b/gcc/m2/mc-boot/GDynamicStrings.cc index 0076047..a79583c 100644 --- a/gcc/m2/mc-boot/GDynamicStrings.cc +++ b/gcc/m2/mc-boot/GDynamicStrings.cc @@ -188,6 +188,12 @@ extern "C" DynamicStrings_String DynamicStrings_ConCatChar (DynamicStrings_Strin extern "C" DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, DynamicStrings_String b); /* + ReplaceChar - returns string s after it has changed all occurances of from to to. +*/ + +extern "C" DynamicStrings_String DynamicStrings_ReplaceChar (DynamicStrings_String s, char from, char to); + +/* Dup - duplicate a String, s, returning the copy of s. */ @@ -1816,6 +1822,35 @@ extern "C" DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, /* + ReplaceChar - returns string s after it has changed all occurances of from to to. +*/ + +extern "C" DynamicStrings_String DynamicStrings_ReplaceChar (DynamicStrings_String s, char from, char to) +{ + DynamicStrings_String t; + unsigned int i; + + t = s; + while (t != NULL) + { + i = 0; + while (i < t->contents.len) + { + if (t->contents.buf.array[i] == from) + { + t->contents.buf.array[i] = to; + } + i += 1; + } + t = t->contents.next; + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* Dup - duplicate a String, s, returning the copy of s. */ @@ -1828,7 +1863,7 @@ extern "C" DynamicStrings_String DynamicStrings_Dup (DynamicStrings_String s) s = DynamicStrings_Assign (DynamicStrings_InitString ((const char *) "", 0), s); if (TraceOn) { - s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1173, (const char *) "Dup", 3); + s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1198, (const char *) "Dup", 3); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ @@ -1850,7 +1885,7 @@ extern "C" DynamicStrings_String DynamicStrings_Add (DynamicStrings_String a, Dy a = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "", 0), a), b); if (TraceOn) { - a = AssignDebug (a, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1193, (const char *) "Add", 3); + a = AssignDebug (a, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1218, (const char *) "Add", 3); } return a; /* static analysis guarentees a RETURN statement will be used before here. */ @@ -1915,7 +1950,7 @@ extern "C" bool DynamicStrings_EqualCharStar (DynamicStrings_String s, void * a) t = DynamicStrings_InitStringCharStar (a); if (TraceOn) { - t = AssignDebug (t, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1250, (const char *) "EqualCharStar", 13); + t = AssignDebug (t, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1275, (const char *) "EqualCharStar", 13); } t = AddToGarbage (t, s); if (DynamicStrings_Equal (t, s)) @@ -1953,7 +1988,7 @@ extern "C" bool DynamicStrings_EqualArray (DynamicStrings_String s, const char * t = DynamicStrings_InitString ((const char *) a, _a_high); if (TraceOn) { - t = AssignDebug (t, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1280, (const char *) "EqualArray", 10); + t = AssignDebug (t, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1305, (const char *) "EqualArray", 10); } t = AddToGarbage (t, s); if (DynamicStrings_Equal (t, s)) @@ -1991,7 +2026,7 @@ extern "C" DynamicStrings_String DynamicStrings_Mult (DynamicStrings_String s, u } if (TraceOn) { - s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1312, (const char *) "Mult", 4); + s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1337, (const char *) "Mult", 4); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ @@ -2070,7 +2105,7 @@ extern "C" DynamicStrings_String DynamicStrings_Slice (DynamicStrings_String s, AddDebugInfo (t->contents.next); if (TraceOn) { - t->contents.next = AssignDebug (t->contents.next, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1380, (const char *) "Slice", 5); + t->contents.next = AssignDebug (t->contents.next, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1405, (const char *) "Slice", 5); } } t = t->contents.next; @@ -2088,7 +2123,7 @@ extern "C" DynamicStrings_String DynamicStrings_Slice (DynamicStrings_String s, } if (TraceOn) { - d = AssignDebug (d, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1397, (const char *) "Slice", 5); + d = AssignDebug (d, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1422, (const char *) "Slice", 5); } return d; /* static analysis guarentees a RETURN statement will be used before here. */ @@ -2216,7 +2251,7 @@ extern "C" DynamicStrings_String DynamicStrings_RemoveComment (DynamicStrings_St } if (TraceOn) { - s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1509, (const char *) "RemoveComment", 13); + s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1534, (const char *) "RemoveComment", 13); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ @@ -2241,7 +2276,7 @@ extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePrefix (DynamicString s = DynamicStrings_Slice (s, (int ) (i), 0); if (TraceOn) { - s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1621, (const char *) "RemoveWhitePrefix", 17); + s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1646, (const char *) "RemoveWhitePrefix", 17); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ @@ -2266,7 +2301,7 @@ extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePostfix (DynamicStrin s = DynamicStrings_Slice (s, 0, i+1); if (TraceOn) { - s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1643, (const char *) "RemoveWhitePostfix", 18); + s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1668, (const char *) "RemoveWhitePostfix", 18); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ diff --git a/gcc/m2/mc-boot/GDynamicStrings.h b/gcc/m2/mc-boot/GDynamicStrings.h index d20d618..c3fb7ff 100644 --- a/gcc/m2/mc-boot/GDynamicStrings.h +++ b/gcc/m2/mc-boot/GDynamicStrings.h @@ -125,6 +125,13 @@ EXTERN DynamicStrings_String DynamicStrings_ConCatChar (DynamicStrings_String a, EXTERN DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, DynamicStrings_String b); /* + ReplaceChar - returns string s after it has changed all + occurances of from to to. +*/ + +EXTERN DynamicStrings_String DynamicStrings_ReplaceChar (DynamicStrings_String s, char from, char to); + +/* Dup - duplicate a String, s, returning the copy of s. */ diff --git a/gcc/m2/mc-boot/GFIO.cc b/gcc/m2/mc-boot/GFIO.cc index a3f5362..683a11f 100644 --- a/gcc/m2/mc-boot/GFIO.cc +++ b/gcc/m2/mc-boot/GFIO.cc @@ -195,7 +195,7 @@ extern "C" void FIO_FlushBuffer (FIO_File f); extern "C" unsigned int FIO_ReadNBytes (FIO_File f, unsigned int nBytes, void * dest); /* - 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. */ @@ -213,7 +213,7 @@ extern "C" void FIO_ReadAny (FIO_File f, unsigned char *a, unsigned int _a_high) extern "C" unsigned int FIO_WriteNBytes (FIO_File f, unsigned int nBytes, void * src); /* - 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. */ @@ -410,7 +410,7 @@ static int ReadFromBuffer (FIO_File f, void * a, unsigned int nBytes); Useful when performing small reads. */ -static int BufferedRead (FIO_File f, unsigned int nBytes, void * a); +static int BufferedRead (FIO_File f, unsigned int nBytes, void * dest); /* HandleEscape - translates @@ -473,7 +473,7 @@ static void SetEndOfLine (FIO_File f, char ch); Useful when performing small writes. */ -static int BufferedWrite (FIO_File f, unsigned int nBytes, void * a); +static int BufferedWrite (FIO_File f, unsigned int nBytes, void * src); /* PreInitialize - preinitialize the file descriptor. @@ -809,11 +809,11 @@ static int ReadFromBuffer (FIO_File f, void * a, unsigned int nBytes) Useful when performing small reads. */ -static int BufferedRead (FIO_File f, unsigned int nBytes, void * a) +static int BufferedRead (FIO_File f, unsigned int nBytes, void * dest) { typedef unsigned char *BufferedRead__T3; - void * t; + void * src; int total; int n; BufferedRead__T3 p; @@ -835,7 +835,7 @@ static int BufferedRead (FIO_File f, unsigned int nBytes, void * a) if (nBytes == 1) { /* too expensive to call memcpy for 1 character */ - p = static_cast<BufferedRead__T3> (a); + p = static_cast<BufferedRead__T3> (dest); (*p) = static_cast<unsigned char> ((*fd->buffer->contents).array[fd->buffer->position]); fd->buffer->left -= 1; /* remove consumed byte */ fd->buffer->position += 1; /* move onwards n byte */ @@ -845,13 +845,13 @@ static int BufferedRead (FIO_File f, unsigned int nBytes, void * a) else { n = Min (fd->buffer->left, nBytes); - t = fd->buffer->address; - t = reinterpret_cast<void *> (reinterpret_cast<char *> (t)+fd->buffer->position); - p = static_cast<BufferedRead__T3> (libc_memcpy (a, t, static_cast<size_t> (n))); + src = fd->buffer->address; + src = reinterpret_cast<void *> (reinterpret_cast<char *> (src)+fd->buffer->position); + p = static_cast<BufferedRead__T3> (libc_memcpy (dest, src, static_cast<size_t> (n))); fd->buffer->left -= n; /* remove consumed bytes */ fd->buffer->position += n; /* move onwards n bytes */ /* move onwards ready for direct reads */ - a = reinterpret_cast<void *> (reinterpret_cast<char *> (a)+n); + dest = reinterpret_cast<void *> (reinterpret_cast<char *> (dest)+n); nBytes -= n; /* reduce the amount for future direct */ /* read */ total += n; @@ -1236,11 +1236,11 @@ static void SetEndOfLine (FIO_File f, char ch) Useful when performing small writes. */ -static int BufferedWrite (FIO_File f, unsigned int nBytes, void * a) +static int BufferedWrite (FIO_File f, unsigned int nBytes, void * src) { typedef unsigned char *BufferedWrite__T5; - void * t; + void * dest; int total; int n; BufferedWrite__T5 p; @@ -1262,7 +1262,7 @@ static int BufferedWrite (FIO_File f, unsigned int nBytes, void * a) if (nBytes == 1) { /* too expensive to call memcpy for 1 character */ - p = static_cast<BufferedWrite__T5> (a); + p = static_cast<BufferedWrite__T5> (src); (*fd->buffer->contents).array[fd->buffer->position] = static_cast<char> ((*p)); fd->buffer->left -= 1; /* reduce space */ fd->buffer->position += 1; /* move onwards n byte */ @@ -1272,13 +1272,13 @@ static int BufferedWrite (FIO_File f, unsigned int nBytes, void * a) else { n = Min (fd->buffer->left, nBytes); - t = fd->buffer->address; - t = reinterpret_cast<void *> (reinterpret_cast<char *> (t)+fd->buffer->position); - p = static_cast<BufferedWrite__T5> (libc_memcpy (a, t, static_cast<size_t> ((unsigned int ) (n)))); + dest = fd->buffer->address; + dest = reinterpret_cast<void *> (reinterpret_cast<char *> (dest)+fd->buffer->position); + p = static_cast<BufferedWrite__T5> (libc_memcpy (dest, src, static_cast<size_t> ((unsigned int ) (n)))); fd->buffer->left -= n; /* remove consumed bytes */ fd->buffer->position += n; /* move onwards n bytes */ /* move ready for further writes */ - a = reinterpret_cast<void *> (reinterpret_cast<char *> (a)+n); + src = reinterpret_cast<void *> (reinterpret_cast<char *> (src)+n); nBytes -= n; /* reduce the amount for future writes */ total += n; /* reduce the amount for future writes */ } @@ -1686,7 +1686,7 @@ extern "C" unsigned int FIO_ReadNBytes (FIO_File f, unsigned int nBytes, void * /* - 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. */ @@ -1694,7 +1694,7 @@ extern "C" unsigned int FIO_ReadNBytes (FIO_File f, unsigned int nBytes, void * extern "C" void FIO_ReadAny (FIO_File f, unsigned char *a, unsigned int _a_high) { CheckAccess (f, FIO_openedforread, false); - if ((BufferedRead (f, _a_high, a)) == ((int ) (_a_high))) + if ((BufferedRead (f, _a_high+1, a)) == ((int ) (_a_high+1))) { SetEndOfLine (f, static_cast<char> (a[_a_high])); } @@ -1745,7 +1745,7 @@ extern "C" unsigned int FIO_WriteNBytes (FIO_File f, unsigned int nBytes, void * /* - 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. */ @@ -1753,7 +1753,7 @@ extern "C" unsigned int FIO_WriteNBytes (FIO_File f, unsigned int nBytes, void * extern "C" void FIO_WriteAny (FIO_File f, unsigned char *a, unsigned int _a_high) { CheckAccess (f, FIO_openedforwrite, true); - if ((BufferedWrite (f, _a_high, a)) == ((int ) (_a_high))) + if ((BufferedWrite (f, _a_high+1, a)) == ((int ) (_a_high+1))) {} /* empty. */ } diff --git a/gcc/m2/mc-boot/GFIO.h b/gcc/m2/mc-boot/GFIO.h index a4a9e40..04dd844 100644 --- a/gcc/m2/mc-boot/GFIO.h +++ b/gcc/m2/mc-boot/GFIO.h @@ -135,7 +135,7 @@ EXTERN void FIO_FlushBuffer (FIO_File f); EXTERN unsigned int FIO_ReadNBytes (FIO_File f, unsigned int nBytes, void * dest); /* - 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. */ @@ -153,7 +153,7 @@ EXTERN void FIO_ReadAny (FIO_File f, unsigned char *a, unsigned int _a_high); EXTERN unsigned int FIO_WriteNBytes (FIO_File f, unsigned int nBytes, void * src); /* - 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/mc-boot/GIO.cc b/gcc/m2/mc-boot/GIO.cc index feaf27d..e1c55de 100644 --- a/gcc/m2/mc-boot/GIO.cc +++ b/gcc/m2/mc-boot/GIO.cc @@ -286,12 +286,13 @@ static void dononraw (termios_TERMIOS term) static void Init (void) { - fdState.array[0].IsEof = false; - fdState.array[0].IsRaw = false; - fdState.array[1].IsEof = false; - fdState.array[1].IsRaw = false; - fdState.array[2].IsEof = false; - fdState.array[2].IsRaw = false; + unsigned int fdi; + + for (fdi=0; fdi<=MaxDefaultFd; fdi++) + { + fdState.array[fdi].IsEof = false; + fdState.array[fdi].IsRaw = false; + } } diff --git a/gcc/m2/mc-boot/GRTint.cc b/gcc/m2/mc-boot/GRTint.cc index e8f4bc4..d67ae94 100644 --- a/gcc/m2/mc-boot/GRTint.cc +++ b/gcc/m2/mc-boot/GRTint.cc @@ -352,6 +352,10 @@ static RTint_Vector FindPendingVector (unsigned int vec) static void AddFd (Selective_SetOfFd *set, int *max, int fd) { + if (fd < 0) + { + return ; + } (*max) = Max (fd, (*max)); if ((*set) == NULL) { @@ -928,6 +932,7 @@ extern "C" void RTint_Listen (bool untilInterrupt, RTint_DispatchVector call, un { bool found; int result; + Selective_Timeval zero; Selective_Timeval after; Selective_Timeval b4; Selective_Timeval timeval; @@ -995,13 +1000,13 @@ extern "C" void RTint_Listen (bool untilInterrupt, RTint_DispatchVector call, un { Selective_SetTime (timeval, 0, 0); } - if (((untilInterrupt && (inSet == NULL)) && (outSet == NULL)) && ! found) + if ((untilInterrupt && (((inSet == NULL) && (outSet == NULL)) || (maxFd == -1))) && ! found) { - M2RTS_Halt ((const char *) "deadlock found, no more processes to run and no interrupts active", 65, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/RTint.mod", 46, (const char *) "Listen", 6, 728); + M2RTS_Halt ((const char *) "deadlock found, no more processes to run and no interrupts active", 65, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/RTint.mod", 46, (const char *) "Listen", 6, 733); } /* printf('} ') ; */ - if (((! found && (maxFd == -1)) && (inSet == NULL)) && (outSet == NULL)) + if (! found && (maxFd == -1)) { /* no file descriptors to be selected upon. */ timeval = Selective_KillTime (timeval); @@ -1012,6 +1017,7 @@ extern "C" void RTint_Listen (bool untilInterrupt, RTint_DispatchVector call, un { Selective_GetTime (timeval, &sec, µ); Assertion_Assert (micro < Microseconds); + zero = Selective_InitTime (0, 0); b4 = Selective_InitTime (0, 0); after = Selective_InitTime (0, 0); result = Selective_GetTimeOfDay (b4); @@ -1028,28 +1034,65 @@ extern "C" void RTint_Listen (bool untilInterrupt, RTint_DispatchVector call, un { libc_printf ((const char *) "select (.., .., .., %u.%06u)\\n", 30, sec, micro); } - result = RTco_select (maxFd+1, inSet, outSet, NULL, timeval); + if (maxFd < 0) + { + result = RTco_select (0, NULL, NULL, NULL, timeval); + } + else + { + result = RTco_select (maxFd+1, inSet, outSet, NULL, timeval); + } if (result == -1) { - libc_perror ((const char *) "select", 6); - result = RTco_select (maxFd+1, inSet, outSet, NULL, NULL); - if (result == -1) + if (Debugging) { - libc_perror ((const char *) "select timeout argument is faulty", 33); + libc_perror ((const char *) "select failed : ", 16); } - result = RTco_select (maxFd+1, inSet, NULL, NULL, timeval); - if (result == -1) + result = RTco_select (maxFd+1, inSet, outSet, NULL, zero); + if (result != -1) { - libc_perror ((const char *) "select output fd argument is faulty", 35); - } - result = RTco_select (maxFd+1, NULL, outSet, NULL, timeval); - if (result == -1) - { - libc_perror ((const char *) "select input fd argument is faulty", 34); + Selective_GetTime (timeval, &sec, µ); + if (Debugging) + { + libc_printf ((const char *) "(nfds : %d timeval: %u.%06u) : \\n", 33, maxFd, sec, micro); + } + libc_perror ((const char *) "select timeout argument was faulty : ", 37); } else { - libc_perror ((const char *) "select maxFD+1 argument is faulty", 33); + result = RTco_select (maxFd+1, inSet, NULL, NULL, timeval); + if (result != -1) + { + libc_perror ((const char *) "select output fd argument was faulty : ", 39); + } + else + { + result = RTco_select (maxFd+1, NULL, outSet, NULL, timeval); + if (result != -1) + { + libc_perror ((const char *) "select input fd argument was faulty : ", 38); + } + else + { + if (maxFd == -1) + { + /* avoid dangling else. */ + result = RTco_select (0, NULL, NULL, NULL, timeval); + if (result == -1) + { + if (Debugging) + { + libc_perror ((const char *) "select does not accept nfds == 0 ", 33); + } + result = 0; + } + } + else + { + libc_perror ((const char *) "select maxFD+1 argument was faulty : ", 37); + } + } + } } } } while (! (result != -1)); @@ -1060,6 +1103,10 @@ extern "C" void RTint_Listen (bool untilInterrupt, RTint_DispatchVector call, un { timeval = Selective_KillTime (timeval); } + if (zero != NULL) + { + zero = Selective_KillTime (zero); + } if (after != NULL) { after = Selective_KillTime (after); diff --git a/gcc/m2/mc-boot/Gdecl.cc b/gcc/m2/mc-boot/Gdecl.cc index 72acd82..793d91e 100644 --- a/gcc/m2/mc-boot/Gdecl.cc +++ b/gcc/m2/mc-boot/Gdecl.cc @@ -2517,6 +2517,12 @@ extern "C" DynamicStrings_String DynamicStrings_ConCatChar (DynamicStrings_Strin extern "C" DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, DynamicStrings_String b); /* + ReplaceChar - returns string s after it has changed all occurances of from to to. +*/ + +extern "C" DynamicStrings_String DynamicStrings_ReplaceChar (DynamicStrings_String s, char from, char to); + +/* Dup - duplicate a String, s, returning the copy of s. */ @@ -2750,6 +2756,9 @@ extern "C" void mcOptions_writeGPLheader (FIO_File f); extern "C" void mcOptions_setSuppressNoReturn (bool value); extern "C" bool mcOptions_getSuppressNoReturn (void); extern "C" bool mcOptions_useBool (void); +extern "C" DynamicStrings_String mcOptions_getCRealType (void); +extern "C" DynamicStrings_String mcOptions_getCLongRealType (void); +extern "C" DynamicStrings_String mcOptions_getCShortRealType (void); extern "C" DynamicStrings_String FormatStrings_Sprintf0 (DynamicStrings_String fmt); extern "C" DynamicStrings_String FormatStrings_Sprintf1 (DynamicStrings_String fmt, const unsigned char *w_, unsigned int _w_high); extern "C" DynamicStrings_String FormatStrings_Sprintf2 (DynamicStrings_String fmt, const unsigned char *w1_, unsigned int _w1_high, const unsigned char *w2_, unsigned int _w2_high); @@ -5346,6 +5355,12 @@ static void doSizeC (mcPretty_pretty p, decl_node n); static void doConvertC (mcPretty_pretty p, decl_node n, const char *conversion_, unsigned int _conversion_high); /* + doConvertSC - +*/ + +static void doConvertSC (mcPretty_pretty p, decl_node n, DynamicStrings_String conversion); + +/* getFuncFromExpr - */ @@ -10544,19 +10559,19 @@ static void doExprC (mcPretty_pretty p, decl_node n) break; case decl_float: - doConvertC (p, n, (const char *) "(double)", 8); + doConvertSC (p, n, mcOptions_getCRealType ()); break; case decl_trunc: - doConvertC (p, n, (const char *) "(int)", 5); + doConvertC (p, n, (const char *) "int", 3); break; case decl_ord: - doConvertC (p, n, (const char *) "(unsigned int)", 14); + doConvertC (p, n, (const char *) "unsigned int", 12); break; case decl_chr: - doConvertC (p, n, (const char *) "(char)", 6); + doConvertC (p, n, (const char *) "char", 4); break; case decl_cap: @@ -12615,15 +12630,15 @@ static void doBaseC (mcPretty_pretty p, decl_node n) break; case decl_real: - outText (p, (const char *) "double", 6); + outTextS (p, mcOptions_getCRealType ()); break; case decl_longreal: - outText (p, (const char *) "long double", 11); + outTextS (p, mcOptions_getCLongRealType ()); break; case decl_shortreal: - outText (p, (const char *) "float", 5); + outTextS (p, mcOptions_getCShortRealType ()); break; case decl_bitset: @@ -16311,15 +16326,29 @@ static void doSizeC (mcPretty_pretty p, decl_node n) static void doConvertC (mcPretty_pretty p, decl_node n, const char *conversion_, unsigned int _conversion_high) { + DynamicStrings_String s; char conversion[_conversion_high+1]; /* make a local copy of each unbounded array. */ memcpy (conversion, conversion_, _conversion_high+1); + s = DynamicStrings_InitString ((const char *) conversion, _conversion_high); + doConvertSC (p, n, s); + s = DynamicStrings_KillString (s); +} + + +/* + doConvertSC - +*/ + +static void doConvertSC (mcPretty_pretty p, decl_node n, DynamicStrings_String conversion) +{ mcDebug_assert (isUnary (n)); mcPretty_setNeedSpace (p); - outText (p, (const char *) "(", 1); - outText (p, (const char *) conversion, _conversion_high); + outText (p, (const char *) "((", 2); + outTextS (p, conversion); + outText (p, (const char *) ")", 1); mcPretty_setNeedSpace (p); outText (p, (const char *) "(", 1); doExprC (p, n->unaryF.arg); diff --git a/gcc/m2/mc-boot/GmcOptions.cc b/gcc/m2/mc-boot/GmcOptions.cc index 9b2dc424..23d2a39 100644 --- a/gcc/m2/mc-boot/GmcOptions.cc +++ b/gcc/m2/mc-boot/GmcOptions.cc @@ -72,6 +72,9 @@ static bool extendedOpaque; static bool internalDebugging; static bool verbose; static bool quiet; +static DynamicStrings_String CReal; +static DynamicStrings_String CLongReal; +static DynamicStrings_String CShortReal; static DynamicStrings_String projectContents; static DynamicStrings_String summaryContents; static DynamicStrings_String contributedContents; @@ -192,6 +195,27 @@ extern "C" bool mcOptions_getSuppressNoReturn (void); extern "C" bool mcOptions_useBool (void); /* + getCRealType - returns the string representing the REAL type + used by C. By default this is "double". +*/ + +extern "C" DynamicStrings_String mcOptions_getCRealType (void); + +/* + getCLongRealType - returns the string representing the REAL type + used by C. By default this is "long double". +*/ + +extern "C" DynamicStrings_String mcOptions_getCLongRealType (void); + +/* + getCShortRealType - returns the string representing the REAL type + used by C. By default this is "float". +*/ + +extern "C" DynamicStrings_String mcOptions_getCShortRealType (void); + +/* getYear - return the year. */ @@ -300,6 +324,34 @@ static void setHPrefix (DynamicStrings_String s); static void setIgnoreFQ (bool value); /* + toCType - returns a new string which has all occurences of '-' + replaced by ' '. +*/ + +static DynamicStrings_String toCType (DynamicStrings_String namedType); + +/* + setCReal - assigns CReal to namedType after it has been transformed by + toCType. +*/ + +static void setCReal (DynamicStrings_String namedType); + +/* + setCShortReal - assigns CShortReal to namedType after it has been + transformed by toCType. +*/ + +static void setCShortReal (DynamicStrings_String namedType); + +/* + setCLongReal - assigns CLongReal to namedType after it has been + transformed by toCType. +*/ + +static void setCLongReal (DynamicStrings_String namedType); + +/* optionIs - returns TRUE if the first len (right) characters match left. */ @@ -675,6 +727,52 @@ static void setIgnoreFQ (bool value) /* + toCType - returns a new string which has all occurences of '-' + replaced by ' '. +*/ + +static DynamicStrings_String toCType (DynamicStrings_String namedType) +{ + return DynamicStrings_ReplaceChar (DynamicStrings_Dup (namedType), '-', ' '); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + setCReal - assigns CReal to namedType after it has been transformed by + toCType. +*/ + +static void setCReal (DynamicStrings_String namedType) +{ + CReal = toCType (namedType); +} + + +/* + setCShortReal - assigns CShortReal to namedType after it has been + transformed by toCType. +*/ + +static void setCShortReal (DynamicStrings_String namedType) +{ + CShortReal = toCType (namedType); +} + + +/* + setCLongReal - assigns CLongReal to namedType after it has been + transformed by toCType. +*/ + +static void setCLongReal (DynamicStrings_String namedType) +{ + CLongReal = toCType (namedType); +} + + +/* optionIs - returns TRUE if the first len (right) characters match left. */ @@ -851,6 +949,21 @@ static void handleOption (DynamicStrings_String arg) /* avoid dangling else. */ suppressNoReturn = true; } + else if (optionIs ((const char *) "--real=", 7, arg)) + { + /* avoid dangling else. */ + setCReal (DynamicStrings_Slice (arg, 7, 0)); + } + else if (optionIs ((const char *) "--longreal=", 11, arg)) + { + /* avoid dangling else. */ + setCLongReal (DynamicStrings_Slice (arg, 11, 0)); + } + else if (optionIs ((const char *) "--shortreal=", 12, arg)) + { + /* avoid dangling else. */ + setCShortReal (DynamicStrings_Slice (arg, 12, 0)); + } } @@ -1106,6 +1219,45 @@ extern "C" bool mcOptions_useBool (void) __builtin_unreachable (); } + +/* + getCRealType - returns the string representing the REAL type + used by C. By default this is "double". +*/ + +extern "C" DynamicStrings_String mcOptions_getCRealType (void) +{ + return CReal; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + getCLongRealType - returns the string representing the REAL type + used by C. By default this is "long double". +*/ + +extern "C" DynamicStrings_String mcOptions_getCLongRealType (void) +{ + return CLongReal; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + getCShortRealType - returns the string representing the REAL type + used by C. By default this is "float". +*/ + +extern "C" DynamicStrings_String mcOptions_getCShortRealType (void) +{ + return CShortReal; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + extern "C" void _M2_mcOptions_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { langC = true; @@ -1136,6 +1288,9 @@ extern "C" void _M2_mcOptions_init (__attribute__((unused)) int argc,__attribute summaryContents = DynamicStrings_InitString ((const char *) "", 0); contributedContents = DynamicStrings_InitString ((const char *) "", 0); projectContents = DynamicStrings_InitString ((const char *) "GNU Modula-2", 12); + CReal = DynamicStrings_InitString ((const char *) "double", 6); + CLongReal = DynamicStrings_InitString ((const char *) "long double", 11); + CShortReal = DynamicStrings_InitString ((const char *) "float", 5); } extern "C" void _M2_mcOptions_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) diff --git a/gcc/m2/mc-boot/GmcOptions.h b/gcc/m2/mc-boot/GmcOptions.h index ba22857..077c588 100644 --- a/gcc/m2/mc-boot/GmcOptions.h +++ b/gcc/m2/mc-boot/GmcOptions.h @@ -151,6 +151,27 @@ EXTERN bool mcOptions_getSuppressNoReturn (void); */ EXTERN bool mcOptions_useBool (void); + +/* + getCRealType - returns the string representing the REAL type + used by C. By default this is "double". +*/ + +EXTERN DynamicStrings_String mcOptions_getCRealType (void); + +/* + getCLongRealType - returns the string representing the REAL type + used by C. By default this is "long double". +*/ + +EXTERN DynamicStrings_String mcOptions_getCLongRealType (void); + +/* + getCShortRealType - returns the string representing the REAL type + used by C. By default this is "float". +*/ + +EXTERN DynamicStrings_String mcOptions_getCShortRealType (void); # ifdef __cplusplus } # endif diff --git a/gcc/m2/mc/decl.mod b/gcc/m2/mc/decl.mod index 856c717..54a6921 100644 --- a/gcc/m2/mc/decl.mod +++ b/gcc/m2/mc/decl.mod @@ -34,7 +34,8 @@ FROM StringConvert IMPORT CardinalToString, ostoc ; FROM mcOptions IMPORT getOutputFile, getDebugTopological, getHPrefix, getIgnoreFQ, getExtendedOpaque, writeGPLheader, getGccConfigSystem, getScaffoldDynamic, getScaffoldMain, getSuppressNoReturn, - useBool ; + useBool, getCRealType, getCShortRealType, + getCLongRealType ; FROM FormatStrings IMPORT Sprintf0, Sprintf1, Sprintf2, Sprintf3 ; FROM libc IMPORT printf, memset ; @@ -6355,10 +6356,10 @@ BEGIN adr : doAdrC (p, n) | size, tsize : doSizeC (p, n) | - float : doConvertC (p, n, "(double)") | - trunc : doConvertC (p, n, "(int)") | - ord : doConvertC (p, n, "(unsigned int)") | - chr : doConvertC (p, n, "(char)") | + float : doConvertSC (p, n, getCRealType ()) | + trunc : doConvertC (p, n, "int") | + ord : doConvertC (p, n, "unsigned int") | + chr : doConvertC (p, n, "char") | cap : doCapC (p, n) | abs : doAbsC (p, n) | high : doFuncHighC (p, n^.unaryF.arg) | @@ -7878,9 +7879,9 @@ BEGIN complex : outText (p, 'double complex') | longcomplex : outText (p, 'long double complex') | shortcomplex: outText (p, 'float complex') | - real : outText (p, 'double') | - longreal : outText (p, 'long double') | - shortreal : outText (p, 'float') | + real : outTextS (p, getCRealType ()) | + longreal : outTextS (p, getCLongRealType ()) | + shortreal : outTextS (p, getCShortRealType ()) | bitset : outText (p, 'unsigned int') | boolean : doBoolC (p) | proc : outText (p, 'PROC') @@ -11026,16 +11027,31 @@ END doSizeC ; *) PROCEDURE doConvertC (p: pretty; n: node; conversion: ARRAY OF CHAR) ; +VAR + s: String ; +BEGIN + s := InitString (conversion) ; + doConvertSC (p, n, s) ; + s := KillString (s) +END doConvertC ; + + +(* + doConvertSC - +*) + +PROCEDURE doConvertSC (p: pretty; n: node; conversion: String) ; BEGIN assert (isUnary (n)) ; setNeedSpace (p) ; - outText (p, "(") ; - outText (p, conversion) ; + outText (p, "((") ; + outTextS (p, conversion) ; + outText (p, ")") ; setNeedSpace (p) ; outText (p, "(") ; doExprC (p, n^.unaryF.arg) ; outText (p, "))") -END doConvertC ; +END doConvertSC ; (* not needed? diff --git a/gcc/m2/mc/mcOptions.def b/gcc/m2/mc/mcOptions.def index a814f83..2b2888a 100644 --- a/gcc/m2/mc/mcOptions.def +++ b/gcc/m2/mc/mcOptions.def @@ -155,4 +155,28 @@ PROCEDURE getSuppressNoReturn () : BOOLEAN ; PROCEDURE useBool () : BOOLEAN ; +(* + getCRealType - returns the string representing the REAL type + used by C. By default this is "double". +*) + +PROCEDURE getCRealType () : String ; + + +(* + getCLongRealType - returns the string representing the REAL type + used by C. By default this is "long double". +*) + +PROCEDURE getCLongRealType () : String ; + + +(* + getCShortRealType - returns the string representing the REAL type + used by C. By default this is "float". +*) + +PROCEDURE getCShortRealType () : String ; + + END mcOptions. diff --git a/gcc/m2/mc/mcOptions.mod b/gcc/m2/mc/mcOptions.mod index 9c439ed..1582dfe 100644 --- a/gcc/m2/mc/mcOptions.mod +++ b/gcc/m2/mc/mcOptions.mod @@ -28,7 +28,7 @@ FROM decl IMPORT setLangC, setLangCP, setLangM2 ; FROM DynamicStrings IMPORT String, Length, InitString, Mark, Slice, EqualArray, InitStringCharStar, ConCatChar, ConCat, KillString, - Dup, string, char ; + Dup, string, char, ReplaceChar ; IMPORT FIO ; IMPORT SFIO ; @@ -55,6 +55,9 @@ VAR internalDebugging, verbose, quiet : BOOLEAN ; + CReal, + CLongReal, + CShortReal, projectContents, summaryContents, contributedContents, @@ -594,6 +597,83 @@ END useBool ; (* + getCRealType - returns the string representing the REAL type + used by C. By default this is "double". +*) + +PROCEDURE getCRealType () : String ; +BEGIN + RETURN CReal +END getCRealType ; + + +(* + getCLongRealType - returns the string representing the REAL type + used by C. By default this is "long double". +*) + +PROCEDURE getCLongRealType () : String ; +BEGIN + RETURN CLongReal +END getCLongRealType ; + + +(* + getCShortRealType - returns the string representing the REAL type + used by C. By default this is "float". +*) + +PROCEDURE getCShortRealType () : String ; +BEGIN + RETURN CShortReal +END getCShortRealType ; + + +(* + toCType - returns a new string which has all occurences of '-' + replaced by ' '. +*) + +PROCEDURE toCType (namedType: String) : String ; +BEGIN + RETURN ReplaceChar (Dup (namedType), '-', ' ') +END toCType ; + + +(* + setCReal - assigns CReal to namedType after it has been transformed by + toCType. +*) + +PROCEDURE setCReal (namedType: String) ; +BEGIN + CReal := toCType (namedType) +END setCReal ; + + +(* + setCShortReal - assigns CShortReal to namedType after it has been + transformed by toCType. +*) + +PROCEDURE setCShortReal (namedType: String) ; +BEGIN + CShortReal := toCType (namedType) +END setCShortReal ; + + +(* + setCLongReal - assigns CLongReal to namedType after it has been + transformed by toCType. +*) + +PROCEDURE setCLongReal (namedType: String) ; +BEGIN + CLongReal := toCType (namedType) +END setCLongReal ; + + +(* optionIs - returns TRUE if the first len (right) characters match left. *) @@ -711,6 +791,15 @@ BEGIN ELSIF optionIs ('--suppress-noreturn', arg) THEN suppressNoReturn := TRUE + ELSIF optionIs ("--real=", arg) + THEN + setCReal (Slice (arg, 7, 0)) + ELSIF optionIs ("--longreal=", arg) + THEN + setCLongReal (Slice (arg, 11, 0)) + ELSIF optionIs ("--shortreal=", arg) + THEN + setCShortReal (Slice (arg, 12, 0)) END END handleOption ; @@ -777,5 +866,8 @@ BEGIN outputFile := InitString ('-') ; summaryContents := InitString ('') ; contributedContents := InitString ('') ; - projectContents := InitString ('GNU Modula-2') + projectContents := InitString ('GNU Modula-2') ; + CReal := InitString ('double') ; + CLongReal := InitString ('long double') ; + CShortReal := InitString ('float') END mcOptions. diff --git a/gcc/match.pd b/gcc/match.pd index a05d4f0..0aa815f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -926,36 +926,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (TYPE_OVERFLOW_UNDEFINED (type)) @0 #if GIMPLE - (with - { - bool overflowed = true; - value_range vr0, vr1; - if (INTEGRAL_TYPE_P (type) - && get_range_query (cfun)->range_of_expr (vr0, @0) - && get_range_query (cfun)->range_of_expr (vr1, @1) - && !vr0.varying_p () && !vr0.undefined_p () - && !vr1.varying_p () && !vr1.undefined_p ()) - { - wide_int wmin0 = vr0.lower_bound (); - wide_int wmax0 = vr0.upper_bound (); - wide_int wmin1 = vr1.lower_bound (); - wide_int wmax1 = vr1.upper_bound (); - /* If the multiplication can't overflow/wrap around, then - it can be optimized too. */ - wi::overflow_type min_ovf, max_ovf; - wi::mul (wmin0, wmin1, TYPE_SIGN (type), &min_ovf); - wi::mul (wmax0, wmax1, TYPE_SIGN (type), &max_ovf); - if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE) - { - wi::mul (wmin0, wmax1, TYPE_SIGN (type), &min_ovf); - wi::mul (wmax0, wmin1, TYPE_SIGN (type), &max_ovf); - if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE) - overflowed = false; - } - } - } - (if (!overflowed) - @0)) + (with {value_range vr0, vr1;} + (if (INTEGRAL_TYPE_P (type) + && get_range_query (cfun)->range_of_expr (vr0, @0) + && get_range_query (cfun)->range_of_expr (vr1, @1) + && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1)) + @0)) #endif )))) @@ -1033,7 +1009,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) || (vr0.nonnegative_p () && vr3.nonnegative_p ()) || (vr0.nonpositive_p () && vr3.nonpositive_p ()))) (plus (op @0 @2) { wide_int_to_tree (type, plus_op1 (c)); }) - (if (TYPE_UNSIGNED (type) && c.sign_mask () < 0 + (if (!vr0.undefined_p () && TYPE_UNSIGNED (type) && c.sign_mask () < 0 && exact_mod (-c) /* unsigned "X-(-C)" doesn't underflow. */ && wi::geu_p (vr0.lower_bound (), -c)) @@ -2183,13 +2159,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (a&1) is always [0,1] too. This is useful again when the range is not known. */ +/* Note this can't be recursive due to VN handling of equivalents, + VN and would cause an infinite recursion. */ (match zero_one_valued_p - (bit_and:c@0 @1 zero_one_valued_p)) + (bit_and:c@0 @1 integer_onep) + (if (INTEGRAL_TYPE_P (type)))) /* A conversion from an zero_one_valued_p is still a [0,1]. This is useful when the range of a variable is not known */ +/* Note this matches can't be recursive because of the way VN handles + nop conversions being equivalent and then recursive between them. */ (match zero_one_valued_p - (convert@0 zero_one_valued_p)) + (convert@0 @1) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && (TYPE_UNSIGNED (TREE_TYPE (@1)) + || TYPE_PRECISION (TREE_TYPE (@1)) > 1) + && wi::leu_p (tree_nonzero_bits (@1), 1)))) /* Transform { 0 or 1 } * { 0 or 1 } into { 0 or 1 } & { 0 or 1 }. */ (simplify @@ -4114,9 +4099,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (INTEGRAL_TYPE_P (type)) (with { int width = element_precision (type) - tree_to_uhwi (@1); - tree stype = build_nonstandard_integer_type (width, 0); + tree stype = NULL_TREE; + if (width <= MAX_FIXED_MODE_SIZE) + stype = build_nonstandard_integer_type (width, 0); } - (if (width == 1 || type_has_mode_precision_p (stype)) + (if (stype && (width == 1 || type_has_mode_precision_p (stype))) (convert (convert:stype @0)))))))) /* Optimize x >> x into 0 */ @@ -5092,49 +5079,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* a ? -1 : 0 -> -a. No need to check the TYPE_PRECISION not being 1 here as the powerof2cst case above will handle that case correctly. */ (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1)) + (negate (convert:type (convert:boolean_type_node @0)))))) + (if (integer_zerop (@1)) + (switch + /* a ? 0 : 1 -> !a. */ + (if (integer_onep (@2)) + (convert (bit_xor (convert:boolean_type_node @0) { boolean_true_node; }))) + /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */ + (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@2)) (with { - auto prec = TYPE_PRECISION (type); - auto unsign = TYPE_UNSIGNED (type); - tree inttype = build_nonstandard_integer_type (prec, unsign); + tree shift = build_int_cst (integer_type_node, tree_log2 (@2)); } - (convert (negate (convert:inttype (convert:boolean_type_node @0)))))))) - (if (integer_zerop (@1)) - (with { - tree booltrue = constant_boolean_node (true, boolean_type_node); - } - (switch - /* a ? 0 : 1 -> !a. */ - (if (integer_onep (@2)) - (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))) - /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */ - (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@2)) - (with { - tree shift = build_int_cst (integer_type_node, tree_log2 (@2)); - } - (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )) - { shift; }))) - /* a ? -1 : 0 -> -(!a). No need to check the TYPE_PRECISION not being 1 + (lshift (convert (bit_xor (convert:boolean_type_node @0) + { boolean_true_node; })) { shift; }))) + /* a ? -1 : 0 -> -(!a). No need to check the TYPE_PRECISION not being 1 here as the powerof2cst case above will handle that case correctly. */ - (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2)) - (with { - auto prec = TYPE_PRECISION (type); - auto unsign = TYPE_UNSIGNED (type); - tree inttype = build_nonstandard_integer_type (prec, unsign); - } - (convert - (negate - (convert:inttype - (bit_xor (convert:boolean_type_node @0) { booltrue; } ) - ) - ) - ) - ) - ) - ) - ) - ) - ) -) + (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2)) + (negate (convert:type (bit_xor (convert:boolean_type_node @0) + { boolean_true_node; })))))))) /* (a > 1) ? 0 : (cast)a is the same as (cast)(a == 1) for unsigned types. */ diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index 5d7c32d..b0c3ef7 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc @@ -3951,6 +3951,7 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data) struct walk_stmt_info *wi = (struct walk_stmt_info *) data; omp_context *ctx = (omp_context *) wi->info; tree t = *tp; + tree tmp; switch (TREE_CODE (t)) { @@ -3960,12 +3961,37 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data) case RESULT_DECL: if (ctx) { + tmp = NULL_TREE; + if (TREE_CODE (t) == VAR_DECL + && (tmp = lookup_attribute ("omp allocate var", + DECL_ATTRIBUTES (t))) != NULL_TREE) + t = TREE_VALUE (TREE_VALUE (tmp)); tree repl = remap_decl (t, &ctx->cb); gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK); - *tp = repl; + if (tmp != NULL_TREE && t != repl) + *tp = build_fold_addr_expr (repl); + else if (tmp == NULL_TREE) + *tp = repl; } break; + case INDIRECT_REF: + case MEM_REF: + if (ctx + && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL + && ((tmp = lookup_attribute ("omp allocate var", + DECL_ATTRIBUTES (TREE_OPERAND (t, 0)))) + != NULL_TREE)) + { + tmp = TREE_VALUE (TREE_VALUE (tmp)); + tree repl = remap_decl (tmp, &ctx->cb); + gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK); + if (tmp != repl) + *tp = repl; + break; + } + gcc_fallthrough (); + default: if (ctx && TYPE_P (t)) *tp = remap_type (t, &ctx->cb); diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 32ff379..8b96f23 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -8102,6 +8102,16 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, goto input; } break; + + case EXPAND_UNDEFINED_INPUT: + /* See if the predicate accepts a SCRATCH rtx, which in this context + indicates an undefined value. Use an uninitialized register if not. */ + if (!insn_operand_matches (icode, opno, op->value)) + { + op->value = gen_reg_rtx (op->mode); + goto input; + } + return true; } return insn_operand_matches (icode, opno, op->value); } @@ -8140,7 +8150,8 @@ can_reuse_operands_p (enum insn_code icode, switch (op1->type) { case EXPAND_OUTPUT: - /* Outputs must remain distinct. */ + case EXPAND_UNDEFINED_INPUT: + /* Outputs and undefined intputs must remain distinct. */ return false; case EXPAND_FIXED: diff --git a/gcc/optabs.h b/gcc/optabs.h index c80b7f4..9b78d40 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -37,7 +37,8 @@ enum expand_operand_type { EXPAND_CONVERT_TO, EXPAND_CONVERT_FROM, EXPAND_ADDRESS, - EXPAND_INTEGER + EXPAND_INTEGER, + EXPAND_UNDEFINED_INPUT }; /* Information about an operand for instruction expansion. */ @@ -117,6 +118,16 @@ create_input_operand (class expand_operand *op, rtx value, create_expand_operand (op, EXPAND_INPUT, value, mode, false); } +/* Make OP describe an undefined input operand of mode MODE. MODE cannot + be null. */ + +inline void +create_undefined_input_operand (class expand_operand *op, machine_mode mode) +{ + create_expand_operand (op, EXPAND_UNDEFINED_INPUT, gen_rtx_SCRATCH (mode), + mode, false); +} + /* Like create_input_operand, except that VALUE must first be converted to mode MODE. UNSIGNED_P says whether VALUE is unsigned. */ diff --git a/gcc/params.opt b/gcc/params.opt index 70cfb49..fffa8b1 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -1106,6 +1106,15 @@ Emit instrumentation calls to __tsan_func_entry() and __tsan_func_exit(). Common Joined UInteger Var(param_uninit_control_dep_attempts) Init(1000) IntegerRange(1, 65536) Param Optimization Maximum number of nested calls to search for control dependencies during uninitialized variable analysis. +-param=uninit-max-chain-len= +Common Joined UInteger Var(param_uninit_max_chain_len) Init(8) IntegerRange(1, 128) Param Optimization +Maximum number of predicates anded for each predicate ored in the normalized +predicate chain. + +-param=uninit-max-num-chains= +Common Joined UInteger Var(param_uninit_max_num_chains) Init(8) IntegerRange(1, 128) Param Optimization +Maximum number of predicates ored in the normalized predicate chain. + -param=uninlined-function-insns= Common Joined UInteger Var(param_uninlined_function_insns) Init(2) Optimization IntegerRange(0, 1000000) Param Instruction accounted for function prologue, epilogue and other overhead. diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index cc729e1..0951bd3 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -281,18 +281,6 @@ maybe_isnan (const frange &op1, const frange &op2) // folded. For example, when attempting to fold x_3 == y_5, MY_REL is // VREL_EQ, and if the statement is dominated by x_3 > y_5, then // TRIO.op1_op2() is VREL_GT. -// -// Relations in a floating point world are a bit tricky, as TRIO -// behaves as the corresponding unordered variant if either operand -// could be a NAN. For example, when resolving "if (x_5 == x_5)", the -// relation is VREL_EQ, but it behaves like VREL_UNEQ if NANs are a -// possibility. Similarly, the false edge of "if (x >= y)" has a -// relation of VREL_LT, but behaves as VREL_UNLT unless we can prove -// neither operand can be NAN. -// -// ?? It is unclear whether providing unordered VREL relations would -// simplify things, as we'd have to add more entries to various -// tables, tweak all the op1_op2_relation() entries, etc. static inline bool frelop_early_resolve (irange &r, tree type, @@ -301,14 +289,6 @@ frelop_early_resolve (irange &r, tree type, { relation_kind rel = trio.op1_op2 (); - if (maybe_isnan (op1, op2)) - { - // There's not much we can do for VREL_EQ if NAN is a - // possibility. It is up to the caller to deal with these - // special cases. - if (rel == VREL_EQ) - return empty_range_varying (r, type, op1, op2); - } // If known relation is a complete subset of this relation, always // return true. However, avoid doing this when NAN is a possibility // as we'll incorrectly fold conditions: @@ -319,7 +299,7 @@ frelop_early_resolve (irange &r, tree type, // ;; With NANs the relation here is basically VREL_UNLT, so we // ;; can't fold the following: // if (x_3 < y_5) - else if (relation_union (rel, my_rel) == my_rel) + if (!maybe_isnan (op1, op2) && relation_union (rel, my_rel) == my_rel) { r = range_true (type); return true; @@ -801,7 +781,13 @@ operator_not_equal::fold_range (irange &r, tree type, r = range_true (type); return true; } - if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE)) + if (rel == VREL_EQ && maybe_isnan (op1, op2)) + { + // Avoid frelop_early_resolve() below as it could fold to FALSE + // without regards to NANs. This would be incorrect if trying + // to fold x_5 != x_5 without prior knowledge of NANs. + } + else if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE)) return true; // x != NAN is always TRUE. @@ -900,6 +886,14 @@ operator_not_equal::op1_range (frange &r, tree type, return true; } +bool +operator_not_equal::op2_range (frange &r, tree type, + const irange &lhs, + const frange &op1, + relation_trio trio) const +{ + return op1_range (r, type, lhs, op1, trio); +} // Check if the LHS range indicates a relation between OP1 and OP2. @@ -925,14 +919,6 @@ operator_lt::fold_range (irange &r, tree type, const frange &op1, const frange &op2, relation_trio trio) const { - relation_kind rel = trio.op1_op2 (); - - // VREL_EQ & LT_EXPR is impossible, even with NANs. - if (rel == VREL_EQ) - { - r = range_false (type); - return true; - } if (frelop_early_resolve (r, type, op1, op2, trio, VREL_LT)) return true; @@ -973,7 +959,7 @@ operator_lt::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x < NAN, we know nothing about x. - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else build_ge (r, type, op2); @@ -1010,7 +996,7 @@ operator_lt::op2_range (frange &r, case BRS_FALSE: // On the FALSE side of NAN < x, we know nothing about x. - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else build_le (r, type, op1); @@ -1083,7 +1069,7 @@ operator_le::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x <= NAN, we know nothing about x. - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else build_gt (r, type, op2); @@ -1116,7 +1102,7 @@ operator_le::op2_range (frange &r, case BRS_FALSE: // On the FALSE side of NAN <= x, we know nothing about x. - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1154,14 +1140,6 @@ operator_gt::fold_range (irange &r, tree type, const frange &op1, const frange &op2, relation_trio trio) const { - relation_kind rel = trio.op1_op2 (); - - // VREL_EQ & GT_EXPR is impossible, even with NANs. - if (rel == VREL_EQ) - { - r = range_false (type); - return true; - } if (frelop_early_resolve (r, type, op1, op2, trio, VREL_GT)) return true; @@ -1202,7 +1180,7 @@ operator_gt::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x > NAN, we know nothing about x. - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1241,7 +1219,7 @@ operator_gt::op2_range (frange &r, case BRS_FALSE: // On The FALSE side of NAN > x, we know nothing about x. - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1315,7 +1293,7 @@ operator_ge::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x >= NAN, we know nothing about x. - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1349,7 +1327,7 @@ operator_ge::op2_range (frange &r, tree type, case BRS_FALSE: // On the FALSE side of NAN >= x, we know nothing about x. - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1666,10 +1644,7 @@ public: const frange &op1, const frange &op2, relation_trio trio = TRIO_VARYING) const final override { - relation_kind rel = trio.op1_op2 (); - - if (op1.known_isnan () || op2.known_isnan () - || rel == VREL_LT) + if (op1.known_isnan () || op2.known_isnan ()) { r = range_true (type); return true; @@ -1712,7 +1687,7 @@ foperator_unordered_lt::op1_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1746,7 +1721,7 @@ foperator_unordered_lt::op2_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1781,10 +1756,7 @@ public: const frange &op1, const frange &op2, relation_trio trio = TRIO_VARYING) const final override { - relation_kind rel = trio.op1_op2 (); - - if (op1.known_isnan () || op2.known_isnan () - || rel == VREL_LE) + if (op1.known_isnan () || op2.known_isnan ()) { r = range_true (type); return true; @@ -1824,7 +1796,7 @@ foperator_unordered_le::op1_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1857,7 +1829,7 @@ foperator_unordered_le::op2_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1892,10 +1864,7 @@ public: const frange &op1, const frange &op2, relation_trio trio = TRIO_VARYING) const final override { - relation_kind rel = trio.op1_op2 (); - - if (op1.known_isnan () || op2.known_isnan () - || rel == VREL_GT) + if (op1.known_isnan () || op2.known_isnan ()) { r = range_true (type); return true; @@ -1937,7 +1906,7 @@ foperator_unordered_gt::op1_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1972,7 +1941,7 @@ foperator_unordered_gt::op2_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -2007,10 +1976,7 @@ public: const frange &op1, const frange &op2, relation_trio trio = TRIO_VARYING) const final override { - relation_kind rel = trio.op1_op2 (); - - if (op1.known_isnan () || op2.known_isnan () - || rel == VREL_GE) + if (op1.known_isnan () || op2.known_isnan ()) { r = range_true (type); return true; @@ -2052,7 +2018,7 @@ foperator_unordered_ge::op1_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan () || op2.maybe_isnan ()) + if (op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -2086,7 +2052,7 @@ foperator_unordered_ge::op2_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan () || op1.maybe_isnan ()) + if (op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -2121,10 +2087,7 @@ public: const frange &op1, const frange &op2, relation_trio trio = TRIO_VARYING) const final override { - relation_kind rel = trio.op1_op2 (); - - if (op1.known_isnan () || op2.known_isnan () - || rel == VREL_EQ) + if (op1.known_isnan () || op2.known_isnan ()) { r = range_true (type); return true; diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index ef56232..f7ff47b 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -164,6 +164,9 @@ public: bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, relation_trio = TRIO_VARYING) const final override; + bool op2_range (frange &r, tree type, + const irange &lhs, const frange &op1, + relation_trio = TRIO_VARYING) const final override; relation_kind op1_op2_relation (const irange &lhs, const irange &, const irange &) const final override; diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index eb1ac12..170406a 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -4093,7 +4093,7 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, } } } - else if (SCALAR_INT_MODE_P (mode)) + else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT) { /* 0/x is 0 (or x&0 if x has side-effects). */ if (trueop0 == CONST0_RTX (mode) @@ -4111,7 +4111,7 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, return tem; } /* x/-1 is -x. */ - if (trueop1 == constm1_rtx) + if (trueop1 == CONSTM1_RTX (mode)) { rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0); if (x) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9bf6b29..cc53d4c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,575 @@ +2023-09-20 Lewis Hyatt <lhyatt@gmail.com> + + PR preprocessor/90400 + * c-c++-common/cpp/pr90400.c: New test. + +2023-09-20 Lewis Hyatt <lhyatt@gmail.com> + + PR preprocessor/61474 + * c-c++-common/cpp/pr61474-2.h: New test. + * c-c++-common/cpp/pr61474.c: New test. + * c-c++-common/cpp/pr61474.h: New test. + +2023-09-20 Patrick O'Neill <patrick@rivosinc.com> + + * gcc.target/riscv/rvv/autovec/vls/def.h: Remove unneeded math.h + import. + +2023-09-20 Aldy Hernandez <aldyh@redhat.com> + + * gcc.dg/tree-ssa/vrp-float-relations-5.c: New test. + * gcc.dg/tree-ssa/vrp-float-relations-6.c: New test. + +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + * c-c++-common/builtin-classify-type-1.c: New test. + * g++.dg/ext/builtin-classify-type-1.C: New test. + * g++.dg/ext/builtin-classify-type-2.C: New test. + * gcc.dg/builtin-classify-type-1.c: New test. + +2023-09-20 Patrick Palka <ppalka@redhat.com> + + PR c++/111471 + * g++.dg/concepts/diagnostic19.C: New test. + +2023-09-20 Tobias Burnus <tobias@codesourcery.com> + + * c-c++-common/gomp/allocate-11.c: Remove C-only dg-message + for 'sorry, unimplemented'. + * c-c++-common/gomp/allocate-12.c: Likewise. + * c-c++-common/gomp/allocate-15.c: Likewise. + * c-c++-common/gomp/allocate-9.c: Likewise. + * c-c++-common/gomp/allocate-10.c: New test. + * c-c++-common/gomp/allocate-17.c: New test. + +2023-09-20 Yanzhang Wang <yanzhang.wang@intel.com> + + * gcc.target/riscv/rvv/base/simplify-vdiv.c: New test. + +2023-09-20 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/widen/widen-10.c: Adapt test. + * gcc.target/riscv/rvv/autovec/widen/widen-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-12.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/ext-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/ext-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/trunc-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/trunc-5.c: New test. + +2023-09-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111489 + * gcc.dg/uninit-pr111489.c: New testcase. + +2023-09-20 Jakub Jelinek <jakub@redhat.com> + + PR c++/111392 + * g++.dg/gomp/attrs-19.C: New test. + * g++.dg/gomp/attrs-20.C: New test. + * g++.dg/gomp/attrs-21.C: New test. + +2023-09-20 Omar Sandoval <osandov@osandov.com> + + PR debug/111409 + * gcc.dg/pr111409.c: New test. + +2023-09-20 Jiufu Guo <guojiufu@linux.ibm.com> + + * gcc.dg/tree-ssa/pr111303.c: Rename to ... + * gcc.dg/tree-ssa/pr111324.c: ... this. + +2023-09-20 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/binop/narrow-1.c: Adapt testcase. + * gcc.target/riscv/rvv/autovec/binop/narrow-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/binop/narrow-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/cmp/vcond-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/cmp/vcond-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/cmp/vcond-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/cmp/vcond-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/partial/slp-18.c: Ditto. + * gcc.target/riscv/rvv/autovec/partial/slp-19.c: Ditto. + * gcc.target/riscv/rvv/autovec/pr110950.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-12.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-10.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-11.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-12.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/def.h: Ditto. + * gcc.target/riscv/rvv/autovec/vls/div-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/shift-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-7.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-8.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-9.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c: Ditto. + * gcc.target/riscv/rvv/autovec/widen/widen-complicate-6.c: Ditto. + * gcc.target/riscv/rvv/autovec/zve32f-1.c: Ditto. + * gcc.target/riscv/rvv/autovec/vls/avg-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/avg-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/avg-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/avg-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/avg-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/avg-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls/ext-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/ext-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/ext-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/trunc-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/trunc-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/trunc-3.c: New test. + +2023-09-20 Surya Kumari Jangala <jskumari@linux.ibm.com> + + PR rtl-optimization/110071 + * gcc.target/powerpc/pr110071.c: New test. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * g++.dg/modules/depreport-2.modmap: New test. + * g++.dg/modules/depreport-2_a.C: New test. + * g++.dg/modules/depreport-2_b.C: New test. + * g++.dg/modules/test-depfile.py: Support `:|` syntax output + when generating modules. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * g++.dg/modules/depreport-1_a.C: New test. + * g++.dg/modules/depreport-1_b.C: New test. + * g++.dg/modules/test-depfile.py: New tool for validating depfile + information. + * lib/modules.exp: Support for validating depfile contents. + +2023-09-19 Ben Boeckel <ben.boeckel@kitware.com> + + * g++.dg/modules/depflags-f-MD.C: New test. + * g++.dg/modules/depflags-f.C: New test. + * g++.dg/modules/depflags-fi.C: New test. + * g++.dg/modules/depflags-fj-MD.C: New test. + * g++.dg/modules/depflags-fj.C: New test. + * g++.dg/modules/depflags-fjo-MD.C: New test. + * g++.dg/modules/depflags-fjo.C: New test. + * g++.dg/modules/depflags-fo-MD.C: New test. + * g++.dg/modules/depflags-fo.C: New test. + * g++.dg/modules/depflags-j-MD.C: New test. + * g++.dg/modules/depflags-j.C: New test. + * g++.dg/modules/depflags-jo-MD.C: New test. + * g++.dg/modules/depflags-jo.C: New test. + * g++.dg/modules/depflags-o-MD.C: New test. + * g++.dg/modules/depflags-o.C: New test. + * g++.dg/modules/p1689-1.C: New test. + * g++.dg/modules/p1689-1.exp.ddi: New test expectation. + * g++.dg/modules/p1689-2.C: New test. + * g++.dg/modules/p1689-2.exp.ddi: New test expectation. + * g++.dg/modules/p1689-3.C: New test. + * g++.dg/modules/p1689-3.exp.ddi: New test expectation. + * g++.dg/modules/p1689-4.C: New test. + * g++.dg/modules/p1689-4.exp.ddi: New test expectation. + * g++.dg/modules/p1689-5.C: New test. + * g++.dg/modules/p1689-5.exp.ddi: New test expectation. + * g++.dg/modules/modules.exp: Load new P1689 library routines. + * g++.dg/modules/test-p1689.py: New tool for validating P1689 output. + * lib/modules.exp: Support for validating P1689 outputs. + * g++.dg/modules/depflags-fj-MF-share.C: New file. + * g++.dg/modules/p1689-file-default.C: New file. + * g++.dg/modules/p1689-file-default.exp.ddi: New file. + * g++.dg/modules/p1689-target-default.C: New file. + * g++.dg/modules/p1689-target-default.exp.ddi: New file. + +2023-09-19 Aldy Hernandez <aldyh@redhat.com> + + * gcc.dg/tree-ssa/vrp-float-12.c: Moved to... + * gcc.dg/tree-ssa/vrp-float-relations-1.c: ...here. + * gcc.dg/tree-ssa/vrp-float-relations-2.c: New test. + * gcc.dg/tree-ssa/vrp-float-relations-3.c: New test. + * gcc.dg/tree-ssa/vrp-float-relations-4.c: New test. + +2023-09-19 Javier Martinez <javier.martinez.bugzilla@gmail.com> + + * g++.dg/ext/attr-hotness.C: New test. + +2023-09-19 Pat Haugen <pthaugen@linux.ibm.com> + + * gcc.target/powerpc/clone1.c: Add xfails. + * gcc.target/powerpc/clone3.c: Likewise. + * gcc.target/powerpc/mod-1.c: Update scan strings and add xfails. + * gcc.target/powerpc/mod-2.c: Likewise. + * gcc.target/powerpc/p10-vdivq-vmodq.c: Add xfails. + +2023-09-19 Gaius Mulley <gaiusmod2@gmail.com> + + * gm2/extensions/pass/libc.def: Add spacing. + * gm2/pimlib/logitech/run/pass/realconv.mod: Add debugging print. + * gm2/switches/uninit-variable-checking/cascade/fail/switches-uninit-variable-checking-cascade-fail.exp: + Add -fdebug-builtins flag. + * lib/gm2.exp (gm2_target_compile_default): Add + -mabi=ieeelongdouble if the target is powerpc. + (gm2_link_flags): Add + -mabi=ieeelongdouble if the target is powerpc. + * gm2/pim/intrinsic/run/pass/cstub.c: New test. + * gm2/pim/intrinsic/run/pass/cstub.def: New test. + * gm2/pim/intrinsic/run/pass/pim-intrinsic-run-pass.exp: New test. + * gm2/pim/intrinsic/run/pass/test.mod: New test. + * gm2/pim/run/pass/builtins.mod: New test. + * gm2/pim/run/pass/convert1.mod: New test. + * gm2/pim/run/pass/longint1.mod: New test. + * gm2/pim/run/pass/longint2.mod: New test. + * gm2/pim/run/pass/longint3.mod: New test. + * gm2/pim/run/pass/longint4.mod: New test. + * gm2/pim/run/pass/longint5.mod: New test. + * gm2/pim/run/pass/longint6.mod: New test. + * gm2/pim/run/pass/longint7.mod: New test. + * gm2/pim/run/pass/longint8.mod: New test. + +2023-09-19 Harald Anlauf <anlauf@gmx.de> + + PR fortran/70231 + * gfortran.dg/bounds_check_fail_7.f90: New test. + +2023-09-19 Aldy Hernandez <aldyh@redhat.com> + + * gcc.dg/tree-ssa/vrp-float-13.c: New test. + +2023-09-19 Jakub Jelinek <jakub@redhat.com> + + PR testsuite/111377 + * c-c++-common/analyzer/compound-assignment-1.c (test_5b): Move + closing } to the same line as the call to work-around differences in + diagnostics line. + +2023-09-19 Jason Merrill <jason@redhat.com> + + DR 2799 + * g++.dg/cpp0x/inh-ctor38.C: New test. + +2023-09-19 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/110080 + PR tree-optimization/110249 + * g++.dg/pr110249.C: New. + * gcc.dg/pr110080.c: New. + * gcc.dg/pr93917.c: Adjust. + +2023-09-19 Marek Polacek <polacek@redhat.com> + + * g++.dg/cpp23/consteval-if2.C: Add xfail. + * g++.dg/cpp2a/consteval-memfn1.C: Adjust. + * g++.dg/cpp2a/consteval11.C: Remove dg-message. + * g++.dg/cpp2a/consteval3.C: Remove dg-message and dg-error. + * g++.dg/cpp2a/consteval9.C: Remove dg-message. + * g++.dg/cpp2a/consteval32.C: New test. + * g++.dg/cpp2a/consteval33.C: New test. + * g++.dg/cpp2a/consteval34.C: New test. + * g++.dg/cpp2a/consteval35.C: New test. + +2023-09-19 Richard Biener <rguenther@suse.de> + + PR c/111468 + * gcc.dg/gimplefe-50.c: Amend. + +2023-09-19 Patrick Palka <ppalka@redhat.com> + + PR c++/111419 + * g++.dg/cpp2a/concepts-requires36.C: New test. + * g++.dg/expr/discarded1.C: New test. + * g++.dg/expr/discarded1a.C: New test. + +2023-09-19 Patrick Palka <ppalka@redhat.com> + + PR c++/99631 + * g++.dg/cpp2a/nontype-class60.C: New test. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/def.h: Add FNMS VLS modes tests. + * gcc.target/riscv/rvv/autovec/vls/fnms-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnms-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnms-3.c: New test. + +2023-09-19 Richard Wai <richard@annexi-strayline.com> + + * gnat.dg/sync_tag_finalize.adb: New test. + +2023-09-19 Richard Wai <richard@annexi-strayline.com> + + * gnat.dg/sync_tag_discriminals.adb: New test. + * gnat.dg/sync_tag_limited.adb: New test. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/def.h: Add unary test. + * gcc.target/riscv/rvv/autovec/vls/neg-2.c: New test. + +2023-09-19 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111465 + * g++.dg/torture/pr111465.C: New testcase. + +2023-09-19 Richard Biener <rguenther@suse.de> + + PR c/111468 + * gcc.dg/gimplefe-50.c: New testcase. + * gcc.dg/gimplefe-51.c: Likewise. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/def.h: Add FMS tests. + * gcc.target/riscv/rvv/autovec/vls/fma-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fma-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fma-7.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fms-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fms-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fms-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnma-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnma-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnma-7.c: New test. + +2023-09-19 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/def.h: Add VLS FMA/FNMA test. + * gcc.target/riscv/rvv/autovec/vls/fma-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fma-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fma-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fma-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnma-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnma-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnma-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/fnma-4.c: New test. + +2023-09-19 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> + + * gcc.target/aarch64/vect_copy_lane_1.c: Scan for zip1 instead + of ins for float32x2_t, int32x2_t and uint32x2_t tests. + +2023-09-18 Pan Li <pan2.li@intel.com> + + * gcc.target/riscv/rvv/autovec/vls/def.h: New macros. + * gcc.target/riscv/rvv/autovec/vls/vec-set-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-10.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-11.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-12.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-13.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-14.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-15.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-16.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-17.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-18.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-19.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-20.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-21.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-22.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-7.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-8.c: New test. + * gcc.target/riscv/rvv/autovec/vls/vec-set-9.c: New test. + +2023-09-18 Pan Li <pan2.li@intel.com> + + * gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c: New test. + +2023-09-18 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111442 + * gcc.c-torture/compile/pr111442-1.c: New test. + +2023-09-18 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111435 + * gcc.c-torture/compile/pr111435-1.c: New test. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + PR c++/89231 + * g++.dg/cpp0x/variadic-partial3.C: New test. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + PR c++/63198 + PR c++/18474 + * g++.dg/cpp0x/static_assert15.C: Expect diagnostic for + non-constant static_assert condition. + * g++.dg/expr/unary2.C: Remove xfails. + * g++.dg/template/init7.C: Make initializer type-dependent to + preserve intent of test. + * g++.dg/template/recurse3.C: Likewise for the erroneous + statement. + * g++.dg/template/non-dependent26.C: New test. + * g++.dg/warn/Wparentheses-32.C: New test. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + PR c++/108347 + * g++.dg/template/ttp41.C: New test. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + * g++.dg/cpp0x/vt-57397-1.C: Expect "candidate expects ... N + argument(s)" at the declaration site instead of the call site. + * g++.dg/cpp0x/vt-57397-2.C: Likewise. + * g++.dg/overload/template5.C: Likewise. + * g++.dg/template/local6.C: Likewise. + * g++.dg/template/conv20.C: New test. + * g++.dg/template/ttp40.C: New test. + +2023-09-18 Patrick Palka <ppalka@redhat.com> + + * g++.dg/template/nontype12.C: Expect two instead of three + duplicate diagnostics for A<double>::bar() specialization. + +2023-09-18 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111431 + * gcc.dg/binop-notand1a.c: Remove xfail. + * gcc.dg/binop-notand4a.c: Likewise. + * gcc.c-torture/execute/pr111431-1.c: New test. + * gcc.dg/binop-andeq1.c: New test. + * gcc.dg/binop-andeq2.c: New test. + * gcc.dg/binop-notand7.c: New test. + * gcc.dg/binop-notand7a.c: New test. + +2023-09-18 Thomas Schwinge <thomas@codesourcery.com> + + * g++.dg/abi/nvptx-nrv1.C: Move... + * g++.target/nvptx/abi-nrv1.C: ... here. + * g++.dg/abi/nvptx-ptrmem1.C: Move... + * g++.target/nvptx/abi-ptrmem1.C: ... here. + +2023-09-18 Thomas Schwinge <thomas@codesourcery.com> + + * g++.target/nvptx/nvptx.exp: New. + +2023-09-18 Thomas Schwinge <thomas@codesourcery.com> + + * g++.dg/abi/nvptx-ptrmem1.C: Fix up. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/pr111313.c: Adapt test. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/vsetvl/avl_single-21.c: Adapt test. + * gcc.target/riscv/rvv/vsetvl/avl_single-26.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/avl_single-39.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/avl_single-41.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/avl_single-6.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_conflict-12.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_conflict-3.c: Ditto. + +2023-09-18 Lehua Ding <lehua.ding@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/div-1.c: Removed comments. + * gcc.target/riscv/rvv/autovec/vls/shift-3.c: Ditto. + +2023-09-18 Wilco Dijkstra <wilco.dijkstra@arm.com> + + PR target/105928 + * gcc.target/aarch64/pr105928.c: Add new test. + * gcc.target/aarch64/vect-cse-codegen.c: Fix test. + +2023-09-18 Lehua Ding <lehua.ding@rivai.ai> + + PR target/111255 + * gcc.target/riscv/rvv/vsetvl/pr111255.c: New test. + +2023-09-18 Richard Biener <rguenther@suse.de> + + PR tree-optimization/111294 + * gcc.dg/tree-ssa/pr111294.c: New test. + * gcc.dg/tree-ssa/phi_on_compare-4.c: Adjust. + * gcc.dg/tree-ssa/pr59597.c: Likewise. + * gcc.dg/tree-ssa/pr61839_2.c: Likewise. + * gcc.dg/tree-ssa/ssa-sink-18.c: Likewise. + * g++.dg/warn/Wstringop-overflow-4.C: XFAIL subtest on ilp32. + * gcc.dg/uninit-pred-9_b.c: XFAIL subtest everywhere. + * gcc.dg/vect/vect-117.c: Make scan for not Invalid sum + conditional on lp64. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/def.h: Add VLS vec_init tests. + * gcc.target/riscv/rvv/autovec/vls/init-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/init-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/init-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/init-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/init-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/init-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls/init-7.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-7.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-8.c: New test. + * gcc.target/riscv/rvv/autovec/vls/repeat-9.c: New test. + +2023-09-18 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/111153 + * gcc.target/riscv/rvv/autovec/vls/def.h: Add VLS mode reduction case. + * gcc.target/riscv/rvv/autovec/vls/reduc-1.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-10.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-11.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-12.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-13.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-14.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-15.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-16.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-17.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-18.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-19.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-2.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-20.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-21.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-3.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-4.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-5.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-6.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-7.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-8.c: New test. + * gcc.target/riscv/rvv/autovec/vls/reduc-9.c: New test. + +2023-09-18 Jiufu Guo <guojiufu@linux.ibm.com> + + PR middle-end/111303 + * gcc.dg/tree-ssa/pr111303.c: New test. + 2023-09-17 Andrew Pinski <apinski@marvell.com> * gcc.dg/tree-ssa/20040204-1.c: Remove xfail. diff --git a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c index 0ab006d..b7389e2 100644 --- a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c @@ -68,5 +68,8 @@ called_by_test_5b (void) void test_5b (void) { - called_by_test_5b (); -} /* { dg-warning "leak of '<anonymous>.ptr_wrapper::ptr'" "" { target c++ } } */ + called_by_test_5b (); } +/* { dg-warning "leak of '<anonymous>.ptr_wrapper::ptr'" "" { target c++ } .-1 } */ +/* The closing } above is intentionally on the same line as the call, because + otherwise the exact line of the diagnostics depends on whether the + called_by_test_5b () call satisfies aggregate_value_p or not. */ diff --git a/gcc/testsuite/c-c++-common/builtin-classify-type-1.c b/gcc/testsuite/c-c++-common/builtin-classify-type-1.c new file mode 100644 index 0000000..a41dbe1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/builtin-classify-type-1.c @@ -0,0 +1,105 @@ +/* { dg-do run { target { c || c++11 } } } */ + +#if !defined(__cplusplus) && __STDC_VERSION__ <= 201710L +#define static_assert _Static_assert +#define bool _Bool +#define false ((_Bool) 0) +#endif +#ifdef __cplusplus +extern "C" void abort (); +#else +extern void abort (void); +#endif + +int +main () +{ + enum E { E1 } e = E1; + struct S { int s; } s = { 0 }; + union U { int u; } u = { 0 }; + int a[2] = { 0, 0 }; + bool b = false; + const char *p = (const char *) 0; + float f = 0.0; + _Complex double c = 0.0; +#ifdef __cplusplus + struct T { void foo (); }; + int &r = a[0]; + int S::*q = &S::s; +#endif + static_assert (__builtin_classify_type (void) == 0, ""); + static_assert (__builtin_classify_type (int) == 1, ""); + static_assert (__builtin_classify_type (enum E) == 3, ""); + static_assert (__builtin_classify_type (bool) == 4, ""); + static_assert (__builtin_classify_type (const char *) == 5, ""); +#ifdef __cplusplus + static_assert (__builtin_classify_type (int &) == 6, ""); + static_assert (__builtin_classify_type (int &&) == 6, ""); + static_assert (__builtin_classify_type (int S::*) == 7, ""); +#endif + static_assert (__builtin_classify_type (float) == 8, ""); + static_assert (__builtin_classify_type (_Complex double) == 9, ""); + static_assert (__builtin_classify_type (int (int, int)) == 10, ""); + static_assert (__builtin_classify_type (struct S) == 12, ""); + static_assert (__builtin_classify_type (union U) == 13, ""); + static_assert (__builtin_classify_type (int [2]) == 14, ""); + static_assert (__builtin_classify_type (__typeof__ (a[0])) == 1, ""); + static_assert (__builtin_classify_type (__typeof__ (e)) == 3, ""); + static_assert (__builtin_classify_type (__typeof__ (b)) == 4, ""); + static_assert (__builtin_classify_type (__typeof__ (p)) == 5, ""); +#ifdef __cplusplus + static_assert (__builtin_classify_type (decltype (r)) == 6, ""); + static_assert (__builtin_classify_type (__typeof__ (q)) == 7, ""); +#endif + static_assert (__builtin_classify_type (__typeof__ (f)) == 8, ""); + static_assert (__builtin_classify_type (__typeof__ (c)) == 9, ""); + static_assert (__builtin_classify_type (__typeof__ (main)) == 10, ""); + static_assert (__builtin_classify_type (__typeof__ (s)) == 12, ""); + static_assert (__builtin_classify_type (__typeof__ (u)) == 13, ""); + static_assert (__builtin_classify_type (__typeof__ (a)) == 14, ""); +#ifndef __cplusplus + static_assert (__builtin_classify_type (a[0]) == 1, ""); + static_assert (__builtin_classify_type (e) == 1, ""); + static_assert (__builtin_classify_type (b) == 1, ""); + static_assert (__builtin_classify_type (p) == 5, ""); + static_assert (__builtin_classify_type (f) == 8, ""); + static_assert (__builtin_classify_type (c) == 9, ""); + static_assert (__builtin_classify_type (main) == 5, ""); + static_assert (__builtin_classify_type (s) == 12, ""); + static_assert (__builtin_classify_type (u) == 13, ""); + static_assert (__builtin_classify_type (a) == 5, ""); +#endif + if (__builtin_classify_type (a[0]) != 1) + abort (); +#ifdef __cplusplus + if (__builtin_classify_type (e) != 3) + abort (); + if (__builtin_classify_type (b) != 4) + abort (); +#else + if (__builtin_classify_type (e) != 1) + abort (); + if (__builtin_classify_type (b) != 1) + abort (); +#endif + if (__builtin_classify_type (p) != 5) + abort (); +#ifdef __cplusplus + if (__builtin_classify_type (r) != 1) + abort (); + if (__builtin_classify_type (q) != 7) + abort (); +#endif + if (__builtin_classify_type (f) != 8) + abort (); + if (__builtin_classify_type (c) != 9) + abort (); + if (__builtin_classify_type (main) != 5) + abort (); + if (__builtin_classify_type (s) != 12) + abort (); + if (__builtin_classify_type (u) != 13) + abort (); + if (__builtin_classify_type (a) != 5) + abort (); +} diff --git a/gcc/testsuite/c-c++-common/cpp/pr61474-2.h b/gcc/testsuite/c-c++-common/cpp/pr61474-2.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr61474-2.h @@ -0,0 +1 @@ +#pragma once diff --git a/gcc/testsuite/c-c++-common/cpp/pr61474.c b/gcc/testsuite/c-c++-common/cpp/pr61474.c new file mode 100644 index 0000000..f835a40 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr61474.c @@ -0,0 +1,5 @@ +/* { dg-do preprocess } */ +#include "pr61474.h" +/* Make sure that the file can be included for real, after it was + fake-included by the linemarker directives in pr61474.h. */ +#include "pr61474-2.h" diff --git a/gcc/testsuite/c-c++-common/cpp/pr61474.h b/gcc/testsuite/c-c++-common/cpp/pr61474.h new file mode 100644 index 0000000..d9e8c3a --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr61474.h @@ -0,0 +1,6 @@ +/* Create a fake include for pr61474-2.h and exercise looking it up. */ +/* Use #pragma once to check also that the fake-include entry in the file + cache does not cause a problem in libcpp/files.cc:has_unique_contents(). */ +#pragma once +# 1 "pr61474-2.h" 1 +# 2 "pr61474-2.h" 1 diff --git a/gcc/testsuite/c-c++-common/cpp/pr90400.c b/gcc/testsuite/c-c++-common/cpp/pr90400.c new file mode 100644 index 0000000..4f2cab8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr90400.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-save-temps" } */ +/* PR preprocessor/90400 */ + +#define OUTER(x) x +#define FOR(x) _Pragma ("GCC unroll 0") for (x) +void f () +{ + /* If the pragma were to be seen prior to the expansion of FOR, as was + the case before r12-5454, then the unroll pragma would complain + because the immediately following statement would be ";" rather than + a loop. */ + OUTER (; FOR (int i = 0; i != 1; ++i);) /* { dg-bogus {statement expected before ';' token} } */ +} diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-10.c b/gcc/testsuite/c-c++-common/gomp/allocate-10.c new file mode 100644 index 0000000..7e8f579 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-10.c @@ -0,0 +1,49 @@ +/* TODO: enable for C++ once implemented. */ +/* { dg-do compile { target c } } */ +/* { dg-additional-options "-Wall -fdump-tree-gimple" } */ + +typedef enum omp_allocator_handle_t +#if __cplusplus >= 201103L +: __UINTPTR_TYPE__ +#endif +{ + omp_default_mem_alloc = 1, + __omp_allocator_handle_t_max__ = __UINTPTR_MAX__ +} omp_allocator_handle_t; + +void +f() +{ + int n; + int A[n]; /* { dg-warning "'n' is used uninitialized" } */ + /* { dg-warning "unused variable 'A'" "" { target *-*-* } .-1 } */ +} + +void +h1() +{ + omp_allocator_handle_t my_handle; + int B1[3]; /* { dg-warning "'my_handle' is used uninitialized" } */ + /* { dg-warning "variable 'B1' set but not used" "" { target *-*-* } .-1 } */ + #pragma omp allocate(B1) allocator(my_handle) + B1[0] = 5; + /* { dg-final { scan-tree-dump-times "__builtin_GOMP_alloc" 1 "gimple" } } */ + /* { dg-final { scan-tree-dump-times "B1.\[0-9\]+ = __builtin_GOMP_alloc \\(4, 12, my_handle\\);" 1 "gimple" } } */ + /* { dg-final { scan-tree-dump-times "__builtin_GOMP_free \\(B1.\[0-9\]+, 0B\\);" 1 "gimple" } } */ +} + +void +h2() +{ + omp_allocator_handle_t my_handle; + int B2[3]; /* { dg-warning "unused variable 'B2'" } */ + #pragma omp allocate(B2) allocator(my_handle) /* No warning as 'B2' is unused */ +} + +void +h3() +{ + omp_allocator_handle_t my_handle; + int B3[3] = {1,2,3}; /* { dg-warning "unused variable 'B3'" } */ + #pragma omp allocate(B3) allocator(my_handle) /* No warning as 'B3' is unused */ +} diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-11.c b/gcc/testsuite/c-c++-common/gomp/allocate-11.c index f9ad50a..dceb97f 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-11.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-11.c @@ -10,7 +10,6 @@ f (int i) switch (i) /* { dg-note "switch starts here" } */ { int j; /* { dg-note "'j' declared here" } */ - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ #pragma omp allocate(j) case 42: /* { dg-error "switch jumps over OpenMP 'allocate' allocation" } */ bar (); @@ -30,9 +29,7 @@ h (int i2) return 5; int k2; /* { dg-note "'k2' declared here" } */ - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ int j2 = 4; /* { dg-note "'j2' declared here" } */ - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ #pragma omp allocate(k2, j2) label: /* { dg-note "label 'label' defined here" } */ k2 = 4; diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-12.c b/gcc/testsuite/c-c++-common/gomp/allocate-12.c index 3c7c3bb..1b77db9 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-12.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-12.c @@ -17,7 +17,6 @@ f () omp_allocator_handle_t my_allocator; int n = 5; /* { dg-note "to be allocated variable declared here" } */ my_allocator = omp_default_mem_alloc; /* { dg-note "modified here" } */ - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-2 } */ #pragma omp allocate(n) allocator(my_allocator) /* { dg-error "variable 'my_allocator' used in the 'allocator' clause must not be modified between declaration of 'n' and its 'allocate' directive" } */ n = 7; return n; @@ -28,7 +27,6 @@ int g () { int n = 5; /* { dg-note "to be allocated variable declared here" } */ - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ omp_allocator_handle_t my_allocator = omp_low_lat_mem_alloc; /* { dg-note "declared here" } */ #pragma omp allocate(n) allocator(my_allocator) /* { dg-error "variable 'my_allocator' used in the 'allocator' clause must be declared before 'n'" } */ n = 7; @@ -42,7 +40,6 @@ h () see gomp/allocate-10.c. */ omp_allocator_handle_t my_allocator; int n = 5; - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target *-*-* } .-1 } */ #pragma omp allocate(n) allocator(my_allocator) n = 7; return n; diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-15.c b/gcc/testsuite/c-c++-common/gomp/allocate-15.c index d9600f9..15105b91 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-15.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-15.c @@ -8,7 +8,7 @@ void f () { - int var; /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive, used for 'var', not yet supported" } */ + int var; #pragma omp allocate(var) var = 5; } @@ -21,7 +21,7 @@ h () #pragma omp parallel #pragma omp serial { - int var2[5]; /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive, used for 'var2', not yet supported" } */ + int var2[5]; #pragma omp allocate(var2) var2[0] = 7; } diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-17.c b/gcc/testsuite/c-c++-common/gomp/allocate-17.c new file mode 100644 index 0000000..f75af0c --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-17.c @@ -0,0 +1,37 @@ +/* This file has a syntax error but should not ICE. + Namely, a '}' is missing in one(). */ + +typedef enum omp_allocator_handle_t +#if __cplusplus >= 201103L +: __UINTPTR_TYPE__ +#endif +{ + omp_default_mem_alloc = 1, + omp_low_lat_mem_alloc = 5, + __omp_allocator_handle_t_max__ = __UINTPTR_MAX__ +} omp_allocator_handle_t; + +#include <stdint.h> + +void +one () +{ /* { dg-note "to match this '\{'" "" { target c++ } } */ + int result = 0, n = 3; + #pragma omp target map(tofrom: result) firstprivate(n) + { + int var = 5; //, var2[n]; + #pragma omp allocate(var) align(128) allocator(omp_low_lat_mem_alloc) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */ + var = 7; +} + +void +two () +{ /* { dg-error "a function-definition is not allowed here before '\{' token" "" { target c++ } } */ + int scalar = 44; + #pragma omp allocate(scalar) + + #pragma omp parallel firstprivate(scalar) + scalar = 33; +} +/* { dg-error "expected declaration or statement at end of input" "" { target c } .-1 } */ +/* { dg-error "expected '\}' at end of input" "" { target c++ } .-2 } */ diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-9.c b/gcc/testsuite/c-c++-common/gomp/allocate-9.c index 8e01041..3c11080 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-9.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-9.c @@ -86,8 +86,6 @@ int g() /* { dg-note "declared here" "" { target c } .-8 } */ /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */ return c2+a2+b2; - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target c } .-5 } */ - /* { dg-message "sorry, unimplemented: OpenMP 'allocate' directive" "" { target c } .-12 } */ } } diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic19.C b/gcc/testsuite/g++.dg/concepts/diagnostic19.C new file mode 100644 index 0000000..70af30b --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/diagnostic19.C @@ -0,0 +1,20 @@ +// Verify pretty printing of class NTTP objects. +// PR c++/111471 +// { dg-do compile { target c++20 } } + +struct A { bool value; }; + +template<A V> + requires (V.value) // { dg-message {'\(V\).value \[with V = A\{false\}\]'} } +void f(); + +template<A V> struct B { static constexpr auto value = V.value; }; + +template<class T> + requires T::value // { dg-message {'T::value \[with T = B<A\{false\}>\]'} } +void g(); + +int main() { + f<A{false}>(); // { dg-error "no match" } + g<B<A{false}>>(); // { dg-error "no match" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor38.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor38.C new file mode 100644 index 0000000..56217be --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor38.C @@ -0,0 +1,19 @@ +// CWG 2799 +// Test that inheriting a trivial default constructor produces a trivial +// default constructor. + +// { dg-do compile { target c++11 } } + +#include <type_traits> + +struct A { + A() = default; +}; + +struct B : A +{ + using A::A; + B(int); +}; + +static_assert (std::is_trivially_constructible<B>::value, ""); diff --git a/gcc/testsuite/g++.dg/cpp0x/static_assert15.C b/gcc/testsuite/g++.dg/cpp0x/static_assert15.C index a740f73..d5f50d0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/static_assert15.C +++ b/gcc/testsuite/g++.dg/cpp0x/static_assert15.C @@ -5,6 +5,6 @@ template<int x> struct a { constexpr void b() { int c; - static_assert(c %= 1, ""); + static_assert(c %= 1, ""); // { dg-error "constant" } } }; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-partial3.C new file mode 100644 index 0000000..5af6071 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial3.C @@ -0,0 +1,19 @@ +// PR c++/89231 +// { dg-do compile { target c++11 } } + +template<class... Ps> +struct A { + template<int... Ns> + struct Collect { }; + + template<int C, int I = 0, class S = Collect<>> + struct Seq; + + template<int C, int I, int... N> + struct Seq<C, I, Collect<N...>> : Seq<C - 1, I + 1, Collect<N..., I>> { }; + + template<int I, int... N> + struct Seq<0, I, Collect<N...>> : Collect<N...> { }; +}; + +A<int>::Seq<4> test; diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C b/gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C index 440bea5..bac3b64 100644 --- a/gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C +++ b/gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C @@ -3,20 +3,20 @@ template<class T1, class... Tn> void foo(T1, Tn...); +// { dg-message "candidate expects at least 1 argument, 0 provided" "" { target *-*-* } .-1 } template<class T1, class T2, class... Tn> void bar(T1, T2, Tn...); +// { dg-message "candidate expects at least 2 arguments, 0 provided" "" { target *-*-* } .-1 } +// { dg-message "candidate expects at least 2 arguments, 1 provided" "" { target *-*-* } .-2 } int main() { foo(); // { dg-error "no matching" } - // { dg-message "candidate expects at least 1 argument, 0 provided" "" { target *-*-* } .-1 } foo(1); foo(1, 2); bar(); // { dg-error "no matching" } - // { dg-message "candidate expects at least 2 arguments, 0 provided" "" { target *-*-* } .-1 } bar(1); // { dg-error "no matching" } - // { dg-message "candidate expects at least 2 arguments, 1 provided" "" { target *-*-* } .-1 } bar(1, 2); bar(1, 2, 3); } diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C b/gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C index 1a99e22..22b19ef 100644 --- a/gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C +++ b/gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C @@ -3,21 +3,21 @@ template<class T1, class... Tn, class... Tm> void foo(T1, Tn..., Tm...); +// { dg-message "candidate expects at least 1 argument, 0 provided" "" { target *-*-* } .-1 } template<class T1, class T2, class... Tn, class... Tm> void bar(T1, T2, Tn..., Tm...); +// { dg-message "candidate expects at least 2 arguments, 0 provided" "" { target *-*-* } .-1 } +// { dg-message "candidate expects at least 2 arguments, 1 provided" "" { target *-*-* } .-2 } int main() { foo(); // { dg-error "no matching" } - // { dg-message "candidate expects at least 1 argument, 0 provided" "" { target *-*-* } .-1 } foo(1); foo(1, 2); foo(1, 2, 3); bar(); // { dg-error "no matching" } - // { dg-message "candidate expects at least 2 arguments, 0 provided" "" { target *-*-* } .-1 } bar(1); // { dg-error "no matching" } - // { dg-message "candidate expects at least 2 arguments, 1 provided" "" { target *-*-* } .-1 } bar(1, 2); bar(1, 2, 3); bar(1, 2, 3, 4); diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if2.C b/gcc/testsuite/g++.dg/cpp23/consteval-if2.C index d1845da..b2c5472 100644 --- a/gcc/testsuite/g++.dg/cpp23/consteval-if2.C +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if2.C @@ -58,6 +58,7 @@ baz (int x) return r; } +// This function is not instantiated so NDR. template <typename T> constexpr int qux (int x) @@ -65,7 +66,7 @@ qux (int x) int r = 0; if not consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } { - r += foo (x); // { dg-error "'x' is not a constant expression" } + r += foo (x); // { dg-error "'x' is not a constant expression" "" { xfail *-*-* } } } else { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C new file mode 100644 index 0000000..8d3a4fc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C @@ -0,0 +1,16 @@ +// PR c++/111419 +// { dg-do compile { target c++20 } } + +template<class F> +concept invocable = requires(F& f) { f(); }; + +template<class F> +concept deref_invocable = requires(F& f) { *f(); }; + +struct Incomplete; + +template<class T> +struct Holder { T t; }; + +static_assert(invocable<Holder<Incomplete>& ()>); +static_assert(deref_invocable<Holder<Incomplete>* ()>); diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C b/gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C index 910e7a1..63f4f1d 100644 --- a/gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C +++ b/gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C @@ -25,3 +25,10 @@ void VerifyHash(fixed_string s) { fixed_string::size_static(-1); // { dg-message "expansion of" } s(); // { dg-bogus "" } } + +void +do_test () +{ + fixed_string f; + VerifyHash<int>(f); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval11.C b/gcc/testsuite/g++.dg/cpp2a/consteval11.C index 2f68ec0..091127e 100644 --- a/gcc/testsuite/g++.dg/cpp2a/consteval11.C +++ b/gcc/testsuite/g++.dg/cpp2a/consteval11.C @@ -5,21 +5,21 @@ consteval int bar (int i) { if (i != 1) throw 1; return 0; } // { dg-error "is n constexpr int a = bar (1); constexpr int b = bar (2); // { dg-message "in 'constexpr' expansion of" } -constexpr int c = 0 ? bar (3) : 1; // { dg-message "in 'constexpr' expansion of" } +constexpr int c = 0 ? bar (3) : 1; const int d = bar (4); // { dg-message "in 'constexpr' expansion of" } -const int e = 0 ? bar (5) : 1; // { dg-message "in 'constexpr' expansion of" } +const int e = 0 ? bar (5) : 1; int f = bar (1); int g = bar (6); // { dg-message "in 'constexpr' expansion of" } -int h = 0 ? bar (7) : 1; // { dg-message "in 'constexpr' expansion of" } +int h = 0 ? bar (7) : 1; void foo () { constexpr int a = bar (1); constexpr int b = bar (2); // { dg-message "in 'constexpr' expansion of" } - constexpr int c = 0 ? bar (3) : 1; // { dg-message "in 'constexpr' expansion of" } + constexpr int c = 0 ? bar (3) : 1; const int d = bar (4); // { dg-message "in 'constexpr' expansion of" } - const int e = 0 ? bar (5) : 1; // { dg-message "in 'constexpr' expansion of" } + const int e = 0 ? bar (5) : 1; int f = bar (1); int g = bar (6); // { dg-message "in 'constexpr' expansion of" } int h = 0 ? bar (7) : 1; // { dg-message "in 'constexpr' expansion of" } @@ -33,13 +33,13 @@ foo () else bar (12); // { dg-message "in 'constexpr' expansion of" } if constexpr (0) - bar (13); // { dg-message "in 'constexpr' expansion of" } + bar (13); else bar (14); // { dg-message "in 'constexpr' expansion of" } if constexpr (1) bar (15); // { dg-message "in 'constexpr' expansion of" } else - bar (16); // { dg-message "in 'constexpr' expansion of" } + bar (16); } consteval int @@ -77,22 +77,25 @@ template <typename T> void qux () { + // Used to give errors errors here, but not since we moved consteval + // function folding to cp_fold_r which isn't called on uninstantiated + // templates. if (0) - bar (2); // { dg-message "in 'constexpr' expansion of" } + bar (2); else - bar (3); // { dg-message "in 'constexpr' expansion of" } + bar (3); if (1) - bar (4); // { dg-message "in 'constexpr' expansion of" } + bar (4); else - bar (5); // { dg-message "in 'constexpr' expansion of" } + bar (5); if constexpr (0) - bar (6); // { dg-message "in 'constexpr' expansion of" } + bar (6); else - bar (7); // { dg-message "in 'constexpr' expansion of" } + bar (7); if constexpr (1) - bar (8); // { dg-message "in 'constexpr' expansion of" } + bar (8); else - bar (9); // { dg-message "in 'constexpr' expansion of" } + bar (9); if (0) bar ((T) 2); else diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval3.C b/gcc/testsuite/g++.dg/cpp2a/consteval3.C index 627ab14..9efac8c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/consteval3.C +++ b/gcc/testsuite/g++.dg/cpp2a/consteval3.C @@ -18,8 +18,7 @@ consteval int f6 (int x) { return x; } int d = 6; // { dg-message "'int d' is not const" } int e = f6 (d); // { dg-error "the value of 'd' is not usable in a constant expression" } constexpr int f7 (int x) { return f6 (x); } // { dg-error "'x' is not a constant expression" } -constexpr int f = f7 (5); // { dg-error "" } - // { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 } +constexpr int f = f7 (5); using fnptr = int (int); fnptr *g = f6; // { dg-error "taking address of an immediate function 'consteval int f6\\(int\\)'" } int f8 (fnptr *); diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval32.C b/gcc/testsuite/g++.dg/cpp2a/consteval32.C new file mode 100644 index 0000000..f1de63e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/consteval32.C @@ -0,0 +1,4 @@ +// { dg-do compile { target c++20 } } + +consteval int foo () { return 42; } +int bar () { return (*(&foo)) (); } // { dg-error "taking address" } diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval33.C b/gcc/testsuite/g++.dg/cpp2a/consteval33.C new file mode 100644 index 0000000..3d50b00 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/consteval33.C @@ -0,0 +1,34 @@ +// { dg-do compile { target c++20 } } + +consteval int id (int i) { return i; } +consteval int add (int i, int j) { return i + j; } + +constexpr int +foo (int i = id (42)) +{ + return i + id (id (id (0))); +} + +constexpr int +bar (int i = id (id (id (42)))) +{ + return i; +} + +constexpr int +baz (int i = add (add (id (1), id (2)), id (3))) +{ + return i; +} + +void +g () +{ + foo (); + bar (); + baz (); +} + +static_assert (foo () == 42); +static_assert (bar () == 42); +static_assert (baz () == 6); diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval34.C b/gcc/testsuite/g++.dg/cpp2a/consteval34.C new file mode 100644 index 0000000..d5e2d1d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/consteval34.C @@ -0,0 +1,33 @@ +// { dg-do compile { target c++20 } } + +consteval int bar (int i) { if (i != 1) throw 1; return 0; } // { dg-error "is not a constant expression" } + +constexpr int +foo (bool b) +{ + return b ? bar (3) : 2; // { dg-message "in .constexpr. expansion" } +} + +static_assert (foo (false) == 2); + +__extension__ constexpr int g1 = false ?: bar (2); // { dg-message "in .constexpr. expansion" } +__extension__ constexpr int g2 = false ?: (1 + bar (2)); // { dg-message "in .constexpr. expansion" } +__extension__ constexpr int g3 = true ?: bar (2); +__extension__ constexpr int g4 = true ?: (1 + bar (2)); +constexpr int g5 = bar (2) ? 1 : 2; // { dg-message "in .constexpr. expansion" } +constexpr int g6 = bar (2) - 1 ? 1 : 2; // { dg-message "in .constexpr. expansion" } + +void +g () +{ + __extension__ int a1[bar(3)]; // { dg-message "in .constexpr. expansion" } + int a2[sizeof (bar(3))]; + + int a3 = false ? (1 + bar (8)) : 1; // { dg-message "in .constexpr. expansion" } + a3 += false ? (1 + bar (8)) : 1; // { dg-message "in .constexpr. expansion" } + + __extension__ int a4 = false ?: (1 + bar (8)); // { dg-message "in .constexpr. expansion" } + __extension__ int a5 = true ?: (1 + bar (8)); // { dg-message "in .constexpr. expansion" } + int a6 = bar (2) ? 1 : 2; // { dg-message "in .constexpr. expansion" } + int a7 = bar (2) - 1 ? 1 : 2; // { dg-message "in .constexpr. expansion" } +} diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval35.C b/gcc/testsuite/g++.dg/cpp2a/consteval35.C new file mode 100644 index 0000000..59d23ac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/consteval35.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++20 } } + +template <typename T, typename F> +constexpr bool is_not(T t, F f) { + return not f(t); +} + +consteval bool is_even(int i) { return i % 2 == 0; } + +static_assert(is_not(5, is_even)); // ok diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval9.C b/gcc/testsuite/g++.dg/cpp2a/consteval9.C index 489286a..aa75ba3 100644 --- a/gcc/testsuite/g++.dg/cpp2a/consteval9.C +++ b/gcc/testsuite/g++.dg/cpp2a/consteval9.C @@ -15,10 +15,11 @@ void qux () int a = bar (N); // { dg-message "in 'constexpr' expansion of 'bar\\(2\\)'" } } +// This function is not instantiated so NDR. template <int N> void quux () { - int a = bar (5); // { dg-message "in 'constexpr' expansion of 'bar\\(5\\)'" } + int a = bar (5); } void diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class60.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class60.C new file mode 100644 index 0000000..9e8030b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class60.C @@ -0,0 +1,18 @@ +// PR c++/99631 +// { dg-do compile { target c++20 } } + +struct A { }; + +template<auto V> +void f() { + static_assert(__is_same(decltype(V), A)); +} + +template<class T, T V> +void g() { + static_assert(__is_same(decltype(V), A)); +} + +constexpr A a; +template void f<a>(); +template void g<A, A{}>(); diff --git a/gcc/testsuite/g++.dg/expr/discarded1.C b/gcc/testsuite/g++.dg/expr/discarded1.C new file mode 100644 index 0000000..c0c22e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/discarded1.C @@ -0,0 +1,15 @@ +// PR c++/111419 + +struct Incomplete; + +template<class T> struct Holder { T t; }; // { dg-bogus "incomplete" } + +extern Holder<Incomplete> a; +extern Holder<Incomplete>& b; +extern Holder<Incomplete>* c; + +int main() { + a; + b; + *c; +} diff --git a/gcc/testsuite/g++.dg/expr/discarded1a.C b/gcc/testsuite/g++.dg/expr/discarded1a.C new file mode 100644 index 0000000..1c4dff4 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/discarded1a.C @@ -0,0 +1,17 @@ +// A version of discarded1.C using volatile types. +// PR c++/111419 + +struct Incomplete; + +template<class T, int> struct Holder { T t; }; // { dg-error "incomplete" } + +extern volatile Holder<Incomplete, 0> a; +extern volatile Holder<Incomplete, 1>& b; +extern volatile Holder<Incomplete, 2>* c; + +int main() { + a; // { dg-message "required from here" } + b; // { dg-message "required from here" } + // { dg-warning "implicit dereference will not access object" "" { target *-*-* } .-1 } + *c; // { dg-message "required from here" } +} diff --git a/gcc/testsuite/g++.dg/expr/unary2.C b/gcc/testsuite/g++.dg/expr/unary2.C index 5962bfe..4db6837 100644 --- a/gcc/testsuite/g++.dg/expr/unary2.C +++ b/gcc/testsuite/g++.dg/expr/unary2.C @@ -1,9 +1,7 @@ +// PR c++/18474 // { dg-do compile } // Unary plus/minus are not lvalues. -// In templates we require an instantiation to emit the diagnostic. This -// is wrong and it is PR 18474. - int n; void f(void) @@ -15,6 +13,6 @@ void f(void) template <int> void g(void) { - -n = 0; // { dg-error "lvalue" "" { xfail *-*-* } } - +n = 0; // { dg-error "lvalue" "" { xfail *-*-* } } + -n = 0; // { dg-error "lvalue" "" } + +n = 0; // { dg-error "lvalue" "" } } diff --git a/gcc/testsuite/g++.dg/ext/attr-hotness.C b/gcc/testsuite/g++.dg/ext/attr-hotness.C new file mode 100644 index 0000000..f9a6930 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-hotness.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wattributes -fdump-tree-gimple" } */ + + +struct __attribute((cold)) A { __attribute((noinline, used)) void foo(void) { } }; + +struct __attribute((hot)) B { __attribute((noinline, used)) void foo(void) { } }; + +struct __attribute((hot, cold)) C { __attribute((noinline, used)) void foo(void) { } }; /* { dg-warning "ignoring attribute .cold. because it conflicts with attribute .hot." } */ + +struct __attribute((cold, hot)) D { __attribute((noinline, used)) void foo(void) { } }; /* { dg-warning "ignoring attribute .hot. because it conflicts with attribute .cold." } */ + + +/* { dg-final { scan-tree-dump-times "cold" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "hot" 2 "gimple" } } */ + diff --git a/gcc/testsuite/g++.dg/ext/builtin-classify-type-1.C b/gcc/testsuite/g++.dg/ext/builtin-classify-type-1.C new file mode 100644 index 0000000..0d145f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-classify-type-1.C @@ -0,0 +1,149 @@ +// { dg-do run { target c++11 } } + +extern "C" void abort (); + +template <int N> +void +foo () +{ + enum E { E1 } e = E1; + struct S { int s; } s = { 0 }; + union U { int u; } u = { 0 }; + int a[2] = { 0, 0 }; + bool b = false; + const char *p = (const char *) 0; + float f = 0.0; + _Complex double c = 0.0; + struct T { void foo (); }; + int &r = a[0]; + int S::*q = &S::s; + static_assert (__builtin_classify_type (void) == 0, ""); + static_assert (__builtin_classify_type (int) == 1, ""); + static_assert (__builtin_classify_type (enum E) == 3, ""); + static_assert (__builtin_classify_type (bool) == 4, ""); + static_assert (__builtin_classify_type (const char *) == 5, ""); + static_assert (__builtin_classify_type (int &) == 6, ""); + static_assert (__builtin_classify_type (int &&) == 6, ""); + static_assert (__builtin_classify_type (int S::*) == 7, ""); + static_assert (__builtin_classify_type (float) == 8, ""); + static_assert (__builtin_classify_type (_Complex double) == 9, ""); + static_assert (__builtin_classify_type (int (int, int)) == 10, ""); + static_assert (__builtin_classify_type (struct S) == 12, ""); + static_assert (__builtin_classify_type (union U) == 13, ""); + static_assert (__builtin_classify_type (int [2]) == 14, ""); + static_assert (__builtin_classify_type (__typeof__ (a[0])) == 1, ""); + static_assert (__builtin_classify_type (__typeof__ (e)) == 3, ""); + static_assert (__builtin_classify_type (__typeof__ (b)) == 4, ""); + static_assert (__builtin_classify_type (__typeof__ (p)) == 5, ""); + static_assert (__builtin_classify_type (decltype (r)) == 6, ""); + static_assert (__builtin_classify_type (__typeof__ (q)) == 7, ""); + static_assert (__builtin_classify_type (__typeof__ (f)) == 8, ""); + static_assert (__builtin_classify_type (__typeof__ (c)) == 9, ""); + static_assert (__builtin_classify_type (__typeof__ (abort)) == 10, ""); + static_assert (__builtin_classify_type (__typeof__ (s)) == 12, ""); + static_assert (__builtin_classify_type (__typeof__ (u)) == 13, ""); + static_assert (__builtin_classify_type (__typeof__ (a)) == 14, ""); + if (__builtin_classify_type (a[0]) != 1) + abort (); + if (__builtin_classify_type (e) != 3) + abort (); + if (__builtin_classify_type (b) != 4) + abort (); + if (__builtin_classify_type (p) != 5) + abort (); + if (__builtin_classify_type (r) != 1) + abort (); + if (__builtin_classify_type (q) != 7) + abort (); + if (__builtin_classify_type (f) != 8) + abort (); + if (__builtin_classify_type (c) != 9) + abort (); + if (__builtin_classify_type (abort) != 5) + abort (); + if (__builtin_classify_type (s) != 12) + abort (); + if (__builtin_classify_type (u) != 13) + abort (); + if (__builtin_classify_type (a) != 5) + abort (); +} + +template <typename V, typename I, typename E, typename B, typename P, + typename R1, typename R2, typename PM, typename F, + typename C, typename FN, typename S, typename U, typename A> +void +bar () +{ + E e = (E) 0; + S s = { 0 }; + U u = { 0 }; + A a = { 0, 0 }; + B b = false; + P p = (P) 0; + F f = 0.0; + C c = 0.0; + R1 r = a[0]; + PM q = &S::s; + static_assert (__builtin_classify_type (V) == 0, ""); + static_assert (__builtin_classify_type (I) == 1, ""); + static_assert (__builtin_classify_type (E) == 3, ""); + static_assert (__builtin_classify_type (B) == 4, ""); + static_assert (__builtin_classify_type (P) == 5, ""); + static_assert (__builtin_classify_type (R1) == 6, ""); + static_assert (__builtin_classify_type (R2) == 6, ""); + static_assert (__builtin_classify_type (PM) == 7, ""); + static_assert (__builtin_classify_type (F) == 8, ""); + static_assert (__builtin_classify_type (C) == 9, ""); + static_assert (__builtin_classify_type (FN) == 10, ""); + static_assert (__builtin_classify_type (S) == 12, ""); + static_assert (__builtin_classify_type (U) == 13, ""); + static_assert (__builtin_classify_type (A) == 14, ""); + static_assert (__builtin_classify_type (__typeof__ (a[0])) == 1, ""); + static_assert (__builtin_classify_type (__typeof__ (e)) == 3, ""); + static_assert (__builtin_classify_type (__typeof__ (b)) == 4, ""); + static_assert (__builtin_classify_type (__typeof__ (p)) == 5, ""); + static_assert (__builtin_classify_type (decltype (r)) == 6, ""); + static_assert (__builtin_classify_type (__typeof__ (q)) == 7, ""); + static_assert (__builtin_classify_type (__typeof__ (f)) == 8, ""); + static_assert (__builtin_classify_type (__typeof__ (c)) == 9, ""); + static_assert (__builtin_classify_type (__typeof__ (abort)) == 10, ""); + static_assert (__builtin_classify_type (__typeof__ (s)) == 12, ""); + static_assert (__builtin_classify_type (__typeof__ (u)) == 13, ""); + static_assert (__builtin_classify_type (__typeof__ (a)) == 14, ""); + if (__builtin_classify_type (a[0]) != 1) + abort (); + if (__builtin_classify_type (e) != 3) + abort (); + if (__builtin_classify_type (b) != 4) + abort (); + if (__builtin_classify_type (p) != 5) + abort (); + if (__builtin_classify_type (r) != 1) + abort (); + if (__builtin_classify_type (q) != 7) + abort (); + if (__builtin_classify_type (f) != 8) + abort (); + if (__builtin_classify_type (c) != 9) + abort (); + if (__builtin_classify_type (abort) != 5) + abort (); + if (__builtin_classify_type (s) != 12) + abort (); + if (__builtin_classify_type (u) != 13) + abort (); + if (__builtin_classify_type (a) != 5) + abort (); +} + +int +main () +{ + enum E { E1 }; + struct S { int s; }; + union U { int u; }; + foo <0> (); + bar <void, int, E, bool, const char *, int &, int &&, int S::*, + float, _Complex double, int (int, int), S, U, int [2]> (); +} diff --git a/gcc/testsuite/g++.dg/ext/builtin-classify-type-2.C b/gcc/testsuite/g++.dg/ext/builtin-classify-type-2.C new file mode 100644 index 0000000..acebd3f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-classify-type-2.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++11 } } +// { dg-options "" } + +void +foo (int n) +{ + __builtin_classify_type (enum E { E1, E2 }); // { dg-error "types may not be defined in '__builtin_classify_type' calls" } + __builtin_classify_type (struct S { int s; });// { dg-error "types may not be defined in '__builtin_classify_type' calls" } + __builtin_classify_type (union U { int u; }); // { dg-error "types may not be defined in '__builtin_classify_type' calls" } + __builtin_classify_type (int [2 * n + 36]); +} diff --git a/gcc/testsuite/g++.dg/gomp/attrs-19.C b/gcc/testsuite/g++.dg/gomp/attrs-19.C new file mode 100644 index 0000000..77e565a --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/attrs-19.C @@ -0,0 +1,68 @@ +// { dg-do compile { target c++11 } } + +void foo1 (); + +void +foo () +{ + [[omp::decl (declare variant (foo1) match (construct={parallel,for}))]] + extern void foo2 (); + [[omp::sequence (directive (parallel), directive (for))]] + for (int i = 0; i < 5; i++) + foo2 (); + [[omp::decl (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch), + omp::directive (declare simd simdlen(8) notinbranch)]] + extern int foo3 (int l, int *p); + [[omp::directive (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch), + omp::decl (declare simd simdlen(8) notinbranch)]] + extern int foo4 (int l, int *p); + [[omp::decl (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch), + omp::decl (declare simd simdlen(8) notinbranch)]] + extern int foo5 (int l, int *p); +} + +void bar1 (); + +void +bar () +{ + [[using omp : decl (declare variant (bar1), match (construct={parallel,for}))]] // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } + extern void bar2 (); + [[using omp : sequence (directive (parallel), directive (for))]] // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } + for (int i = 0; i < 5; i++) + bar2 (); + [[omp::decl (declare simd, simdlen(4), linear(l), aligned(p:4),uniform(p),inbranch), + omp::directive (declare simd simdlen(8) notinbranch)]] + extern int bar3 (int l, int *p); + [[using omp : directive (declare simd,simdlen(4),linear(l),aligned(p:4),uniform(p),inbranch), // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } + decl (declare simd, simdlen(8), notinbranch)]] + extern int bar4 (int l, int *p); + [[omp::decl (declare simd, simdlen(4), linear(l), aligned(p:4), uniform(p), inbranch), + omp::decl (declare simd, simdlen(8), notinbranch)]] + extern int bar5 (int l, int *p); +} + +struct S { S (); ~S (); int s; }; + +[[omp::decl (threadprivate)]] int t1, t2; +int x1, t3 [[omp::decl (threadprivate)]], x2, t4 [[omp::decl (threadprivate)]] [5]; +[[maybe_unused, omp::decl (threadprivate)]] int t5, t6; +[[using omp : decl (threadprivate)]] S t7, t8; // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } +[[using omp : decl (declare target enter device_type (host))]] int d1, d2, d3 (int, int), d4; // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } +int x3, d5 [[omp::decl (declare target, enter, device_type (any))]], d6 [[omp::decl (declare target link)]], x4; +int d7 [[omp::decl (declare target)]]; +[[using omp : decl (declare target), decl (declare target)]] int d8, d9; // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } + +void +baz () +{ + [[omp::decl (threadprivate)]] static int t1, t2; + static int x1, t3 [[omp::decl (threadprivate)]], x2, t4 [[omp::decl (threadprivate)]] [5]; + [[maybe_unused, omp::decl (threadprivate)]] extern int t5, t6; + [[using omp : decl (declare target enter)]] extern int d1, d2, d3 (int, int), d4; // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } + static int x3, d5 [[omp::decl (declare target, enter, device_type (any))]], d6 [[omp::decl (declare target link)]], x4; + ++t1; ++t2; + ++t3; ++t4[2]; + ++t5; ++t6; + ++d1; +} diff --git a/gcc/testsuite/g++.dg/gomp/attrs-20.C b/gcc/testsuite/g++.dg/gomp/attrs-20.C new file mode 100644 index 0000000..86f8612 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/attrs-20.C @@ -0,0 +1,240 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-fopenmp -ffat-lto-objects -fdump-tree-gimple" } + +extern "C" void abort (); + +[[omp::decl (declare simd, linear (l))]] extern int f1 (int l); +extern int f2 (int), f3 [[omp::decl (declare simd, uniform (m))]] (int m), f4 (int), z; +[[omp::decl (declare simd, linear (l), simdlen(4))]] extern int f5 [[omp::decl (declare simd uniform (l) simdlen (8) notinbranch)]] (int l); + +int +f1 (int l) +{ + return l; +} + +// { dg-final { scan-assembler-times "_ZGVbM4l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM16l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN16l__Z2f1i:" 1 { target { i?86-*-* x86_64-*-* } } } } + +int +f2 (int l) +{ + return l + 1; +} + +// { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]__Z2f2i:" { target { i?86-*-* x86_64-*-* } } } } + +int +f3 (int l) +{ + return l + 2; +} + +// { dg-final { scan-assembler-times "_ZGVbM4u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM16u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN16u__Z2f3i:" 1 { target { i?86-*-* x86_64-*-* } } } } + +int +f4 (int l) +{ + return l + 3; +} + +// { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]__Z2f4i:" { target { i?86-*-* x86_64-*-* } } } } + +int +f5 (int l) +{ // { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64*-*-* } .-1 } + return l + 4; +} + +// { dg-final { scan-assembler-times "_ZGVbM4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN4l__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN8u__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN8u__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8u__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN8u__Z2f5i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-not "_ZGV\[bcde]M8u__Z2f5i:" { target { i?86-*-* x86_64-*-* } } } } + +[[omp::decl (declare simd, linear (l), simdlen(4), notinbranch), + omp::decl (declare simd, uniform (l), simdlen(4), inbranch)]] +int +f6 [[using omp : decl (declare simd uniform (l) simdlen (8), notinbranch), // { dg-warning "attribute using prefix only available with" "" { target c++14_down } } + decl (declare simd, linear (l), simdlen (8), inbranch)]] (int l) +{ // { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64*-*-* } .-2 } + return l + 5; +} + +// { dg-final { scan-assembler-times "_ZGVbM4u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbM8l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN8u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM8l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN8u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM4u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN4l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM4u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN4l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM8l__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN8u__Z2f6i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-not "_ZGV\[bcde]M4l__Z2f6i:" { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-not "_ZGV\[bcde]N4u__Z2f6i:" { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-not "_ZGV\[bcde]M8u__Z2f6i:" { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-not "_ZGV\[bcde]N8l__Z2f6i:" { target { i?86-*-* x86_64-*-* } } } } + +int +f7 (int l) +{ + return l + 6; +} + +// { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]__Z2f7i:" { target { i?86-*-* x86_64-*-* } } } } + +int +f8 (int l) +{ + return l + 7; +} + +// { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]__Z2f8i:" { target { i?86-*-* x86_64-*-* } } } } + +[[omp::decl (declare variant (f7), match (construct={parallel})), + omp::decl (declare simd uniform (l), simdlen(4))]] +int +f9 [[omp::decl (declare simd uniform (l) simdlen (8)), + omp::decl (declare variant (f8) match (construct={parallel,for}))]] (int l) +{ // { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64*-*-* } .-2 } + return l + 8; +} + +// { dg-final { scan-assembler-times "_ZGVbM4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN4u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbM8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN8u__Z2f9i:" 1 { target { i?86-*-* x86_64-*-* } } } } + +int z; + +void +test () +{ + [[omp::directive (parallel)]] + if (f9 (3) != 9) + abort (); + [[omp::directive (parallel for)]] + for (int i = 0; i < 1; i++) + if (f9 (4) != 11) + abort (); + if (f9 (5) != 13) + abort (); +} + +// { dg-final { scan-tree-dump-times " = f7 \\\(3\\\);" 1 "gimple" } } +// { dg-final { scan-tree-dump-times " = f8 \\\(4\\\);" 1 "gimple" } } +// { dg-final { scan-tree-dump-times " = f9 \\\(5\\\);" 1 "gimple" } } + +template <int N> +int +f10 (int x) +{ + return x + N; +} + +template [[omp::decl (declare simd, notinbranch)]] int f10<0> (int); + +// { dg-final { scan-assembler-times "_ZGVbN4v__Z3f10ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4v__Z3f10ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8v__Z3f10ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN16v__Z3f10ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } + +template int f10<1> [[omp::decl (declare simd inbranch linear(x))]] (int x); + +// { dg-final { scan-assembler-times "_ZGVbM4l__Z3f10ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4l__Z3f10ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8l__Z3f10ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM16l__Z3f10ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } + +template <int N> +int f11 (int); + +template <> [[omp::decl (declare simd, inbranch)]] int +f11<0> (int x) +{ + return x; +} + +// { dg-final { scan-assembler-times "_ZGVbM4v__Z3f11ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4v__Z3f11ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8v__Z3f11ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM16v__Z3f11ILi0EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } + +template <> int +f11<1> [[omp::decl (declare simd, notinbranch, linear (y))]] (int y) +{ + return y; +} + +// { dg-final { scan-assembler-times "_ZGVbN4l__Z3f11ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4l__Z3f11ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8l__Z3f11ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN16l__Z3f11ILi1EEii:" 1 { target { i?86-*-* x86_64-*-* } } } } + +struct S +{ + [[omp::decl (declare simd, inbranch, uniform (this))]] int f12 (int x); + int f13 [[gnu::noinline, omp::decl (declare simd notinbranch uniform (this) linear (y))]] (int y) { return y; } +}; + +int +S::f12 (int x) +{ + return x; +} + +// { dg-final { scan-assembler-times "_ZGVbM4uv__ZN1S3f12Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4uv__ZN1S3f12Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8uv__ZN1S3f12Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeM16uv__ZN1S3f12Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } + +// { dg-final { scan-assembler-times "_ZGVbN4ul__ZN1S3f13Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4ul__ZN1S3f13Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8ul__ZN1S3f13Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVeN16ul__ZN1S3f13Ei:" 1 { target { i?86-*-* x86_64-*-* } } } } + +int +f14 (S &p, int x) +{ + return p.f13 (x); +} diff --git a/gcc/testsuite/g++.dg/gomp/attrs-21.C b/gcc/testsuite/g++.dg/gomp/attrs-21.C new file mode 100644 index 0000000..46bdef2 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/attrs-21.C @@ -0,0 +1,27 @@ +// { dg-do compile { target c++11 } } + +void +foo () +{ + [[omp::decl]] int v1; // { dg-error "'omp::decl' attribute requires argument" } + [[omp::decl ()]] int v2; // { dg-error "expected OpenMP directive name" } + // { dg-error "'omp::directive' not allowed to be specified in this context" "" { target *-*-* } .-1 } + [[omp::decl (nonexistent foobar)]] int v3; // { dg-error "unknown OpenMP directive name in 'omp::decl' attribute argument" } + // { dg-error "'omp::decl' not allowed to be specified in this context" "" { target *-*-* } .-1 } + [[omp::sequence(decl(threadprivate))]] int v4; // { dg-error "expected 'directive' or 'sequence'" } + // { dg-error "'omp::directive' not allowed to be specified in this context" "" { target *-*-* } .-1 } + [[omp::sequence(omp::decl(threadprivate))]] int v5; // { dg-error "expected 'directive' or 'sequence'" } + // { dg-error "'omp::directive' not allowed to be specified in this context" "" { target *-*-* } .-1 } + [[omp::decl (barrier)]]; // { dg-error "OpenMP 'omp::decl' attribute on a statement" } + [[omp::decl (parallel)]] {}; // { dg-error "OpenMP 'omp::decl' attribute on a statement" } + extern int [[omp::decl (threadprivate)]] *v6; // { dg-warning "attribute ignored" } + [[omp::decl (threadprivate (v5))]] static int v7; // { dg-error "expected end of line before '\\\(' token" } + extern int v8; + [[omp::decl (declare target (v8))]] static int v9; // { dg-error "expected end of line before '\\\(' token" } + [[omp::decl (declare target enter (v8))]] static int v10; // { dg-error "expected an OpenMP clause before '\\\(' token" } + [[omp::decl (declare target, link (v9))]] static int v11; // { dg-error "expected an OpenMP clause before '\\\(' token" } + [[omp::decl (declare target device_type (any))]] static int v12; // { dg-error "directive with only 'device_type' clause" } +} + +int i; +[[omp::decl (assume (i < 42))]]; // { dg-error "OpenMP 'omp::decl' attribute on a statement" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-f-MD.C b/gcc/testsuite/g++.dg/modules/depflags-f-MD.C new file mode 100644 index 0000000..2bd980c --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-f-MD.C @@ -0,0 +1,2 @@ +// { dg-additional-options -MD } +// { dg-additional-options -fdeps-format=p1689r5 } diff --git a/gcc/testsuite/g++.dg/modules/depflags-f.C b/gcc/testsuite/g++.dg/modules/depflags-f.C new file mode 100644 index 0000000..789b18f --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-f.C @@ -0,0 +1,3 @@ +// { dg-additional-options -fdeps-format=p1689r5 } + +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fi.C b/gcc/testsuite/g++.dg/modules/depflags-fi.C new file mode 100644 index 0000000..d8e75ad --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fi.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fdeps-format=invalid } + +// { dg-prune-output "error: '-fdeps-format=' unknown format 'invalid'" } +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fj-MD.C b/gcc/testsuite/g++.dg/modules/depflags-fj-MD.C new file mode 100644 index 0000000..3a94523 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fj-MD.C @@ -0,0 +1,3 @@ +// { dg-additional-options -MD } +// { dg-additional-options -fdeps-file=depflags-3.ddi } +// { dg-additional-options -fdeps-format=p1689r5 } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fj-MF-share.C b/gcc/testsuite/g++.dg/modules/depflags-fj-MF-share.C new file mode 100644 index 0000000..723014f --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fj-MF-share.C @@ -0,0 +1,6 @@ +// { dg-additional-options -MD } +// { dg-additional-options "-MF depflags-3.ddi" } +// { dg-additional-options -fdeps-file=depflags-3.ddi } +// { dg-additional-options -fdeps-format=p1689r5 } + +// { dg-prune-output "error: '-MF' and '-fdeps-file=' cannot share an output file" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fj.C b/gcc/testsuite/g++.dg/modules/depflags-fj.C new file mode 100644 index 0000000..063e0ee --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fj.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fdeps-file=depflags-3.ddi } +// { dg-additional-options -fdeps-format=p1689r5 } + +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fjo-MD.C b/gcc/testsuite/g++.dg/modules/depflags-fjo-MD.C new file mode 100644 index 0000000..84da337 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fjo-MD.C @@ -0,0 +1,4 @@ +// { dg-additional-options -MD } +// { dg-additional-options -fdeps-file=depflags-3.ddi } +// { dg-additional-options -fdeps-target=depflags-1.C } +// { dg-additional-options -fdeps-format=p1689r5 } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fjo.C b/gcc/testsuite/g++.dg/modules/depflags-fjo.C new file mode 100644 index 0000000..760d8f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fjo.C @@ -0,0 +1,5 @@ +// { dg-additional-options -fdeps-file=depflags-3.ddi } +// { dg-additional-options -fdeps-target=depflags-1.C } +// { dg-additional-options -fdeps-format=p1689r5 } + +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fo-MD.C b/gcc/testsuite/g++.dg/modules/depflags-fo-MD.C new file mode 100644 index 0000000..6da03f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fo-MD.C @@ -0,0 +1,3 @@ +// { dg-additional-options -MD } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=depflags-1.C } diff --git a/gcc/testsuite/g++.dg/modules/depflags-fo.C b/gcc/testsuite/g++.dg/modules/depflags-fo.C new file mode 100644 index 0000000..5deb27a --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-fo.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=depflags-1.C } + +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-j-MD.C b/gcc/testsuite/g++.dg/modules/depflags-j-MD.C new file mode 100644 index 0000000..92a2af6 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-j-MD.C @@ -0,0 +1,2 @@ +// { dg-additional-options -MD } +// { dg-additional-options -fdeps-file=depflags-3.ddi } diff --git a/gcc/testsuite/g++.dg/modules/depflags-j.C b/gcc/testsuite/g++.dg/modules/depflags-j.C new file mode 100644 index 0000000..2eb5890 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-j.C @@ -0,0 +1,3 @@ +// { dg-additional-options -fdeps-file=depflags-3.ddi } + +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-jo-MD.C b/gcc/testsuite/g++.dg/modules/depflags-jo-MD.C new file mode 100644 index 0000000..ba2b21e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-jo-MD.C @@ -0,0 +1,3 @@ +// { dg-additional-options -MD } +// { dg-additional-options -fdeps-file=depflags-3.ddi } +// { dg-additional-options -fdeps-target=depflags-1.C } diff --git a/gcc/testsuite/g++.dg/modules/depflags-jo.C b/gcc/testsuite/g++.dg/modules/depflags-jo.C new file mode 100644 index 0000000..a015d35 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-jo.C @@ -0,0 +1,4 @@ +// { dg-additional-options -fdeps-file=depflags-3.ddi } +// { dg-additional-options -fdeps-target=depflags-1.C } + +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depflags-o-MD.C b/gcc/testsuite/g++.dg/modules/depflags-o-MD.C new file mode 100644 index 0000000..1b67558 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-o-MD.C @@ -0,0 +1,2 @@ +// { dg-additional-options -MD } +// { dg-additional-options -fdeps-target=depflags-1.C } diff --git a/gcc/testsuite/g++.dg/modules/depflags-o.C b/gcc/testsuite/g++.dg/modules/depflags-o.C new file mode 100644 index 0000000..38d6450 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depflags-o.C @@ -0,0 +1,3 @@ +// { dg-additional-options -fdeps-target=depflags-1.C } + +// { dg-prune-output "error: to generate dependencies you must specify either '-M' or '-MM'" } diff --git a/gcc/testsuite/g++.dg/modules/depreport-1_a.C b/gcc/testsuite/g++.dg/modules/depreport-1_a.C new file mode 100644 index 0000000..2417017 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depreport-1_a.C @@ -0,0 +1,10 @@ +// { dg-additional-options -fmodules-ts } + +export module Foo; +// { dg-module-cmi Foo } + +export class Base +{ +public: + int m; +}; diff --git a/gcc/testsuite/g++.dg/modules/depreport-1_b.C b/gcc/testsuite/g++.dg/modules/depreport-1_b.C new file mode 100644 index 0000000..b6e317c --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depreport-1_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -MD } +// { dg-additional-options "-MF depreport-1.d" } + +import Foo; + +void foo () +{ + Base b; +} + +// { dg-final { run-check-module-dep-expect-input "depreport-1.d" "gcm.cache/Foo.gcm" } } diff --git a/gcc/testsuite/g++.dg/modules/depreport-2.modmap b/gcc/testsuite/g++.dg/modules/depreport-2.modmap new file mode 100644 index 0000000..ff271df --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depreport-2.modmap @@ -0,0 +1,2 @@ +$root . +Foo Foo.gcm diff --git a/gcc/testsuite/g++.dg/modules/depreport-2_a.C b/gcc/testsuite/g++.dg/modules/depreport-2_a.C new file mode 100644 index 0000000..6912de1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depreport-2_a.C @@ -0,0 +1,15 @@ +// { dg-do preprocess } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fmodule-mapper=[srcdir]/depreport-2.modmap } +// { dg-additional-options -MD } +// { dg-additional-options "-MF depreport-2_a.d" } + +export module Foo; + +export class Base +{ +public: + int m; +}; + +// { dg-final { run-check-module-dep-expect-input "depreport-2_a.d" "[srcdir]/depreport-2.modmap" } } diff --git a/gcc/testsuite/g++.dg/modules/depreport-2_b.C b/gcc/testsuite/g++.dg/modules/depreport-2_b.C new file mode 100644 index 0000000..d94d6a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/depreport-2_b.C @@ -0,0 +1,14 @@ +// { dg-do preprocess } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fmodule-mapper=[srcdir]/depreport-2.modmap } +// { dg-additional-options -MD } +// { dg-additional-options "-MF depreport-2_b.d" } + +import Foo; + +void foo () +{ + Base b; +} + +// { dg-final { run-check-module-dep-expect-input "depreport-2_b.d" "[srcdir]/depreport-2.modmap" } } diff --git a/gcc/testsuite/g++.dg/modules/modules.exp b/gcc/testsuite/g++.dg/modules/modules.exp index dc302d3..b692954 100644 --- a/gcc/testsuite/g++.dg/modules/modules.exp +++ b/gcc/testsuite/g++.dg/modules/modules.exp @@ -28,6 +28,7 @@ # { dg-module-do [link|run] [xfail] [options] } # link [and run] load_lib g++-dg.exp +load_lib modules.exp # If a testcase doesn't have special options, use these. global DEFAULT_CXXFLAGS diff --git a/gcc/testsuite/g++.dg/modules/p1689-1.C b/gcc/testsuite/g++.dg/modules/p1689-1.C new file mode 100644 index 0000000..3c138c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-1.C @@ -0,0 +1,17 @@ +// { dg-additional-options -E } +// { dg-additional-options "-MT p1689-1.ddi" } +// { dg-additional-options -MD } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=p1689-1.o } +// { dg-additional-options -fdeps-file=p1689-1.ddi } + +// Export a module that uses modules, re-exports modules, and partitions. + +export module foo; +export import foo:part1; +import foo:part2; + +export import bar; + +// { dg-final { run-check-p1689-valid p1689-1.ddi p1689-1.exp.ddi } } diff --git a/gcc/testsuite/g++.dg/modules/p1689-1.exp.ddi b/gcc/testsuite/g++.dg/modules/p1689-1.exp.ddi new file mode 100644 index 0000000..c5648ac --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-1.exp.ddi @@ -0,0 +1,27 @@ +{ + "rules": [ + { + "primary-output": "p1689-1.o", + "provides": [ + { + "logical-name": "foo", + "is-interface": true + } + ], + "requires": [ + "__P1689_unordered__", + { + "logical-name": "bar" + }, + { + "logical-name": "foo:part1" + }, + { + "logical-name": "foo:part2" + } + ] + } + ], + "version": 0, + "revision": 0 +} diff --git a/gcc/testsuite/g++.dg/modules/p1689-2.C b/gcc/testsuite/g++.dg/modules/p1689-2.C new file mode 100644 index 0000000..5d7fe52 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-2.C @@ -0,0 +1,15 @@ +// { dg-additional-options -E } +// { dg-additional-options "-MT p1689-2.ddi" } +// { dg-additional-options -MD } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=p1689-2.o } +// { dg-additional-options -fdeps-file=p1689-2.ddi } + +// Export a module partition that uses modules. + +export module foo:part1; + +#include <iostream> + +// { dg-final { run-check-p1689-valid p1689-2.ddi p1689-2.exp.ddi } } diff --git a/gcc/testsuite/g++.dg/modules/p1689-2.exp.ddi b/gcc/testsuite/g++.dg/modules/p1689-2.exp.ddi new file mode 100644 index 0000000..6901172 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-2.exp.ddi @@ -0,0 +1,16 @@ +{ + "rules": [ + { + "primary-output": "p1689-2.o", + "provides": [ + { + "logical-name": "foo:part1", + "is-interface": true + } + ], + "requires": [] + } + ], + "version": 0, + "revision": 0 +} diff --git a/gcc/testsuite/g++.dg/modules/p1689-3.C b/gcc/testsuite/g++.dg/modules/p1689-3.C new file mode 100644 index 0000000..6c0aced --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-3.C @@ -0,0 +1,13 @@ +// { dg-additional-options -E } +// { dg-additional-options "-MT p1689-3.ddi" } +// { dg-additional-options -MD } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=p1689-3.o } +// { dg-additional-options -fdeps-file=p1689-3.ddi } + +// Provide a module partition. + +module foo:part2; + +// { dg-final { run-check-p1689-valid p1689-3.ddi p1689-3.exp.ddi } } diff --git a/gcc/testsuite/g++.dg/modules/p1689-3.exp.ddi b/gcc/testsuite/g++.dg/modules/p1689-3.exp.ddi new file mode 100644 index 0000000..5a40bea --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-3.exp.ddi @@ -0,0 +1,16 @@ +{ + "rules": [ + { + "primary-output": "p1689-3.o", + "provides": [ + { + "logical-name": "foo:part2", + "is-interface": false + } + ], + "requires": [] + } + ], + "version": 0, + "revision": 0 +} diff --git a/gcc/testsuite/g++.dg/modules/p1689-4.C b/gcc/testsuite/g++.dg/modules/p1689-4.C new file mode 100644 index 0000000..922f015 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-4.C @@ -0,0 +1,13 @@ +// { dg-additional-options -E } +// { dg-additional-options "-MT p1689-4.ddi" } +// { dg-additional-options -MD } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=p1689-4.o } +// { dg-additional-options -fdeps-file=p1689-4.ddi } + +// Module implementation unit. + +module foo; + +// { dg-final { run-check-p1689-valid p1689-4.ddi p1689-4.exp.ddi } } diff --git a/gcc/testsuite/g++.dg/modules/p1689-4.exp.ddi b/gcc/testsuite/g++.dg/modules/p1689-4.exp.ddi new file mode 100644 index 0000000..b119f565 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-4.exp.ddi @@ -0,0 +1,14 @@ +{ + "rules": [ + { + "primary-output": "p1689-4.o", + "requires": [] + { + "logical-name": "foo" + } + ] + } + ], + "version": 0, + "revision": 0 +} diff --git a/gcc/testsuite/g++.dg/modules/p1689-5.C b/gcc/testsuite/g++.dg/modules/p1689-5.C new file mode 100644 index 0000000..94908bf --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-5.C @@ -0,0 +1,13 @@ +// { dg-additional-options -E } +// { dg-additional-options "-MT p1689-5.ddi" } +// { dg-additional-options -MD } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=p1689-5.o } +// { dg-additional-options -fdeps-file=p1689-5.ddi } + +// Use modules, don't provide anything. + +import bar; + +// { dg-final { run-check-p1689-valid p1689-5.ddi p1689-5.exp.ddi } } diff --git a/gcc/testsuite/g++.dg/modules/p1689-5.exp.ddi b/gcc/testsuite/g++.dg/modules/p1689-5.exp.ddi new file mode 100644 index 0000000..18704ac --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-5.exp.ddi @@ -0,0 +1,14 @@ +{ + "rules": [ + { + "primary-output": "p1689-5.o", + "requires": [ + { + "logical-name": "bar" + } + ] + } + ], + "version": 0, + "revision": 0 +} diff --git a/gcc/testsuite/g++.dg/modules/p1689-file-default.C b/gcc/testsuite/g++.dg/modules/p1689-file-default.C new file mode 100644 index 0000000..4e1f5bb --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-file-default.C @@ -0,0 +1,16 @@ +// { dg-additional-options -E } +// { dg-additional-options "-MT p1689-file-default.ddi" } +// { dg-additional-options -MD } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-target=p1689-file-default.o } + +// Scan without `-fdeps-file=` + +export module foo; +export import foo:part1; +import foo:part2; + +export import bar; + +// { dg-final { run-check-p1689-valid p1689-file-default.o.ddi p1689-file-default.exp.ddi } } diff --git a/gcc/testsuite/g++.dg/modules/p1689-file-default.exp.ddi b/gcc/testsuite/g++.dg/modules/p1689-file-default.exp.ddi new file mode 100644 index 0000000..187eab6 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-file-default.exp.ddi @@ -0,0 +1,27 @@ +{ + "rules": [ + { + "primary-output": "p1689-file-default.o", + "provides": [ + { + "logical-name": "foo", + "is-interface": true + } + ], + "requires": [ + "__P1689_unordered__", + { + "logical-name": "bar" + }, + { + "logical-name": "foo:part1" + }, + { + "logical-name": "foo:part2" + } + ] + } + ], + "version": 0, + "revision": 0 +} diff --git a/gcc/testsuite/g++.dg/modules/p1689-target-default.C b/gcc/testsuite/g++.dg/modules/p1689-target-default.C new file mode 100644 index 0000000..67088ed --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-target-default.C @@ -0,0 +1,16 @@ +// { dg-additional-options -E } +// { dg-additional-options "-MT p1689-target-default.ddi" } +// { dg-additional-options -MD } +// { dg-additional-options -fmodules-ts } +// { dg-additional-options -fdeps-format=p1689r5 } +// { dg-additional-options -fdeps-file=p1689-target-default.ddi } + +// Scan without `-fdeps-target=` + +export module foo; +export import foo:part1; +import foo:part2; + +export import bar; + +// { dg-final { run-check-p1689-valid p1689-target-default.ddi p1689-target-default.exp.ddi } } diff --git a/gcc/testsuite/g++.dg/modules/p1689-target-default.exp.ddi b/gcc/testsuite/g++.dg/modules/p1689-target-default.exp.ddi new file mode 100644 index 0000000..dd3d9c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/p1689-target-default.exp.ddi @@ -0,0 +1,27 @@ +{ + "rules": [ + { + "primary-output": "p1689-target-default.o", + "provides": [ + { + "logical-name": "foo", + "is-interface": true + } + ], + "requires": [ + "__P1689_unordered__", + { + "logical-name": "bar" + }, + { + "logical-name": "foo:part1" + }, + { + "logical-name": "foo:part2" + } + ] + } + ], + "version": 0, + "revision": 0 +} diff --git a/gcc/testsuite/g++.dg/modules/test-depfile.py b/gcc/testsuite/g++.dg/modules/test-depfile.py new file mode 100644 index 0000000..9693c05 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/test-depfile.py @@ -0,0 +1,207 @@ +import json + + +# Parameters. +ALL_ERRORS = False + + +def _report_error(msg): + '''Report an error.''' + full_msg = 'ERROR: ' + msg + if ALL_ERRORS: + print(full_msg) + else: + raise RuntimeError(full_msg) + + +class Token(object): + pass + + +class Output(Token): + def __init__(self, path): + self.path = path + + +class Input(Token): + def __init__(self, path): + self.path = path + + +class OrderInput(Token): + def __init__(self, path): + self.path = path + + +class Colon(Token): + pass + + +class Append(Token): + pass + + +class Variable(Token): + def __init__(self, name): + self.name = name + + +class Word(Token): + def __init__(self, name): + self.name = name + + +def validate_depfile(depfile, expect_input=None): + '''Validate a depfile contains some information + + Returns `False` if the information is not found. + ''' + with open(depfile, 'r') as fin: + depfile_content = fin.read() + + real_lines = [] + join_line = False + for line in depfile_content.split('\n'): + # Join the line if needed. + if join_line: + line = real_lines.pop() + line + + # Detect line continuations. + join_line = line.endswith('\\') + # Strip line continuation characters. + if join_line: + line = line[:-1] + + # Add to the real line set. + real_lines.append(line) + + # Perform tokenization. + tokenized_lines = [] + for line in real_lines: + tokenized = [] + join_word = False + for word in line.split(' '): + if join_word: + word = tokenized.pop() + ' ' + word + + # Detect word joins. + join_word = word.endswith('\\') + # Strip escape character. + if join_word: + word = word[:-1] + + # Detect `:` at the end of a word. + if word.endswith(':'): + tokenized.append(word[:-1]) + word = word[-1] + # Detect `:` at the end of a word. + if word.endswith(':|'): + tokenized.append(word[:-2]) + word = word[-2] + + # Add word to the tokenized set. + tokenized.append(word) + + tokenized_lines.append(tokenized) + + # Parse. + ast = [] + for line in tokenized_lines: + kind = None + for token in line: + if token == ':': + kind = 'dependency' + elif token == '+=': + kind = 'append' + elif token == ':|': + kind = 'order-only' + if line == ['']: + kind = 'empty' + + if kind is None: + _report_error('unknown line kind: %s' % line) + + line_parse = [] + if kind == 'dependency': + after_colon = False + for token in line: + if token == ':': + after_colon = True + elif after_colon: + line_parse.append(Input(token)) + else: + line_parse.append(Output(token)) + elif kind == 'order-only': + after_op = False + for token in line: + if token == ':|': + after_op = True + elif after_op: + line_parse.append(OrderInput(token)) + else: + line_parse.append(Output(token)) + elif kind == 'append': + after_op = False + for token in line: + if token == '+=': + after_op = True + elif after_op: + line_parse.append(Word(token)) + else: + line_parse.append(Variable(token)) + + ast.append(line_parse) + + for node in ast: + for token in node: + if expect_input is not None: + # If the input is found, clear the expectation. + if isinstance(token, Input) and token.path == expect_input: + expect_input = None + + result = True + if expect_input: + _report_error('missing input: %s' % expect_input) + result = False + + return result + + +if __name__ == '__main__': + import sys + + depfile = None + have_expect = False + expect_input = None + + # Parse arguments. + args = sys.argv[1:] + while args: + # Take an argument. + arg = args.pop(0) + + # Flag to change how errors are reported. + if arg == '-A' or arg == '--all': + ALL_ERRORS = True + # Required arguments. + elif arg == '-d' or arg == '--depfile': + depfile = args.pop(0) + elif arg == '-i' or arg == '--expect-input': + expect_input = args.pop(0) + have_expect = True + + # Validate that we have the required arguments. + if depfile is None: + raise RuntimeError('missing "depfile" file') + if have_expect is None: + raise RuntimeError('missing an "expect" argument') + + # Do the actual work. + try: + is_ok = validate_depfile(depfile, expect_input=expect_input) + except BaseException as e: + _report_error('exception: %s' % e) + + # Fail if errors are found. + if not is_ok: + sys.exit(1) diff --git a/gcc/testsuite/g++.dg/modules/test-p1689.py b/gcc/testsuite/g++.dg/modules/test-p1689.py new file mode 100644 index 0000000..2f07cc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/test-p1689.py @@ -0,0 +1,222 @@ +import json + + +# Parameters. +ALL_ERRORS = False +REPLACEMENTS = {} + + +def _print_path(path): + '''Format a JSON path for output.''' + return '/'.join(path) + + +def _report_error(msg): + '''Report an error.''' + full_msg = 'ERROR: ' + msg + if ALL_ERRORS: + print(full_msg) + else: + raise RuntimeError(full_msg) + + +def _error_type_mismatch(path, actual, expect): + '''Report that there is a type mismatch.''' + _report_error('type mismatch at %s: actual: "%s" expect: "%s"' % (_print_path(path), actual, expect)) + + +def _error_unknown_type(path, typ): + '''Report that there is an unknown type in the JSON object.''' + _report_error('unknown type at %s: "%s"' % (_print_path(path), typ)) + + +def _error_length_mismatch(path, actual, expect): + '''Report a length mismatch in an object or array.''' + _report_error('length mismatch at %s: actual: "%s" expect: "%s"' % (_print_path(path), actual, expect)) + + +def _error_unexpect_value(path, actual, expect): + '''Report a value mismatch.''' + _report_error('value mismatch at %s: actual: "%s" expect: "%s"' % (_print_path(path), actual, expect)) + + +def _error_extra_key(path, key): + '''Report on a key that is unexpected.''' + _report_error('extra key at %s: "%s"' % (_print_path(path), key)) + + +def _error_missing_key(path, key): + '''Report on a key that is missing.''' + _report_error('extra key at %s: %s' % (_print_path(path), key)) + + +def _compare_object(path, actual, expect): + '''Compare a JSON object.''' + is_ok = True + + if not len(actual) == len(expect): + _error_length_mismatch(path, len(actual), len(expect)) + is_ok = False + + for key in actual: + if key not in expect: + _error_extra_key(path, key) + is_ok = False + else: + sub_error = compare_json(path + [key], actual[key], expect[key]) + if sub_error: + is_ok = False + + for key in expect: + if key not in actual: + _error_missing_key(path, key) + is_ok = False + + return is_ok + + +def _compare_array(path, actual, expect): + '''Compare a JSON array.''' + is_ok = True + + if not len(actual) == len(expect): + _error_length_mismatch(path, len(actual), len(expect)) + is_ok = False + + for (idx, (a, e)) in enumerate(zip(actual, expect)): + sub_error = compare_json(path + [str(idx)], a, e) + if sub_error: + is_ok = False + + return is_ok + + +def _make_replacements(value): + for (old, new) in REPLACEMENTS.values(): + value = value.replace(old, new) + return value + + +def _compare_string(path, actual, expect): + '''Compare a JSON string supporting replacements in the expected output.''' + expect = _make_replacements(expect) + + if not actual == expect: + _error_unexpect_value(path, actual, expect) + return False + else: + print('%s is ok: %s' % (_print_path(path), actual)) + return True + + +def _compare_number(path, actual, expect): + '''Compare a JSON integer.''' + if not actual == expect: + _error_unexpect_value(path, actual, expect) + return False + else: + print('%s is ok: %s' % (_print_path(path), actual)) + return True + + +def _inspect_ordering(arr): + req_ordering = True + + if not arr: + return arr, req_ordering + + if arr[0] == '__P1689_unordered__': + arr.pop(0) + req_ordering = False + + return arr, req_ordering + + +def compare_json(path, actual, expect): + actual_type = type(actual) + expect_type = type(expect) + + is_ok = True + + if not actual_type == expect_type: + _error_type_mismatch(path, actual_type, expect_type) + is_ok = False + elif actual_type == dict: + is_ok = _compare_object(path, actual, expect) + elif actual_type == list: + expect, req_ordering = _inspect_ordering(expect) + if not req_ordering: + actual = set(actual) + expect = set(expect) + is_ok = _compare_array(path, actual, expect) + elif actual_type == str: + is_ok = _compare_string(path, actual, expect) + elif actual_type == float: + is_ok = _compare_number(path, actual, expect) + elif actual_type == int: + is_ok = _compare_number(path, actual, expect) + elif actual_type == bool: + is_ok = _compare_number(path, actual, expect) + elif actual_type == type(None): + pass + else: + _error_unknown_type(path, actual_type) + is_ok = False + + return is_ok + + +def validate_p1689(actual, expect): + '''Validate a P1689 file against an expected output file. + + Returns `False` if it fails, `True` if they are the same. + ''' + with open(actual, 'r') as fin: + actual_content = fin.read() + with open(expect, 'r') as fin: + expect_content = fin.read() + + actual_json = json.loads(actual_content) + expect_json = json.loads(expect_content) + + return compare_json([], actual_json, expect_json) + + +if __name__ == '__main__': + import sys + + actual = None + expect = None + + # Parse arguments. + args = sys.argv[1:] + while args: + # Take an argument. + arg = args.pop(0) + + # Parse out replacement expressions. + if arg == '-r' or arg == '--replace': + replacement = args.pop(0) + (key, value) = replacement.split('=', maxsplit=1) + REPLACEMENTS[key] = value + # Flag to change how errors are reported. + elif arg == '-A' or arg == '--all': + ALL_ERRORS = True + # Required arguments. + elif arg == '-a' or arg == '--actual': + actual = args.pop(0) + elif arg == '-e' or arg == '--expect': + expect = args.pop(0) + + # Validate that we have the required arguments. + if actual is None: + raise RuntimeError('missing "actual" file') + if expect is None: + raise RuntimeError('missing "expect" file') + + # Do the actual work. + is_ok = validate_p1689(actual, expect) + + # Fail if errors are found. + if not is_ok: + sys.exit(1) diff --git a/gcc/testsuite/g++.dg/overload/template5.C b/gcc/testsuite/g++.dg/overload/template5.C index 9026840..932c13b 100644 --- a/gcc/testsuite/g++.dg/overload/template5.C +++ b/gcc/testsuite/g++.dg/overload/template5.C @@ -2,14 +2,14 @@ template<typename T> int low(T a, T b, T c) { return a + b + c; } // { dg-message "template" } +// { dg-message "(candidate|3 arguments, 2 provided)" "" { target *-*-* } .-1 } template<typename T> int high(T a, T b, T c) { return a + b + c; } // { dg-message "template" } +// { dg-message "(candidate|3 arguments, 4 provided)" "" { target *-*-* } .-1 } void test (void) { low (5, 6); // { dg-error "no matching function" } - // { dg-message "(candidate|3 arguments, 2 provided)" "" { target *-*-* } .-1 } high (5, 6, 7, 8); // { dg-error "no matching function" } - // { dg-message "(candidate|3 arguments, 4 provided)" "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/g++.dg/pr110249.C b/gcc/testsuite/g++.dg/pr110249.C new file mode 100644 index 0000000..2b73761 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr110249.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1-alias" } */ + +#include <stdint.h> +#include <string.h> + +uint64_t read64r(const uint64_t &x) { + if ((uint64_t) &x % 8 ) { + __builtin_unreachable(); + } + uint64_t value; + memcpy( &value, &x, sizeof(uint64_t) ); + return value; +} + +/* { dg-final { scan-tree-dump "fff8" "vrp1" } } */ diff --git a/gcc/testsuite/g++.dg/template/conv20.C b/gcc/testsuite/g++.dg/template/conv20.C new file mode 100644 index 0000000..202549a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv20.C @@ -0,0 +1,17 @@ +// Verify we check arity early before deduction without explicit +// template arguments. + +template<class T> +struct A; + +template<class T> +struct B : A<T> { }; + +template<class T> void f(A<T>&, int); // #1 +template<class T> void f(B<T>&); // #2 + +int main() { + extern B<int> b; + ::f(b); // OK, deduction for #1 short-circuited and B<int> not instantiated, + // which would have resulted in a hard error +} diff --git a/gcc/testsuite/g++.dg/template/init7.C b/gcc/testsuite/g++.dg/template/init7.C index bb26c8f..94fc22f 100644 --- a/gcc/testsuite/g++.dg/template/init7.C +++ b/gcc/testsuite/g++.dg/template/init7.C @@ -6,4 +6,4 @@ template<typename> struct A static const int i=0; }; -template<typename T> const int A<T>::i = 0=0; /* { dg-error "duplicate initialization" } */ +template<typename T> const int A<T>::i = T()=0; /* { dg-error "duplicate initialization" } */ diff --git a/gcc/testsuite/g++.dg/template/local6.C b/gcc/testsuite/g++.dg/template/local6.C index 94c19be..d8ca5aa 100644 --- a/gcc/testsuite/g++.dg/template/local6.C +++ b/gcc/testsuite/g++.dg/template/local6.C @@ -1,11 +1,11 @@ template <class T> struct PCVector2 // { dg-message "note" } { - template <class T2> PCVector2(const PCVector2<T> &cv) ; // { dg-message "note" } + template <class T2> PCVector2(const PCVector2<T> &cv) ; // { dg-message "candidate:" } + // { dg-message "(candidate|expects 1 argument, 2 provided|cannot convert)" "candidate note" { target *-*-* } .-1 } PCVector2<T> operator- (const PCVector2<T> &ov) const { return PCVector2<T>(ov.xFIELD, ov.yFIELD); // { dg-error "matching" } - // { dg-message "(candidate|expects 1 argument, 2 provided|cannot convert)" "candidate note" { target *-*-* } .-1 } } T xFIELD, yFIELD; diff --git a/gcc/testsuite/g++.dg/template/non-dependent26.C b/gcc/testsuite/g++.dg/template/non-dependent26.C new file mode 100644 index 0000000..1faa39a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent26.C @@ -0,0 +1,25 @@ +// Verify non-dependent assignment expressions are recognized as such +// and are checked ahead of time. +// PR c++/63198 +// { dg-do compile { target c++11 } } + +struct X { using t1 = int; }; +struct Y { X operator=(const Y&); } y; +template<class T> void f1(decltype(y = y)::t1); + +int n; +template<class T> void f2(decltype(n = n)::t1); // { dg-error "not a class" } +template<class T> void f3(decltype(n += n)::t1); // { dg-error "not a class" } + +template<class T> +void g() { + const int n; + n = 42; // { dg-error "read-only" } + + const X x; + x = {}; // { dg-error "no match" } + + const Y y; + y = {}; // { dg-error "no match" } + Y{} = X{}; // { dg-error "no match" } +} diff --git a/gcc/testsuite/g++.dg/template/recurse3.C b/gcc/testsuite/g++.dg/template/recurse3.C index f1db7c5..70c6152 100644 --- a/gcc/testsuite/g++.dg/template/recurse3.C +++ b/gcc/testsuite/g++.dg/template/recurse3.C @@ -1,14 +1,14 @@ // PR c++/44609 // { dg-options -ftemplate-depth=10 } -template<int N> +template<class T, int N> void f() { - 0 = 0; // { dg-error "lvalue required" } - f<N+1>(); // { dg-bogus "instantiation depth" } + T(0) = 0; // { dg-error "lvalue required" } + f<T, N+1>(); // { dg-bogus "instantiation depth" } } int main() { - f<0>(); + f<int, 0>(); } diff --git a/gcc/testsuite/g++.dg/template/ttp40.C b/gcc/testsuite/g++.dg/template/ttp40.C new file mode 100644 index 0000000..9d68b9e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp40.C @@ -0,0 +1,25 @@ +// Verify we check arity early before deduction without explicit +// template arguments. +// PR c++/84075 + +template<class T> +struct trait { + static const int value = T::value; // { dg-bogus "not a member of 'B'" } +}; + +template<class T, int N = trait<T>::value> +struct A { }; + +template<class T> +void f(A<T, 42>, int); // #1 + +struct B { }; + +template<template<class> class TT> +void f(TT<B>); // #2 + +int main() { + A<int, 42> a; + f(a, 0); // OK, deduction for #2 short-circuited and A<B> not specialized, + // which would have resulted in a hard error +} diff --git a/gcc/testsuite/g++.dg/template/ttp41.C b/gcc/testsuite/g++.dg/template/ttp41.C new file mode 100644 index 0000000..c81e5dd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp41.C @@ -0,0 +1,17 @@ +// PR c++/108347 + +template<class T> +struct A { + template<class U> struct C { }; + + template<template<class> class TT, class U> + struct B; + + template<class U> + struct B<C, U*>; + + template<class U> + struct B<C, const U*> { }; +}; + +A<int>::B<A<int>::C, const int*> b; diff --git a/gcc/testsuite/g++.dg/torture/pr111465.C b/gcc/testsuite/g++.dg/torture/pr111465.C new file mode 100644 index 0000000..8f2577a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr111465.C @@ -0,0 +1,55 @@ +// { dg-do compile } +// { dg-additional-options "-fno-exceptions --param=logical-op-non-short-circuit=0" } + +typedef unsigned int location_t; +const location_t MAX_LOCATION_T = 0x7FFFFFFF; +struct line_maps { + unsigned int info_ordinary; + location_t *maps; + unsigned int used; + location_t *data; +}; +inline location_t LINEMAPS_MACRO_LOWEST_LOCATION(const line_maps *set) { + return set->used + ? set->maps[set->used - 1] + : MAX_LOCATION_T + 1; +} +const location_t *linemap_lookup(const line_maps *set, location_t line) { + int mn = set->info_ordinary; + if (mn >= 0) + if ((unsigned int)mn < set->used) + return &set->maps[0]; + __builtin_unreachable(); +} +bool linemap_location_from_macro_expansion_p(const class line_maps *set, + location_t location) { + if (location > MAX_LOCATION_T) + location = set->data[location & MAX_LOCATION_T]; + return location >= LINEMAPS_MACRO_LOWEST_LOCATION(set); +} +void first_map_in_common_1(line_maps *set, location_t *loc0, + location_t *loc1) { + linemap_lookup(set, 0); + __builtin_unreachable(); +} +int linemap_compare_locations(line_maps *set, location_t pre, location_t post) { + bool pre_virtual_p; + location_t l0 = pre, l1 = post; + if (l0 > MAX_LOCATION_T) + l0 = set->data[l0 & MAX_LOCATION_T]; + if (l1 > MAX_LOCATION_T) + l1 = set->data[l1 & MAX_LOCATION_T];; + if (l0 == l1) + return 0; + if ((pre_virtual_p = linemap_location_from_macro_expansion_p(set, l0))) + l0 = set->data[l0 & MAX_LOCATION_T]; + if (linemap_location_from_macro_expansion_p(set, l1)) + l1 = set->data[l1 & MAX_LOCATION_T]; + if (l0 == l1) + if (pre_virtual_p) + first_map_in_common_1(set, &l0, &l1); + if (l0 > MAX_LOCATION_T) + if (l1 > MAX_LOCATION_T) + l1 = set->data[l1 & MAX_LOCATION_T]; + return l1 - l0; +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-32.C b/gcc/testsuite/g++.dg/warn/Wparentheses-32.C new file mode 100644 index 0000000..719a9d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-32.C @@ -0,0 +1,28 @@ +// Verify we issue -Wparentheses warnings at template definition time +// (for suitable non-dependent expressions). +// { dg-additional-options "-Wparentheses" } + +struct X { operator bool(); }; +struct Y { Y& operator=(const Y&); operator bool(); }; +struct Z { int m; operator bool(); }; + +template<class T> +void f() { + int n, m; + if (n = m) { } // { dg-warning "parentheses" } + + X x1, x2; + if (x1 = x2) { } // { dg-warning "parentheses" } + + Y y1, y2; + if (y1 = y2) { } // { dg-warning "parentheses" } + + Z z1, z2; + if (z1 = z2) { } // { dg-warning "parentheses" } + + bool b; + b = m = n; // { dg-warning "parentheses" "" { xfail *-*-* } } + b = x1 = x2; // { dg-warning "parentheses" "" { xfail *-*-* } } + b = y1 = y2; // { dg-warning "parentheses" "" { xfail *-*-* } } + b = z1 = z2; // { dg-warning "parentheses" "" { xfail *-*-* } } +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111435-1.c b/gcc/testsuite/gcc.c-torture/compile/pr111435-1.c new file mode 100644 index 0000000..afa84dd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr111435-1.c @@ -0,0 +1,18 @@ +/* { dg-options "-fexceptions -fno-early-inlining" } */ +/* { dg-require-effective-target exceptions } */ + +void find_slot_with_hash(const int *); + +void put(const int *k, const int *) { + find_slot_with_hash(k); +} +unsigned len(); +int *address(); +void h(int header, int **bounds) { + if (!*bounds) + return; + unsigned t = *bounds ? len() : 0; + int queue_index = t; + address()[(unsigned)queue_index] = 0; + put(&header, &queue_index); +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111442-1.c b/gcc/testsuite/gcc.c-torture/compile/pr111442-1.c new file mode 100644 index 0000000..5814ee9 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr111442-1.c @@ -0,0 +1,13 @@ + +int *a, b; +int main() { + int d = 1, e; + if (d) + e = a ? 0 % 0 : 0; + if (d) + a = &d; + d = -1; + b = d & e; + b = 2 * e ^ 1; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/builtin-classify-type-1.c b/gcc/testsuite/gcc.dg/builtin-classify-type-1.c new file mode 100644 index 0000000..2268c23 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-classify-type-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void +foo (int n) +{ + _Static_assert (__builtin_classify_type (enum E { E1, E2 }) == 3, ""); + _Static_assert (__builtin_classify_type (struct S { int s; }) == 12, ""); + _Static_assert (__builtin_classify_type (union U { int u; }) == 13, ""); + _Static_assert (__builtin_classify_type (int [2 * n + 36]) == 14, ""); +} diff --git a/gcc/testsuite/gcc.dg/gimplefe-50.c b/gcc/testsuite/gcc.dg/gimplefe-50.c new file mode 100644 index 0000000..63d228c --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-50.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +void __GIMPLE (ssa) +foo (float a, float b) +{ + _Bool x; + + __BB(2): + x_3 = a_1(D) __UNLT b_2(D); + x_4 = a_1(D) __UNLE b_2(D); + x_5 = a_1(D) __UNGT b_2(D); + x_6 = a_1(D) __UNGE b_2(D); + x_7 = a_1(D) __UNEQ b_2(D); + x_8 = a_1(D) __UNORDERED b_2(D); + x_9 = a_1(D) __ORDERED b_2(D); + x_10 = a_1(D) __LTGT b_2(D); + if (a_1(D) __UNEQ b_2(D)) + goto __BB4; + else + goto __BB3; + + __BB(3): + goto __BB4; + + __BB(4): + return; +} diff --git a/gcc/testsuite/gcc.dg/gimplefe-51.c b/gcc/testsuite/gcc.dg/gimplefe-51.c new file mode 100644 index 0000000..16e69c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-51.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +__PTRDIFF_TYPE__ __GIMPLE (ssa) +foo (void *p, void *q) +{ + __PTRDIFF_TYPE__ d; + + __BB(2): + d_3 = p_1(D) - q_2(D); + return d_3; +} diff --git a/gcc/testsuite/gcc.dg/pr110080.c b/gcc/testsuite/gcc.dg/pr110080.c new file mode 100644 index 0000000..c10afe0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110080.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +void foo(void); +static unsigned char a = 131; +static int *b; +static int **c = &b; +static void d(int e, unsigned f) { + int *g; + if (f != 131) { + __builtin_unreachable(); + } + if (!e){ + for (; a; ++a) + for (e = 0; 0;) + ; + g = &e; + int **h = &g; + if (**h) { + foo(); + } + } + *c = &e; +} +int main() { d(4 & a, a); } + +/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr111355.c b/gcc/testsuite/gcc.dg/pr111355.c new file mode 100644 index 0000000..7b522d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr111355.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Wno-div-by-zero" } */ + +/* Make sure no ICE. */ +int main() { + unsigned b; + return b ? 1 << --b / 0 : 0; +} diff --git a/gcc/testsuite/gcc.dg/pr111409.c b/gcc/testsuite/gcc.dg/pr111409.c new file mode 100644 index 0000000..1a79d81 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr111409.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-skip-if "split DWARF unsupported" { *-*-darwin* } } */ +/* { dg-options "-gsplit-dwarf -g3 -dA" } */ +/* { dg-final { scan-assembler-times {.section\s+.debug_macro} 1 } } */ +/* { dg-final { scan-assembler-not {.byte\s+0x7\s*#\s*Import} } } */ + +#define foo 1 diff --git a/gcc/testsuite/gcc.dg/pr93917.c b/gcc/testsuite/gcc.dg/pr93917.c index 41d27fb..f09e1c4 100644 --- a/gcc/testsuite/gcc.dg/pr93917.c +++ b/gcc/testsuite/gcc.dg/pr93917.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-vrp2" } */ void f3(int n); @@ -17,4 +17,7 @@ void f2(int*n) f3 (*n); } -/* { dg-final { scan-tree-dump-times "Global Exported" 2 "vrp1" } } */ +/* { dg-final { scan-tree-dump-times "Global Export.*0, \\+INF" 1 "vrp1" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_unreachable" 1 "vrp1" } } */ +/* { dg-final { scan-tree-dump-times "Global Export.*0, \\+INF" 1 "vrp2" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_unreachable" 0 "vrp2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr111303.c b/gcc/testsuite/gcc.dg/tree-ssa/pr111324.c index b703fe4..b703fe4 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr111303.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr111324.c diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-13.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-13.c new file mode 100644 index 0000000..f5a0164 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-13.c @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-options "-O2 -fno-thread-jumps -fdisable-tree-fre1 -fdump-tree-evrp-details" } + +void a(float, float); +void b(float, float); + +void foo(float x, float y) +{ + if (x != y) + a (x,y); + else if (x < y) + b (x,y); +} + +// Test that the false side of if(x != y) has a range for y. +// { dg-final { scan-tree-dump "2->4 \\(F\\) y_3\\(D\\)" "evrp" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-12.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-1.c index 0c9426d..0c9426d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-1.c diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-2.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-2.c new file mode 100644 index 0000000..76c9130 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-2.c @@ -0,0 +1,21 @@ +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-threadfull1-details" } + +void stuff(); + +void foo (float a, int cond) +{ + float x; + + if (cond) + x = a; + else + x = 8.0; + + /* We should be able to fold this as false on the path coming out of + cond == TRUE conditional. */ + if (x < a) + stuff(); +} + +// { dg-final { scan-tree-dump "Registering jump thread: \\(2, 4\\)" "threadfull1" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-3.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-3.c new file mode 100644 index 0000000..b7389f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-3.c @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-all-stats" } + +void stuff(); + +void foo (float a, int cond) +{ + float x; + + if (cond) + x = a; + else + x = 8.0; + + /* Even though on the BB2->BB4 path, x_1 and a_4 are equivalent, we cannot + fold x_1 == a_4 because of possible NANs: + + <bb 4> + # x_1 = PHI <a_4(D)(2), 8.0e+0(3)> + if (x_1 == a_4(D)) + */ + if (x == a) + stuff(); +} + +// { dg-final { scan-tree-dump-not "Jumps threaded" "threadfull1" } } +// { dg-final { scan-tree-dump-not "Jumps threaded" "threadfull2" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-4.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-4.c new file mode 100644 index 0000000..f38b305 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-4.c @@ -0,0 +1,38 @@ +// { dg-do compile } +// { dg-options "-O2 -fgimple -fdump-tree-threadfull1-details" } + +void stuff(); + +void __GIMPLE (ssa,startwith("threadfull1")) +foo (float a, float b, int cond) +{ + float x; + + __BB(2): + if (cond_3(D) != 0) + goto __BB4; + else + goto __BB3; + + __BB(3): + goto __BB4; + + /* We should be able to thread BB2->BB4->BB5 even though we have no knowledge + of the NANness of either x_1 or a_5. */ + __BB(4): + x_1 = __PHI (__BB2: a_5(D), __BB3: b_4(D)); + if (x_1 __UNEQ a_5(D)) + goto __BB5; + else + goto __BB6; + + __BB(5): + stuff (); + goto __BB6; + + __BB(6): + return; + +} + +// { dg-final { scan-tree-dump "Registering jump thread: \\(2, 4\\)" "threadfull1" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-5.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-5.c new file mode 100644 index 0000000..2bd06c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-5.c @@ -0,0 +1,54 @@ +// { dg-do compile } +// { dg-options "-O2 -fgimple -fdump-tree-evrp" } + +void link_error(); + +void __GIMPLE (ssa,startwith("evrp")) +foo1 (float x, float y) +{ + __BB(2): + if (x_4(D) <= y_5(D)) + goto __BB5; + else + goto __BB3; + + __BB(3): + // Relation at this point is VREL_GT. + if (x_4(D) __UNGE y_5(D)) + goto __BB5; + else + goto __BB4; + + __BB(4): + link_error (); + goto __BB5; + + __BB(5): + return; +} + +void __GIMPLE (ssa,startwith("evrp")) +foo2 (float x, float y) +{ + __BB(2): + if (x_4(D) <= y_5(D)) + goto __BB5; + else + goto __BB3; + + __BB(3): + // Relation at this point is VREL_GT. + if (x_4(D) __UNGT y_5(D)) + goto __BB5; + else + goto __BB4; + + __BB(4): + link_error (); + goto __BB5; + + __BB(5): + return; +} + +// { dg-final { scan-tree-dump-not "link_error" "evrp" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-6.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-6.c new file mode 100644 index 0000000..a75ae5d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-6.c @@ -0,0 +1,54 @@ +// { dg-do compile } +// { dg-options "-O2 -fgimple -fdump-tree-evrp" } + +void link_error(); + +void __GIMPLE (ssa,startwith("evrp")) +foo1 (float x, float y) +{ + __BB(2): + if (x_4(D) >= y_5(D)) + goto __BB5; + else + goto __BB3; + + __BB(3): + // Relation at this point is VREL_LT. + if (x_4(D) __UNLT y_5(D)) + goto __BB5; + else + goto __BB4; + + __BB(4): + link_error (); + goto __BB5; + + __BB(5): + return; +} + +void __GIMPLE (ssa,startwith("evrp")) +foo2 (float x, float y) +{ + __BB(2): + if (x_4(D) >= y_5(D)) + goto __BB5; + else + goto __BB3; + + __BB(3): + // Relation at this point is VREL_LT. + if (x_4(D) __UNLE y_5(D)) + goto __BB5; + else + goto __BB4; + + __BB(4): + link_error (); + goto __BB5; + + __BB(5): + return; +} + +// { dg-final { scan-tree-dump-not "link_error" "evrp" } } diff --git a/gcc/testsuite/gcc.dg/uninit-pr111489.c b/gcc/testsuite/gcc.dg/uninit-pr111489.c new file mode 100644 index 0000000..1b3eb65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr111489.c @@ -0,0 +1,112 @@ +/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef struct
+{
+ uint16_t pgv1_size;
+ uint16_t pgv1_flags1;
+ uint16_t pgv1_flags2;
+ uint16_t pgv1_flags3;
+ uint16_t pgv1_nslots;
+ uint32_t pgv1_generic;
+} page_v1_t;
+
+typedef struct
+{
+ page_v1_t pgv2_hdr;
+ int64_t pgv2_next;
+ int64_t pgv2_prev;
+} page_v2_t;
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ uint16_t pgv0_size;
+ uint16_t pgv0_flags;
+ };
+ uint32_t pgv0_nslots;
+ };
+ uint32_t pgv0_mode;
+ uint32_t pgv0_next;
+} page_v0_t;
+
+typedef struct
+{
+ uint16_t sl4_off;
+ uint16_t sl4_len;
+} slot4_t;
+
+typedef struct
+{
+ uint32_t sl8_off;
+ uint32_t sl8_len;
+} slot8_t;
+extern int64_t cur_rowid;
+
+extern uint8_t *pg_alloc(size_t pg_size);
+extern void mem_move(void *dst, const void *src, size_t len);
+extern void pg_expand(uint8_t *row_in, uint8_t *row_out, uint16_t pg_version);
+extern void pg_reorg(uint32_t flags, uint8_t *pg_old, uint16_t slotnum, uint8_t *row_data, uint64_t cur_partp);
+
+void pg_reorg(uint32_t flags, uint8_t *pg_old, uint16_t slotnum, uint8_t *row_data, uint64_t cur_partp)
+{
+ uint16_t pg_version;
+ size_t pg_size = ((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800)));
+ uint8_t *pg_new = pg_alloc(pg_size);
+ uint8_t *old_slot = ((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (&(pg_old)[((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot8_t))]) : ((((page_v0_t *)(pg_old))->pgv0_mode & 1) ? (&(pg_old)[((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot4_t))]) : (&(pg_old)[((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) - sizeof(int32_t) - (1*sizeof(slot4_t))])));
+ uint8_t *new_slot = ((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (&(pg_new)[((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot8_t))]) : ((((page_v0_t *)(pg_new))->pgv0_mode & 1) ? (&(pg_new)[((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot4_t))]) : (&(pg_new)[((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) - sizeof(int32_t) - (1*sizeof(slot4_t))])));
+
+ if (flags == 2)
+ {
+
+ pg_version = ((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_generic >> 24) : ((uint32_t)((page_v0_t *)(pg_old))->pgv0_next >> 24));
+ }
+
+ int64_t sav_rowid = cur_rowid;
+
+
+ for (uint16_t i = 1; i <= ((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_nslots) : (((page_v0_t *)(pg_old))->pgv0_nslots)); i++,
+ (old_slot -= ((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? sizeof(slot8_t) : sizeof(slot4_t))), (new_slot -= ((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? sizeof(slot8_t) : sizeof(slot4_t))))
+ {
+ size_t length;
+
+
+ if (flags == 1 && (slotnum == 0 || i == slotnum))
+ {
+ uint16_t slotlen = ((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(old_slot))->sl8_len & 0x000FFFFF) : (((slot4_t *)(old_slot))->sl4_len & 0x3FFF));
+ ((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len = (((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((slotlen) & 0x000FFFFF))) : (((slot4_t *)(new_slot))->sl4_len = (((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((slotlen) & 0x3FFF))));
+ length = ((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(old_slot))->sl8_len & 0x000FFFFF) : (((slot4_t *)(old_slot))->sl4_len & 0x3FFF));
+ }
+ else
+ {
+ length = ((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(old_slot))->sl8_len & 0x000FFFFF) : (((slot4_t *)(old_slot))->sl4_len & 0x3FFF));
+ ((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len = (((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((length) & 0x000FFFFF))) : (((slot4_t *)(new_slot))->sl4_len = (((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((length) & 0x3FFF))));
+ }
+
+
+ if (((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)old_slot)->sl8_off) : (((slot4_t *)old_slot)->sl4_off)) == 0)
+ {
+ ((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)new_slot)->sl8_off = (0)) : (((slot4_t *)new_slot)->sl4_off = (0)));
+ continue;
+ }
+
+ ((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)new_slot)->sl8_off = (0)) : (((slot4_t *)new_slot)->sl4_off = (0)));
+
+ if (flags == 2)
+ {
+ cur_rowid = (((((cur_partp) & 0x400000000) ? 1 : 0)) ? (uint64_t)(((((int64_t)((((uint64_t)(sav_rowid) & ((uint64_t)1 << 63)) ? (int64_t)(((sav_rowid) & 0x7FFFFFFFFFFF0000) >> 16) : (int64_t)(((sav_rowid) & 0xFFFFFF00) >> 8)))) << 16) + (i)) | ((uint64_t)1 << 63)) : (uint64_t)((((int32_t)((((uint64_t)(sav_rowid) & ((uint64_t)1 << 63)) ? (int64_t)(((sav_rowid) & 0x7FFFFFFFFFFF0000) >> 16) : (int64_t)(((sav_rowid) & 0xFFFFFF00) >> 8)))) << 8) + (i)));
+ pg_expand(((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((uint8_t*)(pg_old)) + ((slot8_t *)old_slot)->sl8_off) : (((uint8_t*)(pg_old)) + ((slot4_t *)old_slot)->sl4_off)), row_data, pg_version); /* { dg-bogus "uninitialized" } */
+ }
+ else
+ {
+
+ mem_move(((((((page_v1_t *)(pg_new))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((uint8_t*)(pg_new)) + ((slot8_t *)new_slot)->sl8_off) : (((uint8_t*)(pg_new)) + ((slot4_t *)new_slot)->sl4_off)), ((((((page_v1_t *)(pg_old))->pgv1_flags3 == 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((uint8_t*)(pg_old)) + ((slot8_t *)old_slot)->sl8_off) : (((uint8_t*)(pg_old)) + ((slot4_t *)old_slot)->sl4_off)), length);
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/vect_copy_lane_1.c b/gcc/testsuite/gcc.target/aarch64/vect_copy_lane_1.c index 2848be5..811dc67 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect_copy_lane_1.c +++ b/gcc/testsuite/gcc.target/aarch64/vect_copy_lane_1.c @@ -22,7 +22,7 @@ BUILD_TEST (uint16x4_t, uint16x4_t, , , u16, 3, 2) BUILD_TEST (float32x2_t, float32x2_t, , , f32, 1, 0) BUILD_TEST (int32x2_t, int32x2_t, , , s32, 1, 0) BUILD_TEST (uint32x2_t, uint32x2_t, , , u32, 1, 0) -/* { dg-final { scan-assembler-times "ins\\tv0.s\\\[1\\\], v1.s\\\[0\\\]" 3 } } */ +/* { dg-final { scan-assembler-times "zip1\\tv0.2s, v0.2s, v1.2s" 3 } } */ BUILD_TEST (int64x1_t, int64x1_t, , , s64, 0, 0) BUILD_TEST (uint64x1_t, uint64x1_t, , , u64, 0, 0) BUILD_TEST (float64x1_t, float64x1_t, , , f64, 0, 0) diff --git a/gcc/testsuite/gcc.target/powerpc/clone1.c b/gcc/testsuite/gcc.target/powerpc/clone1.c index c69fd2a..74323ca 100644 --- a/gcc/testsuite/gcc.target/powerpc/clone1.c +++ b/gcc/testsuite/gcc.target/powerpc/clone1.c @@ -21,6 +21,7 @@ long mod_func_or (long a, long b, long c) return mod_func (a, b) | c; } -/* { dg-final { scan-assembler-times {\mdivd\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mmulld\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mmodsd\M} 1 } } */ +/* { Fail due to RS6000_DISABLE_SCALAR_MODULO. */ +/* { dg-final { scan-assembler-times {\mdivd\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmulld\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmodsd\M} 1 { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/clone3.c b/gcc/testsuite/gcc.target/powerpc/clone3.c index 911b88b..d3eb4dd 100644 --- a/gcc/testsuite/gcc.target/powerpc/clone3.c +++ b/gcc/testsuite/gcc.target/powerpc/clone3.c @@ -27,7 +27,8 @@ long mod_func_or (long a, long b, long c) return mod_func (a, b) | c; } -/* { dg-final { scan-assembler-times {\mdivd\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mmulld\M} 1 } } */ -/* { dg-final { scan-assembler-times {\mmodsd\M} 2 } } */ +/* { Fail due to RS6000_DISABLE_SCALAR_MODULO. */ +/* { dg-final { scan-assembler-times {\mdivd\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmulld\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmodsd\M} 2 { xfail *-*-* } } } */ /* { dg-final { scan-assembler-times {\mpld\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/mod-1.c b/gcc/testsuite/gcc.target/powerpc/mod-1.c index 861ba67..8720ffb 100644 --- a/gcc/testsuite/gcc.target/powerpc/mod-1.c +++ b/gcc/testsuite/gcc.target/powerpc/mod-1.c @@ -7,13 +7,14 @@ long lsmod (long a, long b) { return a%b; } unsigned int iumod (unsigned int a, unsigned int b) { return a%b; } unsigned long lumod (unsigned long a, unsigned long b) { return a%b; } -/* { dg-final { scan-assembler-times "modsw " 1 } } */ -/* { dg-final { scan-assembler-times "modsd " 1 } } */ -/* { dg-final { scan-assembler-times "moduw " 1 } } */ -/* { dg-final { scan-assembler-times "modud " 1 } } */ -/* { dg-final { scan-assembler-not "mullw " } } */ -/* { dg-final { scan-assembler-not "mulld " } } */ -/* { dg-final { scan-assembler-not "divw " } } */ -/* { dg-final { scan-assembler-not "divd " } } */ -/* { dg-final { scan-assembler-not "divwu " } } */ -/* { dg-final { scan-assembler-not "divdu " } } */ +/* { Fail due to RS6000_DISABLE_SCALAR_MODULO. */ +/* { dg-final { scan-assembler-times {\mmodsw\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmodsd\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmoduw\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmodud\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mmullw\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mmulld\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mdivw\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mdivd\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mdivwu\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mdivdu\M} { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/mod-2.c b/gcc/testsuite/gcc.target/powerpc/mod-2.c index 441ec58..54bdca8 100644 --- a/gcc/testsuite/gcc.target/powerpc/mod-2.c +++ b/gcc/testsuite/gcc.target/powerpc/mod-2.c @@ -5,8 +5,9 @@ int ismod (int a, int b) { return a%b; } unsigned int iumod (unsigned int a, unsigned int b) { return a%b; } -/* { dg-final { scan-assembler-times "modsw " 1 } } */ -/* { dg-final { scan-assembler-times "moduw " 1 } } */ -/* { dg-final { scan-assembler-not "mullw " } } */ -/* { dg-final { scan-assembler-not "divw " } } */ -/* { dg-final { scan-assembler-not "divwu " } } */ +/* { Fail due to RS6000_DISABLE_SCALAR_MODULO. */ +/* { dg-final { scan-assembler-times {\mmodsw\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {\mmoduw\M} 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mmullw\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mdivw\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not {\mdivwu\M} { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c index 84685e5..148998c 100644 --- a/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c +++ b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c @@ -23,5 +23,6 @@ __int128 s_mod(__int128 a, __int128 b) /* { dg-final { scan-assembler {\mvdivsq\M} } } */ /* { dg-final { scan-assembler {\mvdivuq\M} } } */ -/* { dg-final { scan-assembler {\mvmodsq\M} } } */ -/* { dg-final { scan-assembler {\mvmoduq\M} } } */ +/* { Fail due to RS6000_DISABLE_SCALAR_MODULO. */ +/* { dg-final { scan-assembler {\mvmodsq\M} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler {\mvmoduq\M} { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr110071.c b/gcc/testsuite/gcc.target/powerpc/pr110071.c new file mode 100644 index 0000000..282349c --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr110071.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */ + +/* Verify there is an early return without the prolog and shrink-wrap + the function. */ +void bar (); +long +foo (long i, long cond) +{ + if (cond) + bar (); + return i+1; +} + +/* { dg-final { scan-rtl-dump-times "Performing shrink-wrapping" 1 "pro_and_epilogue" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-1.c index b12cb63..48a2386 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-2.c index e5c2e37..86b7661 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-3.c index 315d2de..370498f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/narrow-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> 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 index 5ce2e57..f7d7704 100644 --- 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 @@ -10,3 +10,9 @@ /* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ /* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 6 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv4r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv8r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.i} } } */ 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 9b984dd..bb421fa 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 @@ -12,3 +12,9 @@ /* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */ /* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv4r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv8r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.i} } } */ 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 index 7b1aa28..0dd4df6 100644 --- 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 @@ -10,3 +10,9 @@ /* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ /* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 6 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv4r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv8r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.i} } } */ 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 ca4d23bb..9764cc3 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 @@ -12,3 +12,9 @@ /* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */ /* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 16 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv4r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv8r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.i} } } */ 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 6d0493b..7628f4a 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 @@ -5,3 +5,9 @@ /* { 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" } } */ +/* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv4r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv8r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.i} } } */ 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 24b2bc8..8af9a8b 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 @@ -6,3 +6,9 @@ /* { 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" } } */ +/* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv4r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv8r\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.v} } } */ +/* { dg-final { scan-assembler-not {\tvmv\.v\.i} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c index c882654..99a230d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-2.c index 738f978..1a82440 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-3.c index 5338482..07a9074 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-trapping-math" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-trapping-math -fno-vect-cost-model" } */ /* The difference here is that nueq can use LTGT. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-4.c index 435a59c..a73f7d8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c index 6e60dab..06bf10e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c index 309c30e..dda2075 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c index 9f276d0..b927f1e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable -Ofast" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable -Ofast -fno-vect-cost-model" } */ int a; void b() { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111486.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111486.c new file mode 100644 index 0000000..2ba2a36 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111486.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64iv -mabi=lp64d -O2" } */ + +typedef char __attribute__((__vector_size__ (1))) V; + +V +foo (V v, long x) +{ + x &= v[0]; + return v + (char) x; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c index 4420001..38e4815 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c index fc66def..4130869 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c index 23c542f..a8685c6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c index 8ec261b..d13ab41 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c index ad2673a..f00c608 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c index cd97f4d..1886fc2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c index a225ea0..fff5191 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c index 12dfa0a..238cd5d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c index b83590f..8d9e63c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c index 0f80da4..7fdf512 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c index ae65298..a73e04b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c index 299bd2d..b5ee009 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> 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 index 3f7febc..c5fab3f 100644 --- 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 @@ -1,9 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include "ternop-1.c" -/* 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" 3 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-10.c index 27981fc..a65c398 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-10.c @@ -1,9 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include "ternop-10.c" -/* 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_FNMS" 3 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-11.c index fcbed65..9725cfa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-11.c @@ -1,9 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include "ternop-11.c" -/* 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_FNMS" 3 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-12.c index 0ce468d..97be71c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-12.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-12.c @@ -1,6 +1,8 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns -fno-vect-cost-model" } */ #include "ternop-12.c" /* { dg-final { scan-tree-dump-times "COND_LEN_FNMS" 3 "optimized" } } */ +/* { dg-final { scan-assembler-times {\tvmv} 3 } } */ + 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 index cb60540..965365d 100644 --- 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 @@ -1,11 +1,9 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #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-assembler-times {\tvfma[c-d][c-d]\.vv} 9 } } */ /* { dg-final { scan-tree-dump-times "COND_LEN_FMA" 9 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ 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 index 429cff9..de6d404 100644 --- 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 @@ -1,8 +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" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns -fno-vect-cost-model" } */ #include "ternop-3.c" /* { dg-final { scan-assembler-times {\tvmacc\.vv} 8 } } */ -/* { dg-final { scan-assembler-times {\tvfmacc\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {\tvfma[c-d][c-d]\.vv} 9 } } */ /* { dg-final { scan-tree-dump-times "COND_LEN_FMA" 9 "optimized" } } */ +/* { dg-final { scan-assembler-times {\tvmv} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-4.c index 9ec7527..4d73a54 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-4.c @@ -1,9 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include "ternop-4.c" -/* 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_FNMA" 3 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-5.c index 9aa8e83..6fa28a2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-5.c @@ -1,9 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include "ternop-5.c" -/* 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_FNMA" 3 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-6.c index cc4f7f2..33faf05 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-6.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns -fno-vect-cost-model" } */ #include "ternop-6.c" /* { dg-final { scan-tree-dump-times "COND_LEN_FNMA" 3 "optimized" } } */ +/* { dg-final { scan-assembler-times {\tvmv} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-7.c index 7100fe7..4480799 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-7.c @@ -1,9 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include "ternop-7.c" -/* 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_FMS" 3 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-8.c index 228ada7..c89f583 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-8.c @@ -1,9 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include "ternop-8.c" -/* 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_FMS" 9 "optimized" } } */ +/* { dg-final { scan-assembler-not {\tvmv} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-9.c index 5ab2228..2de649b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_nofm-9.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-schedule-insns -fno-vect-cost-model" } */ #include "ternop-9.c" /* { dg-final { scan-tree-dump-times "COND_LEN_FMS" 9 "optimized" } } */ +/* { dg-final { scan-assembler-times {\tvmv} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c new file mode 100644 index 0000000..d53bd3a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_AVG_FLOOR (int8_t, int16_t, 4) +DEF_AVG_FLOOR (int8_t, int16_t, 8) +DEF_AVG_FLOOR (int8_t, int16_t, 16) +DEF_AVG_FLOOR (int8_t, int16_t, 32) +DEF_AVG_FLOOR (int8_t, int16_t, 64) +DEF_AVG_FLOOR (int8_t, int16_t, 128) +DEF_AVG_FLOOR (int8_t, int16_t, 256) +DEF_AVG_FLOOR (int8_t, int16_t, 512) +DEF_AVG_FLOOR (int8_t, int16_t, 1024) +DEF_AVG_FLOOR (int8_t, int16_t, 2048) + +DEF_AVG_FLOOR (uint8_t, uint16_t, 4) +DEF_AVG_FLOOR (uint8_t, uint16_t, 8) +DEF_AVG_FLOOR (uint8_t, uint16_t, 16) +DEF_AVG_FLOOR (uint8_t, uint16_t, 32) +DEF_AVG_FLOOR (uint8_t, uint16_t, 64) +DEF_AVG_FLOOR (uint8_t, uint16_t, 128) +DEF_AVG_FLOOR (uint8_t, uint16_t, 256) +DEF_AVG_FLOOR (uint8_t, uint16_t, 512) +DEF_AVG_FLOOR (uint8_t, uint16_t, 1024) +DEF_AVG_FLOOR (uint8_t, uint16_t, 2048) + +/* { dg-final { scan-assembler-times {vwadd\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {vwaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {vnsra\.wi} 10 } } */ +/* { dg-final { scan-assembler-times {vnsrl\.wi} 10 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c new file mode 100644 index 0000000..68d1df7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_AVG_FLOOR (int16_t, int32_t, 4) +DEF_AVG_FLOOR (int16_t, int32_t, 8) +DEF_AVG_FLOOR (int16_t, int32_t, 16) +DEF_AVG_FLOOR (int16_t, int32_t, 32) +DEF_AVG_FLOOR (int16_t, int32_t, 64) +DEF_AVG_FLOOR (int16_t, int32_t, 128) +DEF_AVG_FLOOR (int16_t, int32_t, 256) +DEF_AVG_FLOOR (int16_t, int32_t, 512) +DEF_AVG_FLOOR (int16_t, int32_t, 1024) + +DEF_AVG_FLOOR (uint16_t, uint32_t, 4) +DEF_AVG_FLOOR (uint16_t, uint32_t, 8) +DEF_AVG_FLOOR (uint16_t, uint32_t, 16) +DEF_AVG_FLOOR (uint16_t, uint32_t, 32) +DEF_AVG_FLOOR (uint16_t, uint32_t, 64) +DEF_AVG_FLOOR (uint16_t, uint32_t, 128) +DEF_AVG_FLOOR (uint16_t, uint32_t, 256) +DEF_AVG_FLOOR (uint16_t, uint32_t, 512) +DEF_AVG_FLOOR (uint16_t, uint32_t, 1024) + +/* { dg-final { scan-assembler-times {vwadd\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {vwaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {vnsra\.wi} 9 } } */ +/* { dg-final { scan-assembler-times {vnsrl\.wi} 9 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c new file mode 100644 index 0000000..07ffab6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_AVG_FLOOR (int32_t, int64_t, 4) +DEF_AVG_FLOOR (int32_t, int64_t, 8) +DEF_AVG_FLOOR (int32_t, int64_t, 16) +DEF_AVG_FLOOR (int32_t, int64_t, 32) +DEF_AVG_FLOOR (int32_t, int64_t, 64) +DEF_AVG_FLOOR (int32_t, int64_t, 128) +DEF_AVG_FLOOR (int32_t, int64_t, 256) +DEF_AVG_FLOOR (int32_t, int64_t, 512) + +DEF_AVG_FLOOR (uint32_t, uint64_t, 4) +DEF_AVG_FLOOR (uint32_t, uint64_t, 8) +DEF_AVG_FLOOR (uint32_t, uint64_t, 16) +DEF_AVG_FLOOR (uint32_t, uint64_t, 32) +DEF_AVG_FLOOR (uint32_t, uint64_t, 64) +DEF_AVG_FLOOR (uint32_t, uint64_t, 128) +DEF_AVG_FLOOR (uint32_t, uint64_t, 256) +DEF_AVG_FLOOR (uint32_t, uint64_t, 512) + +/* { dg-final { scan-assembler-times {vwadd\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {vwaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {vnsra\.wi} 8 } } */ +/* { dg-final { scan-assembler-times {vnsrl\.wi} 8 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c new file mode 100644 index 0000000..83e219c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_AVG_CEIL (int8_t, int16_t, 4) +DEF_AVG_CEIL (int8_t, int16_t, 8) +DEF_AVG_CEIL (int8_t, int16_t, 16) +DEF_AVG_CEIL (int8_t, int16_t, 32) +DEF_AVG_CEIL (int8_t, int16_t, 64) +DEF_AVG_CEIL (int8_t, int16_t, 128) +DEF_AVG_CEIL (int8_t, int16_t, 256) +DEF_AVG_CEIL (int8_t, int16_t, 512) +DEF_AVG_CEIL (int8_t, int16_t, 1024) +DEF_AVG_CEIL (int8_t, int16_t, 2048) + +DEF_AVG_CEIL (uint8_t, uint16_t, 4) +DEF_AVG_CEIL (uint8_t, uint16_t, 8) +DEF_AVG_CEIL (uint8_t, uint16_t, 16) +DEF_AVG_CEIL (uint8_t, uint16_t, 32) +DEF_AVG_CEIL (uint8_t, uint16_t, 64) +DEF_AVG_CEIL (uint8_t, uint16_t, 128) +DEF_AVG_CEIL (uint8_t, uint16_t, 256) +DEF_AVG_CEIL (uint8_t, uint16_t, 512) +DEF_AVG_CEIL (uint8_t, uint16_t, 1024) +DEF_AVG_CEIL (uint8_t, uint16_t, 2048) + +/* { dg-final { scan-assembler-times {vwadd\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {vwaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {vnsra\.wi} 10 } } */ +/* { dg-final { scan-assembler-times {vnsrl\.wi} 10 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 20 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c new file mode 100644 index 0000000..325faea --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_AVG_CEIL (int16_t, int32_t, 4) +DEF_AVG_CEIL (int16_t, int32_t, 8) +DEF_AVG_CEIL (int16_t, int32_t, 16) +DEF_AVG_CEIL (int16_t, int32_t, 32) +DEF_AVG_CEIL (int16_t, int32_t, 64) +DEF_AVG_CEIL (int16_t, int32_t, 128) +DEF_AVG_CEIL (int16_t, int32_t, 256) +DEF_AVG_CEIL (int16_t, int32_t, 512) +DEF_AVG_CEIL (int16_t, int32_t, 1024) + +DEF_AVG_CEIL (uint16_t, uint32_t, 4) +DEF_AVG_CEIL (uint16_t, uint32_t, 8) +DEF_AVG_CEIL (uint16_t, uint32_t, 16) +DEF_AVG_CEIL (uint16_t, uint32_t, 32) +DEF_AVG_CEIL (uint16_t, uint32_t, 64) +DEF_AVG_CEIL (uint16_t, uint32_t, 128) +DEF_AVG_CEIL (uint16_t, uint32_t, 256) +DEF_AVG_CEIL (uint16_t, uint32_t, 512) +DEF_AVG_CEIL (uint16_t, uint32_t, 1024) + +/* { dg-final { scan-assembler-times {vwadd\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {vwaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {vnsra\.wi} 9 } } */ +/* { dg-final { scan-assembler-times {vnsrl\.wi} 9 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 18 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c new file mode 100644 index 0000000..d836428 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_AVG_CEIL (int16_t, int32_t, 4) +DEF_AVG_CEIL (int16_t, int32_t, 8) +DEF_AVG_CEIL (int16_t, int32_t, 16) +DEF_AVG_CEIL (int16_t, int32_t, 32) +DEF_AVG_CEIL (int16_t, int32_t, 64) +DEF_AVG_CEIL (int16_t, int32_t, 128) +DEF_AVG_CEIL (int16_t, int32_t, 256) +DEF_AVG_CEIL (int16_t, int32_t, 512) + +DEF_AVG_CEIL (uint16_t, uint32_t, 4) +DEF_AVG_CEIL (uint16_t, uint32_t, 8) +DEF_AVG_CEIL (uint16_t, uint32_t, 16) +DEF_AVG_CEIL (uint16_t, uint32_t, 32) +DEF_AVG_CEIL (uint16_t, uint32_t, 64) +DEF_AVG_CEIL (uint16_t, uint32_t, 128) +DEF_AVG_CEIL (uint16_t, uint32_t, 256) +DEF_AVG_CEIL (uint16_t, uint32_t, 512) + +/* { dg-final { scan-assembler-times {vwadd\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {vwaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {vnsra\.wi} 8 } } */ +/* { dg-final { scan-assembler-times {vnsrl\.wi} 8 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 16 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-1.c new file mode 100644 index 0000000..ca04f7f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-1.c @@ -0,0 +1,74 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fcvt, _Float16, int16_t, 4) +DEF_CONVERT (fcvt, _Float16, int16_t, 16) +DEF_CONVERT (fcvt, _Float16, int16_t, 32) +DEF_CONVERT (fcvt, _Float16, int16_t, 64) +DEF_CONVERT (fcvt, _Float16, int16_t, 128) +DEF_CONVERT (fcvt, _Float16, int16_t, 256) +DEF_CONVERT (fcvt, _Float16, int16_t, 512) +DEF_CONVERT (fcvt, _Float16, int16_t, 1024) +DEF_CONVERT (fcvt, _Float16, int16_t, 2048) + +DEF_CONVERT (fcvt, float, int32_t, 4) +DEF_CONVERT (fcvt, float, int32_t, 16) +DEF_CONVERT (fcvt, float, int32_t, 32) +DEF_CONVERT (fcvt, float, int32_t, 64) +DEF_CONVERT (fcvt, float, int32_t, 128) +DEF_CONVERT (fcvt, float, int32_t, 256) +DEF_CONVERT (fcvt, float, int32_t, 512) +DEF_CONVERT (fcvt, float, int32_t, 1024) + +DEF_CONVERT (fcvt, double, int64_t, 4) +DEF_CONVERT (fcvt, double, int64_t, 16) +DEF_CONVERT (fcvt, double, int64_t, 32) +DEF_CONVERT (fcvt, double, int64_t, 64) +DEF_CONVERT (fcvt, double, int64_t, 128) +DEF_CONVERT (fcvt, double, int64_t, 256) +DEF_CONVERT (fcvt, double, int64_t, 512) + +DEF_CONVERT (fcvt, _Float16, uint16_t, 4) +DEF_CONVERT (fcvt, _Float16, uint16_t, 16) +DEF_CONVERT (fcvt, _Float16, uint16_t, 32) +DEF_CONVERT (fcvt, _Float16, uint16_t, 64) +DEF_CONVERT (fcvt, _Float16, uint16_t, 128) +DEF_CONVERT (fcvt, _Float16, uint16_t, 256) +DEF_CONVERT (fcvt, _Float16, uint16_t, 512) +DEF_CONVERT (fcvt, _Float16, uint16_t, 1024) +DEF_CONVERT (fcvt, _Float16, uint16_t, 2048) + +DEF_CONVERT (fcvt, float, uint32_t, 4) +DEF_CONVERT (fcvt, float, uint32_t, 16) +DEF_CONVERT (fcvt, float, uint32_t, 32) +DEF_CONVERT (fcvt, float, uint32_t, 64) +DEF_CONVERT (fcvt, float, uint32_t, 128) +DEF_CONVERT (fcvt, float, uint32_t, 256) +DEF_CONVERT (fcvt, float, uint32_t, 512) +DEF_CONVERT (fcvt, float, uint32_t, 1024) + +DEF_CONVERT (fcvt, double, uint64_t, 4) +DEF_CONVERT (fcvt, double, uint64_t, 16) +DEF_CONVERT (fcvt, double, uint64_t, 32) +DEF_CONVERT (fcvt, double, uint64_t, 64) +DEF_CONVERT (fcvt, double, uint64_t, 128) +DEF_CONVERT (fcvt, double, uint64_t, 256) +DEF_CONVERT (fcvt, double, uint64_t, 512) + +/* { dg-final { scan-assembler-times {vfcvt\.rtz\.x\.f\.v} 24 } } */ +/* { dg-final { scan-assembler-times {vfcvt\.rtz\.xu\.f\.v} 24 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-10.c new file mode 100644 index 0000000..95d04cd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-10.c @@ -0,0 +1,80 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fncvt, _Float16, int8_t, 4) +DEF_CONVERT (fncvt, _Float16, int8_t, 16) +DEF_CONVERT (fncvt, _Float16, int8_t, 32) +DEF_CONVERT (fncvt, _Float16, int8_t, 64) +DEF_CONVERT (fncvt, _Float16, int8_t, 128) +DEF_CONVERT (fncvt, _Float16, int8_t, 256) +DEF_CONVERT (fncvt, _Float16, int8_t, 512) +DEF_CONVERT (fncvt, _Float16, int8_t, 1024) +DEF_CONVERT (fncvt, _Float16, int8_t, 2048) +DEF_CONVERT (fncvt, _Float16, int8_t, 4096) + +DEF_CONVERT (fncvt, _Float16, uint8_t, 4) +DEF_CONVERT (fncvt, _Float16, uint8_t, 16) +DEF_CONVERT (fncvt, _Float16, uint8_t, 32) +DEF_CONVERT (fncvt, _Float16, uint8_t, 64) +DEF_CONVERT (fncvt, _Float16, uint8_t, 128) +DEF_CONVERT (fncvt, _Float16, uint8_t, 256) +DEF_CONVERT (fncvt, _Float16, uint8_t, 512) +DEF_CONVERT (fncvt, _Float16, uint8_t, 1024) +DEF_CONVERT (fncvt, _Float16, uint8_t, 2048) +DEF_CONVERT (fncvt, _Float16, uint8_t, 4096) + +DEF_CONVERT (fncvt, float, int16_t, 4) +DEF_CONVERT (fncvt, float, int16_t, 16) +DEF_CONVERT (fncvt, float, int16_t, 32) +DEF_CONVERT (fncvt, float, int16_t, 64) +DEF_CONVERT (fncvt, float, int16_t, 128) +DEF_CONVERT (fncvt, float, int16_t, 256) +DEF_CONVERT (fncvt, float, int16_t, 512) +DEF_CONVERT (fncvt, float, int16_t, 1024) +DEF_CONVERT (fncvt, float, int16_t, 2048) + +DEF_CONVERT (fncvt, float, uint16_t, 4) +DEF_CONVERT (fncvt, float, uint16_t, 16) +DEF_CONVERT (fncvt, float, uint16_t, 32) +DEF_CONVERT (fncvt, float, uint16_t, 64) +DEF_CONVERT (fncvt, float, uint16_t, 128) +DEF_CONVERT (fncvt, float, uint16_t, 256) +DEF_CONVERT (fncvt, float, uint16_t, 512) +DEF_CONVERT (fncvt, float, uint16_t, 1024) +DEF_CONVERT (fncvt, float, uint16_t, 2048) + +DEF_CONVERT (fncvt, double, int32_t, 4) +DEF_CONVERT (fncvt, double, int32_t, 16) +DEF_CONVERT (fncvt, double, int32_t, 32) +DEF_CONVERT (fncvt, double, int32_t, 64) +DEF_CONVERT (fncvt, double, int32_t, 128) +DEF_CONVERT (fncvt, double, int32_t, 256) +DEF_CONVERT (fncvt, double, int32_t, 512) +DEF_CONVERT (fncvt, double, int32_t, 1024) + +DEF_CONVERT (fncvt, double, uint32_t, 4) +DEF_CONVERT (fncvt, double, uint32_t, 16) +DEF_CONVERT (fncvt, double, uint32_t, 32) +DEF_CONVERT (fncvt, double, uint32_t, 64) +DEF_CONVERT (fncvt, double, uint32_t, 128) +DEF_CONVERT (fncvt, double, uint32_t, 256) +DEF_CONVERT (fncvt, double, uint32_t, 512) +DEF_CONVERT (fncvt, double, uint32_t, 1024) + +/* { dg-final { scan-assembler-times {vfncvt\.rtz\.x\.f\.w} 30 } } */ +/* { dg-final { scan-assembler-times {vfncvt\.rtz\.xu\.f\.w} 30 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-11.c new file mode 100644 index 0000000..853acb3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-11.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fno-trapping-math -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fncvt, float, int8_t, 4) +DEF_CONVERT (fncvt, float, int8_t, 16) +DEF_CONVERT (fncvt, float, int8_t, 32) +DEF_CONVERT (fncvt, float, int8_t, 64) +DEF_CONVERT (fncvt, float, int8_t, 128) +DEF_CONVERT (fncvt, float, int8_t, 256) +DEF_CONVERT (fncvt, float, int8_t, 512) +DEF_CONVERT (fncvt, float, int8_t, 1024) + +DEF_CONVERT (fncvt, float, uint8_t, 4) +DEF_CONVERT (fncvt, float, uint8_t, 16) +DEF_CONVERT (fncvt, float, uint8_t, 32) +DEF_CONVERT (fncvt, float, uint8_t, 64) +DEF_CONVERT (fncvt, float, uint8_t, 128) +DEF_CONVERT (fncvt, float, uint8_t, 256) +DEF_CONVERT (fncvt, float, uint8_t, 512) +DEF_CONVERT (fncvt, float, uint8_t, 1024) + +DEF_CONVERT (fncvt, double, int16_t, 4) +DEF_CONVERT (fncvt, double, int16_t, 16) +DEF_CONVERT (fncvt, double, int16_t, 32) +DEF_CONVERT (fncvt, double, int16_t, 64) +DEF_CONVERT (fncvt, double, int16_t, 128) +DEF_CONVERT (fncvt, double, int16_t, 256) +DEF_CONVERT (fncvt, double, int16_t, 512) + +DEF_CONVERT (fncvt, double, uint16_t, 4) +DEF_CONVERT (fncvt, double, uint16_t, 16) +DEF_CONVERT (fncvt, double, uint16_t, 32) +DEF_CONVERT (fncvt, double, uint16_t, 64) +DEF_CONVERT (fncvt, double, uint16_t, 128) +DEF_CONVERT (fncvt, double, uint16_t, 256) +DEF_CONVERT (fncvt, double, uint16_t, 512) + +/* { dg-final { scan-assembler-times {vfncvt\.rtz\.x\.f.w} 30 } } */ +/* { dg-final { scan-assembler-times {vncvt\.x\.x\.w} 30 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-12.c new file mode 100644 index 0000000..8fdfa44 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-12.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fno-trapping-math -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fncvt, double, int8_t, 4) +DEF_CONVERT (fncvt, double, int8_t, 16) +DEF_CONVERT (fncvt, double, int8_t, 32) +DEF_CONVERT (fncvt, double, int8_t, 64) +DEF_CONVERT (fncvt, double, int8_t, 128) +DEF_CONVERT (fncvt, double, int8_t, 256) +DEF_CONVERT (fncvt, double, int8_t, 512) + +DEF_CONVERT (fncvt, double, uint8_t, 4) +DEF_CONVERT (fncvt, double, uint8_t, 16) +DEF_CONVERT (fncvt, double, uint8_t, 32) +DEF_CONVERT (fncvt, double, uint8_t, 64) +DEF_CONVERT (fncvt, double, uint8_t, 128) +DEF_CONVERT (fncvt, double, uint8_t, 256) +DEF_CONVERT (fncvt, double, uint8_t, 512) + +/* { dg-final { scan-assembler-times {vfncvt\.rtz\.x\.f.w} 14 } } */ +/* { dg-final { scan-assembler-times {vncvt\.x\.x\.w} 28 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-2.c new file mode 100644 index 0000000..4b6a168 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-2.c @@ -0,0 +1,74 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fcvt, int16_t, _Float16, 4) +DEF_CONVERT (fcvt, int16_t, _Float16, 16) +DEF_CONVERT (fcvt, int16_t, _Float16, 32) +DEF_CONVERT (fcvt, int16_t, _Float16, 64) +DEF_CONVERT (fcvt, int16_t, _Float16, 128) +DEF_CONVERT (fcvt, int16_t, _Float16, 256) +DEF_CONVERT (fcvt, int16_t, _Float16, 512) +DEF_CONVERT (fcvt, int16_t, _Float16, 1024) +DEF_CONVERT (fcvt, int16_t, _Float16, 2048) + +DEF_CONVERT (fcvt, int32_t, float, 4) +DEF_CONVERT (fcvt, int32_t, float, 16) +DEF_CONVERT (fcvt, int32_t, float, 32) +DEF_CONVERT (fcvt, int32_t, float, 64) +DEF_CONVERT (fcvt, int32_t, float, 128) +DEF_CONVERT (fcvt, int32_t, float, 256) +DEF_CONVERT (fcvt, int32_t, float, 512) +DEF_CONVERT (fcvt, int32_t, float, 1024) + +DEF_CONVERT (fcvt, int64_t, double, 4) +DEF_CONVERT (fcvt, int64_t, double, 16) +DEF_CONVERT (fcvt, int64_t, double, 32) +DEF_CONVERT (fcvt, int64_t, double, 64) +DEF_CONVERT (fcvt, int64_t, double, 128) +DEF_CONVERT (fcvt, int64_t, double, 256) +DEF_CONVERT (fcvt, int64_t, double, 512) + +DEF_CONVERT (fcvt, uint16_t, _Float16, 4) +DEF_CONVERT (fcvt, uint16_t, _Float16, 16) +DEF_CONVERT (fcvt, uint16_t, _Float16, 32) +DEF_CONVERT (fcvt, uint16_t, _Float16, 64) +DEF_CONVERT (fcvt, uint16_t, _Float16, 128) +DEF_CONVERT (fcvt, uint16_t, _Float16, 256) +DEF_CONVERT (fcvt, uint16_t, _Float16, 512) +DEF_CONVERT (fcvt, uint16_t, _Float16, 1024) +DEF_CONVERT (fcvt, uint16_t, _Float16, 2048) + +DEF_CONVERT (fcvt, uint32_t, float, 4) +DEF_CONVERT (fcvt, uint32_t, float, 16) +DEF_CONVERT (fcvt, uint32_t, float, 32) +DEF_CONVERT (fcvt, uint32_t, float, 64) +DEF_CONVERT (fcvt, uint32_t, float, 128) +DEF_CONVERT (fcvt, uint32_t, float, 256) +DEF_CONVERT (fcvt, uint32_t, float, 512) +DEF_CONVERT (fcvt, uint32_t, float, 1024) + +DEF_CONVERT (fcvt, uint64_t, double, 4) +DEF_CONVERT (fcvt, uint64_t, double, 16) +DEF_CONVERT (fcvt, uint64_t, double, 32) +DEF_CONVERT (fcvt, uint64_t, double, 64) +DEF_CONVERT (fcvt, uint64_t, double, 128) +DEF_CONVERT (fcvt, uint64_t, double, 256) +DEF_CONVERT (fcvt, uint64_t, double, 512) + +/* { dg-final { scan-assembler-times {vfcvt\.f\.x\.v} 24 } } */ +/* { dg-final { scan-assembler-times {vfcvt\.f\.xu\.v} 24 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-3.c new file mode 100644 index 0000000..6d74bdd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-3.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fwcvt, _Float16, int32_t, 4) +DEF_CONVERT (fwcvt, _Float16, int32_t, 16) +DEF_CONVERT (fwcvt, _Float16, int32_t, 32) +DEF_CONVERT (fwcvt, _Float16, int32_t, 64) +DEF_CONVERT (fwcvt, _Float16, int32_t, 128) +DEF_CONVERT (fwcvt, _Float16, int32_t, 256) +DEF_CONVERT (fwcvt, _Float16, int32_t, 512) +DEF_CONVERT (fwcvt, _Float16, int32_t, 1024) +DEF_CONVERT (fwcvt, _Float16, int32_t, 2048) + +DEF_CONVERT (fwcvt, _Float16, uint32_t, 4) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 16) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 32) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 64) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 128) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 256) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 512) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 1024) +DEF_CONVERT (fwcvt, _Float16, uint32_t, 2048) + +DEF_CONVERT (fwcvt, float, int64_t, 4) +DEF_CONVERT (fwcvt, float, int64_t, 16) +DEF_CONVERT (fwcvt, float, int64_t, 32) +DEF_CONVERT (fwcvt, float, int64_t, 64) +DEF_CONVERT (fwcvt, float, int64_t, 128) +DEF_CONVERT (fwcvt, float, int64_t, 256) +DEF_CONVERT (fwcvt, float, int64_t, 512) +DEF_CONVERT (fwcvt, float, int64_t, 1024) + +DEF_CONVERT (fwcvt, float, uint64_t, 4) +DEF_CONVERT (fwcvt, float, uint64_t, 16) +DEF_CONVERT (fwcvt, float, uint64_t, 32) +DEF_CONVERT (fwcvt, float, uint64_t, 64) +DEF_CONVERT (fwcvt, float, uint64_t, 128) +DEF_CONVERT (fwcvt, float, uint64_t, 256) +DEF_CONVERT (fwcvt, float, uint64_t, 512) +DEF_CONVERT (fwcvt, float, uint64_t, 1024) + +/* { dg-final { scan-assembler-times {vfwcvt\.rtz\.x\.f\.v} 19 } } */ +/* { dg-final { scan-assembler-times {vfwcvt\.rtz\.xu\.f\.v} 19 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-4.c new file mode 100644 index 0000000..8ef991d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-4.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fno-trapping-math -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fwcvt, _Float16, int64_t, 4) +DEF_CONVERT (fwcvt, _Float16, int64_t, 16) +DEF_CONVERT (fwcvt, _Float16, int64_t, 32) +DEF_CONVERT (fwcvt, _Float16, int64_t, 64) +DEF_CONVERT (fwcvt, _Float16, int64_t, 128) +DEF_CONVERT (fwcvt, _Float16, int64_t, 256) +DEF_CONVERT (fwcvt, _Float16, int64_t, 512) + +DEF_CONVERT (fwcvt, _Float16, uint64_t, 4) +DEF_CONVERT (fwcvt, _Float16, uint64_t, 16) +DEF_CONVERT (fwcvt, _Float16, uint64_t, 32) +DEF_CONVERT (fwcvt, _Float16, uint64_t, 64) +DEF_CONVERT (fwcvt, _Float16, uint64_t, 128) +DEF_CONVERT (fwcvt, _Float16, uint64_t, 256) +DEF_CONVERT (fwcvt, _Float16, uint64_t, 512) + +/* { dg-final { scan-assembler-times {vfwcvt\.rtz\.x\.f\.v} 14 } } */ +/* { dg-final { scan-assembler-times {vsext\.vf2} 14 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-5.c new file mode 100644 index 0000000..09a44de --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-5.c @@ -0,0 +1,80 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fwcvt, int8_t, _Float16, 4) +DEF_CONVERT (fwcvt, int8_t, _Float16, 16) +DEF_CONVERT (fwcvt, int8_t, _Float16, 32) +DEF_CONVERT (fwcvt, int8_t, _Float16, 64) +DEF_CONVERT (fwcvt, int8_t, _Float16, 128) +DEF_CONVERT (fwcvt, int8_t, _Float16, 256) +DEF_CONVERT (fwcvt, int8_t, _Float16, 512) +DEF_CONVERT (fwcvt, int8_t, _Float16, 1024) +DEF_CONVERT (fwcvt, int8_t, _Float16, 2048) +DEF_CONVERT (fwcvt, int8_t, _Float16, 4096) + +DEF_CONVERT (fwcvt, uint8_t, _Float16, 4) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 16) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 32) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 64) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 128) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 256) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 512) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 1024) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 2048) +DEF_CONVERT (fwcvt, uint8_t, _Float16, 4096) + +DEF_CONVERT (fwcvt, int16_t, float, 4) +DEF_CONVERT (fwcvt, int16_t, float, 16) +DEF_CONVERT (fwcvt, int16_t, float, 32) +DEF_CONVERT (fwcvt, int16_t, float, 64) +DEF_CONVERT (fwcvt, int16_t, float, 128) +DEF_CONVERT (fwcvt, int16_t, float, 256) +DEF_CONVERT (fwcvt, int16_t, float, 512) +DEF_CONVERT (fwcvt, int16_t, float, 1024) +DEF_CONVERT (fwcvt, int16_t, float, 2048) + +DEF_CONVERT (fwcvt, uint16_t, float, 4) +DEF_CONVERT (fwcvt, uint16_t, float, 16) +DEF_CONVERT (fwcvt, uint16_t, float, 32) +DEF_CONVERT (fwcvt, uint16_t, float, 64) +DEF_CONVERT (fwcvt, uint16_t, float, 128) +DEF_CONVERT (fwcvt, uint16_t, float, 256) +DEF_CONVERT (fwcvt, uint16_t, float, 512) +DEF_CONVERT (fwcvt, uint16_t, float, 1024) +DEF_CONVERT (fwcvt, uint16_t, float, 2048) + +DEF_CONVERT (fwcvt, int32_t, double, 4) +DEF_CONVERT (fwcvt, int32_t, double, 16) +DEF_CONVERT (fwcvt, int32_t, double, 32) +DEF_CONVERT (fwcvt, int32_t, double, 64) +DEF_CONVERT (fwcvt, int32_t, double, 128) +DEF_CONVERT (fwcvt, int32_t, double, 256) +DEF_CONVERT (fwcvt, int32_t, double, 512) +DEF_CONVERT (fwcvt, int32_t, double, 1024) + +DEF_CONVERT (fwcvt, uint32_t, double, 4) +DEF_CONVERT (fwcvt, uint32_t, double, 16) +DEF_CONVERT (fwcvt, uint32_t, double, 32) +DEF_CONVERT (fwcvt, uint32_t, double, 64) +DEF_CONVERT (fwcvt, uint32_t, double, 128) +DEF_CONVERT (fwcvt, uint32_t, double, 256) +DEF_CONVERT (fwcvt, uint32_t, double, 512) +DEF_CONVERT (fwcvt, uint32_t, double, 1024) + +/* { dg-final { scan-assembler-times {vfwcvt\.f\.x\.v} 30 } } */ +/* { dg-final { scan-assembler-times {vfwcvt\.f\.xu\.v} 30 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-6.c new file mode 100644 index 0000000..2948dde --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-6.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fno-trapping-math -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fwcvt, int8_t, float, 4) +DEF_CONVERT (fwcvt, int8_t, float, 16) +DEF_CONVERT (fwcvt, int8_t, float, 32) +DEF_CONVERT (fwcvt, int8_t, float, 64) +DEF_CONVERT (fwcvt, int8_t, float, 128) +DEF_CONVERT (fwcvt, int8_t, float, 256) +DEF_CONVERT (fwcvt, int8_t, float, 512) +DEF_CONVERT (fwcvt, int8_t, float, 1024) + +DEF_CONVERT (fwcvt, uint8_t, float, 4) +DEF_CONVERT (fwcvt, uint8_t, float, 16) +DEF_CONVERT (fwcvt, uint8_t, float, 32) +DEF_CONVERT (fwcvt, uint8_t, float, 64) +DEF_CONVERT (fwcvt, uint8_t, float, 128) +DEF_CONVERT (fwcvt, uint8_t, float, 256) +DEF_CONVERT (fwcvt, uint8_t, float, 512) +DEF_CONVERT (fwcvt, uint8_t, float, 1024) + +DEF_CONVERT (fwcvt, int16_t, double, 4) +DEF_CONVERT (fwcvt, int16_t, double, 16) +DEF_CONVERT (fwcvt, int16_t, double, 32) +DEF_CONVERT (fwcvt, int16_t, double, 64) +DEF_CONVERT (fwcvt, int16_t, double, 128) +DEF_CONVERT (fwcvt, int16_t, double, 256) +DEF_CONVERT (fwcvt, int16_t, double, 512) + +DEF_CONVERT (fwcvt, uint16_t, double, 4) +DEF_CONVERT (fwcvt, uint16_t, double, 16) +DEF_CONVERT (fwcvt, uint16_t, double, 32) +DEF_CONVERT (fwcvt, uint16_t, double, 64) +DEF_CONVERT (fwcvt, uint16_t, double, 128) +DEF_CONVERT (fwcvt, uint16_t, double, 256) +DEF_CONVERT (fwcvt, uint16_t, double, 512) + +/* { dg-final { scan-assembler-times {vfwcvt\.f\.x\.v} 30 } } */ +/* { dg-final { scan-assembler-times {vsext\.vf2} 15 } } */ +/* { dg-final { scan-assembler-times {vzext\.vf2} 15 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-7.c new file mode 100644 index 0000000..ea39012 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-7.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fwcvt, int8_t, double, 4) +DEF_CONVERT (fwcvt, int8_t, double, 16) +DEF_CONVERT (fwcvt, int8_t, double, 32) +DEF_CONVERT (fwcvt, int8_t, double, 64) +DEF_CONVERT (fwcvt, int8_t, double, 128) +DEF_CONVERT (fwcvt, int8_t, double, 256) +DEF_CONVERT (fwcvt, int8_t, double, 512) + +DEF_CONVERT (fwcvt, uint8_t, double, 4) +DEF_CONVERT (fwcvt, uint8_t, double, 16) +DEF_CONVERT (fwcvt, uint8_t, double, 32) +DEF_CONVERT (fwcvt, uint8_t, double, 64) +DEF_CONVERT (fwcvt, uint8_t, double, 128) +DEF_CONVERT (fwcvt, uint8_t, double, 256) +DEF_CONVERT (fwcvt, uint8_t, double, 512) + +/* { dg-final { scan-assembler-times {vfwcvt\.f\.x\.v} 14 } } */ +/* { dg-final { scan-assembler-times {vsext\.vf4} 7 } } */ +/* { dg-final { scan-assembler-times {vzext\.vf4} 7 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-8.c new file mode 100644 index 0000000..59f36f5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-8.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fncvt, int32_t, _Float16, 4) +DEF_CONVERT (fncvt, int32_t, _Float16, 16) +DEF_CONVERT (fncvt, int32_t, _Float16, 32) +DEF_CONVERT (fncvt, int32_t, _Float16, 64) +DEF_CONVERT (fncvt, int32_t, _Float16, 128) +DEF_CONVERT (fncvt, int32_t, _Float16, 256) +DEF_CONVERT (fncvt, int32_t, _Float16, 512) +DEF_CONVERT (fncvt, int32_t, _Float16, 1024) +DEF_CONVERT (fncvt, int32_t, _Float16, 2048) + +DEF_CONVERT (fncvt, uint32_t, _Float16, 4) +DEF_CONVERT (fncvt, uint32_t, _Float16, 16) +DEF_CONVERT (fncvt, uint32_t, _Float16, 32) +DEF_CONVERT (fncvt, uint32_t, _Float16, 64) +DEF_CONVERT (fncvt, uint32_t, _Float16, 128) +DEF_CONVERT (fncvt, uint32_t, _Float16, 256) +DEF_CONVERT (fncvt, uint32_t, _Float16, 512) +DEF_CONVERT (fncvt, uint32_t, _Float16, 1024) +DEF_CONVERT (fncvt, uint32_t, _Float16, 2048) + +DEF_CONVERT (fncvt, int64_t, float, 4) +DEF_CONVERT (fncvt, int64_t, float, 16) +DEF_CONVERT (fncvt, int64_t, float, 32) +DEF_CONVERT (fncvt, int64_t, float, 64) +DEF_CONVERT (fncvt, int64_t, float, 128) +DEF_CONVERT (fncvt, int64_t, float, 256) +DEF_CONVERT (fncvt, int64_t, float, 512) +DEF_CONVERT (fncvt, int64_t, float, 1024) + +DEF_CONVERT (fncvt, uint64_t, float, 4) +DEF_CONVERT (fncvt, uint64_t, float, 16) +DEF_CONVERT (fncvt, uint64_t, float, 32) +DEF_CONVERT (fncvt, uint64_t, float, 64) +DEF_CONVERT (fncvt, uint64_t, float, 128) +DEF_CONVERT (fncvt, uint64_t, float, 256) +DEF_CONVERT (fncvt, uint64_t, float, 512) +DEF_CONVERT (fncvt, uint64_t, float, 1024) + +/* { dg-final { scan-assembler-times {vfncvt\.f\.x\.w} 19 } } */ +/* { dg-final { scan-assembler-times {vfncvt\.f\.xu\.w} 19 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-9.c new file mode 100644 index 0000000..3546ddc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/convert-9.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fno-trapping-math -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fncvt, int64_t, _Float16, 4) +DEF_CONVERT (fncvt, int64_t, _Float16, 16) +DEF_CONVERT (fncvt, int64_t, _Float16, 32) +DEF_CONVERT (fncvt, int64_t, _Float16, 64) +DEF_CONVERT (fncvt, int64_t, _Float16, 128) +DEF_CONVERT (fncvt, int64_t, _Float16, 256) +DEF_CONVERT (fncvt, int64_t, _Float16, 512) + +DEF_CONVERT (fncvt, uint64_t, _Float16, 4) +DEF_CONVERT (fncvt, uint64_t, _Float16, 16) +DEF_CONVERT (fncvt, uint64_t, _Float16, 32) +DEF_CONVERT (fncvt, uint64_t, _Float16, 64) +DEF_CONVERT (fncvt, uint64_t, _Float16, 128) +DEF_CONVERT (fncvt, uint64_t, _Float16, 256) +DEF_CONVERT (fncvt, uint64_t, _Float16, 512) + +/* TODO: Currently, we can't vectorize this case. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h index 59f31d0..74685f8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h @@ -210,7 +210,7 @@ typedef double v512df __attribute__ ((vector_size (4096))); PREFIX##_##TYPE##NUM (TYPE *restrict a, TYPE *restrict b) \ { \ for (int i = 0; i < NUM; ++i) \ - a[i] = OP b[i]; \ + a[i] = OP (b[i]); \ } #define DEF_CALL_VV(PREFIX, NUM, TYPE, CALL) \ @@ -439,3 +439,82 @@ typedef double v512df __attribute__ ((vector_size (4096))); TYPE1 v = {__VA_ARGS__}; \ *(TYPE1 *) out = v; \ } + +#define DEF_VEC_SET_IMM_INDEX(PREFIX, VECTOR, TYPE, INDEX) \ + VECTOR __attribute__ ((noinline, noclone)) \ + PREFIX##_##VECTOR##_##INDEX (VECTOR v, TYPE a) \ + { \ + v[INDEX] = a; \ + \ + return v; \ + } + +#define DEF_VEC_SET_SCALAR_INDEX(PREFIX, VECTOR, TYPE) \ + VECTOR __attribute__ ((noinline, noclone)) \ + PREFIX##_##VECTOR##_##TYPE (VECTOR v, TYPE a, unsigned index) \ + { \ + v[index] = a; \ + \ + return v; \ + } + +#define DEF_FMA_VV(PREFIX, NUM, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + PREFIX##_##TYPE##NUM (TYPE *restrict a, TYPE *restrict b, TYPE *restrict c, \ + TYPE *restrict d) \ + { \ + for (int i = 0; i < NUM; ++i) \ + a[i] = b[i] * c[i] + d[i]; \ + } + +#define DEF_FNMA_VV(PREFIX, NUM, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + PREFIX##_##TYPE##NUM (TYPE *restrict a, TYPE *restrict b, TYPE *restrict c, \ + TYPE *restrict d) \ + { \ + for (int i = 0; i < NUM; ++i) \ + a[i] = d[i] - b[i] * c[i]; \ + } + +#define DEF_FMS_VV(PREFIX, NUM, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + PREFIX##_##TYPE##NUM (TYPE *restrict a, TYPE *restrict b, TYPE *restrict c, \ + TYPE *restrict d) \ + { \ + for (int i = 0; i < NUM; ++i) \ + a[i] = b[i] * c[i] - d[i]; \ + } + +#define DEF_FNMS_VV(PREFIX, NUM, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + PREFIX##_##TYPE##NUM (TYPE *restrict a, TYPE *restrict b, TYPE *restrict c, \ + TYPE *restrict d) \ + { \ + for (int i = 0; i < NUM; ++i) \ + a[i] = -(b[i] * c[i]) - d[i]; \ + } + +#define DEF_CONVERT(PREFIX, TYPE1, TYPE2, NUM) \ + __attribute__ (( \ + noipa)) void PREFIX##_##TYPE1##TYPE2##_##NUM (TYPE2 *__restrict dst, \ + TYPE1 *__restrict a) \ + { \ + for (int i = 0; i < NUM; i++) \ + dst[i] = (TYPE2) a[i]; \ + } + +#define DEF_AVG_FLOOR(TYPE, TYPE2, NUM) \ + __attribute__ ((noipa)) void vavg_##TYPE##_##TYPE2##NUM ( \ + TYPE *__restrict dst, TYPE *__restrict a, TYPE *__restrict b, int n) \ + { \ + for (int i = 0; i < NUM; i++) \ + dst[i] = ((TYPE2) a[i] + b[i]) >> 1; \ + } + +#define DEF_AVG_CEIL(TYPE, TYPE2, NUM) \ + __attribute__ ((noipa)) void vavg2_##TYPE##_##TYPE2##NUM ( \ + TYPE *__restrict dst, TYPE *__restrict a, TYPE *__restrict b, int n) \ + { \ + for (int i = 0; i < NUM; i++) \ + dst[i] = ((TYPE2) a[i] + b[i] + 1) >> 1; \ + } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c index e36fa9d..7d8a3e2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c @@ -53,5 +53,5 @@ DEF_OP_VV (div, 128, int64_t, /) DEF_OP_VV (div, 256, int64_t, /) DEF_OP_VV (div, 512, int64_t, /) -/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 42 } } */ +/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 44 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-1.c new file mode 100644 index 0000000..e46990e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-1.c @@ -0,0 +1,72 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (sext, int8_t, int16_t, 4) +DEF_CONVERT (sext, int8_t, int16_t, 16) +DEF_CONVERT (sext, int8_t, int16_t, 32) +DEF_CONVERT (sext, int8_t, int16_t, 64) +DEF_CONVERT (sext, int8_t, int16_t, 128) +DEF_CONVERT (sext, int8_t, int16_t, 256) +DEF_CONVERT (sext, int8_t, int16_t, 512) +DEF_CONVERT (sext, int8_t, int16_t, 1024) +DEF_CONVERT (sext, int8_t, int16_t, 2048) + +DEF_CONVERT (sext, int16_t, int32_t, 4) +DEF_CONVERT (sext, int16_t, int32_t, 16) +DEF_CONVERT (sext, int16_t, int32_t, 32) +DEF_CONVERT (sext, int16_t, int32_t, 64) +DEF_CONVERT (sext, int16_t, int32_t, 128) +DEF_CONVERT (sext, int16_t, int32_t, 256) +DEF_CONVERT (sext, int16_t, int32_t, 512) +DEF_CONVERT (sext, int16_t, int32_t, 1024) + +DEF_CONVERT (sext, int32_t, int64_t, 4) +DEF_CONVERT (sext, int32_t, int64_t, 16) +DEF_CONVERT (sext, int32_t, int64_t, 32) +DEF_CONVERT (sext, int32_t, int64_t, 64) +DEF_CONVERT (sext, int32_t, int64_t, 128) +DEF_CONVERT (sext, int32_t, int64_t, 256) + +DEF_CONVERT (zext, uint8_t, uint16_t, 4) +DEF_CONVERT (zext, uint8_t, uint16_t, 16) +DEF_CONVERT (zext, uint8_t, uint16_t, 32) +DEF_CONVERT (zext, uint8_t, uint16_t, 64) +DEF_CONVERT (zext, uint8_t, uint16_t, 128) +DEF_CONVERT (zext, uint8_t, uint16_t, 256) +DEF_CONVERT (zext, uint8_t, uint16_t, 512) +DEF_CONVERT (zext, uint8_t, uint16_t, 1024) +DEF_CONVERT (zext, uint8_t, uint16_t, 2048) + +DEF_CONVERT (zext, uint16_t, uint32_t, 4) +DEF_CONVERT (zext, uint16_t, uint32_t, 16) +DEF_CONVERT (zext, uint16_t, uint32_t, 32) +DEF_CONVERT (zext, uint16_t, uint32_t, 64) +DEF_CONVERT (zext, uint16_t, uint32_t, 128) +DEF_CONVERT (zext, uint16_t, uint32_t, 256) +DEF_CONVERT (zext, uint16_t, uint32_t, 512) +DEF_CONVERT (zext, uint16_t, uint32_t, 1024) + +DEF_CONVERT (zext, uint32_t, uint64_t, 4) +DEF_CONVERT (zext, uint32_t, uint64_t, 16) +DEF_CONVERT (zext, uint32_t, uint64_t, 32) +DEF_CONVERT (zext, uint32_t, uint64_t, 64) +DEF_CONVERT (zext, uint32_t, uint64_t, 128) +DEF_CONVERT (zext, uint32_t, uint64_t, 256) + +/* { dg-final { scan-assembler-times {vsext\.vf2} 23 } } */ +/* { dg-final { scan-assembler-times {vzext\.vf2} 23 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-2.c new file mode 100644 index 0000000..03968a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-2.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (sext, int8_t, int32_t, 4) +DEF_CONVERT (sext, int8_t, int32_t, 16) +DEF_CONVERT (sext, int8_t, int32_t, 32) +DEF_CONVERT (sext, int8_t, int32_t, 64) +DEF_CONVERT (sext, int8_t, int32_t, 128) +DEF_CONVERT (sext, int8_t, int32_t, 256) +DEF_CONVERT (sext, int8_t, int32_t, 512) +DEF_CONVERT (sext, int8_t, int32_t, 1024) + +DEF_CONVERT (sext, int16_t, int64_t, 4) +DEF_CONVERT (sext, int16_t, int64_t, 16) +DEF_CONVERT (sext, int16_t, int64_t, 32) +DEF_CONVERT (sext, int16_t, int64_t, 64) +DEF_CONVERT (sext, int16_t, int64_t, 128) +DEF_CONVERT (sext, int16_t, int64_t, 256) +DEF_CONVERT (sext, int16_t, int64_t, 512) + +DEF_CONVERT (zext, uint8_t, uint32_t, 4) +DEF_CONVERT (zext, uint8_t, uint32_t, 16) +DEF_CONVERT (zext, uint8_t, uint32_t, 32) +DEF_CONVERT (zext, uint8_t, uint32_t, 64) +DEF_CONVERT (zext, uint8_t, uint32_t, 128) +DEF_CONVERT (zext, uint8_t, uint32_t, 256) +DEF_CONVERT (zext, uint8_t, uint32_t, 512) +DEF_CONVERT (zext, uint8_t, uint32_t, 1024) + +DEF_CONVERT (zext, uint16_t, uint64_t, 4) +DEF_CONVERT (zext, uint16_t, uint64_t, 16) +DEF_CONVERT (zext, uint16_t, uint64_t, 32) +DEF_CONVERT (zext, uint16_t, uint64_t, 64) +DEF_CONVERT (zext, uint16_t, uint64_t, 128) +DEF_CONVERT (zext, uint16_t, uint64_t, 256) +DEF_CONVERT (zext, uint16_t, uint64_t, 512) + +/* { dg-final { scan-assembler-times {vsext\.vf4} 15 } } */ +/* { dg-final { scan-assembler-times {vzext\.vf4} 15 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-3.c new file mode 100644 index 0000000..4cc1930 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-3.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (sext, int8_t, int64_t, 4) +DEF_CONVERT (sext, int8_t, int64_t, 16) +DEF_CONVERT (sext, int8_t, int64_t, 32) +DEF_CONVERT (sext, int8_t, int64_t, 64) +DEF_CONVERT (sext, int8_t, int64_t, 128) +DEF_CONVERT (sext, int8_t, int64_t, 256) +DEF_CONVERT (sext, int8_t, int64_t, 512) + +DEF_CONVERT (zext, uint8_t, uint64_t, 4) +DEF_CONVERT (zext, uint8_t, uint64_t, 16) +DEF_CONVERT (zext, uint8_t, uint64_t, 32) +DEF_CONVERT (zext, uint8_t, uint64_t, 64) +DEF_CONVERT (zext, uint8_t, uint64_t, 128) +DEF_CONVERT (zext, uint8_t, uint64_t, 256) +DEF_CONVERT (zext, uint8_t, uint64_t, 512) + +/* { dg-final { scan-assembler-times {vsext\.vf8} 7 } } */ +/* { dg-final { scan-assembler-times {vzext\.vf8} 7 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-4.c new file mode 100644 index 0000000..7593a35 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-4.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fwcvt, _Float16, float, 4) +DEF_CONVERT (fwcvt, _Float16, float, 16) +DEF_CONVERT (fwcvt, _Float16, float, 32) +DEF_CONVERT (fwcvt, _Float16, float, 64) +DEF_CONVERT (fwcvt, _Float16, float, 128) +DEF_CONVERT (fwcvt, _Float16, float, 256) +DEF_CONVERT (fwcvt, _Float16, float, 512) +DEF_CONVERT (fwcvt, _Float16, float, 1024) + +DEF_CONVERT (fwcvt, float, double, 4) +DEF_CONVERT (fwcvt, float, double, 16) +DEF_CONVERT (fwcvt, float, double, 32) +DEF_CONVERT (fwcvt, float, double, 64) +DEF_CONVERT (fwcvt, float, double, 128) +DEF_CONVERT (fwcvt, float, double, 256) + +/* { dg-final { scan-assembler-times {vfwcvt\.f\.f\.v} 14 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-5.c new file mode 100644 index 0000000..5dca5a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/ext-5.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fwcvt, _Float16, double, 4) +DEF_CONVERT (fwcvt, _Float16, double, 16) +DEF_CONVERT (fwcvt, _Float16, double, 32) +DEF_CONVERT (fwcvt, _Float16, double, 64) +DEF_CONVERT (fwcvt, _Float16, double, 128) +DEF_CONVERT (fwcvt, _Float16, double, 256) +DEF_CONVERT (fwcvt, _Float16, double, 512) + +/* { dg-final { scan-assembler-times {vfwcvt\.f\.f\.v} 14 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-1.c new file mode 100644 index 0000000..7f9073a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMA_VV (fma, 2, int8_t) +DEF_FMA_VV (fma, 4, int8_t) +DEF_FMA_VV (fma, 8, int8_t) +DEF_FMA_VV (fma, 16, int8_t) +DEF_FMA_VV (fma, 32, int8_t) +DEF_FMA_VV (fma, 64, int8_t) +DEF_FMA_VV (fma, 128, int8_t) +DEF_FMA_VV (fma, 256, int8_t) +DEF_FMA_VV (fma, 512, int8_t) +DEF_FMA_VV (fma, 1024, int8_t) +DEF_FMA_VV (fma, 2048, int8_t) +DEF_FMA_VV (fma, 4096, int8_t) + +DEF_FMA_VV (fma, 2, uint8_t) +DEF_FMA_VV (fma, 4, uint8_t) +DEF_FMA_VV (fma, 8, uint8_t) +DEF_FMA_VV (fma, 16, uint8_t) +DEF_FMA_VV (fma, 32, uint8_t) +DEF_FMA_VV (fma, 64, uint8_t) +DEF_FMA_VV (fma, 128, uint8_t) +DEF_FMA_VV (fma, 256, uint8_t) +DEF_FMA_VV (fma, 512, uint8_t) +DEF_FMA_VV (fma, 1024, uint8_t) +DEF_FMA_VV (fma, 2048, uint8_t) +DEF_FMA_VV (fma, 4096, uint8_t) + +/* { dg-final { scan-assembler-times {vma[c-d][c-d]\.vv} 24 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-2.c new file mode 100644 index 0000000..ddc4b55 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-2.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMA_VV (fma, 2, int16_t) +DEF_FMA_VV (fma, 4, int16_t) +DEF_FMA_VV (fma, 8, int16_t) +DEF_FMA_VV (fma, 16, int16_t) +DEF_FMA_VV (fma, 32, int16_t) +DEF_FMA_VV (fma, 64, int16_t) +DEF_FMA_VV (fma, 128, int16_t) +DEF_FMA_VV (fma, 256, int16_t) +DEF_FMA_VV (fma, 512, int16_t) +DEF_FMA_VV (fma, 1024, int16_t) +DEF_FMA_VV (fma, 2048, int16_t) + +DEF_FMA_VV (fma, 2, uint16_t) +DEF_FMA_VV (fma, 4, uint16_t) +DEF_FMA_VV (fma, 8, uint16_t) +DEF_FMA_VV (fma, 16, uint16_t) +DEF_FMA_VV (fma, 32, uint16_t) +DEF_FMA_VV (fma, 64, uint16_t) +DEF_FMA_VV (fma, 128, uint16_t) +DEF_FMA_VV (fma, 256, uint16_t) +DEF_FMA_VV (fma, 512, uint16_t) +DEF_FMA_VV (fma, 1024, uint16_t) +DEF_FMA_VV (fma, 2048, uint16_t) + +/* { dg-final { scan-assembler-times {vma[c-d][c-d]\.vv} 22 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-3.c new file mode 100644 index 0000000..3bb52ae --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-3.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMA_VV (fma, 2, int32_t) +DEF_FMA_VV (fma, 4, int32_t) +DEF_FMA_VV (fma, 8, int32_t) +DEF_FMA_VV (fma, 16, int32_t) +DEF_FMA_VV (fma, 32, int32_t) +DEF_FMA_VV (fma, 64, int32_t) +DEF_FMA_VV (fma, 128, int32_t) +DEF_FMA_VV (fma, 256, int32_t) +DEF_FMA_VV (fma, 512, int32_t) +DEF_FMA_VV (fma, 1024, int32_t) + +DEF_FMA_VV (fma, 2, uint32_t) +DEF_FMA_VV (fma, 4, uint32_t) +DEF_FMA_VV (fma, 8, uint32_t) +DEF_FMA_VV (fma, 16, uint32_t) +DEF_FMA_VV (fma, 32, uint32_t) +DEF_FMA_VV (fma, 64, uint32_t) +DEF_FMA_VV (fma, 128, uint32_t) +DEF_FMA_VV (fma, 256, uint32_t) +DEF_FMA_VV (fma, 512, uint32_t) +DEF_FMA_VV (fma, 1024, uint32_t) + +/* { dg-final { scan-assembler-times {vma[c-d][c-d]\.vv} 20 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-4.c new file mode 100644 index 0000000..903a4f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-4.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMA_VV (fma, 2, int64_t) +DEF_FMA_VV (fma, 4, int64_t) +DEF_FMA_VV (fma, 8, int64_t) +DEF_FMA_VV (fma, 16, int64_t) +DEF_FMA_VV (fma, 32, int64_t) +DEF_FMA_VV (fma, 64, int64_t) +DEF_FMA_VV (fma, 128, int64_t) +DEF_FMA_VV (fma, 256, int64_t) +DEF_FMA_VV (fma, 512, int64_t) + +DEF_FMA_VV (fma, 2, uint64_t) +DEF_FMA_VV (fma, 4, uint64_t) +DEF_FMA_VV (fma, 8, uint64_t) +DEF_FMA_VV (fma, 16, uint64_t) +DEF_FMA_VV (fma, 32, uint64_t) +DEF_FMA_VV (fma, 64, uint64_t) +DEF_FMA_VV (fma, 128, uint64_t) +DEF_FMA_VV (fma, 256, uint64_t) +DEF_FMA_VV (fma, 512, uint64_t) + +/* { dg-final { scan-assembler-times {vma[c-d][c-d]\.vv} 18 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-5.c new file mode 100644 index 0000000..de565b76 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-5.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMA_VV (fma, 2, _Float16) +DEF_FMA_VV (fma, 4, _Float16) +DEF_FMA_VV (fma, 8, _Float16) +DEF_FMA_VV (fma, 16, _Float16) +DEF_FMA_VV (fma, 32, _Float16) +DEF_FMA_VV (fma, 64, _Float16) +DEF_FMA_VV (fma, 128, _Float16) +DEF_FMA_VV (fma, 256, _Float16) +DEF_FMA_VV (fma, 512, _Float16) +DEF_FMA_VV (fma, 1024, _Float16) +DEF_FMA_VV (fma, 2048, _Float16) + +/* { dg-final { scan-assembler-times {vfma[c-d][c-d]\.vv} 11 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-6.c new file mode 100644 index 0000000..97fd9b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-6.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMA_VV (fma, 2, float) +DEF_FMA_VV (fma, 4, float) +DEF_FMA_VV (fma, 8, float) +DEF_FMA_VV (fma, 16, float) +DEF_FMA_VV (fma, 32, float) +DEF_FMA_VV (fma, 64, float) +DEF_FMA_VV (fma, 128, float) +DEF_FMA_VV (fma, 256, float) +DEF_FMA_VV (fma, 512, float) +DEF_FMA_VV (fma, 1024, float) + +/* { dg-final { scan-assembler-times {vfma[c-d][c-d]\.vv} 10 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-7.c new file mode 100644 index 0000000..c6dc9f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fma-7.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMA_VV (fma, 2, double) +DEF_FMA_VV (fma, 4, double) +DEF_FMA_VV (fma, 8, double) +DEF_FMA_VV (fma, 16, double) +DEF_FMA_VV (fma, 32, double) +DEF_FMA_VV (fma, 64, double) +DEF_FMA_VV (fma, 128, double) +DEF_FMA_VV (fma, 256, double) +DEF_FMA_VV (fma, 512, double) + +/* { dg-final { scan-assembler-times {vfma[c-d][c-d]\.vv} 9 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-1.c new file mode 100644 index 0000000..491ed00 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMS_VV (fms, 2, _Float16) +DEF_FMS_VV (fms, 4, _Float16) +DEF_FMS_VV (fms, 8, _Float16) +DEF_FMS_VV (fms, 16, _Float16) +DEF_FMS_VV (fms, 32, _Float16) +DEF_FMS_VV (fms, 64, _Float16) +DEF_FMS_VV (fms, 128, _Float16) +DEF_FMS_VV (fms, 256, _Float16) +DEF_FMS_VV (fms, 512, _Float16) +DEF_FMS_VV (fms, 1024, _Float16) +DEF_FMS_VV (fms, 2048, _Float16) + +/* { dg-final { scan-assembler-times {vfms[a-u][b-c]\.vv} 11 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-2.c new file mode 100644 index 0000000..ade6cb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMS_VV (fms, 2, float) +DEF_FMS_VV (fms, 4, float) +DEF_FMS_VV (fms, 8, float) +DEF_FMS_VV (fms, 16, float) +DEF_FMS_VV (fms, 32, float) +DEF_FMS_VV (fms, 64, float) +DEF_FMS_VV (fms, 128, float) +DEF_FMS_VV (fms, 256, float) +DEF_FMS_VV (fms, 512, float) +DEF_FMS_VV (fms, 1024, float) + +/* { dg-final { scan-assembler-times {vfms[a-u][b-c]\.vv} 10 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-3.c new file mode 100644 index 0000000..1746f17 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fms-3.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FMS_VV (fms, 2, double) +DEF_FMS_VV (fms, 4, double) +DEF_FMS_VV (fms, 8, double) +DEF_FMS_VV (fms, 16, double) +DEF_FMS_VV (fms, 32, double) +DEF_FMS_VV (fms, 64, double) +DEF_FMS_VV (fms, 128, double) +DEF_FMS_VV (fms, 256, double) +DEF_FMS_VV (fms, 512, double) + +/* { dg-final { scan-assembler-times {vfms[a-u][b-c]\.vv} 9 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-1.c new file mode 100644 index 0000000..418c767 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMA_VV (fnma, 2, int8_t) +DEF_FNMA_VV (fnma, 4, int8_t) +DEF_FNMA_VV (fnma, 8, int8_t) +DEF_FNMA_VV (fnma, 16, int8_t) +DEF_FNMA_VV (fnma, 32, int8_t) +DEF_FNMA_VV (fnma, 64, int8_t) +DEF_FNMA_VV (fnma, 128, int8_t) +DEF_FNMA_VV (fnma, 256, int8_t) +DEF_FNMA_VV (fnma, 512, int8_t) +DEF_FNMA_VV (fnma, 1024, int8_t) +DEF_FNMA_VV (fnma, 2048, int8_t) +DEF_FNMA_VV (fnma, 4096, int8_t) + +DEF_FNMA_VV (fnma, 2, uint8_t) +DEF_FNMA_VV (fnma, 4, uint8_t) +DEF_FNMA_VV (fnma, 8, uint8_t) +DEF_FNMA_VV (fnma, 16, uint8_t) +DEF_FNMA_VV (fnma, 32, uint8_t) +DEF_FNMA_VV (fnma, 64, uint8_t) +DEF_FNMA_VV (fnma, 128, uint8_t) +DEF_FNMA_VV (fnma, 256, uint8_t) +DEF_FNMA_VV (fnma, 512, uint8_t) +DEF_FNMA_VV (fnma, 1024, uint8_t) +DEF_FNMA_VV (fnma, 2048, uint8_t) +DEF_FNMA_VV (fnma, 4096, uint8_t) + +/* { dg-final { scan-assembler-times {vnms[a-u][b-c]\.vv} 24 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-2.c new file mode 100644 index 0000000..c1b629a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-2.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMA_VV (fnma, 2, int16_t) +DEF_FNMA_VV (fnma, 4, int16_t) +DEF_FNMA_VV (fnma, 8, int16_t) +DEF_FNMA_VV (fnma, 16, int16_t) +DEF_FNMA_VV (fnma, 32, int16_t) +DEF_FNMA_VV (fnma, 64, int16_t) +DEF_FNMA_VV (fnma, 128, int16_t) +DEF_FNMA_VV (fnma, 256, int16_t) +DEF_FNMA_VV (fnma, 512, int16_t) +DEF_FNMA_VV (fnma, 1024, int16_t) +DEF_FNMA_VV (fnma, 2048, int16_t) + +DEF_FNMA_VV (fnma, 2, uint16_t) +DEF_FNMA_VV (fnma, 4, uint16_t) +DEF_FNMA_VV (fnma, 8, uint16_t) +DEF_FNMA_VV (fnma, 16, uint16_t) +DEF_FNMA_VV (fnma, 32, uint16_t) +DEF_FNMA_VV (fnma, 64, uint16_t) +DEF_FNMA_VV (fnma, 128, uint16_t) +DEF_FNMA_VV (fnma, 256, uint16_t) +DEF_FNMA_VV (fnma, 512, uint16_t) +DEF_FNMA_VV (fnma, 1024, uint16_t) +DEF_FNMA_VV (fnma, 2048, uint16_t) + +/* { dg-final { scan-assembler-times {vnms[a-u][b-c]\.vv} 22 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-3.c new file mode 100644 index 0000000..bab693e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-3.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMA_VV (fnma, 2, int32_t) +DEF_FNMA_VV (fnma, 4, int32_t) +DEF_FNMA_VV (fnma, 8, int32_t) +DEF_FNMA_VV (fnma, 16, int32_t) +DEF_FNMA_VV (fnma, 32, int32_t) +DEF_FNMA_VV (fnma, 64, int32_t) +DEF_FNMA_VV (fnma, 128, int32_t) +DEF_FNMA_VV (fnma, 256, int32_t) +DEF_FNMA_VV (fnma, 512, int32_t) +DEF_FNMA_VV (fnma, 1024, int32_t) + +DEF_FNMA_VV (fnma, 2, uint32_t) +DEF_FNMA_VV (fnma, 4, uint32_t) +DEF_FNMA_VV (fnma, 8, uint32_t) +DEF_FNMA_VV (fnma, 16, uint32_t) +DEF_FNMA_VV (fnma, 32, uint32_t) +DEF_FNMA_VV (fnma, 64, uint32_t) +DEF_FNMA_VV (fnma, 128, uint32_t) +DEF_FNMA_VV (fnma, 256, uint32_t) +DEF_FNMA_VV (fnma, 512, uint32_t) +DEF_FNMA_VV (fnma, 1024, uint32_t) + +/* { dg-final { scan-assembler-times {vnms[a-u][b-c]\.vv} 20 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-4.c new file mode 100644 index 0000000..f0a7c5d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-4.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMA_VV (fnma, 2, int64_t) +DEF_FNMA_VV (fnma, 4, int64_t) +DEF_FNMA_VV (fnma, 8, int64_t) +DEF_FNMA_VV (fnma, 16, int64_t) +DEF_FNMA_VV (fnma, 32, int64_t) +DEF_FNMA_VV (fnma, 64, int64_t) +DEF_FNMA_VV (fnma, 128, int64_t) +DEF_FNMA_VV (fnma, 256, int64_t) +DEF_FNMA_VV (fnma, 512, int64_t) + +DEF_FNMA_VV (fnma, 2, uint64_t) +DEF_FNMA_VV (fnma, 4, uint64_t) +DEF_FNMA_VV (fnma, 8, uint64_t) +DEF_FNMA_VV (fnma, 16, uint64_t) +DEF_FNMA_VV (fnma, 32, uint64_t) +DEF_FNMA_VV (fnma, 64, uint64_t) +DEF_FNMA_VV (fnma, 128, uint64_t) +DEF_FNMA_VV (fnma, 256, uint64_t) +DEF_FNMA_VV (fnma, 512, uint64_t) + +/* { dg-final { scan-assembler-times {vnms[a-u][b-c]\.vv} 18 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-5.c new file mode 100644 index 0000000..053f1ee --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-5.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMA_VV (fnma, 2, _Float16) +DEF_FNMA_VV (fnma, 4, _Float16) +DEF_FNMA_VV (fnma, 8, _Float16) +DEF_FNMA_VV (fnma, 16, _Float16) +DEF_FNMA_VV (fnma, 32, _Float16) +DEF_FNMA_VV (fnma, 64, _Float16) +DEF_FNMA_VV (fnma, 128, _Float16) +DEF_FNMA_VV (fnma, 256, _Float16) +DEF_FNMA_VV (fnma, 512, _Float16) +DEF_FNMA_VV (fnma, 1024, _Float16) +DEF_FNMA_VV (fnma, 2048, _Float16) + +/* { dg-final { scan-assembler-times {vfnms[a-u][b-c]\.vv} 11 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-6.c new file mode 100644 index 0000000..9053517 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-6.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMA_VV (fnma, 2, float) +DEF_FNMA_VV (fnma, 4, float) +DEF_FNMA_VV (fnma, 8, float) +DEF_FNMA_VV (fnma, 16, float) +DEF_FNMA_VV (fnma, 32, float) +DEF_FNMA_VV (fnma, 64, float) +DEF_FNMA_VV (fnma, 128, float) +DEF_FNMA_VV (fnma, 256, float) +DEF_FNMA_VV (fnma, 512, float) +DEF_FNMA_VV (fnma, 1024, float) + +/* { dg-final { scan-assembler-times {vfnms[a-u][b-c]\.vv} 10 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-7.c new file mode 100644 index 0000000..9952a49 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnma-7.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMA_VV (fnma, 2, double) +DEF_FNMA_VV (fnma, 4, double) +DEF_FNMA_VV (fnma, 8, double) +DEF_FNMA_VV (fnma, 16, double) +DEF_FNMA_VV (fnma, 32, double) +DEF_FNMA_VV (fnma, 64, double) +DEF_FNMA_VV (fnma, 128, double) +DEF_FNMA_VV (fnma, 256, double) +DEF_FNMA_VV (fnma, 512, double) + +/* { dg-final { scan-assembler-times {vfnms[a-u][b-c]\.vv} 9 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-1.c new file mode 100644 index 0000000..7fb8884 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMS_VV (fnms, 2, _Float16) +DEF_FNMS_VV (fnms, 4, _Float16) +DEF_FNMS_VV (fnms, 8, _Float16) +DEF_FNMS_VV (fnms, 16, _Float16) +DEF_FNMS_VV (fnms, 32, _Float16) +DEF_FNMS_VV (fnms, 64, _Float16) +DEF_FNMS_VV (fnms, 128, _Float16) +DEF_FNMS_VV (fnms, 256, _Float16) +DEF_FNMS_VV (fnms, 512, _Float16) +DEF_FNMS_VV (fnms, 1024, _Float16) +DEF_FNMS_VV (fnms, 2048, _Float16) + +/* { dg-final { scan-assembler-times {vfnma[c-d][c-d]\.vv} 11 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-2.c new file mode 100644 index 0000000..b044061 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMS_VV (fnms, 2, float) +DEF_FNMS_VV (fnms, 4, float) +DEF_FNMS_VV (fnms, 8, float) +DEF_FNMS_VV (fnms, 16, float) +DEF_FNMS_VV (fnms, 32, float) +DEF_FNMS_VV (fnms, 64, float) +DEF_FNMS_VV (fnms, 128, float) +DEF_FNMS_VV (fnms, 256, float) +DEF_FNMS_VV (fnms, 512, float) +DEF_FNMS_VV (fnms, 1024, float) + +/* { dg-final { scan-assembler-times {vfnma[c-d][c-d]\.vv} 10 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-3.c new file mode 100644 index 0000000..5547bc4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/fnms-3.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_FNMS_VV (fnms, 2, double) +DEF_FNMS_VV (fnms, 4, double) +DEF_FNMS_VV (fnms, 8, double) +DEF_FNMS_VV (fnms, 16, double) +DEF_FNMS_VV (fnms, 32, double) +DEF_FNMS_VV (fnms, 64, double) +DEF_FNMS_VV (fnms, 128, double) +DEF_FNMS_VV (fnms, 256, double) +DEF_FNMS_VV (fnms, 512, double) + +/* { dg-final { scan-assembler-times {vfnma[c-d][c-d]\.vv} 9 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/neg-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/neg-2.c new file mode 100644 index 0000000..c2ab009 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/neg-2.c @@ -0,0 +1,52 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_OP_V (neg, 2, _Float16, -) +DEF_OP_V (neg, 4, _Float16, -) +DEF_OP_V (neg, 8, _Float16, -) +DEF_OP_V (neg, 16, _Float16, -) +DEF_OP_V (neg, 32, _Float16, -) +DEF_OP_V (neg, 64, _Float16, -) +DEF_OP_V (neg, 128, _Float16, -) +DEF_OP_V (neg, 256, _Float16, -) +DEF_OP_V (neg, 512, _Float16, -) +DEF_OP_V (neg, 1024, _Float16, -) +DEF_OP_V (neg, 2048, _Float16, -) + +DEF_OP_V (neg, 2, float, -) +DEF_OP_V (neg, 4, float, -) +DEF_OP_V (neg, 8, float, -) +DEF_OP_V (neg, 16, float, -) +DEF_OP_V (neg, 32, float, -) +DEF_OP_V (neg, 64, float, -) +DEF_OP_V (neg, 128, float, -) +DEF_OP_V (neg, 256, float, -) +DEF_OP_V (neg, 512, float, -) +DEF_OP_V (neg, 1024, float, -) + +DEF_OP_V (neg, 2, double, -) +DEF_OP_V (neg, 4, double, -) +DEF_OP_V (neg, 8, double, -) +DEF_OP_V (neg, 16, double, -) +DEF_OP_V (neg, 32, double, -) +DEF_OP_V (neg, 64, double, -) +DEF_OP_V (neg, 128, double, -) +DEF_OP_V (neg, 256, double, -) +DEF_OP_V (neg, 512, double, -) + +/* { dg-final { scan-assembler-times {vfneg\.v\s+v[0-9]+,\s*v[0-9]+} 30 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c index db2295b..e25e7b5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c @@ -53,5 +53,5 @@ DEF_OP_VV (shift, 128, int64_t, <<) DEF_OP_VV (shift, 256, int64_t, <<) DEF_OP_VV (shift, 512, int64_t, <<) -/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 41 } } */ +/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 43 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-1.c new file mode 100644 index 0000000..ae129d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-1.c @@ -0,0 +1,71 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (trunc, int16_t, int8_t, 4) +DEF_CONVERT (trunc, int16_t, int8_t, 16) +DEF_CONVERT (trunc, int16_t, int8_t, 32) +DEF_CONVERT (trunc, int16_t, int8_t, 64) +DEF_CONVERT (trunc, int16_t, int8_t, 128) +DEF_CONVERT (trunc, int16_t, int8_t, 256) +DEF_CONVERT (trunc, int16_t, int8_t, 512) +DEF_CONVERT (trunc, int16_t, int8_t, 1024) +DEF_CONVERT (trunc, int16_t, int8_t, 2048) + +DEF_CONVERT (trunc, int32_t, int16_t, 4) +DEF_CONVERT (trunc, int32_t, int16_t, 16) +DEF_CONVERT (trunc, int32_t, int16_t, 32) +DEF_CONVERT (trunc, int32_t, int16_t, 64) +DEF_CONVERT (trunc, int32_t, int16_t, 128) +DEF_CONVERT (trunc, int32_t, int16_t, 256) +DEF_CONVERT (trunc, int32_t, int16_t, 512) +DEF_CONVERT (trunc, int32_t, int16_t, 1024) + +DEF_CONVERT (trunc, int64_t, int32_t, 4) +DEF_CONVERT (trunc, int64_t, int32_t, 16) +DEF_CONVERT (trunc, int64_t, int32_t, 32) +DEF_CONVERT (trunc, int64_t, int32_t, 64) +DEF_CONVERT (trunc, int64_t, int32_t, 128) +DEF_CONVERT (trunc, int64_t, int32_t, 256) + +DEF_CONVERT (trunc, uint16_t, uint8_t, 4) +DEF_CONVERT (trunc, uint16_t, uint8_t, 16) +DEF_CONVERT (trunc, uint16_t, uint8_t, 32) +DEF_CONVERT (trunc, uint16_t, uint8_t, 64) +DEF_CONVERT (trunc, uint16_t, uint8_t, 128) +DEF_CONVERT (trunc, uint16_t, uint8_t, 256) +DEF_CONVERT (trunc, uint16_t, uint8_t, 512) +DEF_CONVERT (trunc, uint16_t, uint8_t, 1024) +DEF_CONVERT (trunc, uint16_t, uint8_t, 2048) + +DEF_CONVERT (trunc, uint32_t, uint16_t, 4) +DEF_CONVERT (trunc, uint32_t, uint16_t, 16) +DEF_CONVERT (trunc, uint32_t, uint16_t, 32) +DEF_CONVERT (trunc, uint32_t, uint16_t, 64) +DEF_CONVERT (trunc, uint32_t, uint16_t, 128) +DEF_CONVERT (trunc, uint32_t, uint16_t, 256) +DEF_CONVERT (trunc, uint32_t, uint16_t, 512) +DEF_CONVERT (trunc, uint32_t, uint16_t, 1024) + +DEF_CONVERT (trunc, uint64_t, uint32_t, 4) +DEF_CONVERT (trunc, uint64_t, uint32_t, 16) +DEF_CONVERT (trunc, uint64_t, uint32_t, 32) +DEF_CONVERT (trunc, uint64_t, uint32_t, 64) +DEF_CONVERT (trunc, uint64_t, uint32_t, 128) +DEF_CONVERT (trunc, uint64_t, uint32_t, 256) + +/* { dg-final { scan-assembler-times {vncvt\.x\.x\.w} 46 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-2.c new file mode 100644 index 0000000..0631dad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-2.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (trunc, int32_t, int8_t, 4) +DEF_CONVERT (trunc, int32_t, int8_t, 16) +DEF_CONVERT (trunc, int32_t, int8_t, 32) +DEF_CONVERT (trunc, int32_t, int8_t, 64) +DEF_CONVERT (trunc, int32_t, int8_t, 128) +DEF_CONVERT (trunc, int32_t, int8_t, 256) +DEF_CONVERT (trunc, int32_t, int8_t, 512) +DEF_CONVERT (trunc, int32_t, int8_t, 1024) + +DEF_CONVERT (trunc, int64_t, int16_t, 4) +DEF_CONVERT (trunc, int64_t, int16_t, 16) +DEF_CONVERT (trunc, int64_t, int16_t, 32) +DEF_CONVERT (trunc, int64_t, int16_t, 64) +DEF_CONVERT (trunc, int64_t, int16_t, 128) +DEF_CONVERT (trunc, int64_t, int16_t, 256) +DEF_CONVERT (trunc, int64_t, int16_t, 512) + +DEF_CONVERT (trunc, uint32_t, uint8_t, 4) +DEF_CONVERT (trunc, uint32_t, uint8_t, 16) +DEF_CONVERT (trunc, uint32_t, uint8_t, 32) +DEF_CONVERT (trunc, uint32_t, uint8_t, 64) +DEF_CONVERT (trunc, uint32_t, uint8_t, 128) +DEF_CONVERT (trunc, uint32_t, uint8_t, 256) +DEF_CONVERT (trunc, uint32_t, uint8_t, 512) +DEF_CONVERT (trunc, uint32_t, uint8_t, 1024) + +DEF_CONVERT (trunc, uint64_t, uint16_t, 4) +DEF_CONVERT (trunc, uint64_t, uint16_t, 16) +DEF_CONVERT (trunc, uint64_t, uint16_t, 32) +DEF_CONVERT (trunc, uint64_t, uint16_t, 64) +DEF_CONVERT (trunc, uint64_t, uint16_t, 128) +DEF_CONVERT (trunc, uint64_t, uint16_t, 256) +DEF_CONVERT (trunc, uint64_t, uint16_t, 512) + +/* { dg-final { scan-assembler-times {vncvt\.x\.x\.w} 60 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-3.c new file mode 100644 index 0000000..3c5f045 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-3.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (trunc, int64_t, int8_t, 4) +DEF_CONVERT (trunc, int64_t, int8_t, 16) +DEF_CONVERT (trunc, int64_t, int8_t, 32) +DEF_CONVERT (trunc, int64_t, int8_t, 64) +DEF_CONVERT (trunc, int64_t, int8_t, 128) +DEF_CONVERT (trunc, int64_t, int8_t, 256) +DEF_CONVERT (trunc, int64_t, int8_t, 512) + +DEF_CONVERT (trunc, uint64_t, uint8_t, 4) +DEF_CONVERT (trunc, uint64_t, uint8_t, 16) +DEF_CONVERT (trunc, uint64_t, uint8_t, 32) +DEF_CONVERT (trunc, uint64_t, uint8_t, 64) +DEF_CONVERT (trunc, uint64_t, uint8_t, 128) +DEF_CONVERT (trunc, uint64_t, uint8_t, 256) +DEF_CONVERT (trunc, uint64_t, uint8_t, 512) + +/* { dg-final { scan-assembler-times {vncvt\.x\.x\.w} 42 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-4.c new file mode 100644 index 0000000..d9a5eeb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-4.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fncvt, float, _Float16, 4) +DEF_CONVERT (fncvt, float, _Float16, 16) +DEF_CONVERT (fncvt, float, _Float16, 32) +DEF_CONVERT (fncvt, float, _Float16, 64) +DEF_CONVERT (fncvt, float, _Float16, 128) +DEF_CONVERT (fncvt, float, _Float16, 256) +DEF_CONVERT (fncvt, float, _Float16, 512) +DEF_CONVERT (fncvt, float, _Float16, 1024) + +DEF_CONVERT (fncvt, double, float, 4) +DEF_CONVERT (fncvt, double, float, 16) +DEF_CONVERT (fncvt, double, float, 32) +DEF_CONVERT (fncvt, double, float, 64) +DEF_CONVERT (fncvt, double, float, 128) +DEF_CONVERT (fncvt, double, float, 256) + +/* { dg-final { scan-assembler-times {vfncvt\.f\.f\.w} 14 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-5.c new file mode 100644 index 0000000..b87a5c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/trunc-5.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -fdump-tree-optimized" } */ + +#include "def.h" + +DEF_CONVERT (fncvt, double, _Float16, 4) +DEF_CONVERT (fncvt, double, _Float16, 16) +DEF_CONVERT (fncvt, double, _Float16, 32) +DEF_CONVERT (fncvt, double, _Float16, 64) +DEF_CONVERT (fncvt, double, _Float16, 128) +DEF_CONVERT (fncvt, double, _Float16, 256) +DEF_CONVERT (fncvt, double, _Float16, 512) + +/* { dg-final { scan-assembler-times {vfncvt} 14 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4,4" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "16,16" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "32,32" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "64,64" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "128,128" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "256,256" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "512,512" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "1024,1024" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "2048,2048" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-1.c new file mode 100644 index 0000000..d53fdc2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-1.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048qi, int8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4096qi, int8_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048qi, int8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4096qi, int8_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 12 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-10.c new file mode 100644 index 0000000..c924236 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-10.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512sf, float, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024sf, float, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512sf, float, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024sf, float, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vfmv\.s\.f\s+v[0-9]+,\s*[fa]+[0-9]+} 10 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 10 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-11.c new file mode 100644 index 0000000..4ec8678 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-11.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256df, double, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512df, double, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256df, double, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512df, double, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vfmv\.s\.f\s+v[0-9]+,\s*[fa]+[0-9]+} 9 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-12.c new file mode 100644 index 0000000..4436830 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-12.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2048qi, int8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4096qi, int8_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[axt][0-9]+} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-13.c new file mode 100644 index 0000000..037a4a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-13.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024hi, int16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2048hi, int16_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[axt][0-9]+} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-14.c new file mode 100644 index 0000000..4dd5888 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-14.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512si, int32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024si, int32_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 10 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-15.c new file mode 100644 index 0000000..77eeed4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-15.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256di, int64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512di, int64_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-16.c new file mode 100644 index 0000000..4f2bb2c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-16.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2048uqi, uint8_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4096uqi, uint8_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-17.c new file mode 100644 index 0000000..9376aee --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-17.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024uhi, uint16_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2048uhi, uint16_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-18.c new file mode 100644 index 0000000..ade887e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-18.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512usi, uint32_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024usi, uint32_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 10 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-19.c new file mode 100644 index 0000000..7106bd9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-19.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256udi, uint64_t) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512udi, uint64_t) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-2.c new file mode 100644 index 0000000..6132bb4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-2.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024hi, int16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048hi, int16_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024hi, int16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048hi, int16_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 11 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-20.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-20.c new file mode 100644 index 0000000..2da3e3c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-20.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024hf, _Float16) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2048hf, _Float16) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-21.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-21.c new file mode 100644 index 0000000..db2682a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-21.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512sf, float) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1024sf, float) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[atx][0-9]+} 10 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-22.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-22.c new file mode 100644 index 0000000..3bb3936 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-22.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_SCALAR_INDEX (vec_set, v1df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v2df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v4df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v8df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v16df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v32df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v64df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v128df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v256df, double) +DEF_VEC_SET_SCALAR_INDEX (vec_set, v512df, double) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vslideup\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[axt][0-9]+} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-3.c new file mode 100644 index 0000000..6080060 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-3.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512si, int32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024si, int32_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512si, int32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024si, int32_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 10 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 10 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-4.c new file mode 100644 index 0000000..09852f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-4.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256di, int64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512di, int64_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256di, int64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512di, int64_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 9 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-5.c new file mode 100644 index 0000000..b6a4d1a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-5.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048uqi, uint8_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4096uqi, uint8_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048uqi, uint8_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4096uqi, uint8_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 12 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-6.c new file mode 100644 index 0000000..11e22db --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-6.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024uhi, uint16_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048uhi, uint16_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024uhi, uint16_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048uhi, uint16_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 11 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-7.c new file mode 100644 index 0000000..d4ce093 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-7.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512usi, uint32_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024usi, uint32_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512usi, uint32_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024usi, uint32_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 10 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 10 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-8.c new file mode 100644 index 0000000..4beb2b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-8.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256udi, uint64_t, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512udi, uint64_t, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256udi, uint64_t, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512udi, uint64_t, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vmv\.s\.x\s+v[0-9]+,\s*[atx][0-9]+} 9 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-9.c new file mode 100644 index 0000000..b59f3f3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/vec-set-9.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2 --param=riscv-autovec-lmul=m8" } */ + +#include "def.h" + +DEF_VEC_SET_IMM_INDEX (vec_set, v1hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v4hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v8hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v16hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v32hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v64hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v128hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v256hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v512hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024hf, _Float16, 0) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048hf, _Float16, 0) + +DEF_VEC_SET_IMM_INDEX (vec_set, v2hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v4hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v8hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v16hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v32hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v64hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v128hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v256hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v512hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v1024hf, _Float16, 1) +DEF_VEC_SET_IMM_INDEX (vec_set, v2048hf, _Float16, 1) + +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-assembler-times {vfmv\.s\.f\s+v[0-9]+,\s*[fa]+[0-9]+} 11 } } */ +/* { dg-final { scan-assembler-times {vslideup\.vi\s+v[0-9]+,\s*v[0-9]+,\s*1} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c index e2ec4ee..b6cbb10 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c index 490f1a4..28aacb9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c index 4d44a40..6d39bff 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-11.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c index 2cb2a1e..1f50fd2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-12.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -O3 -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c index 246acf2..9fcdae5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c index b2b1440..d070be2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c index 26f27ea..65e9828 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c index 62b121d..e744c3d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c index cd48537..b79438c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c index 3806e8b..dc98161 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c index 8f41bdf..4ab08b2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-9.c index 969a1e8..d63aaa1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c index 83e16c6..5a38f43 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c index 97036e6..7c7f1c6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c index 1515374..9ded3cd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c index aeac4cb..66183e7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c index 3ff8483..1f42761 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-6.c index fa56f21..977d9de 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c index 2e3f666..5d93a0ed 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c index 2acfbd0..1a496bc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c index da7f870..4d2f7cc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */ +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math -fno-vect-cost-model" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c index ab57e89..e0a4a1f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c @@ -3,4 +3,4 @@ #include "template-1.h" -/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 4 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111450.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111450.c new file mode 100644 index 0000000..50aadcd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111450.c @@ -0,0 +1,100 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32d -O2" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "riscv_vector.h" + +typedef _Float16 float16_t; +typedef float float32_t; +typedef double float64_t; + +/* +**foo: +** vsetvli\s+zero,\s*[a-z0-9]+,e8,m1,ta,ma +** vle8\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** vse8\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** ret +*/ +void foo (int8_t *in, int8_t *out, int n) +{ + vint8m1_t v = __riscv_vlse8_v_i8m1 (in, 1, n); + __riscv_vsse8_v_i8m1 (out, 1, v, n); +} + +/* +**foo1: +** vsetvli\s+zero,\s*[a-z0-9]+,e16,m1,ta,ma +** vle16\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** vse16\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** ret +*/ +void foo1 (int16_t *in, int16_t *out, int n) +{ + vint16m1_t v = __riscv_vlse16_v_i16m1 (in, 2, n); + __riscv_vsse16_v_i16m1 (out, 2, v, n); +} + +/* +**foo2: +** vsetvli\s+zero,\s*[a-z0-9]+,e32,m1,ta,ma +** vle32\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** vse32\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** ret +*/ +void foo2 (int32_t *in, int32_t *out, int n) +{ + vint32m1_t v = __riscv_vlse32_v_i32m1 (in, 4, n); + __riscv_vsse32_v_i32m1 (out, 4, v, n); +} + +/* +**foo3: +** vsetvli\s+zero,\s*[a-z0-9]+,e64,m1,ta,ma +** vle64\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** vse64\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** ret +*/ +void foo3 (int64_t *in, int64_t *out, int n) +{ + vint64m1_t v = __riscv_vlse64_v_i64m1 (in, 8, n); + __riscv_vsse64_v_i64m1 (out, 8, v, n); +} + +/* +**foo4: +** vsetvli\s+zero,\s*[a-z0-9]+,e16,mf2,ta,ma +** vle16\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** vse16\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** ret +*/ +void foo4 (float16_t *in, float16_t *out, int n) +{ + vfloat16mf2_t v = __riscv_vlse16_v_f16mf2 (in, 2, n); + __riscv_vsse16_v_f16mf2 (out, 2, v, n); +} + +/* +**foo5: +** vsetvli\s+zero,\s*[a-z0-9]+,e32,m1,ta,ma +** vle32\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** vse32\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** ret +*/ +void foo5 (float32_t *in, float32_t *out, int n) +{ + vfloat32m1_t v = __riscv_vlse32_v_f32m1 (in, 4, n); + __riscv_vsse32_v_f32m1 (out, 4, v, n); +} + +/* +**foo6: +** vsetvli\s+zero,\s*[a-z0-9]+,e64,m1,ta,ma +** vle64\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** vse64\.v\s+v[0-9]+,\s*0\([a-x0-9]+\) +** ret +*/ +void foo6 (float64_t *in, float64_t *out, int n) +{ + vfloat64m1_t v = __riscv_vlse64_v_f64m1 (in, 8, n); + __riscv_vsse64_v_f64m1 (out, 8, v, n); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c new file mode 100644 index 0000000..7aee75c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/scalar-move-merged-run-1.c @@ -0,0 +1,29 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "-O3 -Wno-psabi" } */ + +#define TEST_VAL 2 + +typedef long long vl_t __attribute__((vector_size(2 * sizeof (long long)))); + +void init_vl (vl_t *u) +{ + vl_t t; + long long *p = (long long *)&t; + + p[0] = p[1] = TEST_VAL; + + *u = t; +} + +int +main () +{ + vl_t vl = {}; + + init_vl (&vl); + + if (vl[0] != TEST_VAL || vl[1] != TEST_VAL) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vdiv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vdiv.c new file mode 100644 index 0000000..0830006 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/simplify-vdiv.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +#define VDIV_WITH_LMUL(LMUL, DTYPE) \ + vint##DTYPE##m##LMUL##_t \ + shortcut_for_riscv_vdiv_case_##LMUL##_##DTYPE \ + (vint##DTYPE##m##LMUL##_t v1, \ + size_t vl) \ + { \ + return __riscv_vdiv_vx_i##DTYPE##m##LMUL (v1, -1, vl); \ + } + +VDIV_WITH_LMUL (1, 16) +VDIV_WITH_LMUL (1, 32) + +/* { dg-final { scan-assembler-times {vneg\.v} 2 } } */ diff --git a/gcc/testsuite/gfortran.dg/bounds_check_fail_7.f90 b/gcc/testsuite/gfortran.dg/bounds_check_fail_7.f90 new file mode 100644 index 0000000..6a8dafc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bounds_check_fail_7.f90 @@ -0,0 +1,20 @@ +! { dg-do run } +! { dg-additional-options "-fcheck=bounds -g" } +! { dg-output "At line 18 .*" } +! { dg-shouldfail "Different CHARACTER lengths (32/0) in array constructor" } +! +! PR fortran/70231 - CHARACTER lengths in array constructors + +program p + implicit none + integer, parameter :: char_len = 32 + integer :: l = 0 + character(char_len) :: ch = "a" + character(char_len), allocatable :: ch_array(:), res1(:), res2(:) + + allocate(ch_array(0)) + res1 = [ ch_array, ch ] ! was false positive + print *, res1 + res2 = [[ch_array, ch(1:l)], ch(1:l)] ! was false negative on x86 + print *, res2 +end diff --git a/gcc/testsuite/gm2/extensions/pass/libc.def b/gcc/testsuite/gm2/extensions/pass/libc.def index 73a5f65..c064569 100644 --- a/gcc/testsuite/gm2/extensions/pass/libc.def +++ b/gcc/testsuite/gm2/extensions/pass/libc.def @@ -14,6 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with gm2; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) + DEFINITION MODULE libc ; FROM SYSTEM IMPORT ADDRESS ; diff --git a/gcc/testsuite/gm2/pim/intrinsic/run/pass/cstub.c b/gcc/testsuite/gm2/pim/intrinsic/run/pass/cstub.c new file mode 100644 index 0000000..8c43ac4 --- /dev/null +++ b/gcc/testsuite/gm2/pim/intrinsic/run/pass/cstub.c @@ -0,0 +1,24 @@ +#if defined(PPC64LE) +typedef __float128 longreal_t; +#else +typedef long double longreal_t; +#endif + +longreal_t +cstub_identicall (longreal_t x) +{ + return x; +} + +double +cstub_identical (double x) +{ + return x; +} + + +float +cstub_identicalf (float x) +{ + return x; +} diff --git a/gcc/testsuite/gm2/pim/intrinsic/run/pass/cstub.def b/gcc/testsuite/gm2/pim/intrinsic/run/pass/cstub.def new file mode 100644 index 0000000..02e2a74 --- /dev/null +++ b/gcc/testsuite/gm2/pim/intrinsic/run/pass/cstub.def @@ -0,0 +1,7 @@ +DEFINITION MODULE FOR "C" cstub ; (*!m2pim+gm2*) + +PROCEDURE identicall (x: LONGREAL) : LONGREAL ; +PROCEDURE identical (x: REAL) : REAL ; +PROCEDURE identicalf (x: SHORTREAL) : SHORTREAL ; + +END cstub. diff --git a/gcc/testsuite/gm2/pim/intrinsic/run/pass/pim-intrinsic-run-pass.exp b/gcc/testsuite/gm2/pim/intrinsic/run/pass/pim-intrinsic-run-pass.exp new file mode 100644 index 0000000..69e8fb6 --- /dev/null +++ b/gcc/testsuite/gm2/pim/intrinsic/run/pass/pim-intrinsic-run-pass.exp @@ -0,0 +1,48 @@ +# 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 +# <http://www.gnu.org/licenses/>. + +# 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 +load_lib file-format.exp +load_lib target-libpath.exp + +set gm2src ${srcdir}/../m2 + +gm2_init_pim "${srcdir}/gm2/pim/intrinsic/run/pass/" +gm2_link_obj "cstub.o" + +if { [istarget powerpc*-*-*] } then { + set mabi_flags "-mabi=ieeelongdouble" + set options [concat "{additional_flags=$mabi_flags}" $options] +} + +set output [target_compile $srcdir/$subdir/cstub.c cstub.o object $options] + +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-execute $testcase "" "pass" +} diff --git a/gcc/testsuite/gm2/pim/intrinsic/run/pass/test.mod b/gcc/testsuite/gm2/pim/intrinsic/run/pass/test.mod new file mode 100644 index 0000000..36deb21 --- /dev/null +++ b/gcc/testsuite/gm2/pim/intrinsic/run/pass/test.mod @@ -0,0 +1,102 @@ +MODULE test ; (*!m2pim+gm2*) + +IMPORT cstub ; +FROM libc IMPORT printf, exit ; +FROM Builtins IMPORT sinl, sin, cosl, cos, log10, log10l ; + + +CONST + epsilon = 0.001 ; + pi = 3.1415927 ; + +VAR + code: INTEGER ; + + +PROCEDURE near (x, y: REAL) ; +VAR + diff: REAL ; +BEGIN + diff := x - y ; + IF diff < 0.0 + THEN + diff := -diff + END ; + IF diff > epsilon + THEN + printf ("failure: %f, %f differ\n", x, y) ; + code := 1 + END +END near ; + + +PROCEDURE nearl (in, out, correct: LONGREAL; func: ARRAY OF CHAR) ; +VAR + diff: LONGREAL ; +BEGIN + diff := out - correct ; + IF diff < 0.0 + THEN + diff := -diff + END ; + IF diff > epsilon + THEN + printf ("failure: %s ( %Lf ) -> %Lf # %Lf \n", func, in, out, correct) ; + code := 1 + END +END nearl ; + + +PROCEDURE testfunc ; +VAR + l: LONGREAL ; + r: REAL ; +BEGIN + near (1.0, 1.0) ; + near (10.0, 10.0) ; + near (100.0, 100.0) ; + nearl (1.0, 1.0, 1.0, "") ; + nearl (10.0, 10.0, 10.0, "") ; + nearl (100.0, 100.0, 100.0, "") ; + + near (cstub.identical (1.0), 1.0) ; + near (cstub.identical (10.0), 10.0) ; + near (cstub.identical (100.0), 100.0) ; + nearl (cstub.identicall (1.0), 1.0, 1.0, "identicall") ; + nearl (cstub.identicall (10.0), 10.0, 10.0, "identicall") ; + nearl (cstub.identicall (100.0), 100.0, 100.0, "identicall") ; + + nearl (pi / 6.0, sinl (pi / 6.0), 0.5, "sinl") ; + near (sin (pi / 6.0), 0.5) ; + nearl (pi / 3.0, cosl (pi / 3.0), 0.5, "cosl") ; + near (cos (pi / 3.0), 0.5) ; + nearl (100.0, log10l (100.0), 2.0, "log10l") ; + near (log10 (100.0), 2.0) ; + + nearl (1.23456789, log10l (1.23456789), 0.091515, "log10l") ; + l := 1.23456789 ; + nearl (l, log10l (l), 0.091515, "log10l") ; + + r := pi / 6.0 ; + l := pi / 6.0 ; + nearl (l, sinl (l), 0.5, "sinl") ; + near (sin (r), 0.5) ; + + r := pi / 3.0 ; + l := pi / 3.0 ; + nearl (l, cosl (l), 0.5, "cosl") ; + near (cos (r), 0.5) ; + + r := 100.0 ; + l := 100.0 ; + nearl (l, log10l (l), 2.0, "log10l") ; + near (log10 (r), 2.0) ; + +END testfunc ; + + +BEGIN + code := 0 ; + testfunc ; + exit (code) +END test. diff --git a/gcc/testsuite/gm2/pim/run/pass/builtins.mod b/gcc/testsuite/gm2/pim/run/pass/builtins.mod new file mode 100644 index 0000000..1cf9fb7 --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/builtins.mod @@ -0,0 +1,79 @@ +MODULE builtins ; (*!m2pim+gm2*) + +FROM Builtins IMPORT log10l ; +FROM libc IMPORT printf, exit ; +FROM libm IMPORT powl ; + + +(* + doPowerOfTen - safely returns the exponent of a LONGREAL as an INTEGER. +*) + +PROCEDURE doPowerOfTen (r: LONGREAL) : INTEGER ; +VAR + i : INTEGER ; + c, d: LONGREAL ; +BEGIN + IF r=0.0 + THEN + RETURN( 0 ) + ELSE + IF r<0.0 + THEN + c := -r + ELSE + c := r + END ; + IF c>=1.0 + THEN + RETURN( VAL(INTEGER, log10l (c)) ) + ELSE + i := 0 ; + LOOP + d := c*powl(10.0, VAL(LONGREAL, i)) ; + IF d>=1.0 + THEN + RETURN( -i ) + ELSE + INC(i) + END + END + END + END +END doPowerOfTen ; + + +PROCEDURE test ; +BEGIN + Assert (doPowerOfTen (1.0), 0) ; + Assert (doPowerOfTen (10.0), 1) ; + Assert (doPowerOfTen (100.0), 2) ; + Assert (doPowerOfTen (-1.0), 0) ; + Assert (doPowerOfTen (-10.0), 1) ; + Assert (doPowerOfTen (-100.0), 2) +END test ; + + +(* + Assert - +*) + +PROCEDURE Assert (func, actual: INTEGER) ; +BEGIN + IF func = actual + THEN + printf ("success: computed %d = actual %d\n", func, actual) + ELSE + printf ("failure: computed %d # actual %d\n", func, actual) ; + code := 1 + END +END Assert ; + + +VAR + code: INTEGER ; +BEGIN + code := 0 ; + test ; + exit (code) +END builtins. diff --git a/gcc/testsuite/gm2/pim/run/pass/convert1.mod b/gcc/testsuite/gm2/pim/run/pass/convert1.mod new file mode 100644 index 0000000..00eb43f --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/convert1.mod @@ -0,0 +1,49 @@ +MODULE convert1 ; + +FROM libc IMPORT printf, exit ; +FROM Builtins IMPORT log10l ; + + +PROCEDURE assert (a, b: INTEGER) ; +BEGIN + IF a # b + THEN + printf ("failure: %d # %d\n", a, b) ; + code := 1 + END +END assert ; + + +PROCEDURE identityl (l: LONGREAL) : LONGREAL ; +BEGIN + RETURN l +END identityl ; + + +PROCEDURE foo (l: LONGREAL) : INTEGER ; +BEGIN + RETURN VAL (INTEGER, identityl (l)) +END foo ; + + +PROCEDURE fooi (l: LONGREAL) : INTEGER ; +BEGIN + RETURN VAL (INTEGER, log10l (l)) +END fooi ; + + +PROCEDURE test ; +BEGIN + assert (foo (1.0), 1) ; + assert (fooi (100.0), 2) ; + assert (fooi (1.23456789), 0) +END test ; + + +VAR + code: INTEGER ; +BEGIN + code := 0 ; + test ; + exit (code) +END convert1. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint1.mod b/gcc/testsuite/gm2/pim/run/pass/longint1.mod new file mode 100644 index 0000000..ed62c5e --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint1.mod @@ -0,0 +1,49 @@ +MODULE longint1 ; + +FROM libc IMPORT printf, exit ; +FROM Builtins IMPORT log10l ; + + +PROCEDURE equals (left, right: LONGREAL) : BOOLEAN ; +CONST + epsilon = 0.001 ; +VAR + diff: LONGREAL ; +BEGIN + IF right > left + THEN + diff := right - left + ELSE + diff := left - right + END ; + RETURN diff <= epsilon +END equals ; + + +PROCEDURE test (function: ARRAY OF CHAR; input, output, result: LONGREAL) ; +BEGIN + printf ("function %s (%Lf) = %Lf", function, input, output) ; + IF equals (output, result) + THEN + printf (" passed") + ELSE + printf (" (incorrect and should be: %Lf)", result) ; + code := 1 + END ; + printf ("\n") +END test ; + + +VAR + code: INTEGER ; + li : LONGINT ; + in, + res : LONGREAL ; +BEGIN + code := 0 ; + li := 123 ; + in := VAL (LONGREAL, li) ; + res := log10l (in) ; + test ("log10l", in, res, 2.0899) ; + exit (code) +END longint1. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint2.mod b/gcc/testsuite/gm2/pim/run/pass/longint2.mod new file mode 100644 index 0000000..7487544 --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint2.mod @@ -0,0 +1,51 @@ +MODULE longint2 ; + +FROM libc IMPORT printf, exit ; +FROM Builtins IMPORT log10l, fabsl ; + + +PROCEDURE equals (left, right: LONGREAL) : BOOLEAN ; +CONST + epsilon = 0.001 ; +VAR + diff: LONGREAL ; +BEGIN + IF right > left + THEN + diff := right - left + ELSE + diff := left - right + END ; + RETURN diff <= epsilon +END equals ; + + +PROCEDURE test (function: ARRAY OF CHAR; input, output, result: LONGREAL) ; +BEGIN + printf ("function %s (%Lf) = %Lf", function, input, output) ; + IF equals (output, result) + THEN + printf (" passed") + ELSE + printf (" (incorrect and should be: %Lf)", result) ; + code := 1 + END ; + printf ("\n") +END test ; + + +VAR + code: INTEGER ; + li : LONGINT ; + in, + res : LONGREAL ; +BEGIN + code := 0 ; + li := 123 ; + in := VAL (LONGREAL, li) ; + res := log10l (in) ; + test ("log10l", in, res, 2.0899) ; + res := fabsl (in) ; + test ("fabsl", in, res, 123.0) ; + exit (code) +END longint2. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint3.mod b/gcc/testsuite/gm2/pim/run/pass/longint3.mod new file mode 100644 index 0000000..73a2531 --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint3.mod @@ -0,0 +1,23 @@ +MODULE longint3 ; + +FROM libc IMPORT exit, printf ; +FROM Builtins IMPORT log10l ; + +PROCEDURE test ; +VAR + li : LONGINT ; + in, + res : LONGREAL ; +BEGIN + li := 123 ; + in := VAL (LONGREAL, li) ; + res := log10l (in) ; + printf ("log10l (%Lf) = %Lf\n", in, res); + in := VAL (REAL, li) ; + res := log10l (in) ; + printf ("log10l (%Lf) = %Lf\n", in, res); +END test ; + +BEGIN + test +END longint3. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint4.mod b/gcc/testsuite/gm2/pim/run/pass/longint4.mod new file mode 100644 index 0000000..d368056 --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint4.mod @@ -0,0 +1,21 @@ +MODULE longint4 ; + +FROM libc IMPORT exit ; + + +PROCEDURE myfunc (x: LONGREAL) : LONGREAL ; +BEGIN + RETURN x +END myfunc ; + + +PROCEDURE test ; +VAR + res : LONGREAL ; +BEGIN + res := myfunc (1.0) +END test ; + +BEGIN + test +END longint4. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint5.mod b/gcc/testsuite/gm2/pim/run/pass/longint5.mod new file mode 100644 index 0000000..785f707 --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint5.mod @@ -0,0 +1,24 @@ +MODULE longint5 ; + +FROM libc IMPORT exit ; + + +PROCEDURE myfunc (x: LONGREAL) : LONGREAL ; + VAR + y: LONGREAL ; +BEGIN + y := 1.2 ; + RETURN y +END myfunc ; + + +PROCEDURE test ; +VAR + res : LONGREAL ; +BEGIN + res := myfunc (1.0) +END test ; + +BEGIN + test +END longint5. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint6.mod b/gcc/testsuite/gm2/pim/run/pass/longint6.mod new file mode 100644 index 0000000..db49fe9 --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint6.mod @@ -0,0 +1,25 @@ +MODULE longint6 ; + +FROM libc IMPORT exit ; +FROM cbuiltin IMPORT sinl ; + + +PROCEDURE myfunc (x: LONGREAL) : LONGREAL ; + VAR + y: LONGREAL ; +BEGIN + y := sinl (x) ; + RETURN y +END myfunc ; + + +PROCEDURE test ; +VAR + res : LONGREAL ; +BEGIN + res := myfunc (1.0) +END test ; + +BEGIN + test +END longint6. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint7.mod b/gcc/testsuite/gm2/pim/run/pass/longint7.mod new file mode 100644 index 0000000..ec05e7a --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint7.mod @@ -0,0 +1,25 @@ +MODULE longint7 ; + +FROM libc IMPORT exit ; +FROM Builtins IMPORT sinl ; + + +PROCEDURE myfunc (x: LONGREAL) : LONGREAL ; + VAR + y: LONGREAL ; +BEGIN + y := sinl (x) ; + RETURN y +END myfunc ; + + +PROCEDURE test ; +VAR + res : LONGREAL ; +BEGIN + res := myfunc (1.0) +END test ; + +BEGIN + test +END longint7. diff --git a/gcc/testsuite/gm2/pim/run/pass/longint8.mod b/gcc/testsuite/gm2/pim/run/pass/longint8.mod new file mode 100644 index 0000000..a11869f --- /dev/null +++ b/gcc/testsuite/gm2/pim/run/pass/longint8.mod @@ -0,0 +1,25 @@ +MODULE longint8 ; + +FROM libc IMPORT exit ; +FROM Builtins IMPORT log10l ; + + +PROCEDURE myfunc (x: LONGREAL) : LONGREAL ; + VAR + y: LONGREAL ; +BEGIN + y := log10l (x) ; + RETURN y +END myfunc ; + + +PROCEDURE test ; +VAR + res : LONGREAL ; +BEGIN + res := myfunc (1.0) +END test ; + +BEGIN + test +END longint8. diff --git a/gcc/testsuite/gm2/pimlib/logitech/run/pass/realconv.mod b/gcc/testsuite/gm2/pimlib/logitech/run/pass/realconv.mod index f50f882..31e27a3 100644 --- a/gcc/testsuite/gm2/pimlib/logitech/run/pass/realconv.mod +++ b/gcc/testsuite/gm2/pimlib/logitech/run/pass/realconv.mod @@ -45,6 +45,7 @@ VAR BEGIN res := 0 ; RealToString(100.0, 10, 10, a, ok) ; + printf ("RealToString generates string: %s\n", a) ; Assert(ok, __FILE__, __LINE__, 'testing ok return BOOLEAN') ; printf("value returned is '%s'\n", ADR(a)) ; Assert(StrEqual('100.000000', a), __FILE__, __LINE__, 'testing return value of "100.000000"') ; 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 index f5e0c07..1010854 100644 --- 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 @@ -22,6 +22,9 @@ if $tracelevel then { strace $tracelevel } +set OLD_TORTURE_OPTIONS $TORTURE_OPTIONS +set TORTURE_OPTIONS "{ { -g } { -g -O2 } { -g -fdebug-builtins } }" + # load support procs load_lib gm2-torture.exp @@ -35,3 +38,5 @@ foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] { gm2-torture-fail $testcase } + +set TORTURE_OPTIONS $OLD_TORTURE_OPTIONS diff --git a/gcc/testsuite/gnat.dg/sync_tag_discriminals.adb b/gcc/testsuite/gnat.dg/sync_tag_discriminals.adb new file mode 100644 index 0000000..b105acf --- /dev/null +++ b/gcc/testsuite/gnat.dg/sync_tag_discriminals.adb @@ -0,0 +1,51 @@ +-- This test is related to sync_tag_limited in that previous versions of GNAT +-- failed to consider a synchronized private extension as limited if it was +-- not derrived from a synchronized interface (i.e. a limited interface). Since +-- such a private type would not be considered limited, GNAT would fail to +-- correctly build the expected discriminals later needed by the creation of +-- the concurrent type's "corresponding record type", leading to a compilation +-- error where the discriminants of the corresponding record type had no +-- identifiers. +-- +-- This test is in addition to sync_tag_limited because the sync_tag_limited +-- would fail for "legality" reasons (default discriminants not allowed for +-- a non-limited taged type). It is also an opportunity to ensure that non- +-- defaulted discriminated synchronized private extensions work as expected. + +-- { dg-do compile } + +procedure Sync_Tag_Discriminals is + + package Ifaces is + + type Test_Interface is limited interface; + + procedure Interface_Action (Test: in out Test_Interface) is abstract; + + end Ifaces; + + + package Implementation is + type Test_Implementation + (Constraint: Positive) is + synchronized new Ifaces.Test_Interface with private; + + private + protected type Test_Implementation + (Constraint: Positive) + is new Ifaces.Test_Interface with + + overriding procedure Interface_Action; + + end Test_Implementation; + end Implementation; + + package body Implementation is + protected body Test_Implementation is + procedure Interface_Action is null; + end; + end Implementation; + +begin + null; +end Sync_Tag_Discriminals; diff --git a/gcc/testsuite/gnat.dg/sync_tag_finalize.adb b/gcc/testsuite/gnat.dg/sync_tag_finalize.adb new file mode 100644 index 0000000..6dffd4a --- /dev/null +++ b/gcc/testsuite/gnat.dg/sync_tag_finalize.adb @@ -0,0 +1,60 @@ +-- In previous versions of GNAT there was a curious bug that caused +-- compilation to fail in the case of a synchronized private extension +-- with non-default discriminants, where the creation of a constrained object +-- (and thus subtype) caused the TSS deep finalize machinery of the internal +-- class-wide constratined subtype (TConstrainedC) to construct a malformed +-- TSS finalize address body. The issue was that the machinery climbs +-- the type parent chain looking for a "non-constrained" type to use as a +-- designated (class-wide) type for a dispatching call to a higher TSS DF +-- subprogram. When there is a discriminated synchronized private extension +-- with known, non-default discriminants (thus unconstrained/indefinite), +-- that search ends up at that private extension declaration. Since the +-- underlying type is actually a concurrent type, class-wide TSS finalizers +-- are not built for the type, but rather the corresponding record type. The +-- TSS machinery that selects the designated type was prevsiously unaware of +-- this caveat, and thus selected an incompatible designated type, leading to +-- failed compilation. +-- +-- TL;DR: When creating a constrained subtype of a synchronized private +-- extension with known non-defaulted disciminants, the class-wide TSS +-- address finalization body for the constrained subtype should dispatch to +-- the corresponding record (class-wide) type deep finalize subprogram. + +-- { dg-do compile } + +procedure Sync_Tag_Finalize is + + package Ifaces is + + type Test_Interface is synchronized interface; + + procedure Interface_Action (Test: in out Test_Interface) is abstract; + + end Ifaces; + + + package Implementation is + type Test_Implementation + (Constraint: Positive) is + synchronized new Ifaces.Test_Interface with private; + + private + protected type Test_Implementation + (Constraint: Positive) + is new Ifaces.Test_Interface with + + overriding procedure Interface_Action; + + end Test_Implementation; + end Implementation; + + package body Implementation is + protected body Test_Implementation is + procedure Interface_Action is null; + end; + end Implementation; + + Constrained: Implementation.Test_Implementation(2); +begin + null; +end; diff --git a/gcc/testsuite/gnat.dg/sync_tag_limited.adb b/gcc/testsuite/gnat.dg/sync_tag_limited.adb new file mode 100644 index 0000000..608f106 --- /dev/null +++ b/gcc/testsuite/gnat.dg/sync_tag_limited.adb @@ -0,0 +1,50 @@ +-- Synchronized tagged types created by a private extension with the keyword +-- 'synchronized' shall be seen as an (immutably) limited tagged type, and +-- should therefore accept default disciminant spectifications. +-- This was a bug in earlier versions of GNAT, whereby GNAT erroneously +-- relied on a parent synchronized interface to determine limitedness +-- of a synchronized private extension. The problem being that a synchronized +-- private extension can derive a non-synchronized interface (specifically a +-- limited interface), Yet the RM makes it clear (7.3(6/2)) that such +-- synchronized private extensions are always limited. +-- +-- Ergo: Default discriminants are of course legal on any synchronized private +-- extension. + +-- { dg-do compile } + +procedure Sync_Tag_Limited is + + package Ifaces is + + type Test_Interface is limited interface; + + procedure Interface_Action (Test: in out Test_Interface) is abstract; + + end Ifaces; + + + package Implementation is + type Test_Implementation + (Constraint: Positive := 1) is + synchronized new Ifaces.Test_Interface with private; + + private + protected type Test_Implementation + (Constraint: Positive := 1) + is new Ifaces.Test_Interface with + + overriding procedure Interface_Action; + + end Test_Implementation; + end Implementation; + + package body Implementation is + protected body Test_Implementation is + procedure Interface_Action is null; + end; + end Implementation; + +begin + null; +end Sync_Tag_Limited; diff --git a/gcc/testsuite/lib/gm2.exp b/gcc/testsuite/lib/gm2.exp index ab58a56..82915e3 100644 --- a/gcc/testsuite/lib/gm2.exp +++ b/gcc/testsuite/lib/gm2.exp @@ -221,6 +221,9 @@ proc gm2_target_compile_default { source dest type options } { if [istarget *-*-solaris2*] { lappend options "ldflags=-lnsl -lsocket" } + if [istarget "powerpc-*-*"] { + lappend options "-mabi=ieeelongdouble" + } lappend options "timeout=[timeout_value]" lappend options "compiler=$GCC_UNDER_TEST" @@ -240,6 +243,7 @@ proc gm2_target_compile { source dest type options } { return [gm2_target_compile_${gm2_compile_method} $source $dest $type $options] } + # # gm2_link_lib - allows tests to specify link libraries. # This _must_ be called before gm2_init. @@ -281,6 +285,9 @@ proc gm2_link_flags { paths } { set shlib_ext [get_shlib_extension] verbose "shared lib extension: $shlib_ext" + if [istarget "powerpc-*-*"] { + lappend flags "-mabi=ieeelongdouble" + } if { $gccpath == "" } { global tool_root_dir diff --git a/gcc/testsuite/lib/modules.exp b/gcc/testsuite/lib/modules.exp new file mode 100644 index 0000000..e24ee76 --- /dev/null +++ b/gcc/testsuite/lib/modules.exp @@ -0,0 +1,100 @@ +# Copyright (C) 1997-2022 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 +# <http://www.gnu.org/licenses/>. + +# Verify various kinds of gcov output: line counts, branch percentages, +# and call return percentages. None of this is language-specific. + +load_lib "target-supports.exp" + +# +# clean-p1689-file -- delete a working file the compiler creates for p1689 +# +# TESTCASE is the name of the test. +# SUFFIX is file suffix + +proc clean-p1689-file { testcase suffix } { + set basename [file tail $testcase] + set base [file rootname $basename] + remote_file host delete $base.$suffix +} + +# +# clean-p1689 -- delete the working files the compiler creates for p1689 +# +# TESTCASE is the name of the test. +# +proc clean-p1689 { testcase } { + clean-p1689-file $testcase "d" + clean-p1689-file $testcase "ddi" +} + +# Call by dg-final to check a P1689 dependency file + +proc run-check-p1689-valid { depfile template } { + global srcdir subdir + # Extract the test file name from the arguments. + set testcase [file rootname [file tail $depfile]] + + verbose "Running P1689 validation for $testcase in $srcdir/$subdir" 2 + set testcase [remote_download host $testcase] + + set pytest_script "test-p1689.py" + if { ![check_effective_target_recent_python3] } { + unsupported "$pytest_script python3 is missing" + return + } + + verbose "running script" 1 + spawn -noecho python3 $srcdir/$subdir/$pytest_script --all --actual $depfile --expect $srcdir/$subdir/$template + + expect { + -re "ERROR: (\[^\r\n\]*)" { + fail $expect_out(0,string) + exp_continue + } + } + + clean-p1689 $testcase +} + +proc run-check-module-dep { depfile flag expected } { + global srcdir subdir + # Extract the test file name from the arguments. + set testcase [file rootname [file tail $depfile]] + + verbose "Verifying dependencies for $testcase in $srcdir/$subdir" 2 + set testcase [remote_download host $testcase] + + set pytest_script "test-depfile.py" + if { ![check_effective_target_recent_python3] } { + unsupported "$pytest_script python3 is missing" + return + } + + verbose "running script test-depfile.py" 1 + spawn -noecho python3 $srcdir/$subdir/$pytest_script --all --depfile $depfile $flag $expected + + expect { + -re "ERROR: (\[^\r\n\]*)" { + fail $expect_out(0,string) + exp_continue + } + } +} + +proc run-check-module-dep-expect-input { depfile expected } { + run-check-module-dep $depfile "--expect-input" $expected +} diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc index 45a1fd3..12c57c1 100644 --- a/gcc/tree-pretty-print.cc +++ b/gcc/tree-pretty-print.cc @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see #endif /* Local functions, macros and variables. */ -static const char *op_symbol (const_tree); +static const char *op_symbol (const_tree, dump_flags_t = TDF_NONE); static void newline_and_indent (pretty_printer *, int); static void maybe_init_pretty_print (FILE *); static void print_struct_decl (pretty_printer *, const_tree, int, dump_flags_t); @@ -4327,7 +4327,7 @@ op_prio (const_tree op) /* Return the symbol associated with operator CODE. */ const char * -op_symbol_code (enum tree_code code) +op_symbol_code (enum tree_code code, dump_flags_t flags) { switch (code) { @@ -4354,14 +4354,14 @@ op_symbol_code (enum tree_code code) return "&"; case ORDERED_EXPR: - return "ord"; + return (flags & TDF_GIMPLE) ? "__ORDERED" : "ord"; case UNORDERED_EXPR: - return "unord"; + return (flags & TDF_GIMPLE) ? "__UNORDERED" : "unord"; case EQ_EXPR: return "=="; case UNEQ_EXPR: - return "u=="; + return (flags & TDF_GIMPLE) ? "__UNEQ" : "u=="; case NE_EXPR: return "!="; @@ -4369,25 +4369,25 @@ op_symbol_code (enum tree_code code) case LT_EXPR: return "<"; case UNLT_EXPR: - return "u<"; + return (flags & TDF_GIMPLE) ? "__UNLT" : "u<"; case LE_EXPR: return "<="; case UNLE_EXPR: - return "u<="; + return (flags & TDF_GIMPLE) ? "__UNLE" : "u<="; case GT_EXPR: return ">"; case UNGT_EXPR: - return "u>"; + return (flags & TDF_GIMPLE) ? "__UNGT" : "u>"; case GE_EXPR: return ">="; case UNGE_EXPR: - return "u>="; + return (flags & TDF_GIMPLE) ? "__UNGE" : "u>="; case LTGT_EXPR: - return "<>"; + return (flags & TDF_GIMPLE) ? "__LTGT" : "<>"; case LSHIFT_EXPR: return "<<"; @@ -4417,7 +4417,7 @@ op_symbol_code (enum tree_code code) return "w*"; case MULT_HIGHPART_EXPR: - return "h*"; + return (flags & TDF_GIMPLE) ? "__MULT_HIGHPART" : "h*"; case NEGATE_EXPR: case MINUS_EXPR: @@ -4488,9 +4488,9 @@ op_symbol_code (enum tree_code code) /* Return the symbol associated with operator OP. */ static const char * -op_symbol (const_tree op) +op_symbol (const_tree op, dump_flags_t flags) { - return op_symbol_code (TREE_CODE (op)); + return op_symbol_code (TREE_CODE (op), flags); } /* Prints the name of a call. NODE is the CALL_EXPR_FN of a CALL_EXPR or diff --git a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h index 681384a..2c8ee9a 100644 --- a/gcc/tree-pretty-print.h +++ b/gcc/tree-pretty-print.h @@ -49,7 +49,7 @@ extern int dump_generic_node (pretty_printer *, tree, int, dump_flags_t, bool); extern void print_declaration (pretty_printer *, tree, int, dump_flags_t); extern int op_code_prio (enum tree_code); extern int op_prio (const_tree); -extern const char *op_symbol_code (enum tree_code); +extern const char *op_symbol_code (enum tree_code, dump_flags_t = TDF_NONE); extern void pretty_print_string (pretty_printer *, const char *, size_t); extern void print_call_name (pretty_printer *, tree, dump_flags_t); extern void pp_tree_identifier (pretty_printer *, tree); diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 1eaf5f6..e464985 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -7004,10 +7004,7 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi) && !type_has_mode_precision_p (TREE_TYPE (lhs))) { if (TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE - && (TYPE_PRECISION (TREE_TYPE (lhs)) - > (targetm.scalar_mode_supported_p (TImode) - ? GET_MODE_PRECISION (TImode) - : GET_MODE_PRECISION (DImode)))) + && TYPE_PRECISION (TREE_TYPE (lhs)) > MAX_FIXED_MODE_SIZE) lookup_lhs = NULL_TREE; else if (TREE_CODE (lhs) == COMPONENT_REF || TREE_CODE (lhs) == MEM_REF) diff --git a/gcc/tree-ssa-threadupdate.cc b/gcc/tree-ssa-threadupdate.cc index a5b9a00..86fe8aa 100644 --- a/gcc/tree-ssa-threadupdate.cc +++ b/gcc/tree-ssa-threadupdate.cc @@ -1454,6 +1454,19 @@ fwd_jt_path_registry::thread_block_1 (basic_block bb, || ((*path)[1]->type == EDGE_COPY_SRC_BLOCK && joiners)) continue; + /* When a NO_COPY_SRC block became non-empty cancel the path. */ + if (path->last ()->type == EDGE_NO_COPY_SRC_BLOCK) + { + auto gsi = gsi_start_nondebug_bb (path->last ()->e->src); + if (!gsi_end_p (gsi) + && !is_ctrl_stmt (gsi_stmt (gsi))) + { + cancel_thread (path, "Non-empty EDGE_NO_COPY_SRC_BLOCK"); + e->aux = NULL; + continue; + } + } + e2 = path->last ()->e; if (!e2 || noloop_only) { diff --git a/gcc/tree-streamer.h b/gcc/tree-streamer.h index ff49d1b..886ee6a 100644 --- a/gcc/tree-streamer.h +++ b/gcc/tree-streamer.h @@ -118,7 +118,10 @@ bp_unpack_machine_mode (struct bitpack_d *bp) lto_input_block *ib = (class lto_input_block *) bp->stream; int last = 1 << ib->file_data->mode_bits; unsigned ix = bp_unpack_enum (bp, machine_mode, last); - return (machine_mode) ib->file_data->mode_table[ix]; + if (ib->file_data->mode_table) + return (machine_mode) ib->file_data->mode_table[ix]; + else + return (machine_mode) ix; } #endif /* GCC_TREE_STREAMER_H */ diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc index 2d9f627..d7b194f 100644 --- a/gcc/tree-vrp.cc +++ b/gcc/tree-vrp.cc @@ -56,11 +56,17 @@ along with GCC; see the file COPYING3. If not see // This class is utilized by VRP and ranger to remove __builtin_unreachable // calls, and reflect any resulting global ranges. // -// maybe_register_block () is called on basic blocks, and if that block -// matches the pattern of one branch being a builtin_unreachable, register -// the resulting executable edge in a list. +// maybe_register() is called on condition statements , and if that +// matches the pattern of one branch being a builtin_unreachable, either check +// for early removal or register the resulting executable edge in a list. // -// After all blocks have been processed, remove_and_update_globals() will +// During early/non-final processing, we check to see if ALL exports from the +// block can be safely updated with a new global value. If they can, then +// we rewrite the condition and update those values immediately. Otherwise +// the unreachable condition is left in the IL until the final pass. +// +// During final processing, after all blocks have been registered, +// remove_and_update_globals() will // - check all exports from registered blocks // - ensure the cache entry of each export is set with the appropriate range // - rewrite the conditions to take the executable edge @@ -71,23 +77,25 @@ along with GCC; see the file COPYING3. If not see class remove_unreachable { public: - remove_unreachable (gimple_ranger &r) : m_ranger (r) { m_list.create (30); } + remove_unreachable (gimple_ranger &r, bool all) : m_ranger (r), final_p (all) + { m_list.create (30); } ~remove_unreachable () { m_list.release (); } - void maybe_register_block (basic_block bb); - bool remove_and_update_globals (bool final_p); + void handle_early (gimple *s, edge e); + void maybe_register (gimple *s); + bool remove_and_update_globals (); vec<std::pair<int, int> > m_list; gimple_ranger &m_ranger; + bool final_p; }; // Check if block BB has a __builtin_unreachable () call on one arm, and // register the executable edge if so. void -remove_unreachable::maybe_register_block (basic_block bb) +remove_unreachable::maybe_register (gimple *s) { - gimple *s = gimple_outgoing_range_stmt_p (bb); - if (!s || gimple_code (s) != GIMPLE_COND) - return; + gcc_checking_assert (gimple_code (s) == GIMPLE_COND); + basic_block bb = gimple_bb (s); edge e0 = EDGE_SUCC (bb, 0); basic_block bb0 = e0->dest; @@ -102,21 +110,150 @@ remove_unreachable::maybe_register_block (basic_block bb) if (un0 == un1) return; - if (un0) - m_list.safe_push (std::make_pair (e1->src->index, e1->dest->index)); + // Constant expressions are ignored. + if (TREE_CODE (gimple_cond_lhs (s)) != SSA_NAME + && TREE_CODE (gimple_cond_rhs (s)) != SSA_NAME) + return; + + edge e = un0 ? e1 : e0; + + if (!final_p) + handle_early (s, e); else - m_list.safe_push (std::make_pair (e0->src->index, e0->dest->index)); + m_list.safe_push (std::make_pair (e->src->index, e->dest->index)); } +// Return true if all uses of NAME are dominated by by block BB. 1 use +// is allowed in block BB, This is one we hope to remove. +// ie +// _2 = _1 & 7; +// if (_2 != 0) +// goto <bb 3>; [0.00%] +// Any additional use of _1 or _2 in this block invalidates early replacement. + +static bool +fully_replaceable (tree name, basic_block bb) +{ + use_operand_p use_p; + imm_use_iterator iter; + bool saw_in_bb = false; + + // If a name loads from memory, we may lose information used in + // commoning opportunities later. See tree-ssa/ssa-pre-34.c. + gimple *def_stmt = SSA_NAME_DEF_STMT (name); + if (gimple_vuse (def_stmt)) + return false; + + FOR_EACH_IMM_USE_FAST (use_p, iter, name) + { + gimple *use_stmt = USE_STMT (use_p); + // Ignore debug stmts and the branch. + if (is_gimple_debug (use_stmt)) + continue; + basic_block use_bb = gimple_bb (use_stmt); + // Only one use in the block allowed to avoid complicated cases. + if (use_bb == bb) + { + if (saw_in_bb) + return false; + else + saw_in_bb = true; + } + else if (!dominated_by_p (CDI_DOMINATORS, use_bb, bb)) + return false; + } + return true; +} + +// This routine is called to check builtin_unreachable calls during any +// time before final removal. The only way we can be sure it does not +// provide any additional information is to expect that we can update the +// global values of all exports from a block. This means the branch +// to the unreachable call must dominate all uses of those ssa-names, with +// the exception that there can be a single use in the block containing +// the branch. IF the name used in the branch is defined in the block, it may +// contain the name of something else that will be an export. And likewise +// that may also use another name that is an export etc. +// +// As long as there is only a single use, we can be sure that there are no other +// side effects (like being passed to a call, or stored to a global, etc. +// This means we will miss cases where there are 2 or more uses that have +// no interveneing statements that may had side effects, but it catches most +// of the caes we care about, and prevents expensive in depth analysis. +// +// Ranger will still reflect the proper ranges at other places in these missed +// cases, we simply will not remove/set globals early. + +void +remove_unreachable::handle_early (gimple *s, edge e) +{ + bool lhs_p = TREE_CODE (gimple_cond_lhs (s)) == SSA_NAME; + bool rhs_p = TREE_CODE (gimple_cond_rhs (s)) == SSA_NAME; + // Do not remove __builtin_unreachable if it confers a relation, or + // that relation may be lost in subsequent passes. + if (lhs_p && rhs_p) + return; + // Do not remove addresses early. ie if (x == &y) + if (lhs_p && TREE_CODE (gimple_cond_rhs (s)) == ADDR_EXPR) + return; + + gcc_checking_assert (gimple_outgoing_range_stmt_p (e->src) == s); + gcc_checking_assert (!final_p); + + // Check if every export use is dominated by this branch. + tree name; + FOR_EACH_GORI_EXPORT_NAME (m_ranger.gori (), e->src, name) + { + if (!fully_replaceable (name, e->src)) + return; + } + + // Set the global value for each. + FOR_EACH_GORI_EXPORT_NAME (m_ranger.gori (), e->src, name) + { + Value_Range r (TREE_TYPE (name)); + m_ranger.range_on_entry (r, e->dest, name); + // Nothing at this late stage we can do if the write fails. + if (!set_range_info (name, r)) + continue; + if (dump_file) + { + fprintf (dump_file, "Global Exported (via early unreachable): "); + print_generic_expr (dump_file, name, TDF_SLIM); + fprintf (dump_file, " = "); + gimple_range_global (r, name); + r.dump (dump_file); + fputc ('\n', dump_file); + } + } + + tree ssa = lhs_p ? gimple_cond_lhs (s) : gimple_cond_rhs (s); + + // Rewrite the condition. + if (e->flags & EDGE_TRUE_VALUE) + gimple_cond_make_true (as_a<gcond *> (s)); + else + gimple_cond_make_false (as_a<gcond *> (s)); + update_stmt (s); + + // If the name on S is defined in this block, see if there is DCE work to do. + if (gimple_bb (SSA_NAME_DEF_STMT (ssa)) == e->src) + { + auto_bitmap dce; + bitmap_set_bit (dce, SSA_NAME_VERSION (ssa)); + simple_dce_from_worklist (dce); + } +} + + // Process the edges in the list, change the conditions and removing any // dead code feeding those conditions. Calculate the range of any // names that may have been exported from those blocks, and determine if // there is any updates to their global ranges.. -// FINAL_P indicates all builtin_unreachable calls should be removed. // Return true if any builtin_unreachables/globals eliminated/updated. bool -remove_unreachable::remove_and_update_globals (bool final_p) +remove_unreachable::remove_and_update_globals () { if (m_list.length () == 0) return false; @@ -140,19 +277,7 @@ remove_unreachable::remove_and_update_globals (bool final_p) edge e = find_edge (src, dest); gimple *s = gimple_outgoing_range_stmt_p (e->src); gcc_checking_assert (gimple_code (s) == GIMPLE_COND); - bool lhs_p = TREE_CODE (gimple_cond_lhs (s)) == SSA_NAME; - bool rhs_p = TREE_CODE (gimple_cond_rhs (s)) == SSA_NAME; - // Do not remove __builtin_unreachable if it confers a relation, or - // that relation will be lost in subsequent passes. Unless its the - // final pass. - if (!final_p && lhs_p && rhs_p) - continue; - // If this is already a constant condition, don't look either - if (!lhs_p && !rhs_p) - continue; - // Do not remove addresses early. ie if (x == &y) - if (!final_p && lhs_p && TREE_CODE (gimple_cond_rhs (s)) == ADDR_EXPR) - continue; + bool dominate_exit_p = true; FOR_EACH_GORI_EXPORT_NAME (m_ranger.gori (), e->src, name) { @@ -827,9 +952,10 @@ class rvrp_folder : public substitute_and_fold_engine { public: - rvrp_folder (gimple_ranger *r) : substitute_and_fold_engine (), - m_unreachable (*r), - m_simplifier (r, r->non_executable_edge_flag) + rvrp_folder (gimple_ranger *r, bool all) + : substitute_and_fold_engine (), + m_unreachable (*r, all), + m_simplifier (r, r->non_executable_edge_flag) { m_ranger = r; m_pta = new pointer_equiv_analyzer (m_ranger); @@ -883,8 +1009,6 @@ public: void post_fold_bb (basic_block bb) override { m_pta->leave (bb); - if (cfun->after_inlining) - m_unreachable.maybe_register_block (bb); } void pre_fold_stmt (gimple *stmt) override @@ -893,7 +1017,12 @@ public: // If this is the last stmt and there are inferred ranges, reparse the // block for transitive inferred ranges that occur earlier in the block. if (stmt == m_last_bb_stmt) - m_ranger->register_transitive_inferred_ranges (gimple_bb (stmt)); + { + m_ranger->register_transitive_inferred_ranges (gimple_bb (stmt)); + // Also check for builtin_unreachable calls. + if (cfun->after_inlining && gimple_code (stmt) == GIMPLE_COND) + m_unreachable.maybe_register (stmt); + } } bool fold_stmt (gimple_stmt_iterator *gsi) override @@ -928,11 +1057,11 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, set_all_edges_as_executable (fun); gimple_ranger *ranger = enable_ranger (fun, false); - rvrp_folder folder (ranger); + rvrp_folder folder (ranger, final_p); phi_analysis_initialize (ranger->const_query ()); folder.substitute_and_fold (); // Remove tagged builtin-unreachable and maybe update globals. - folder.m_unreachable.remove_and_update_globals (final_p); + folder.m_unreachable.remove_and_update_globals (); if (dump_file && (dump_flags & TDF_DETAILS)) ranger->dump (dump_file); diff --git a/gcc/tree.cc b/gcc/tree.cc index b34d75f..8a8d6d5 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -7179,6 +7179,8 @@ build_bitint_type (unsigned HOST_WIDE_INT precision, int unsignedp) { tree itype, ret; + gcc_checking_assert (precision >= 1 + !unsignedp); + if (unsignedp) unsignedp = MAX_INT_CACHED_PREC + 1; @@ -11096,7 +11098,7 @@ signed_or_unsigned_type_for (int unsignedp, tree type) else return NULL_TREE; - if (TREE_CODE (type) == BITINT_TYPE) + if (TREE_CODE (type) == BITINT_TYPE && (unsignedp || bits > 1)) return build_bitint_type (bits, unsignedp); return build_nonstandard_integer_type (bits, unsignedp); } diff --git a/gcc/ubsan.cc b/gcc/ubsan.cc index 25726df..4289ff4 100644 --- a/gcc/ubsan.cc +++ b/gcc/ubsan.cc @@ -136,13 +136,10 @@ ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase) } else { - scalar_int_mode arith_mode - = (targetm.scalar_mode_supported_p (TImode) ? TImode : DImode); - if (TYPE_PRECISION (type) > GET_MODE_PRECISION (arith_mode)) + if (TYPE_PRECISION (type) > MAX_FIXED_MODE_SIZE) return build_zero_cst (pointer_sized_int_node); - type - = build_nonstandard_integer_type (GET_MODE_PRECISION (arith_mode), - TYPE_UNSIGNED (type)); + type = build_nonstandard_integer_type (MAX_FIXED_MODE_SIZE, + TYPE_UNSIGNED (type)); t = fold_build1 (NOP_EXPR, type, t); } } @@ -381,14 +378,9 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle) { /* Temporary hack for -fsanitize=shift with _BitInt(129) and more. libubsan crashes if it is not TK_Integer type. */ - if (TREE_CODE (type) == BITINT_TYPE) - { - scalar_int_mode arith_mode - = (targetm.scalar_mode_supported_p (TImode) - ? TImode : DImode); - if (TYPE_PRECISION (type) > GET_MODE_PRECISION (arith_mode)) - type3 = build_qualified_type (type, TYPE_QUAL_CONST); - } + if (TREE_CODE (type) == BITINT_TYPE + && TYPE_PRECISION (type) > MAX_FIXED_MODE_SIZE) + type3 = build_qualified_type (type, TYPE_QUAL_CONST); if (type3 == type) pstyle = UBSAN_PRINT_NORMAL; } @@ -523,16 +515,10 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle) tkind = 0x0000; break; case BITINT_TYPE: - { - /* FIXME: libubsan right now only supports _BitInts which - fit into DImode or TImode. */ - scalar_int_mode arith_mode = (targetm.scalar_mode_supported_p (TImode) - ? TImode : DImode); - if (TYPE_PRECISION (eltype) <= GET_MODE_PRECISION (arith_mode)) - tkind = 0x0000; - else - tkind = 0xffff; - } + if (TYPE_PRECISION (eltype) <= MAX_FIXED_MODE_SIZE) + tkind = 0x0000; + else + tkind = 0xffff; break; case REAL_TYPE: /* FIXME: libubsan right now only supports float, double and @@ -553,9 +539,7 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle) if (pstyle == UBSAN_PRINT_FORCE_INT) { tkind = 0x0000; - scalar_int_mode arith_mode = (targetm.scalar_mode_supported_p (TImode) - ? TImode : DImode); - tree t = lang_hooks.types.type_for_mode (arith_mode, + tree t = build_nonstandard_integer_type (MAX_FIXED_MODE_SIZE, TYPE_UNSIGNED (eltype)); tinfo = get_ubsan_type_info_for_type (t); } diff --git a/gcc/value-range.h b/gcc/value-range.h index da04be0..a792c59 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -1257,36 +1257,40 @@ frange::set_undefined () verify_range (); } -// Set the NAN bit and adjust the range. +// Set the NAN bits to NAN and adjust the range. inline void -frange::update_nan () +frange::update_nan (const nan_state &nan) { gcc_checking_assert (!undefined_p ()); if (HONOR_NANS (m_type)) { - m_pos_nan = true; - m_neg_nan = true; + m_pos_nan = nan.pos_p (); + m_neg_nan = nan.neg_p (); normalize_kind (); if (flag_checking) verify_range (); } } +// Set the NAN bit to +-NAN. + +inline void +frange::update_nan () +{ + gcc_checking_assert (!undefined_p ()); + nan_state nan (true); + update_nan (nan); +} + // Like above, but set the sign of the NAN. inline void frange::update_nan (bool sign) { gcc_checking_assert (!undefined_p ()); - if (HONOR_NANS (m_type)) - { - m_pos_nan = !sign; - m_neg_nan = sign; - normalize_kind (); - if (flag_checking) - verify_range (); - } + nan_state nan (/*pos=*/!sign, /*neg=*/sign); + update_nan (nan); } inline bool |