On Wed, Jul 27, 2011 at 8:33 AM, Kai Tietz <ktiet...@googlemail.com> wrote: > I adjusted logic in patch for interger zero/all-one case for bit > and/or. By simply copying the variable operand to destination, > without checking for valid ranges for and-expression with all-ones and > or-expression with zero operand, logic could be simplified pretty > much. > I adjusted names for variables and removed unnecessary helper variable > about ranges. > I didn't noticed that the range-check-function doesn't return in all > cases true for a partial ranged variable. Thanks for the heads-up. > > Regression tested for all languages and boostrapped on host > x86_64-pc-linux-gnu. Ok for apply?
Ok with a proper ChangeLog entry and ... > @@ -2702,9 +2658,39 @@ extract_range_from_binary_expr (value_ra > int_cst_range1 = zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1, > &must_be_nonzero1); > > + singleton_val = (vr0_int_cst_singleton_p ? vr0.min : vr1.min); > + non_singleton_vr = (vr0_int_cst_singleton_p ? &vr1 : &vr0); > + > type = VR_RANGE; > if (vr0_int_cst_singleton_p && vr1_int_cst_singleton_p) > min = max = int_const_binop (code, vr0.max, vr1.max); > + else if ((vr0_int_cst_singleton_p || vr1_int_cst_singleton_p) > + && (integer_zerop (singleton_val) > + || integer_all_onesp (singleton_val))) > + { > + /* If one of the operands is zero for and-case, we know that > + * the whole expression evaluates zero. > + If one of the operands has all bits set to one for > + or-case, we know that the whole expression evaluates > + to this one. */ > + min = max = singleton_val; > + if ((code == BIT_IOR_EXPR > + && !integer_all_onesp (singleton_val)) && integer_zerop (singleton_val) > + || (code == BIT_AND_EXPR > + && !integer_zerop (singleton_val))) && integer_all_onesp (singleton_val) instead of the inverted checks. Thanks, Richard. > + /* If one of the operands has all bits set to one, we know > + that the whole expression evaluates to the other one for > + the and-case. > + If one of the operands is zero, we know that the whole > + expression evaluates to the other one for the or-case. */ > + { > + type = non_singleton_vr->type; > + min = non_singleton_vr->min; > + max = non_singleton_vr->max; > + } > + set_value_range (vr, type, min, max, NULL); > + return; > + } > else if (!int_cst_range0 && !int_cst_range1) > { > set_value_range_to_varying (vr); > @@ -3316,10 +3302,7 @@ extract_range_from_assignment (value_ran > extract_range_from_assert (vr, gimple_assign_rhs1 (stmt)); > else if (code == SSA_NAME) > extract_range_from_ssa_name (vr, gimple_assign_rhs1 (stmt)); > - else if (TREE_CODE_CLASS (code) == tcc_binary > - || code == TRUTH_AND_EXPR > - || code == TRUTH_OR_EXPR > - || code == TRUTH_XOR_EXPR) > + else if (TREE_CODE_CLASS (code) == tcc_binary) > extract_range_from_binary_expr (vr, gimple_assign_rhs_code (stmt), > gimple_expr_type (stmt), > gimple_assign_rhs1 (stmt), > @@ -4532,11 +4515,9 @@ register_edge_assert_for_1 (tree op, enu > invert); > } > else if ((code == NE_EXPR > - && (gimple_assign_rhs_code (op_def) == TRUTH_AND_EXPR > - || gimple_assign_rhs_code (op_def) == BIT_AND_EXPR)) > + && gimple_assign_rhs_code (op_def) == BIT_AND_EXPR) > || (code == EQ_EXPR > - && (gimple_assign_rhs_code (op_def) == TRUTH_OR_EXPR > - || gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))) > + && gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR)) > { > /* Recurse on each operand. */ > retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def), > @@ -4601,8 +4582,8 @@ register_edge_assert_for (tree name, edg > the value zero or one, then we may be able to assert values > for SSA_NAMEs which flow into COND. */ > > - /* In the case of NAME == 1 or NAME != 0, for TRUTH_AND_EXPR defining > - statement of NAME we can assert both operands of the TRUTH_AND_EXPR > + /* In the case of NAME == 1 or NAME != 0, for BIT_AND_EXPR defining > + statement of NAME we can assert both operands of the BIT_AND_EXPR > have nonzero value. */ > if (((comp_code == EQ_EXPR && integer_onep (val)) > || (comp_code == NE_EXPR && integer_zerop (val)))) > @@ -4610,8 +4591,7 @@ register_edge_assert_for (tree name, edg > gimple def_stmt = SSA_NAME_DEF_STMT (name); > > if (is_gimple_assign (def_stmt) > - && (gimple_assign_rhs_code (def_stmt) == TRUTH_AND_EXPR > - || gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR)) > + && gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR) > { > tree op0 = gimple_assign_rhs1 (def_stmt); > tree op1 = gimple_assign_rhs2 (def_stmt); > @@ -4620,20 +4600,20 @@ register_edge_assert_for (tree name, edg > } > } > > - /* In the case of NAME == 0 or NAME != 1, for TRUTH_OR_EXPR defining > - statement of NAME we can assert both operands of the TRUTH_OR_EXPR > + /* In the case of NAME == 0 or NAME != 1, for BIT_IOR_EXPR defining > + statement of NAME we can assert both operands of the BIT_IOR_EXPR > have zero value. */ > if (((comp_code == EQ_EXPR && integer_zerop (val)) > || (comp_code == NE_EXPR && integer_onep (val)))) > { > gimple def_stmt = SSA_NAME_DEF_STMT (name); > > + /* For BIT_IOR_EXPR only if NAME == 0 both operands have > + necessarily zero value, or if type-precision is one. */ > if (is_gimple_assign (def_stmt) > - && (gimple_assign_rhs_code (def_stmt) == TRUTH_OR_EXPR > - /* For BIT_IOR_EXPR only if NAME == 0 both operands have > - necessarily zero value. */ > - || (comp_code == EQ_EXPR > - && (gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)))) > + && (gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR > + && (TYPE_PRECISION (TREE_TYPE (name)) == 1 > + || comp_code == EQ_EXPR))) > { > tree op0 = gimple_assign_rhs1 (def_stmt); > tree op1 = gimple_assign_rhs2 (def_stmt); > @@ -6804,8 +6784,7 @@ simplify_truth_ops_using_ranges (gimple_ > { > /* Exclude anything that should have been already folded. */ > if (rhs_code != EQ_EXPR > - && rhs_code != NE_EXPR > - && rhs_code != TRUTH_XOR_EXPR) > + && rhs_code != NE_EXPR) > return false; > > if (!integer_zerop (op1) > @@ -6849,14 +6828,9 @@ simplify_truth_ops_using_ranges (gimple_ > else > location = gimple_location (stmt); > > - if (rhs_code == TRUTH_AND_EXPR || rhs_code == TRUTH_OR_EXPR) > - warning_at (location, OPT_Wstrict_overflow, > - _("assuming signed overflow does not occur when " > - "simplifying && or || to & or |")); > - else > - warning_at (location, OPT_Wstrict_overflow, > - _("assuming signed overflow does not occur when " > - "simplifying ==, != or ! to identity or ^")); > + warning_at (location, OPT_Wstrict_overflow, > + _("assuming signed overflow does not occur when " > + "simplifying ==, != or ! to identity or ^")); > } > > need_conversion = > @@ -6871,13 +6845,6 @@ simplify_truth_ops_using_ranges (gimple_ > > switch (rhs_code) > { > - case TRUTH_AND_EXPR: > - rhs_code = BIT_AND_EXPR; > - break; > - case TRUTH_OR_EXPR: > - rhs_code = BIT_IOR_EXPR; > - break; > - case TRUTH_XOR_EXPR: > case NE_EXPR: > if (integer_zerop (op1)) > { > @@ -7548,9 +7515,6 @@ simplify_stmt_using_ranges (gimple_stmt_ > case EQ_EXPR: > case NE_EXPR: > case TRUTH_NOT_EXPR: > - case TRUTH_AND_EXPR: > - case TRUTH_OR_EXPR: > - case TRUTH_XOR_EXPR: > /* Transform EQ_EXPR, NE_EXPR, TRUTH_NOT_EXPR into BIT_XOR_EXPR > or identity if the RHS is zero or one, and the LHS are known > to be boolean values. Transform all TRUTH_*_EXPR into >