diff mbox

Fix PR rtl-optimization/81424

Message ID 40551004.PRfSaV3QlZ@polaris
State New
Headers show

Commit Message

Eric Botcazou July 16, 2017, 10:08 p.m. UTC
This is a regression present on the mainline and 7 branch: the compiler aborts 
on the attached testcase for x86 at -O2 -march=i686:

+===========================GNAT BUG DETECTED==============================+
| 8.0.0 20170716 (experimental) [trunk revision 250237] (x86_64-suse-linux) 
GCC error:|
| in emit_move_insn, at expr.c:3704                                        |
| Error detected around opt65.adb:30:4  

because it is trying to generate a move from HImode to SImode.  The problem 
comes from the relatively new code in prepare_cmp_insn:

  /* Don't allow operands to the compare to trap, as that can put the
     compare and branch in different basic blocks.  */
  if (cfun->can_throw_non_call_exceptions)
    {
      if (may_trap_p (x))
	x = force_reg (mode, x);
      if (may_trap_p (y))
	y = force_reg (mode, y);
    }

which assumes that "mode" is the mode of "x" and "y".  While that's true on 
entry to the function, that can be wrong at this point because just above:

      x = result;
      y = const0_rtx;
      mode = TYPE_MODE (integer_type_node);
      methods = OPTAB_LIB_WIDEN;
      unsignedp = false;

can change it to something totally different.  That's why the attached fix 
replaces the call to force_reg with a call to copy_to_reg, which should be OK 
since the mode-less RTXes, i.e. constants, cannot satisfy may_trap_p.

Bootstrapped/regtested on x86_64-suse-linux, applied on mainline and 7 branch.


2017-07-16  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/81424
	* optabs.c (prepare_cmp_insn): Use copy_to_reg instead of force_reg
	to remove potential trapping from operands if -fnon-call-exceptions.


2017-07-16  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/opt65.adb: New test.
diff mbox

Patch

Index: optabs.c
===================================================================
--- optabs.c	(revision 250226)
+++ optabs.c	(working copy)
@@ -3844,9 +3844,9 @@  prepare_cmp_insn (rtx x, rtx y, enum rtx
   if (cfun->can_throw_non_call_exceptions)
     {
       if (may_trap_p (x))
-	x = force_reg (mode, x);
+	x = copy_to_reg (x);
       if (may_trap_p (y))
-	y = force_reg (mode, y);
+	y = copy_to_reg (y);
     }
 
   if (GET_MODE_CLASS (mode) == MODE_CC)