Hi, After much discussion we've concluded that the first patch isn't salvageable. There are register assignments for which we can't fix up the addressing legally after reload using such tricks (for example: base=r31, offset=r0).
This patch (suggested by Michael Meissner) instead prevents the problem by disallowing reg+reg addressing for TImode, allowing D-form addressing to be used for the separate stores of the GPRs. This is not an ideal permanent solution, because it disallows reg+reg addressing not only for TImode in GPRs, but also for TImode in VSRs. Our intent is to work on a solution to provide a scratch register via secondary reload, but this may take some time. Thus I'd like to submit this patch as a short-term solution for the bootstrap problem until then. I plan to do a performance evaluation of this patch for informational purposes, but I don't expect much change, and the results won't affect our choice to handle this properly in secondary reload. Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no regressions, and the gnattools now build properly so that the ada bootstrap succeeds. Is this ok for trunk? Thanks, Bill 2016-08-31 Bill Schmidt <wschm...@linux.vnet.ibm.com> Michael Meissner <meiss...@linux.vnet.ibm.com> PR target/72827 * config/rs6000/rs6000.c (rs6000_legitimize_address): Avoid reg+reg addressing for TImode. (rs6000_legitimate_address_p): Only allow register indirect addressing for TImode, even without TARGET_QUAD_MEMORY. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 239871) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -8409,7 +8409,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBU 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, rt 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