@@ -3971,15 +3971,20 @@ get_vector_binary_rtx_cost (rtx x, int scalar2vr_cost)
   rtx op_0;
   rtx op_1;
- if (GET_CODE (x) == UNSPEC)
-    {
-      op_0 = XVECEXP (x, 0, 0);
-      op_1 = XVECEXP (x, 0, 1);
-    }
-  else
+  switch (GET_CODE (x))
     {
-      op_0 = XEXP (x, 0);
-      op_1 = XEXP (x, 1);
+      case REG:
+       return COSTS_N_INSNS (1);
+      case VEC_DUPLICATE:
+       return (scalar2vr_cost + 1) * COSTS_N_INSNS (1);
+      case UNSPEC:
+       op_0 = XVECEXP (x, 0, 0);
+       op_1 = XVECEXP (x, 0, 1);
+       break;
+      default:
+       op_0 = XEXP (x, 0);
+       op_1 = XEXP (x, 1);
+       break;

Generally, the patch looks reasonable to me but costing gets more confusing by the day :)

Originally we used get_vector_binary_rtx_cost just for binary ops but now it also takes regs, vec_duplicates etc.? And merge is not really a binary op either, is it?

The whole idea of rtx costing is to use the recursive properties and build a "cost tree". Generally, isn't it sufficient to find a (vec_duplicate: scalar) anywhere and then be done? The only distinction we need is whether we're costing a real vmv.v.x or any other instruction.

As we're not recursively traversing, does something like

FOR_EACH_SUBRTX (...)
if (GET_CODE (*iter) == VEC_DUPLICATE)

help, regardless of the actual operation?

--
Regards
Robin

Reply via email to