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;