https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111150
Bug ID: 111150 Summary: (vec CMP vec) != (vec CMP vec) should just produce (vec CMP vec) ^ (vec CMP vec) Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: enhancement Priority: P3 Component: tree-optimization Assignee: pinskia at gcc dot gnu.org Reporter: pinskia at gcc dot gnu.org Target Milestone: --- Take: ``` typedef int v4si __attribute((__vector_size__(4*sizeof(int)))); v4si f2_(v4si a, v4si b, v4si c, v4si d) { v4si X = a == b; v4si Y = c == d; return (X != Y); } ``` Currently we produce on x86_64 -O2: ``` pcmpeqd %xmm1, %xmm0 pcmpeqd %xmm3, %xmm2 pxor %xmm1, %xmm1 pcmpeqd %xmm2, %xmm0 pcmpeqd %xmm1, %xmm0 ``` But we should produce: ``` pcmpeqd %xmm1, %xmm0 pcmpeqd %xmm3, %xmm2 pxor %xmm2, %xmm0 ``` In forwprop1 we have: ``` _1 = a_4(D) == b_5(D); X_6 = VEC_COND_EXPR <_1, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; _2 = c_7(D) == d_8(D); Y_9 = VEC_COND_EXPR <_2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; _3 = X_6 != Y_9; ``` But we can push != further up since -1 != 0 is true. basically in scalar we have: (a ? -1 : 0) != (b ? -1 : 0) but we know that is really `(a^b) ? -1 : 0` Now in theory you could do the full expansion for this but I think we should just handle the case where we have -1 and 0.