Changes between 2.6 and 2.7: SSA Verifier and visitFreeInst

Hi llvm,

1) The lib/VMCore/Verifier.cpp in 2.7 implements Verifier::VerifyType,
which is empty in 2.6. I noticed that it does not check all types,
for example, UnionTyID, OpaqueTyID, LabelTyID, MetadataTyID
and etc are ignored in the 'default' branch. Does it mean we dont
need to check them?

Another question is: How much does Verifier.cpp check statically?
Can I take it as a type checker for SSA? Is there any static
semantics that has not been checked yet?

2) visitFreeInst has been removed from lib/ExecutionEngine/Interpreter in 2.7
Will this have any back-compatible problem when interpreting any
*.bc from 2.6?

Thanks

Hi llvm,

1) The lib/VMCore/Verifier.cpp in 2.7 implements Verifier::VerifyType,
which is empty in 2.6. I noticed that it does not check all types,
for example, UnionTyID, OpaqueTyID, LabelTyID, MetadataTyID
and etc are ignored in the 'default' branch. Does it mean we dont
need to check them?

They are leaf types (just like integer type), there is nothing to check.

Another question is: How much does Verifier.cpp check statically?
Can I take it as a type checker for SSA? Is there any static
semantics that has not been checked yet?

The verifier is best effort, it does not guarantee correctness.

2) visitFreeInst has been removed from lib/ExecutionEngine/Interpreter in 2.7
Will this have any back-compatible problem when interpreting any
*.bc from 2.6?

The .bc reader will eliminate freeinst from the ir when reading an old file.

-chris

Jianzhou Zhao wrote:

Hi llvm,

1) The lib/VMCore/Verifier.cpp in 2.7 implements Verifier::VerifyType,
which is empty in 2.6. I noticed that it does not check all types,
for example, UnionTyID, OpaqueTyID, LabelTyID, MetadataTyID
and etc are ignored in the 'default' branch. Does it mean we dont
need to check them?

We do need to check union. I'll add that. The others don't need a case because they don't contain subtypes; it's impossible to have an illegal label type. It's either a label type or it isn't. :slight_smile:

Another question is: How much does Verifier.cpp check statically?
Can I take it as a type checker for SSA? Is there any static
semantics that has not been checked yet?

There are things that it does not check yet. It doesn't verify constant expressions, so 'bitcast i32* @x to i32' will still escape detection, if you can manage to create one (ie., you're running with assertions off).

Further, there are semantics of the program that the verifier will never verify. It is undefined behaviour to shift beyond the width of an integer. It is undefined behaviour to call a function with mismatching calling conventions. http://llvm.org/docs/FAQ.html#callconvwrong

2) visitFreeInst has been removed from lib/ExecutionEngine/Interpreter in 2.7
Will this have any back-compatible problem when interpreting any
*.bc from 2.6?

The 'free' instruction has been removed from LLVM 2.7. Any .bc files using it will have a 'call @free' inserted in its place.

Nick

Jianzhou Zhao wrote:

Hi llvm,

1) The lib/VMCore/Verifier.cpp in 2.7 implements Verifier::VerifyType,
which is empty in 2.6. I noticed that it does not check all types,
for example, UnionTyID, OpaqueTyID, LabelTyID, MetadataTyID
and etc are ignored in the 'default' branch. Does it mean we dont
need to check them?

We do need to check union. I'll add that. The others don't need a case
because they don't contain subtypes; it's impossible to have an illegal
label type. It's either a label type or it isn't. :slight_smile:

Another question is: How much does Verifier.cpp check statically?
Can I take it as a type checker for SSA? Is there any static
semantics that has not been checked yet?

There are things that it does not check yet. It doesn't verify constant
expressions, so 'bitcast i32* @x to i32' will still escape detection, if you
can manage to create one (ie., you're running with assertions off).

Further, there are semantics of the program that the verifier will never
verify. It is undefined behaviour to shift beyond the width of an integer.
It is undefined behaviour to call a function with mismatching calling
conventions. http://llvm.org/docs/FAQ.html#callconvwrong

2) visitFreeInst has been removed from lib/ExecutionEngine/Interpreter in
2.7
Will this have any back-compatible problem when interpreting any
*.bc from 2.6?

The 'free' instruction has been removed from LLVM 2.7. Any .bc files using
it will have a 'call @free' inserted in its place.

Thanks.

Another question is about 'ret'.
http://llvm.org/docs/LangRef.html#i_ret gives the syntax:
   ret <type> <value> ; Return a value from a non-void function
   ret void ; Return from void function
In the case when the return type is not void, it returns
a single value. But if I am looking into the code,
the Verifier also allows 'multi returned values' if the return
type is of structure or array, while there is not interface
in 'ReturnInst' to create a multi-value 'ret'. Is it only for
the ll code that was generated by an old version LLVM
which had still supported 'multi-return'.

The comments in 'Verifier' say this 'multi-return' verification
feature may be removed from LLVM 3.0. So If I am generating
'ret' with multi values, will that be a verification error
when LLVM 3.0 releases?

Hi Jianzhou Zhao,

Another question is about 'ret'.
http://llvm.org/docs/LangRef.html#i_ret gives the syntax:
    ret<type> <value> ; Return a value from a non-void function
    ret void ; Return from void function
In the case when the return type is not void, it returns
a single value. But if I am looking into the code,
the Verifier also allows 'multi returned values' if the return
type is of structure or array, while there is not interface
in 'ReturnInst' to create a multi-value 'ret'. Is it only for
the ll code that was generated by an old version LLVM
which had still supported 'multi-return'.

it used to be the case that you could not have registers of struct or
array type, and thus you could not return structs or arrays from functions.
A special syntax was created to allow you to nonetheless return multiple
values from a function. However the restriction on registers was later
removed: you can now have registers of struct or array type, and return
them from functions. This made the special support for multiple return
values obsolete: nowadays you can just return a struct/array. There is
no need for a special ReturnInst, since scalar and struct/array values
are handled the same way.

The comments in 'Verifier' say this 'multi-return' verification
feature may be removed from LLVM 3.0. So If I am generating
'ret' with multi values, will that be a verification error
when LLVM 3.0 releases?

If you are returning a struct or array, then that will continue to be
supported, since this is now the standard way of doing things. As a
general rule, LLVM is backwards compatible, so even if you are using the
obsolete special multiple return values syntax, then it should continue
to be supported for ever (though you may be required to run a special
tool to upgrade your bitcode).

Ciao,

Duncan.

Hi llvm,

1) The lib/VMCore/Verifier.cpp in 2.7 implements Verifier::VerifyType,
which is empty in 2.6. I noticed that it does not check all types,
for example, UnionTyID, OpaqueTyID, LabelTyID, MetadataTyID
and etc are ignored in the 'default' branch. Does it mean we dont
need to check them?

They are leaf types (just like integer type), there is nothing to check.

Another question is: How much does Verifier.cpp check statically?
Can I take it as a type checker for SSA? Is there any static
semantics that has not been checked yet?

The verifier is best effort, it does not guarantee correctness.

Can we take the verifier as a reference to generate correct SSA?
I had some confusions when I was reading the RefManual
on the LLVM website, so I looked into the source code of
Verifier to see how well-formedness is checked in practice.

For example,
1) Can I have a block that does not start with a label?
Verifier checks that a block must end with a terminator
instruction. If the block without a label is not the entry block
in a function, could that be jumped into? or is it still a valid block?
since the syntax allows the label to be optional.

2) Verifier checks a block must contain only one terminator
insn which must be the last insn, and phi insns must be
in the beginning of the block as a group. If this is the right grammar,
could we not change the syntax of blocks as..?
  phi* i* t* where
    phi is a Phi node, i is an insn except Phi and terminator,
    and t is a terminator node.
So we dont need to check this at runtime.
This is same to ask if the verifier is a module that we have to run.

Thanks.

Hi Jianzhou Zhao

For example,
1) Can I have a block that does not start with a label?

yes.

Verifier checks that a block must end with a terminator
instruction. If the block without a label is not the entry block
in a function, could that be jumped into? or is it still a valid block?
since the syntax allows the label to be optional.

A block with no label is unreachable if it is not the entry block. It
is nonetheless a valid basic block.

2) Verifier checks a block must contain only one terminator
insn which must be the last insn, and phi insns must be
in the beginning of the block as a group. If this is the right grammar,
could we not change the syntax of blocks as..?
   phi* i* t* where
     phi is a Phi node, i is an insn except Phi and terminator,
     and t is a terminator node.
So we dont need to check this at runtime.

I don't understand what you are saying. Bitcode is not just obtained
by parsing .ll files, it can also be (and usually is) constructed via
the API.

This is same to ask if the verifier is a module that we have to run.

It is wise to run it, especially when you are developing your front-end,
but running it is not obligatory.

Ciao,

Duncan.