[llvm-dev] Prevent LLVM optimizations from erasing unused basic blocks

Friedman, Eli via llvm-dev llvm-dev at lists.llvm.org
Tue Oct 9 13:42:30 PDT 2018


On 10/9/2018 1:03 PM, Gleb Popov wrote:
>
>
> On Tue, Oct 9, 2018 at 10:39 PM Friedman, Eli <efriedma at codeaurora.org 
> <mailto:efriedma at 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 at codeaurora.org <mailto:efriedma at 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20181009/19c75f80/attachment.html>


More information about the llvm-dev mailing list