Fix PR15293: ARM codegen ice - expected larger existing stack allocation

Manman Ren mren at apple.com
Fri Mar 29 15:51:50 PDT 2013


On Mar 29, 2013, at 11:05 AM, Stepan Dyatkovskiy wrote:

> Hello,
> 
> Below some results of my small investigation.
> 
> [code]
> target triple = "arm--linux-gnueabihf"
> define void @t(i32 %a, %struct.s* byval %s, ...) nounwind {
> define void @caller() {
>  call void (i32, %struct.s*, ...)* @t(i32 0, %struct.s* @v, i32 777);
>  ret void
> }
> [/code]
> 
> llc generates wrong asm code for IR above.
> 
> After some simple tests I conclude the next:
> 
> X86: tries don't use "byval" IR attribute in all cases its possible: it replaces structures with set of smaller params, does bitcasts and so on. But in some narrow set of cases it emits "byval" attributes.
> 
> ARM:
>    clang: just casts structures to arrays and doesn't use byval at all.
>    IR: generates bad code when two byval params passed, or
>    "byval" + "..." pair passed. The only case works fine here is
>    the big byval structure that splitted onto reg-part and stack-part.
> 
> That because CCState assumes that only parameter could be passed by value.
> 
> I propose to replace the term of "FirstByValRegister" with "SmallVector<std::pair<StartReg, RegsCount> ByValInRegArgs". The last one allows to track several small structures passed by value; it also automatically solves problem when we have single tiny "byval" structure (PR15293).
Small "byval" structs are not fully tested and they are not efficient to begin with.
If we think we should support small "byval" structs, the solution proposed above sounds reasonable.
I wonder why we have a small "byval" struct in PR15293, clang should not generate that and it may be due to bug point.

Thanks,
Manman
> 
> And BTW since arm-linux-gnueabi-clang avoids byval IR attribute, this feature will not be activated after llvm will fixed. Or I'm wrong? Are there some cases when arm-clang still emits something with "byval" attribute?
> If no - byval structures handling shouldn't change clang behaviour.
> 
> Well, if I properly read the code, there are 3 points to be fixed in LLVM:
> 
> Callee side:
> 1. ARMTargetLowering::HandleByVal, since it allocates stack areas for arguments passed by value. Its also "caller" side though: for caller it just mark necessary amount of regs as byval.
> 2. ARMTargetLowering::LowerFormalArguments. Both for byval args and for var-arg function it calls VarArgStyleRegisters that allocates stack-frames for them and stores stores registers that contains byval arguments. Note if both byval parameter and "..." are presented it will store *the same* registers into all stack frames.
> 
> Caller side:
> 1. ARMTargetLowering::LowerCall. This funtion saves byval arguments into registers. If argument is too big to be stored in regs, method splits it onto reg-part and stack-part.
> 
> -Stepan.
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list