diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-12-21 16:54:55 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-12-21 16:54:55 +0100 |
commit | f9f248c8b86bbc5c69d4c3083d617736a65d7244 (patch) | |
tree | b0383a5bf34aa046177c0201b4320f8670639d21 /gcc/expr.c | |
parent | 247c45b265ff85428aafb7cfcf6f968936ad48f3 (diff) | |
download | gcc-f9f248c8b86bbc5c69d4c3083d617736a65d7244.zip gcc-f9f248c8b86bbc5c69d4c3083d617736a65d7244.tar.gz gcc-f9f248c8b86bbc5c69d4c3083d617736a65d7244.tar.bz2 |
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) <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.
From-SVN: r267326
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 24 |
1 files changed, 11 insertions, 13 deletions
@@ -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); |