https://gcc.gnu.org/g:c3226db63fa8e694d1edd064c4634a3514e69878
commit c3226db63fa8e694d1edd064c4634a3514e69878 Author: Alexandre Oliva <ol...@gnu.org> Date: Thu Jan 23 02:51:41 2025 -0300 [ifcombine] check for more zero-extension cases [PR118572] Diff: --- gcc/gimple-fold.cc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index cd9d35034918..53bbf6cf70aa 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -8552,12 +8552,20 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, { /* Before clipping upper bits of the right-hand operand of the compare, check that they're sign or zero extensions, depending on how the - left-hand operand would be extended. */ + left-hand operand would be extended. If it is unsigned, or if there's + a mask that zeroes out extension bits, whether because we've checked + for upper bits in the mask and did not set ll_signbit, or because the + sign bit itself is masked out, check that the right-hand operand is + zero-extended. */ bool l_non_ext_bits = false; if (ll_bitsize < lr_bitsize) { wide_int zext = wi::zext (l_const, ll_bitsize); - if ((ll_unsignedp ? zext : wi::sext (l_const, ll_bitsize)) == l_const) + if ((ll_unsignedp + || (ll_and_mask.get_precision () + && (!ll_signbit + || !(ll_and_mask & wi::mask (ll_bitsize - 1, true, ll_bitsize))))) + ? zext : wi::sext (l_const, ll_bitsize)) == l_const) l_const = zext; else l_non_ext_bits = true; @@ -8583,7 +8591,11 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (rl_bitsize < rr_bitsize) { wide_int zext = wi::zext (r_const, rl_bitsize); - if ((rl_unsignedp ? zext : wi::sext (r_const, rl_bitsize)) == r_const) + if ((rl_unsignedp + || (rl_and_mask.get_precision () + && (!rl_signbit + || !(rl_and_mask & wi::mask (rl_bitsize - 1, true, rl_bitsize)))) + ? zext : wi::sext (r_const, rl_bitsize)) == r_const) r_const = zext; else r_non_ext_bits = true;