[LLVMdev] How to disable simplifying function parameters in llvm-g++

Xiaolong Tang xiaolong.snake at gmail.com
Mon Jul 26 13:35:13 PDT 2010

Hi Duncan,

> > Note that the original parameter (of the function in concern) is of
> > type "struct.std::_List_const_iterator<int>", whereas the parameter
> > (after the compilation) is of type
> > "struct.std::_List_node_base"*. Evidently, llvm-g++ replaces the
> > original parameter with its sole field. This is understandable and the
> > LLVM output indicates this by using "__position.0" rather than
> > "__position". Further, llvm-g++ represents (bitcasts) the parameter
> > type "struct.std::_List_node_base"* as (into) i64.  Though this may
> > be decoded by analyzing the meta data with the function, I believe
> > that llvm-g++ has conducted some transformations somehow. To me, the
> > transformation looks likes scalar replacement.
> I think on the contrary this is llvm-g++ trying to obtain ABI conformance.
> The rules on how parameters should be passed to functions (in registers, on
> the stack, partly in registers, partly on the stack) can be quite complicated.
> Rather than pushing this complexity into LLVM, front-ends are required to take
> care of ensuring ABI conformance when they generate the LLVM IR.  The kind of
> transform you see looks typical of llvm-g++ trying to handle an ABI rule which
> says that initial fields of a struct should be passed in registers.  In short,
> I don't think this is LLVM doing an optimization, it is LLVM trying to produce
> correct ABI conformant code.

I checked the result spit out by Clang (I have not found good reasons
to switch to Clang until today :). It turned out that Clang preserves
more accurate type information than llvm-g++, at least in my test
cases. Back to the example in our discussion, the compiled function
prototype is:

  define linkonce_odr void @_ZNSt4listIiSaIiEE9_M_insertESt14_List_iteratorIiERKi(%"class.std::list"* %this, %"struct.std::_List_node_base"* %__position.coerce, i32* %__x) ssp align 2 { ... }

Compared with llvm-g++, the second parameter is of type
%"struct.std::_List_node_base"*, rather than a plain i64. Note that
the fact does not impair your argument on the conformance to
ABI. llvm-g++ may do better, however. :)


More information about the llvm-dev mailing list