diff options
author | Maciej W. Rozycki <macro@orcam.me.uk> | 2021-04-21 23:33:25 +0200 |
---|---|---|
committer | Maciej W. Rozycki <macro@orcam.me.uk> | 2021-04-27 20:02:06 +0200 |
commit | c605a8bf92708e81d771426a87b3baddc32082dd (patch) | |
tree | 36db3154cf76a963eb4fc8f92247e48b8fce11f5 /gcc/config | |
parent | f3bfed3381be2e616599679b2a093b0ac8f1c5f7 (diff) | |
download | gcc-c605a8bf92708e81d771426a87b3baddc32082dd.zip gcc-c605a8bf92708e81d771426a87b3baddc32082dd.tar.gz gcc-c605a8bf92708e81d771426a87b3baddc32082dd.tar.bz2 |
VAX: Accept ASHIFT in address expressions
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.
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/vax/vax.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 870af2b..96a7925 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -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; |