https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101373

--- Comment #4 from rguenther at suse dot de <rguenther at suse dot de> ---
On Fri, 9 Jul 2021, ebotcazou at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101373
> 
> --- Comment #3 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> > Eric, is it possible to write an equivalent testcase in Ada?
> 
> procedure P is
> 
>   function Foo (J : Integer) return Integer;
>   pragma Machine_Attribute (Foo, "const");
>   pragma Machine_Attribute (Foo, "noipa");
> 
>   function Foo (J : Integer) return Integer is
>   begin
>     if J /= 0 then
>       raise Constraint_Error;
>     end if;
>     return 0;
>   end;
> 
>   function Bar (A : access Integer; N : Integer) return Integer;
>   pragma Machine_Attribute (Bar, "noipa");
> 
>   function Bar (A : access Integer; N : Integer) return Integer is
>     Ret : Integer := 0;
>   begin
>     if N /= 0 then
>       Ret := Foo (N);
>       Ret := A.all;
>     end if;
>     Ret := Ret + A.all;
>     return Ret;
>   end;
> 
>   V : Integer;
>   pragma Volatile (V);
> 
> begin
>   V := Bar (null, 1);
> exception
>   when Constraint_Error => null;
> end;
> 
> compiled with -O2 -gnatp, but I cannot have the load hoisted in this case.

The issue I can see is that the middle-end does not consider
the Foo function 'const' (gimple_call_flags does not return ECF_CONST)
which is likely because the decl isn't TREE_READONLY and for 'const'
we nowhere lookup the actual attribute but handlers are expected to
mimic c-family/c-attribs.c handling.

With

diff --git a/gcc/gimple.c b/gcc/gimple.c
index 60a90667e4b..576b5df5cec 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1470,7 +1470,11 @@ gimple_call_flags (const gimple *stmt)
     {
       tree decl = gimple_call_fndecl (stmt);
       if (decl)
-       flags = flags_from_decl_or_type (decl);
+       {
+         flags = flags_from_decl_or_type (decl);
+         if (lookup_attribute ("const", DECL_ATTRIBUTES (decl)))
+           flags |= ECF_CONST;
+       }
       flags |= flags_from_decl_or_type (gimple_call_fntype (stmt));
     }

I see the access hoisted (but as said, the Ada FE should set
TREE_READONLY here).

I first thought that non-call exceptions might be the issue
(we wouldn't move A.all then), but non-call exceptions seem off.

Reply via email to