[LLVMdev] GlobalValues appear in their own use lists?

Chris Lattner
Mon, 10 Mar 2014 22:36:59 -0000

On Mar 10, 2014, at 11:59 AM, Sean Callanan <scallanan at apple.com>
wrote:

> In the following IR module:
> –
> define i8 @foo() #0 {
> entry:
>   %call0 = call i8 @bar()
>   ret i8 %call0
> }
>
> declare i8 @bar() #1
> –
> @bar() gets marked as its own user in top-of-tree LLVM.  I patched the
Verifier to check it (but didn’t commit the patch):
> –
> Index: lib/IR/Verifier.cpp
> ==================================================================> ---
lib/IR/Verifier.cpp	(revision 203468)
> +++ lib/IR/Verifier.cpp	(working copy)
> @@ -360,6 +360,11 @@
>            "Global is external, but doesn't have external or weak
linkage!",
>            &GV);
>
> +  for (Value::const_use_iterator UI = GV.use_begin(), UE = GV.use_end();
> +       UI != UE; ++UI) {
> +    Assert1(*UI != &GV, "Global values cannot be their own
uses!", &GV);
> +  }
> +
>    Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
>            "Only global variables can have appending linkage!",
&GV);
> –
> Is it ever reasonable for a global value to be its own use?

No, this is never possible.  The only globals that have uses are GlobalVariables
and Aliases, and both of them require that the operand have a different type
than the global itself (one level of pointer is removed).  Since LLVM 2.0, it
isn’t possible to have a "pointer to itself” type anymore.

>  If not, can I commit this patch?

Sure, but note that it won’t apply to mainline.  use iterators got reworked to
be C++’11ified and got renamed in the process.

> This really causes problems for LLDB in various parts of our logic,
including infinite loops when following use chains, but a major issue is that we
try to strip certain global values out of the module, and if they’re their own
uses then that doesn’t work because we can never eliminate the last use.

Are you sure that they are direct uses like this?  If *is* possible to have
global variables that use themselves through constant expressions.  A C example
would be something like:

extern void *G;
void *G = &G;

which compiles to:

@G = global i8* bitcast (i8** @G to i8*), align 8

-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20140310/4744da4a/attachment.html>