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]

[PATCH] Loop reversal code misses a check


Hi,

the attached testcase fails on powerpc-linux-gnu if compiled with -O2. We end 
up with 2 BIVs reg83 and reg84, where reg84 is set from reg83. reg83 is the 
loop count register and is considered for inc->dec conversion in 
check_dbra_loop. In there we end up reverting the loop, cause 
no_use_except_counting remains at 1. The BIV replacing code then ends up 
incorrectly replacing uses of reg84, causing access of the wrong array member 
in &psd[j] in the testcase.

My solution is to check for the loop reg in the init_set of all BIVs too and 
clearing no_use_except_counting accordingly, this fixes the testcase.

OK to commit patch and testcase to mainline and branch if the bootstrap (PPC 
and x86) succeeds?

Franz.

	* loop.c (check_dbra_loop): A biv has uses besides counting if it is
	used to set another biv.

extern void abort (void);

typedef signed short int16_t;
typedef unsigned short uint16_t;

int16_t logadd (int16_t *a, int16_t *b);
void ba_compute_psd (int16_t start);

int16_t masktab[6] = { 1, 2, 3, 4, 5};
int16_t psd[6] = { 50, 40, 30, 20, 10};
int16_t bndpsd[6] = { 1, 2, 3, 4, 5};

void ba_compute_psd (int16_t start)
{
  int i,j,k;
  int16_t lastbin = 4;

  j = start; 
  k = masktab[start]; 

  bndpsd[k] = psd[j]; 
  j++; 

  for (i = j; i < lastbin; i++) { 
    bndpsd[k] = logadd(&bndpsd[k], &psd[j]);
    j++; 
  } 
}

int16_t logadd (int16_t *a, int16_t *b)
{
  return *a + *b;
}

int main (void)
{
  int i;

  ba_compute_psd (0);

  if (bndpsd[1] != 140) abort ();
  return 0;
}
  
Index: gcc/loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.322
diff -u -p -r1.322 loop.c
--- gcc/loop.c	2001/01/26 22:06:41	1.322
+++ gcc/loop.c	2001/02/24 18:14:29
@@ -7259,6 +7259,7 @@ check_dbra_loop (loop, insn_count)
       if (bl->giv_count == 0 && ! loop->exit_count)
 	{
 	  rtx bivreg = regno_reg_rtx[bl->regno];
+	  struct iv_class *blt;
 
 	  /* If there are no givs for this biv, and the only exit is the
 	     fall through at the end of the loop, then
@@ -7294,6 +7295,14 @@ check_dbra_loop (loop, insn_count)
 		    no_use_except_counting = 0;
 		    break;
 		  }
+	      }
+
+	  /* A biv has uses besides counting if it is used to set another biv.  */
+	  for (blt = ivs->list; blt; blt = blt->next)
+	    if (blt->init_set && reg_mentioned_p (bivreg, SET_SRC (blt->init_set)))
+	      {
+		no_use_except_counting = 0;
+		break;
 	      }
 	}
 

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