[LLVMbugs] [Bug 22853] New: A limitation of LLVM with regard to marking sret functions as pure/readonly.

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Mar 9 08:23:03 PDT 2015


http://llvm.org/bugs/show_bug.cgi?id=22853

            Bug ID: 22853
           Summary: A limitation of LLVM with regard to marking sret
                    functions as pure/readonly.
           Product: new-bugs
           Version: 3.4
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: nick at indigorenderer.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Hi all,
I have identified what seems to be a limitation of LLVM with regard to marking
'sret functions' as pure/readonly.

For some context - I have some JITed code produced by LLVM, and that code calls
back into the host application occasionally.
Since my language is purely functional, no functions have side-effects. 
Therefore I would like to be able to cache the value of identical calls back
into the host application, e.g.
if f is a function exported by the host application,
f(1) + f(1)
should only call f(1) once, then cache and reuse the value instead of making a
second call.

The problem is is that some of the exported functions need to return
structures.  As such a pointer to the returned structure is passed as the first
argument and marked with the sret attribute.
However due to this, that function can no longer be marked with the 'readonly'
attribute (as it needs to write to the returned structure).  (I tried marking
the function as readonly anyway and the function is incorrectly compiled to
'ret void' or similar)

There seems to be a similar problem with C++ code:

------------------------------------
class s
{
  public:
  float x;
  float y;
};

extern s g(void* env)  __attribute__ ((pure));


float func(float x, void* env)
{
  return g(env).x + g(env).x;
}
------------------------------------

Compiles the function 'func' to just make a single call to g.  Note that 's' is
returned directly instead of being converted into an SRET arg, due to the small
size of the class 's'.  See http://goo.gl/ezXxrI

If we make the class bigger, so it gets returned by SRET:

----------------------------------
class s
{
  public:
  float x;
  float y;

  int a;
  int b;
  int c;
};

extern s g(void* env)  __attribute__ ((pure));


float func(float x, void* env)
{
  return g(env).x + g(env).x;
}
---------------------------------

Then LLVM compiles 'func' to have 2 calls to g, and g is no longer marked as
'readonly'  See http://goo.gl/YW0n3V

So it doesn't seem possible to me to mark an SRET function as readonly.
To me this seems like a problem.

One way to fix this could be to change the semantics of the readonly attribute
- it could be changed to allow writing through the SRET pointer argument only. 

Discussed on LLVMDev here:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-March/083137.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150309/0c12db49/attachment.html>


More information about the llvm-bugs mailing list