diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-04 23:42:48 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-04 23:42:48 +0000 |
commit | cf58ef1d6fbe1a6314a68061ffb09439410751b3 (patch) | |
tree | 9617a20782252283684d9c8639c9ad8e7fbf7873 /gcc/expmed.c | |
parent | b518d98cdf1091c3dd4cefa5d959b69677197394 (diff) | |
download | gcc-cf58ef1d6fbe1a6314a68061ffb09439410751b3.tar.gz |
* fold-const.c (fold <PLUS_EXPR>): Transform x+x into x*2.0.
Optimize x*c+x and x+x*c into x*(c+1) and x*c1+x*c2 into x*(c1+c2)
for floating point expressions with -ffast-math.
(fold <MULT_EXPR>): Don't transform x*2.0 into x+x.
* expmed.c (expand_mult): Wrap long line. Expand x*2.0 as x+x.
* gcc.dg/20030804-1.c: New test case.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70158 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 68163e9ba2b..89ecd0c1982 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -2300,7 +2300,8 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, you should swap the two operands if OP0 would be constant. */ rtx -expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp) +expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, + int unsignedp) { rtx const_op1 = op1; @@ -2514,6 +2515,28 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp } } + if (GET_CODE (op0) == CONST_DOUBLE) + { + rtx temp = op0; + op0 = op1; + op1 = temp; + } + + /* Expand x*2.0 as x+x. */ + if (GET_CODE (op1) == CONST_DOUBLE + && GET_MODE_CLASS (mode) == MODE_FLOAT) + { + REAL_VALUE_TYPE d; + REAL_VALUE_FROM_CONST_DOUBLE (d, op1); + + if (REAL_VALUES_EQUAL (d, dconst2)) + { + op0 = force_reg (GET_MODE (op0), op0); + return expand_binop (mode, add_optab, op0, op0, + target, unsignedp, OPTAB_LIB_WIDEN); + } + } + /* This used to use umul_optab if unsigned, but for non-widening multiply there is no difference between signed and unsigned. */ op0 = expand_binop (mode, |