re PR rtl-optimization/47299 (Widening multiply optimization generates bad code)

PR rtl-optimization/47299
	* expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Don't use
	subtarget.  Use normal multiplication if both operands are
	constants.
	* expmed.c (expand_widening_mult): Don't try to optimize constant
	multiplication if op0 has VOIDmode.  Convert op1 constant to mode
	before using it.

	* gcc.c-torture/execute/pr47299.c: New test.

From-SVN: r168944
This commit is contained in:
Jakub Jelinek 2011-01-18 08:45:12 +01:00 committed by Jakub Jelinek
parent fb70168707
commit e7ef91dc8e
5 changed files with 46 additions and 7 deletions

View File

@ -1,3 +1,13 @@
2011-01-18 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/47299
* expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Don't use
subtarget. Use normal multiplication if both operands are
constants.
* expmed.c (expand_widening_mult): Don't try to optimize constant
multiplication if op0 has VOIDmode. Convert op1 constant to mode
before using it.
2011-01-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* doc/lto.texi (LTO): Ensure two spaces after period. Fix

View File

@ -1,7 +1,8 @@
/* Medium-level subroutines: convert bit-field store and extract
and shifts, multiplies and divides to rtl instructions.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011
Free Software Foundation, Inc.
This file is part of GCC.
@ -3188,12 +3189,17 @@ expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
int unsignedp, optab this_optab)
{
bool speed = optimize_insn_for_speed_p ();
rtx cop1;
if (CONST_INT_P (op1)
&& (INTVAL (op1) >= 0
&& GET_MODE (op0) != VOIDmode
&& (cop1 = convert_modes (mode, GET_MODE (op0), op1,
this_optab == umul_widen_optab))
&& CONST_INT_P (cop1)
&& (INTVAL (cop1) >= 0
|| GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT))
{
HOST_WIDE_INT coeff = INTVAL (op1);
HOST_WIDE_INT coeff = INTVAL (cop1);
int max_cost;
enum mult_variant variant;
struct algorithm algorithm;

View File

@ -1,6 +1,6 @@
/* Convert tree expression to rtl instructions, for GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
@ -7631,10 +7631,10 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
if (optab_handler (this_optab, mode) != CODE_FOR_nothing)
{
if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
EXPAND_NORMAL);
else
expand_operands (treeop0, treeop1, subtarget, &op1, &op0,
expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
EXPAND_NORMAL);
goto binop3;
}
@ -7652,7 +7652,8 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
if (mode == GET_MODE_2XWIDER_MODE (innermode))
if (mode == GET_MODE_2XWIDER_MODE (innermode)
&& TREE_CODE (treeop0) != INTEGER_CST)
{
if (optab_handler (this_optab, mode) != CODE_FOR_nothing)
{

View File

@ -1,3 +1,8 @@
2011-01-18 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/47299
* gcc.c-torture/execute/pr47299.c: New test.
2011-01-17 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-virtual.C: New.

View File

@ -0,0 +1,17 @@
/* PR rtl-optimization/47299 */
extern void abort (void);
__attribute__ ((noinline, noclone)) unsigned short
foo (unsigned char x)
{
return x * 255;
}
int
main ()
{
if (foo (0x40) != 0x3fc0)
abort ();
return 0;
}