Commit 440ed9f8 by Richard Sandiford Committed by Richard Sandiford

Handle a null lhs in expand_direct_optab_fn (PR85862)

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.

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.

From-SVN: r260504
parent 81d5198d
2018-05-22 Richard Sandiford <richard.sandiford@linaro.org>
PR middle-end/85862
* internal-fn.c (expand_direct_optab_fn): Cope with a null lhs.
2018-05-22 Richard Biener <rguenther@suse.de> 2018-05-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/85834 PR tree-optimization/85834
......
...@@ -2891,14 +2891,15 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab, ...@@ -2891,14 +2891,15 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first)); insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
tree lhs = gimple_call_lhs (stmt); tree lhs = gimple_call_lhs (stmt);
tree lhs_type = TREE_TYPE (lhs); rtx lhs_rtx = NULL_RTX;
rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); if (lhs)
lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
/* Do not assign directly to a promoted subreg, since there is no /* Do not assign directly to a promoted subreg, since there is no
guarantee that the instruction will leave the upper bits of the guarantee that the instruction will leave the upper bits of the
register in the state required by SUBREG_PROMOTED_SIGN. */ register in the state required by SUBREG_PROMOTED_SIGN. */
rtx dest = lhs_rtx; 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; dest = NULL_RTX;
create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode); create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
...@@ -2917,7 +2918,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab, ...@@ -2917,7 +2918,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
} }
expand_insn (icode, nargs + 1, ops); 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 /* If the return value has an integral type, convert the instruction
result to that type. This is useful for things that return an result to that type. This is useful for things that return an
...@@ -2931,7 +2932,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab, ...@@ -2931,7 +2932,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
/* If this is a scalar in a register that is stored in a wider /* If this is a scalar in a register that is stored in a wider
mode than the declared mode, compute the result into its mode than the declared mode, compute the result into its
declared mode and then convert to the wider mode. */ 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); rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
convert_move (SUBREG_REG (lhs_rtx), tmp, convert_move (SUBREG_REG (lhs_rtx), tmp,
SUBREG_PROMOTED_SIGN (lhs_rtx)); SUBREG_PROMOTED_SIGN (lhs_rtx));
...@@ -2940,7 +2941,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab, ...@@ -2940,7 +2941,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
emit_move_insn (lhs_rtx, ops[0].value); emit_move_insn (lhs_rtx, ops[0].value);
else 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); convert_move (lhs_rtx, ops[0].value, 0);
} }
} }
......
2018-05-22 Richard Sandiford <richard.sandiford@linaro.org>
PR middle-end/85862
* gcc.dg/torture/pr85862.c: New test.
2018-05-22 Richard Biener <rguenther@suse.de> 2018-05-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/85834 PR tree-optimization/85834
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment