> On Mar 26, 2019, at 3:20 PM, Vladimir Makarov <vmaka...@redhat.com> wrote: > > On 3/26/19 4:25 AM, Maxim Kuvyrkov wrote: >>> On Mar 26, 2019, at 12:22 AM, Vladimir Makarov <vmaka...@redhat.com> wrote: >>> >>> Jeff Law recently found that my latest patch break some existing code >>> compilation (the code is big to make test out of it). >>> >>> Here is the patch to fix it. The patch was successfully bootstrapped on >>> x86-64. The patch actually results in less new transformations the >>> previous patch introduced. So it should be safe. >>> >>> Committed as rev. 269924. >> Hi Vladimir, >> >> FWIW, this fixed linux kernel builds on AArch64 and ARM, which your first >> patch caused. >> >> The failure was: >> === >> slub.s: Assembler messages: >> slub.s:26: Error: reg pair must start from even reg at operand 1 -- `casp >> x1,x0,x3,x5,[x6]' >> === >> >> from a reduced testcase: >> === >> void *a; >> long b, c; >> void d(void) { >> typeof(0) e=0; >> asm(" casp\t%[old1], %[old2], %[new1], %[new2], %[v]\n" >> : [old1] "+&r"(b), [old2] "+&r"(c), [v] "+Q"(a) >> : [new1] "r"(d), [new2] "r"(e)); >> } >> === >> >> Is this the same bug that Jeff reported? >> > Yes, it looks similar (reg pair and casp). I did know it was a kernel. I > only had a preprocessed file slub.i. > > The reduced case is actually wrong. The constraints +&r does not guarantee > that b and c will be in the subsequent regs.
Right, this was reduction artifact. > In the original test case b and c were also local *register* variables (x0 > and x1). Generally speaking even this does no guarantee (according to the > documentation) that the original variable values will be in subsequent regs > for casp. I don't follow. Do you mean that in the below testcase it's not guaranteed that casp will get its first two arguments in x0 and x1? (If so, why?) === void *a; long b, c; void d(void) { typeof(0) e=0; register long x0 asm ("x0") = b; register long x1 asm ("x1") = c; asm(" casp\t%[old1], %[old2], %[new1], %[new2], %[v]\n" : [old1] "+&r"(b), [old2] "+&r"(c), [v] "+Q"(a) : [new1] "r"(d), [new2] "r"(e)); } === IIRC, there is plenty of syscall code in glibc that relies on asms getting variables in "right" registers. > But as people assume such (undocumented) semantics, we should maintain this. Regards, -- Maxim Kuvyrkov www.linaro.org