2020-05-08 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/94956
+ * match.pd (FFS): Optimize __builtin_ffs* of non-zero argument into
+ __builtin_ctz* + 1 if direct IFN_CTZ is supported.
+
PR tree-optimization/94913
* match.pd (A - B + -1 >= A to B >= A): New simplification.
(A - B > A to A < B): Don't test TYPE_OVERFLOW_WRAPS which is always
&& direct_internal_fn_supported_p (IFN_POPCOUNT, type,
OPTIMIZE_FOR_BOTH))
(convert (IFN_POPCOUNT:type @0)))))
+
+/* __builtin_ffs needs to deal on many targets with the possible zero
+ argument. If we know the argument is always non-zero, __builtin_ctz + 1
+ should lead to better code. */
+(simplify
+ (FFS tree_expr_nonzero_p@0)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && direct_internal_fn_supported_p (IFN_CTZ, TREE_TYPE (@0),
+ OPTIMIZE_FOR_SPEED))
+ (plus (CTZ:type @0) { build_one_cst (type); })))
#endif
/* Simplify:
2020-05-08 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/94956
+ * gcc.target/i386/pr94956.c: New test.
+
PR tree-optimization/94913
* gcc.dg/tree-ssa/pr94913.c: New test.
--- /dev/null
+/* PR tree-optimization/94956 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "\tcmovne\t" } } */
+/* { dg-final { scan-assembler-not "\tsete\t" } } */
+
+int
+foo (unsigned x)
+{
+ if (x == 0) __builtin_unreachable ();
+ return __builtin_ffs (x) - 1;
+}
+
+int
+bar (unsigned long x)
+{
+ if (x == 0) __builtin_unreachable ();
+ return __builtin_ffsl (x) - 1;
+}
+
+#ifdef __x86_64__
+int
+baz (unsigned long long x)
+{
+ if (x == 0) __builtin_unreachable ();
+ return __builtin_ffsll (x) - 1;
+}
+#endif