aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@orcam.me.uk>2021-04-21 23:33:25 +0200
committerMaciej W. Rozycki <macro@orcam.me.uk>2021-04-27 20:02:06 +0200
commitc605a8bf92708e81d771426a87b3baddc32082dd (patch)
tree36db3154cf76a963eb4fc8f92247e48b8fce11f5 /gcc/config
parentf3bfed3381be2e616599679b2a093b0ac8f1c5f7 (diff)
downloadgcc-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.c34
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;