On Thu, Nov 5, 2020 at 10:36 AM Alexander Monakov <amona...@ispras.ru> wrote: > > On Thu, 5 Nov 2020, Uros Bizjak via Gcc wrote: > > > > Looks like writing > > > > > > typeof((typeof(_var))0) tmp__; > > > > > > makes it work. Assumes there's a literal zero for the type of course. > > > > This is very limiting assumption, which already breaks for the following > > test: > > To elaborate Richard's idea, you need a way to decay lvalue to rvalue inside > the typeof to strip the address space; if you need the macro to work for > more types than just scalar types, the following expression may be useful: > > typeof(0?(_var):(_var)) > > (though there's a bug: +(_var) should also suffice for scalar types, but > somehow GCC keeps the address space on the resulting rvalue) > > But I wonder if you actually need this at all: > > > > works around the warning. I think the wording you cite > > > suggests (uintptr_t) &y here, not sure if there's a reliable > > > way to get the lea with just a uintptr_t operand though. > > > > No, because we have to use the "m" constraint for the LEA. We get the > > following error: > > What is the usecase for stripping the address space for asm operands?
Please see the end of [2], where the offset to <mem> is passed in %rsi to the call to this_cpu_cmpxchg16b_emu. this_cpu_cmpxchg16b_emu implements access with PER_CPU_VAR((%rsi)), which expands to %gs:(%rsi), so it is the same as %gs:<mem> in cmpxchg16b alternative. The offset is loaded by lea <mem>, %rsi to %rsi reg. > From reading the patch I understand the kernel wants to pass qualified > lvalues to inline assembly to get > > lea <reg>, %fs:<mem> No, this will emit an assembler warning that "segment override on 'lea' is ineffectual". Uros. > LEA without the %fs will produce the offset within the segment, which > you can obtain simply by casting the pointer to intptr_t in the first place. > Alexander