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]

Call for testers: fix PR 16194


I'm testing this currently on i686-pc-linux-gnu native and X sh-elf and X sh64-elf. I think this needs testing for cris in particular, but for the new testcase it would be useful to
have all the tested architectures coverd, and at least one which isn't tested for.
2006-01-31  J"orn Rennecke <joern.rennecke@st.com>

gcc:
	* tree.h (decl_overlaps_hard_reg_set_p) Don't declare.
	(tree_overlaps_hard_reg_set): Declare.
	* stmt.c (decl_overlaps_hard_reg_set_p): Now static.  Change return
	type and signature to match function type expected by walk_tree.
	(tree_overlaps_hard_reg_set): New function.
	(decl_conflicts_with_clobbers_p): Rename to:
	(tree_conflicts_with_clobbers_p).  Take HARD_REG_SET * argument.
	Use tree_overlaps_hard_reg_set.  Changed caller.
	* doc/tm.texi (TARGET_MD_ASM_CLOBBERS): Replace
	decl_overlaps_hard_reg_set_p with tree_overlaps_hard_reg_set.
	* cris.c (cris_md_asm_clobbers): Likewise.

gcc/testsuite:
	* gcc.dg/pr16194.c: New test.

Index: doc/tm.texi
===================================================================
/usr/bin/diff -p -d -F^( -u -L doc/tm.texi	(revision 110439) -L doc/tm.texi	(working copy) doc/.svn/text-base/tm.texi.svn-base doc/tm.texi
--- doc/tm.texi	(revision 110439)
+++ doc/tm.texi	(working copy)
@@ -9337,7 +9337,7 @@ It should return the result of the last 
 clobber.  The @var{outputs}, @var{inputs} and @var{clobber} lists are the
 corresponding parameters to the asm and may be inspected to avoid
 clobbering a register that is an input or output of the asm.  You can use
-@code{decl_overlaps_hard_reg_set_p}, declared in @file{tree.h}, to test
+@code{tree_overlaps_hard_reg_set}, declared in @file{tree.h}, to test
 for overlap with regards to asm-declared registers.
 @end deftypefn
 
Index: tree.h
===================================================================
/usr/bin/diff -p -d -F^( -u -L tree.h	(revision 110439) -L tree.h	(working copy) .svn/text-base/tree.h.svn-base tree.h
--- tree.h	(revision 110439)
+++ tree.h	(working copy)
@@ -4384,7 +4384,7 @@ extern void expand_decl (tree);
 extern void expand_anon_union_decl (tree, tree, tree);
 #ifdef HARD_CONST
 /* Silly ifdef to avoid having all includers depend on hard-reg-set.h.  */
-extern bool decl_overlaps_hard_reg_set_p (tree, const HARD_REG_SET);
+extern tree tree_overlaps_hard_reg_set (tree, HARD_REG_SET *);
 #endif
 
 /* In gimplify.c.  */
Index: testsuite/gcc.dg/pr16194.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L testsuite/gcc.dg/pr16194.c	(revision 0) -L testsuite/gcc.dg/pr16194.c	(revision 0) testsuite/gcc.dg/.svn/empty-file testsuite/gcc.dg/pr16194.c
--- testsuite/gcc.dg/pr16194.c	(revision 0)
+++ testsuite/gcc.dg/pr16194.c	(revision 0)
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+#define ASMDECL __asm (REG);
+#if defined (__alpha__)
+# define REG "$1"
+#elif defined (__CRIS__) || defined (__sh__)
+# define REG "r10"
+#elif defined (__i386__)
+# define REG "%eax"
+#elif defined (__MMIX__)
+# define REG "$8"
+#elif defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) \
+        || defined (__POWERPC__) || defined (PPC) || defined (_IBMR2)
+# define REG "6"
+#elif defined (__x86_64__)
+# define REG "rax"
+#else
+  /* Make this test harmless for any target not recognized above.  */
+# undef ASMDECL
+# define ASMDECL
+# define REG "conflict"
+#endif
+
+struct A
+{
+  int a;
+};
+
+struct B
+{
+  struct A b[3];
+};
+
+struct C
+{
+  struct B c;
+};
+
+void bug (void)
+{
+  register char* dst ASMDECL;
+  __asm__ ("":"=g"(*dst): : REG); /* { dg-error "conflict" } */
+}
+
+/* The tree optimizers currently prevent us from finding an overlap -
+   we end up using a copy of dst rather than dst.
+   But at least make sure we don't get an ICE.  */
+void bug2 (void)
+{
+  register char* dst ASMDECL;
+  __asm__ ("": :"g"(*dst) : REG);
+}
+
+void
+foo (void)
+{
+  register struct C *dst ASMDECL;
+  __asm__ ("" : "=g"(dst->c.b[1].a) : : REG);
+}
Index: config/cris/cris.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L config/cris/cris.c	(revision 110439) -L config/cris/cris.c	(working copy) config/cris/.svn/text-base/cris.c.svn-base config/cris/cris.c
--- config/cris/cris.c	(revision 110439)
+++ config/cris/cris.c	(working copy)
@@ -3462,7 +3462,7 @@ cris_md_asm_clobbers (tree outputs, tree
 	 impossible constraints.  */
       if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))),
 		  'h') != NULL
