diff options
Diffstat (limited to 'gcc/config')
| -rw-r--r-- | gcc/config/aarch64/aarch64-cores.def | 5 | ||||
| -rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 12 | ||||
| -rw-r--r-- | gcc/config/aarch64/aarch64-tune.md | 2 | ||||
| -rw-r--r-- | gcc/config/darwin-c.cc | 7 | ||||
| -rw-r--r-- | gcc/config/gcn/gcn.cc | 9 | ||||
| -rw-r--r-- | gcc/config/gcn/mkoffload.cc | 9 | ||||
| -rw-r--r-- | gcc/config/i386/i386-expand.cc | 9 | ||||
| -rw-r--r-- | gcc/config/i386/i386.cc | 15 | ||||
| -rw-r--r-- | gcc/config/i386/sse.md | 3 | ||||
| -rw-r--r-- | gcc/config/mingw/winnt.cc | 10 | ||||
| -rw-r--r-- | gcc/config/riscv/autovec.md | 31 | ||||
| -rw-r--r-- | gcc/config/riscv/predicates.md | 2 | ||||
| -rw-r--r-- | gcc/config/riscv/riscv-c.cc | 44 | ||||
| -rw-r--r-- | gcc/config/riscv/riscv-protos.h | 4 | ||||
| -rw-r--r-- | gcc/config/riscv/riscv-target-attr.cc | 96 | ||||
| -rw-r--r-- | gcc/config/riscv/riscv-v.cc | 50 | ||||
| -rw-r--r-- | gcc/config/riscv/riscv.cc | 60 | ||||
| -rw-r--r-- | gcc/config/riscv/riscv.opt | 4 | ||||
| -rw-r--r-- | gcc/config/riscv/riscv.opt.urls | 2 | ||||
| -rw-r--r-- | gcc/config/riscv/vector.md | 8 | ||||
| -rw-r--r-- | gcc/config/rs6000/predicates.md | 5 | ||||
| -rw-r--r-- | gcc/config/rs6000/vsx.md | 7 | ||||
| -rw-r--r-- | gcc/config/s390/predicates.md | 5 | ||||
| -rw-r--r-- | gcc/config/s390/vector.md | 7 |
24 files changed, 349 insertions, 57 deletions
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def index b86d80c..851594a 100644 --- a/gcc/config/aarch64/aarch64-cores.def +++ b/gcc/config/aarch64/aarch64-cores.def @@ -229,6 +229,11 @@ AARCH64_CORE("grace", grace, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, SVE2_AES AARCH64_CORE("neoverse-v3", neoversev3, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, MEMTAG, PROFILE), neoversev3, 0x41, 0xd84, -1) AARCH64_CORE("neoverse-v3ae", neoversev3ae, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, MEMTAG, PROFILE), neoversev3ae, 0x41, 0xd83, -1) +AARCH64_CORE("c1-nano", c1nano, cortexa53, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, SME2, RCPC3), cortexa53, 0x41, 0xd8a, -1) +AARCH64_CORE("c1-pro", c1pro, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), neoversen3, 0x41, 0xd8b, -1) +AARCH64_CORE("c1-premium", c1premium, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), neoversev3, 0x41, 0xd90, -1) +AARCH64_CORE("c1-ultra", c1ultra, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), cortexx925, 0x41, 0xd8c, -1) + AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1) /* NVIDIA ('N') cores. */ diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 3f9d5f6..c02ffd6 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -3544,10 +3544,10 @@ rtx reduc = gen_lowpart (V4SImode, tmp); rtx res = gen_reg_rtx (V4SImode); emit_insn (gen_aarch64_uminpv4si (res, reduc, reduc)); - emit_move_insn (tmp, gen_lowpart (<MODE>mode, res)); + tmp = gen_lowpart (<MODE>mode, res); } - rtx val = gen_reg_rtx (DImode); - emit_move_insn (val, gen_lowpart (DImode, tmp)); + + rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode); rtx cc_reg = aarch64_gen_compare_reg (EQ, val, constm1_rtx); rtx cmp = gen_rtx_fmt_ee (EQ, SImode, cc_reg, constm1_rtx); rtx tmp2 = gen_reg_rtx (SImode); @@ -3607,10 +3607,10 @@ rtx reduc = gen_lowpart (V4SImode, tmp); rtx res = gen_reg_rtx (V4SImode); emit_insn (gen_aarch64_umaxpv4si (res, reduc, reduc)); - emit_move_insn (tmp, gen_lowpart (<MODE>mode, res)); + tmp = gen_lowpart (<MODE>mode, res); } - rtx val = gen_reg_rtx (DImode); - emit_move_insn (val, gen_lowpart (DImode, tmp)); + + rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode); rtx cc_reg = aarch64_gen_compare_reg (NE, val, const0_rtx); rtx cmp = gen_rtx_fmt_ee (NE, SImode, cc_reg, const0_rtx); rtx tmp2 = gen_reg_rtx (SImode); diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md index 292796c..d6f1bbc 100644 --- a/gcc/config/aarch64/aarch64-tune.md +++ b/gcc/config/aarch64/aarch64-tune.md @@ -1,5 +1,5 @@ ;; -*- buffer-read-only: t -*- ;; Generated automatically by gentune.sh from aarch64-cores.def (define_attr "tune" - "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,ampere1c,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,applem3_1,applem3_2,applem4_0,applem4_1,applem4_2,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a" + "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,ampere1c,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,applem3_1,applem3_2,applem4_0,applem4_1,applem4_2,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,c1nano,c1pro,c1premium,c1ultra,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a" (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) diff --git a/gcc/config/darwin-c.cc b/gcc/config/darwin-c.cc index 7257015..c3a1cd5 100644 --- a/gcc/config/darwin-c.cc +++ b/gcc/config/darwin-c.cc @@ -537,17 +537,18 @@ find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp) const char *n; for (b = cpp_get_buffer (pfile); - b && cpp_get_file (b) && cpp_get_path (cpp_get_file (b)); + b && cpp_get_file (b) && _cpp_get_file_path (cpp_get_file (b)); b = cpp_get_prev (b)) { - n = find_subframework_file (fname, cpp_get_path (cpp_get_file (b))); + n = find_subframework_file (fname, + _cpp_get_file_path (cpp_get_file (b))); if (n) { /* Logically, the place where we found the subframework is the place where we found the Framework that contains the subframework. This is useful for tracking wether or not we are in a system header. */ - *dirp = cpp_get_dir (cpp_get_file (b)); + *dirp = _cpp_get_file_dir (cpp_get_file (b)); return n; } } diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc index a729ea4..54abf8c 100644 --- a/gcc/config/gcn/gcn.cc +++ b/gcc/config/gcn/gcn.cc @@ -2940,14 +2940,17 @@ gcn_init_cumulative_args (CUMULATIVE_ARGS *cum /* Argument info to init */ , if (!caller && cfun->machine->normal_function) gcn_detect_incoming_pointer_arg (fndecl); - if ((omp_requires_mask & (OMP_REQUIRES_UNIFIED_SHARED_MEMORY - | OMP_REQUIRES_SELF_MAPS)) + static bool warned_xnack = 0; + if (!warned_xnack + && (omp_requires_mask & (OMP_REQUIRES_UNIFIED_SHARED_MEMORY + | OMP_REQUIRES_SELF_MAPS)) && gcn_devices[gcn_arch].xnack_default != HSACO_ATTR_UNSUPPORTED && flag_xnack == HSACO_ATTR_OFF) { warning_at (UNKNOWN_LOCATION, 0, - "Unified Shared Memory is enabled, but XNACK is disabled"); + "Unified Shared Memory is required, but XNACK is disabled"); inform (UNKNOWN_LOCATION, "Try -foffload-options=-mxnack=any"); + warned_xnack = 1; } reinit_regs (); diff --git a/gcc/config/gcn/mkoffload.cc b/gcc/config/gcn/mkoffload.cc index d9d89c6..ac6aae5 100644 --- a/gcc/config/gcn/mkoffload.cc +++ b/gcc/config/gcn/mkoffload.cc @@ -627,9 +627,12 @@ process_asm (FILE *in, FILE *out, FILE *cfile, uint32_t omp_requires) || TEST_XNACK_ON (elf_flags) || xnack_required); if (TEST_XNACK_OFF (elf_flags) && xnack_required) - fatal_error (input_location, - "conflicting settings; XNACK is forced off but Unified " - "Shared Memory is on"); + { + warning (input_location, + "conflicting settings; XNACK is forced off but Unified " + "Shared Memory is required"); + xnack_required = 0; + } /* Start generating the C code. */ if (gcn_stack_size) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index fd9bcaa..438fa4e 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -4159,12 +4159,18 @@ static bool ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1, rtx if_true, rtx if_false) { - machine_mode mode; + machine_mode mode = GET_MODE (dest); bool is_min; rtx tmp; if (code == LT) ; + else if (code == LE && !HONOR_NANS (mode)) + { + /* We can swap LE to GE and then invert to LT. */ + std::swap (cmp_op0, cmp_op1); + std::swap (if_true, if_false); + } else if (code == UNGE) std::swap (if_true, if_false); else @@ -4177,7 +4183,6 @@ ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0, else return false; - mode = GET_MODE (dest); if (immediate_operand (if_false, mode)) if_false = force_reg (mode, if_false); if (immediate_operand (if_true, mode)) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index db43045..75a9cb6 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -26397,7 +26397,20 @@ ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, (TREE_OPERAND (gimple_assign_rhs1 (def), 0)))))) { if (fp) - m_num_sse_needed[where]++; + { + /* Scalar FP values residing in x87 registers need to be + spilled and reloaded. */ + auto mode2 = TYPE_MODE (TREE_TYPE (op)); + if (IS_STACK_MODE (mode2)) + { + int cost + = (ix86_cost->hard_register.fp_store[mode2 == SFmode + ? 0 : 1] + + ix86_cost->sse_load[sse_store_index (mode2)]); + stmt_cost += COSTS_N_INSNS (cost) / 2; + } + m_num_sse_needed[where]++; + } else { m_num_gpr_needed[where]++; diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 0be898c..fb79b2e 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -4900,7 +4900,8 @@ (match_operand:SI 3 "<cmp_imm_predicate>")] UNSPEC_PCMP_ITER))] "TARGET_AVX512F && ix86_pre_reload_split () - && rtx_equal_p (operands[1], operands[2])" + && rtx_equal_p (operands[1], operands[2]) + && (!MEM_P (operands[1]) || !MEM_VOLATILE_P (operands[1]))" "#" "&& 1" [(set (match_dup 0) (match_dup 4))] diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc index b51fd8e..fe2fb4c 100644 --- a/gcc/config/mingw/winnt.cc +++ b/gcc/config/mingw/winnt.cc @@ -446,8 +446,11 @@ mingw_pe_unique_section (tree decl, int reloc) prefix = ".text$"; else if (decl_readonly_section (decl, reloc)) prefix = ".rdata$"; + /* Note that we need two dollar signs for TLS sections + because they need to be ASCII-sorted before .tls$ZZZ + to be properly laid out by the GNU linker. */ else if (DECL_THREAD_LOCAL_P (decl)) - prefix = ".tls$"; + prefix = ".tls$$"; else prefix = ".data$"; len = strlen (name) + strlen (prefix); @@ -522,9 +525,6 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags, *f++ = 'e'; #endif - if (strcmp (name, ".tls$") == 0) - *f++ = 'd'; - if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0) /* readonly data */ { @@ -533,6 +533,8 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags, } else { + if (startswith (name, ".tls$")) + *f++ = 'd'; if (flags & SECTION_CODE) *f++ = 'x'; if (flags & SECTION_WRITE) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index cec0113..c694684 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -2302,6 +2302,37 @@ }) ;; ------------------------------------------------------------------------- +;; ---- [INT] Mask reductions +;; ------------------------------------------------------------------------- + +(define_expand "reduc_sbool_and_scal_<mode>" + [(match_operand:QI 0 "register_operand") + (match_operand:VB_VLS 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_mask_reduction (operands, AND); + DONE; +}) + +(define_expand "reduc_sbool_ior_scal_<mode>" + [(match_operand:QI 0 "register_operand") + (match_operand:VB_VLS 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_mask_reduction (operands, IOR); + DONE; +}) + +(define_expand "reduc_sbool_xor_scal_<mode>" + [(match_operand:QI 0 "register_operand") + (match_operand:VB_VLS 1 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::expand_mask_reduction (operands, XOR); + DONE; +}) + +;; ------------------------------------------------------------------------- ;; ---- [FP] Tree reductions ;; ------------------------------------------------------------------------- ;; Includes: diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 3cc954e..5b44165 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -612,7 +612,7 @@ (match_code "eq,ne,le,leu,gt,gtu,lt,ltu")) (define_predicate "comparison_swappable_operator" - (match_code "gtu")) + (match_code "gtu,gt")) (define_predicate "ge_operator" (match_code "ge,geu")) diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index 4fc0528..24537d5 100644 --- a/gcc/config/riscv/riscv-c.cc +++ b/gcc/config/riscv/riscv-c.cc @@ -213,6 +213,49 @@ riscv_pragma_intrinsic (cpp_reader *) error ("unknown %<#pragma riscv intrinsic%> option %qs", name); } +/* Implement TARGETM.TARGET_OPTION.PRAGMA_PARSE. */ + +static bool +riscv_pragma_target_parse (tree args, tree pop_target) +{ + /* If args is not NULL then process it and setup the target-specific + information that it specifies. */ + if (args) + { + if (!riscv_process_target_attr_for_pragma (args)) + return false; + + riscv_override_options_internal (&global_options); + } + /* args is NULL, restore to the state described in pop_target. */ + else + { + pop_target = pop_target ? pop_target : target_option_default_node; + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (pop_target)); + } + + target_option_current_node + = build_target_option_node (&global_options, &global_options_set); + + riscv_reset_previous_fndecl (); + + /* For the definitions, ensure all newly defined macros are considered + as used for -Wunused-macros. There is no point warning about the + compiler predefined macros. */ + cpp_options *cpp_opts = cpp_get_options (parse_in); + unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros; + cpp_opts->warn_unused_macros = 0; + + cpp_force_token_locations (parse_in, BUILTINS_LOCATION); + riscv_cpu_cpp_builtins (parse_in); + cpp_stop_forcing_token_locations (parse_in); + + cpp_opts->warn_unused_macros = saved_warn_unused_macros; + + return true; +} + /* Implement TARGET_CHECK_BUILTIN_CALL. */ static bool riscv_check_builtin_call (location_t loc, vec<location_t> arg_loc, tree fndecl, @@ -272,5 +315,6 @@ riscv_register_pragmas (void) { targetm.resolve_overloaded_builtin = riscv_resolve_overloaded_builtin; targetm.check_builtin_call = riscv_check_builtin_call; + targetm.target_option.pragma_parse = riscv_pragma_target_parse; c_register_pragma ("riscv", "intrinsic", riscv_pragma_intrinsic); } diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 261c25c..abf9df7 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -664,6 +664,7 @@ bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); void expand_cond_len_unop (unsigned, rtx *); void expand_cond_len_binop (unsigned, rtx *); void expand_reduction (unsigned, unsigned, unsigned, rtx *, rtx); +void expand_mask_reduction (rtx *, rtx_code); void expand_vec_ceil (rtx, rtx, machine_mode, machine_mode); void expand_vec_floor (rtx, rtx, machine_mode, machine_mode); void expand_vec_nearbyint (rtx, rtx, machine_mode, machine_mode); @@ -848,12 +849,15 @@ riscv_option_valid_attribute_p (tree, tree, tree, int); extern bool riscv_option_valid_version_attribute_p (tree, tree, tree, int); extern bool +riscv_process_target_attr_for_pragma (tree); +extern bool riscv_process_target_version_attr (tree, location_t *); extern bool riscv_process_target_version_str (string_slice, location_t *); extern void riscv_override_options_internal (struct gcc_options *); extern void riscv_option_override (void); +extern void riscv_reset_previous_fndecl (void); extern rtx riscv_prefetch_cookie (rtx, rtx); extern bool riscv_prefetch_offset_address_p (rtx, machine_mode); diff --git a/gcc/config/riscv/riscv-target-attr.cc b/gcc/config/riscv/riscv-target-attr.cc index 94f0a29..eb3e688 100644 --- a/gcc/config/riscv/riscv-target-attr.cc +++ b/gcc/config/riscv/riscv-target-attr.cc @@ -44,6 +44,7 @@ public: , m_cpu_info (nullptr) , m_tune (nullptr) , m_priority (0) + , m_max_vect (false) { } @@ -51,6 +52,7 @@ public: bool handle_cpu (const char *); bool handle_tune (const char *); bool handle_priority (const char *); + bool handle_max_vect (const char *); void update_settings (struct gcc_options *opts) const; private: @@ -66,31 +68,35 @@ private: const riscv_cpu_info *m_cpu_info; const char *m_tune; int m_priority; + bool m_max_vect; }; } /* All the information needed to handle a target attribute. NAME is the name of the attribute. - HANDLER is the function that takes the attribute string as an argument. */ + HANDLER is the function that takes the attribute string as an argument. + REQUIRES_ARG indicates whether this attribute requires an argument value. */ struct riscv_attribute_info { const char *name; bool (riscv_target_attr_parser::*handler) (const char *); + bool requires_arg; }; /* The target attributes that we support. */ static const struct riscv_attribute_info riscv_target_attrs[] - = {{"arch", &riscv_target_attr_parser::handle_arch}, - {"cpu", &riscv_target_attr_parser::handle_cpu}, - {"tune", &riscv_target_attr_parser::handle_tune}, - {NULL, NULL}}; + = {{"arch", &riscv_target_attr_parser::handle_arch, true}, + {"cpu", &riscv_target_attr_parser::handle_cpu, true}, + {"tune", &riscv_target_attr_parser::handle_tune, true}, + {"max-vectorization", &riscv_target_attr_parser::handle_max_vect, false}, + {NULL, NULL, false}}; static const struct riscv_attribute_info riscv_target_version_attrs[] - = {{"arch", &riscv_target_attr_parser::handle_arch}, - {"priority", &riscv_target_attr_parser::handle_priority}, - {NULL, NULL}}; + = {{"arch", &riscv_target_attr_parser::handle_arch, true}, + {"priority", &riscv_target_attr_parser::handle_priority, true}, + {NULL, NULL, false}}; bool riscv_target_attr_parser::parse_arch (const char *str) @@ -254,6 +260,17 @@ riscv_target_attr_parser::handle_priority (const char *str) return true; } +/* Handle max-vectorization. There are no further options, just + enable it. */ + +bool +riscv_target_attr_parser::handle_max_vect (const char *str ATTRIBUTE_UNUSED) +{ + m_max_vect = true; + + return true; +} + void riscv_target_attr_parser::update_settings (struct gcc_options *opts) const { @@ -279,6 +296,9 @@ riscv_target_attr_parser::update_settings (struct gcc_options *opts) const if (m_priority) opts->x_riscv_fmv_priority = m_priority; + + if (m_max_vect) + opts->x_riscv_max_vectorization = true; } /* Parse ARG_STR which contains the definition of one target attribute. @@ -303,33 +323,50 @@ riscv_process_one_target_attr (char *arg_str, char *str_to_check = buf.get(); strcpy (str_to_check, arg_str); + /* Split attribute name from argument (if present). */ char *arg = strchr (str_to_check, '='); - - if (!arg) + if (arg) { - if (loc) - error_at (*loc, "attribute %<target(\"%s\")%> does not " - "accept an argument", str_to_check); - return false; + *arg = '\0'; + ++arg; + /* Check for empty argument after '='. */ + if (*arg == '\0') + { + if (loc) + error_at (*loc, "attribute %<target(\"%s\")%> has empty argument", + str_to_check); + return false; + } } - arg[0] = '\0'; - ++arg; - for (const auto *attr = attrs; - attr->name; - ++attr) + /* Find matching attribute. */ + for (const auto *attr = attrs; attr->name; ++attr) { - /* If the names don't match up, or the user has given an argument - to an attribute that doesn't accept one, or didn't give an argument - to an attribute that expects one, fail to match. */ - if (strncmp (str_to_check, attr->name, strlen (attr->name)) != 0) + if (strcmp (str_to_check, attr->name) != 0) continue; + /* Validate argument presence matches expectations. */ + if (attr->requires_arg && !arg) + { + if (loc) + error_at (*loc, "attribute %<target(\"%s\")%> expects " + "an argument", str_to_check); + return false; + } + + if (!attr->requires_arg && arg) + { + if (loc) + error_at (*loc, "attribute %<target(\"%s\")%> does not " + "accept an argument", str_to_check); + return false; + } + return (&attr_parser->*attr->handler) (arg); } if (loc) - error_at (*loc, "Got unknown attribute %<target(\"%s\")%>", str_to_check); + error_at (*loc, "unknown attribute %<target(\"%s\")%>", str_to_check); return false; } @@ -489,6 +526,17 @@ riscv_option_valid_attribute_p (tree fndecl, tree, tree args, int) return ret; } +/* Public wrapper for pragma processing. + Parse ARGS (a TREE_LIST of target attributes) and update global_options. + This is used by #pragma GCC target. */ + +bool +riscv_process_target_attr_for_pragma (tree args) +{ + location_t loc = UNKNOWN_LOCATION; + return riscv_process_target_attr (args, &loc, riscv_target_attrs); +} + /* Parse the tree in ARGS that contains the target_version attribute information and update the global target options space. If LOC is nonnull, report diagnostics against *LOC, otherwise remain silent. */ diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index c0f0b99..f3c4431 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -4885,6 +4885,54 @@ expand_reduction (unsigned unspec, unsigned unspec_for_vl0_safe, emit_insn (gen_pred_extract_first (m1_mode, scalar_dest, m1_tmp2)); } +/* Expand mask reductions. OPS are {dest, src} where DEST's mode + is QImode and SRC's mode is a mask mode. + CODE is one of AND, IOR, XOR. */ + +void +expand_mask_reduction (rtx *ops, rtx_code code) +{ + machine_mode mode = GET_MODE (ops[1]); + rtx dest = ops[0]; + gcc_assert (GET_MODE (dest) == QImode); + + rtx tmp = gen_reg_rtx (Xmode); + rtx cpop_ops[] = {tmp, ops[1]}; + emit_vlmax_insn (code_for_pred_popcount (mode, Xmode), CPOP_OP, cpop_ops); + + bool eq_zero = false; + + /* AND reduction is popcount (mask) == len, + IOR reduction is popcount (mask) != 0, + XOR reduction is popcount (mask) & 1 != 0. */ + if (code == AND) + { + rtx len = gen_int_mode (GET_MODE_NUNITS (mode), HImode); + tmp = expand_binop (Xmode, sub_optab, tmp, len, NULL, true, + OPTAB_DIRECT); + eq_zero = true; + } + else if (code == IOR) + ; + else if (code == XOR) + tmp = expand_binop (Xmode, and_optab, tmp, GEN_INT (1), NULL, true, + OPTAB_DIRECT); + else + gcc_unreachable (); + + rtx els = gen_label_rtx (); + rtx end = gen_label_rtx (); + + riscv_expand_conditional_branch (els, eq_zero ? EQ : NE, tmp, const0_rtx); + emit_move_insn (dest, const0_rtx); + emit_jump_insn (gen_jump (end)); + emit_barrier (); + + emit_label (els); + emit_move_insn (dest, const1_rtx); + emit_label (end); +} + /* Prepare ops for ternary operations. It can be called before or after RA. */ void @@ -5869,6 +5917,8 @@ get_swapped_cmp_rtx_code (rtx_code code) { case GTU: return LTU; + case GT: + return LT; default: gcc_unreachable (); } diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 1804d5a..96519c9 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1840,8 +1840,19 @@ riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type) /* Nonzero offsets are only valid for references that don't use the GOT. */ switch (*symbol_type) { - case SYMBOL_ABSOLUTE: case SYMBOL_PCREL: + /* In 64-bit mode, PC-relative offsets with ranges beyond +/-1GiB are + more likely than not to end up out of range for an auipc instruction + randomly-placed within the 2GB range usable by medany, and such + offsets are quite unlikely to come up by chance, so be conservative + and separate the offset for them when in 64-bit mode, where they don't + wrap around. */ + if (TARGET_64BIT) + return sext_hwi (INTVAL (offset), 30) == INTVAL (offset); + + /* Fall through. */ + + case SYMBOL_ABSOLUTE: case SYMBOL_TLS_LE: /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */ return sext_hwi (INTVAL (offset), 32) == INTVAL (offset); @@ -12214,6 +12225,12 @@ riscv_override_options_internal (struct gcc_options *opts) /* Convert -march and -mrvv-vector-bits to a chunks count. */ riscv_vector_chunks = riscv_convert_vector_chunks (opts); + /* Set scalar costing to a high value such that we always pick + vectorization. Increase scalar costing by 100x. */ + if (opts->x_riscv_max_vectorization) + SET_OPTION_IF_UNSET (&global_options, &global_options_set, + param_vect_scalar_cost_multiplier, 10000); + if (opts->x_flag_cf_protection != CF_NONE) { if ((opts->x_flag_cf_protection & CF_RETURN) == CF_RETURN @@ -12451,6 +12468,39 @@ riscv_option_restore (struct gcc_options *opts, static GTY (()) tree riscv_previous_fndecl; +/* Reset the previous function declaration. */ + +void +riscv_reset_previous_fndecl (void) +{ + riscv_previous_fndecl = NULL; +} + +/* Implement TARGET_OPTION_SAVE. */ + +static void +riscv_option_save (struct cl_target_option *ptr, + struct gcc_options *opts, + struct gcc_options * /* opts_set */) +{ + ptr->x_riscv_arch_string = opts->x_riscv_arch_string; + ptr->x_riscv_tune_string = opts->x_riscv_tune_string; + ptr->x_riscv_cpu_string = opts->x_riscv_cpu_string; +} + +/* Implement TARGET_OPTION_PRINT. */ + +static void +riscv_option_print (FILE *file, int indent, struct cl_target_option *ptr) +{ + fprintf (file, "%*sarch = %s\n", indent, "", + ptr->x_riscv_arch_string ? ptr->x_riscv_arch_string : "default"); + fprintf (file, "%*stune = %s\n", indent, "", + ptr->x_riscv_tune_string ? ptr->x_riscv_tune_string : "default"); + if (ptr->x_riscv_cpu_string) + fprintf (file, "%*scpu = %s\n", indent, "", ptr->x_riscv_cpu_string); +} + /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ static void @@ -12787,7 +12837,7 @@ riscv_get_interrupt_type (tree decl) /* Implement `TARGET_SET_CURRENT_FUNCTION'. Unpack the codegen decisions like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET of the function, if such exists. This function may be called multiple - times on a single function so use aarch64_previous_fndecl to avoid + times on a single function so use riscv_previous_fndecl to avoid setting up identical state. */ /* Sanity checking for above function attributes. */ @@ -16298,9 +16348,15 @@ riscv_prefetch_offset_address_p (rtx x, machine_mode mode) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE riscv_option_override +#undef TARGET_OPTION_SAVE +#define TARGET_OPTION_SAVE riscv_option_save + #undef TARGET_OPTION_RESTORE #define TARGET_OPTION_RESTORE riscv_option_restore +#undef TARGET_OPTION_PRINT +#define TARGET_OPTION_PRINT riscv_option_print + #undef TARGET_OPTION_VALID_ATTRIBUTE_P #define TARGET_OPTION_VALID_ATTRIBUTE_P riscv_option_valid_attribute_p diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index b334e6c..452062c 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -341,6 +341,10 @@ Target Undocumented RejectNegative Joined Enum(vsetvl_strategy) Var(vsetvl_strat Target Undocumented Uinteger Var(riscv_two_source_permutes) Init(0) -param=riscv-two-source-permutes Enable permutes with two source vectors. +mmax-vectorization +Target Var(riscv_max_vectorization) Save +Override the scalar cost model such that vectorization is always profitable. + Enum Name(stringop_strategy) Type(enum stringop_strategy_enum) Valid arguments to -mstringop-strategy=: diff --git a/gcc/config/riscv/riscv.opt.urls b/gcc/config/riscv/riscv.opt.urls index fe88ec8..bfb1a2d 100644 --- a/gcc/config/riscv/riscv.opt.urls +++ b/gcc/config/riscv/riscv.opt.urls @@ -96,6 +96,8 @@ UrlSuffix(gcc/RISC-V-Options.html#index-minline-strncmp) minline-strlen UrlSuffix(gcc/RISC-V-Options.html#index-minline-strlen) +; skipping UrlSuffix for 'mmax-vectorization' due to finding no URLs + ; skipping UrlSuffix for 'mtls-dialect=' due to finding no URLs mfence-tso diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index c4f60bf..ba4a43b 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -4199,6 +4199,7 @@ "TARGET_VECTOR" "vw<plus_minus:insn><any_extend:u>.wx\t%0,%3,%z4%p1" [(set_attr "type" "vi<widen_binop_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<V_DOUBLE_TRUNC>")]) (define_insn "@pred_single_widen_add<any_extend:su><mode>_extended_scalar" @@ -4465,6 +4466,7 @@ "TARGET_VECTOR" "v<insn>.vx\t%0,%3,%4%p1" [(set_attr "type" "<int_binop_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<MODE>")]) (define_insn "@pred_<optab><mode>_scalar" @@ -4486,6 +4488,7 @@ "TARGET_VECTOR" "v<insn>.vx\t%0,%3,%4%p1" [(set_attr "type" "<int_binop_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<MODE>")]) (define_expand "@pred_<optab><mode>_scalar" @@ -4540,6 +4543,7 @@ "TARGET_VECTOR" "v<insn>.vx\t%0,%3,%4%p1" [(set_attr "type" "<int_binop_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<MODE>")]) (define_insn "*pred_<optab><mode>_extended_scalar" @@ -4562,6 +4566,7 @@ "TARGET_VECTOR && !TARGET_64BIT" "v<insn>.vx\t%0,%3,%4%p1" [(set_attr "type" "<int_binop_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<MODE>")]) (define_expand "@pred_<optab><mode>_scalar" @@ -4616,6 +4621,7 @@ "TARGET_VECTOR" "v<insn>.vx\t%0,%3,%z4%p1" [(set_attr "type" "<int_binop_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<MODE>")]) (define_insn "*pred_<optab><mode>_extended_scalar" @@ -4638,6 +4644,7 @@ "TARGET_VECTOR && !TARGET_64BIT" "v<insn>.vx\t%0,%3,%z4%p1" [(set_attr "type" "<int_binop_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<MODE>")]) (define_insn "@pred_<sat_op><mode>" @@ -4683,6 +4690,7 @@ "TARGET_VECTOR" "v<sat_op>.vx\t%0,%3,%z4%p1" [(set_attr "type" "<sat_insn_type>") + (set_attr "mode_idx" "3") (set_attr "mode" "<MODE>")]) (define_insn "@pred_<sat_op><mode>_scalar" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 647e89a..5133dac 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -2166,3 +2166,8 @@ (and (match_code "subreg") (match_test "subreg_lowpart_offset (mode, GET_MODE (SUBREG_REG (op))) == SUBREG_BYTE (op)"))) + +; Else operand for LEN_LOAD. +(define_predicate "lxvl_else_operand" + (and (match_code "const_vector") + (match_test "op == CONST0_RTX (GET_MODE (op))"))) diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index dd3573b..4d47833 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -5798,13 +5798,14 @@ (define_expand "len_load_v16qi" [(match_operand:V16QI 0 "vlogical_operand") (match_operand:V16QI 1 "memory_operand") - (match_operand:QI 2 "gpc_reg_operand") - (match_operand:QI 3 "zero_constant")] + (match_operand:V16QI 2 "lxvl_else_operand") + (match_operand:QI 3 "gpc_reg_operand") + (match_operand:QI 4 "zero_constant")] "TARGET_P9_VECTOR && TARGET_64BIT" { rtx mem = XEXP (operands[1], 0); mem = force_reg (DImode, mem); - rtx len = gen_lowpart (DImode, operands[2]); + rtx len = gen_lowpart (DImode, operands[3]); emit_insn (gen_lxvl (operands[0], mem, len)); DONE; }) diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index c7b93bd..e181399 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -614,3 +614,8 @@ (define_predicate "vll_bias_operand" (and (match_code "const_int") (match_test "op == CONSTM1_RTX (QImode)"))) + +; Else operand for LEN_LOAD. +(define_predicate "vll_else_operand" + (and (match_code "const_vector") + (match_test "op == CONST0_RTX (GET_MODE (op))"))) diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index 375e3e8..367389c 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -3557,15 +3557,16 @@ (define_expand "len_load_v16qi" [(match_operand:V16QI 0 "register_operand") (match_operand:V16QI 1 "memory_operand") - (match_operand:QI 2 "register_operand") - (match_operand:QI 3 "vll_bias_operand") + (match_operand:V16QI 2 "vll_else_operand") + (match_operand:QI 3 "register_operand") + (match_operand:QI 4 "vll_bias_operand") ] "TARGET_VX && TARGET_64BIT" { rtx mem = adjust_address (operands[1], BLKmode, 0); rtx len = gen_reg_rtx (SImode); - emit_move_insn (len, gen_rtx_ZERO_EXTEND (SImode, operands[2])); + emit_move_insn (len, gen_rtx_ZERO_EXTEND (SImode, operands[3])); emit_insn (gen_vllv16qi (operands[0], len, mem)); DONE; }) |
