Commit 378393da by Roger Sayle Committed by Roger Sayle

tree.c (real_minus_onep): New function to test for -1.0.

	* tree.c (real_minus_onep): New function to test for -1.0.
	* fold-const.c (fold) [MULT_EXPR]:  Optimize -1.0*x into -x.

	* gcc.dg/fnegate-1.c: New test case.

From-SVN: r54149
parent 01c58f26
2002-06-01 Roger Sayle <roger@eyesopen.com>
* tree.c (real_minus_onep): New function to test for -1.0.
* fold-const.c (fold) [MULT_EXPR]: Optimize -1.0*x into -x.
2002-06-01 Roger Sayle <roger@eyesopen.com>
* fold-const.c (fold_truthop): Transform "a || b" into "(a|b) != 0"
and "!p && !q" into "(p|q) == 0" under suitable conditions.
......
......@@ -5370,6 +5370,14 @@ fold (expr)
so we can do this anyway. */
if (real_onep (arg1))
return non_lvalue (convert (type, arg0));
/* Transform x * -1.0 into -x. This should be safe for NaNs,
signed zeros and signed infinities, but is currently
restricted to "unsafe math optimizations" just in case. */
if (flag_unsafe_math_optimizations
&& real_minus_onep (arg1))
return fold (build1 (NEGATE_EXPR, type, arg0));
/* x*2 is x+x */
if (! wins && real_twop (arg1)
&& (*lang_hooks.decls.global_bindings_p) () == 0
......
2002-06-01 Roger Sayle <roger@eyesopen.com>
* gcc.dg/fnegate-1.c: New test case.
2002-05-30 Osku Salerma <osku@iki.fi>
* gcc.c-torture/execute/mayalias-1.c: New file.
......
/* Copyright (C) 2002 Free Software Foundation.
Test floating point negation produces the expected results.
Written by Roger Sayle, 21st May 2002. */
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math" } */
extern void abort ();
double
dneg (double x)
{
return -x;
}
double
dmult (double x)
{
return -1.0 * x;
}
double
ddiv (double x)
{
return x / -1.0;
}
float
fneg (float x)
{
return -x;
}
float
fmult (float x)
{
return -1.0f * x;
}
float
fdiv (float x)
{
return x / -1.0f;
}
void
ftest(float src, float dst)
{
if (fneg (src) != dst)
abort ();
if (src != fneg (dst))
abort ();
if (fmult (src) != dst)
abort ();
if (src != fmult (dst))
abort ();
if (fdiv (src) != dst)
abort ();
if (src != fdiv(dst))
abort ();
}
void
dtest(double src, double dst)
{
if (dneg (src) != dst)
abort ();
if (src != dneg (dst))
abort ();
if (dmult (src) != dst)
abort ();
if (src != dmult (dst))
abort ();
if (ddiv (src) != dst)
abort ();
if (src != ddiv(dst))
abort ();
}
int
main ()
{
ftest (1.0f, -1.0f);
ftest (2.0f, -2.0f);
ftest (-3.0f, 3.0f);
ftest (0.0f, -0.0f);
ftest (-0.0f, 0.0f);
dtest (1.0, -1.0);
dtest (2.0, -2.0);
dtest (-3.0, 3.0);
dtest (0.0, -0.0);
dtest (-0.0, 0.0);
return 0;
}
......@@ -892,6 +892,22 @@ real_twop (expr)
&& real_zerop (TREE_IMAGPART (expr))));
}
/* Return 1 if EXPR is the real constant minus one. */
int
real_minus_onep (expr)
tree expr;
{
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (expr)
&& REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_minus_onep (TREE_REALPART (expr))
&& real_zerop (TREE_IMAGPART (expr))));
}
/* Nonzero if EXP is a constant or a cast of a constant. */
int
......
......@@ -2850,6 +2850,7 @@ extern void expand_pending_sizes PARAMS ((tree));
extern int real_onep PARAMS ((tree));
extern int real_twop PARAMS ((tree));
extern int real_minus_onep PARAMS ((tree));
extern void gcc_obstack_init PARAMS ((struct obstack *));
extern void init_obstacks PARAMS ((void));
extern void build_common_tree_nodes PARAMS ((int));
......
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