cond_expr_convert_p used TYPE_SIZE to compare the selected operands.
For _BitInt this could build a COND_EXPR with arms of different
precision and ICE in range analysis.

Require equal precision for _BitInt arms.  Reject padded comparison
operands and padded inputs to conditional conversions.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
Ok for trunk?

gcc/ChangeLog:

        PR tree-optimization/127382
        * match.pd (cond_expr_convert_p): Check _BitInt precision and reject
        unsupported padded operands.

gcc/testsuite/ChangeLog:

        * gcc.dg/bitint-143.c: New test.
        * gcc.dg/bitint-144.c: Ditto.
        * gcc.target/i386/pr127382.c: Ditto.
---
 gcc/match.pd                             | 18 +++++++++++++++++
 gcc/testsuite/gcc.dg/bitint-143.c        | 20 +++++++++++++++++++
 gcc/testsuite/gcc.dg/bitint-144.c        | 19 ++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr127382.c | 25 ++++++++++++++++++++++++
 4 files changed, 82 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/bitint-143.c
 create mode 100644 gcc/testsuite/gcc.dg/bitint-144.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr127382.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 4059ed787f0..2e0077706c8 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -13140,6 +13140,15 @@ and,
                           TYPE_SIZE (TREE_TYPE (@2)))
        && operand_equal_p (TYPE_SIZE (TREE_TYPE (@0)),
                           TYPE_SIZE (TREE_TYPE (@3)))
+       /* Vector comparisons cannot ignore padding bits.  */
+       && (!BITINT_TYPE_P (TREE_TYPE (@0))
+          || type_has_mode_precision_p (TREE_TYPE (@0)))
+       /* @2 and @3 become the COND_EXPR arms.  If either is a _BitInt,
+         require equal precision and require @2 to have mode precision.  */
+       && (!(BITINT_TYPE_P (TREE_TYPE (@2)) || BITINT_TYPE_P (TREE_TYPE (@3)))
+          || (TYPE_PRECISION (TREE_TYPE (@2))
+              == TYPE_PRECISION (TREE_TYPE (@3))
+              && type_has_mode_precision_p (TREE_TYPE (@2))))
        /* For vect_recog_cond_expr_convert_pattern, @2 and @3 can differ in
          signess when convert is truncation, but not ok for extension since
          it's sign_extend vs zero_extend.  */
@@ -13160,6 +13169,9 @@ and,
        && !operand_equal_p (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (@0)))
        && operand_equal_p (TYPE_SIZE (TREE_TYPE (@0)),
                           TYPE_SIZE (TREE_TYPE (@2)))
+       && (!BITINT_TYPE_P (TREE_TYPE (@0))
+          || type_has_mode_precision_p (TREE_TYPE (@0)))
+       && type_has_mode_precision_p (TREE_TYPE (@2))
        && single_use (@4)
        && single_use (@5))))
 
@@ -13174,6 +13186,8 @@ and,
                            TYPE_SIZE (TREE_TYPE (@0)))
        && operand_equal_p (TYPE_SIZE (TREE_TYPE (@0)),
                           TYPE_SIZE (TREE_TYPE (@2)))
+       && (!BITINT_TYPE_P (TREE_TYPE (@0))
+          || type_has_mode_precision_p (TREE_TYPE (@0)))
        && single_use (@4)
        && single_use (@5))))
 
@@ -13188,6 +13202,8 @@ and,
                            TYPE_SIZE (TREE_TYPE (@0)))
        && operand_equal_p (TYPE_SIZE (TREE_TYPE (@0)),
                           TYPE_SIZE (TREE_TYPE (@3)))
+       && (!BITINT_TYPE_P (TREE_TYPE (@0))
+          || type_has_mode_precision_p (TREE_TYPE (@0)))
        && single_use (@5)
        && (flag_unsafe_math_optimizations
           || exact_real_truncate (TYPE_MODE (TREE_TYPE (@3)),
@@ -13203,6 +13219,8 @@ and,
        && !operand_equal_p (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (@0)))
        && operand_equal_p (TYPE_SIZE (TREE_TYPE (@0)),
                           TYPE_SIZE (TREE_TYPE (@2)))
+       && (!BITINT_TYPE_P (TREE_TYPE (@0))
+          || type_has_mode_precision_p (TREE_TYPE (@0)))
        && single_use (@4)
        && (flag_unsafe_math_optimizations
           || exact_real_truncate (TYPE_MODE (TREE_TYPE (@2)),
diff --git a/gcc/testsuite/gcc.dg/bitint-143.c 
b/gcc/testsuite/gcc.dg/bitint-143.c
new file mode 100644
index 00000000000..c461974d323
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-143.c
@@ -0,0 +1,20 @@
+/* PR tree-optimization/127382 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O2" } */
+
+#if __BITINT_MAXWIDTH__ >= 65
+_BitInt(7) m0[8];
+unsigned _BitInt(17) g1;
+_BitInt(7) p0;
+
+void
+foo (int s0)
+{
+  p0 = g1;
+  for (unsigned i = 0; i < 7; i++)
+    {
+      _BitInt(65) tt = -(_BitInt(65)) (s0 ? i : g1);
+      m0[i & 7] = tt / 10;
+    }
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/bitint-144.c 
b/gcc/testsuite/gcc.dg/bitint-144.c
new file mode 100644
index 00000000000..555ac75dc21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-144.c
@@ -0,0 +1,19 @@
+/* PR tree-optimization/127382 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O3" } */
+
+/* This used to ICE during vectorization.  */
+
+#if __BITINT_MAXWIDTH__ >= 17
+_BitInt(17) g[256];
+unsigned int a[256];
+int b[256];
+short d[256];
+
+void
+foo (void)
+{
+  for (int i = 0; i < 256; i++)
+    d[i] = g[i] < 5wb ? (short) a[i] : (short) b[i];
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/pr127382.c 
b/gcc/testsuite/gcc.target/i386/pr127382.c
new file mode 100644
index 00000000000..edf2ebf688f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr127382.c
@@ -0,0 +1,25 @@
+/* PR tree-optimization/127382 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-march=x86-64-v4 -O3 -fdump-tree-vect-details" } */
+
+/* A bit-precise type whose precision fills its container is as good as the
+   plain integer type of the same width, so cond_expr_convert_p has to keep
+   matching it, no mask packing.  */
+
+/* { dg-final { scan-tree-dump "vect_recog_cond_expr_convert_pattern" "vect" { 
target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "kshift" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "kunpck" { target { ! ia32 } } } } */
+
+#if __BITINT_MAXWIDTH__ >= 32
+_BitInt(32) a[256];
+int b[256];
+short d[256];
+float c[256];
+
+void
+foo (void)
+{
+  for (int i = 0; i < 256; i++)
+    d[i] = c[i] < 1.0f ? (short) a[i] : (short) b[i];
+}
+#endif
-- 
2.34.1

Reply via email to