aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPeter Bergner <bergner@vnet.ibm.com>2012-04-11 06:51:50 -0500
committerPeter Bergner <bergner@gcc.gnu.org>2012-04-11 06:51:50 -0500
commit7bc14a04f26551b74ab89b56ae9cb37a3216baca (patch)
tree6e7eefc3eddd1af4ac56297fa67f1bdc9071dae9 /gcc
parent8c2a3f3b6cc7bc38af483ac4923258d376f90954 (diff)
downloadgcc-7bc14a04f26551b74ab89b56ae9cb37a3216baca.zip
gcc-7bc14a04f26551b74ab89b56ae9cb37a3216baca.tar.gz
gcc-7bc14a04f26551b74ab89b56ae9cb37a3216baca.tar.bz2
re PR target/16458 (PowerPC - redundant compare)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/rs6000/rs6000.c11
-rw-r--r--gcc/expr.c9
-rw-r--r--gcc/rtl.h3
-rw-r--r--gcc/rtlanal.c21
-rw-r--r--gcc/stmt.c6
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr16458-1.c18
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr16458-2.c18
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr16458-3.c41
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr16458-4.c44
11 files changed, 180 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f456157..79193e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index fa882de..d053931 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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;
diff --git a/gcc/expr.c b/gcc/expr.c
index 548a407..14709bf 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 915ef13..4d5d6d8 100644
--- 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);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 7c4a49b..858264b 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -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.
@@ -636,6 +636,25 @@ count_occurrences (const_rtx x, const_rtx find, int count_dest)
}
+/* 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;
+}
+
+
/* Nonzero if register REG appears somewhere within IN.
Also works if REG is not a register; in this case it checks
for a subexpression of IN that is Lisp "equal" to REG. */
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 0589bfd..7aabdc2 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5c16617..fac0cb0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..45b8c75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr16458-1.c
@@ -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
index 0000000..95e97de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr16458-2.c
@@ -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
index 0000000..740d61d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr16458-3.c
@@ -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
index 0000000..8db43e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr16458-4.c
@@ -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;
+}