https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125941
--- Comment #3 from Tamar Christina <tnfchris at gcc dot gnu.org> --- (In reply to Christopher Bazley from comment #2) > > So if the ticket is about the spills then that's not an issue. if it's > > about adding PMOV support, then yes :) > > The context is this email thread: > https://inbox.sourceware.org/gcc-patches/CAFiYyc19Ks7- > [email protected]/ > > Richard Biener is saying that the CTOR was previously 'invalid', although > the test is pre-existing and the test passes without the assertion that he > wants to add. He is also saying that vec_initvnx16bibi must be implemented. > > It sounds as though you are saying that there is nothing wrong with the code > currently generated by GCC, despite the fact that vec_initvnx16bibi has not > been implemented. Correct, I don't think Richi is right here. Predicate registers are 1/8th the size of a vector register. The register above at VNx16BI is fully packed. there are no "bits to clear" and so the constructor was perfectly valid. A possibly invalid one is #include <arm_sve.h> #define VECT_CSTN { -1, t (svpfalse ()) } int __attribute__ ((noipa)) t (svbool_t) { return -1; } svbool_t __attribute__ ((noipa)) func_init4 () { svbool_t temp = VECT_CSTN; return temp; } where in GIMPLE you'd have svbool_t temp; int _1; <signed-boolean:1> _2; <bb 2> [local count: 1073741824]: _1 = t ({ 0, ... }); _2 = _1 != 0; temp_5 = {-1, _2}; return temp_5; But if you look at the generated code: addpl x2, sp, #7 addpl x1, sp, #7 pfalse p3.b add x2, x2, 16 addpl x0, sp, #6 add x1, x1, 16 add x0, x0, 16 str p3, [x1] mov w1, 1 strh w1, [x2] csetm w1, ne ldr p3, [x2] str p3, [x0] ldrh w0, [x0] bfi w0, w1, 1, 1 addpl x1, sp, #6 add x1, x1, 16 strh w0, [x1] ldr p0, [x1] ldp x29, x30, [sp] addvl sp, sp, #1 add sp, sp, 16 it's using the stack to construct the predicate because it has to set 1 bit at a time. But the zero-ing is done by the initial pfalse p3.b so this is semantically correct as well. In RTL we have (insn 8 7 9 2 (set (reg:VNx16BI 105 [ temp_5 ]) (const_vector:VNx16BI repeat [ (const_int 0 [0]) ])) "cops.c":14:12 discrim 1 -1 (nil)) which is generated by this clear /* Inform later passes that the old value is dead. */ if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u)) { emit_move_insn (target, CONST0_RTX (mode)); cleared = 1; } so it was always clearing it. > > Would adding PMOV support entail implementing vec_initvnx16bibi? For all > targets, or only for targets with SVE2p1? This is one where the semantics of the instruction kinda makes it hard. PMOV is a data to predicate vector transfer. But to make the register the ugliness here is in the fact that every element has to be converted to BImode. This is a case where the C style initializers don't match up with the svbool_t type and so it's a bit YOLO. For the above I think the best solution is to replace the expression before expansion to one that produces a boolean vector from data. So essentially svbool_t __attribute__ ((noipa)) func_init5 () { svint8_t temp = VECT_CSTN; return svcmpne_n_s8 (svptrue_b8 (), temp, 0); } This would then trigger the new defined zero-ing semantics and so you get func_init5: stp x29, x30, [sp, -16]! pfalse p0.b mov x29, sp bl t mvni v30.2s, 0 ptrue p0.b, all adrp x1, .LC0 ldp x29, x30, [sp], 16 add x1, x1, :lo12:.LC0 ld1rqb z31.b, p0/z, [x1] insr z31.b, w0 insr z31.b, b30 cmpne p0.b, p0/z, z31.b, #0 ret so in GIMPLE I think we want to have svint8_t temp; int _1; signed char _2; svbool_t _6; <bb 2> [local count: 1073741824]: _1 = t ({ 0, ... }); _2 = (signed char) _1; temp_5 = {-1, _2}; _6 = temp_5 != { 0, ... }; return _6; instead.
