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>
This commit is contained in:
parent
f9a60d575f
commit
9059734109
2 changed files with 64 additions and 0 deletions
|
@ -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) \
|
||||
|
|
32
gcc/testsuite/g++.dg/torture/pr115961-run-1.C
Normal file
32
gcc/testsuite/g++.dg/torture/pr115961-run-1.C
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* PR target/115961 */
|
||||
/* { dg-do run } */
|
||||
|
||||
struct e
|
||||
{
|
||||
unsigned pre : 12;
|
||||
unsigned a : 4;
|
||||
};
|
||||
|
||||
static unsigned min_u (unsigned a, unsigned b)
|
||||
{
|
||||
return (b < a) ? b : a;
|
||||
}
|
||||
|
||||
__attribute__((noipa))
|
||||
void bug (e * v, unsigned def, unsigned use) {
|
||||
e & defE = *v;
|
||||
defE.a = min_u (use + 1, 0xf);
|
||||
}
|
||||
|
||||
__attribute__((noipa, optimize(0)))
|
||||
int main(void)
|
||||
{
|
||||
e v = { 0xded, 3 };
|
||||
|
||||
bug(&v, 32, 33);
|
||||
|
||||
if (v.a != 0xf)
|
||||
__builtin_abort ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue