[LLVMdev] conversion from 'const llvm::Value*' to 'llvm::Constant*'

991 views
Skip to first unread message

Anton Skvorts

unread,
Feb 12, 2011, 12:07:48 AM2/12/11
to llv...@cs.uiuc.edu
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

Duncan Sands

unread,
Feb 12, 2011, 7:47:01 AM2/12/11
to llv...@cs.uiuc.edu
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.
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Anton Skvorts

unread,
Feb 12, 2011, 7:03:25 PM2/12/11
to llv...@cs.uiuc.edu
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<X>(Val) && "cast<Ty>() 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<Constant>(InitVal), Twine(GlobalName) );
 
Any help, as always, would be really much appreciated!
 
Anton Skvorts
 
2011/2/12 Duncan Sands <bald...@free.fr>

Duncan Sands

unread,
Feb 13, 2011, 7:20:02 AM2/13/11
to llv...@cs.uiuc.edu
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.

Anton Skvorts

unread,
Feb 13, 2011, 11:35:41 AM2/13/11
to llv...@cs.uiuc.edu
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

2011/2/13 Duncan Sands <bald...@free.fr>:

Reid Kleckner

unread,
Feb 13, 2011, 11:55:45 AM2/13/11
to Anton Skvorts, llv...@cs.uiuc.edu
On Sun, Feb 13, 2011 at 11:35 AM, Anton Skvorts <anton....@gmail.com> wrote:
> 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

Duncan Sands

unread,
Feb 13, 2011, 12:09:56 PM2/13/11
to llv...@cs.uiuc.edu
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.

António Saragga Seabra

unread,
Feb 13, 2011, 2:45:54 PM2/13/11
to llv...@cs.uiuc.edu
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.

Duncan Sands

unread,
Feb 14, 2011, 4:11:02 AM2/14/11
to llv...@cs.uiuc.edu
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.

Reply all
Reply to author
Forward
0 new messages