------- Comment #9 from danglin at gcc dot gnu dot org 2006-01-07 18:37 ------- I'm changing this to a target bug. The bug is in the define for SECONDARY_MEMORY_NEEDED_RTX(MODE):
#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ gen_rtx_MEM (MODE, gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-16))) There are a number of places where this memory location gets used during final code generation. I don't think we can add clobbers. When we define SECONDARY_MEMORY_NEEDED_RTX as above, reload introduces store-load insns into the RTL to copy a value from a general/floating register to a floating/general register. Subsequently, scheduling may copy separate the load and store insns. This then can introduce a conflict with the use of this memory location during code generation. I'm not sure about the validity of scheduling moving the "fldws -16(%r30),%fr21L" over a call. The call_insn is marked as a const or pure call: (call_insn/u 80 4722 4769 0 cxg1005.adb:88 (parallel [ (set (reg:SC 28 %r28) (call (mem:SI (symbol_ref/v:SI ("@cxg1005__test_block__complex_p ack__compose_from_cartesian__3___395") <function_decl 0x40100620 cxg1005__test_b lock__complex_pack__compose_from_cartesian__3>) [0 S4 A32]) (const_int 16 [0x10]))) (clobber (reg:SI 1 %r1)) (clobber (reg:SI 2 %r2)) (use (const_int 0 [0x0])) ]) 204 {call_val_symref} (insn_list:REG_DEP_TRUE 60 (insn_list:REG_DEP_O UTPUT 63 (insn_list:REG_DEP_ANTI 66 (insn_list:REG_DEP_ANTI 65 (insn_list:REG_DE P_OUTPUT 20 (insn_list:REG_DEP_ANTI 22 (insn_list:REG_DEP_OUTPUT 21 (insn_list:R EG_DEP_TRUE 79 (insn_list:REG_DEP_ANTI 64 (nil)))))))))) (expr_list:REG_DEAD (reg:SF 32 %fr4) (expr_list:REG_UNUSED (reg:SI 2 %r2) (expr_list:REG_UNUSED (reg:SI 1 %r1) (nil)))) (expr_list:REG_DEP_TRUE (use (reg:SF 32 %fr4)) (nil))) The decision as to whether the function is pure is made before reload and that doesn't change when the SECONDARY_MEMORY_NEEDED_RTX MEM is used (ie., we use a special location in the frame of the caller for the copy. This problem can be avoided if we always ensure that the function has a frame. However, this adds instructions and still doesn't fix the issue that the MEM might be used between the store and load in other situations. Thus, I think the best fix is to remove the SECONDARY_MEMORY_NEEDED_RTX define and do the register copy in the move patterns directly. This keeps the MEM from being exposed in the RTL. We lose the performance benefit of scheduling the store and load. However, we don't need a frame to do floating-general copies. As an aside, the problem is introduced in the RTL in the sched2 pass: call_insn/u 80 4722 5740 0 cxg1005.adb:88 (parallel [ (set (reg:SC 28 %r28) (call (mem:SI (symbol_ref/v:SI ("@cxg1005__test_block__complex_p ack__compose_from_cartesian__3___395") <function_decl 0x40100620 cxg1005__test_b lock__complex_pack__compose_from_cartesian__3>) [0 S4 A32]) (const_int 16 [0x10]))) (clobber (reg:SI 1 %r1)) (clobber (reg:SI 2 %r2)) (use (const_int 0 [0x0])) ]) 204 {call_val_symref} (insn_list:REG_DEP_OUTPUT 63 (insn_list:REG_DEP _ANTI 4765 (insn_list:REG_DEP_ANTI 4763 (insn_list:REG_DEP_OUTPUT 12 (insn_list: REG_DEP_OUTPUT 10 (insn_list:REG_DEP_OUTPUT 17 (insn_list:REG_DEP_ANTI 22 (insn_ list:REG_DEP_OUTPUT 15 (insn_list:REG_DEP_ANTI 4767 (insn_list:REG_DEP_ANTI 4768 (insn_list:REG_DEP_OUTPUT 4677 (insn_list:REG_DEP_ANTI 5372 (insn_list:REG_DEP_ ANTI 5391 (insn_list:REG_DEP_ANTI 5392 (insn_list:REG_DEP_ANTI 5393 (insn_list:R EG_DEP_ANTI 5394 (insn_list:REG_DEP_ANTI 5395 (insn_list:REG_DEP_ANTI 5396 (insn _list:REG_DEP_ANTI 5397 (insn_list:REG_DEP_ANTI 5398 (insn_list:REG_DEP_ANTI 539 9 (insn_list:REG_DEP_ANTI 5400 (insn_list:REG_DEP_OUTPUT 5390 (insn_list:REG_DEP _TRUE 79 (insn_list:REG_DEP_TRUE 5373 (insn_list:REG_DEP_ANTI 64 (nil))))))))))) )))))))))))))))) (expr_list:REG_DEAD (reg:SF 32 %fr4) (expr_list:REG_UNUSED (reg:SI 2 %r2) (expr_list:REG_UNUSED (reg:SI 1 %r1) (nil)))) (expr_list:REG_DEP_TRUE (use (reg:SF 32 %fr4)) (nil))) (note 5740 80 4766 0 ("cxg1005.adb") 87) (insn 4766 5740 5741 0 cxg1005.adb:87 (set (reg:SF 66 %fr21 [orig:778+4 ] [778]) (mem:SF (plus:SI (reg/f:SI 30 %r30) (const_int -16 [0xfffffff0])) [0 S4 A32])) 77 {*pa.md:4325} (ins n_list:REG_DEP_ANTI 5391 (insn_list:REG_DEP_TRUE 5373 (insn_list:REG_DEP_ANTI 64 (insn_list:REG_DEP_TRUE 4763 (insn_list:REG_DEP_TRUE 4765 (nil)))))) (nil)) -- danglin at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Component|ada |target http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20754