On Tue, Aug 23, 2011 at 1:11 PM, Artem Shinkarov <artyom.shinkar...@gmail.com> wrote: > On Tue, Aug 23, 2011 at 11:56 AM, Richard Guenther > <richard.guent...@gmail.com> wrote: >> On Tue, Aug 23, 2011 at 12:45 PM, Artem Shinkarov >> <artyom.shinkar...@gmail.com> wrote: >>> I'm confused. >>> There is a set of problems which are tightly connected and you address >>> only one one of them. >>> >>> I need to do something with C_MAYBE_CONST_EXPR node to allow the >>> gimplification of the expression. In order to achieve that I am >>> wrapping expression which can contain C_MAYBE_EXPR_NODE into >>> SAVE_EXPR. This works fine, but, the vector condition is lifted out. >>> So the question is how to get rid of C_MAYBE_CONST_EXPR nodes, making >>> sure that the expression is still inside VEC_COND_EXPR? >> >> I can't answer this, but no C_MAYBE_CONST_EXPR nodes may survive >> until gimplification. I thought c_fully_fold is exactly used (instead >> of c_save_expr) because it _doesn't_ wrap things in C_MAYBE_CONST_EXPR >> nodes. Instead you delay that (well, commented out in your patch). > > Ok. So for the time being save_expr is the only way that we know to > avoid C_MAYBE_CONST_EXPR nodes. > >>> All the rest is fine -- a > b is transformed to VEC_COND_EXPR of the >>> integer type, and when we are using it we can add != 0 to the mask, no >>> problem. The problem is to make sure that the vector expression is not >>> lifted out from the VEC_COND_EXPR and that C_MAYBE_CONST_EXPRs are >>> also no there at the same time. >> >> Well, for example for floating-point comparisons and -fnon-call-exceptions >> you _will_ get comparisons lifted out of the VEC_COND_EXPR. But >> that shouldn't be an issue because C semantics are ensured for >> the mask ? v0 : v1 source form by changing it to mask != 0 ? v0 : v1 and >> the VEC_COND_EXPR semantic for a non-comparison mask operand >> is (v0 & mask) | (v1 & ~mask). Which means that we have to be able to >> expand mask = v0 < v1 anyway, but we'll simply expand it if it were >> VEC_COND_EXPR <v0<v1, {-1,}, {0,}>. > > Richard, I think you almost get it, but there is a tiny thing you have missed. > Look, let's assume, that by some reason when we gimplified a > b, the > comparison was lifted out. So we have the following situation: > > D.1 = a > b; > comp = vcond<D.1, v0, v1> > ... > > Ok? > Now, I fully agree that we want to treat lifted a > b as VCOND. Now, > what I am doing in the veclower is when I meet vector comparison a > > b, I wrap it in the VCOND, otherwise it would not be recognized by > optabs. literally I am doing: > > rhs = gimplify_build3 (gsi, VEC_COND_EXPR, a, b, {-1}, {0}> > > And here is a devil hidden. By some reason, when this expression is > gimplified, a > b is lifted again and is left outside the > VEC_COND_EXPR, and that is the problem I am trying to fight with. Have > any ideas what could be done here?
Well, don't do it. Check if the target can expand D.1 = a > b; via feeding it vcond <a < b, {-1,...}, {0,...} > and if not, expand it piecewise in veclower. If it can handle it - leave it alone! In expand_expr_real_2 add to the EQ_EXPR (etc.) case the case of a vector-typed comparison and use the vcond optab for it, again via vcond <a < b, {-1,...}, {0,...} >. If you look at the EQ_EXPR case it dispatches to do_store_flag - that's the best place to handle vector-typed compares. Richard.