Hello, this patch re-enables the branch-cost optimization on simple boolean-typed operands, which are casted to a wider integral type. This happens due casts from boolean-types are preserved, but FE might expands simple-expression to wider mode.
I added two tests for already working branch-cost optimization for IA-architecture and two for explicit checking for boolean-type. ChangeLog 2011-10-20 Kai Tietz <kti...@redhat.com> * fold-const.c (simple_operand_p_2): Handle integral casts from boolean-operands. 2011-10-20 Kai Tietz <kti...@redhat.com> * gcc.target/i386/branch-cost1.c: New test. * gcc.target/i386/branch-cost2.c: New test. * gcc.target/i386/branch-cost3.c: New test. * gcc.target/i386/branch-cost4.c: New test. Bootstrapped and regression tested on x86_64-unknown-linux-gnu for all languages including Ada and Obj-C++. Ok for apply? Regards, Kai Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ + +extern int doo (void); + +int +foo (int a, int b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=2" } */ + +extern int doo (void); + +int +foo (_Bool a, _Bool b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times " & " 1 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost4.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ + +extern int doo (void); + +int +foo (_Bool a, _Bool b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ Index: gcc-head/gcc/fold-const.c =================================================================== --- gcc-head.orig/gcc/fold-const.c +++ gcc-head/gcc/fold-const.c @@ -3706,6 +3706,19 @@ simple_operand_p_2 (tree exp) /* Strip any conversions that don't change the machine mode. */ STRIP_NOPS (exp); + /* Handle integral widening casts from boolean-typed + expressions as simple. This happens due casts from + boolean-types are preserved, but FE might expands + simple-expression to wider mode. */ + if (INTEGRAL_TYPE_P (TREE_TYPE (exp)) + && CONVERT_EXPR_P (exp) + && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) + == BOOLEAN_TYPE) + { + exp = TREE_OPERAND (exp, 0); + STRIP_NOPS (exp); + } + code = TREE_CODE (exp); if (TREE_SIDE_EFFECTS (exp) Index: gcc-head/gcc/testsuite/gcc.target/i386/branch-cost1.c =================================================================== --- /dev/null +++ gcc-head/gcc/testsuite/gcc.target/i386/branch-cost1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple -mbranch-cost=0" } */ + +extern int doo (void); + +int +foo (int a, int b) +{ + if (a && b) + return doo (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-not " & " "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */