[PATCH] Fix emit_conditional_move (PR target/84860)

Jakub Jelinek jakub@redhat.com
Wed Mar 14 22:35:00 GMT 2018


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.

--- 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



More information about the Gcc-patches mailing list