Commit e7ef91dc by Jakub Jelinek Committed by Jakub Jelinek

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
parent fb701687
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> 2011-01-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* doc/lto.texi (LTO): Ensure two spaces after period. Fix * doc/lto.texi (LTO): Ensure two spaces after period. Fix
......
/* Medium-level subroutines: convert bit-field store and extract /* Medium-level subroutines: convert bit-field store and extract
and shifts, multiplies and divides to rtl instructions. and shifts, multiplies and divides to rtl instructions.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 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. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -3188,12 +3189,17 @@ expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, ...@@ -3188,12 +3189,17 @@ expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
int unsignedp, optab this_optab) int unsignedp, optab this_optab)
{ {
bool speed = optimize_insn_for_speed_p (); bool speed = optimize_insn_for_speed_p ();
rtx cop1;
if (CONST_INT_P (op1) 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)) || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT))
{ {
HOST_WIDE_INT coeff = INTVAL (op1); HOST_WIDE_INT coeff = INTVAL (cop1);
int max_cost; int max_cost;
enum mult_variant variant; enum mult_variant variant;
struct algorithm algorithm; struct algorithm algorithm;
......
/* Convert tree expression to rtl instructions, for GNU compiler. /* Convert tree expression to rtl instructions, for GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 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. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -7631,10 +7631,10 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, ...@@ -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 (optab_handler (this_optab, mode) != CODE_FOR_nothing)
{ {
if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
expand_operands (treeop0, treeop1, subtarget, &op0, &op1, expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
EXPAND_NORMAL); EXPAND_NORMAL);
else else
expand_operands (treeop0, treeop1, subtarget, &op1, &op0, expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
EXPAND_NORMAL); EXPAND_NORMAL);
goto binop3; goto binop3;
} }
...@@ -7652,7 +7652,8 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, ...@@ -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; optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
this_optab = zextend_p ? umul_widen_optab : smul_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) if (optab_handler (this_optab, mode) != CODE_FOR_nothing)
{ {
......
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> 2011-01-17 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-virtual.C: New. * g++.dg/cpp0x/constexpr-virtual.C: New.
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment