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] Check precision rather than machine mode in STRIP_NOPS and STRIP_SIGN_NOPS


This is the patch based the discussion at
http://gcc.gnu.org/ml/gcc/2009-06/msg00072.html.  I had second thoughts after
testing the patch as to whether we should still have the TYPE_MODE check *in
addition* to the TYPE_PRECISION so I verified a few things.

Based on verify_gimple_assign_unary we can only have conversion between
ENUM_TYPE, BOOLEAN_TYPE, INTEGER_TYPE, OFFSET_TYPE, POINTER_TYPE and
REFERENCE_TYPE here which I think can be removed as long as they have the same
precision.  I also verified that when using the mode-attribute extension
(__attribute__ ((mode (...)))), we always find a matching type to the mode
instead of just using the type supplied and overriding TYPE_MODE.  Thus I
concluded that TYPE_MODE carried no futher information beyond TYPE_PRECISION;
let me know if I missed something.

As for my code-quality concerns, I benchmarked it with our internal suite of
apps which use lots of bitfield operations.  Numbers were unaffected.

Bootstrapped and regtested with mips64octeon-linux and x86_64-linux.

OK to install?

Adam


	* tree.h (STRIP_NOPS, STRIP_SIGN_NOPS): Check TYPE_PRECISION
	rather than TYPE_MODE.

testsuite/
	* gcc.c-torture/execute/bitfld-5.c: New test.

Index: tree.h
===================================================================
--- tree.h	(revision 148091)
+++ tree.h	(working copy)
@@ -967,25 +967,25 @@ extern void omp_clause_range_check_faile
 /* Given an expression as a tree, strip any NON_LVALUE_EXPRs and NOP_EXPRs
    that don't change the machine mode.  */
 
-#define STRIP_NOPS(EXP)						\
-  while ((CONVERT_EXPR_P (EXP)					\
-	  || TREE_CODE (EXP) == NON_LVALUE_EXPR)		\
-	 && TREE_OPERAND (EXP, 0) != error_mark_node		\
-	 && (TYPE_MODE (TREE_TYPE (EXP))			\
-	     == TYPE_MODE (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
+#define STRIP_NOPS(EXP)						     \
+  while ((CONVERT_EXPR_P (EXP)					     \
+	  || TREE_CODE (EXP) == NON_LVALUE_EXPR)		     \
+	 && TREE_OPERAND (EXP, 0) != error_mark_node		     \
+	 && (TYPE_PRECISION (TREE_TYPE (EXP))			     \
+	     == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
     (EXP) = TREE_OPERAND (EXP, 0)
 
 /* Like STRIP_NOPS, but don't let the signedness change either.  */
 
-#define STRIP_SIGN_NOPS(EXP) \
-  while ((CONVERT_EXPR_P (EXP)					\
-	  || TREE_CODE (EXP) == NON_LVALUE_EXPR)		\
-	 && TREE_OPERAND (EXP, 0) != error_mark_node		\
-	 && (TYPE_MODE (TREE_TYPE (EXP))			\
-	     == TYPE_MODE (TREE_TYPE (TREE_OPERAND (EXP, 0))))	\
-	 && (TYPE_UNSIGNED (TREE_TYPE (EXP))			\
-	     == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0)))) \
-	 && (POINTER_TYPE_P (TREE_TYPE (EXP))			\
+#define STRIP_SIGN_NOPS(EXP)					     \
+  while ((CONVERT_EXPR_P (EXP)					     \
+	  || TREE_CODE (EXP) == NON_LVALUE_EXPR)		     \
+	 && TREE_OPERAND (EXP, 0) != error_mark_node		     \
+	 && (TYPE_PRECISION (TREE_TYPE (EXP))			     \
+	     == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (EXP, 0))))  \
+	 && (TYPE_UNSIGNED (TREE_TYPE (EXP))			     \
+	     == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0))))   \
+	 && (POINTER_TYPE_P (TREE_TYPE (EXP))			     \
 	     == POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
     (EXP) = TREE_OPERAND (EXP, 0)
 
Index: testsuite/gcc.c-torture/execute/bitfld-5.c
===================================================================
--- testsuite/gcc.c-torture/execute/bitfld-5.c	(revision 0)
+++ testsuite/gcc.c-torture/execute/bitfld-5.c	(revision 0)
@@ -0,0 +1,35 @@
+/* See http://gcc.gnu.org/ml/gcc/2009-06/msg00072.html.  */
+
+extern void abort (void);
+
+struct s
+{
+  unsigned long long a:2;
+  unsigned long long b:40;
+  unsigned long long c:22;
+};
+
+__attribute__ ((noinline)) void
+g (unsigned long long a, unsigned long long b)
+{
+  asm ("");
+  if (a != b)
+    abort ();
+}
+
+__attribute__ ((noinline)) void
+f (struct s s, unsigned long long b)
+{
+  asm ("");
+  g (((unsigned long long) (s.b-8)) + 8, b);
+}
+
+int
+main ()
+{
+  struct s s = {1, 10, 3};
+  struct s t = {1, 2, 3};
+  f (s, 10);
+  f (t, 0x10000000002);
+  return 0;
+}


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