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
This commit is contained in:
Peter Bergner 2012-04-11 06:51:50 -05:00 committed by Peter Bergner
parent 8c2a3f3b6c
commit 7bc14a04f2
11 changed files with 180 additions and 12 deletions

View 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

View 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;

View 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);

View File

@ -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);

View 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;
}
/* 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

View 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:

View 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.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}