This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/48308] [4.6/4.7 Regression] crosscompiling to arm fails with assembler: can't resolve '.LC4' {.rodata.str1.1 section} - '.LPIC4' {*UND* section}


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48308

--- Comment #18 from Ramana Radhakrishnan <ramana at gcc dot gnu.org> 2012-01-11 18:15:05 UTC ---
(In reply to comment #14)
> Note, can't be reproduced on the trunk, the strcmp isn't DCEd there, but guess
> the problem is just latent there.
> 
> It looks like a target bug to me.  Before RTL loop opts we have:
> (insn 91 90 92 13 (set (reg:SI 167)
>         (unspec:SI [
>                 (const:SI (unspec:SI [
>                             (symbol_ref/v/f:SI ("*.LC4") [flags 0x82] 
> <var_decl 0x7f5ebb0a5500 *.LC4>)
>                             (const:SI (plus:SI (unspec:SI [
>                                             (const_int 4 [0x4])
>                                         ] 21)
>                                     (const_int 8 [0x8])))
>                         ] 27))
>             ] 3)) pr48308.i:228 170 {pic_load_addr_32bit}
>      (nil))
> 
> (insn 92 91 94 13 (set (reg:SI 167)
>         (unspec:SI [
>                 (reg:SI 167)
>                 (const_int 8 [0x8])
>                 (const_int 4 [0x4])
>             ] 4)) pr48308.i:228 173 {pic_add_dot_plus_eight}
>      (expr_list:REG_EQUAL (symbol_ref/v/f:SI ("*.LC4") [flags 0x82]  <var_decl
> 0x7f5ebb0a5500 *.LC4>)
>         (nil)))
> 
> and the pseudo 167 is then used to load one of the strcmp parameters.
> Then (probably loop invariant motion) moves insn 91 before the loop, as it
> looks to be loop invariant, but insn 92 is kept in the loop.
> Next during RA, the register pressure is high and thus pseudo 167 is spilled,
> so
> before the loop there is a store.  Then during the *.csa pass DCE is performed
> and the strcmp is removed, which means insn 92 is removed as well, but the
> store before the loop of course is kept.  And there is no further DSE pass that
> would optimize that (now dead) store away.
> So, IMHO arm_reorg needs to handle this case, find out what minipool entries
> don't have the corresponding UNSPEC_PIC_BASE insn and handle them somehow
> (either by emitting there a dummy 0 or similar, or trying to replace the insn
> with UNSPEC_PIC_SYM with something else, ...).
> That said, perhaps it would be nice to help the loop optimizers somehow figure
> out that even the UNSPEC_PIC_BASE is loop invariant (wrap it into CONST?).


Found it I think- the problem is way before any of this . A transformation 
in combine looks suspicious. 

The first clue to all this was that the compiler was removing a call of strcmp
with .LC4 which is the constant string "-noout" . If you look at the testcase,
there is a use of noout afterwards which is to call :

   if (!noout)   
     PEM_write_bio_Parameters(out,pkey);

However the condition 

 else if (strcmp(*args,"-text") == 0)    
       text=1;

has a value of text set to 1. 

However given text is not used later that is the only call 
to strcmp that can be removed safely. However the strcmp of "-text" is retained
in the final code generated but the call to strcmp of "-noout" is the one
that's getting eliminated. 

Here's the suspicious transformation after combine: 


(insn 97 96 188 13 (set (reg:SI 168)
        (reg:SI 0 r0)) ./t.i:41 624 {*arm_movsi_vfp}
     (expr_list:REG_DEAD (reg:SI 0 r0)
        (nil)))

(insn 188 97 189 13 (set (reg:CC 24 cc)
        (compare:CC (reg:SI 168)
            (const_int 0 [0]))) ./t.i:41 198 {*arm_cmpsi_insn}
     (nil))

(insn 189 188 191 13 (set (reg/v:SI 136 [ badarg ])
        (if_then_else:SI (eq (reg:CC 24 cc)
                (const_int 0 [0]))
            (reg:SI 168)
            (const_int 0 [0]))) ./t.i:41 220 {*movsicc_insn}
     (expr_list:REG_DEAD (reg:SI 168)
        (nil)))

(insn 191 189 153 13 (set (reg/v:SI 135 [ noout ])
        (if_then_else:SI (ne (reg:CC 24 cc)
                (const_int 0 [0]))
            (reg/v:SI 135 [ noout ])
            (const_int 1 [0x1]))) ./t.i:41 220 {*movsicc_insn}
     (expr_list:REG_DEAD (reg:CC 24 cc)
        (nil)))


is transformed to :

(note 97 96 188 13 NOTE_INSN_DELETED)

(note 188 97 189 13 NOTE_INSN_DELETED)

(insn 189 188 191 13 (set (reg/v:SI 136 [ badarg ])
        (const_int 0 [0])) ./t.i:41 624 {*arm_movsi_vfp}
     (nil))

(insn 191 189 153 13 (parallel [
            (set (reg/v:SI 135 [ noout ])
                (if_then_else:SI (ne (reg:SI 168)
                        (const_int 0 [0]))
                    (reg/v:SI 135 [ noout ])
                    (const_int 1 [0x1])))
            (clobber (reg:CC 24 cc))
        ]) ./t.i:41 273 {movcond}
     (expr_list:REG_UNUSED (reg:CC 24 cc)
        (expr_list:REG_DEAD (reg:SI 168)
            (nil))))


Look at the use of reg:SI 168  in insn 191 rather than reg:SI r0 . That's where
it all goes pear shaped as we've now used reg:SI 168 which we've not defined
before. The other bits of info from .combine is as below.  

Trying 97 -> 188:
Successfully matched this instruction:
(parallel [
        (set (reg:CC 24 cc)
            (compare:CC (reg:SI 0 r0)
                (const_int 0 [0])))
        (set (reg:SI 168)
            (reg:SI 0 r0))
    ])

and then further trying to combine insn 188 into insn 189 we get the following 


Trying 188 -> 189:
Failed to match this instruction:
(parallel [
        (set (reg/v:SI 136 [ badarg ])
            (const_int 0 [0]))
        (set (reg:CC 24 cc)
            (compare:CC (reg:SI 168)
                (const_int 0 [0])))
    ])
Failed to match this instruction:
(parallel [
        (set (reg/v:SI 136 [ badarg ])
            (const_int 0 [0]))
        (set (reg:CC 24 cc)
            (compare:CC (reg:SI 168)
                (const_int 0 [0])))
    ])
Successfully matched this instruction:
(set (reg:CC 24 cc)
    (compare:CC (reg:SI 168)
        (const_int 0 [0])))
Successfully matched this instruction:
(set (reg/v:SI 136 [ badarg ])
    (const_int 0 [0]))
deferring deletion of insn with uid = 188.
modifying insn i2   188 cc:CC=cmp(r168:SI,0)
      REG_DEAD: r168:SI
deferring rescan insn with uid = 188.
modifying insn i3   189 r136:SI=0
deferring rescan insn with uid = 189.

 I still need to debug through try_combine to figure out where everything goes
pear shaped but that's my understanding on this bug as of today. 

Ofcourse, the simple workaround is to simply disable the transformation in this
form in the ARM backend (*movsi_compare0) but I don't want to do that before
I've finished stepping through combine. 

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 794b865..01c2a87 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -5380,7 +5380,7 @@
                    (const_int 0)))
    (set (match_operand:SI 0 "s_register_operand" "=r,r")
        (match_dup 1))]
-  "TARGET_32BIT"
+  "TARGET_32BIT && 0"
   "@
    cmp%?\\t%0, #0
    sub%.\\t%0, %1, #0"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]