https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124560
Jeevitha <jeevitha at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jeevitha at gcc dot gnu.org
--- Comment #2 from Jeevitha <jeevitha at gcc dot gnu.org> ---
I am trying to learn GCC tree optimizations and started with this issue. I have
a patch for it, but currently it only handles unsigned types. Let me explain
why I excluded signed types.
The bug report mentions that the transformation is valid for both signed and
unsigned types, but I believe it is not safe for signed types, even under
TYPE_OVERFLOW_UNDEFINED. Could you please confirm whether this assumption is
correct?
int x = INT_MAX, y = -1, z = 0;
/* src */
x - y = INT_MAX - (-1) = INT_MAX + 1 /* signed overflow - UB */
z - y = 0 - (-1) = 1
min(UB, 1) = UB
/* tgt */
min(INT_MAX, 0) = 0
0 - (-1) = 1 /* no overflow - defined */
In this case, the original expression results in undefined behavior, while the
transformed version produces a defined result.
Therefore, I am restricting the transformation to unsigned types only.
diff --git a/gcc/match.pd b/gcc/match.pd
index 7b652afb43d..f59eb40bb97 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7054,6 +7054,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, @3,
@4)))
(max @2 @4))))))
+/* Optimize min(x - y, z - y) -> min(x, z) - y
+ max(x - y, z - y) -> max(x, z) - y */
+(for minmax (min max)
+ (simplify
+ (minmax (minus @0 @1) (minus @2 @1))
+ (if (TYPE_UNSIGNED (type))
+ (minus (minmax @0 @2) @1))))
+
/* Optimize (((signed)a CMP 0) ? max<a,CST2> : CST3 */
(for cmp (lt ge)
minmax (min max)