From f9f248c8b86bbc5c69d4c3083d617736a65d7244 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 21 Dec 2018 16:54:55 +0100 Subject: [PATCH] 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) 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: r267326 --- gcc/ChangeLog | 8 ++++++++ gcc/expr.c | 24 +++++++++++------------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/pr88563.c | 15 +++++++++++++++ 4 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr88563.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7738e8528b..ce6ba2f16ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +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-21 Uros Bizjak PR target/88556 diff --git a/gcc/expr.c b/gcc/expr.c index fe3647f0ac7..81831342677 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8775,8 +8775,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)); } @@ -8798,7 +8798,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) - != 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 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, @@ -8820,21 +8820,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) - != 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 749a7b71f35..76ffd3d60d1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-12-21 Jakub Jelinek + PR rtl-optimization/88563 + * gcc.dg/pr88563.c: New test. + PR c++/87125 * g++.dg/cpp0x/pr87125.C: New test. diff --git a/gcc/testsuite/gcc.dg/pr88563.c b/gcc/testsuite/gcc.dg/pr88563.c new file mode 100644 index 00000000000..5526a8d0157 --- /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; +} -- 2.30.2