https://gcc.gnu.org/g:d135ff4f42672b11b5bfdc2a5a447f3919b3d331

commit r16-9781-gd135ff4f42672b11b5bfdc2a5a447f3919b3d331
Author: liuhongt <[email protected]>
Date:   Mon Sep 14 23:51:26 2026 -0700

    match.pd: Check cond_expr_convert_p operand precision [PR127382]
    
    cond_expr_convert_p compared the selected operands only by TYPE_SIZE.
    For integral operands this could build a COND_EXPR whose arms have
    different precision, e.g. unsigned _BitInt(17) vs unsigned int, which
    ICEs in range analysis.
    
    Require the integral arms to be nop-convertible to each other instead,
    which still allows them to differ in sign.
    
            PR tree-optimization/127382
    
    gcc/ChangeLog:
    
            * match.pd (cond_expr_convert_p): Use tree_nop_conversion_p
            instead of INTEGRAL_TYPE_P to check the integral selected
            operands.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/bitint-146.c: New test.
            * gcc.target/i386/pr127382.c: Likewise.
    
    (cherry picked from commit 164e45f035160df9e3eac7decb8202ba098e2f3c)

Diff:
---
 gcc/match.pd                             |  2 +-
 gcc/testsuite/gcc.dg/bitint-146.c        | 20 ++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr127382.c | 25 +++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index e9132e857168..c23df0086080 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -11994,7 +11994,7 @@ and,
   (if ((INTEGRAL_TYPE_P (type)
        || (!flag_trapping_math && SCALAR_FLOAT_TYPE_P (type)))
        && ((INTEGRAL_TYPE_P (TREE_TYPE (@2))
-           && INTEGRAL_TYPE_P (TREE_TYPE (@3)))
+           && tree_nop_conversion_p (TREE_TYPE (@2), TREE_TYPE (@3)))
           || (SCALAR_FLOAT_TYPE_P (TREE_TYPE (@2))
               && types_match (TREE_TYPE (@2), TREE_TYPE (@3))))
        && !operand_equal_p (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (@0)))
diff --git a/gcc/testsuite/gcc.dg/bitint-146.c 
b/gcc/testsuite/gcc.dg/bitint-146.c
new file mode 100644
index 000000000000..c461974d3239
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-146.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.target/i386/pr127382.c 
b/gcc/testsuite/gcc.target/i386/pr127382.c
new file mode 100644
index 000000000000..edf2ebf688f8
--- /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

Reply via email to