From: Pan Li <pan2...@intel.com>

The .SAT_TRUNC matching doesn't check the type has mode precision.  Thus
when 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 type_has_mode_precision_p for the
.SAT_TRUNC matching to get rid of this.

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:

        * match.pd: Add type_has_mode_precision_p check for .SAT_TRUNC.

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...@intel.com>
---
 gcc/match.pd                                  |  4 +--
 .../g++.target/i386/pr115961-run-1.C          | 34 +++++++++++++++++++
 .../riscv/rvv/base/pr115961-run-1.C           | 34 +++++++++++++++++++
 3 files changed, 70 insertions(+), 2 deletions(-)
 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/match.pd b/gcc/match.pd
index 24a0bbead3e..8121ec09f53 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3240,7 +3240,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (bit_ior:c (negate (convert (gt @0 INTEGER_CST@1)))
    (convert @0))
  (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
-      && TYPE_UNSIGNED (TREE_TYPE (@0)))
+      && TYPE_UNSIGNED (TREE_TYPE (@0)) && type_has_mode_precision_p (type))
  (with
   {
    unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
@@ -3255,7 +3255,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (match (unsigned_integer_sat_trunc @0)
  (convert (min @0 INTEGER_CST@1))
  (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
-      && TYPE_UNSIGNED (TREE_TYPE (@0)))
+      && TYPE_UNSIGNED (TREE_TYPE (@0)) && type_has_mode_precision_p (type))
  (with
   {
    unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
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" } } */
-- 
2.34.1

Reply via email to