[LLVMdev] A create-distinct-item function with no (other) side effects

Kenneth Uildriks
Fri, 28 Aug 2009 13:40:32 -0000

Suppose I have some LLVM assembly like this:

declare i8* @CreateDistinctItem() nounwind

declare void @dumpBoolean(i1 %val)

define i32 @main()
{
 %var1 = call i8* CreateDistinctItem()
 %var2 = call i8* CreateDistinctItem()
 %isEqual = icmp eq i8* %val1, %val2
 call void @dumpBoolean(i1 %isEqual)
 ret i32 0
}

So far so good.  But if I take out the "call @dumpBoolean", the
optimizer still leaves me with two calls to CreateDistinctItem,
because it assumes that CreateDistinctItem might have side-effects.

Now if I add the "readonly" flag to CreateDistinctItem and put back
the "call @dumpBoolean", the optimizer now assumes that
CreateDistinctItem always returns the *same* item, and optimizes the
whole body of main down to:

define i32 @main()
{
 tail call void @dumpBoolean(i1 true)
 ret i32 0
}

which is totally wrong.

This is by design, of course, (CreateDistinctItem does not return the
same value given the same caller-visible global state) but I see no
way to declare a function that:

1. Returns a distinct item each time it's called,
2. Doesn't need to be called at all if its return value from that call
isn't used, and
3. Doesn't even need to be declared if its return value is *never* used.

If I happen to know about CreateDistinctItem at build time, I can
write a custom pass, of course, but I was wondering if there was an
easier way to get the standard optimizers to recognize it, or if y'all
think it's worthwhile to add an easier way.