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 <ebotca...@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 <ebotca...@adacore.com>
* gnat.dg/opt65.adb: New test.
--
Eric Botcazou
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)
-- { dg-do run }
-- { dg-options "-O2" }
with Ada.Command_Line; use Ada.Command_Line;
procedure Opt65 is
procedure Check_Version_And_Help (Version_String : String) is
Help_Switch_Present : Boolean := False;
Next_Arg : Natural := 1;
begin
while Next_Arg <= Argument_Count loop
declare
Next_Argv : constant String := Argument (Next_Arg);
begin
if Next_Argv = "--help" then
Help_Switch_Present := True;
end if;
Next_Arg := Next_Arg + 1;
end;
end loop;
if Help_Switch_Present then
raise Program_Error;
end if;
end;
begin
Check_Version_And_Help ("version");
end;