This is a fallout of the recent gigi changes: we can now set MEM_NOTRAP_P on 
the memory accesses more often in Ada.  This uncovered a problem in the ifcvt 
pass, which is hoisting a MEM_NOTRAP_P load before a test guarding it.  This 
is a known pattern and the fix is to use may_trap_or_fault_p to detect such 
memory accesses (like already done in noce_mem_write_may_trap_or_fault_p).

Tested on x86_64-suse-linux, applied on the mainline.


2011-09-26  Eric Botcazou  <ebotca...@adacore.com>

        * ifcvt.c (noce_try_cmove_arith): Use may_trap_or_fault_p in lieu of
        may_trap_p to detect loads that may trap of fault.


2011-09-26  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/opt21.adb: New test.
        * gnat.dg/opt21_pkg.ad[sb]: New helper.


-- 
Eric Botcazou
-- { dg-do run }
-- { dg-options "-O2" }

with System;
with Opt21_Pkg; use Opt21_Pkg;

procedure Opt21 is
   V : System.Address := Convert (null);
begin
   null;
end;
with System;

package Opt21_Pkg is

   type R is record
      Ptr : System.Address := System.Null_Address;
   end record;

   type Obj is access all R;

   function Get_Object (Object : not null access R) return System.Address;

   function Convert (W : Obj) return System.Address;

end Opt21_Pkg;
package body Opt21_Pkg is

   function Get_Object (Object : not null access R) return System.Address is
   begin
      return Object.Ptr;
   end;

   function Convert (W : Obj) return System.Address is
   begin
      if W = null then
         return System.Null_Address;
      else
         return Get_Object (W);
      end if;
   end;

end Opt21_Pkg;
Index: ifcvt.c
===================================================================
--- ifcvt.c	(revision 179167)
+++ ifcvt.c	(working copy)
@@ -1519,9 +1519,9 @@ noce_try_cmove_arith (struct noce_if_inf
     }
 
   /* ??? We could handle this if we knew that a load from A or B could
-     not fault.  This is also true if we've already loaded
+     not trap or fault.  This is also true if we've already loaded
      from the address along the path from ENTRY.  */
-  else if (may_trap_p (a) || may_trap_p (b))
+  else if (may_trap_or_fault_p (a) || may_trap_or_fault_p (b))
     return FALSE;
 
   /* if (test) x = a + b; else x = c - d;

Reply via email to