Invalid code generated for Coldfire target
Jeff Law
law@redhat.com
Mon Nov 17 20:36:00 GMT 2008
Meloun Michal wrote:
> Hello all,
> I tracing bug in GCC for Coldfire target, but I end in dead water and
> I need some help from real experts :).
> Both gcc 4.4 and 4.3 have same problem
>
> GCC miscompile this small test case.
>
> //-----------------------------------------------------------------
> //m68k-elf-gcc -save-temps -da -fdump-tree-all -fdump-ipa-all -c test.c -o test.o
> void dummy(char *arg);
>
> static void test1(void)
> {
> char tmp[2] = "0";
> }
>
> void test2(void)
> {
> dummy("0");
> }
> //------------------------------------------------------------------
> The file is compiled to:
> #NO_APP
> .file "test.c"
> .section .rodata
> .LC0:
> .string "0"
> .text
> .align 2
> .type test1, @function
> test1:
> link.w %fp,#-4
> lea .LC0,%a0
> move.w (%a0),-2(%fp)
> unlk %fp
> rts
> .size test1, .-test1
>
> .align 2
> .globl test2
> .type test2, @function
> test2:
> link.w %fp,#0
> move.l %a0,-(%sp) <-- note: a0 is used uninitialized here
> jsr dummy
> addq.l #4,%sp
> unlk %fp
> rts
> .size test2, .-test2
>
> .ident "GCC: (GNU) 4.4.0 20081031 (experimental)"
>
>
> And relevant part of RTL after expand pass:
>
> ;; Function test1 (test1)
> ;; Generating RTL for gimple basic block 2
> ;; tmp ={v} "0";
> (insn 5 4 0 test.c:8 (set (mem/s/c:HI (plus:SI (reg/f:SI 26 virtual-stack-vars)
> (const_int -2 [0xfffffffe])) [0 tmp+0 S2 A16])
> (mem/s:HI (symbol_ref/f:SI ("*.LC0") [flags 0x2] <string_cst 0x7fdf7700>) [0 S2 A8])) -1 (nil))
>
> ;; Function test2 (test2)
> ;; Generating RTL for gimple basic block 2
> ;; dummy (&"0"[0]);
> <--- !!!! bad insn here -----
> (insn 5 4 6 test.c:15 (set (mem/f/i:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
> (reg:SI 8 %a0)) -1 (nil))
> <------------------------------
> (call_insn 6 5 7 test.c:15 (call (mem:QI (symbol_ref:SI ("dummy") [flags 0x41] <function_decl 0x7fdd4580 dummy>) [0 S1 A8])
> (const_int 4 [0x4])) -1 (nil)
> (nil))
>
> (insn 7 6 0 test.c:15 (set (reg/f:SI 15 %sp)
> (plus:SI (reg/f:SI 15 %sp)
> (const_int 4 [0x4]))) -1 (nil))
>
> After some debugging, I found cause of this bug, but proper solution is
> not clear for me. When "char tmp[2] = "0";" is compiled, the function "output_constant_def"
> is called and proper insn is stored into cache:
>
> (gdb) call debug_rtx(desc->rtl)
> (mem/s:HI (symbol_ref/f:SI ("*.LC0") [flags 0x2] <string_cst 0x7fdf7700>) [0 S2 A8])
>
>
> Later, in ira pass, this insn is spitted to this (Coldfire has no memory to memory move):
>
> Reloads for insn # 5
> Reload 0: reload_in (SI) = (symbol_ref/f:SI ("*.LC0") [flags 0x2] <string_cst
> 0x7fdf7700>)
> ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1), inc by 2
> reload_in_reg: (symbol_ref/f:SI ("*.LC0") [flags 0x2] <string_cst 0x7fdf7700>)
> reload_reg_rtx: (reg:SI 8 %a0)
> ...
> (note 2 3 14 2 NOTE_INSN_FUNCTION_BEG)
>
> (insn 14 2 5 2 test.c:7 (set (reg:SI 8 %a0)
> (symbol_ref/f:SI ("*.LC0") [flags 0x2] <string_cst 0x7fdf7700>)) 38 {*movsi_cf} (nil))
>
> (insn 5 14 13 2 test.c:7 (set (mem/s/c:HI (plus:SI (reg/f:SI 14 %a6)
> (const_int -2 [0xfffffffe])) [0 tmp+0 S2 A16])
> (mem/s:HI (reg:SI 8 %a0) [0 S2 A8])) 41 {*m68k.md:906} (nil))
> ;; End of basic block 2 -> ( 1)
> ;; lr out 14 [%a6] 15 [%sp] 24 [%argptr]
>
> The first insn is newly allocated, but second one overwrites original insn.
> From local point of view, this is still OK, but this corrupt the output_constant_def
> cache (cache holds pointer to overwritten insn. So every
> next access to "0" constat returns
> (mem/s:HI (reg:SI 8 %a0) [0 S2 A8])) 41 {*m68k.md:906} (nil))
> and not
> (symbol_ref/f:SI ("*.LC0") [flags 0x2] <string_cst 0x7fdf7700>)) 38 {*movsi_cf} (nil))
>
> But how to fix this? By my mean, the cache must hold own immutable copy of insn.
> But im not gcc expert, so I need help with proper solution. Is this patch OK? Any other solution?
>
> --- varasm.c.orig 2008-11-14 18:04:27.693643900 +0100
> +++ varasm.c 2008-11-14 17:58:06.522748300 +0100
> @@ -3245,7 +3245,7 @@
> }
>
> maybe_output_constant_def_contents (desc, defer);
> - return desc->rtl;
> + return copy_rtx (desc->rtl);
> }
>
> /* Subroutine of output_constant_def: Decide whether or not we need to
> ---------------------------------------------
>
> Moreover, this can be common problem on more places (at least at gen_rtx_CONST_INT).
>
>
> Ohh, and sorry for my english.
>
> Many thanks
>
> Michal Meloun
>
Can you forward all the debugging dumps? Clearly there's a structure
sharing problem here, but I'd like to see the full dumps.
Jeff
More information about the Gcc
mailing list