Description
It seems that ReadUnaligned and WriteUnaligned no longer support unaligned pointer access on ARM architecture.
Reproduction Steps
https://godbolt.org/z/nGh9vP6KK
using System;
using System.Runtime.CompilerServices;
unsafe class Repro
{
public struct Test
{
public int X, Y, Z;
}
public static Test Test1(void*ptr)
{
return Unsafe.ReadUnaligned<Test>(ptr);
}
public static Test Test2(void*ptr)
{
return *(Test*)ptr;
}
public static void WTest1(void*ptr, Test t)
{
Unsafe.WriteUnaligned<Test>(ptr, t);
}
public static void WTest2(void*ptr, Test t)
{
*(Test*)ptr = t;
}
}
.NET 6.0: Only ReadUnaligned generates invalid code
Repro:WTest2(int,Repro+Test):
push {r1,r2,r3}
push {lr}
ldr r3, [sp+0x04]
str r3, [r0]
ldr r3, [sp+0x08]
str r3, [r0+4]
ldr r3, [sp+0x0c]
str r3, [r0+8]
pop lr
add sp, 12
bx lr
Repro:WTest1(int,Repro+Test):
push {r1,r2,r3}
push {lr}
sub sp, 16
ldr r3, [sp+0x14]
str r3, [sp+0x04] // [V04 tmp2]
ldr r3, [sp+0x18] // [V01 arg1+0x04]
str r3, [sp+0x08] // [V05 tmp3]
ldr r3, [sp+0x1c] // [V01 arg1+0x08]
str r3, [sp+0x0c] // [V06 tmp4]
ldr r3, [sp+0x04] // [V03 tmp1]
str r3, [r0]
ldr r3, [sp+0x08] // [V03 tmp1+0x04]
str r3, [r0+4]
ldr r3, [sp+0x0c] // [V03 tmp1+0x08]
str r3, [r0+8]
add sp, 16
pop lr
add sp, 12
bx lr
Repro:Test2(int):Repro+Test:
push {r3,lr}
ldr r3, [r1]
str r3, [r0]
ldr r3, [r1+4]
str r3, [r0+4]
ldr r3, [r1+8]
str r3, [r0+8]
pop {r3,pc}
Repro:Test1(int):Repro+Test:
push {r3,lr}
ldr r3, [r1]
str r3, [r0]
ldr r3, [r1+4]
str r3, [r0+4]
ldr r3, [r1+8]
str r3, [r0+8]
pop {r3,pc}
.NET 7.0: Both WriteUnaligned and ReadUnaligned generate direct pointer access
Repro:Test1(uint):Test:
push {r3,lr}
ldr r3, [r1]
str r3, [r0]
ldr r3, [r1+0x04]
str r3, [r0+0x04]
ldr r3, [r1+0x08]
str r3, [r0+0x08]
pop {r3,pc}
Repro:Test2(uint):Test:
push {r3,lr}
ldr r3, [r1]
str r3, [r0]
ldr r3, [r1+0x04]
str r3, [r0+0x04]
ldr r3, [r1+0x08]
str r3, [r0+0x08]
pop {r3,pc}
Repro:WTest1(uint,Test):
push {r1,r2,r3}
push {lr}
ldr r3, [sp+0x04]
str r3, [r0]
ldr r3, [sp+0x08]
str r3, [r0+0x04]
ldr r3, [sp+0x0C]
str r3, [r0+0x08]
pop lr
add sp, 12
bx lr
Repro:WTest2(uint,Test):
push {r1,r2,r3}
push {lr}
ldr r3, [sp+0x04]
str r3, [r0]
ldr r3, [sp+0x08]
str r3, [r0+0x04]
ldr r3, [sp+0x0C]
str r3, [r0+0x08]
pop lr
add sp, 12
bx lr
Expected behavior
Generated code properly handles misaligned pointers
Actual behavior
Unhandled fault: alignment exception
Regression?
No response
Known Workarounds
Buffer.MemoryCopy
Configuration
Raspberry Pi 3, Debian 11 32 bit
Other information
No response
Description
It seems that ReadUnaligned and WriteUnaligned no longer support unaligned pointer access on ARM architecture.
Reproduction Steps
https://godbolt.org/z/nGh9vP6KK
.NET 6.0: Only ReadUnaligned generates invalid code
.NET 7.0: Both WriteUnaligned and ReadUnaligned generate direct pointer access
Expected behavior
Generated code properly handles misaligned pointers
Actual behavior
Unhandled fault: alignment exceptionRegression?
No response
Known Workarounds
Buffer.MemoryCopy
Configuration
Raspberry Pi 3, Debian 11 32 bit
Other information
No response