The following patch fixes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88207
The patch was tested and bootstrapped on x86/x86-64.
Committed as rev. 266582.
The patch creates one new regression on pr34256.c. But I think gcc
with the patch generates the right code. I'll send a patch modifying
the test for discussion and/or approval later today.
Index: ChangeLog
===================================================================
--- ChangeLog (revision 266581)
+++ ChangeLog (working copy)
@@ -1,3 +1,9 @@
+2018-11-28 Vladimir Makarov <vmaka...@redhat.com>
+
+ PR target/88207
+ * ira-costs.c (scan_one_insn): Process subregs when updating costs
+ for pseudos and allocnos from insn.
+
2018-11-28 David Edelsohn <dje....@gmail.com>
* config/rs6000/aix72.h: Update to match aix71.h changes.
Index: ira-costs.c
===================================================================
--- ira-costs.c (revision 266435)
+++ ira-costs.c (working copy)
@@ -1535,36 +1535,40 @@ scan_one_insn (rtx_insn *insn)
/* Now add the cost for each operand to the total costs for its
allocno. */
for (i = 0; i < recog_data.n_operands; i++)
- if (REG_P (recog_data.operand[i])
- && REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER)
- {
- int regno = REGNO (recog_data.operand[i]);
- struct costs *p = COSTS (costs, COST_INDEX (regno));
- struct costs *q = op_costs[i];
- int *p_costs = p->cost, *q_costs = q->cost;
- cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
- int add_cost;
-
- /* If the already accounted for the memory "cost" above, don't
- do so again. */
- if (!counted_mem)
- {
- add_cost = q->mem_cost;
- if (add_cost > 0 && INT_MAX - add_cost < p->mem_cost)
- p->mem_cost = INT_MAX;
- else
- p->mem_cost += add_cost;
- }
- for (k = cost_classes_ptr->num - 1; k >= 0; k--)
- {
- add_cost = q_costs[k];
- if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
- p_costs[k] = INT_MAX;
- else
- p_costs[k] += add_cost;
- }
- }
-
+ {
+ rtx op = recog_data.operand[i];
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+ if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
+ {
+ int regno = REGNO (op);
+ struct costs *p = COSTS (costs, COST_INDEX (regno));
+ struct costs *q = op_costs[i];
+ int *p_costs = p->cost, *q_costs = q->cost;
+ cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
+ int add_cost;
+
+ /* If the already accounted for the memory "cost" above, don't
+ do so again. */
+ if (!counted_mem)
+ {
+ add_cost = q->mem_cost;
+ if (add_cost > 0 && INT_MAX - add_cost < p->mem_cost)
+ p->mem_cost = INT_MAX;
+ else
+ p->mem_cost += add_cost;
+ }
+ for (k = cost_classes_ptr->num - 1; k >= 0; k--)
+ {
+ add_cost = q_costs[k];
+ if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
+ p_costs[k] = INT_MAX;
+ else
+ p_costs[k] += add_cost;
+ }
+ }
+ }
return insn;
}