re PR bootstrap/64050 (r218009 causes LTO/PGO bootstrap failure: ICE: in inline_small_functions, at ipa-inline.c:1709)
2014-11-25 Martin Liska <mliska@suse.cz> PR bootstrap/64050 PR ipa/64060 * sreal.c (sreal::operator+): Addition fixed. (sreal::signedless_plus): Negative numbers are handled correctly. (sreal::operator-): Subtraction is fixed. (sreal::signedless_minus): Negative numbers are handled correctly. * sreal.h (sreal::operator<): Equal negative numbers are compared correctly. (sreal::shift): New checking asserts are introduced. Operation is fixed. * gcc.dg/plugin/plugin.exp: New plugin. * gcc.dg/plugin/sreal-test-1.c: New test. * gcc.dg/plugin/sreal_plugin.c: New test. From-SVN: r218048
This commit is contained in:
parent
6b4b59fc6f
commit
8301b194d2
|
@ -1,3 +1,18 @@
|
||||||
|
2014-11-25 Martin Liska <mliska@suse.cz>
|
||||||
|
|
||||||
|
PR bootstrap/64050
|
||||||
|
PR ipa/64060
|
||||||
|
* sreal.c (sreal::operator+): Addition fixed.
|
||||||
|
(sreal::signedless_plus): Negative numbers are
|
||||||
|
handled correctly.
|
||||||
|
(sreal::operator-): Subtraction is fixed.
|
||||||
|
(sreal::signedless_minus): Negative numbers are
|
||||||
|
handled correctly.
|
||||||
|
* sreal.h (sreal::operator<): Equal negative numbers
|
||||||
|
are compared correctly.
|
||||||
|
(sreal::shift): New checking asserts are introduced.
|
||||||
|
Operation is fixed.
|
||||||
|
|
||||||
2014-11-25 Richard Biener <rguenther@suse.de>
|
2014-11-25 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/61927
|
PR tree-optimization/61927
|
||||||
|
|
12
gcc/sreal.c
12
gcc/sreal.c
|
@ -182,9 +182,9 @@ sreal::operator+ (const sreal &other) const
|
||||||
{
|
{
|
||||||
sreal tmp = -(*b_p);
|
sreal tmp = -(*b_p);
|
||||||
if (*a_p < tmp)
|
if (*a_p < tmp)
|
||||||
return signedless_minus (tmp, *a_p, false);
|
return signedless_minus (tmp, *a_p, true);
|
||||||
else
|
else
|
||||||
return signedless_minus (*a_p, tmp, true);
|
return signedless_minus (*a_p, tmp, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_checking_assert (a_p->m_negative == b_p->m_negative);
|
gcc_checking_assert (a_p->m_negative == b_p->m_negative);
|
||||||
|
@ -203,7 +203,7 @@ sreal::signedless_plus (const sreal &a, const sreal &b, bool negative)
|
||||||
const sreal *a_p = &a;
|
const sreal *a_p = &a;
|
||||||
const sreal *b_p = &b;
|
const sreal *b_p = &b;
|
||||||
|
|
||||||
if (*a_p < *b_p)
|
if (a_p->m_exp < b_p->m_exp)
|
||||||
std::swap (a_p, b_p);
|
std::swap (a_p, b_p);
|
||||||
|
|
||||||
dexp = a_p->m_exp - b_p->m_exp;
|
dexp = a_p->m_exp - b_p->m_exp;
|
||||||
|
@ -211,6 +211,7 @@ sreal::signedless_plus (const sreal &a, const sreal &b, bool negative)
|
||||||
if (dexp > SREAL_BITS)
|
if (dexp > SREAL_BITS)
|
||||||
{
|
{
|
||||||
r.m_sig = a_p->m_sig;
|
r.m_sig = a_p->m_sig;
|
||||||
|
r.m_negative = negative;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,11 +249,11 @@ sreal::operator- (const sreal &other) const
|
||||||
/* We want to substract a smaller number from bigger
|
/* We want to substract a smaller number from bigger
|
||||||
for nonegative numbers. */
|
for nonegative numbers. */
|
||||||
if (!m_negative && *this < other)
|
if (!m_negative && *this < other)
|
||||||
return -signedless_minus (other, *this, true);
|
return signedless_minus (other, *this, true);
|
||||||
|
|
||||||
/* Example: -2 - (-3) => 3 - 2 */
|
/* Example: -2 - (-3) => 3 - 2 */
|
||||||
if (m_negative && *this > other)
|
if (m_negative && *this > other)
|
||||||
return signedless_minus (-other, -(*this), true);
|
return signedless_minus (-other, -(*this), false);
|
||||||
|
|
||||||
sreal r = signedless_minus (*this, other, m_negative);
|
sreal r = signedless_minus (*this, other, m_negative);
|
||||||
|
|
||||||
|
@ -274,6 +275,7 @@ sreal::signedless_minus (const sreal &a, const sreal &b, bool negative)
|
||||||
if (dexp > SREAL_BITS)
|
if (dexp > SREAL_BITS)
|
||||||
{
|
{
|
||||||
r.m_sig = a_p->m_sig;
|
r.m_sig = a_p->m_sig;
|
||||||
|
r.m_negative = negative;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (dexp == 0)
|
if (dexp == 0)
|
||||||
|
|
18
gcc/sreal.h
18
gcc/sreal.h
|
@ -60,6 +60,11 @@ public:
|
||||||
|
|
||||||
bool operator< (const sreal &other) const
|
bool operator< (const sreal &other) const
|
||||||
{
|
{
|
||||||
|
/* We negate result in case of negative numbers and
|
||||||
|
it would return true for equal negative numbers. */
|
||||||
|
if (*this == other)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (m_negative != other.m_negative)
|
if (m_negative != other.m_negative)
|
||||||
return m_negative > other.m_negative;
|
return m_negative > other.m_negative;
|
||||||
|
|
||||||
|
@ -86,10 +91,19 @@ public:
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
sreal shift (int sig) const
|
sreal shift (int s) const
|
||||||
{
|
{
|
||||||
|
gcc_checking_assert (s <= SREAL_BITS);
|
||||||
|
gcc_checking_assert (s >= -SREAL_BITS);
|
||||||
|
|
||||||
|
/* Exponent should never be so large because shift_right is used only by
|
||||||
|
sreal_add and sreal_sub ant thus the number cannot be shifted out from
|
||||||
|
exponent range. */
|
||||||
|
gcc_checking_assert (m_exp + s <= SREAL_MAX_EXP);
|
||||||
|
gcc_checking_assert (m_exp + s >= -SREAL_MAX_EXP);
|
||||||
|
|
||||||
sreal tmp = *this;
|
sreal tmp = *this;
|
||||||
tmp.m_sig += sig;
|
tmp.m_exp += s;
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
2014-11-25 Martin Liska <mliska@suse.cz>
|
||||||
|
|
||||||
|
PR bootstrap/64050
|
||||||
|
PR ipa/64060
|
||||||
|
* gcc.dg/plugin/plugin.exp: New plugin.
|
||||||
|
* gcc.dg/plugin/sreal-test-1.c: New test.
|
||||||
|
* gcc.dg/plugin/sreal_plugin.c: New test.
|
||||||
|
|
||||||
2014-11-25 Matthew Fortune <matthew.fortune@imgtec.com>
|
2014-11-25 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||||
|
|
||||||
* gcc.target/mips/mips.exp: Add support for -msoft-float and
|
* gcc.target/mips/mips.exp: Add support for -msoft-float and
|
||||||
|
|
|
@ -59,6 +59,7 @@ set plugin_test_list [list \
|
||||||
{ selfassign.c self-assign-test-1.c self-assign-test-2.c } \
|
{ selfassign.c self-assign-test-1.c self-assign-test-2.c } \
|
||||||
{ ggcplug.c ggcplug-test-1.c } \
|
{ ggcplug.c ggcplug-test-1.c } \
|
||||||
{ one_time_plugin.c one_time-test-1.c } \
|
{ one_time_plugin.c one_time-test-1.c } \
|
||||||
|
{ sreal_plugin.c sreal-test-1.c } \
|
||||||
{ start_unit_plugin.c start_unit-test-1.c } \
|
{ start_unit_plugin.c start_unit-test-1.c } \
|
||||||
{ finish_unit_plugin.c finish_unit-test-1.c } \
|
{ finish_unit_plugin.c finish_unit-test-1.c } \
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
/* Test that pass is inserted and invoked once. */
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O" } */
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
/* Plugin that process internal tests for sreal. */
|
||||||
|
#include "config.h"
|
||||||
|
#include "gcc-plugin.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "coretypes.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include "tm.h"
|
||||||
|
#include "toplev.h"
|
||||||
|
#include "hash-table.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "ggc.h"
|
||||||
|
#include "basic-block.h"
|
||||||
|
#include "tree-ssa-alias.h"
|
||||||
|
#include "internal-fn.h"
|
||||||
|
#include "gimple-fold.h"
|
||||||
|
#include "tree-eh.h"
|
||||||
|
#include "gimple-expr.h"
|
||||||
|
#include "is-a.h"
|
||||||
|
#include "gimple.h"
|
||||||
|
#include "tree-pass.h"
|
||||||
|
#include "intl.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "sreal.h"
|
||||||
|
|
||||||
|
int plugin_is_GPL_compatible;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static void assert (bool c)
|
||||||
|
{
|
||||||
|
if (!c)
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
const pass_data pass_data_sreal_pass =
|
||||||
|
{
|
||||||
|
GIMPLE_PASS, /* type */
|
||||||
|
"sreal", /* name */
|
||||||
|
OPTGROUP_NONE, /* optinfo_flags */
|
||||||
|
TV_NONE, /* tv_id */
|
||||||
|
PROP_gimple_any, /* properties_required */
|
||||||
|
0, /* properties_provided */
|
||||||
|
0, /* properties_destroyed */
|
||||||
|
0, /* todo_flags_start */
|
||||||
|
0, /* todo_flags_finish */
|
||||||
|
};
|
||||||
|
|
||||||
|
class sreal_pass : public gimple_opt_pass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sreal_pass(gcc::context *ctxt)
|
||||||
|
: gimple_opt_pass(pass_data_sreal_pass, ctxt)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/* opt_pass methods: */
|
||||||
|
virtual bool gate (function *);
|
||||||
|
virtual unsigned int execute (function *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void check_sreal ();
|
||||||
|
|
||||||
|
static void verify_aritmetics (int a, int b);
|
||||||
|
static void verify_shifting (int a);
|
||||||
|
}; // class one_pass
|
||||||
|
|
||||||
|
} // anon namespace
|
||||||
|
|
||||||
|
void
|
||||||
|
sreal_pass::verify_aritmetics (int a, int b)
|
||||||
|
{
|
||||||
|
assert (a == -(-(sreal (a))).to_int ());
|
||||||
|
assert ((a < b) == (sreal (a) < sreal (b)));
|
||||||
|
assert ((a <= b) == (sreal (a) <= sreal (b)));
|
||||||
|
assert ((a == b) == (sreal (a) == sreal (b)));
|
||||||
|
assert ((a != b) == (sreal (a) != sreal (b)));
|
||||||
|
assert ((a > b) == (sreal (a) > sreal (b)));
|
||||||
|
assert ((a >= b) == (sreal (a) >= sreal (b)));
|
||||||
|
assert ((a + b) == (sreal (a) + sreal (b)).to_int ());
|
||||||
|
assert ((a - b) == (sreal (a) - sreal (b)).to_int ());
|
||||||
|
assert ((b + a) == (sreal (b) + sreal (a)).to_int ());
|
||||||
|
assert ((b - a) == (sreal (b) - sreal (a)).to_int ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sreal_pass::verify_shifting (int a)
|
||||||
|
{
|
||||||
|
sreal v = a;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 16; i++)
|
||||||
|
assert ((a << i) == (v << i).to_int());
|
||||||
|
|
||||||
|
a = a << 16;
|
||||||
|
v = v << 16;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 16; i++)
|
||||||
|
assert ((a >> i) == (v >> i).to_int());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sreal_pass::check_sreal ()
|
||||||
|
{
|
||||||
|
sreal minimum = INT_MIN;
|
||||||
|
sreal maximum = INT_MAX;
|
||||||
|
sreal seven = 7;
|
||||||
|
sreal minus_two = -2;
|
||||||
|
sreal minus_nine = -9;
|
||||||
|
|
||||||
|
assert (minimum.to_int () == INT_MIN);
|
||||||
|
assert (maximum.to_int () == INT_MAX);
|
||||||
|
|
||||||
|
assert (!(minus_two < minus_two));
|
||||||
|
assert (!(seven < seven));
|
||||||
|
assert (seven > minus_two);
|
||||||
|
assert (minus_two < seven);
|
||||||
|
assert (minus_two != seven);
|
||||||
|
assert (minus_two == minus_two);
|
||||||
|
assert (seven == seven);
|
||||||
|
|
||||||
|
assert (seven == ((seven << 10) >> 10));
|
||||||
|
|
||||||
|
assert ((seven + minus_two) == 5);
|
||||||
|
assert ((seven + minus_nine) == -2);
|
||||||
|
|
||||||
|
for (int a = -100; a < 100; a++)
|
||||||
|
for (int b = -100; b < 100; b++)
|
||||||
|
{
|
||||||
|
verify_aritmetics (a, b);
|
||||||
|
verify_aritmetics (INT_MIN + 100, b);
|
||||||
|
verify_aritmetics (INT_MAX - 100, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
srand (123456);
|
||||||
|
|
||||||
|
for (int i = 0; i < 1000 * 1000; i++)
|
||||||
|
{
|
||||||
|
verify_aritmetics (rand () % 10, rand () % 1000000);
|
||||||
|
verify_aritmetics (rand () % 100, rand () % 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int a = -100; a < 100; a++)
|
||||||
|
verify_shifting (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sreal_pass::gate (function *)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
sreal_pass::execute (function *)
|
||||||
|
{
|
||||||
|
check_sreal ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_init (struct plugin_name_args *plugin_info,
|
||||||
|
struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
struct register_pass_info p;
|
||||||
|
|
||||||
|
p.pass = new sreal_pass (g);
|
||||||
|
p.reference_pass_name = "cfg";
|
||||||
|
p.ref_pass_instance_number = 1;
|
||||||
|
p.pos_op = PASS_POS_INSERT_AFTER;
|
||||||
|
|
||||||
|
register_callback ("sreal", PLUGIN_PASS_MANAGER_SETUP, NULL, &p);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue