]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
match.pd: Restrict clz cmp 0 replacement by single_use, PR99142
authorHans-Peter Nilsson <hp@axis.com>
Tue, 16 Feb 2021 21:27:53 +0000 (22:27 +0100)
committerHans-Peter Nilsson <hp@axis.com>
Thu, 18 Feb 2021 12:19:08 +0000 (13:19 +0100)
If we're not going to eliminate the clz, it's better for the
comparison to use that result than its input, so we don't
extend the lifetime of the input.  Also, an additional use
of the result is more likely cheaper than a compare of the
input, in particular considering that the clz may have made
available a non-zero condition matching the original use.
The "s" modifier doesn't stop this situation, as the
transformation wouldn't result in "an expression with more
than one operator"; a gating single_use condition on the
result is necessary.

gcc:
PR tree-optimization/99142
* match.pd (clz cmp 0): Gate replacement on single_use of clz result.

gcc/testsuite:
PR tree-optimization/99142
* gcc.dg/tree-ssa/pr99142.c: New test.

gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr99142.c [new file with mode: 0644]

index e14f69744d7e320c6289de7db6f57ab31d7c53ba..760f773cf1b13794094d11543ffa07c55769936d 100644 (file)
@@ -6315,8 +6315,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (for op (eq ne)
       cmp (lt ge)
   (simplify
-   (op (clz:s @0) INTEGER_CST@1)
-   (if (integer_zerop (@1))
+   (op (clz:s@2 @0) INTEGER_CST@1)
+   (if (integer_zerop (@1) && single_use (@2))
     /* clz(X) == 0 is (int)X < 0 and clz(X) != 0 is (int)X >= 0.  */
     (with { tree stype = signed_type_for (TREE_TYPE (@0));
            HOST_WIDE_INT val = 0;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr99142.c b/gcc/testsuite/gcc.dg/tree-ssa/pr99142.c
new file mode 100644 (file)
index 0000000..1781a89
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " >= 0\\)" "optimized" } } */
+int f(int a, int *b, int *d)
+{
+  int c = __builtin_clz(a);
+
+  *b = c;
+
+  if (c != 0)
+    *d = c;
+
+  return c;
+}