gcc.c-torture/execute/20000403-1.c tripped over this on an internal
(16 bit) port doing SImode subtract.  The comments for expand_binop()
explicitly state that you can't rely on the target being set:

   If TARGET is nonzero, the value
   is generated there, if it is convenient to do so.

but we seem to have that expectation later:

          /* Main add/subtract of the input operands.  */
          x = expand_binop (word_mode, binoptab,
                            op0_piece, op1_piece,
                            target_piece, unsignedp, next_methods);

The only place where target_piece is assigned is in the (i > 0) case:

          if (i > 0)
            {
              . . .
              emit_move_insn (target_piece, newx);
            }

So it seems to me that in the (i == 0) case we need to see if
target_piece happened to receive the result, and if not, assign it.

It seems to me that this kind of bug should have been noticed already,
so... am I missing something?


2005-03-21  DJ Delorie  <[EMAIL PROTECTED]>

        * optabs.c (expand_binop): Make sure the first subword's result
        gets stored.

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.265
diff -p -U3 -r1.265 optabs.c
--- optabs.c    16 Mar 2005 18:29:23 -0000      1.265
+++ optabs.c    22 Mar 2005 01:25:35 -0000
@@ -1534,6 +1534,11 @@ expand_binop (enum machine_mode mode, op
                }
              emit_move_insn (target_piece, newx);
            }
+         else
+           {
+             if (x != target_piece)
+               emit_move_insn (target_piece, x);
+           }
 
          carry_in = carry_out;
        }

Reply via email to