Message ID | 877ewt1ry3.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | SUBREG_PROMOTED_VAR_P handling in expand_direct_optab_fn | expand |
On 09/20/2017 06:21 AM, Richard Sandiford wrote: > This is needed by the later SVE LAST reductions, where an 8-bit > or 16-bit result is zero- rather than sign-extended to 32 bits. > I think it could occur in other situations too. > > Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linus-gnu. > OK to install? > > Richard > > > 2017-09-20 Richard Sandiford <richard.sandiford@linaro.org> > Alan Hayward <alan.hayward@arm.com> > David Sherwood <david.sherwood@arm.com> > > gcc/ > * internal-fn.c (expand_direct_optab_fn): Don't assign directly > to a SUBREG_PROMOTED_VAR. OK. jeff
Index: gcc/internal-fn.c =================================================================== --- gcc/internal-fn.c 2017-08-30 12:18:46.627041352 +0100 +++ gcc/internal-fn.c 2017-09-20 13:19:54.460290742 +0100 @@ -2606,7 +2606,15 @@ expand_direct_optab_fn (internal_fn fn, tree lhs = gimple_call_lhs (stmt); tree lhs_type = TREE_TYPE (lhs); rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); - create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode); + + /* Do not assign directly to a promoted subreg, since there is no + guarantee that the instruction will leave the upper bits of the + register in the state required by SUBREG_PROMOTED_SIGN. */ + rtx dest = lhs_rtx; + if (GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest)) + dest = NULL_RTX; + + create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode); for (unsigned int i = 0; i < nargs; ++i) {