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  <ja...@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 <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to