diff mbox series

[v1] Internal-fn: Only allow modes describe types for internal fn[PR115961]

Message ID 20240719033241.2255739-1-pan2.li@intel.com
State New
Headers show
Series [v1] Internal-fn: Only allow modes describe types for internal fn[PR115961] | expand

Commit Message

Li, Pan2 July 19, 2024, 3:32 a.m. UTC
From: Pan Li <pan2.li@intel.com>

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 (mode_describle_type_precision_p): Add new func
	impl to check if mode describle the tree type.
	(direct_internal_fn_supported_p): Add above check for the first
	and second tree type of tree pair.

gcc/testsuite/ChangeLog:

	* g++.target/i386/pr115961-run-1.C: New test.
	* g++.target/riscv/rvv/base/pr115961-run-1.C: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/internal-fn.cc                            | 21 ++++++++++++
 .../g++.target/i386/pr115961-run-1.C          | 34 +++++++++++++++++++
 .../riscv/rvv/base/pr115961-run-1.C           | 34 +++++++++++++++++++
 3 files changed, 89 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/i386/pr115961-run-1.C
 create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C

Comments

Richard Sandiford July 19, 2024, 7:46 a.m. UTC | #1
pan2.li@intel.com writes:
> From: Pan Li <pan2.li@intel.com>
>
> 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 (mode_describle_type_precision_p): Add new func
> 	impl to check if mode describle the tree type.
> 	(direct_internal_fn_supported_p): Add above check for the first
> 	and second tree type of tree pair.
>
> gcc/testsuite/ChangeLog:
>
> 	* g++.target/i386/pr115961-run-1.C: New test.
> 	* g++.target/riscv/rvv/base/pr115961-run-1.C: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/internal-fn.cc                            | 21 ++++++++++++
>  .../g++.target/i386/pr115961-run-1.C          | 34 +++++++++++++++++++
>  .../riscv/rvv/base/pr115961-run-1.C           | 34 +++++++++++++++++++
>  3 files changed, 89 insertions(+)
>  create mode 100644 gcc/testsuite/g++.target/i386/pr115961-run-1.C
>  create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
>
> diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
> index 95946bfd683..4dc69264a24 100644
> --- a/gcc/internal-fn.cc
> +++ b/gcc/internal-fn.cc
> @@ -4164,6 +4164,23 @@ direct_internal_fn_optab (internal_fn fn)
>    gcc_unreachable ();
>  }
>  
> +/* Return true if the mode describes the precision of tree type,  or false.  */
> +
> +static bool
> +mode_describle_type_precision_p (const_tree type)

Bit pedantic, but it's not really just about precision.  For floats
and vectors it's also about format.  Maybe:

/* 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.  */

And maybe my mode_describes_type_p suggestion wasn't the best,
but given that it's not just about precision, I'm not sure about
mode_describle_type_precision_p either.  How about:

  type_strictly_matches_mode_p

?  I'm open to other suggestions.

> +{
> +  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;
> +}
> +
>  /* 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 +4190,10 @@ bool
>  direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
>  				optimization_type opt_type)
>  {
> +  if (!mode_describle_type_precision_p (types.first)
> +    || !mode_describle_type_precision_p (types.second))

Formatting nit: the "||" should line up with the "!".

LGTM otherwise.

Thanks,
Richard

> +    return false;
> +
>    switch (fn)
>      {
>  #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
> diff --git a/gcc/testsuite/g++.target/i386/pr115961-run-1.C b/gcc/testsuite/g++.target/i386/pr115961-run-1.C
> new file mode 100644
> index 00000000000..b8c8aef3b17
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/i386/pr115961-run-1.C
> @@ -0,0 +1,34 @@
> +/* PR target/115961 */
> +/* { dg-do run } */
> +/* { dg-options "-O3 -fdump-rtl-expand-details" } */
> +
> +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;
> +}
> +/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */
> diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
> new file mode 100644
> index 00000000000..b8c8aef3b17
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
> @@ -0,0 +1,34 @@
> +/* PR target/115961 */
> +/* { dg-do run } */
> +/* { dg-options "-O3 -fdump-rtl-expand-details" } */
> +
> +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;
> +}
> +/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */
Li, Pan2 July 19, 2024, 11:11 a.m. UTC | #2
Thanks Richard S for comments and suggestions, updated in v2.

Pan

