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]

[PATCH] Segfault in rtx_varies_p


When complied with -O2 on arm-none-elf, the following testcase causes a 
segfault.

static const char digs[] = "0123456789ABCDEF";
int __attribute__((pure)) bar();

int foo (int i)
{
  int len;
  if (i)
    return 0;
  len = bar();
  return digs[len];
}

For the call to bar() we generate a libcall sequence. This includes a 
REG_EQUAL note containing a EXPR_LIST of the parameters of the libcall (and 
symbol for bar).

(insn (set (reg 101) (...))
	(insn_list:REG_RETVAL ...
	(expr_list:REG_EQUAL (expr_list (use (mem:blk scratch))
					(expr_list (symbol_ref "bar")
					(nil)))))
	(nil))
(insn (set (reg 102) (symbol_ref "digs)))
(insn (set (reg 103) (mem (plus (reg 101) (reg 102))))
	(expr_list:REG_EQUAL (plus (reg 101) (symbol_ref "bar")))
	(nil))


During the gcse pass we then propagate the equality for reg101 from the first 
REG_EQUAL note into the second REG_EQUAL note (the code for for digs[len]). 
In a later pass rtx_varies_p falls over on the NULL terminator of the 
EXPR_LIST.

I've reproduced this problem on 3.4 and mainline. I haven't managed to 
reproduce on 3.3 or on other architectures.

Solution A is to prevent the substitution of an EXPR_LIST from a REG_EQUAL 
note in cases where it may cause problems. Ignoring these altogether inhibits 
cse of libcalls, so is not desirable.

Solution B is to make rtx_varies_p return 0 when it encounters a NULL rtx.

I don't know enought about the operation of cse to tell which is best, or to 
easily implement A. Patch implementing B is appended.

Tested with cross-compiler to arm-non-elf and boostrap in i686-linux.
Ok for mainline, 3.4 branch and csl-arm-branch?

Paul

2004-02-17  Paul Brook  <paul@codesourcery.com>

	* rtlanal.c (rtx_varies_p): Return 0 for NULL_RTX

Index: rtlanal.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/rtlanal.c,v
retrieving revision 1.177
diff -u -p -r1.177 rtlanal.c
--- a/rtlanal.c	6 Feb 2004 04:28:46 -0000	1.177
+++ b/rtlanal.c	17 Feb 2004 00:42:12 -0000
@@ -134,10 +134,14 @@ rtx_unstable_p (rtx x)
 int
 rtx_varies_p (rtx x, int for_alias)
 {
-  RTX_CODE code = GET_CODE (x);
+  RTX_CODE code;
   int i;
   const char *fmt;
 
+  if (!x)
+    return 0;
+
+  code = GET_CODE (x);
   switch (code)
     {
     case MEM:


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