aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-10-22 21:41:57 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-10-22 21:41:57 +0000
commitb7753f75ea1644c3d18dcfaf9878fb5ec1460c6a (patch)
treed028c05d20720e17819a5d21a031798677278e6a
parentbb06a2d85567fc0d5d82d28629ebc54453c35f17 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/internal-fn.c10
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)
{