On Thu, Nov 5, 2020 at 9:56 AM Uros Bizjak <ubiz...@gmail.com> wrote: > > 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?
Well, I think we should fix typeof to not retain the address space. It's probably our implementation detail of having those in TYPE_QUALS that exposes the issue and not standard mandated. The rvalue trick is to avoid depending on a "fixed" GCC. Joseph should know how typeof should behave here. Richard. > > 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.