diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-02-03 21:31:00 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-02-03 21:31:00 +0000 |
commit | 888d65b5a81249c56aa92bc2998c798929f29f30 (patch) | |
tree | df60fe33a838990b239163a30dda629632e31212 /gcc/expr.c | |
parent | a8c0bbc7214a44d82448ea5b6d443f53c8b5c43b (diff) | |
download | gcc-888d65b5a81249c56aa92bc2998c798929f29f30.zip gcc-888d65b5a81249c56aa92bc2998c798929f29f30.tar.gz gcc-888d65b5a81249c56aa92bc2998c798929f29f30.tar.bz2 |
re PR target/9348 ([HP-UX] error in int to unsigned long multiplication)
PR target/9348
* expr.c (expand_expr_real) <MULT_EXPR>: When performing widening
multiplies with a multiplication of the wrong signedness, its the
signedness of the multiplication that we've performed that needs to
be passed to expand_mult_highpart_adjust. Avoid emitting a nop-move
if expand_mult_highpart_adjust places the result in target.
* gcc.c-torture/execute/multdi-1.c: New test case.
From-SVN: r77192
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 26 |
1 files changed, 13 insertions, 13 deletions
@@ -7859,12 +7859,12 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, == TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))))))) { - enum machine_mode innermode - = TYPE_MODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))); - optab other_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) - ? smul_widen_optab : umul_widen_optab); - this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) - ? umul_widen_optab : smul_widen_optab); + tree op0type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)); + enum machine_mode innermode = TYPE_MODE (op0type); + bool zextend_p = TREE_UNSIGNED (op0type); + optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; + this_optab = zextend_p ? umul_widen_optab : smul_widen_optab; + if (mode == GET_MODE_WIDER_MODE (innermode)) { if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) @@ -7882,7 +7882,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing && innermode == word_mode) { - rtx htem; + rtx htem, hipart; op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), NULL_RTX, VOIDmode, 0); if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) @@ -7895,12 +7895,12 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, NULL_RTX, VOIDmode, 0); temp = expand_binop (mode, other_optab, op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); - htem = expand_mult_highpart_adjust (innermode, - gen_highpart (innermode, temp), - op0, op1, - gen_highpart (innermode, temp), - unsignedp); - emit_move_insn (gen_highpart (innermode, temp), htem); + hipart = gen_highpart (innermode, temp); + htem = expand_mult_highpart_adjust (innermode, hipart, + op0, op1, hipart, + zextend_p); + if (htem != hipart) + emit_move_insn (hipart, htem); return temp; } } |