]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/9348 ([HP-UX] error in int to unsigned long multiplication)
authorRoger Sayle <roger@eyesopen.com>
Tue, 3 Feb 2004 21:31:00 +0000 (21:31 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 3 Feb 2004 21:31:00 +0000 (21:31 +0000)
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

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/multdi-1.c [new file with mode: 0644]

index daf843df80f7b2d26e65bc5b53eacc0e52583228..2ee6a1435877bccf1dab2e84a7f7e600ae95f6b3 100644 (file)
@@ -1,3 +1,12 @@
+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>
 
        * varasm.c (const_desc_rtx_sym_eq): Compare symbol strings.
index ba27b04d115a57e794a2d4efadf6d650f86f10ff..55e5f0690fe7d598adacab8b75daca3966bc089d 100644 (file)
@@ -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;
                }
            }
index f31c5c53007b6187aaafad5b8b991c0829c581c8..ca134857b2d41a4c37aff278e5ac34f2efd505f9 100644 (file)
@@ -1,3 +1,8 @@
+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>
 
        PR c++/13925
diff --git a/gcc/testsuite/gcc.c-torture/execute/multdi-1.c b/gcc/testsuite/gcc.c-torture/execute/multdi-1.c
new file mode 100644 (file)
index 0000000..1ffcc57
--- /dev/null
@@ -0,0 +1,20 @@
+/* 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;
+}
+