(original) (raw)

On 10/9/2018 1:03 PM, Gleb Popov wrote:


On Tue, Oct 9, 2018 at 10:39 PM Friedman, Eli <efriedma@codeaurora.org> wrote:
On 10/9/2018 11:58 AM, Gleb Popov wrote:


On Tue, Oct 9, 2018 at 9:39 PM Friedman, Eli <efriedma@codeaurora.org> wrote:
On 10/9/2018 11:31 AM, Gleb Popov via llvm-dev wrote:
\> Hello LLVM Devs.
\>
\> In my compiler I attach some arbitrary data to functions by creating
\> BBs with inline assembly. However, these blocks are "unused" from LLVM
\> point of view and get erased from the function.
\>
\> To counter that I started adding checks for conditions that are
\> guaranteed to be true or false. I ended up with calling
\> @llvm.returnaddress(i32 0) intrinsic and comparing the result with 0\.
\> It worked well until in one function I had two such calls and SROA
\> replaced one of checks with constant 1 and erased the BB.
\>
\> I should probably stop trying to fool LLVM and "do it right", but
\> don't have any idea how. Note that I can't use global variables for a
\> reason, so the data has to be encoded in a BB using inline assembly.
\> All I need is just prevent optimizations from erasing it.

A reachable inline asm won't be erased if LLVM thinks it has some
side-effect. The simplest way to do this is the "sideeffect" marking
(in C++, it's a parameter to InlineAsm::get()). See
http://llvm.org/docs/LangRef.html#inline-assembler-expressions .

The problem is exactly reachability. Here is a simple example:

define void @foo() {
entry:
...
ret void
data:
call void asm sideeffect inteldialect ".byte 0xB2", "\~{dirflag},\~{fpsr},\~{flags}"()
call void asm sideeffect inteldialect ".byte 0xB9", "\~{dirflag},\~{fpsr},\~{flags}"()
...
}

To make "data" reachable I change entry's terminator to br %tobool, label %exit, label %data, where %tobool is a result of icmp eq that is always true. However, I can't come up with such a condition that didn't get erased by SROA.

Even if you manage to trick LLVM into emitting the inline asm, it won't be in a predictable location in the emitted assembly; some LLVM transforms will rearrange the code in a function.

Won't @llvm.returnaddress() always get me correct location of my inline asm block?

I'm very confused... how could you possibly use @llvm.returnaddress to return the address of a block of code that's never executed?

\-Eli
--   
Employee of Qualcomm Innovation Center, Inc.  
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project