Handle a null lhs in expand_direct_optab_fn (PR85862)

Message ID 878t8cmb2a.fsf@linaro.org
State New
Headers show
Series
  • Handle a null lhs in expand_direct_optab_fn (PR85862)
Related show

Commit Message

Richard Sandiford May 22, 2018, 6:58 a.m.
This PR showed that the normal function for expanding directly-mapped
internal functions didn't handle the case in which the call was only
being kept for its side-effects.

Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
and x86_64-linux-gnu.  OK to install?

Richard


2018-05-22  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	PR middle-end/85862
	* internal-fn.c (expand_direct_optab_fn): Cope with a null lhs.

gcc/testsuite/
	PR middle-end/85862
	* gcc.dg/torture/pr85862.c: New test.

Comments

Richard Biener May 22, 2018, 8:59 a.m. | #1
On Tue, May 22, 2018 at 8:58 AM Richard Sandiford <
richard.sandiford@linaro.org> wrote:

> This PR showed that the normal function for expanding directly-mapped

> internal functions didn't handle the case in which the call was only

> being kept for its side-effects.


> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf

> and x86_64-linux-gnu.  OK to install?


OK.

Richard.

> Richard



> 2018-05-22  Richard Sandiford  <richard.sandiford@linaro.org>


> gcc/

>          PR middle-end/85862

>          * internal-fn.c (expand_direct_optab_fn): Cope with a null lhs.


> gcc/testsuite/

>          PR middle-end/85862

>          * gcc.dg/torture/pr85862.c: New test.


> Index: gcc/internal-fn.c

> ===================================================================

> --- gcc/internal-fn.c   2018-05-18 09:26:37.734714355 +0100

> +++ gcc/internal-fn.c   2018-05-22 07:56:26.130013854 +0100

> @@ -2891,14 +2891,15 @@ expand_direct_optab_fn (internal_fn fn,

>     insn_code icode = direct_optab_handler (optab, TYPE_MODE

(types.first));

>     tree lhs = gimple_call_lhs (stmt);

> -  tree lhs_type = TREE_TYPE (lhs);

> -  rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);

> +  rtx lhs_rtx = NULL_RTX;

> +  if (lhs)

> +    lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);


>     /* 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))

> +  if (dest && GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))

>       dest = NULL_RTX;


>     create_output_operand (&ops[0], dest,

insn_data[icode].operand[0].mode);
> @@ -2917,7 +2918,7 @@ expand_direct_optab_fn (internal_fn fn,

>       }


>     expand_insn (icode, nargs + 1, ops);

> -  if (!rtx_equal_p (lhs_rtx, ops[0].value))

> +  if (lhs_rtx && !rtx_equal_p (lhs_rtx, ops[0].value))

>       {

>         /* If the return value has an integral type, convert the

instruction
>           result to that type.  This is useful for things that return an

> @@ -2931,7 +2932,7 @@ expand_direct_optab_fn (internal_fn fn,

>            /* If this is a scalar in a register that is stored in a wider

>               mode than the declared mode, compute the result into its

>               declared mode and then convert to the wider mode.  */

> -         gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));

> +         gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));

>            rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);

>            convert_move (SUBREG_REG (lhs_rtx), tmp,

>                          SUBREG_PROMOTED_SIGN (lhs_rtx));

> @@ -2940,7 +2941,7 @@ expand_direct_optab_fn (internal_fn fn,

>          emit_move_insn (lhs_rtx, ops[0].value);

>         else

>          {

> -         gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));

> +         gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));

>            convert_move (lhs_rtx, ops[0].value, 0);

>          }

>       }

> Index: gcc/testsuite/gcc.dg/torture/pr85862.c

> ===================================================================

> --- /dev/null   2018-04-20 16:19:46.369131350 +0100

> +++ gcc/testsuite/gcc.dg/torture/pr85862.c      2018-05-22

07:56:26.131013803 +0100
> @@ -0,0 +1,9 @@

> +/* { dg-do compile } */

> +/* { dg-additional-options "-fexceptions -fnon-call-exceptions" } */

> +/* { dg-additional-options "-fexceptions -fnon-call-exceptions -mfma" {

target i?86-*-* x86_64-*-* } } */
> +

> +void

> +ki (double nq)

> +{

> +  double no = 1.1 * nq - nq;

> +}

Patch

Index: gcc/internal-fn.c
===================================================================
--- gcc/internal-fn.c	2018-05-18 09:26:37.734714355 +0100
+++ gcc/internal-fn.c	2018-05-22 07:56:26.130013854 +0100
@@ -2891,14 +2891,15 @@  expand_direct_optab_fn (internal_fn fn,
   insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
 
   tree lhs = gimple_call_lhs (stmt);
-  tree lhs_type = TREE_TYPE (lhs);
-  rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+  rtx lhs_rtx = NULL_RTX;
+  if (lhs)
+    lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
 
   /* 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))
+  if (dest && GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))
     dest = NULL_RTX;
 
   create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
@@ -2917,7 +2918,7 @@  expand_direct_optab_fn (internal_fn fn,
     }
 
   expand_insn (icode, nargs + 1, ops);
-  if (!rtx_equal_p (lhs_rtx, ops[0].value))
+  if (lhs_rtx && !rtx_equal_p (lhs_rtx, ops[0].value))
     {
       /* If the return value has an integral type, convert the instruction
 	 result to that type.  This is useful for things that return an
@@ -2931,7 +2932,7 @@  expand_direct_optab_fn (internal_fn fn,
 	  /* If this is a scalar in a register that is stored in a wider
 	     mode than the declared mode, compute the result into its
 	     declared mode and then convert to the wider mode.  */
-	  gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
+	  gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
 	  rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
 	  convert_move (SUBREG_REG (lhs_rtx), tmp,
 			SUBREG_PROMOTED_SIGN (lhs_rtx));
@@ -2940,7 +2941,7 @@  expand_direct_optab_fn (internal_fn fn,
 	emit_move_insn (lhs_rtx, ops[0].value);
       else
 	{
-	  gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
+	  gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
 	  convert_move (lhs_rtx, ops[0].value, 0);
 	}
     }
Index: gcc/testsuite/gcc.dg/torture/pr85862.c
===================================================================
--- /dev/null	2018-04-20 16:19:46.369131350 +0100
+++ gcc/testsuite/gcc.dg/torture/pr85862.c	2018-05-22 07:56:26.131013803 +0100
@@ -0,0 +1,9 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-fexceptions -fnon-call-exceptions" } */
+/* { dg-additional-options "-fexceptions -fnon-call-exceptions -mfma" { target i?86-*-* x86_64-*-* } } */
+
+void
+ki (double nq)
+{
+  double no = 1.1 * nq - nq;
+}