[llvm-dev] Dereferenceable load semantics & LICM

Sanjoy Das via llvm-dev
Wed, 05 Apr 2017 16:30:29 -0000

Hi Piotr,

On Mon, Apr 3, 2017 at 2:01 PM, Piotr Padlewski
<piotr.padlewski at gmail.com> wrote:
>> I don't see any way to model it right now in LLVM, but I see a one
simple
>> solution:
>>  add extra information to the metadata nodes indicating that this
property
>> is non-local:
>>
>> %0 = load... %p, !invariant.group !1, !dereferenceable !2
>> %1 = load ... %0, !invariant.load !0, !dereferenceable !2
>>
>> !0 = !{!"GlobalProperty"}
>> !1 = !{!"MyType", !"GlobalProperty"}
>> !2 = !{i64 8, !"GlobalProperty}
>>
>> With that we would strip only the metadata not containing this
>> information.
>>
>> For devirtualization it would make sense with invariant.load,
>> invariant.group and dereferenceable.
>>
>> What do you think about this idea?

I'm sorry for being *this* annoying, but I'm not on board with this.  :)

I think this will run into the same dead-code-can-affect-behavior
issue discussed in https://reviews.llvm.org/D20116.

Specifically, if your program is:

if (false) {
  ptr = load i8*, i8** %ptrptr, !dereferenceable !{i64 8, !"GlobalProperty}
  // ptr is not actually dereferenceable, even the load above has UB
  // (since the metadata is "wrong"), but it is never executed so all
is well.
  int val = *ptr;
}

then you could transform it to

ptr = load i8*, i8** %ptrptr, !dereferenceable !{i64 8, !"GlobalProperty}
// ptr is not actually dereferenceable
int val = *ptr;
if (false) {
}

and you'd have gone from a program with no UB to one with UB.

-- Sanjoy