On 10/18/18, Richard Sandiford <richard.sandif...@arm.com> wrote:
> "H.J. Lu" <hjl.to...@gmail.com> writes:
>> On 10/18/18, Richard Sandiford <richard.sandif...@arm.com> wrote:
>>> "H.J. Lu" <hjl.to...@gmail.com> writes:
>>>> On 10/17/18, Marc Glisse <marc.gli...@inria.fr> wrote:
>>>>> On Wed, 17 Oct 2018, H.J. Lu wrote:
>>>>>
>>>>>> We may simplify
>>>>>>
>>>>>>  (subreg (vec_merge (vec_duplicate X) (vector) (const_int 1)) 0)
>>>>>>
>>>>>> to X when mode of X is the same as of mode of subreg.
>>>>>
>>>>> Hello,
>>>>>
>>>>> we already have code to simplify vec_select(vec_merge):
>>>>>
>>>>>      /* If we select elements in a vec_merge that all come from the
>>>>> same
>>>>>         operand, select from that operand directly.  */
>>>>>
>>>>> It would make sense to me to make the subreg transform as similar to
>>>>> it
>>>>> as
>>>>> possible, in particular you don't need to special case vec_duplicate,
>>>>> the
>>>>> transformation would see that everything comes from the first vector,
>>>>> produce (subreg (vec_duplicate X) 0), and let another transformation
>>>>> optimize that.
>>>
>>> Sorry, didn't see this before the OK.
>>>
>>>> What do you mean by another transformation? If simplify_subreg doesn't
>>>> return X for
>>>>
>>>>   (subreg (vec_merge (vec_duplicate X)
>>>>                 (vector)
>>>>                 (const_int ((1 << N) | M)))
>>>>      (N * sizeof (X)))
>>>>
>>>>
>>>> no further transformation will be done.
>>>
>>> I think the point was that we should transform:
>>>
>>>   (subreg (vec_merge X
>>>                  (vector)
>>>                  (const_int ((1 << N) | M)))
>>>       (N * sizeof (X)))
>>>
>>> into:
>>>
>>>   simplify_gen_subreg (outermode, X, innermode, byte)
>>>
>>> which should further simplify when X is a vec_duplicate.
>>
>> But sizeof (X) is the size of scalar of vec_dup.  How do we
>> check the mask of vec_merge?
>
> Yeah, should be sizeof (outermode) (which was the same thing
> in the original pattern, but not here).
>
> Richard
>

Like this

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index b0cf3bbb2a9..e12b5c0e165 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -6601,20 +6601,21 @@ simplify_subreg (machine_mode outermode, rtx op,
       return NULL_RTX;
     }

-  /* Return X for
-  (subreg (vec_merge (vec_duplicate X)
+  /* Simplify
+  (subreg (vec_merge (X)
            (vector)
            (const_int ((1 << N) | M)))
-     (N * sizeof (X)))
+     (N * sizeof (outermode)))
+     to
+  (subreg ((X) (N * sizeof (outermode)))
    */
   unsigned int idx;
   if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
       && GET_CODE (op) == VEC_MERGE
-      && GET_CODE (XEXP (op, 0)) == VEC_DUPLICATE
-      && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
+      && GET_MODE_INNER (innermode) == outermode
       && CONST_INT_P (XEXP (op, 2))
       && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
-    return XEXP (XEXP (op, 0), 0);
+    return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);

   /* A SUBREG resulting from a zero extension may fold to zero if
      it extracts higher bits that the ZERO_EXTEND's source bits.  */

-- 
H.J.

Reply via email to