-----Original Message-----
From: Richard Sandiford <richard.sandiford@arm.com> 
Sent: Friday, July 19, 2024 3:46 PM
To: Li, Pan2 <pan2.li@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; kito.cheng@gmail.com; richard.guenther@gmail.com; tamar.christina@arm.com; jeffreyalaw@gmail.com; rdapp.gcc@gmail.com
Subject: Re: [PATCH v1] Internal-fn: Only allow modes describe types for internal fn[PR115961]

pan2.li@intel.com writes:
> From: Pan Li <pan2.li@intel.com>
>
> 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 (mode_describle_type_precision_p): Add new func
> 	impl to check if mode describle the tree type.
> 	(direct_internal_fn_supported_p): Add above check for the first
> 	and second tree type of tree pair.
>
> gcc/testsuite/ChangeLog:
>
> 	* g++.target/i386/pr115961-run-1.C: New test.
> 	* g++.target/riscv/rvv/base/pr115961-run-1.C: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/internal-fn.cc                            | 21 ++++++++++++
>  .../g++.target/i386/pr115961-run-1.C          | 34 +++++++++++++++++++
>  .../riscv/rvv/base/pr115961-run-1.C           | 34 +++++++++++++++++++
>  3 files changed, 89 insertions(+)
>  create mode 100644 gcc/testsuite/g++.target/i386/pr115961-run-1.C
>  create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
>
> diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
> index 95946bfd683..4dc69264a24 100644
> --- a/gcc/internal-fn.cc
> +++ b/gcc/internal-fn.cc
> @@ -4164,6 +4164,23 @@ direct_internal_fn_optab (internal_fn fn)
>    gcc_unreachable ();
>  }
>  
> +/* Return true if the mode describes the precision of tree type,  or false.  */
> +
> +static bool
> +mode_describle_type_precision_p (const_tree type)

Bit pedantic, but it's not really just about precision.  For floats
and vectors it's also about format.  Maybe:

/* 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.  */

And maybe my mode_describes_type_p suggestion wasn't the best,
but given that it's not just about precision, I'm not sure about
mode_describle_type_precision_p either.  How about:

  type_strictly_matches_mode_p

?  I'm open to other suggestions.

> +{
> +  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;
> +}
> +
>  /* 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 +4190,10 @@ bool
>  direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
>  				optimization_type opt_type)
>  {
> +  if (!mode_describle_type_precision_p (types.first)
> +    || !mode_describle_type_precision_p (types.second))

Formatting nit: the "||" should line up with the "!".

LGTM otherwise.

Thanks,
Richard

> +    return false;
> +
>    switch (fn)
>      {
>  #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
> diff --git a/gcc/testsuite/g++.target/i386/pr115961-run-1.C b/gcc/testsuite/g++.target/i386/pr115961-run-1.C
> new file mode 100644
> index 00000000000..b8c8aef3b17
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/i386/pr115961-run-1.C
> @@ -0,0 +1,34 @@
> +/* PR target/115961 */
> +/* { dg-do run } */
> +/* { dg-options "-O3 -fdump-rtl-expand-details" } */
> +
> +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;
> +}
> +/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */
> diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
> new file mode 100644
> index 00000000000..b8c8aef3b17
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
> @@ -0,0 +1,34 @@
> +/* PR target/115961 */
> +/* { dg-do run } */
> +/* { dg-options "-O3 -fdump-rtl-expand-details" } */
> +
> +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;
> +}
> +/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */
diff mbox series

Patch

diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index 95946bfd683..4dc69264a24 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -4164,6 +4164,23 @@  direct_internal_fn_optab (internal_fn fn)
   gcc_unreachable ();
 }
 
+/* Return true if the mode describes the precision of tree type,  or false.  */
+
+static bool
+mode_describle_type_precision_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;
+}
+
 /* 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 +4190,10 @@  bool
 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
 				optimization_type opt_type)
 {
+  if (!mode_describle_type_precision_p (types.first)
+    || !mode_describle_type_precision_p (types.second))
+    return false;
+
   switch (fn)
     {
 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
diff --git a/gcc/testsuite/g++.target/i386/pr115961-run-1.C b/gcc/testsuite/g++.target/i386/pr115961-run-1.C
new file mode 100644
index 00000000000..b8c8aef3b17
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr115961-run-1.C
@@ -0,0 +1,34 @@ 
+/* PR target/115961 */
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-rtl-expand-details" } */
+
+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;
+}
+/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */
diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
new file mode 100644
index 00000000000..b8c8aef3b17
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/rvv/base/pr115961-run-1.C
@@ -0,0 +1,34 @@ 
+/* PR target/115961 */
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-rtl-expand-details" } */
+
+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;
+}
+/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */