diff mbox series

Fix emit_conditional_move (PR target/84860)

Message ID 20180314221856.GL8577@tucnak
State New
Headers show
Series Fix emit_conditional_move (PR target/84860) | expand

Commit Message

Jakub Jelinek March 14, 2018, 10:18 p.m. UTC
Hi!

prepare_cmp_insn in some cases changes both the passed in comparison and the
comparison mode, e.g. by promoting the arguments from SFmode to DFmode etc.

In emit_conditional_move we call this in a loop, for (pass = 0; pass < 2; pass++)
and in each case construct comparison arguments as well as the comparison
passed to it from the original arguments (we have to after all, because when
not successful, we throw the whole insn sequence away), but use cmode which
the first iteration could have changed, on this testcase on powerpcspe with
-mcpu=8548 from SFmode to DFmode, so we ICE the second time, because the
arguments don't really match the comparison mode.

Fixed by passing it an address of a copy of the cmode parameter, so that the
second pass starts with the original cmode that matches the arguments again.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-03-14  Jakub Jelinek  <jakub@redhat.com>

	PR target/84860
	* optabs.c (emit_conditional_move): Pass address of cmode's copy
	rather than address of cmode as last argument to prepare_cmp_insn.

	* gcc.c-torture/compile/pr84860.c: New test.


	Jakub

Comments

Richard Biener March 15, 2018, 8:22 a.m. UTC | #1
On Wed, 14 Mar 2018, Jakub Jelinek wrote:

> Hi!
> 
> prepare_cmp_insn in some cases changes both the passed in comparison and the
> comparison mode, e.g. by promoting the arguments from SFmode to DFmode etc.
> 
> In emit_conditional_move we call this in a loop, for (pass = 0; pass < 2; pass++)
> and in each case construct comparison arguments as well as the comparison
> passed to it from the original arguments (we have to after all, because when
> not successful, we throw the whole insn sequence away), but use cmode which
> the first iteration could have changed, on this testcase on powerpcspe with
> -mcpu=8548 from SFmode to DFmode, so we ICE the second time, because the
> arguments don't really match the comparison mode.
> 
> Fixed by passing it an address of a copy of the cmode parameter, so that the
> second pass starts with the original cmode that matches the arguments again.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Richard.

> 2018-03-14  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR target/84860
> 	* optabs.c (emit_conditional_move): Pass address of cmode's copy
> 	rather than address of cmode as last argument to prepare_cmp_insn.
> 
> 	* gcc.c-torture/compile/pr84860.c: New test.
> 
> --- gcc/optabs.c.jj	2018-02-09 19:11:29.000000000 +0100
> +++ gcc/optabs.c	2018-03-14 09:22:31.707873477 +0100
> @@ -4345,9 +4345,10 @@ emit_conditional_move (rtx target, enum
>  	  save_pending_stack_adjust (&save);
>  	  last = get_last_insn ();
>  	  do_pending_stack_adjust ();
> +	  machine_mode cmpmode = cmode;
>  	  prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
>  			    GET_CODE (comparison), NULL_RTX, unsignedp,
> -			    OPTAB_WIDEN, &comparison, &cmode);
> +			    OPTAB_WIDEN, &comparison, &cmpmode);
>  	  if (comparison)
>  	    {
>  	      struct expand_operand ops[4];
> --- gcc/testsuite/gcc.c-torture/compile/pr84860.c.jj	2018-03-14 09:26:19.988883506 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr84860.c	2018-03-14 09:26:44.854884590 +0100
> @@ -0,0 +1,11 @@
> +/* PR target/84860 */
> +
> +void
> +foo (int x, int y)
> +{
> +  while (x < 1)
> +    {
> +      x = y;
> +      y = ((float)1 / 0) ? 2 : 0;
> +    }
> +}
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/optabs.c.jj	2018-02-09 19:11:29.000000000 +0100
+++ gcc/optabs.c	2018-03-14 09:22:31.707873477 +0100
@@ -4345,9 +4345,10 @@  emit_conditional_move (rtx target, enum
 	  save_pending_stack_adjust (&save);
 	  last = get_last_insn ();
 	  do_pending_stack_adjust ();
+	  machine_mode cmpmode = cmode;
 	  prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
 			    GET_CODE (comparison), NULL_RTX, unsignedp,
-			    OPTAB_WIDEN, &comparison, &cmode);
+			    OPTAB_WIDEN, &comparison, &cmpmode);
 	  if (comparison)
 	    {
 	      struct expand_operand ops[4];
--- gcc/testsuite/gcc.c-torture/compile/pr84860.c.jj	2018-03-14 09:26:19.988883506 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr84860.c	2018-03-14 09:26:44.854884590 +0100
@@ -0,0 +1,11 @@ 
+/* PR target/84860 */
+
+void
+foo (int x, int y)
+{
+  while (x < 1)
+    {
+      x = y;
+      y = ((float)1 / 0) ? 2 : 0;
+    }
+}