On Wed, Sep 18, 2024 at 03:53:37PM +0200, Michael Matz wrote:
> Hello,
> 
> On Thu, 12 Sep 2024, Stefan Schulze Frielinghaus wrote:
> 
> > > > #define call_on_stack(stack, func, asm_call, argconstr...)              
> > > > \
> > > > {                                                                       
> > > > \
> > > >          register void *tos asm("r11");                                 
> > > >  \
> > > >                                                                         
> > > >  \
> > > >          tos = ((void *)(stack));                                       
> > > >  \
> > > >                                                                         
> > > >  \
> > > >          asm_inline volatile(                                           
> > > >  \
> > > >          "movq   %%rsp, (%[tos])                         \n"            
> > > >  \
> > > >          "movq   %[tos], %%rsp                           \n"            
> > > >  \
> > > >                                                                         
> > > >  \
> > > >          asm_call                                                       
> > > >  \
> > > >                                                                         
> > > >  \
> > > >          "popq   %%rsp                                   \n"            
> > > >  \
> > > >                                                                         
> > > >  \
> > > >          : "+r" (tos), ASM_CALL_CONSTRAINT                              
> > > >  \
> > > >          : [__func] "i" (func), [tos] "r" (tos) argconstr               
> > > >  \
> > > >          : "cc", "rax", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10",  
> > > >  \
> > > >            "memory"                                                     
> > > >  \
> > > >          );                                                             
> > > >  \
> > > > }
> > 
> > I didn't find documentation how "digit references" behave in combination
> > with register asm.
> 
> Because noone thought of that corner case while documenting stuff :-)
> 
> As you say: it only works because the involved inputs/outputs are the same 
> expression.  If they weren't the inconsistency would be detected in 
> reload/LRA when the necessary reloads would need to be generated and the 
> pass would find that that's impossible.
> 
> Now, question is, what to do in this case in the light of a new feature.  
> I would say that while perhaps sometimes convenient it's more likely to be 
> a programmers fault, so for your new hardreg constraints it seems better 
> to ...
> 
> > Anyway, I digress.  I haven't made up my mind how hard register
> > constraints should behave in those cases, i.e., in cases where multiple
> > inputs share the same register.  If the inputs are different or may be
> > different, then we can reject those programs.
> > 
> > asm ("" : "={r4}" (x) : "{r5}" (42), "{r5}" (24));
> > 
> > Whereas if the operands are provable equal (assuming y is not volatile)
> > 
> > asm ("" : "={r4}" (x) : "{r5}" (y), "{r5}" (y));
> > 
> > we could accept those programs.  Currently, I error out even for
> > programs of the latter form which may be a bit to restrictive.
> 
> ... do exactly this, error out unconditionally.  I wouldn't change 
> behaviour for existing features, i.e. register-asm vars plus matching 
> constraints (if for inout operands, or explicit matching constraints 
> doesn't matter) because there's existing usage that happens to work fine.
> 
> Why unconditionally and not just "when expressions are different"?  
> Because the latter is inherently hard to see when optimizations are 
> involved: is "(a + 0)" the same as "(a)"?  At which optimization levels?
> What if the "0" is an expression that needs further analysis to see that 
> it's actually zero?  And so on.

Thanks for sharing this.  I also tend to error out in those cases as it
rather looks like a programming error.  I came up with an updated
version just a few minutes ago where I added some documentation which
also discusses this.  I also added some discussion for output operands
where I also tend to error out because those look like programming
errors.

> 
> If it's not easily possible to error out only for the new hard-reg 
> constraints, and accept whatever is there for register-asm vars and 
> matching constraints, then I would opt to also _not_ error out for the new 
> feature, though.  Essentially that's saying that if the user writes 
> wacky code then its their responsibility that everything works out, which 
> is exactly what the current implementation does: if at the end no reloads 
> are required, it's fine (because it indeed adheres to all given 
> constraints!), otherwise we give an error.

I will have a look and try to distinguish between both mechanisms during
error checking.

Thanks!
Stefan

Reply via email to