Hi,
  After SSA-expand, the code which did the optimization for
(a&(1<<C))!=0 to (a>>C)&1 became not working because BIT_AND_EXPR
would no longer be in there.  This patch fixes the problem by using
get_def_for_expr to get the BIT_AND_EXPR.

OK?  Bootstrapped and tested on x86_64-linux-gnu with no regressions.

Thanks,
Andrew Pinski

ChangeLog:
* expr.c (do_store_flag): Rewrite code that looks for BIT_AND_EXPR for
SSA-expand.

testsuite/ChangeLog:
* gcc.dg/pr45416.c: New testcase.
Index: testsuite/gcc.dg/pr45416.c
===================================================================
--- testsuite/gcc.dg/pr45416.c  (revision 0)
+++ testsuite/gcc.dg/pr45416.c  (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+int foo(long long a)
+{
+   if (a & (long long) 0x400)
+      return 1;
+   return 0;
+}
+
+/* { dg-final { scan-assembler "andl" { target i?86-*-linux* x86_64-*-linux* } 
} } " */
+/* { dg-final { scan-assembler "setne" { target i?86-*-linux* x86_64-*-linux* 
} } }" */
+/* { dg-final { scan-assembler "and" { target arm*-*-* } } }" */
+/* { dg-final { scan-assembler-not "moveq" { target arm*-*-* } } }" */
Index: expr.c
===================================================================
--- expr.c      (revision 182068)
+++ expr.c      (working copy)
@@ -10563,15 +10563,22 @@ do_store_flag (sepops ops, rtx target, e
      so we just call into the folder and expand its result.  */
 
   if ((code == NE || code == EQ)
-      && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
-      && integer_pow2p (TREE_OPERAND (arg0, 1))
+      && integer_zerop (arg1)
       && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type)))
     {
-      tree type = lang_hooks.types.type_for_mode (mode, unsignedp);
-      return expand_expr (fold_single_bit_test (loc,
-                                               code == NE ? NE_EXPR : EQ_EXPR,
-                                               arg0, arg1, type),
-                         target, VOIDmode, EXPAND_NORMAL);
+      gimple srcstmt = get_def_for_expr (arg0, BIT_AND_EXPR);
+      if (srcstmt
+         && integer_pow2p (gimple_assign_rhs2 (srcstmt)))
+       {
+         enum tree_code tcode = code == NE ? NE_EXPR : EQ_EXPR;
+         tree type = lang_hooks.types.type_for_mode (mode, unsignedp);
+         tree temp = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg1),
+                                      gimple_assign_rhs1 (srcstmt),
+                                      gimple_assign_rhs2 (srcstmt));
+         temp = fold_single_bit_test (loc, tcode, temp, arg1, type);
+         if (temp)
+           return expand_expr (temp, target, VOIDmode, EXPAND_NORMAL);
+       }
     }
 
   if (! get_subtarget (target)

Reply via email to