Duncan Sands
2012-Jul-17 10:59 UTC
[LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
Hi Dmitry,> Do you think this is a system problem of gcc applicable to other functions too, or just a flush-specific bug?it has nothing to do with flush - for all I know flush is fine. Dragonegg does this for all Fortran functions because the Fortran front-end is so buggy, i.e. often produces wrong function types. I have another way of handling this in mind, which would avoid this trick, but I didn't get round to implementing it yet. Ciao, Duncan.> > Best, > - Dima. > > ----- Original message ----- >> On 17/07/12 08:22, Anton Korobeynikov wrote: >>> Dmitry, >>> >>>> This is probably a question for Fortran/DragonEGG experts: >>>> >>>> Why Fortran's "call flush()" is converted to "call void bitcast >>>> (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" >>>> ? Why it needs bitcast? >>> Just a wild guess (basing from my llvm-gcc knwoledge though): there is >>> a bug with in gcc fortran frontend where it fails to create the >>> function TREEs with proper types. It might easily be possible that >>> e.g. call of function with type with no args is performed with some >>> amount of args, etc. It's pretty fine in gcc, but not in LLVM, the >>> latter is much more strict wrt this. >>> >>> The only solution / workaround for this was to emit the function >>> definition as variadic and do bitcast at a call site (there are some >>> other fortran-specific stuff involved here, e.g dummy args)... >>> >>> See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33097 for more info. >>> >> >> Yes, this is the reason. >> >> Ciao, Duncan. >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Dmitry N. Mikushin
2012-Jul-17 12:10 UTC
[LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
Duncan, Oh, right, now I remember: it's a very old problem I knew 1.5 years ago. There were even some bugs on it, here is a common case:> cat test1.f90program test call test1() end program test> kernelgen-dragonegg test1.f90 -o- | opt -O3 -S -o -; ModuleID = '<stdin>' target datalayout "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-unknown-linux-gnu" @options.0.1537 = internal constant [8 x i32] [i32 68, i32 511, i32 0, i32 0, i32 0, i32 1, i32 0, i32 1], align 32 declare void @test1_(...) define i32 @main(i32 %argc, i8** %argv) nounwind uwtable { entry: tail call void @_gfortran_set_args(i32 %argc, i8** %argv) nounwind tail call void @_gfortran_set_options(i32 8, i32* getelementptr inbounds ([8 x i32]* @options.0.1537, i64 0, i64 0)) nounwind tail call void bitcast (void (...)* @test1_ to void ()*)() nounwind ret i32 0 } declare void @_gfortran_set_args(i32, i8**) declare void @_gfortran_set_options(i32, i32*) So every external function call, not only flush, in DragonEgg is declared varargs and called with a bitcast. This is really really big problem in our case, because: 1) We need to convert calls to external functions to FFI invocation, i.e. catch all CallInsts-s, get function name, args' values and types. I don't know how to deal with CallInst-s that have bitcasts. 2) We can't have any varargs function defined in module, because it is operated by NVPTX, varargs are not allowed there. How do you think what would be the best way to workaround this problem, if it seems to be not in focus for anybody for now? Thanks, - D. 2012/7/17 Duncan Sands <baldrick at free.fr>> Hi Dmitry, > > > Do you think this is a system problem of gcc applicable to other >> functions too, or just a flush-specific bug? >> > > it has nothing to do with flush - for all I know flush is fine. Dragonegg > does this for all Fortran functions because the Fortran front-end is so > buggy, > i.e. often produces wrong function types. I have another way of handling > this > in mind, which would avoid this trick, but I didn't get round to > implementing > it yet. > > Ciao, Duncan. > > > >> Best, >> - Dima. >> >> ----- Original message ----- >> >>> On 17/07/12 08:22, Anton Korobeynikov wrote: >>> >>>> Dmitry, >>>> >>>> This is probably a question for Fortran/DragonEGG experts: >>>>> >>>>> Why Fortran's "call flush()" is converted to "call void bitcast >>>>> (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" >>>>> ? Why it needs bitcast? >>>>> >>>> Just a wild guess (basing from my llvm-gcc knwoledge though): there is >>>> a bug with in gcc fortran frontend where it fails to create the >>>> function TREEs with proper types. It might easily be possible that >>>> e.g. call of function with type with no args is performed with some >>>> amount of args, etc. It's pretty fine in gcc, but not in LLVM, the >>>> latter is much more strict wrt this. >>>> >>>> The only solution / workaround for this was to emit the function >>>> definition as variadic and do bitcast at a call site (there are some >>>> other fortran-specific stuff involved here, e.g dummy args)... >>>> >>>> See http://gcc.gnu.org/bugzilla/**show_bug.cgi?id=33097<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33097>for more info. >>>> >>>> >>> Yes, this is the reason. >>> >>> Ciao, Duncan. >>> ______________________________**_________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/**mailman/listinfo/llvmdev<http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev> >>> >> >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120717/ad07d51a/attachment.html>
Anton Korobeynikov
2012-Jul-17 13:06 UTC
[LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
> Oh, right, now I remember: it's a very old problem I knew 1.5 years ago. > There were even some bugs on it, here is a common case:Yes, this is right, fortran frontend produces bogus trees for every external call. The problem seems to have roots from the fact that there is no external function decl here, so frontend has no way even to infer the type from.> How do you think what would be the best way to workaround this problem, if > it seems to be not in focus for anybody for now?Keep in mind, this not LLVM problem, it's gfortran problem. Also, it's of pretty low priority for gcc devs since they do almost no type checking on TREEs, so the varargs decl seems to be only viable llvm-side fix. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
Possibly Parallel Threads
- [LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
- [LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
- [LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
- [LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
- [LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?