32

I create a llvm::Value* from a integer constant like this:

llvm::Value* constValue = llvm::ConstantInt::get( llvmContext , llvm::APInt( node->someInt() ));

now i want to retrieve the compile-time constant value back;

int constIntValue = constValue->???

The examples shown in LLVM Programmer manual seem to imply that cast<> will accept a pointer when using the type (rather than the type plus pointer) template parameter, however i'm pretty sure thats failing as from 2.8:

llvm::Value* foo = 0;
llvm::ConstantInt* intValue = & llvm::cast< llvm::ConstantInt , llvm::Value >(foo );

//build error:
//error: no matching function for call to ‘cast(llvm::Value*&)’

What would be the correct approach here?

3 Answers 3

47

Eli's answer is great, but it's missing the final part, which is getting the integer back. The full picture should look like this:

if (ConstantInt* CI = dyn_cast<ConstantInt>(Val)) {
  if (CI->getBitWidth() <= 32) {
    constIntValue = CI->getSExtValue();
  }
}

Of course, you can also change it to <= 64 if constIntValue is a 64-bit integer, etc.

And as Eli wrote, if you are confident the value is indeed of type ConstInt, you can use cast<ConstantInt> instead of dyn_cast.

Sign up to request clarification or add additional context in comments.

Comments

41

Given llvm::Value* foo and you know that foo is actually a ConstantInt, I believe that the idiomatic LLVM code approach is to use dyn_cast as follows:

if (llvm::ConstantInt* CI = dyn_cast<llvm::ConstantInt>(foo)) {
  // foo indeed is a ConstantInt, we can use CI here
}
else {
  // foo was not actually a ConstantInt
}

If you're absolutely sure that foo is a ConstantInt and are ready to be hit with an assertion failure if it isn't, you can use cast instead of dyn_cast.


P.S. Do note that cast and dyn_cast are part of LLVM's own implementation of RTTI. dyn_cast acts somewhat similarly to the standard C++ dynamic_cast, though there are differences in implementation and performance (as can be read here).

2 Comments

According to the link you provide, if the pointer is not pointing to the expected type, it's cast that will lead to an assertion failure, and dyn_cast will return 0, instead of the opposite.
How to detect whether this ConstantInt is signed or unsigned ?
2

Other answers work if the constant is a variable in current file.

However if the constant variable is a global variable defined in other file, which is refered by current file by extern. In this case the variable in current file is a PointerType value. We have to get its real value through following code:

Constant *c;

if (isa<GlobalValue>(c)) {
        GlobalValue *gvalue = dyn_cast<GlobalValue>(c);
        GlobalVariable *gv = dyn_cast<GlobalVariable>(gvalue);
        ConstantInt *ci = dyn_cast<ConstantInt>(gv->getInitializer());
        errs() << ci->getValue();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.