https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43725

--- Comment #8 from Marat Zakirov <m.zakirov at samsung dot com> ---
UPDATE

Using little fix you may got a much better code...

transpose_16x16:
        .fnstart
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        add     r2, r0, #128
        vld4.16 {d24, d26, d28, d30}, [r0]
        add     r1, r0, #160
        vld4.16 {d16, d18, d20, d22}, [r2]
        add     r0, r0, #32
        movw    r3, #:lower16:m1
        vldr    d6, .L2
        vldr    d7, .L2+8(in CSE)
        movw    r2, #:lower16:m0
        movt    r3, #:upper16:m1
        movt    r2, #:upper16:m0
        vld4.16 {d25, d27, d29, d31}, [r0]
        vld4.16 {d17, d19, d21, d23}, [r1]
        vmul.i16        q12, q3, q12
        vmul.i16        q8, q3, q8
        vmul.i16        q13, q3, q13
        vmul.i16        q9, q3, q9
        vmul.i16        q14, q3, q14
        vmul.i16        q10, q3, q10
        vmul.i16        q15, q3, q15
        vmul.i16        q11, q3, q11
        vstmia  r2, {d24-d31}
        vstmia  r3, {d16-d23}
        bx      lr
.L3:

About fix:

I discovered that GCC register allocator has 'weak' support for stream (in my
case NEON) registers. RA works with stream resgisters as with unsplitible
ranges. So if some register of range becomes free GCC do not reuse them untill
whole range becomes free.

Is actually OK, but...

I found that GCC CSE phase makes partly substitution for register-ranges and
this leads to terrible register pressure increse.

Example

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 define so
actually a != b. Yes but a1 = b1, unfortuanatly CSE also do not how to handle
register-ranges parts as RA does. And I am not sure that 'unfortuanatly'.

Because.

a0 = b0 * 3 
a1 = b1 * 3
a2 = b2 * 3
a3 = b3 * 3

Also requres x2 more stream registers than its really need to.

My solution here is to forbid CSE for XImode registers.

Reply via email to