This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix WIDEN_MULT_EXPR expansion (PR rtl-optimization/88563)


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]