Commit 888d65b5 by Roger Sayle Committed by Roger Sayle

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
parent a8c0bbc7
2004-02-03 Roger Sayle <roger@eyesopen.com>
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.
2004-02-03 Richard Henderson <rth@redhat.com> 2004-02-03 Richard Henderson <rth@redhat.com>
* varasm.c (const_desc_rtx_sym_eq): Compare symbol strings. * varasm.c (const_desc_rtx_sym_eq): Compare symbol strings.
......
...@@ -7859,12 +7859,12 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, ...@@ -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))))))) TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))))))
{ {
enum machine_mode innermode tree op0type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0));
= TYPE_MODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))); enum machine_mode innermode = TYPE_MODE (op0type);
optab other_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) bool zextend_p = TREE_UNSIGNED (op0type);
? smul_widen_optab : umul_widen_optab); optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
? umul_widen_optab : smul_widen_optab);
if (mode == GET_MODE_WIDER_MODE (innermode)) if (mode == GET_MODE_WIDER_MODE (innermode))
{ {
if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 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, ...@@ -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 else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
&& innermode == word_mode) && innermode == word_mode)
{ {
rtx htem; rtx htem, hipart;
op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
NULL_RTX, VOIDmode, 0); NULL_RTX, VOIDmode, 0);
if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
...@@ -7895,12 +7895,12 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, ...@@ -7895,12 +7895,12 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
NULL_RTX, VOIDmode, 0); NULL_RTX, VOIDmode, 0);
temp = expand_binop (mode, other_optab, op0, op1, target, temp = expand_binop (mode, other_optab, op0, op1, target,
unsignedp, OPTAB_LIB_WIDEN); unsignedp, OPTAB_LIB_WIDEN);
htem = expand_mult_highpart_adjust (innermode, hipart = gen_highpart (innermode, temp);
gen_highpart (innermode, temp), htem = expand_mult_highpart_adjust (innermode, hipart,
op0, op1, op0, op1, hipart,
gen_highpart (innermode, temp), zextend_p);
unsignedp); if (htem != hipart)
emit_move_insn (gen_highpart (innermode, temp), htem); emit_move_insn (hipart, htem);
return temp; return temp;
} }
} }
......
2004-02-03 Roger Sayle <roger@eyesopen.com>
PR target/9348
* gcc.c-torture/execute/multdi-1.c: New test case.
2004-02-03 Mark Mitchell <mark@codesourcery.com> 2004-02-03 Mark Mitchell <mark@codesourcery.com>
PR c++/13925 PR c++/13925
......
/* PR target/9348 */
#define u_l_l unsigned long long
#define l_l long long
l_l mpy_res;
u_l_l mpy (long a, long b)
{
return (u_l_l) a * (u_l_l) b;
}
int main(void)
{
mpy_res = mpy(1,-1);
if (mpy_res != -1LL)
abort ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment