either you use unaligned loads and sequences or you use your own `ptr UncheckedArray` and you align manually and then you can use aligned loads.
Either use posix_memalign or windows equivalent <https://github.com/mratsim/constantine/blob/478c19e/constantine/platforms/allocs.nim#L43-L56> when defined(windows): proc aligned_alloc_windows(size, alignment: int): pointer {.tags:[HeapAlloc],importc:"_aligned_malloc", header:"<malloc.h>".} # Beware of the arg order! proc aligned_alloc(alignment, size: int): pointer {.inline.} = aligned_alloc_windows(size, alignment) proc aligned_free(p: pointer){.tags:[HeapAlloc],importc:"_aligned_free", header:"<malloc.h>".} elif defined(osx): proc posix_memalign(mem: var pointer, alignment, size: int){.tags:[HeapAlloc],importc, header:"<stdlib.h>".} proc aligned_alloc(alignment, size: int): pointer {.inline.} = posix_memalign(result, alignment, size) proc aligned_free(p: pointer) {.tags:[HeapAlloc], importc: "free", header: "<stdlib.h>".} else: proc aligned_alloc(alignment, size: int): pointer {.tags:[HeapAlloc],importc, header:"<stdlib.h>".} proc aligned_free(p: pointer) {.tags:[HeapAlloc], importc: "free", header: "<stdlib.h>".} Run or align a pointer yourself after allocating extra = alignment of memory: <https://github.com/mratsim/laser/blob/master/laser/private/memory.nim> func align_raw_data*(T: typedesc, p: pointer): ptr UncheckedArray[T] = static: assert T.supportsCopyMem withCompilerOptimHints() let address = cast[ByteAddress](p) let aligned_ptr{.restrict.} = block: # We cannot directly apply restrict to the default "result" let remainder = address and (LASER_MEM_ALIGN - 1) # modulo LASER_MEM_ALIGN (power of 2) if remainder == 0: assume_aligned cast[ptr UncheckedArray[T]](address) else: let offset = LASER_MEM_ALIGN - remainder assume_aligned cast[ptr UncheckedArray[T]](address +% offset) return aligned_ptr Run