diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index caa33e0aacf1b9cb5b6d6dfebc7f8e946b3c7eb9..0d132bf7b6c491ed29c3f3e535366c9fe15c6717 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -1267,13 +1267,17 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx) the most significant limb is handled in straight line code. If m_var_msb (on left shifts) or if m_upwards_2limb * limb_prec is equal to - lhs precision that is not the case. */ + lhs precision or if not m_upwards_2limb and lhs_type + has precision which is multiple of limb_prec that is + not the case. */ || (!m_var_msb && (CEIL (TYPE_PRECISION (lhs_type), limb_prec) == CEIL (TYPE_PRECISION (rhs_type), limb_prec)) - && (!m_upwards_2limb - || (m_upwards_2limb * limb_prec - < TYPE_PRECISION (lhs_type))))) + && ((!m_upwards_2limb + && (TYPE_PRECISION (lhs_type) % limb_prec != 0)) + || (m_upwards_2limb + && (m_upwards_2limb * limb_prec + < TYPE_PRECISION (lhs_type)))))) { rhs1 = handle_operand (rhs1, idx); if (tree_fits_uhwi_p (idx)) diff --git a/gcc/testsuite/gcc.dg/torture/bitint-58.c b/gcc/testsuite/gcc.dg/torture/bitint-58.c new file mode 100644 index 0000000000000000000000000000000000000000..bdadd8b88d679424ca8deb04bc05731dfdd14958 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-58.c @@ -0,0 +1,25 @@ +/* PR tree-optimization/113849 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +signed char c; +unsigned _BitInt(512) b; + +__attribute__((noipa)) void +foo (unsigned _BitInt(511) a, int *x) +{ + int z = (a << 510) <= b; + *x = z + c; +} + +int +main () +{ + int x; + foo (2, &x); + if (x != 1) + __builtin_abort (); + return 0; +}