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.

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