]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
VAX: Accept ASHIFT in address expressions
authorMaciej W. Rozycki <macro@orcam.me.uk>
Wed, 21 Apr 2021 21:33:25 +0000 (23:33 +0200)
committerMaciej W. Rozycki <macro@orcam.me.uk>
Tue, 27 Apr 2021 18:02:06 +0000 (20:02 +0200)
Fix regressions:

FAIL: gcc.c-torture/execute/20090113-2.c   -O1  (internal compiler error)
FAIL: gcc.c-torture/execute/20090113-2.c   -O1  (test for excess errors)
FAIL: gcc.c-torture/execute/20090113-3.c   -O1  (internal compiler error)
FAIL: gcc.c-torture/execute/20090113-3.c   -O1  (test for excess errors)

triggering if LRA is used rather than old reload and caused by:

(plus:SI (plus:SI (mult:SI (reg:SI 30 [ _10 ])
            (const_int 4 [0x4]))
        (reg/f:SI 26 [ _6 ]))
    (const_int 12 [0xc]))

coming from:

(insn 58 57 59 10 (set (reg:SI 33 [ _13 ])
        (zero_extract:SI (mem:SI (plus:SI (plus:SI (mult:SI (reg:SI 30 [ _10 ])
                            (const_int 4 [0x4]))
                        (reg/f:SI 26 [ _6 ]))
                    (const_int 12 [0xc])) [4 _6->bits[_10]+0 S4 A32])
            (reg:QI 56)
            (reg:SI 53)))
".../gcc/testsuite/gcc.c-torture/execute/20090113-2.c":64:12 490 {*extzv_non_const}
     (expr_list:REG_DEAD (reg:QI 56)
        (expr_list:REG_DEAD (reg:SI 53)
            (expr_list:REG_DEAD (reg:SI 30 [ _10 ])
                (expr_list:REG_DEAD (reg/f:SI 26 [ _6 ])
                    (nil))))))

being converted into:

(plus:SI (plus:SI (ashift:SI (reg:SI 30 [ _10 ])
            (const_int 2 [0x2]))
        (reg/f:SI 26 [ _6 ]))
    (const_int 12 [0xc]))

which is an rtx the VAX backend currently does not recognize as a valid
machine address, although apparently it is only inside MEM rtx's that
indexed addressing is supposed to be canonicalized to a MULT rather than
ASHIFT form.  Handle the ASHIFT form too throughout the backend then.

