diff options
author | Pan Li <pan2.li@intel.com> | 2024-07-18 17:23:36 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2024-07-24 12:51:58 +0800 |
commit | 905973410957891fec8a3e42eeefa4618780e0ce (patch) | |
tree | 073e2338fa4b2d9a745f388f8fc94c29a5c51fa4 /gcc/internal-fn.cc | |
parent | f9a60d575f02822852aa22513c636be38f9c63ea (diff) | |
download | gcc-905973410957891fec8a3e42eeefa4618780e0ce.zip gcc-905973410957891fec8a3e42eeefa4618780e0ce.tar.gz gcc-905973410957891fec8a3e42eeefa4618780e0ce.tar.bz2 |
Internal-fn: Only allow modes describe types for internal fn[PR115961]
The direct_internal_fn_supported_p has no restrictions for the type
modes. For example the bitfield like below will be recog as .SAT_TRUNC.
struct e
{
unsigned pre : 12;
unsigned a : 4;
};
__attribute__((noipa))
void bug (e * v, unsigned def, unsigned use) {
e & defE = *v;
defE.a = min_u (use + 1, 0xf);
}
This patch would like to add checks for the direct_internal_fn_supported_p,
and only allows the tree types describled by modes.
The below test suites are passed for this patch:
1. The rv64gcv fully regression tests.
2. The x86 bootstrap tests.
3. The x86 fully regression tests.
PR target/115961
gcc/ChangeLog:
* internal-fn.cc (type_strictly_matches_mode_p): Add new func
impl to check type strictly matches mode or not.
(type_pair_strictly_matches_mode_p): Ditto but for tree type
pair.
(direct_internal_fn_supported_p): Add above check for the tree
type pair.
gcc/testsuite/ChangeLog:
* g++.dg/torture/pr115961-run-1.C: New test.
Signed-off-by: Pan Li <pan2.li@intel.com>
Diffstat (limited to 'gcc/internal-fn.cc')
-rw-r--r-- | gcc/internal-fn.cc | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 95946bf..8a2e07f 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -4164,6 +4164,35 @@ direct_internal_fn_optab (internal_fn fn) gcc_unreachable (); } +/* Return true if TYPE's mode has the same format as TYPE, and if there is + a 1:1 correspondence between the values that the mode can store and the + values that the type can store. */ + +static bool +type_strictly_matches_mode_p (const_tree type) +{ + if (VECTOR_TYPE_P (type)) + return VECTOR_MODE_P (TYPE_MODE (type)); + + if (INTEGRAL_TYPE_P (type)) + return type_has_mode_precision_p (type); + + if (SCALAR_FLOAT_TYPE_P (type) || COMPLEX_FLOAT_TYPE_P (type)) + return true; + + return false; +} + +/* Returns true if both types of TYPE_PAIR strictly match their modes, + else returns false. */ + +static bool +type_pair_strictly_matches_mode_p (tree_pair type_pair) +{ + return type_strictly_matches_mode_p (type_pair.first) + && type_strictly_matches_mode_p (type_pair.second); +} + /* Return true if FN is supported for the types in TYPES when the optimization type is OPT_TYPE. The types are those associated with the "type0" and "type1" fields of FN's direct_internal_fn_info @@ -4173,6 +4202,9 @@ bool direct_internal_fn_supported_p (internal_fn fn, tree_pair types, optimization_type opt_type) { + if (!type_pair_strictly_matches_mode_p (types)) + return false; + switch (fn) { #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \ |