[Bug middle-end/82062] [8 regression] simple conditional expressions no longer folded
rguenther at suse dot de
gcc-bugzilla@gcc.gnu.org
Wed Oct 25 13:15:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82062
--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> ---
On Wed, 25 Oct 2017, ebotcazou at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82062
>
> --- Comment #11 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> > Simplified but not equal - you are also stripping a possible truncation.
> > I think the original code only ever stripped widening conversions.
>
> Right, but IMO there is no real reason to distinguish the 2 cases now.
>
> > It also had some additional constraints on the stripping looking
> > at the other comparison operand (for some weird reason...).
>
> I agree with your wording. :-) I think it was supposed to deal with more
> general cases of comparison X < (T1) Y ? (T2) X : (T2) Y. My understanding is
> that it's obsolete if we forbids non-NOPS conversions in the operands of the
> comparison.
>
> > I guess I'm ok with your proposed change if you restrict it to
> > widening conversions (and use CONVERT_EXPR_P (arg1)).
>
> Fair enough. Here's what I'm going to test:
>
> Index: fold-const.c
> ===================================================================
> --- fold-const.c (revision 254037)
> +++ fold-const.c (working copy)
> @@ -3366,7 +3366,8 @@ operand_equal_p (const_tree arg0, const_
> #undef OP_SAME_WITH_NULL
> }
>
> -/* Similar to operand_equal_p, but strip nops first. */
> +/* Similar to operand_equal_p, but see if ARG0 might be a variant of ARG1
> + with a different signedness or a narrower precision. */
>
> static bool
> operand_equal_for_comparison_p (tree arg0, tree arg1)
> @@ -3381,9 +3382,20 @@ operand_equal_for_comparison_p (tree arg
> /* Discard any conversions that don't change the modes of ARG0 and ARG1
> and see if the inner values are the same. This removes any
> signedness comparison, which doesn't matter here. */
> - STRIP_NOPS (arg0);
> - STRIP_NOPS (arg1);
> - if (operand_equal_p (arg0, arg1, 0))
> + tree op0 = arg0;
> + tree op1 = arg1;
> + STRIP_NOPS (op0);
> + STRIP_NOPS (op1);
> + if (operand_equal_p (op0, op1, 0))
> + return true;
> +
> + /* Discard a single widening conversion from ARG1 and see if the inner
> + value is the same as ARG0. */
> + if (CONVERT_EXPR_P (arg1)
> + && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0)))
> + && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))
> + < TYPE_PRECISION (TREE_TYPE (arg1))
> + && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
> return true;
>
> return false;
> @@ -11169,8 +11181,8 @@ fold_ternary_loc (location_t loc, enum t
>
> Also try swapping the arguments and inverting the conditional. */
> if (COMPARISON_CLASS_P (arg0)
> - && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), arg1)
> - && !HONOR_SIGNED_ZEROS (element_mode (arg1)))
> + && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op1)
> + && !HONOR_SIGNED_ZEROS (element_mode (op1)))
> {
> tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2);
> if (tem)
>
>
> The third hunk makes sure that we always pass the unstripped operand to the
> predicate, as in the swapped case just below.
Ok if it passes bootstrap / regtest (with the testcase added of course).
More information about the Gcc-bugs
mailing list