On 7/10/2026 6:44 AM, Richard Biener wrote:
On Fri, Jul 10, 2026 at 8:32 AM Odysseas Georgoudis <[email protected]> wrote:
Hi Jeff,

Sorry about that, Outlook turned the attachment into a OneDrive link. Here is 
the patch inline and also attached as plain file.

On the RISC-V point, thanks, that makes sense.  My intent is for the
middle-end transform to expose the conditional negate / ABS semantics and
leave target expansion/combine to recover the preferred form where that is
better.

 From 81b2690e383b37222954225198f8895a370e45c0 Mon Sep 17 00:00:00 2001
From: Odysseas Georgoudis <[email protected]>
Date: Wed, 1 Jul 2026 02:43:49 +0100
Subject: [PATCH v1] match.pd: Recognize branchless conditional negate
  [PR113894]

This patch teaches match.pd to recognize the branchless conditional negate
idiom (x ^ -cmp) + cmp when cmp is known to be zero or one.  The
expression is folded to a conditional negate form.

For the sign-test spelling based on x < 0, the patch exposes ABS_EXPR.

PR tree-optimization/113894

gcc/ChangeLog:

      * match.pd: Add simplifications for branchless conditional negate
      and sign-test absolute value idioms.

gcc/testsuite/ChangeLog:

      * gcc.dg/tree-ssa/pr113894.c: New test.

Signed-off-by: Odysseas Georgoudis <[email protected]>
---
  gcc/match.pd                             | 15 ++++++
  gcc/testsuite/gcc.dg/tree-ssa/pr113894.c | 60 ++++++++++++++++++++++++
  2 files changed, 75 insertions(+)
  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr113894.c

diff --git a/gcc/match.pd b/gcc/match.pd
index ddf3b61638c..70d7f3a8733 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -236,6 +236,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && !TYPE_UNSIGNED (TREE_TYPE (@0)))
    (abs @0)))

+/* (X ^ -(X < 0)) + (X < 0) -> abs (X) */
+(simplify
+ (plus:c (bit_xor:c @0 (negate (convert@1 (lt @0 integer_zerop)))) @1)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+      && !TYPE_UNSIGNED (TREE_TYPE (@0)))
+  (abs @0)))
Both forms invoke UB for -INT_MIN, so OK I guess.  But does this not
also require !TYPE_SATURATING?
I thought so too (it's on my mind due to Kael's patches) and the LLM evaluation flagged it as-well.  But I haven't come up with a value where the transformation doesn't hold.   The most interesting value would be INT_MIN, but the original and converted both produce INT_MAX for that on saturating types.

Given this pattern can match in the GENERIC context, do we have to worry about dropping side effects?  The original would reference X 3 times whereas the result only references once for that abs pattern.

Kind of like Kael's recent patches, testing an earlier dump would potentially make the test more robust.

So I think we need a V2.

Jeff

Reply via email to