conversion from 'const llvm::Value*' to 'llvm::Constant*'

Hi

Apolagize if this newbie question has some obvious answer. When running something like


ExprAST *Init = GlobalNames[i].second;
const Value *InitVal;
InitVal = Init->Codegen();
GlobalVariable * globvar = new GlobalVariable(*TheModule, InitVal->getType(), false, llvm::GlobalValue::ExternalLinkage, InitVal, Twine(GlobalName));

I’m getting the following error

error: invalid conversion from const llvm::Value*' to llvm::Constant*’

How may I make this conversion? Any help would be much appreciated!

Anton

Hi Anton,

I'm getting the following error

    error: invalid conversion from `const llvm::Value*' to `llvm::Constant*'

How may I make this conversion? Any help would be much appreciated!

cast<Constant>(whatever)

Ciao, Duncan.

Hi Duncan

Many many thanks, it works now!
But there are still some details I must be missing. I’m getting an assertion when I try the following assignment in my script:

global c = cos(1);

Assertion failed: isa(Val) && “cast() argument of incompatible type!”, file c:/llvm-source-2.7/include/llvm/Support/Casting.h, line 200

However, running for example
cos(1);
global a = 0.5403023058681398; # cos(1) = 0.5403023058681398
global b = 1 + 1;
works fine
@a = global double 0x3FE14A280FB5068C ; <double*> [#uses=0]
@b = global double 2.000000e+000 ; <double*> [#uses=0]
define double @0() {
entry:
ret double 0x3FE14A280FB5068C
}

The relevant code is

Value *InitVal;
InitVal = Init->Codegen();
GlobalVariable * globval = new GlobalVariable(*TheModule, InitVal->getType(), false,
llvm::GlobalValue::ExternalLinkage, cast(InitVal), Twine(GlobalName) );

Any help, as always, would be really much appreciated!

Anton Skvorts

2011/2/12 Duncan Sands <baldrick@free.fr>

Hi Anton,

But there are still some details I must be missing. I'm getting an assertion
when I try the following assignment in my script:
    global c = cos(1);
Assertion failed: isa<X>(Val) && "cast<Ty>() argument of incompatible type!",

I think this is telling you that cos(1) is not a constant.

Ciao, Duncan.

Oh, I thought that after "codegening" cos(0) would get me double 1.0
(assigment is working for anything like: global a = 1/3 + 2 /3 for
example) What would be the best way to make assigments involving
functions, like global a = cos(0);
without getting the assertion arising from InitVal =
cast<Constant>(Init->Codegen()); ?

I made some changes and now my code basically works, except in
assigments like the one above. It is a little bit frustrating because
is the main thing preventing me finishing my little silly scripting
language for monte carlo simulations.

Value *GlobalExprAST::Codegen() {
for (unsigned i = 0, e = GlobalNames.size(); i != e; ++i) {
  const std::string &GlobalName = GlobalNames[i].first;
  ExprAST *Init = GlobalNames[i].second;
  Constant *InitVal;
  InitVal = cast<Constant>(Init->Codegen());
  if (InitVal == 0) return 0;

GlobalVariable * globval = new GlobalVariable(*TheModule,
InitVal->getType(), false, llvm::GlobalValue::ExternalLinkage,
InitVal, Twine(GlobalName) );
}
}

Thank you very much for our help
Anton

Oh, I thought that after "codegening" cos(0) would get me double 1.0

Your codegen method looks like it will generate code to evaluate
cos(0). There's no way in LLVM to run this code at global scope, it
has to be inside a function. If you want to support running arbitrary
code at global scope in your language, you probably want to do
something like what C++ does for static initializers, where you run
code before main and fill in the values of global variables.

(assigment is working for anything like: global a = 1/3 + 2 /3 for
example)

The reason 1/3 + 2/3 works is because the IRBuilder recognizes these
as constants for you and folds them down to an LLVM Constant.

Reid

Hi Anton,

Oh, I thought that after "codegening" cos(0) would get me double 1.0
(assigment is working for anything like: global a = 1/3 + 2 /3 for
example) What would be the best way to make assigments involving
functions, like global a = cos(0);
without getting the assertion arising from InitVal =
cast<Constant>(Init->Codegen()); ?

the problem is that you are performing a function call (to "cos"). A function
call is simply not a constant in the sense of LLVM (even if it is a constant in
the sense of mathematics): it needs to be executed to work out what the return
value is, and something that needs to be executed is not a Constant.

Probably you should have a constructor call "cos" and assign the return value
to your global. To work out how to do this I suggest you write the C code
corresponding to assigning cos(0) to a and stick it in http://llvm.org/demo to
see how it is handled.

Ciao, Duncan.

Hi Duncan and Reid,

Thanks for your comments and suggestions. I was puzzled because
assigning to a local variable in the tutorial example works. For
example:

var a = cos(1) in (
2 * a );

emits

declare double @cos(double)
define double @0() {
entry:
  ret double 0x3FF14A280FB5068C
}

and we get the right answer 1.08060461.

Hi António,

Thanks for your comments and suggestions. I was puzzled because
assigning to a local variable in the tutorial example works. For
example:

var a = cos(1) in (
2 * a );

emits

declare double @cos(double)
define double @0() {
entry:
   ret double 0x3FF14A280FB5068C
}

and we get the right answer 1.08060461.

note that it did not declare a global variable "a". Probably it initialized
"a" (however it was defined) with a call of "cos(1)" which the optimizers
evaluated as the constant 0x3FF14A280FB5068C.

Ciao, Duncan.