Hello,

While testing the "expr" coreutil, I ran into a Klee crash caused by
LLVM instructions processing 128bit integers (i128 types).
Surprisingly enough, they can be found in various places in the LLVM
assembly generated by LLVM on a 64-bit architecture, as optimization
tricks when passing large structures as value parameters. By grepping
through the assembly.ll file generated by Klee for the "expr" tool, I
found 17 places where i128 occurs as an operand type.

In my particular case, the crash occurs when the
ConstantExpr::getZExtValue() attempts to convert the encapsulated
constant value (which is an arbitrary llvm::APInt value) to the
uint64_t standard C type. This method is called during the
initialization of an OrExpr object between two 128bit integers, when
the ConstantExpr::isZero() is called, which in turns it calls
getZExtValue(), and hence the crash.

The getZExtValue() documentation states that this function should be
used whenever the width of the constant is known to be bounded by 64
bits. Therefore, my proposed solution is to identify those places in
Klee when this function is misused (that is, one should not rely on 64
bit boundary), and replace it with an APInt based solution. In my
case, the isZero() method can be rewritten to construct an "0" APInt
object with the same width, and compare it against the target
constant. If you know some other places when I could use a similar
approach, I would be glad to apply it to those, as well.

More technical details about the crash symptoms and causes can be found here:
http://llvm.org/bugs/show_bug.cgi?id=6602

Cheers,
Stefan

Reply via email to