Hello, This patch improves reassociation folding for comparision. It expands expressions within binary-AND/OR expression like (X | Y) == 0 to (X == 0 && Y == 0) and (X | Y) != 0 to (X != 0 || Y != 0). This is necessary to allow better reassociation on weak pre-folded logical expressions. This unfolding gets undone anyway later by pass, so no disadvantage gets introduced. Also while going through BB-list, it tries to do some little type-sinking for SSA sequences like "D1 = (type) bool1; D2 = (type) bool2; D3 = D1 & D2;' to 'D1 = bool1 & bool2; D2 = (type) D1;'. This folding has the advantage to see better through intermediate results with none-boolean type. The function eliminate_redundant_comparison () got reworded so, that doesn't break in all cases. It now continues to find duplicates and tries to find inverse variant (folded to constant). By this change we don't combine possible weak optimizations too fast, before we can find and handle inverse or duplicates. ChangeLog * tree-ssa-reassoc.c (is_boolean_compatible_type_p): New helper. (is_ior_ne_eq_cmp): Likewise. (build_inner_expand_ne_eq_cmp): Likewise. (build_expand_ne_eq_cmp): Likewise. (sink_cast_and_expand): Likewise. (build_and_add_sum): Add forward declaration. (remove_visited_stmt_chain): Likewise. (build_and_add_sum): Allow generation of unary expression. (eliminate_redundant_comparison): Rework this routine. (break_up_subtract_bb): Rename to break_up_operation_bb. Additional do logical unfolding for optimization and primitive type-sinking for type-casts on boolean-kind (do_reassoc): Rename break_up_subtract_bb to break_up_operation_bb. ChangeLog * gcc.dg/binop-tand1.c * gcc.dg/binop-tand2.c * gcc.dg/binop-tand3.c * gcc.dg/binop-tand4.c * gcc.dg/binop-tor1.c * gcc.dg/binop-tor2.c * gcc.dg/binop-tor3.c * gcc.dg/binop-tor4.c * gcc.dg/binop-tor5.c Bootstrapped and tested for x86_64-pc-linux-gnu for all standard languages plus ADA and Obj-C++. Ok for apply? Regards, Kai