This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

expand_binop misplacing results?


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  <dj@redhat.com>

	* 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;
 	}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]