On 12/30/25 7:19 PM, Jeffrey Law wrote:


On 12/30/2025 6:29 AM, Daniel Barboza wrote:
Add a pattern to handle cases where we have an OP that is
unconditionally being applied in the result of a gcond. In this case we
can apply OP to both legs of the conditional. E.g:

t = b ? 10 : 20;
t = t + 20;

becomes just:

t = b ? 30 : 40

A variant pattern was also added to handle the case where the gcond
result is used as the second operand. This was needed because most of
the ops we're handling aren't commutative.

         PR 122608

gcc/ChangeLog:

         * match.pd (`(c ? a : b) op d -> c ? (a op d) : (b op d)`): New
      pattern.
      (`d op (c ? a : b) -> c ? (d op a) : (d op b)`): Likewise

gcc/testsuite/ChangeLog:

         * gcc.target/i386/pr110701.c: the pattern added is now folding
      an XOR into the ifcond and the assembler isn't emitting an
      'andl' anymore. The test was turned into a runtime test
           instead.
         * gcc.dg/torture/pr122608.c: New test.

Signed-off-by: Daniel Barboza <[email protected]>
I'd totally lost state on this in the last few weeks.

Obviously for the included testcases we're collapsing down to constants which 
should always be profitable as we'll end up removing the conditional branch and 
reduce the number of expression evaluations.  For non-constant cases it's 
probably still profitable because we're removing the pesky conditional branch.  
In fact this patch may lessen our reliance on RTL's ifcvt code, which would 
definitely be good as well.

+
+/* Similar to above:
+   (c ? a : b) op d  ->  c ? (a op d) : (b op d)
+   But with non-vector binary ops, most of them non-commutative.  */
+(for op (plus minus mult bit_and bit_ior bit_xor
+     lshift rshift rdiv trunc_div ceil_div floor_div round_div exact_div
+     trunc_mod ceil_mod floor_mod round_mod min max pointer_diff
+     lrotate rrotate mult_highpart)
Does it make sense to handle pointer_plus as well?  It would seem like it.  
It's marginally harder to test and I wouldn't lose too much sleep if we didn't 
have coverage.

This is mostly the reason why we didn't add pointer_plus: I didn't find a
suitable test case to see before/after. All tests I come up with showed
that pointer_plus was already being taken care of, but then again I'm not
sure if I was testing it correctly to be honest. This all happened during
the v1 discussions.

If we're ok with not having coverage for this specific case I'm ok with
adding pointer_plus in the pattern. I would even make a note in the
testcase mentioning that we do not have a test for it.


Thanks,

Daniel




I've thrown the V3 patch into my tester to see how it behaves across a variety 
of platforms.   Should have results in a couple hours across x86 native as well 
as many embedded targets.  It's burned through ~20 of the embedded targets 
without any issues.


Jeff

Reply via email to