This fixes a wrong loop-invariant motion applied to an adjustment of the frame
pointer generated by expand_builtin_setjmp_receiver, e.g. for a target using
the SJLJ exception handling scheme.
Tested on x86-64/Linux, applied on the mainline.
2018-04-26 Eric Botcazou <ebotca...@adacore.com>
* loop-invariant.c (may_assign_reg_p): Return false for frame pointer.
2018-04-26 Eric Botcazou <ebotca...@adacore.com>
* gnat.dg/loop_optimization24.adb: New test.
--
Eric Botcazou
-- { dg-do run }
-- { dg-options "-O" }
procedure Loop_Optimization24 is
procedure Callback is
begin
raise Constraint_Error;
end;
type Thread_Name_Ptr is access constant String;
type Callback_Ptr is access procedure;
type Callback_Information is record
Name : Thread_Name_Ptr;
Proc : Callback_Ptr;
end record;
type Callback_List is array (Positive range <>) of Callback_Information;
Cbs : Callback_List
:= (1 => (Proc => Callback'access, name => new String'("Callback")),
2 => (Proc => Callback'access, name => new String'("Callback")));
begin
for Index in Cbs'Range loop
begin
if Cbs(Index).proc /= null then
Cbs(Index).proc.all;
end if;
exception
when Constraint_Error => null;
end;
end loop;
end;
Index: loop-invariant.c
===================================================================
--- loop-invariant.c (revision 259642)
+++ loop-invariant.c (working copy)
@@ -660,6 +660,9 @@ may_assign_reg_p (rtx x)
return (GET_MODE (x) != VOIDmode
&& GET_MODE (x) != BLKmode
&& can_copy_p (GET_MODE (x))
+ /* Do not mess with the frame pointer adjustments that can
+ be generated e.g. by expand_builtin_setjmp_receiver. */
+ && x != frame_pointer_rtx
&& (!REG_P (x)
|| !HARD_REGISTER_P (x)
|| REGNO_REG_CLASS (REGNO (x)) != NO_REGS));