================

----------------
zibi2 wrote:

Here is a concrete cross-compiler test run on z/OS (clang caller, xlc callee):

```
PASS  int 2                       R2D = 0x0000000000000002
PASS  int -1                      R2D = 0x00000000ffffffff
PASS  int 0x7fffffff              R2D = 0x000000007fffffff
PASS  int 0                       R2D = 0x0000000000000000
PASS  int -2147483648             R2D = 0x0000000080000000
```

poison() pre-loads 0xDEADBEEF into the upper 32 bits of R1–R3 before each call. 
If clang wrote only R2L, the result for int -1 would be 0xDEADBEEFffffffff. It 
is 0x00000000ffffffff so clang zero-extends into the full 64-bit register.

<details>
<summary>caller.c (clang -m64)</summary>

```
/* passes known int values; clang is the thing under test */
extern void witness_r1(unsigned long long *out, int val);
extern void poison(void);
#define ZX(n) ((unsigned long long)(unsigned int)(n))
static void check(const char *label, int val, unsigned long long expected)
{
    unsigned long long got = 0;
    poison();
    witness_r1(&got, val);
    if (got == expected)
        printf("PASS  %-26s  R2D = 0x%016llx\n", label, got);
    else {
        printf("FAIL  %-26s  R2D = 0x%016llx  expected 0x%016llx\n",
               label, got, expected);
        failures++;
    }
}

int main(void)
{
    check("int 2",           2,           ZX(2));
    check("int -1",         -1,           ZX(-1));
    check("int 0x7fffffff",  0x7fffffff,  ZX(0x7fffffff));
    check("int 0",           0,           ZX(0));
    check("int -2147483648", -2147483648, ZX(-2147483648));
    printf("\n%s\n", failures ? "FAILED" : "ALL PASSED");
    return failures != 0;
}
```

</details><details>
<summary>witness.c (xlc -q64) — captures raw R2D before any prologue</summary>

```
/* parameter is unsigned long long, NOT int -- suppresses xlc's LGFR prologue */
void witness_r1(unsigned long long *out, unsigned long long val) {
    __asm(" stg 2,0(1)");   /* store raw R2D into *out */
}
```

</details> <details>
<summary>poison.c (xlc -q64) — pre-contaminates upper half</summary>

```
void poison(void) {
    __asm(" llihf 1,X'DEADBEEF'");
    __asm(" llihf 2,X'DEADBEEF'");
    __asm(" llihf 3,X'DEADBEEF'");
}
```
</details>

Without last commit the last sub-test would fail as follows:
`FAIL  int -2147483648             R2D = 0xffffffff80000000  expected 
0x0000000080000000`

https://github.com/llvm/llvm-project/pull/206833
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to