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]

PR debug/41248 [VTA] deal with Pmode != ptr_mode in expand_debug_expr


Hi, Steve,

Thanks for the report.  expand_debug_expr() was not prepared to deal
with addresses/pointers with different modes.

This patch fixes it.  I expect machine-dependent pointer extension
should never arise in debug stmts.  Please let me know if you think this
expectation is unwarranted.

Is this ok to install if it passes bootstrap testing?  Could you please
give it a try on ia64-hpux?  Thanks in advance,

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/41248
	* cfgexpand.c (convert_debug_memory_address): New.
	(expand_debug_expr): Convert base address and offset to the same
	mode.  Use it to convert addresses to other modes.
	
for  gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/41248
	* gcc.dg/pr41248.c: New.

Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c.orig	2009-09-03 21:06:13.000000000 -0300
+++ gcc/cfgexpand.c	2009-09-03 22:11:28.000000000 -0300
@@ -2238,6 +2238,38 @@ unwrap_constant (rtx x)
   return ret;
 }
 
+/* Convert X to MODE, that must be Pmode or ptr_mode, without emitting
+   any rtl.  */
+
+static rtx
+convert_debug_memory_address (enum machine_mode mode, rtx x)
+{
+  enum machine_mode xmode = GET_MODE (x);
+
+#ifndef POINTERS_EXTEND_UNSIGNED
+  gcc_assert (mode == Pmode);
+  gcc_assert (xmode == mode || xmode == VOIDmode);
+#else
+  gcc_assert (mode == Pmode || mode == ptr_mode);
+
+  if (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode)
+    return x;
+
+  if (GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (xmode))
+    x = simplify_gen_subreg (mode, x, xmode,
+			     subreg_lowpart_offset
+			     (mode, xmode));
+  else if (POINTERS_EXTEND_UNSIGNED > 0)
+    x = gen_rtx_ZERO_EXTEND (mode, x);
+  else if (!POINTERS_EXTEND_UNSIGNED)
+    x = gen_rtx_SIGN_EXTEND (mode, x);
+  else
+    gcc_unreachable ();
+#endif /* POINTERS_EXTEND_UNSIGNED */
+
+  return x;
+}
+
 /* Return an RTX equivalent to the value of the tree expression
    EXP.  */
 
@@ -2472,13 +2504,32 @@ expand_debug_expr (tree exp)
 
 	if (offset)
 	  {
+	    enum machine_mode addrmode, offmode;
+
 	    gcc_assert (MEM_P (op0));
 
+	    op0 = XEXP (op0, 0);
+	    addrmode = GET_MODE (op0);
+	    if (addrmode == VOIDmode)
+	      addrmode = Pmode;
+
 	    op1 = expand_debug_expr (offset);
 	    if (!op1)
 	      return NULL;
 
-	    op0 = gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, XEXP (op0, 0), op1));
+	    offmode = GET_MODE (op1);
+	    if (offmode == VOIDmode)
+	      offmode = TYPE_MODE (TREE_TYPE (offset));
+
+	    if (addrmode != offmode)
+	      op1 = simplify_gen_subreg (addrmode, op1, offmode,
+					 subreg_lowpart_offset (addrmode,
+								offmode));
+
+	    /* Don't use offset_address here, we don't need a
+	       recognizable address, and we don't want to generate
+	       code.  */
+	    op0 = gen_rtx_MEM (mode, gen_rtx_PLUS (addrmode, op0, op1));
 	  }
 
 	if (MEM_P (op0))
@@ -2798,7 +2849,9 @@ expand_debug_expr (tree exp)
       if (!op0 || !MEM_P (op0))
 	return NULL;
 
-      return XEXP (op0, 0);
+      op0 = convert_debug_memory_address (mode, XEXP (op0, 0));
+
+      return op0;
 
     case VECTOR_CST:
       exp = build_constructor_from_list (TREE_TYPE (exp),
Index: gcc/testsuite/gcc.dg/pr41248.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/pr41248.c	2009-09-03 22:01:06.000000000 -0300
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+struct __gcov_var {
+   unsigned int offset;
+   unsigned int buffer[(1 << 10) + 1];
+} __gcov_var;
+unsigned int * gcov_write_words (unsigned int words) {
+   unsigned int *result;
+   result = &__gcov_var.buffer[__gcov_var.offset];
+   return result;
+}

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer

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