On Mon, Mar 19, 2018 at 08:38:00PM +0000, Michael Matz wrote: > > Ah, ok, but > > asm volatile ("" : "=m,m" (b), "=r,r" (b) : "1,p" (b)); > > ICEs the same way, and that should be valid even according to the above > > description. > > Yes that's valid and shouldn't ICE.
I will change the testcase in the patch to the above to make it valid. > > > > if (! REG_P (output) > > > > || rtx_equal_p (output, input) > > > > || (GET_MODE (input) != VOIDmode > > > > - && GET_MODE (input) != GET_MODE (output))) > > > > + && GET_MODE (input) != GET_MODE (output)) > > > > + || !(REG_P (input) || SUBREG_P (input) > > > > + || MEM_P (input) || CONSTANT_P (input))) > > > > > > I'd only allow REG_P (input) as well, not any of the other forms. > > > > I'll try to gather some statistics on what kind of inputs appear there > > during bootstrap/regtest and will try to write a few testcases to see > > if just || ! REG_P (output) is sufficient or not. > > I think you don't need to try too hard. The function is designed to > handle the situation where the matching constraint is a result from an > input-output constraint, not for improving arbitrary matching constraints. > As such the expected situation is that input and output are lvalues, and > hence (when their type is anything sensible) gimple registers, and > therefore pseudos at RTL time. It is very common that input is one of the above cases, during x86_64-linux and i686-linux bootstraps+regtests I got: 13201x CONST_INT, 1959x MEM, 114x SUBREG, 110x SYMBOL_REF, 2x PLUS (the new testcase only) and most of those were actually from input-output constraints, like: var = 1; asm ("" : "+g" (var)); var2 = &static_var3; asm ("" : "+g" (var2)); etc. I believe the mini-pass does a useful transformation for these that ought to make it easier for reload to actually handle the matching constraints. Consider: long a, b, c, d; long f1 (void) { long r = 1; long s = 2; long t = 3; long u = 4; asm volatile ("" : "+g" (r), "+g" (s), "+g" (t), "+g" (u) : : "ax", "bx", "cx", "dx", "bp", "si", "di", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"); return r + s + t + u; } This ought to be reloadable, by spilling r, s, t, u into stack slots and using NN(%rsp) for those, and the patch with the || !(REG_P (input) || SUBREG_P (input) || MEM_P (input) || CONSTANT_P (input))) rather than just || ! REG_P (input)) attempts to help that by forcing the constants into the output pseudo. Similarly for &static_var (SYMBOL_REF), loads from some memory (MEM), or e.g. generic vector casts (SUBREG). Seems LRA gives up on it anyway, which to me looks like a LRA bug (it works with "+rm" instead of "+g"). Tried also: long a, b, c, d; long f1 (void) { long r = 1; long s = 2; long t = 3; long u = 4; asm volatile ("" : "+g" (r), "+g" (s), "+g" (t), "+g" (u) : : "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); return r + s + t + u; } on s390x with -O2 {-mno-lra,-mlra} to test both reload and LRA, LRA ICEs on it, reload just gives up, but again it ought to be reloadable. > You could basically reject any constraint that isn't just a single integer > (i.e. anything with not only digits after the optional '%') and still > handle the sitatuations for which this function was invented. I.e. like > this: > > Index: function.c > =================================================================== > --- function.c (revision 254008) > +++ function.c (working copy) > @@ -6605,7 +6605,7 @@ match_asm_constraints_1 (rtx_insn *insn, > constraint++; > > match = strtoul (constraint, &end, 10); > - if (end == constraint) > + if (end == constraint || *end) > continue; That wouldn't handle e.g. asm volatile ("" : "=m,m" (b), "=r,r" (b) : "1,1" (b)); case. Jakub