From: Jakub Jelinek Date: Fri, 30 Aug 2019 11:22:27 +0000 (+0200) Subject: backport: re PR rtl-optimization/88563 (wrong code with -O2 -fno-code-hoisting -fno... X-Git-Tag: releases/gcc-7.5.0~280 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d1d8699642bb56951c9c8826206e2d172b485d1;p=thirdparty%2Fgcc.git backport: re PR rtl-optimization/88563 (wrong code with -O2 -fno-code-hoisting -fno-tree-ccp -fno-tree-dominator-opts -fno-tree-forwprop -fno-tree-fre -fno-tree-pre -fno-tree-vrp) Backported from mainline 2018-12-21 Jakub Jelinek PR rtl-optimization/88563 * expr.c (expand_expr_real_2) : 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. From-SVN: r275081 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 230038a4eb19..0cc2c4b1540a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,14 @@ 2019-08-30 Jakub Jelinek Backported from mainline + 2018-12-21 Jakub Jelinek + + PR rtl-optimization/88563 + * expr.c (expand_expr_real_2) : 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. + 2018-12-13 Jakub Jelinek PR rtl-optimization/88470 diff --git a/gcc/expr.c b/gcc/expr.c index ee545ce071f0..47cc005a5661 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8671,7 +8671,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0)); this_optab = usmul_widen_optab; if (find_widening_optab_handler (this_optab, mode, innermode, 0) - != CODE_FOR_nothing) + != CODE_FOR_nothing) { if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, @@ -8683,8 +8683,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, != 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)); } @@ -8706,7 +8706,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, if (TREE_CODE (treeop0) != INTEGER_CST) { if (find_widening_optab_handler (this_optab, mode, innermode, 0) - != CODE_FOR_nothing) + != CODE_FOR_nothing) { expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); @@ -8715,9 +8715,9 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, 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, @@ -8728,21 +8728,19 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, return REDUCE_BIT_FIELD (temp); } if (find_widening_optab_handler (other_optab, mode, innermode, 0) - != 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 (innermode, 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 (innermode, temp); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2dd25cb7c6ff..fbf21ce95fe4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2019-08-30 Jakub Jelinek Backported from mainline + 2018-12-21 Jakub Jelinek + + PR rtl-optimization/88563 + * gcc.dg/pr88563.c: New test. + 2018-12-13 Jakub Jelinek PR rtl-optimization/88470 diff --git a/gcc/testsuite/gcc.dg/pr88563.c b/gcc/testsuite/gcc.dg/pr88563.c new file mode 100644 index 000000000000..5526a8d01570 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88563.c @@ -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; +}