diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-10-22 21:41:57 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-10-22 21:41:57 +0000 |
commit | b7753f75ea1644c3d18dcfaf9878fb5ec1460c6a (patch) | |
tree | d028c05d20720e17819a5d21a031798677278e6a | |
parent | bb06a2d85567fc0d5d82d28629ebc54453c35f17 (diff) | |
download | gcc-b7753f75ea1644c3d18dcfaf9878fb5ec1460c6a.zip gcc-b7753f75ea1644c3d18dcfaf9878fb5ec1460c6a.tar.gz gcc-b7753f75ea1644c3d18dcfaf9878fb5ec1460c6a.tar.bz2 |
SUBREG_PROMOTED_VAR_P handling in expand_direct_optab_fn
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.
2017-09-19 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.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r253992
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/internal-fn.c | 10 |
2 files changed, 16 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ebaf8b3..64ee44e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,13 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * internal-fn.c (expand_direct_optab_fn): Don't assign directly + to a SUBREG_PROMOTED_VAR. + +2017-10-22 Richard Sandiford <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * cfgexpand.c (expand_debug_expr): Use GET_MODE_UNIT_PRECISION. (expand_debug_source_expr): Likewise. * combine.c (combine_simplify_rtx): Likewise. diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index ce9e8bb..94873c2 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -2606,7 +2606,15 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab, 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) { |