update in v2:
> I think this can happen for non-BitInt INTEGER_TYPE as well, so
> the checks should be done for all INTEGRAL_TYPE_P
Yes, for _Bool it's storage size is not equal to type_precision.
changed.

Bootstrapped and regtested on x86_64-pc-linu-gnu{-m32,}.
Ok for trunk(and backport to GCC16)?

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

Require equal precision for integral arms.  When either arm is a
_BitInt, also require the COND_EXPR type to have mode precision.  Reject
padded _BitInt comparison operands as well.

        PR tree-optimization/127382

gcc/ChangeLog:

        * match.pd (cond_expr_convert_p): Require equal precision for integral
        arms.  Reject unsupported padded _BitInt operands.

gcc/testsuite/ChangeLog:

        * gcc.dg/bitint-143.c: Test mismatched selected-arm precisions.
        * gcc.dg/bitint-144.c: Test a padded _BitInt comparison operand.
        * gcc.target/i386/pr127382.c: Test a mode-precision _BitInt arm.
---
 gcc/match.pd                             | 20 +++++++++++++++++++
 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, 84 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..9bdd8d5e447 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -13140,6 +13140,17 @@ 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, so integral types must have
+         equal precision.  If either is a _BitInt, @2 must also have mode
+         precision.  */
+       && (!INTEGRAL_TYPE_P (TREE_TYPE (@2))
+          || (TYPE_PRECISION (TREE_TYPE (@2))
+              == TYPE_PRECISION (TREE_TYPE (@3))))
+       && (!(BITINT_TYPE_P (TREE_TYPE (@2)) || BITINT_TYPE_P (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 +13171,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 +13188,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 +13204,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 +13221,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