aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/aarch64/aarch64-cores.def5
-rw-r--r--gcc/config/aarch64/aarch64-simd.md12
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/darwin-c.cc7
-rw-r--r--gcc/config/gcn/gcn.cc9
-rw-r--r--gcc/config/gcn/mkoffload.cc9
-rw-r--r--gcc/config/i386/i386-expand.cc9
-rw-r--r--gcc/config/i386/i386.cc15
-rw-r--r--gcc/config/i386/sse.md3
-rw-r--r--gcc/config/mingw/winnt.cc10
-rw-r--r--gcc/config/riscv/autovec.md31
-rw-r--r--gcc/config/riscv/predicates.md2
-rw-r--r--gcc/config/riscv/riscv-c.cc44
-rw-r--r--gcc/config/riscv/riscv-protos.h4
-rw-r--r--gcc/config/riscv/riscv-target-attr.cc96
-rw-r--r--gcc/config/riscv/riscv-v.cc50
-rw-r--r--gcc/config/riscv/riscv.cc60
-rw-r--r--gcc/config/riscv/riscv.opt4
-rw-r--r--gcc/config/riscv/riscv.opt.urls2
-rw-r--r--gcc/config/riscv/vector.md8
-rw-r--r--gcc/config/rs6000/predicates.md5
-rw-r--r--gcc/config/rs6000/vsx.md7
-rw-r--r--gcc/config/s390/predicates.md5
-rw-r--r--gcc/config/s390/vector.md7
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;
})