Message ID | 878t8cmb2a.fsf@linaro.org |
---|---|
State | Accepted |
Commit | 440ed9f839a068948c72441eda2ef3da515f4656 |
Headers | show |
Series | Handle a null lhs in expand_direct_optab_fn (PR85862) | expand |
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; > +}
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; +}