[LLVMdev] Need Help With Verifier

Chris Lattner sabre at nondot.org
Fri Nov 21 11:50:01 PST 2003


On Fri, 21 Nov 2003, Reid Spencer wrote:

> While it is great that LLVM has an IR Verifier, its a little troublesome
> to use because it separates the point of detection from the source of
> the problem. That is, the verifier gets run on a module or function
> after its been built. By that point, the compiler's state has moved past

Well, you can run the verifier any time you want: there is a verifier
pass, or you can manually call verifyModule/verifyFunction.  Aside from
that, I'm not sure exactly what we could add...

> Now, here's the specific problem. When the verifier runs, I get:
>
> Stored value is not of right type for indices!
> void <badref>
> type[1024 x int] [1024 x int]

WOW.  That is an absolutely horrible error message.  I've fixed both the
error message itself (it should now read "Stored value type does not
match pointer operand type!"), and the things being printed.  The first
one is supposed to print the Store instruction itself (allowing you to
actually find the thing), but didn't due to an unrelated change in the
verifier recently. :(

Try it now.

> So, I've tracked this down to being one of three StoreInst instructions.
> In particular, its one of the two StoreInst instructions I generate that
> write into a global array of int (Stacker's global stack).

Ok.

> Here's what I don't understand:
>
> The first operand of the StoreInst is being reported as "void <badref>".
> First, I don't really know what this means but I assume its just an
> invalid references of some sort.

Actually, that is the store instruction itself.  The verifier was
mistakenly passing the store into 'WriteAsOperand', which, since it
returns void, isn't a valid reference.  Now it should print the actual
instruction itself.

> The only thing I store into the array
> is an "IntTy". I use a GEP instruction to index into the stack and then
> generate the store instruction like this:
>
> > ConstantInt* val = ConstantInt::get( Type::IntTy, value );
> > bb->getInstList().push_back( new StoreInst( val, gep ) );
>
> How could this "ConstantInt" value be reported as "void <badref>" ?

Again, this is should be fixed.  Sorry for the confusion.  :(

> The next thing that troubles me is that the verifier output for the
> second operand indicates a two dimensional array.

Actually, another failure, it's printing out the type twice.  In LLVM, a
two dimensional array would look like '[ 40 x [10 x int]]' or something.

> Shouldn't that create just a single dimensioned array? Note that
> "stack_size" is an integer with the value 1024.

Yes, it should.

> Finally, I have some confusion about how SSA works with LLVM. If I
> understand the documentation correctly, there is no distinction between
> an instruction that creates a value and the value itself.

Correct.

> So, for example, if I want to add two numbers stored in memory, I add
> the two load instructions used to fetch the values. Right? Please say
> yes or I have to change my whole conception of how this works! :)

yes!  :)

> Okay, so one of the built-in operations in Stacker is to push an integer
> onto the stack. This is done by just mentioning the integer value as in
> Forth. For example,
>
> : PushOne 1 ;
>
> is Stackerese for defining a function that pushes the value 1 onto the
> stack. To implement "PushOne", I have to conceptually do this:
>
>      1. Load the integer stack index (LoadInst)
>      2. Increment the index (Add BinaryOperator)
>      3. Get the address of the stack element at that index (GEP)
>      4. Store the value 1 at that address (StoreInst).

Yup, that sounds good.

>     std::vector<Value*> indexVec;       // Index vector
>     indexVec.push_back(loadop);         // Insert single index
>     GetElementPtrInst* gep = new GetElementPtrInst(
>         TheStack, indexVec );
>     bb->getInstList().push_back( gep );         // Put GEP in Block

This is the problem.  The deal here is that the 'getelementptr'
instruction actually takes one extra argument than you are giving it (this
is, by far, the most confusing aspect of the getelementptr instruction).
Lets say your stack is of type:

%Stack = ...  <[100 x int] *>

If you index into this with a single "long" index, you will get this:

%Ptr = getelementptr [100 x int]* %Stack, long %X     ; <[100 x int] *>

Where what you really want is this:

%Ptr = getelementptr [100 x int]* %Stack, long 0, long %X     ; <int*>


The deal with the initial zero is that it is specifying how to index
_through the pointer_, which is often forgotten about.  This allows LLVM
to translate this C code:

int *P = ...
P = P + 1;

into this LLVM code:

%P.1 = ...
%P.2 = getelementptr int* %P.1, long 1

This probably won't make sense the first time you see it.  Take a look at:
http://llvm.cs.uiuc.edu/docs/LangRef.html#i_getelementptr

And remember that we are turning the '->' syntactic sugar into it's
equivalent [0] form.

If you have any other questions about this, please just let me know (and
try out the fixed verifier too :)

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/




More information about the llvm-dev mailing list