The change appears to also improve code generation with old reload and
code size stats are as follows, collected from 18153 executables built
in `check-c' GCC testing:

              samples average  median
--------------------------------------
regressions        47  0.702%  0.521%
unchanged       17503  0.000%  0.000%
progressions      603 -0.920% -0.403%
--------------------------------------
total           18153 -0.029%  0.000%

with a small number of outliers (over 5% size change):

old     new     change  %change filename
----------------------------------------------------
1885    1645    -240   -12.7320 pr53505.exe
1331    1221    -110    -8.2644 pr89634.exe
1553    1473    -80     -5.1513 stdatomic-vm.exe
1413    1341    -72     -5.0955 pr45830.exe
1415    1343    -72     -5.0883 stdatomic-vm.exe
25765   24463   -1302   -5.0533 strlen-5.exe
25765   24463   -1302   -5.0533 strlen-5.exe
25765   24463   -1302   -5.0533 strlen-5.exe
1191    1131    -60     -5.0377 20050527-1.exe

(all changes on the expansion side are below 5%).

gcc/
* config/vax/vax.c (print_operand_address, vax_address_cost_1)
(index_term_p): Handle ASHIFT too.

gcc/config/vax/vax.c

index 870af2b3af4cd32c4c7694c80e8db0aafbd73bf6..96a792593a3e2a9560ede6c44cdaf0c64d33087a 100644 (file)
@@ -333,12 +333,12 @@ print_operand_address (FILE * file, rtx addr)
 
     case PLUS:
       /* There can be either two or three things added here.  One must be a
-        REG.  One can be either a REG or a MULT of a REG and an appropriate
-        constant, and the third can only be a constant or a MEM.
+        REG.  One can be either a REG or a MULT/ASHIFT of a REG and an
+        appropriate constant, and the third can only be a constant or a MEM.
 
         We get these two or three things and put the constant or MEM in
-        OFFSET, the MULT or REG in IREG, and the REG in BREG.  If we have
-        a register and can't tell yet if it is a base or index register,
+        OFFSET, the MULT/ASHIFT or REG in IREG, and the REG in BREG.  If we
+        have a register and can't tell yet if it is a base or index register,
         put it into REG1.  */
 
       reg1 = 0; ireg = 0; breg = 0; offset = 0;
@@ -355,12 +355,14 @@ print_operand_address (FILE * file, rtx addr)
          offset = XEXP (addr, 1);
          addr = XEXP (addr, 0);
        }
-      else if (GET_CODE (XEXP (addr, 1)) == MULT)
+      else if (GET_CODE (XEXP (addr, 1)) == MULT
+              || GET_CODE (XEXP (addr, 1)) == ASHIFT)
        {
          ireg = XEXP (addr, 1);
          addr = XEXP (addr, 0);
        }
-      else if (GET_CODE (XEXP (addr, 0)) == MULT)
+      else if (GET_CODE (XEXP (addr, 0)) == MULT
+              || GET_CODE (XEXP (addr, 0)) == ASHIFT)
        {
          ireg = XEXP (addr, 0);
          addr = XEXP (addr, 1);
@@ -385,7 +387,7 @@ print_operand_address (FILE * file, rtx addr)
          else
            reg1 = addr;
        }
-      else if (GET_CODE (addr) == MULT)
+      else if (GET_CODE (addr) == MULT || GET_CODE (addr) == ASHIFT)
        ireg = addr;
       else
        {
@@ -416,7 +418,8 @@ print_operand_address (FILE * file, rtx addr)
            }
          else
            {
-             gcc_assert (GET_CODE (XEXP (addr, 0)) == MULT);
+             gcc_assert (GET_CODE (XEXP (addr, 0)) == MULT
+                         || GET_CODE (XEXP (addr, 0)) == ASHIFT);
              gcc_assert (!ireg);
              ireg = XEXP (addr, 0);
            }
@@ -447,7 +450,8 @@ print_operand_address (FILE * file, rtx addr)
            }
          else
            {
-             gcc_assert (GET_CODE (XEXP (addr, 1)) == MULT);
+             gcc_assert (GET_CODE (XEXP (addr, 1)) == MULT
+                         || GET_CODE (XEXP (addr, 1)) == ASHIFT);
              gcc_assert (!ireg);
              ireg = XEXP (addr, 1);
            }
@@ -506,7 +510,7 @@ print_operand_address (FILE * file, rtx addr)
 
       if (ireg != 0)
        {
-         if (GET_CODE (ireg) == MULT)
+         if (GET_CODE (ireg) == MULT || GET_CODE (ireg) == ASHIFT)
            ireg = XEXP (ireg, 0);
          gcc_assert (REG_P (ireg));
          fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
@@ -707,6 +711,7 @@ vax_address_cost_1 (rtx addr)
       reg = 1;
       break;
     case MULT:
+    case ASHIFT:
       indexed = 1;     /* 2 on VAX 2 */
       break;
     case CONST_INT:
@@ -1824,23 +1829,26 @@ static bool
 index_term_p (rtx prod, machine_mode mode, bool strict)
 {
   rtx xfoo0, xfoo1;
+  bool log_p;
 
   if (GET_MODE_SIZE (mode) == 1)
     return BASE_REGISTER_P (prod, strict);
 
-  if (GET_CODE (prod) != MULT || GET_MODE_SIZE (mode) > 8)
+  if ((GET_CODE (prod) != MULT && GET_CODE (prod) != ASHIFT)
+      || GET_MODE_SIZE (mode) > 8)
     return false;
 
+  log_p = GET_CODE (prod) == ASHIFT;
   xfoo0 = XEXP (prod, 0);
   xfoo1 = XEXP (prod, 1);
 
   if (CONST_INT_P (xfoo0)
-      && INTVAL (xfoo0) == (int)GET_MODE_SIZE (mode)
+      && GET_MODE_SIZE (mode) == (log_p ? 1 << INTVAL (xfoo0) : INTVAL (xfoo0))
       && INDEX_REGISTER_P (xfoo1, strict))
     return true;
 
   if (CONST_INT_P (xfoo1)
-      && INTVAL (xfoo1) == (int)GET_MODE_SIZE (mode)
+      && GET_MODE_SIZE (mode) == (log_p ? 1 << INTVAL (xfoo1) : INTVAL (xfoo1))
       && INDEX_REGISTER_P (xfoo0, strict))
     return true;