This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix WIDEN_MULT_EXPR expansion (PR rtl-optimization/88563)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 21 Dec 2018 16:19:53 +0100 (CET)
- Subject: Re: [PATCH] Fix WIDEN_MULT_EXPR expansion (PR rtl-optimization/88563)
- References: <20181221150926.GH23305@tucnak>
On Fri, 21 Dec 2018, Jakub Jelinek wrote:
> Hi!
>
> In the PR57251 fixes, I've messed up the modes, convert_modes first argument
> is the to mode and second argument is the from mode, i.e. mode the third
> argument has or is assumed to have.
>
> The following patch fixes that. Additionally I've swapped two conditions
> to avoid first convert_modes a CONST_INT to one mode and then convert_modes
> it again from the old mode rather than new one. With the two conditions
> swapped it uses just one convert_modes for that case.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Richard.
> 2018-12-21 Jakub Jelinek <jakub@redhat.com>
>
> PR rtl-optimization/88563
> * expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Swap innermode
> and mode arguments to convert_modes. Likewise swap mode and word_mode
> arguments. Handle both arguments with VOIDmode before convert_modes
> of one of them. Formatting fixes.
>
> * gcc.dg/pr88563.c: New test.
>
> --- gcc/expr.c.jj 2018-12-18 12:20:53.511482381 +0100
> +++ gcc/expr.c 2018-12-21 11:57:25.523576071 +0100
> @@ -8775,8 +8775,8 @@ expand_expr_real_2 (sepops ops, rtx targ
> != INTEGER_CST check. Handle it. */
> if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
> {
> - op0 = convert_modes (innermode, mode, op0, true);
> - op1 = convert_modes (innermode, mode, op1, false);
> + op0 = convert_modes (mode, innermode, op0, true);
> + op1 = convert_modes (mode, innermode, op1, false);
> return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
> target, unsignedp));
> }
> @@ -8798,7 +8798,7 @@ expand_expr_real_2 (sepops ops, rtx targ
> if (TREE_CODE (treeop0) != INTEGER_CST)
> {
> if (find_widening_optab_handler (this_optab, mode, innermode)
> - != CODE_FOR_nothing)
> + != CODE_FOR_nothing)
> {
> expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
> EXPAND_NORMAL);
> @@ -8807,9 +8807,9 @@ expand_expr_real_2 (sepops ops, rtx targ
> if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
> {
> widen_mult_const:
> - op0 = convert_modes (innermode, mode, op0, zextend_p);
> + op0 = convert_modes (mode, innermode, op0, zextend_p);
> op1
> - = convert_modes (innermode, mode, op1,
> + = convert_modes (mode, innermode, op1,
> TYPE_UNSIGNED (TREE_TYPE (treeop1)));
> return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
> target,
> @@ -8820,21 +8820,19 @@ expand_expr_real_2 (sepops ops, rtx targ
> return REDUCE_BIT_FIELD (temp);
> }
> if (find_widening_optab_handler (other_optab, mode, innermode)
> - != CODE_FOR_nothing
> + != CODE_FOR_nothing
> && innermode == word_mode)
> {
> rtx htem, hipart;
> op0 = expand_normal (treeop0);
> - if (TREE_CODE (treeop1) == INTEGER_CST)
> - op1 = convert_modes (word_mode, mode,
> - expand_normal (treeop1),
> - TYPE_UNSIGNED (TREE_TYPE (treeop1)));
> - else
> - op1 = expand_normal (treeop1);
> - /* op0 and op1 might still be constant, despite the above
> + op1 = expand_normal (treeop1);
> + /* op0 and op1 might be constants, despite the above
> != INTEGER_CST check. Handle it. */
> if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
> goto widen_mult_const;
> + if (TREE_CODE (treeop1) == INTEGER_CST)
> + op1 = convert_modes (mode, word_mode, op1,
> + TYPE_UNSIGNED (TREE_TYPE (treeop1)));
> temp = expand_binop (mode, other_optab, op0, op1, target,
> unsignedp, OPTAB_LIB_WIDEN);
> hipart = gen_highpart (word_mode, temp);
> --- gcc/testsuite/gcc.dg/pr88563.c.jj 2018-12-21 12:19:02.850681604 +0100
> +++ gcc/testsuite/gcc.dg/pr88563.c 2018-12-21 12:18:52.891841942 +0100
> @@ -0,0 +1,15 @@
> +/* PR rtl-optimization/88563 */
> +/* { dg-do run { target int128 } } */
> +/* { dg-options "-O2 -fno-code-hoisting -fno-tree-ccp -fno-tree-dominator-opts -fno-tree-forwprop -fno-tree-fre -fno-tree-pre -fno-tree-vrp" } */
> +
> +int
> +main ()
> +{
> +#if __SIZEOF_LONG_LONG__ == 8 && __SIZEOF_INT128__ == 16 && __CHAR_BIT__ == 8
> + unsigned __int128 a = 5;
> + __builtin_mul_overflow (0xffffffffffffffffULL, (unsigned long long) a, &a);
> + if (a != ((unsigned __int128)4 << 64 | 0xfffffffffffffffb))
> + __builtin_abort ();
> +#endif
> + return 0;
> +}
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)