/* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized --param logical-op-non-short-circuit=1" } */
+/* { dg-options "-O1 -fdump-tree-phiopt2 -fdump-tree-optimized --param logical-op-non-short-circuit=1" } */
int f(int a, int b, int c)
{
return a;
}
+int i(int a, int b, int c)
+{
+ if ((a > c) & (a == b))
+ return a;
+ return b;
+}
+
+int j(int a, int b, int c)
+{
+ if ((a > c) & (a == b))
+ return b;
+ return a;
+}
+
+int k(int a, int b, int c)
+{
+ if ((a > c) | (a != b))
+ return b;
+ return a;
+}
+
+int l(int a, int b, int c)
+{
+ if ((a > c) | (a != b))
+ return a;
+ return b;
+}
+
+/* { dg-final { scan-tree-dump-times "if" 0 "phiopt2" } } */
/* { dg-final { scan-tree-dump-times "if" 0 "optimized" } } */
return false;
}
-/* RHS is a source argument in a BIT_AND_EXPR which feeds a conditional
- of the form SSA_NAME NE 0.
+/* RHS is a source argument in a BIT_AND_EXPR or BIT_IOR_EXPR which feeds
+ a conditional of the form SSA_NAME NE 0.
- If RHS is fed by a simple EQ_EXPR comparison of two values, see if
- the two input values of the EQ_EXPR match arg0 and arg1.
+ If RHS is fed by a simple EQ_EXPR or NE_EXPR comparison of two values,
+ see if the two input values of the comparison match arg0 and arg1.
If so update *code and return TRUE. Otherwise return FALSE. */
static bool
rhs_is_fed_for_value_replacement (const_tree arg0, const_tree arg1,
- enum tree_code *code, const_tree rhs)
+ enum tree_code *code, const_tree rhs,
+ enum tree_code bit_expression_code)
{
/* Obviously if RHS is not an SSA_NAME, we can't look at the defining
statement. */
{
gimple *def1 = SSA_NAME_DEF_STMT (rhs);
- /* Verify the defining statement has an EQ_EXPR on the RHS. */
- if (is_gimple_assign (def1) && gimple_assign_rhs_code (def1) == EQ_EXPR)
+ /* Verify the defining statement has an EQ_EXPR or NE_EXPR on the RHS. */
+ if (is_gimple_assign (def1)
+ && ((bit_expression_code == BIT_AND_EXPR
+ && gimple_assign_rhs_code (def1) == EQ_EXPR)
+ || (bit_expression_code == BIT_IOR_EXPR
+ && gimple_assign_rhs_code (def1) == NE_EXPR)))
{
- /* Finally verify the source operands of the EQ_EXPR are equal
- to arg0 and arg1. */
+ /* Finally verify the source operands of the EQ_EXPR or NE_EXPR
+ are equal to arg0 and arg1. */
tree op0 = gimple_assign_rhs1 (def1);
tree op1 = gimple_assign_rhs2 (def1);
if ((operand_equal_for_phi_arg_p (arg0, op0)
/* Return TRUE if arg0/arg1 are equal to the rhs/lhs or lhs/rhs of COND.
- Also return TRUE if arg0/arg1 are equal to the source arguments of a
- an EQ comparison feeding a BIT_AND_EXPR which feeds COND.
+ Also return TRUE if arg0/arg1 are equal to the source arguments of an
+ EQ comparison feeding a BIT_AND_EXPR, or NE comparison feeding a
+ BIT_IOR_EXPR which feeds COND.
Return FALSE otherwise. */
return true;
/* Now handle more complex case where we have an EQ comparison
- which feeds a BIT_AND_EXPR which feeds COND.
+ feeding a BIT_AND_EXPR, or a NE comparison feeding a BIT_IOR_EXPR,
+ which then feeds into COND.
First verify that COND is of the form SSA_NAME NE 0. */
if (*code != NE_EXPR || !integer_zerop (rhs)
|| TREE_CODE (lhs) != SSA_NAME)
return false;
- /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR. */
+ /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR or BIT_OR_EXPR. */
def = SSA_NAME_DEF_STMT (lhs);
- if (!is_gimple_assign (def) || gimple_assign_rhs_code (def) != BIT_AND_EXPR)
+ if (!is_gimple_assign (def)
+ || (gimple_assign_rhs_code (def) != BIT_AND_EXPR
+ && gimple_assign_rhs_code (def) != BIT_IOR_EXPR))
return false;
- /* Now verify arg0/arg1 correspond to the source arguments of an
- EQ comparison feeding the BIT_AND_EXPR. */
+ /* Now verify arg0/arg1 correspond to the source arguments of an EQ
+ comparison feeding the BIT_AND_EXPR or a NE comparison feeding the
+ BIT_IOR_EXPR. */
tree tmp = gimple_assign_rhs1 (def);
- if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp))
+ if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
+ gimple_assign_rhs_code (def)))
return true;
tmp = gimple_assign_rhs2 (def);
- if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp))
+ if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
+ gimple_assign_rhs_code (def)))
return true;
return false;