On Thu, Nov 5, 2020 at 8:26 AM Richard Biener <richard.guent...@gmail.com> wrote: > > On Wed, Nov 4, 2020 at 7:33 PM Uros Bizjak via Gcc <gcc@gcc.gnu.org> wrote: > > > > Hello! > > > > I was looking at the recent linux patch series [1] where segment > > qualifiers (named address spaces) were introduced to handle percpu > > variables. In the patch [2], the author mentions that: > > > > --q-- > > Unfortunately, gcc does not provide a way to remove segment > > qualifiers, which is needed to use typeof() to create local instances > > of the per-cpu variable. For this reason, do not use the segment > > qualifier for per-cpu variables, and do casting using the segment > > qualifier instead. > > --/q-- > > > > The core of the problem can be seen with the following testcase: > > > > --cut here-- > > #define foo(_var) \ > > ({ \ > > typeof(_var) tmp__; \ > > 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: --cut here-- typedef struct { short a; short b; } pair_t; #define foo(_var) \ ({ \ typeof((typeof(_var))0) tmp__; \ asm ("mov %1, %0" : "=r"(tmp__) : "m"(_var)); \ tmp__; \ }) __seg_fs pair_t x; pair_t test (void) { pair_t y; y = foo (x); return y; } --cut here-- So, what about introducing e.g. typeof_noas (not sure about the name) that would simply strip the address space from typeof? > Basically I try to get at a rvalue for the typeof. > > Is there a way to query the address space of an object so I can > put another variable in the same address space? I think that would go hand in hand with the above typeof_noas. Perhaps typeof_as, that would return the address space of the variable? > > asm ("mov %1, %0" : "=r"(tmp__) : "m"(_var)); \ > > tmp__; \ > > }) > > > > __seg_fs int x; > > > > int test (void) > > { > > int y; > > > > y = foo (x); > > return y; > > } > > --cut here-- > > > > when compiled with -O2 for x86 target, the compiler reports: > > > > pcpu.c: In function ‘test’: > > pcpu.c:14:3: error: ‘__seg_fs’ specified for auto variable ‘tmp__’ > > > > It looks to me that the compiler should remove address space > > information when typeof is used, otherwise, there is no way to use > > typeof as intended in the above example. > > > > A related problem is exposed when we want to cast address from the > > named address space to a generic address space (e.g. to use it with > > LEA): > > > > --cut here-- > > typedef __UINTPTR_TYPE__ uintptr_t; > > > > __seg_fs int x; > > > > uintptr_t test (void) > > { > > uintptr_t *p = (uintptr_t *) &y; > > uintptr_t *p = (uintptr_t *)(uintptr_t) &y; Indeed, this works as expected. > 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: as1.c:10:49: error: memory input 1 is not directly addressable Uros.