re PR target/16458 (PowerPC - redundant compare)
authorPeter Bergner <bergner@vnet.ibm.com>
Wed, 11 Apr 2012 11:51:50 +0000 (06:51 -0500)
committerPeter Bergner <bergner@gcc.gnu.org>
Wed, 11 Apr 2012 11:51:50 +0000 (06:51 -0500)
gcc/
PR target/16458
* rtlanal.c (unsigned_reg_p): New function.
Update copyright notice dates.
* rtl.h (unsigned_reg_p): Prototype it.
Update copyright notice dates.
* config/rs6000/rs6000.c (rs6000_generate_compare): Use it.
Update comment.
* expr.c (expand_expr_real_1): Set register attributes.
* stmt.c (expand_case): Likewise.

gcc/testsuite/
PR target/16458
* gcc.target/powerpc/pr16458-1.c: New test.
* gcc.target/powerpc/pr16458-2.c: Likewise.
* gcc.target/powerpc/pr16458-3.c: Likewise.
* gcc.target/powerpc/pr16458-4.c: Likewise.

Co-Authored-By: Michael Matz <matz@suse.de>
From-SVN: r186312

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/expr.c
gcc/rtl.h
gcc/rtlanal.c
gcc/stmt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr16458-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr16458-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr16458-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr16458-4.c [new file with mode: 0644]

index f45615709b2adb5dd03c593a4f40b1f99a5c582d..79193e7be444176e35fed17af01a5b3ee3dbe9b8 100644 (file)
@@ -1,3 +1,16 @@
+2012-04-11  Peter Bergner  <bergner@vnet.ibm.com>
+           Michael Matz  <matz@suse.de>
+
+       PR target/16458
+       * rtlanal.c (unsigned_reg_p): New function.
+       Update copyright notice dates.
+       * rtl.h (unsigned_reg_p): Prototype it.
+       Update copyright notice dates.
+       * config/rs6000/rs6000.c (rs6000_generate_compare): Use it.
+       Update comment.
+       * expr.c (expand_expr_real_1): Set register attributes.
+       * stmt.c (expand_case): Likewise.
+
 2012-04-11  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/50751
index fa882de429bcbd01aad2c3cf0ab30da206c2702e..d053931d85b838bf0a94c8f624961a71a342f3fd 100644 (file)
@@ -15561,14 +15561,11 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
           || code == GEU || code == LEU)
     comp_mode = CCUNSmode;
   else if ((code == EQ || code == NE)
-          && GET_CODE (op0) == SUBREG
-          && GET_CODE (op1) == SUBREG
-          && SUBREG_PROMOTED_UNSIGNED_P (op0)
-          && SUBREG_PROMOTED_UNSIGNED_P (op1))
+          && unsigned_reg_p (op0)
+          && (unsigned_reg_p (op1)
+              || (CONST_INT_P (op1) && INTVAL (op1) != 0)))
     /* These are unsigned values, perhaps there will be a later
-       ordering compare that can be shared with this one.
-       Unfortunately we cannot detect the signedness of the operands
-       for non-subregs.  */
+       ordering compare that can be shared with this one.  */
     comp_mode = CCUNSmode;
   else
     comp_mode = CCmode;
index 548a407d55e7d20a3fdf9a0b471b8376eb4e8d8e..14709bfcd082981f599296ce1d9b7769a802a496 100644 (file)
@@ -9015,8 +9015,13 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
          && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
        g = SSA_NAME_DEF_STMT (exp);
       if (g)
-       return expand_expr_real (gimple_assign_rhs_to_tree (g), target, tmode,
-                                modifier, NULL);
+       {
+         rtx r = expand_expr_real (gimple_assign_rhs_to_tree (g), target,
+                                   tmode, modifier, NULL);
+         if (REG_P (r) && !REG_EXPR (r))
+           set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (exp), r);
+         return r;
+       }
 
       ssa_name = exp;
       decl_rtl = get_rtx_for_ssa_name (ssa_name);
