discard """ disabled: "arm64" cmd: "nim c --gc:arc $file" output: "y" """ {.passC: "-march=native".} proc isAlignedCheck(p: pointer, alignment: int) = doAssert (cast[uint](p) and uint(alignment - 1)) == 0 proc isAlignedCheck[T](p: ref T, alignment: int) = isAlignedCheck(cast[pointer](p), alignment) type m256d {.importc: "__m256d", header: "immintrin.h".} = object proc set1(x: float): m256d {.importc: "_mm256_set1_pd", header: "immintrin.h".} func `+`(a,b: m256d): m256d {.importc: "_mm256_add_pd", header: "immintrin.h".} proc `$`(a: m256d): string = result = $(cast[ptr float](a.unsafeAddr)[]) var res: seq[seq[m256d]] for _ in 1..1000: var x = newSeq[m256d](1) x[0] = set1(1.0) # test if operation causes segfault isAlignedCheck(x[0].addr, alignof(m256d)) res.add x var res2: seq[m256d] for i in 1..10000: res2.setLen(res2.len + 1) # check if realloc works isAlignedCheck(res2[0].addr, alignof(m256d)) proc lambdaGen(a, b: float, z: ref m256d) : auto = var x1 = new(m256d) var x2 = new(m256d) isAlignedCheck(x1, alignof(m256d)) isAlignedCheck(x2, alignof(m256d)) x1[] = set1(2.0 + a) x2[] = set1(-23.0 - b) let capturingLambda = proc(x: ref m256d): ref m256d = var cc = new(m256d) var bb = new(m256d) isAlignedCheck(x1, alignof(m256d)) isAlignedCheck(x2, alignof(m256d)) isAlignedCheck(cc, alignof(m256d)) isAlignedCheck(bb, alignof(m256d)) isAlignedCheck(z, alignof(m256d)) cc[] = x1[] + x1[] + z[] bb[] = x2[] + set1(12.5) + z[] result = new(m256d) isAlignedCheck(result, alignof(m256d)) result[] = cc[] + bb[] + x[] return capturingLambda var xx = new(m256d) xx[] = set1(10) isAlignedCheck(xx, alignOf(m256d)) let f1 = lambdaGen(2.0 , 2.221, xx) let f2 = lambdaGen(-1.226 , 3.5, xx) isAlignedCheck(f1(xx), alignOf(m256d)) isAlignedCheck(f2(xx), alignOf(m256d)) #----------------------------------------------------------------------------- type MyAligned = object of RootObj a{.align: 128.}: float var f: MyAligned isAlignedCheck(f.addr, MyAligned.alignOf) var fref = new(MyAligned) isAlignedCheck(fref, MyAligned.alignOf) var fs: seq[MyAligned] var fr: seq[RootRef] for i in 0..1000: fs.add MyAligned() isAlignedCheck(fs[^1].addr, MyAligned.alignOf) fs[^1].a = i.float fr.add new(MyAligned) isAlignedCheck(fr[^1], MyAligned.alignOf) ((ref MyAligned)fr[^1])[].a = i.float for i in 0..1000: doAssert(fs[i].a == i.float) doAssert(((ref MyAligned)fr[i]).a == i.float) proc lambdaTest2(a: MyAligned, z: ref MyAligned): auto = var x1: MyAligned x1.a = a.a + z.a var x2: MyAligned x2.a = a.a - z.a let capturingLambda = proc(x: MyAligned): MyAligned = var cc: MyAligned var bb: MyAligned isAlignedCheck(x1.addr, MyAligned.alignOf) isAlignedCheck(x2.addr, MyAligned.alignOf) isAlignedCheck(cc.addr, MyAligned.alignOf) isAlignedCheck(bb.addr, MyAligned.alignOf) isAlignedCheck(z, MyAligned.alignOf) cc.a = x1.a + x1.a + z.a bb.a = x2.a - z.a isAlignedCheck(result.addr, MyAligned.alignOf) result.a = cc.a + bb.a + x2.a return capturingLambda let q1 = lambdaTest2(MyAligned(a: 1.0), (ref MyAligned)(a: 2.0)) let q2 = lambdaTest2(MyAligned( a: -1.0), (ref MyAligned)(a: -2.0)) isAlignedCheck(rawEnv(q1), MyAligned.alignOf) isAlignedCheck(rawEnv(q2), MyAligned.alignOf) discard q1(MyAligned(a: 1.0)) discard q2(MyAligned(a: -1.0)) #----------------------------------------------------------------------------- block: var s: seq[seq[MyAligned]] for len in 0..128: s.add newSeq[MyAligned](len) for i in 0.. 0: isAlignedCheck(s[^1][0].addr, MyAligned.alignOf) echo "y"