On Wed, 16 Sep 2026, liuhongt wrote:

> 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?

I think this can happen for non-BitInt INTEGER_TYPE as well, so
the checks should be done for all INTEGRAL_TYPE_P

Richard.
 
> 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
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri; (HRB 36809, AG Nuernberg)

Reply via email to