[backport from gcc-4.7/trunk ] Date: Tue, 6 Dec 2011 20:17:04 -0800 Subject: [PATCH] Fix PR middle-end/45416, missing opt for (a&(1<>C)&1 From: Andrew Pinski List-Archive: Hi, After SSA-expand, the code which did the optimization for (a&(1<>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 gcc/ 2011-12-07 Andrew Pinski PR middle-end/45416 * expr.c (do_store_flag): Rewrite code that looks for BIT_AND_EXPR for SSA-expand. gcc/testsuite/ 2011-12-07 Andrew Pinski PR middle-end/45416 * gcc.dg/pr45416.c: New testcase. --- gcc-4.6.2/gcc/expr.c.~1~ 2011-08-10 11:17:32.000000000 +0200 +++ gcc-4.6.2/gcc/expr.c 2011-12-17 15:49:38.000000000 +0100 @@ -10098,15 +10098,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) --- gcc-4.6.2/gcc/testsuite/gcc.dg/pr45416.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.2/gcc/testsuite/gcc.dg/pr45416.c 2011-12-17 15:49:38.000000000 +0100 @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +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-not "setne" { target i?86-*-linux* x86_64-*-linux* } } }" */ +/* { dg-final { scan-assembler "and" { target arm*-*-* } } }" */ +/* { dg-final { scan-assembler-not "moveq" { target arm*-*-* } } }" */