[LLVMdev] [cfe-dev] Clang devirtualization proposal

Sanjoy Das sanjoy at playingwithpointers.com
Sat Aug 1 12:27:41 PDT 2015


On Sat, Aug 1, 2015 at 6:33 AM, Hal Finkel <hfinkel at anl.gov> wrote:
> ----- Original Message -----
>> From: "Sanjoy Das" <sanjoy at playingwithpointers.com>
>> To: "Reid Kleckner" <rnk at google.com>
>> Cc: "Piotr Padlewski" <prazek at google.com>, "cfe-dev at cs.uiuc.edu Developers" <cfe-dev at cs.uiuc.edu>, "LLVM Developers
>> Mailing List" <llvmdev at cs.uiuc.edu>
>> Sent: Saturday, August 1, 2015 1:22:50 AM
>> Subject: Re: [LLVMdev] [cfe-dev] Clang devirtualization proposal
>>
>> On Fri, Jul 31, 2015 at 6:18 PM, Reid Kleckner <rnk at google.com>
>> wrote:
>> > Consider this pseudo-IR and some possible transforms that I would
>> > expect to
>> > be semantics preserving:
>> >
>> > void f(i32* readonly %a, i32* %b) {
>> >   llvm.assume(%a == %b)
>> >   store i32 42, i32* %b
>> > }
>> >   ...
>> >   %p = alloca i32
>> >   store i32 13, i32* %p
>> >   call f(i32* readonly %p, i32* %p)
>> >   %r = load i32, i32* %p
>> >
>> > ; Propagate llvm.assume info
>> > void f(i32* readonly %a, i32* %b) {
>> >   store i32 42, i32* %a
>> > }
>> >   ...
>> >   %p = alloca i32
>> >   store i32 13, i32* %p
>> >   call f(i32* readonly %p, i32* %p)
>> >   %r = load i32, i32* %p
>>
>> I'd say this first transformation is incorrect.  `readonly` is
>> effectively part of `%a`'s "type" as it constrains and affects the
>> operations you can do on `%a`. Even if `%b` is bitwise equivalent to
>> `%a` at runtime, it is "type incompatible" to replace `%a` with `%b`.
>>
>> This is similar to how you cannot replace `store i32 42, i32
>> addrspace(1)* %a` with `store i32 42, i32 addrspace(2)* %b`, even if
>> you can prove `ptrtoint %a` == `ptrtoint %b` -- the nature of `store`
>> is dependent on the type of the pointer you store through.
>>
>> The glitch in LLVM IR right now is that the `readonly`ness of `%a` is
>> not modeled in the type system, when I think it should be. An `i32
>> readonly*` should be a different type from `i32*`.  In practice this
>> may be non-trivial to get right (for instance `phi`s and `selects`
>> will either have to do a type merge, or we'd have to have explicit
>> type operators at the IR level).
>
> We could do this, but then we'd need to promote these things to first-class parts of the type system (and I'd need to put further thought about how this interacts with dynamically-true properties at callsites and inlining).
>
> The alternative way of looking at it, which is true today, is that @llvm.assume is not removed even when its information is 'used'. It appears, given this example, that this is actually required for correctness, and that dead-argument elimination needs to specifically not ignore effectively-ephemeral values/arguments.

I don't think the problem has to do with llvm.assume specifically.
This is a problematic example too:

void f(i32* readonly %a, i32* %b) {
   if (%a != %b) then unreachable;

   store i32 42, i32* %b
}

-- Sanjoy




More information about the llvm-dev mailing list