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:
parent
8c2a3f3b6c
commit
7bc14a04f2
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue