re PR rtl-optimization/60969 (ICE in output_129 in MMXMOV of mode MODE_SF for march=pentium4)

2014-05-16  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/60969
	* ira-costs.c (record_reg_classes): Allow only memory for pseudo.
	Calculate costs for this case.

2014-05-16  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/60969
	* g++.dg/pr60969.C: New.

From-SVN: r210520
This commit is contained in:
Vladimir Makarov 2014-05-16 17:37:17 +00:00 committed by Vladimir Makarov
parent 8b628e86ec
commit f4e075e7d9
4 changed files with 121 additions and 26 deletions

View File

@ -1,3 +1,9 @@
2014-05-16 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/60969
* ira-costs.c (record_reg_classes): Allow only memory for pseudo.
Calculate costs for this case.
2014-05-16 Eric Botcazou <ebotcazou@adacore.com>
* fold-const (fold_unary_loc) <NON_LVALUE_EXPR>: New case.

View File

@ -762,10 +762,11 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
into that class. */
if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
{
if (classes[i] == NO_REGS)
if (classes[i] == NO_REGS && ! allows_mem[i])
{
/* We must always fail if the operand is a REG, but
we did not find a suitable class.
we did not find a suitable class and memory is
not allowed.
Otherwise we may perform an uninitialized read
from this_op_costs after the `continue' statement
@ -783,50 +784,90 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
bool out_p = recog_data.operand_type[i] != OP_IN;
enum reg_class op_class = classes[i];
move_table *move_in_cost, *move_out_cost;
short (*mem_cost)[2];
ira_init_register_move_cost_if_necessary (mode);
if (! in_p)
{
ira_assert (out_p);
move_out_cost = ira_may_move_out_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
if (op_class == NO_REGS)
{
rclass = cost_classes[k];
pp_costs[k]
= move_out_cost[op_class][rclass] * frequency;
mem_cost = ira_memory_move_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
pp_costs[k] = mem_cost[rclass][0] * frequency;
}
}
else
{
move_out_cost = ira_may_move_out_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
pp_costs[k]
= move_out_cost[op_class][rclass] * frequency;
}
}
}
else if (! out_p)
{
ira_assert (in_p);
move_in_cost = ira_may_move_in_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
if (op_class == NO_REGS)
{
rclass = cost_classes[k];
pp_costs[k]
= move_in_cost[rclass][op_class] * frequency;
mem_cost = ira_memory_move_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
pp_costs[k] = mem_cost[rclass][1] * frequency;
}
}
else
{
move_in_cost = ira_may_move_in_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
pp_costs[k]
= move_in_cost[rclass][op_class] * frequency;
}
}
}
else
{
move_in_cost = ira_may_move_in_cost[mode];
move_out_cost = ira_may_move_out_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
if (op_class == NO_REGS)
{
rclass = cost_classes[k];
pp_costs[k] = ((move_in_cost[rclass][op_class]
+ move_out_cost[op_class][rclass])
* frequency);
mem_cost = ira_memory_move_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
pp_costs[k] = ((mem_cost[rclass][0]
+ mem_cost[rclass][1])
* frequency);
}
}
else
{
move_in_cost = ira_may_move_in_cost[mode];
move_out_cost = ira_may_move_out_cost[mode];
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
pp_costs[k] = ((move_in_cost[rclass][op_class]
+ move_out_cost[op_class][rclass])
* frequency);
}
}
}
/* If the alternative actually allows memory, make
things a bit cheaper since we won't need an extra
insn to load it. */
pp->mem_cost
= ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0)
+ (in_p ? ira_memory_move_cost[mode][op_class][1] : 0)
- allows_mem[i]) * frequency;
if (op_class != NO_REGS)
pp->mem_cost
= ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0)
+ (in_p ? ira_memory_move_cost[mode][op_class][1] : 0)
- allows_mem[i]) * frequency;
/* If we have assigned a class to this allocno in
our first pass, add a cost to this alternative
corresponding to what we would add if this
@ -836,15 +877,28 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
enum reg_class pref_class = pref[COST_INDEX (REGNO (op))];
if (pref_class == NO_REGS)
{
if (op_class != NO_REGS)
alt_cost
+= ((out_p
? ira_memory_move_cost[mode][op_class][0]
: 0)
+ (in_p
? ira_memory_move_cost[mode][op_class][1]
: 0));
}
else if (op_class == NO_REGS)
alt_cost
+= ((out_p
? ira_memory_move_cost[mode][op_class][0] : 0)
? ira_memory_move_cost[mode][pref_class][1]
: 0)
+ (in_p
? ira_memory_move_cost[mode][op_class][1]
? ira_memory_move_cost[mode][pref_class][0]
: 0));
else if (ira_reg_class_intersect[pref_class][op_class]
== NO_REGS)
alt_cost += ira_register_move_cost[mode][pref_class][op_class];
alt_cost += (ira_register_move_cost
[mode][pref_class][op_class]);
}
}
}

View File

@ -1,3 +1,8 @@
2014-05-16 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/60969
* g++.dg/pr60969.C: New.
2014-05-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/61194

View File

@ -0,0 +1,30 @@
/* { dg-do compile { target i?86-*-* } } */
/* { dg-options "-O2 -ftree-vectorize -march=pentium4" } */
struct A
{
float f, g, h, k;
A () {}
A (float v0, float x, float y) : f(v0), g(x), h(y), k(0.0f) {}
A bar (A &a, float t) { return A (f + a.f * t, g + a.g * t, h + a.h * t); }
};
A
baz (A &x, A &y, float t)
{
return x.bar (y, t);
}
A *
foo (A &s, A &t, A &u, A &v, int y, int z)
{
A *x = new A[y * z];
for (int i = 0; i < 7; i++)
{
A s = baz (s, u, i / (float) z);
A t = baz (t, v, i / (float) z);
for (int j = 0; j < 7; j++)
x[i * y + j] = baz (s, t, j / (float) y);
}
return x;
}