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)