Michael Hope <michael.h...@linaro.org> writes:
> On Wed, Jan 26, 2011 at 3:54 AM, Peter Maydell <peter.mayd...@linaro.org> 
> wrote:
>> Some news from the qemu mailing list that I think might be
>> of interest to gcc folks here:
>>
>> Christophe Lyon from ST has kindly released a large
>> set of test cases of Neon intrinsics:
>> http://gitorious.org/arm-neon-tests/arm-neon-tests
>> (the tests themselves are more aimed at testing qemu,
>> so they just produce output to be compared against a
>> reference generated from running on hardware).
>>
>> However they don't currently compile with gcc (but
>> are ok with armcc). From the README:
>>
>> # The tests currently fail to build with GCC/ARM:
>> # - no support for Neon_Overflow/fpsrc register
>> # - ICE when compiling ref_vldX.c, ref_vldX_lane.c, ref_vstX_lane.c
>
> gcc-linaro-2011.01 no longer ICEs.

It fails with -marm:

(insn 1817 1816 1818 2 
/home/export/usr/gcc-linaro/H-x86_64-unknown-linux-gnu/bin/../lib/gcc/arm-linux-gnueabi/4.5.2/include/arm_neon.h:921
5 (parallel [
            (set (reg:CI 303 [ D.14795 ])
                (unspec:CI [
                        (mem:CI (reg:SI 3 r3 [1023]) [0 S48 A64])
                        (reg:CI 303 [ D.14795 ])
                        (unspec:V8HI [
                                (const_int 0 [0x0])
                            ] 191)
                    ] 106))
            (set (reg:SI 3 r3 [1023])
                (plus:SI (reg:SI 3 r3 [1023])
                    (const_int 24 [0x18])))
        ]) 1614 {neon_vld3qav8hi} (nil))
ref_vldX.c:157: confused by earlier errors, bailing out

I suspect the original testing was using a normal -marm default
instead of Linaro's -mthumb.

The problem is that register 303 is spilled to the stack, and the stack
slot address isn't legitimate for CImode (it's too far from the frame
pointer).  Reload rightly decides to reload the address into a temporary
reload register, but the ARM backend also says that the load must go
through a GENERAL_REGS reload register:

Reloads for insn # 1817
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 11 fp)
                                                    (const_int -7548 
[0xffffffffffffe284]))
        CORE_REGS, RELOAD_FOR_OUTPUT_ADDRESS (opnum = 0), can't combine
        reload_in_reg: (plus:SI (reg/f:SI 11 fp)
                                                    (const_int -7548 
[0xffffffffffffe284]))
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 11 fp)
                                                    (const_int -7548 
[0xffffffffffffe284]))
        CORE_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0), can't combine
        reload_in_reg: (plus:SI (reg/f:SI 11 fp)
                                                    (const_int -7548 
[0xffffffffffffe284]))
Reload 2: GENERAL_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0), can't combine, 
secondary_reload_p
Reload 3: GENERAL_REGS, RELOAD_FOR_OUTPUT_ADDRESS (opnum = 0), can't combine, 
secondary_reload_p
Reload 4: reload_in (CI) = (mem/c:CI (plus:SI (reg/f:SI 11 fp)
                                                        (const_int -7548 
[0xffffffffffffe284])) [0 %sfp+-7496 S48 A64])
        reload_out (CI) = (mem/c:CI (plus:SI (reg/f:SI 11 fp)
                                                        (const_int -7548 
[0xffffffffffffe284])) [0 %sfp+-7496 S48 A64])
        VFP_REGS, RELOAD_OTHER (opnum = 0), can't combine
        reload_in_reg: (reg:CI 303 [ D.14795 ])
        reload_out_reg: (reg:CI 303 [ D.14795 ])
        secondary_in_reload = 2, secondary_out_reload = 3

where secondary reloads 2 and 3 are bogus.

This comes from two related problems in coproc_secondary_reload_class:
it doesn't handle structure modes like CImode, and it checks whether
the MEM is already legitimate.  The latter is wrong because the memory
is still in its unreloaded form.  The structure (and vector) move patterns
handle all valid addresses, and reload will take care of invalid
addresses for us, so we should simply check for a MEM.

The patch below seems to fix the ICEs.  I'll test and submit one I've
looked at the lane problem.

Richard


=== modified file 'gcc/config/arm/arm.c'
--- gcc/config/arm/arm.c        2011-01-13 16:06:19 +0000
+++ gcc/config/arm/arm.c        2011-01-28 11:16:07 +0000
@@ -9285,11 +9285,14 @@
       return GENERAL_REGS;
     }
 
+  /* The neon move patterns handle all legitimate vector and struct
+     addresses.  */
   if (TARGET_NEON
+      && MEM_P (x)
       && (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
-          || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
-      && neon_vector_mem_operand (x, 0))
-     return NO_REGS;
+         || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
+         || VALID_NEON_STRUCT_MODE (mode)))
+    return NO_REGS;
 
   if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
     return NO_REGS;


_______________________________________________
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-toolchain

Reply via email to