diff mbox series

SUBREG_PROMOTED_VAR_P handling in expand_direct_optab_fn

Message ID 877ewt1ry3.fsf@linaro.org
State New
Headers show
Series SUBREG_PROMOTED_VAR_P handling in expand_direct_optab_fn | expand

Commit Message

Richard Sandiford Sept. 20, 2017, 12:21 p.m. UTC
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.

Comments

Jeff Law Oct. 13, 2017, 6:55 p.m. UTC | #1
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
diff mbox series

Patch

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)
     {