diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 2f15a053075..ed24d96006f 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -8409,7 +8409,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, pointer, so it works with both GPRs and VSX registers. */ /* Make sure both operands are registers. */ else if (GET_CODE (x) == PLUS - && (mode != TImode || !TARGET_QUAD_MEMORY)) + && (mode != TImode || !TARGET_VSX_TIMODE)) return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)), force_reg (Pmode, XEXP (x, 1))); @@ -9418,12 +9418,16 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict) return 1; } - /* For TImode, if we have load/store quad and TImode in VSX registers, only - allow register indirect addresses. This will allow the values to go in - either GPRs or VSX registers without reloading. The vector types would - tend to go into VSX registers, so we allow REG+REG, while TImode seems + /* For TImode, if we have TImode in VSX registers, only allow register + indirect addresses. This will allow the values to go in either GPRs + or VSX registers without reloading. The vector types would tend to + go into VSX registers, so we allow REG+REG, while TImode seems somewhat split, in that some uses are GPR based, and some VSX based. */ - if (mode == TImode && TARGET_QUAD_MEMORY && TARGET_VSX_TIMODE) + /* FIXME: We could loosen this by changing the following to + if (mode == TImode && TARGET_QUAD_MEMORY && TARGET_VSX_TIMODE) + but currently we cannot allow REG+REG addressing for TImode. See + PR72827 for complete details on how this ends up hoodwinking DSE. */ + if (mode == TImode && TARGET_VSX_TIMODE) return 0; /* If not REG_OK_STRICT (before reload) let pass any stack offset. */ if (! reg_ok_strict @@ -39097,10 +39101,15 @@ rtx_is_swappable_p (rtx op, unsigned int *special) handling. */ if (GET_CODE (XEXP (op, 0)) == CONST_INT) return 1; - else if (GET_CODE (XEXP (op, 0)) == REG + else if (REG_P (XEXP (op, 0)) && GET_MODE_INNER (GET_MODE (op)) == GET_MODE (XEXP (op, 0))) /* This catches V2DF and V2DI splat, at a minimum. */ return 1; + else if (GET_CODE (XEXP (op, 0)) == TRUNCATE + && REG_P (XEXP (XEXP (op, 0), 0)) + && GET_MODE_INNER (GET_MODE (op)) == GET_MODE (XEXP (op, 0))) + /* This catches splat of a truncated value. */ + return 1; else if (GET_CODE (XEXP (op, 0)) == VEC_SELECT) /* If the duplicated item is from a select, defer to the select processing to see if we can change the lane for the splat. */ |