delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-announce/1994/09/16/04:17:00

Date: Thu, 15 Sep 1994 18:57:02 +0800
From: pierre AT phi DOT la DOT tce DOT com (Pierre Willard)
To: bug-gcc AT prep DOT ai DOT mit DOT edu, djgpp-announce AT sun DOT soe DOT clarkson DOT edu
Subject: bug division in gcc-2.6.0 expmed.c
Reply-To: pierre AT la DOT tce DOT com

gcc-2.6.0 generates bad code for some division operations.

Around line 2865 of expmed.c, there is the following code :


			rtx t1, t2, t3;
			t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
					   build_int_2 (size - 1, 0),
					   NULL_RTX, 0);
			t2 = expand_shift (RSHIFT_EXPR, compute_mode, t1,
					   build_int_2 (size - lgup, 0),
					   NULL_RTX, 1);
			t3 = force_operand (gen_rtx (PLUS, compute_mode,
						     op0, t2),

This is intended to do a signed division by a power of 2.

The bug is that in the first expand_shift, the shift count has to be
(lgup -1) and not (size - 1). I checked in gcc-2.5.8, the code was 
correct.

So the above code should be :

			rtx t1, t2, t3;
			t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
					   build_int_2 (lgup - 1, 0),
					   NULL_RTX, 0);
			t2 = expand_shift (RSHIFT_EXPR, compute_mode, t1,
					   build_int_2 (size - lgup, 0),
					   NULL_RTX, 1);
			t3 = force_operand (gen_rtx (PLUS, compute_mode,
						     op0, t2),

In gcc-2.5.8, there is this useful comment (lost in gcc-2.6.0) :

/* Here we need to add OP1-1 if OP0 is negative, 0 otherwise.
	     This can be computed without jumps by arithmetically shifting
	     OP0 right LOG-1 places and then shifting right logically
	     SIZE-LOG bits.  The resulting value is unconditionally added
	     to OP0.

Let me know your comments.
Thanks
Pierre Willard

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019