This is the mail archive of the gcc-patches@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]

Re: [PATCH] Fix *two* AVR backend bugs (PR19293 + PR19329)




Mark Mitchell wrote:
Bernardo Innocenti wrote:

Marek Michalkiewicz wrote:


For 3.4 branch, we'd need Mark's explicit approval.  It's marked
as a regression in bugzilla, even though I can't prove that older
versions of GCC generated correct code.


You don't need my approval if it really is a regression. If it's not, let's leave it aside.

It now turned out that there are two subtly similar PRs that affect AVR shift insns.

Not sure if they can be called regressions, as no one could test with an
older version of GCC.  Both are quite critical: PR19293 is an ICE, PR19329
is wrong-code, both with valid trivial input.

PR19293 and PR19329 can both be closed by applying the following
combined patch (Marek, please review it again).


gcc/ 2005-01-23 Björn Haase <bjoern.m.haase@web.de> Bernardo Innocenti <bernie@develer.com> Giovanni Bajo <rasky@develer.com> Stefano Fedrigo <aleph@develer.com>

	PR target/19293
	PR target/19329
	* config/avr/avr.c (ashlqi3_out, ashrqi3_out, lshrqi3_out): Handle
	shifts by 0 positions.
	(ashrhi3_out, ashrsi3_out, lshrhi3_out, lshrsi3_out): Handle out of
	range shift counts.



--- avr.c.orig	2004-12-31 14:57:13.000000000 +0100
+++ avr.c	2005-01-23 09:07:13.000000000 +0100
@@ -2870,17 +2870,21 @@ ashlqi3_out (rtx insn, rtx operands[], i

switch (INTVAL (operands[2]))
{
default:
*len = 1;
return AS1 (clr,%0);
- +
+ case 0:
+ *len = 0;
+ return "";
+
case 1:
*len = 1;
return AS1 (lsl,%0);
- +
case 2:
*len = 2;
return (AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0));


	case 3:
@@ -3315,12 +3319,16 @@ ashrqi3_out (rtx insn, rtx operands[], i

      if (!len)
	len = &k;

      switch (INTVAL (operands[2]))
	{
+	case 0:
+	  *len = 0;
+	  return "";
+
	case 1:
	  *len = 1;
	  return AS1 (asr,%0);

case 2:
*len = 2;
@@ -3379,16 +3387,23 @@ ashrhi3_out (rtx insn, rtx operands[], i
if (GET_CODE (operands[2]) == CONST_INT)
{
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k;
int *t = len;
- +
if (!len)
len = &k;


+ /* Test for out of range shift count. */
+ if ((INTVAL (operands[2]) <= 0) || (INTVAL (operands[2]) >= 16))
+ {
+ *len = 0;
+ return "";
+ }
+
switch (INTVAL (operands[2]))
{
case 4:
case 5:
/* XXX try to optimize this too? */
break;
@@ -3539,16 +3554,23 @@ const char *
ashrsi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
int *t = len;
- +
if (!len)
len = &k;
- +
+ /* Test for out of range shift count. */
+ if ((INTVAL (operands[2]) <= 0) || (INTVAL (operands[2]) >= 32))
+ {
+ *len = 0;
+ return "";
+ }
+
switch (INTVAL (operands[2]))
{
case 8:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
@@ -3657,19 +3679,23 @@ lshrqi3_out (rtx insn, rtx operands[], i
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;


if (!len)
len = &k;
- +
switch (INTVAL (operands[2]))
{
default:
*len = 1;
return AS1 (clr,%0);


+	case 0:
+	  *len = 0;
+	  return "";
+
	case 1:
	  *len = 1;
	  return AS1 (lsr,%0);

	case 2:
	  *len = 2;
@@ -3752,13 +3778,20 @@ lshrhi3_out (rtx insn, rtx operands[], i
      int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
      int k;
      int *t = len;

if (!len)
len = &k;
- +
+ /* Test for out of range shift count. */
+ if ((INTVAL (operands[2]) <= 0) || (INTVAL (operands[2]) >= 16))
+ {
+ *len = 0;
+ return "";
+ }
+
switch (INTVAL (operands[2]))
{
case 4:
if (optimize_size && scratch)
break; /* 5 */
if (ldi_ok)
@@ -3999,16 +4032,23 @@ const char *
lshrsi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
int *t = len;
- +
if (!len)
len = &k;
- +
+ /* Test for out of range shift count. */
+ if ((INTVAL (operands[2]) <= 0) || (INTVAL (operands[2]) >= 32))
+ {
+ *len = 0;
+ return "";
+ }
+
switch (INTVAL (operands[2]))
{
case 8:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);


--
 // Bernardo Innocenti - Develer S.r.l., R&D dept.
\X/  http://www.develer.com/


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