www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 22980] New: 16 bit alignment for function arguments in 32 bit

https://issues.dlang.org/show_bug.cgi?id=22980

          Issue ID: 22980
           Summary: 16 bit alignment for function arguments in 32 bit code
           Product: D
           Version: D2
          Hardware: x86
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: bugzilla digitalmars.com

void main() { test(); }

align (16) struct Cent
{
    ulong lo, hi;
}

public struct Int128
{
    Cent data;

    this(long hi, long lo)
    {
        data.hi = hi;
        data.lo = lo;
    }

    this(Cent data)
    {
        this.data = data;
    }

    Int128 foo(int a, Int128 op2, int b, Int128 op3) const // op2 and op3 are
not 16 aligned when accessed
    {
        printf("&a: %p &op2: %p &b: %p &op3 %p\n", &a, &op2, &b, &op3);
        print(op2);
        return Int128();
    }
}

import core.stdc.stdio;

void print(Int128 c)
{
    printf("%lld, %lld\n", c.data.hi, c.data.lo);
}

void print(Int128 c, Int128 d)
{
    printf("%lld, %lld    ", c.data.hi, c.data.lo);
    printf("%lld, %lld\n", d.data.hi, d.data.lo);
}

void test()
{
    Int128 d = Int128(10, 20);
    Int128 c = Int128(5, 6);
    printf("&d = %p\n", &d);

    c.foo(1,d,2,c);     // c and d are aligned to 16 when pushed on parameter
stack

    bar(c, d);
}

Int128 bar(ref Int128 x, Int128 op2)
{
    print(op2);
    return Int128();
}

-------------------------------------------------------------
This will print garbage when compiled with -m32 on Linux. The trouble is the
push of the arguments on the function call stack aligns the Int128 to 16 bytes,
while foo() expects them to be not aligned.

gcc does not align 16 byte objects on the function argument stack - it adds
code to the function to copy the parameter to 16 byte aligned local storage.

--
Apr 03 2022