Hi Vladimir,

The following testcase fails when compiled with -O2 -mips32r2: 

long long a[];
long long b, c, d, k, m, n, o, p, q, r, s, t, u, v, w;
int e, f, g, h, i, j, l, x;
fn1() {
  for (; x; x++)
    if (x & 1)
      s = h | g;
    else
      s = f | e;
  l = ~0;
  m = 1 | k;
  n = i;
  o = j;
  p = f | e;
  q = h | g;
  w = d | c | a[1];
  t = c;
  v = b | c;
  u = v;
  r = b | a[4];
}

It is reproducible on mips-linux-gnu using SVN revision 212763. After a patch 
to p5600.md the bug is not triggered but it may reappear in the future.

The decompose_normal_address function throws an assertion because it cannot
decompose the following RTL:

(mem/c:SI (lo_sum:SI (high:SI (symbol_ref:SI ("w")))  
                (const:SI (plus:SI (symbol_ref:SI ("w"))                        
                        (const_int 4 [0x4]))

It appears that it all starts in the following instruction and how LRA deals
with REG_EQUIV notes:

(insn 107 119 123 10 (set (reg:SI 283)                                          
               
        (ior:SI (reg:SI 284 [ a+12 ])                                           
               
            (reg:SI 309 [ D.1467+4 ]))) init.i:16 163 {*iorsi3}                 
               
     (expr_list:REG_DEAD (reg:SI 309 [ D.1467+4 ])                              
               
        (expr_list:REG_DEAD (reg:SI 284 [ a+12 ])                               
               
            (expr_list:REG_EQUIV (mem/c:SI (lo_sum:SI (reg/f:SI 274)            
               
                        (const:SI (plus:SI (symbol_ref:SI ("w"))  
                                (const_int 4 [0x4])))))                         
                (nil)))))

There are two conditions necessary to trigger the ICE.
Firstly, the pseudo 274 is spilled to memory that is marked by IRA, thus, 
during LRA pass the pseudo 274 is replaced with 'high' when equivalences 
are updated for pseudos. Secondly, pseudo 283 also gets spilled and LRA starts 
using equivalences but LO_SUM and HIGH are already combined leading to 
an assertion error. 

Accepting HIGH as the base does seem to solve the problem. HIGH is also 
reloaded after the decomposition splitting HIGH/LO_SUM into a pair again. 
However, is this an acceptable solution?

Regards,
Robert

gcc/
        * rtlanal.c (get_base_term): Accept HIGH as the base term.


diff --git gcc/rtlanal.c gcc/rtlanal.c
index 82cfc1bf..2bea2ca 100644
--- gcc/rtlanal.c
+++ gcc/rtlanal.c
@@ -5624,6 +5624,7 @@ get_base_term (rtx *inner)
     inner = strip_address_mutations (&XEXP (*inner, 0));
   if (REG_P (*inner)
       || MEM_P (*inner)
+      || GET_CODE (*inner) == HIGH
       || GET_CODE (*inner) == SUBREG)
     return inner;
   return 0;

Reply via email to