https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114084
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Or perhaps the if (ok && ((var0 != 0) + (var1 != 0) + (minus_var0 != 0) + (minus_var1 != 0) + (con0 != 0) + (con1 != 0) + (minus_con0 != 0) + (minus_con1 != 0) + (lit0 != 0) + (lit1 != 0) + (minus_lit0 != 0) + (minus_lit1 != 0)) > 2) condition should be amended to avoid the reassociation in cases where clearly nothing good can come out of that. Which is if the association actually doesn't reshuffle anything. (var0 == 0) || (var1 == 0) && (and similarly for the other 5 pairs) and (ignoring the minus_* stuff that would need more thoughts on it) (con0 != 0 && lit0 != 0) || (con1 != 0 && lit1 != 0), then it reassociates to the original stuff in op0 and original stuff in op1, no change. But how the minus_* plays together with this is harder. Perhaps if lazy we could have a bool var whether there has been any association between subtrees from original op0 and op1, initially set to false and set if we associate_trees between something that comes from op0 and op1, and only do the final associate_trees if that is the case, because if not, it should be folding of the individual suboperands, not reassociation.