On 10/7/26 8:51 PM, Daniel Barboza wrote:
This is done by RTL.  Do it earlier in Gimple to potentially allow more
optimizations opportunities.

Bootstrapped and regression tested in x86_64.

        PR 126644

gcc/ChangeLog:

        * match.pd:

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/pr126644.c: New test.
---
  gcc/match.pd                             | 19 +++++++++++++++++++
  gcc/testsuite/gcc.dg/tree-ssa/pr126644.c | 18 ++++++++++++++++++
  2 files changed, 37 insertions(+)
  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126644.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 2d1161b860b..06bbe32c029 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1561,6 +1561,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
              { wide_int_to_tree (type,
                                wi::lshift (wone, wi::to_wide (@2))); }))))
+#if GIMPLE
+/* PR126644: A << CST >> CST -> A
+   As long as the upper CST bits of A are known to be zero.  */
+(simplify
+ (rshift (lshift@2 @0 INTEGER_CST@1) @1)
+  (if (INTEGRAL_TYPE_P (type)
+       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && tree_fits_uhwi_p (@1)
+       && tree_to_uhwi (@1) < TYPE_PRECISION (type)
+       && single_use (@2))
+   (with {
+      unsigned int prec = TYPE_PRECISION (type);
+      wide_int mask = wi::mask (prec - tree_to_uhwi (@1),
+                               true, prec);
+    }
+    (if ((tree_nonzero_bits (@0) & mask) == 0)
+     @0))))
+#endif
+
Doesn't this fail from a correctness standpoint if we're dealing with a signed type?  The upper CST bits may be zero, but CST+1 may be on, so after the left shift that on bit is in the sign bit, then we shift it right (arithmetically if the type is signed), filling in 1s rather than 0s in the vacated bits.

Jeff
  /* Fold (-x >> C) into -(x > 0) where C = precision(type) - 1.  */
  (for cst (INTEGER_CST VECTOR_CST)
   (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126644.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr126644.c
new file mode 100644
index 00000000000..73286cd5a1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126644.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+int f1 (int a)
+{
+  if ((a & 0xE0000000) != 0)  __builtin_unreachable ();
+
+  return a << 3 >> 3;
+}
+
+/* Can't be optimized.  */
+int f2 (int a, int b)
+{
+  return a << 3 >> 3;
+}
+
+/* { dg-final { scan-tree-dump-times " << " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " >> " 1 "optimized" } } */

Reply via email to