Hi! The following testcase is miscompiled since r15-7597. The left comparison is unsigned (x & 0x8000U) != 0) while the right one is signed (x >> 16) >= 0 and is actually a signbit test, so rsignbit is 64. After debugging this and reading the r15-7597 change, I believe there is just a pasto, the if (lsignbit) and if (rsignbit) blocks are pretty much identical with just the first l on all variables starting with l replaced with r (the only difference is that if (lsignbit) has a comment explaining the sign <<= 1; stuff, while it isn't repeated in the second one. Except the second one was using ll_unsignedp instead of rl_unsignedp in one spot. I think it should use the latter, the signedness of the left comparison doesn't affect the other one, they are basically independent with the exception that we check that after transformations they are both EQ or both NE and later on we try to merge them together.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-02-27 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/119030 * gimple-fold.cc (fold_truth_andor_for_ifcombine): Fix a pasto, ll_unsignedp -> rl_unsignedp. * gcc.c-torture/execute/pr119030.c: New test. --- gcc/gimple-fold.cc.jj 2025-02-24 00:06:26.018729158 +0100 +++ gcc/gimple-fold.cc 2025-02-27 16:27:28.843075160 +0100 @@ -8313,7 +8313,7 @@ fold_truth_andor_for_ifcombine (enum tre if (rsignbit) { wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize); - if (rsignbit > rl_bitsize && ll_unsignedp) + if (rsignbit > rl_bitsize && rl_unsignedp) sign <<= 1; if (!rl_and_mask.get_precision ()) rl_and_mask = sign; --- gcc/testsuite/gcc.c-torture/execute/pr119030.c.jj 2025-02-27 16:34:11.332490739 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr119030.c 2025-02-27 16:33:49.778789792 +0100 @@ -0,0 +1,26 @@ +/* PR tree-optimization/119030 */ + +static inline unsigned +foo (long long x) +{ + return x & 0x8000; +} + +static inline long long +bar (long long x) +{ + if (foo (x)) + return -1000L; + else + return x >> 16; +} + +long long x = -0x20000LL; + +int +main () +{ + if (bar (x) >= 0) + __builtin_abort (); + return 0; +} Jakub