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