Apologies, the inline diff in my previous email is line-wrapped. Please use the intact copy of the same patch already attached to Bugzilla: https://gcc.gnu.org/bugzilla/attachment.cgi?id=65929
There are no code changes; the reported bootstrap and regression results apply to this attachment. On Fri, 23 Oct 2026 at 14:54, Oleksandr Kulkov <[email protected]> wrote: > > This fixes the wrong-code regression in PR ipa/128092: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128092 > > The IPA bit lattice can mark bits above the operand precision as unknown. > Passing those bits to value_mask_to_min_max can make it mistake them for a > varying sign bit and misfold MAX_EXPR. Extend the value and mask to the > operation's precision and signedness before calling the unary or binary bit > folder. > > The new torture test covers the reduced reproducer, including LTO. > > Bootstrapped and regression-tested on x86_64-pc-linux-gnu with the default > languages and --disable-multilib, with no new test failures. The libgomp > tests were rerun after fixing a local Tcl module-path issue. > > OK for trunk? If approved, please commit it on my behalf. > > Assisted-by: OpenAI Codex > > gcc/ChangeLog: > > PR ipa/128092 > * ipa-cp.cc (ipcp_bits_lattice::meet_with): Extend the source value > and mask to the operation type before folding. > > gcc/testsuite/ChangeLog: > > PR ipa/128092 > * g++.dg/torture/pr128092.C: New test. > > --- > diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc > index cecc8d17f..daea1da62 100644 > --- a/gcc/ipa-cp.cc > +++ b/gcc/ipa-cp.cc > @@ -1050,6 +1050,9 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, > unsigned precision, > return false; > > widest_int adjusted_value, adjusted_mask; > + /* The lattice may mark bits above PRECISION as unknown. */ > + widest_int value = wi::ext (other.get_value (), precision, sgn); > + widest_int mask = wi::ext (other.get_mask (), precision, sgn); > > if (TREE_CODE_CLASS (code) == tcc_binary) > { > @@ -1058,7 +1061,7 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, > unsigned precision, > get_value_and_mask (operand, &o_value, &o_mask); > > bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask, > - sgn, precision, other.get_value (), other.get_mask (), > + sgn, precision, value, mask, > TYPE_SIGN (type), TYPE_PRECISION (type), o_value, > o_mask); > > if (wi::sext (adjusted_mask, precision) == -1) > @@ -1068,8 +1071,7 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, > unsigned precision, > else if (TREE_CODE_CLASS (code) == tcc_unary) > { > bit_value_unop (code, sgn, precision, &adjusted_value, > - &adjusted_mask, sgn, precision, other.get_value (), > - other.get_mask ()); > + &adjusted_mask, sgn, precision, value, mask); > > if (wi::sext (adjusted_mask, precision) == -1) > return set_to_bottom (); > diff --git a/gcc/testsuite/g++.dg/torture/pr128092.C > b/gcc/testsuite/g++.dg/torture/pr128092.C > new file mode 100644 > index 000000000..152026430 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/torture/pr128092.C > @@ -0,0 +1,20 @@ > +/* { dg-do run { target c++11 } } */ > + > +[[gnu::noinline]] static unsigned > +f (unsigned x) > +{ > + return x; > +} > + > +[[gnu::noinline]] static unsigned > +g (int x) > +{ > + return f (x > 0 ? x : 0); > +} > + > +int > +main () > +{ > + if (g (1) + g (0) != 1) > + __builtin_abort (); > +}
