[PATCH] fix non-canonical RTL produced by expand

Paolo Bonzini paolo.bonzini@lu.unisi.ch
Wed Sep 14 11:44:00 GMT 2005


I found one thing while researching non-canonical RTL produced by 
expand.  The thing is that expand_binop, while expanding multi-word 
operations, produces RTL like this:

         (set (subreg:SI (reg:DI 64) 0)
              (and:SI (subreg:SI (reg:DI 63) 0)
                  (mem:SI (reg/f:SI 62) [2 S4 A64])))

which was extracted from the .expand dump of this:

    unsigned long long b, w;
    int f(int wtm, long long mask)
    {
      unsigned long long *p[2];
    
      p[0] = &b;
      p[1] = &w;
      if (*p[!wtm] & mask)
        return wtm;
      else
        return -1;
    }

As nice as it may seem, this RTL is not canonical.  The subreg is placed 
first by expand_binop because it only tries to canonicalize the position 
of REGs, and does not rely on commutative_operand_precedence:

      if (((target == 0 || REG_P (target))
           ? ((REG_P (op1)
               && !REG_P (op0))
              || target == op1)
           : rtx_equal_p (op1, target))
          || GET_CODE (op0) == CONST_INT)
        {
          temp = op1;
          op1 = op0;
          op0 = temp;
        }

This almost always produces canonical expressions because all objects 
(RTX class = RTX_OBJECT) have the same precedence with respect to 
canonicalization.  The notable exception is expanding multi-word 
operations: in this case operand_subword could be a SUBREG for the first 
operand but not for the first.  In this case, according to 
commutative_operand_precedence, the SUBREG should go last.  However, 
only CSE is able to fix this bad choice of operand order.

In my tree (which performs less CSE than mainline), better code would be 
produced from the above RTL than from the canonical (and (mem) 
(subreg)).  This results in a 3% performance decrease on crafty, which 
this simple patch fixes.

Bootstrapped/regtested i686-pc-linux-gnu.  Ok for mainline or 4.2?

Paolo

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: fix-com-op-prec.patch
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20050914/224b099f/attachment.ksh>


More information about the Gcc-patches mailing list