Hi! The following testcase is miscompiled. The problem is in the last_ovf step. The second operand has signed _BitInt(513) type but has the MSB clear, so range_to_prec returns 512 for it (i.e. it fits into unsigned _BitInt(512)). Because of that the last step actually doesn't need to get the most significant bit from the second operand, but the code was deciding what to use purely from TYPE_UNSIGNED (type1) - if unsigned, use 0, otherwise sign-extend the last processed bit; but that in this case was set. We don't want to treat the positive operand as if it was negative regardless of the bit below that precision, and precN >= 0 indicates that the operand is in the [0, inf) range.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-09-02 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/116501 * gimple-lower-bitint.cc (bitint_large_huge::lower_addsub_overflow): In the last_ovf case, use build_zero_cst operand not just when TYPE_UNSIGNED (typeN), but also when precN >= 0. * gcc.dg/torture/bitint-73.c: New test. --- gcc/gimple-lower-bitint.cc.jj 2024-07-17 23:36:01.264307447 +0200 +++ gcc/gimple-lower-bitint.cc 2024-09-02 15:17:30.347950715 +0200 @@ -4192,7 +4192,7 @@ bitint_large_huge::lower_addsub_overflow else { m_data_cnt = data_cnt; - if (TYPE_UNSIGNED (type0)) + if (TYPE_UNSIGNED (type0) || prec0 >= 0) rhs1 = build_zero_cst (m_limb_type); else { @@ -4210,7 +4210,7 @@ bitint_large_huge::lower_addsub_overflow rhs1 = add_cast (m_limb_type, gimple_assign_lhs (g)); } } - if (TYPE_UNSIGNED (type1)) + if (TYPE_UNSIGNED (type1) || prec1 >= 0) rhs2 = build_zero_cst (m_limb_type); else { --- gcc/testsuite/gcc.dg/torture/bitint-73.c.jj 2024-09-02 15:19:00.220782186 +0200 +++ gcc/testsuite/gcc.dg/torture/bitint-73.c 2024-09-02 15:20:43.222442952 +0200 @@ -0,0 +1,20 @@ +/* PR tree-optimization/116501 */ +/* { dg-do run { target bitint575 } } */ +/* { dg-options "-std=c23" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +_BitInt (4) a; + +int +foo (_BitInt(513) b) +{ + return __builtin_sub_overflow_p (a, b, (_BitInt (511)) 0); +} + +int +main () +{ + if (!foo (0xffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000wb)) + __builtin_abort (); +} Jakub