-	  || decl_overlaps_hard_reg_set_p (val, mof_set))
+	  || tree_overlaps_hard_reg_set (val, &mof_set) != NULL_TREE)
 	return clobbers;
     }
 
@@ -3472,7 +3472,7 @@ cris_md_asm_clobbers (tree outputs, tree
 
       if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))),
 		  'h') != NULL
-	  || decl_overlaps_hard_reg_set_p (val, mof_set))
+	  || tree_overlaps_hard_reg_set (val, &mof_set) != NULL_TREE)
 	return clobbers;
     }
 
Index: stmt.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L stmt.c	(revision 110439) -L stmt.c	(working copy) .svn/text-base/stmt.c.svn-base stmt.c
--- stmt.c	(revision 110439)
+++ stmt.c	(working copy)
@@ -105,7 +105,7 @@ static int cost_table_initialized;
 #define COST_TABLE(I)  cost_table_[(unsigned HOST_WIDE_INT) ((I) + 1)]
 
 static int n_occurrences (int, const char *);
-static bool decl_conflicts_with_clobbers_p (tree, const HARD_REG_SET);
+static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *);
 static void expand_nl_goto_receiver (void);
 static bool check_operand_nalternatives (tree, tree);
 static bool check_unique_operand_names (tree, tree);
@@ -558,12 +558,16 @@ parse_input_constraint (const char **con
   return true;
 }
 
-/* Return true iff there's an overlap between REGS and DECL, where DECL
-   can be an asm-declared register.  */
+/* Return DECL iff there's an overlap between *REGS and DECL, where DECL
+   can be an asm-declared register.  Called via walk_tree.  */
 
-bool
-decl_overlaps_hard_reg_set_p (tree decl, const HARD_REG_SET regs)
+static tree
+decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
+			      void *data)
 {
+  tree decl = *declp;
+  const HARD_REG_SET *regs = data;
+
   if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
       && DECL_REGISTER (decl)
       && REG_P (DECL_RTL (decl))
@@ -576,31 +580,40 @@ decl_overlaps_hard_reg_set_p (tree decl,
 	   regno < (REGNO (reg)
 		    + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]);
 	   regno++)
-	if (TEST_HARD_REG_BIT (regs, regno))
-	  return true;
+	if (TEST_HARD_REG_BIT (*regs, regno))
+	  return decl;
     }
 
-  return false;
+  return NULL_TREE;
 }
 
+/* If there is an overlap between *REGS and DECL, return the first overlap
+   found.  */
+tree
+tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
+{
+  return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
+}
 
 /* Check for overlap between registers marked in CLOBBERED_REGS and
-   anything inappropriate in DECL.  Emit error and return TRUE for error,
-   FALSE for ok.  */
+   anything inappropriate in T.  Emit error and return the register
+   variable definition for error, NULL_TREE for ok.  */
 
 static bool
-decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
+tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
 {
   /* Conflicts between asm-declared register variables and the clobber
      list are not allowed.  */
-  if (decl_overlaps_hard_reg_set_p (decl, clobbered_regs))
+  tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs);
+
+  if (overlap)
     {
       error ("asm-specifier for variable %qs conflicts with asm clobber list",
-	     IDENTIFIER_POINTER (DECL_NAME (decl)));
+	     IDENTIFIER_POINTER (DECL_NAME (overlap)));
 
       /* Reset registerness to stop multiple errors emitted for a single
 	 variable.  */
-      DECL_REGISTER (decl) = 0;
+      DECL_REGISTER (overlap) = 0;
       return true;
     }
 
@@ -827,7 +840,7 @@ expand_asm_operands (tree string, tree o
 	  inout_opnum[ninout++] = i;
 	}
 
-      if (decl_conflicts_with_clobbers_p (val, clobbered_regs))
+      if (tree_conflicts_with_clobbers_p (val, &clobbered_regs))
 	clobber_conflict_found = 1;
     }
 
@@ -923,7 +936,7 @@ expand_asm_operands (tree string, tree o
 	= gen_rtx_ASM_INPUT (TYPE_MODE (type), 
 			     ggc_strdup (constraints[i + noutputs]));
 
-      if (decl_conflicts_with_clobbers_p (val, clobbered_regs))
+      if (tree_conflicts_with_clobbers_p (val, &clobbered_regs))
 	clobber_conflict_found = 1;
     }
 

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