summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-05-09 08:37:26 +0930
committerAlan Modra <amodra@gcc.gnu.org>2019-05-09 08:37:26 +0930
commit20d70cd2719815d9ea853314775ae5787648ece5 (patch)
treea39f6103672abd88d4ded48d127cb65355f1c2d7 /gcc/config/rs6000/rs6000.md
parent3407d1658f7d60cfb78293d61dfc21258efb0074 (diff)
[RS6000] PR89271, gcc.target/powerpc/vsx-simode2.c
This patch makes a number of corrections to rs6000_register_move_cost, adds a new register union class, GEN_OR_VSX_REGS, and adjusts insn alternative costs to suit. The patch initially just corrected register move cost when direct moves are available, but that resulted in regressions. Inspection of those regressions showed ALL_REGS being used as the register allocno class, which isn't ideal. gcc/doc/tm.texi says: "You should define a class for the union of two classes whenever some instruction allows both classes". Thus, define GEN_OR_VSX_REGS for the register allocator. (IRA wants to use the union of two register classes when the costs of the classes are below memory cost, which happens more often with the low direct move cost.) As per https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89271#c11 we ought to be returning the minimal cost for union classes. That can be done by rs6000_register_move_cost testing for vsx first, where the number of regs for a given mode might be smaller than the same mode in gprs, and changing the LINK_OR_CTR_REGS case to exclude SPEC_OR_GEN_REGS and NON_FLOAT_REGS. I removed the VECTOR_MEM_VSX_P test since that leads to silly results for scalar mode moves between altivec and float when TARGET_VSX. eg. rs6000_register_move_cost:, ret=2, mode=DF, from=FLOAT_REGS, to=FLOAT_REGS rs6000_register_move_cost:, ret=16, mode=DF, from=FLOAT_REGS, to=ALTIVEC_REGS rs6000_register_move_cost:, ret=2, mode=DF, from=FLOAT_REGS, to=VSX_REGS The patch also fixes wrong results for moves within and between any of the non-gpr, non-vsx special reg classes. The comment about "moving between two similar registers is just one instruction" is false. We can't move lr to ctr directly, for example. I believe the intent of the "reg_classes_intersect_p (to, from)" was to cover moves within float or altivec, so I moved that test inside the code handling vsx, and made sure the intersection wasn't anything besides vsx by masking off everything else. Masking isn't strictly necessary at the moment, but would be if we create a GEN_OR_ALTIVEC_REGS class some time in the future. TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS is needed for rs6000 in order to fix the 20% cactus_adm spec regression when using GEN_OR_VSX_REGS as an allocno class. It is similar to the aarch64 version but without any selection by regno mode if the best class is a union class. PR target/89271 * config/rs6000/rs6000.h (enum reg_class, REG_CLASS_NAMES), (REG_CLASS_CONTENTS): Add GEN_OR_VSX_REGS class. * config/rs6000/rs6000.c (rs6000_register_move_cost): Correct cost for general <-> vsx when direct moves are available. Cost union classes at minimal cost for any reg in the class. Correct calculation for moves between vsx, float, and altivec. Don't return a low cost for moves between special regs. Don't use hard coded register numbers. (TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS): Define. (rs6000_ira_change_pseudo_allocno_class): New function. * config/rs6000/rs6000.md (movsi_internal1, mov<mode>_internal), (movdi_internal32, movdi_internal64): Remove '*' from vsx register alternatives. (movsi_internal1): Don't disparage vector alternatives. (mov<mode>_internal): Likewise, excepting alternative that will be split. * config/rs6000/vsx.md (vsx_splat_<mode>_reg): Don't disparage we <- b alternative. From-SVN: r271022
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md26
1 files changed, 13 insertions, 13 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 411d7f0d352..8da7aba4080 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -6830,10 +6830,10 @@
;; MF%1 MT%0 NOP
(define_insn "*movsi_internal1"
[(set (match_operand:SI 0 "nonimmediate_operand"
- "=r, r, r, ?*wI, ?*wH,
- m, ?Z, ?Z, r, r,
- r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
- ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
+ "=r, r, r, wI, wH,
+ m, Z, Z, r, r,
+ r, wIwH, wJwK, wJwK, wu,
+ wJwK, wH, wK, wIwH, r,
r, *h, *h")
(match_operand:SI 1 "input_operand"
@@ -7104,13 +7104,13 @@
;; MTVSRWZ MF%1 MT%1 NOP
(define_insn "*mov<mode>_internal"
[(set (match_operand:QHI 0 "nonimmediate_operand"
- "=r, r, ?*wJwK, m, Z, r,
- ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
- ?*wJwK, r, *c*l, *h")
+ "=r, r, wJwK, m, Z, r,
+ wJwK, wJwK, wJwK, wK, ?wK, r,
+ wJwK, r, *c*l, *h")
(match_operand:QHI 1 "input_operand"
"r, m, Z, r, wJwK, i,
- wJwK, O, wM, wB, wS, ?*wJwK,
+ wJwK, O, wM, wB, wS, wJwK,
r, *h, r, 0"))]
"gpc_reg_operand (operands[0], <MODE>mode)
@@ -8671,8 +8671,8 @@
[(set (match_operand:DI 0 "nonimmediate_operand"
"=Y, r, r, m, ^d, ^d,
r, wY, Z, ^wb, $wv, ^wi,
- *wo, *wo, *wv, *wi, *wi, *wv,
- *wv")
+ wo, wo, wv, wi, *i, wv,
+ wv")
(match_operand:DI 1 "input_operand"
"r, Y, r, ^d, m, ^d,
@@ -8751,9 +8751,9 @@
[(set (match_operand:DI 0 "nonimmediate_operand"
"=YZ, r, r, r, r, r,
m, ^d, ^d, wY, Z, $wb,
- $wv, ^wi, *wo, *wo, *wv, *wi,
- *wi, *wv, *wv, r, *h, *h,
- ?*r, ?*wg, ?*r, ?*wj")
+ $wv, ^wi, wo, wo, wv, wi,
+ wi, wv, wv, r, *h, *h,
+ ?r, ?wg, ?r, ?wj")
(match_operand:DI 1 "input_operand"
"r, YZ, r, I, L, nF,