On Tue, May 22, 2018 at 8:58 AM Richard Sandiford < richard.sandif...@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.sandif...@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; > +}