Hao Shen
2010-Apr-12 15:02 UTC
[LLVMdev] Why function pointer is different from other data type?
Dear all, I compiled c program with llvm and found something strange with function pointer as following small example . ------------- In C Code -------------- float a (int value) { return value + 1; }; typedef float (*funcptr_t) (int); funcptr_t get_ptr(funcptr_t p) { return p; } float result = get_ptr(a)(4); ------------- In LLVM Code -------------- %4 = call float (i32)* (float (i32)*)* @get_ptr(float (i32)* @a1) nounwind ; <float (i32)*> [#uses=1] ~~~~~~~~~~~~~~~~~~~~ VERY STRANGE RETURN TYPE !!! %5 = call float %4(i32 4) nounwind ; <float> [#uses=1] Why we need duplicated return type? Best regards, -- Hao Shen
Nick Lewycky
2010-Apr-12 15:21 UTC
[LLVMdev] Why function pointer is different from other data type?
Hao Shen wrote:> Dear all, > > I compiled c program with llvm and found something strange with > function pointer as following small example . > > ------------- In C Code -------------- > float a (int value) { > return value + 1; > }; > > typedef float (*funcptr_t) (int); > > funcptr_t get_ptr(funcptr_t p) { > return p; > } > > float result = get_ptr(a)(4); > > ------------- In LLVM Code -------------- > > %4 = call float (i32)* (float (i32)*)* @get_ptr(float (i32)* @a1) > nounwind ;<float (i32)*> [#uses=1] > ~~~~~~~~~~~~~~~~~~~~ VERY STRANGE RETURN TYPE !!! > %5 = call float %4(i32 4) nounwind ;<float> [#uses=1] > > > Why we need duplicated return type?Maybe I've just been reading LLVM IR for too long, but this looks completely normal to me. :-) To answer the question in the subject line, a function pointer is just yet another type, like a struct pointer or a char pointer, etc. The 'float (i32)' indicates a function that takes an i32 and returns a float, so 'float (i32)*' is the type of a pointer to that function. This is your funcptr_t. That makes 'float (i32)* (float (i32)*)*' the exact type you'd expect for get_ptr(); it takes a funcptr_t and it returns a funcptr_t. Note that the type is the type of @get_ptr itself, not the type that @get_ptr returns. Why a duplicated return type? The part after the ; is a plain-text comment. By default LLVM prints <return type> [#uses=X] for every non-void instruction. Note that the <> aren't part of the type in this case. Nick
SHEN Hao
2010-Apr-12 15:40 UTC
[LLVMdev] Why function pointer is different from other data type?
Thanks a lot. I can understand the "float (i32)* (float (i32)*)*" is the type of function instead of return value type. But why in most LLVM call assembly, such as "%retval = call i32 @test(i32 %argc)" the "i32" is just the return value. In the document, 'call' Instruction is defined as following: <result> = [tail] call [cconv] [ret attrs] <ty> [<fnty>*] <fnptrval>(<function args>) [fn attrs] 'ty': the type of the call instruction itself which is also the type of the return value. Functions that return no value are marked void. Would you please explain this? Hao On Mon, Apr 12, 2010 at 5:21 PM, Nick Lewycky <nicholas at mxc.ca> wrote:> Hao Shen wrote: >> >> Dear all, >> >> I compiled c program with llvm and found something strange with >> function pointer as following small example . >> >> ------------- In C Code -------------- >> float a (int value) { >> return value + 1; >> }; >> >> typedef float (*funcptr_t) (int); >> >> funcptr_t get_ptr(funcptr_t p) { >> return p; >> } >> >> float result = get_ptr(a)(4); >> >> ------------- In LLVM Code -------------- >> >> %4 = call float (i32)* (float (i32)*)* @get_ptr(float (i32)* @a1) >> nounwind ;<float (i32)*> [#uses=1] >> ~~~~~~~~~~~~~~~~~~~~ VERY STRANGE RETURN TYPE !!! >> %5 = call float %4(i32 4) nounwind ;<float> [#uses=1] >> >> >> Why we need duplicated return type? > > Maybe I've just been reading LLVM IR for too long, but this looks completely > normal to me. :-) > > To answer the question in the subject line, a function pointer is just yet > another type, like a struct pointer or a char pointer, etc. The 'float > (i32)' indicates a function that takes an i32 and returns a float, so 'float > (i32)*' is the type of a pointer to that function. This is your funcptr_t. > That makes 'float (i32)* (float (i32)*)*' the exact type you'd expect for > get_ptr(); it takes a funcptr_t and it returns a funcptr_t. Note that the > type is the type of @get_ptr itself, not the type that @get_ptr returns. > > Why a duplicated return type? The part after the ; is a plain-text comment. > By default LLVM prints <return type> [#uses=X] for every non-void > instruction. Note that the <> aren't part of the type in this case. > > Nick >-- Hao Shen
Duncan Sands
2010-Apr-12 15:42 UTC
[LLVMdev] Why function pointer is different from other data type?
Hi Hao Shen,> %4 = call float (i32)* (float (i32)*)* @get_ptr(float (i32)* @a1) > nounwind ;<float (i32)*> [#uses=1] > ~~~~~~~~~~~~~~~~~~~~ VERY STRANGE RETURN TYPE !!!this is a comment, and only exists to help the human reader. Comments start with a semi-colon (;). You can remove them if you like. Ciao, Duncan.
SHEN Hao
2010-Apr-12 15:58 UTC
[LLVMdev] Why function pointer is different from other data type?
I'm sorry that I should remove the comment. In fact my question is about the "float (i32)* (float (i32)*)*", why we use this kind of return type instead of just "float (i32)*". Thanks a lot. Hao On Mon, Apr 12, 2010 at 5:42 PM, Duncan Sands <baldrick at free.fr> wrote:> Hi Hao Shen, > >> %4 = call float (i32)* (float (i32)*)* @get_ptr(float (i32)* @a1) >> nounwind ;<float (i32)*> [#uses=1] >> ~~~~~~~~~~~~~~~~~~~~ VERY STRANGE RETURN TYPE !!! > > this is a comment, and only exists to help the human reader. Comments > start with a semi-colon (;). You can remove them if you like. > > Ciao, > > Duncan. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- Hao Shen
Chris Lattner
2010-Apr-12 16:25 UTC
[LLVMdev] Why function pointer is different from other data type?
On Apr 12, 2010, at 8:02 AM, Hao Shen wrote:> Dear all, > > I compiled c program with llvm and found something strange with > function pointer as following small example . > > ------------- In C Code -------------- > float a (int value) { > return value + 1; > }; > > typedef float (*funcptr_t) (int); > > funcptr_t get_ptr(funcptr_t p) { > return p; > } > > float result = get_ptr(a)(4); > > ------------- In LLVM Code -------------- > > %4 = call float (i32)* (float (i32)*)* @get_ptr(float (i32)* @a1) > nounwind > ~~~~~~~~~~~~~~~~~~~~ VERY STRANGE RETURN TYPE !!! > %5 = call float %4(i32 4) nounwind ; <float> [#uses=1]These two are equivalent in the .ll file syntax: call void @foo() and: call void()* @foo() The .ll printer uses the first when it can because it is cleaner and easier to read. It can't do this for varargs and for functions returning a pointer to a function (because of ambiguity issues). -Chris
Reasonably Related Threads
- [LLVMdev] Why function pointer is different from other data type?
- [LLVMdev] Why function pointer is different from other data type?
- [LLVMdev] Why function pointer is different from other data type?
- [LLVMdev] Why function pointer is different from other data type?
- [LLVMdev] know if individual LLVM's Instruction has a result, and how to obtain it?