current NEON status

Marat Zakirov m.zakirov@samsung.com
Tue Aug 12 06:44:00 GMT 2014


Hi Vladimir!

I think you are as the main IRA contributor would be appropriate person 
to answer question bellow. Please confirm or refute my statement about 
unsplittable register ranges in GCC IRA.

On 07/30/2014 05:38 PM, Marat Zakirov wrote:
> Hi there!
>
> My question came from bug
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43725. I found that GCC 
> considers NEON register ranges as unsplittable. So any subregister may 
> be used only after whole chunk is dead. This issue leads to redundant 
> spill fills which is performance trouble.
>
> Example 1: RAL trouble
>
> #include <arm_neon.h>
> #include <inttypes.h>
>
> extern  uint16x8x4_t m0;
> extern  uint16x8x4_t m1;
> extern  uint16x8x4_t m2;
> extern  uint16x8x4_t m3;
> extern  uint16x8_t   m4;
>
> void foo1(uint16_t * in_ptr)
> {
>      uint16x8x4_t t0, t1, t2, t3;
>      t0 = vld4q_u16((uint16_t *)&in_ptr[0 ]);
>      t1 = vld4q_u16((uint16_t *)&in_ptr[64]);
>      t2 = vld4q_u16((uint16_t *)&in_ptr[128]);
>      t3 = vld4q_u16((uint16_t *)&in_ptr[192]);
>      m4 = t0.val[3];
>      m4 = m4 * 3;                       <<< *
>      t0.val[3] = t1.val[3];
>      m0 = t3;
>      m1 = t2;
>      m2 = t1;
>      m3 = t0;
> }
>
> Here test uses all NEON registers. No spill is needed. Because 
> multiplication requires one Q register which may be obtained from dead 
> t0.val[3] subregister. But GCC makes spill if multiplication (*) 
> exists because of issue described above.
>
> Example 2: CSE makes trouble for IRA
>
> #include <arm_neon.h>
> #include <inttypes.h>
>
> extern  uint16x8x4_t m0;
> extern  uint16x8x4_t m1;
>
> void foo2(uint16_t * in_ptr)
> {
>      uint16x8x4_t t0, t1;
>      t0 = vld4q_u16((uint16_t *)&in_ptr[0 ]);
>      t1 = vld4q_u16((uint16_t *)&in_ptr[64]);
>      t0.val[0] *= 333;
>      t0.val[1] *= 333;
>      t0.val[2] *= 333;
>      t0.val[3] *= 333;
>      t1.val[0] *= 333;
>      t1.val[1] *= 333;
>      t1.val[2] *= 333;
>      t1.val[3] *= 333;
>      m0 = t0;
>      m1 = t1;
> }
>
> Here test uses only half NEON + one Q for '333' factor. But GCC makes 
> spills here too! Briefly speak problem is in partial CSE. GCC 
> generates rtl with the listed bellow form:
>
> Before CSE:
>
> a = b
> a0 = a0 * 3
> a1 = a1 * 3
> a2 = a2 * 3
> a3 = a3 * 3
>
> After:
>
> a = b
> a0 = b0 * 3
> a1 = a1 * 3 <<< *
> a2 = a2 * 3
> a3 = a3 * 3
>
> CSE do not substitute b1 to a1 because at the moment (*) a0 was 
> already defined so actually a != b. Yes but a1 = b1, unfortunately CSE 
> also do not handle register-ranges parts as RA does. Strange thing 
> here is that even if we fix CSE, so CSE could propagate 
> register-ranges subregs, this will make trouble to RAL also because of 
> the same reason: IRA do not handle precisely register ranges parts. I 
> attached a demo patch which forbids partial CSE propagation and 
> removes spills from Ex2. Is this patch OK? Or maybe CSE should be 
> fixed in a different way? Or maybe partial substitution is OK?
>
> Main question: Are there any plans to fix/upgrade IRA?
>
> --Marat

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ximode.diff
Type: text/x-patch
Size: 880 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20140812/6576ca8a/attachment.bin>


More information about the Gcc mailing list