aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-01-18 08:45:12 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-01-18 08:45:12 +0100
commite7ef91dc8eb398de7b6c780b00f1360dafd84798 (patch)
tree020c8a49163b7cf9347b1c3455970378ec548bc7 /gcc
parentfb70168707ecbe4175c069f6c36baa8986a075bd (diff)
downloadgcc-e7ef91dc8eb398de7b6c780b00f1360dafd84798.zip
gcc-e7ef91dc8eb398de7b6c780b00f1360dafd84798.tar.gz
gcc-e7ef91dc8eb398de7b6c780b00f1360dafd84798.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/expmed.c12
-rw-r--r--gcc/expr.c9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr47299.c17
5 files changed, 46 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a8f3ad7..0ed4f018 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 24aedcc..f17abb5 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -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;
diff --git a/gcc/expr.c b/gcc/expr.c
index dfcaefb..7441548 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e12ba4c..19a6ab9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr47299.c b/gcc/testsuite/gcc.c-torture/execute/pr47299.c
new file mode 100644
index 0000000..4f3d1f9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr47299.c
@@ -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;
+}