Skip to content

Commit

Permalink
[bitcode] round up value type size for slot calculation (#13009)
Browse files Browse the repository at this point in the history
[2018-10] [bitcode] round up value type size for slot calculation

consider

```csharp
struct S3
{
    public ushort X;
    public ushort Y;
    public ushort Z;
}
```
this would be 3 * 2 = 6 bytes. Structs, however, are passed around as i32
arrays in LLVM IR between functions. Those, if such a struct is passed, are
split to `int32`s depending on the struct's size. The previous calulation was
wrongly reserving one such i32 slot instead of two for `S3` above.

Additionally increase slot size to i64 so that it aligns with a
slightly different ABI on arm64_32.


Fixes #8486

@rolfbjarne I've tested it on a arm64_32 device, please confirm that this fixes the issue on your armv7k device as well

Backport of #12992.

/cc @lewurm
  • Loading branch information
monojenkins authored Feb 14, 2019
1 parent aa0b580 commit 0955247
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions mono/mini/mini-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2368,17 +2368,22 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
case RegTypeFP:
lainfo->storage = LLVMArgNormal;
break;
case RegTypeStructByVal:
case RegTypeStructByVal: {
lainfo->storage = LLVMArgAsIArgs;
if (eabi_supported && ainfo->align == 8) {
/* LLVM models this by passing an int64 array */
lainfo->nslots = ALIGN_TO (ainfo->struct_size, 8) / 8;
lainfo->esize = 8;
} else {
lainfo->nslots = ainfo->struct_size / sizeof (target_mgreg_t);
lainfo->esize = 4;
}
int slotsize;
#ifdef TARGET_WATCHOS
/* slotsize=4 would work for armv7k, however arm64_32 allows
* passing structs with sizes up to 8 bytes in a single register.
* On armv7k slotsize=8 boils down to the same generated native
* code by LLVM, so it's okay. */
slotsize = 8;
#else
slotsize = eabi_supported && ainfo->align == 8 ? 8 : 4;
#endif
lainfo->nslots = ALIGN_TO (ainfo->struct_size, slotsize) / slotsize;
lainfo->esize = slotsize;
break;
}
case RegTypeStructByAddr:
case RegTypeStructByAddrOnStack:
lainfo->storage = LLVMArgVtypeByRef;
Expand Down

0 comments on commit 0955247

Please sign in to comment.