index 915ef136538f3552eb98658f1729a154ed7e95da..4d5d6d88990a41c03a9575bcbed5d4189307a372 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1,6 +1,6 @@
 /* Register Transfer Language (RTL) definitions for GCC
    Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1909,6 +1909,7 @@ extern HOST_WIDE_INT get_integer_term (const_rtx);
 extern rtx get_related_value (const_rtx);
 extern bool offset_within_block_p (const_rtx, HOST_WIDE_INT);
 extern void split_const (rtx, rtx *, rtx *);
+extern bool unsigned_reg_p (rtx);
 extern int reg_mentioned_p (const_rtx, const_rtx);
 extern int count_occurrences (const_rtx, const_rtx, int);
 extern int reg_referenced_p (const_rtx, const_rtx);
index 7c4a49bef09e3148717b600ed6585914a8194934..858264b7a03d70347a130babc590d50eb2227c53 100644 (file)
@@ -1,7 +1,7 @@
 /* Analyze RTL for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   2011, 2012 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -635,6 +635,25 @@ count_occurrences (const_rtx x, const_rtx find, int count_dest)
   return count;
 }
 
+\f
+/* Return TRUE if OP is a register or subreg of a register that
+   holds an unsigned quantity.  Otherwise, return FALSE.  */
+
+bool
+unsigned_reg_p (rtx op)
+{
+  if (REG_P (op)
+      && REG_EXPR (op)
+      && TYPE_UNSIGNED (TREE_TYPE (REG_EXPR (op))))
+    return true;
+
+  if (GET_CODE (op) == SUBREG
+      && SUBREG_PROMOTED_UNSIGNED_P (op))
+    return true;
+
+  return false;
+}
+
 \f
 /* Nonzero if register REG appears somewhere within IN.
    Also works if REG is not a register; in this case it checks
index 0589bfd1bb88529228c446cb6593cf630a5eccb2..7aabdc2caa63cccd348470ff8b1c4bd7b9a2273b 100644 (file)
@@ -2285,7 +2285,11 @@ expand_case (gimple stmt)
          do_pending_stack_adjust ();
 
          if (MEM_P (index))
-           index = copy_to_reg (index);
+           {
+             index = copy_to_reg (index);
+             if (TREE_CODE (index_expr) == SSA_NAME)
+               set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (index_expr), index);
+           }
 
          /* We generate a binary decision tree to select the
             appropriate target code.  This is done as follows:
index 5c16617adfb1cac7be8837030b0e36f419cafc82..fac0cb0c8bd4594f174cff243f641b7ab66d8dab 100644 (file)
@@ -1,3 +1,11 @@
+2012-04-11  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR target/16458
+       * gcc.target/powerpc/pr16458-1.c: New test.
+       * gcc.target/powerpc/pr16458-2.c: Likewise.
+       * gcc.target/powerpc/pr16458-3.c: Likewise.
+       * gcc.target/powerpc/pr16458-4.c: Likewise.
+
 2012-04-11  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc.dg/builtin-bswap-1.c: Test __builtin_bswap16 & __builtin_bswap64.
diff --git a/gcc/testsuite/gcc.target/powerpc/pr16458-1.c b/gcc/testsuite/gcc.target/powerpc/pr16458-1.c
new file mode 100644 (file)
index 0000000..45b8c75
--- /dev/null
@@ -0,0 +1,18 @@
+/* Test cse'ing of unsigned compares.  */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* { dg-final { scan-assembler-not "cmpw" } } */
+/* { dg-final { scan-assembler-times "cmplw" 1 } } */
+
+unsigned int a, b;
+
+int
+foo (void)
+{
+  if (a == b) return 1;
+  if (a > b)  return 2;
+  if (a < b)  return 3;
+  if (a != b) return 4;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr16458-2.c b/gcc/testsuite/gcc.target/powerpc/pr16458-2.c
new file mode 100644 (file)
index 0000000..95e97de
--- /dev/null
@@ -0,0 +1,18 @@
+/* Test cse'ing of unsigned compares.  */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* { dg-final { scan-assembler-not "cmpw" } } */
+/* { dg-final { scan-assembler-times "cmplw" 1 } } */
+
+unsigned int *a, *b;
+
+int
+foo (void)
+{
+  if (*a == *b) return 1;
+  if (*a > *b)  return 2;
+  if (*a < *b)  return 3;
+  if (*a != *b) return 4;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr16458-3.c b/gcc/testsuite/gcc.target/powerpc/pr16458-3.c
new file mode 100644 (file)
index 0000000..740d61d
--- /dev/null
@@ -0,0 +1,41 @@
+/* Test cse'ing of unsigned compares.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-jump-tables" } */
+
+/* { dg-final { scan-assembler-not "cmpwi" } } */
+/* { dg-final { scan-assembler-times "cmplwi" 5 } } */
+
+extern int case0 (void);
+extern int case1 (void);
+extern int case2 (void);
+extern int case3 (void);
+extern int case4 (void);
+
+enum CASE_VALUES
+{
+  CASE0 = 1,
+  CASE1,
+  CASE2,
+  CASE3,
+  CASE4
+};
+
+int
+foo (enum CASE_VALUES index)
+{
+  switch (index)
+    {
+    case CASE0:
+      return case0 ();
+    case CASE1:
+      return case1 ();
+    case CASE2:
+      return case2 ();
+    case CASE3:
+      return case3 ();
+    case CASE4:
+      return case4 ();
+    }
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr16458-4.c b/gcc/testsuite/gcc.target/powerpc/pr16458-4.c
new file mode 100644 (file)
index 0000000..8db43e8
--- /dev/null
@@ -0,0 +1,44 @@
+/* Test cse'ing of unsigned compares.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-jump-tables" } */
+
+/* The following tests fail due to an issue in expand not
+   attaching an type expression information on *index's reg rtx.  */
+
+/* { dg-final { scan-assembler-not "cmpwi" } } */
+/* { dg-final { scan-assembler-times "cmplwi" 5 } } */
+
+extern int case0 (void);
+extern int case1 (void);
+extern int case2 (void);
+extern int case3 (void);
+extern int case4 (void);
+
+enum CASE_VALUES
+{
+  CASE0 = 1,
+  CASE1,
+  CASE2,
+  CASE3,
+  CASE4
+};
+
+int
+foo (enum CASE_VALUES *index)
+{
+  switch (*index)
+    {
+    case CASE0:
+      return case0 ();
+    case CASE1:
+      return case1 ();
+    case CASE2:
+      return case2 ();
+    case CASE3:
+      return case3 ();
+    case CASE4:
+      return case4 ();
+    }
+
+  return 0;
+}