On Tue, 4 May 2021, Jakub Jelinek wrote: > Hi! > > genericize_spaceship genericizes i <=> j to approximately > ({ int c; if (i == j) c = 0; else if (i < j) c = -1; else c = 1; c; }) > for strong ordering and > ({ int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; > else c = 2; c; }) > for partial ordering. > The C++ standard supports then == or != comparisons of that against > strong/partial ordering enums, or </<=/==/!=/>/>= comparisons of <=> result > against literal 0. > > In some cases we already optimize that but in many cases we keep performing > all the 2 or 3 comparisons, compute the spaceship value and then compare > that. > > The following patch recognizes those patterns if the <=> operands are > integral types or floating point (the latter only for -ffast-math) and > optimizes it to the single comparison that is needed (plus adds debug stmts > if needed for the spaceship result). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > There are two things I'd like to address in a follow-up: > 1) if (HONOR_NANS (TREE_TYPE (lhs1)) || HONOR_SIGNED_ZEROS (TREE_TYPE (lhs1))) > is what I've copied from elsewhere in phiopt, but thinking about it, > alll we care is probably only HONOR_NANS, the matched pattern starts with > == or != comparison and branches to the PHI bb with -1/0/1/2 result if it is > equal, which should be the case for signed zero differences. > 2) the pr94589-2.C testcase should be matching just 12 times each, but runs > into operator>=(strong_ordering, unspecified) being defined as > (_M_value&1)==_M_value > rather than _M_value>=0. When not honoring NaNs, the 2 case should be > unreachable and so (_M_value&1)==_M_value is then equivalent to _M_value>=0, > but is not a single use but two uses. I'll need to pattern match that case > specially. > > 2021-05-04 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/94589 > * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Call > spaceship_replacement. > (cond_only_block_p, spaceship_replacement): New functions. > > * gcc.dg/pr94589-1.c: New test. > * gcc.dg/pr94589-2.c: New test. > * gcc.dg/pr94589-3.c: New test. > * gcc.dg/pr94589-4.c: New test. > * g++.dg/opt/pr94589-1.C: New test. > * g++.dg/opt/pr94589-2.C: New test. > * g++.dg/opt/pr94589-3.C: New test. > * g++.dg/opt/pr94589-4.C: New test. > > --- gcc/tree-ssa-phiopt.c.jj 2021-05-02 10:17:49.095397758 +0200 > +++ gcc/tree-ssa-phiopt.c 2021-05-03 17:49:54.233300624 +0200 > @@ -64,6 +64,8 @@ static bool abs_replacement (basic_block > edge, edge, gimple *, tree, tree); > static bool xor_replacement (basic_block, basic_block, > edge, edge, gimple *, tree, tree); > +static bool spaceship_replacement (basic_block, basic_block, > + edge, edge, gimple *, tree, tree); > static bool cond_removal_in_popcount_clz_ctz_pattern (basic_block, > basic_block, > edge, edge, gimple *, > tree, tree); > @@ -357,6 +359,8 @@ tree_ssa_phiopt_worker (bool do_store_el > cfgchanged = true; > else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) > cfgchanged = true; > + else if (spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) > + cfgchanged = true; > } > } > > @@ -1806,6 +1810,420 @@ minmax_replacement (basic_block cond_bb, > > return true; > } > + > +/* Return true if the only executable statement in BB is a GIMPLE_COND. */ > + > +static bool > +cond_only_block_p (basic_block bb) > +{ > + /* BB must have no executable statements. */ > + gimple_stmt_iterator gsi = gsi_after_labels (bb); > + if (phi_nodes (bb)) > + return false; > + while (!gsi_end_p (gsi)) > + { > + gimple *stmt = gsi_stmt (gsi); > + if (is_gimple_debug (stmt)) > + ; > + else if (gimple_code (stmt) == GIMPLE_NOP > + || gimple_code (stmt) == GIMPLE_PREDICT > + || gimple_code (stmt) == GIMPLE_COND) > + ; > + else > + return false; > + gsi_next (&gsi); > + } > + return true; > +} > + > +/* Attempt to optimize (x <=> y) cmp 0 and similar comparisons. > + For strong ordering <=> try to match something like: > + <bb 2> : > + if (x_4(D) != y_5(D)) > + goto <bb 3>; [INV] > + else > + goto <bb 6>; [INV] > + > + <bb 3> : > + if (x_4(D) < y_5(D)) > + goto <bb 6>; [INV] > + else > + goto <bb 4>; [INV] > + > + <bb 4> : > + > + <bb 6> : > + # iftmp.0_2 = PHI <1(4), 0(2), -1(3)> > + _1 = iftmp.0_2 == 0; > + > + and for partial ordering <=> something like: > + > + <bb 2> : > + if (a_3(D) == b_5(D)) > + goto <bb 6>; [50.00%] > + else > + goto <bb 3>; [50.00%] > + > + <bb 3> [local count: 536870913]: > + if (a_3(D) < b_5(D)) > + goto <bb 6>; [50.00%] > + else > + goto <bb 4>; [50.00%] > + > + <bb 4> [local count: 268435456]: > + if (a_3(D) > b_5(D)) > + goto <bb 6>; [50.00%] > + else > + goto <bb 5>; [50.00%] > + > + <bb 5> [local count: 134217728]: > + > + <bb 6> [local count: 1073741824]: > + # SR.27_4 = PHI <0(2), -1(3), 1(4), 2(5)> > + _2 = SR.27_4 > 0; */
Can you in the above IL snippets mark COND_BB and MIDDLE_BB? > +static bool > +spaceship_replacement (basic_block cond_bb, basic_block middle_bb, > + edge e0, edge e1, gimple *phi, This could be a gphi * > + tree arg0, tree arg1) > +{ > + if (!INTEGRAL_TYPE_P (TREE_TYPE (PHI_RESULT (phi))) > + || TYPE_UNSIGNED (TREE_TYPE (PHI_RESULT (phi))) > + || !tree_fits_shwi_p (arg0) > + || !tree_fits_shwi_p (arg1) > + || !IN_RANGE (tree_to_shwi (arg0), -1, 2) > + || !IN_RANGE (tree_to_shwi (arg1), -1, 2)) > + return false; > + > + use_operand_p use_p; > + gimple *use_stmt; > + if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))) > + return false; > + if (!single_imm_use (PHI_RESULT (phi), &use_p, &use_stmt)) > + return false; > + enum tree_code cmp; > + tree lhs, rhs; > + if (gimple_code (use_stmt) == GIMPLE_COND) > + { > + cmp = gimple_cond_code (use_stmt); > + lhs = gimple_cond_lhs (use_stmt); > + rhs = gimple_cond_rhs (use_stmt); > + } > + else if (is_gimple_assign (use_stmt)) > + { > + if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS) > + { > + cmp = gimple_assign_rhs_code (use_stmt); > + lhs = gimple_assign_rhs1 (use_stmt); > + rhs = gimple_assign_rhs2 (use_stmt); > + } > + else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR) > + { > + tree cond = gimple_assign_rhs1 (use_stmt); > + if (!COMPARISON_CLASS_P (cond)) > + return false; > + cmp = TREE_CODE (cond); > + lhs = TREE_OPERAND (cond, 0); > + rhs = TREE_OPERAND (cond, 1); > + } > + else > + return false; > + } > + else > + return false; > + switch (cmp) > + { > + case EQ_EXPR: > + case NE_EXPR: > + case LT_EXPR: > + case GT_EXPR: > + case LE_EXPR: > + case GE_EXPR: > + break; > + default: > + return false; > + } > + if (lhs != PHI_RESULT (phi) > + || !tree_fits_shwi_p (rhs) > + || !IN_RANGE (tree_to_shwi (rhs), -1, 1)) > + return false; > + > + if (!empty_block_p (middle_bb)) > + return false; > + > + basic_block phi_bb = gimple_bb (phi); > + gcc_assert (phi_bb == e0->dest && phi_bb == e1->dest); > + if (!IN_RANGE (EDGE_COUNT (phi_bb->preds), 3, 4)) > + return false; I guess this check could be done earlier. > + > + gcond *cond1 = as_a <gcond *> (last_stmt (cond_bb)); > + enum tree_code cmp1 = gimple_cond_code (cond1); > + if (cmp1 != LT_EXPR && cmp1 != GT_EXPR) > + return false; > + tree lhs1 = gimple_cond_lhs (cond1); > + tree rhs1 = gimple_cond_rhs (cond1); > + /* The optimization may be unsafe due to NaNs. */ > + if (HONOR_NANS (TREE_TYPE (lhs1)) || HONOR_SIGNED_ZEROS (TREE_TYPE (lhs1))) > + return false; > + if (TREE_CODE (lhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs1)) > + return false; > + if (TREE_CODE (rhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)) > + return false; > + > + if (!single_pred_p (cond_bb) || !cond_only_block_p (cond_bb)) > + return false; > + > + basic_block cond2_bb = single_pred (cond_bb); > + if (EDGE_COUNT (cond2_bb->succs) != 2) > + return false; > + edge cond2_phi_edge; > + if (EDGE_SUCC (cond2_bb, 0)->dest == cond_bb) > + { > + if (EDGE_SUCC (cond2_bb, 1)->dest != phi_bb) > + return false; > + cond2_phi_edge = EDGE_SUCC (cond2_bb, 1); > + } > + else if (EDGE_SUCC (cond2_bb, 0)->dest != phi_bb) > + return false; > + else > + cond2_phi_edge = EDGE_SUCC (cond2_bb, 0); > + tree arg2 = gimple_phi_arg_def (phi, cond2_phi_edge->dest_idx); > + if (!tree_fits_shwi_p (arg2)) > + return false; > + gimple *cond2 = last_stmt (cond2_bb); > + if (cond2 == NULL || gimple_code (cond2) != GIMPLE_COND) > + return false; > + enum tree_code cmp2 = gimple_cond_code (cond2); > + tree lhs2 = gimple_cond_lhs (cond2); > + tree rhs2 = gimple_cond_rhs (cond2); > + if (lhs2 == lhs1) > + { > + if (!operand_equal_p (rhs2, rhs1, 0)) > + return false; > + } > + else if (lhs2 == rhs1) > + { > + if (rhs2 != lhs1) > + return false; > + } > + else > + return false; > + tree arg3 = arg2; > + basic_block cond3_bb = cond2_bb; > + edge cond3_phi_edge = cond2_phi_edge; > + gimple *cond3 = cond2; > + enum tree_code cmp3 = cmp2; > + tree lhs3 = lhs2; > + tree rhs3 = rhs2; > + if (EDGE_COUNT (phi_bb->preds) == 4) > + { > + if (absu_hwi (tree_to_shwi (arg2)) != 1) > + return false; > + if (e1->flags & EDGE_TRUE_VALUE) > + { > + if (tree_to_shwi (arg0) != 2 > + || absu_hwi (tree_to_shwi (arg1)) != 1 > + || wi::to_widest (arg1) == wi::to_widest (arg2)) > + return false; > + } > + else if (tree_to_shwi (arg1) != 2 > + || absu_hwi (tree_to_shwi (arg0)) != 1 > + || wi::to_widest (arg0) == wi::to_widest (arg1)) > + return false; > + if (cmp2 != LT_EXPR && cmp2 != GT_EXPR) > + return false; > + /* if (x < y) goto phi_bb; else fallthru; > + if (x > y) goto phi_bb; else fallthru; > + bbx:; > + phi_bb:; > + is ok, but if x and y are swapped in one of the comparisons, > + or the comparisons are the same and operands not swapped, > + or second goto phi_bb is not the true edge, it is not. */ > + if ((lhs2 == lhs1) > + ^ (cmp2 == cmp1) > + ^ ((e1->flags & EDGE_TRUE_VALUE) != 0)) > + return false; > + if ((cond2_phi_edge->flags & EDGE_TRUE_VALUE) == 0) > + return false; > + if (!single_pred_p (cond2_bb) || !cond_only_block_p (cond2_bb)) > + return false; > + cond3_bb = single_pred (cond2_bb); > + if (EDGE_COUNT (cond2_bb->succs) != 2) > + return false; > + if (EDGE_SUCC (cond3_bb, 0)->dest == cond2_bb) > + { > + if (EDGE_SUCC (cond3_bb, 1)->dest != phi_bb) > + return false; > + cond3_phi_edge = EDGE_SUCC (cond3_bb, 1); > + } > + else if (EDGE_SUCC (cond3_bb, 0)->dest != phi_bb) > + return false; > + else > + cond3_phi_edge = EDGE_SUCC (cond3_bb, 0); > + arg3 = gimple_phi_arg_def (phi, cond3_phi_edge->dest_idx); > + cond3 = last_stmt (cond3_bb); > + if (cond3 == NULL || gimple_code (cond3) != GIMPLE_COND) > + return false; > + cmp3 = gimple_cond_code (cond3); > + lhs3 = gimple_cond_lhs (cond3); > + rhs3 = gimple_cond_rhs (cond3); > + if (lhs3 == lhs1) > + { > + if (!operand_equal_p (rhs3, rhs1, 0)) > + return false; > + } > + else if (lhs3 == rhs1) > + { > + if (rhs3 != lhs1) > + return false; > + } > + else > + return false; > + } > + else if (absu_hwi (tree_to_shwi (arg0)) != 1 > + || absu_hwi (tree_to_shwi (arg1)) != 1 > + || wi::to_widest (arg0) == wi::to_widest (arg1)) > + return false; > + > + if (!integer_zerop (arg3) || (cmp3 != EQ_EXPR && cmp3 != NE_EXPR)) > + return false; > + if ((cond3_phi_edge->flags & (cmp3 == EQ_EXPR > + ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE)) == 0) > + return false; > + > + /* lhs1 one_cmp rhs1 results in PHI_RESULT (phi) of 1. */ > + enum tree_code one_cmp; > + if ((cmp1 == LT_EXPR) > + ^ (!integer_onep ((e1->flags & EDGE_TRUE_VALUE) ? arg1 : arg0))) > + one_cmp = LT_EXPR; > + else > + one_cmp = GT_EXPR; > + > + enum tree_code res_cmp; > + switch (cmp) > + { > + case EQ_EXPR: > + if (integer_zerop (rhs)) > + res_cmp = EQ_EXPR; > + else if (integer_minus_onep (rhs)) > + res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR; > + else if (integer_onep (rhs)) > + res_cmp = one_cmp; > + else > + return false; > + break; > + case NE_EXPR: > + if (integer_zerop (rhs)) > + res_cmp = NE_EXPR; > + else if (integer_minus_onep (rhs)) > + res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR; > + else if (integer_onep (rhs)) > + res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR; > + else > + return false; > + break; > + case LT_EXPR: > + if (integer_onep (rhs)) > + res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR; > + else if (integer_zerop (rhs)) > + res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR; > + else > + return false; > + break; > + case LE_EXPR: > + if (integer_zerop (rhs)) > + res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR; > + else if (integer_minus_onep (rhs)) > + res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR; > + else > + return false; > + break; > + case GT_EXPR: > + if (integer_minus_onep (rhs)) > + res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR; > + else if (integer_zerop (rhs)) > + res_cmp = one_cmp; > + else > + return false; > + break; > + case GE_EXPR: > + if (integer_zerop (rhs)) > + res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR; > + else if (integer_onep (rhs)) > + res_cmp = one_cmp; > + else > + return false; > + break; > + default: > + gcc_unreachable (); > + } > + > + if (gimple_code (use_stmt) == GIMPLE_COND) > + { > + gcond *use_cond = as_a <gcond *> (use_stmt); > + gimple_cond_set_code (use_cond, res_cmp); > + gimple_cond_set_lhs (use_cond, lhs1); > + gimple_cond_set_rhs (use_cond, rhs1); > + } > + else if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS) > + { > + gimple_assign_set_rhs_code (use_stmt, res_cmp); > + gimple_assign_set_rhs1 (use_stmt, lhs1); > + gimple_assign_set_rhs2 (use_stmt, rhs1); > + } > + else > + { > + tree cond = build2 (res_cmp, TREE_TYPE (gimple_assign_rhs1 (use_stmt)), > + lhs1, rhs1); > + gimple_assign_set_rhs1 (use_stmt, cond); > + } > + update_stmt (use_stmt); > + if (cmp3 == EQ_EXPR) > + gimple_cond_make_true (as_a <gcond *> (cond3)); > + else > + gimple_cond_make_false (as_a <gcond *> (cond3)); > + update_stmt (cond3); I'm missing the removal of the PHI node - that's sth other phiopt transforms usually do. > + > + if (MAY_HAVE_DEBUG_BIND_STMTS) > + { > + use_operand_p use_p; > + imm_use_iterator iter; > + bool has_debug_uses = false; > + FOR_EACH_IMM_USE_FAST (use_p, iter, PHI_RESULT (phi)) > + { > + gimple *use_stmt = USE_STMT (use_p); > + gcc_assert (is_gimple_debug (use_stmt)); > + has_debug_uses = true; > + break; > + } > + > + if (has_debug_uses) > + { > + gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi)); > + tree type = TREE_TYPE (PHI_RESULT (phi)); > + tree temp1 = make_node (DEBUG_EXPR_DECL); > + DECL_ARTIFICIAL (temp1) = 1; > + TREE_TYPE (temp1) = type; > + SET_DECL_MODE (temp1, TYPE_MODE (type)); > + tree t = build2 (one_cmp, boolean_type_node, lhs1, rhs2); > + t = build3 (COND_EXPR, type, t, build_one_cst (type), > + build_int_cst (type, -1)); > + gimple *g = gimple_build_debug_bind (temp1, t, phi); > + gsi_insert_before (&gsi, g, GSI_SAME_STMT); > + tree temp2 = make_node (DEBUG_EXPR_DECL); > + DECL_ARTIFICIAL (temp2) = 1; > + TREE_TYPE (temp2) = type; > + SET_DECL_MODE (temp2, TYPE_MODE (type)); > + t = build2 (EQ_EXPR, boolean_type_node, lhs1, rhs2); > + t = build3 (COND_EXPR, type, t, build_zero_cst (type), temp1); > + g = gimple_build_debug_bind (temp2, t, phi); > + gsi_insert_before (&gsi, g, GSI_SAME_STMT); > + replace_uses_by (PHI_RESULT (phi), temp2); Please add a comment on what you are generating here. Do we handle COND_EXPRs in debug expr expansion at all? I suppose we need DW_OP_GNU_spaceship ;) Otherwise looks OK, not that I like such elaborate matching code much. Thanks, Richard. > + } > + } > + > + return true; > +} > > /* Convert > > --- gcc/testsuite/gcc.dg/pr94589-1.c.jj 2021-05-03 17:32:14.940203230 > +0200 > +++ gcc/testsuite/gcc.dg/pr94589-1.c 2021-05-03 17:54:33.081167518 +0200 > @@ -0,0 +1,35 @@ > +/* PR tree-optimization/94589 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -g0 -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) > (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */ > +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) > \[45]" 14 "optimized" } } */ > + > +#define A __attribute__((noipa)) > +A int f1 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == > 0; } > +A int f2 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != > 0; } > +A int f3 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c > 0; > } > +A int f4 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c < 0; > } > +A int f5 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c >= > 0; } > +A int f6 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c <= > 0; } > +A int f7 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == > -1; } > +A int f8 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != > -1; } > +A int f9 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c > > -1; } > +A int f10 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c <= > -1; } > +A int f11 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == > 1; } > +A int f12 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != > 1; } > +A int f13 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c < > 1; } > +A int f14 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c >= > 1; } > +A int f15 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == 0; } > +A int f16 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != 0; } > +A int f17 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c > 0; } > +A int f18 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c < 0; } > +A int f19 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c >= 0; } > +A int f20 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c <= 0; } > +A int f21 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == -1; } > +A int f22 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != -1; } > +A int f23 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c > -1; } > +A int f24 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c <= -1; } > +A int f25 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == 1; } > +A int f26 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != 1; } > +A int f27 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c < 1; } > +A int f28 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c >= 1; } > --- gcc/testsuite/gcc.dg/pr94589-2.c.jj 2021-05-03 17:32:17.950169407 > +0200 > +++ gcc/testsuite/gcc.dg/pr94589-2.c 2021-05-03 17:56:12.577049606 +0200 > @@ -0,0 +1,35 @@ > +/* PR tree-optimization/94589 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) > (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */ > +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) > 5\\.0" 14 "optimized" } } */ > + > +#define A __attribute__((noipa)) > +A int f1 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c == 0; } > +A int f2 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c != 0; } > +A int f3 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c > 0; } > +A int f4 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c < 0; } > +A int f5 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c >= 0; } > +A int f6 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c <= 0; } > +A int f7 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c == -1; } > +A int f8 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c != -1; } > +A int f9 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c > -1; } > +A int f10 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c <= -1; } > +A int f11 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c == 1; } > +A int f12 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c != 1; } > +A int f13 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c < 1; } > +A int f14 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c > = -1; else if (i > j) c = 1; else c = 2; return c >= 1; } > +A int f15 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c == 0; } > +A int f16 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c != 0; } > +A int f17 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c > 0; } > +A int f18 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c < 0; } > +A int f19 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c >= 0; } > +A int f20 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c <= 0; } > +A int f21 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c == -1; } > +A int f22 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c != -1; } > +A int f23 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c > -1; } > +A int f24 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c <= -1; } > +A int f25 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c == 1; } > +A int f26 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c != 1; } > +A int f27 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c < 1; } > +A int f28 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; > else if (i > 5.0) c = 1; else c = 2; return c >= 1; } > --- gcc/testsuite/gcc.dg/pr94589-3.c.jj 2021-05-03 17:32:19.998146397 > +0200 > +++ gcc/testsuite/gcc.dg/pr94589-3.c 2021-05-03 18:02:41.628678802 +0200 > @@ -0,0 +1,97 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 -g" } */ > + > +#include "pr94589-1.c" > + > +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () > +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () > + > +int > +main () > +{ > + C (f1, 7, 8, 0); > + C (f1, 8, 8, 1); > + C (f1, 9, 8, 0); > + C (f2, 7, 8, 1); > + C (f2, 8, 8, 0); > + C (f2, 9, 8, 1); > + C (f3, 7, 8, 0); > + C (f3, 8, 8, 0); > + C (f3, 9, 8, 1); > + C (f4, 7, 8, 1); > + C (f4, 8, 8, 0); > + C (f4, 9, 8, 0); > + C (f5, 7, 8, 0); > + C (f5, 8, 8, 1); > + C (f5, 9, 8, 1); > + C (f6, 7, 8, 1); > + C (f6, 8, 8, 1); > + C (f6, 9, 8, 0); > + C (f7, 7, 8, 1); > + C (f7, 8, 8, 0); > + C (f7, 9, 8, 0); > + C (f8, 7, 8, 0); > + C (f8, 8, 8, 1); > + C (f8, 9, 8, 1); > + C (f9, 7, 8, 0); > + C (f9, 8, 8, 1); > + C (f9, 9, 8, 1); > + C (f10, 7, 8, 1); > + C (f10, 8, 8, 0); > + C (f10, 9, 8, 0); > + C (f11, 7, 8, 0); > + C (f11, 8, 8, 0); > + C (f11, 9, 8, 1); > + C (f12, 7, 8, 1); > + C (f12, 8, 8, 1); > + C (f12, 9, 8, 0); > + C (f13, 7, 8, 1); > + C (f13, 8, 8, 1); > + C (f13, 9, 8, 0); > + C (f14, 7, 8, 0); > + C (f14, 8, 8, 0); > + C (f14, 9, 8, 1); > + D (f15, 4, 0); > + D (f15, 5, 1); > + D (f15, 6, 0); > + D (f16, 4, 1); > + D (f16, 5, 0); > + D (f16, 6, 1); > + D (f17, 4, 0); > + D (f17, 5, 0); > + D (f17, 6, 1); > + D (f18, 4, 1); > + D (f18, 5, 0); > + D (f18, 6, 0); > + D (f19, 4, 0); > + D (f19, 5, 1); > + D (f19, 6, 1); > + D (f20, 4, 1); > + D (f20, 5, 1); > + D (f20, 6, 0); > + D (f21, 4, 1); > + D (f21, 5, 0); > + D (f21, 6, 0); > + D (f22, 4, 0); > + D (f22, 5, 1); > + D (f22, 6, 1); > + D (f23, 4, 0); > + D (f23, 5, 1); > + D (f23, 6, 1); > + D (f24, 4, 1); > + D (f24, 5, 0); > + D (f24, 6, 0); > + D (f25, 4, 0); > + D (f25, 5, 0); > + D (f25, 6, 1); > + D (f26, 4, 1); > + D (f26, 5, 1); > + D (f26, 6, 0); > + D (f27, 4, 1); > + D (f27, 5, 1); > + D (f27, 6, 0); > + D (f28, 4, 0); > + D (f28, 5, 0); > + D (f28, 6, 1); > + return 0; > +} > --- gcc/testsuite/gcc.dg/pr94589-4.c.jj 2021-05-03 17:32:21.915124851 > +0200 > +++ gcc/testsuite/gcc.dg/pr94589-4.c 2021-05-03 18:12:50.748835798 +0200 > @@ -0,0 +1,97 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 -g -ffast-math" } */ > + > +#include "pr94589-2.c" > + > +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () > +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () > + > +int > +main () > +{ > + C (f1, 7.0, 8.0, 0); > + C (f1, 8.0, 8.0, 1); > + C (f1, 9.0, 8.0, 0); > + C (f2, 7.0, 8.0, 1); > + C (f2, 8.0, 8.0, 0); > + C (f2, 9.0, 8.0, 1); > + C (f3, 7.0, 8.0, 0); > + C (f3, 8.0, 8.0, 0); > + C (f3, 9.0, 8.0, 1); > + C (f4, 7.0, 8.0, 1); > + C (f4, 8.0, 8.0, 0); > + C (f4, 9.0, 8.0, 0); > + C (f5, 7.0, 8.0, 0); > + C (f5, 8.0, 8.0, 1); > + C (f5, 9.0, 8.0, 1); > + C (f6, 7.0, 8.0, 1); > + C (f6, 8.0, 8.0, 1); > + C (f6, 9.0, 8.0, 0); > + C (f7, 7.0, 8.0, 1); > + C (f7, 8.0, 8.0, 0); > + C (f7, 9.0, 8.0, 0); > + C (f8, 7.0, 8.0, 0); > + C (f8, 8.0, 8.0, 1); > + C (f8, 9.0, 8.0, 1); > + C (f9, 7.0, 8.0, 0); > + C (f9, 8.0, 8.0, 1); > + C (f9, 9.0, 8.0, 1); > + C (f10, 7.0, 8.0, 1); > + C (f10, 8.0, 8.0, 0); > + C (f10, 9.0, 8.0, 0); > + C (f11, 7.0, 8.0, 0); > + C (f11, 8.0, 8.0, 0); > + C (f11, 9.0, 8.0, 1); > + C (f12, 7.0, 8.0, 1); > + C (f12, 8.0, 8.0, 1); > + C (f12, 9.0, 8.0, 0); > + C (f13, 7.0, 8.0, 1); > + C (f13, 8.0, 8.0, 1); > + C (f13, 9.0, 8.0, 0); > + C (f14, 7.0, 8.0, 0); > + C (f14, 8.0, 8.0, 0); > + C (f14, 9.0, 8.0, 1); > + D (f15, 4.0, 0); > + D (f15, 5.0, 1); > + D (f15, 6.0, 0); > + D (f16, 4.0, 1); > + D (f16, 5.0, 0); > + D (f16, 6.0, 1); > + D (f17, 4.0, 0); > + D (f17, 5.0, 0); > + D (f17, 6.0, 1); > + D (f18, 4.0, 1); > + D (f18, 5.0, 0); > + D (f18, 6.0, 0); > + D (f19, 4.0, 0); > + D (f19, 5.0, 1); > + D (f19, 6.0, 1); > + D (f20, 4.0, 1); > + D (f20, 5.0, 1); > + D (f20, 6.0, 0); > + D (f21, 4.0, 1); > + D (f21, 5.0, 0); > + D (f21, 6.0, 0); > + D (f22, 4.0, 0); > + D (f22, 5.0, 1); > + D (f22, 6.0, 1); > + D (f23, 4.0, 0); > + D (f23, 5.0, 1); > + D (f23, 6.0, 1); > + D (f24, 4.0, 1); > + D (f24, 5.0, 0); > + D (f24, 6.0, 0); > + D (f25, 4.0, 0); > + D (f25, 5.0, 0); > + D (f25, 6.0, 1); > + D (f26, 4.0, 1); > + D (f26, 5.0, 1); > + D (f26, 6.0, 0); > + D (f27, 4.0, 1); > + D (f27, 5.0, 1); > + D (f27, 6.0, 0); > + D (f28, 4.0, 0); > + D (f28, 5.0, 0); > + D (f28, 6.0, 1); > + return 0; > +} > --- gcc/testsuite/g++.dg/opt/pr94589-1.C.jj 2021-05-03 15:24:02.002046458 > +0200 > +++ gcc/testsuite/g++.dg/opt/pr94589-1.C 2021-05-03 15:23:47.445210269 > +0200 > @@ -0,0 +1,33 @@ > +// PR tree-optimization/94589 > +// { dg-do compile { target c++20 } } > +// { dg-options "-O2 -g0 -fdump-tree-optimized" } > +// { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) > (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 12 "optimized" } } > +// { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) > \[45]" 12 "optimized" } } > + > +#include <compare> > + > +#define A __attribute__((noipa)) > +A bool f1 (int i, int j) { auto c = i <=> j; return c == 0; } > +A bool f2 (int i, int j) { auto c = i <=> j; return c != 0; } > +A bool f3 (int i, int j) { auto c = i <=> j; return c > 0; } > +A bool f4 (int i, int j) { auto c = i <=> j; return c < 0; } > +A bool f5 (int i, int j) { auto c = i <=> j; return c >= 0; } > +A bool f6 (int i, int j) { auto c = i <=> j; return c <= 0; } > +A bool f7 (int i, int j) { auto c = i <=> j; return c == > std::strong_ordering::less; } > +A bool f8 (int i, int j) { auto c = i <=> j; return c != > std::strong_ordering::less; } > +A bool f9 (int i, int j) { auto c = i <=> j; return c == > std::strong_ordering::equal; } > +A bool f10 (int i, int j) { auto c = i <=> j; return c != > std::strong_ordering::equal; } > +A bool f11 (int i, int j) { auto c = i <=> j; return c == > std::strong_ordering::greater; } > +A bool f12 (int i, int j) { auto c = i <=> j; return c != > std::strong_ordering::greater; } > +A bool f13 (int i) { auto c = i <=> 5; return c == 0; } > +A bool f14 (int i) { auto c = i <=> 5; return c != 0; } > +A bool f15 (int i) { auto c = i <=> 5; return c > 0; } > +A bool f16 (int i) { auto c = i <=> 5; return c < 0; } > +A bool f17 (int i) { auto c = i <=> 5; return c >= 0; } > +A bool f18 (int i) { auto c = i <=> 5; return c <= 0; } > +A bool f19 (int i) { auto c = i <=> 5; return c == > std::strong_ordering::less; } > +A bool f20 (int i) { auto c = i <=> 5; return c != > std::strong_ordering::less; } > +A bool f21 (int i) { auto c = i <=> 5; return c == > std::strong_ordering::equal; } > +A bool f22 (int i) { auto c = i <=> 5; return c != > std::strong_ordering::equal; } > +A bool f23 (int i) { auto c = i <=> 5; return c == > std::strong_ordering::greater; } > +A bool f24 (int i) { auto c = i <=> 5; return c != > std::strong_ordering::greater; } > --- gcc/testsuite/g++.dg/opt/pr94589-2.C.jj 2021-05-03 16:12:12.002540809 > +0200 > +++ gcc/testsuite/g++.dg/opt/pr94589-2.C 2021-05-03 16:16:53.194380966 > +0200 > @@ -0,0 +1,33 @@ > +// PR tree-optimization/94589 > +// { dg-do compile { target c++20 } } > +// { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } > +// { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) > (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } > +// { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) > 5\\.0" 14 "optimized" } } > + > +#include <compare> > + > +#define A __attribute__((noipa)) > +A bool f1 (double i, double j) { auto c = i <=> j; return c == 0; } > +A bool f2 (double i, double j) { auto c = i <=> j; return c != 0; } > +A bool f3 (double i, double j) { auto c = i <=> j; return c > 0; } > +A bool f4 (double i, double j) { auto c = i <=> j; return c < 0; } > +A bool f5 (double i, double j) { auto c = i <=> j; return c >= 0; } > +A bool f6 (double i, double j) { auto c = i <=> j; return c <= 0; } > +A bool f7 (double i, double j) { auto c = i <=> j; return c == > std::partial_ordering::less; } > +A bool f8 (double i, double j) { auto c = i <=> j; return c != > std::partial_ordering::less; } > +A bool f9 (double i, double j) { auto c = i <=> j; return c == > std::partial_ordering::equivalent; } > +A bool f10 (double i, double j) { auto c = i <=> j; return c != > std::partial_ordering::equivalent; } > +A bool f11 (double i, double j) { auto c = i <=> j; return c == > std::partial_ordering::greater; } > +A bool f12 (double i, double j) { auto c = i <=> j; return c != > std::partial_ordering::greater; } > +A bool f13 (double i) { auto c = i <=> 5.0; return c == 0; } > +A bool f14 (double i) { auto c = i <=> 5.0; return c != 0; } > +A bool f15 (double i) { auto c = i <=> 5.0; return c > 0; } > +A bool f16 (double i) { auto c = i <=> 5.0; return c < 0; } > +A bool f17 (double i) { auto c = i <=> 5.0; return c >= 0; } > +A bool f18 (double i) { auto c = i <=> 5.0; return c <= 0; } > +A bool f19 (double i) { auto c = i <=> 5.0; return c == > std::partial_ordering::less; } > +A bool f20 (double i) { auto c = i <=> 5.0; return c != > std::partial_ordering::less; } > +A bool f21 (double i) { auto c = i <=> 5.0; return c == > std::partial_ordering::equivalent; } > +A bool f22 (double i) { auto c = i <=> 5.0; return c != > std::partial_ordering::equivalent; } > +A bool f23 (double i) { auto c = i <=> 5.0; return c == > std::partial_ordering::greater; } > +A bool f24 (double i) { auto c = i <=> 5.0; return c != > std::partial_ordering::greater; } > --- gcc/testsuite/g++.dg/opt/pr94589-3.C.jj 2021-05-03 16:22:29.898597327 > +0200 > +++ gcc/testsuite/g++.dg/opt/pr94589-3.C 2021-05-03 17:21:23.290556509 > +0200 > @@ -0,0 +1,84 @@ > +// { dg-do run { target c++20 } } > +// { dg-options "-O2 -g" } > + > +#include "pr94589-1.C" > + > +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () > +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () > + > +int > +main () > +{ > + C (f1, 7, 8, false); > + C (f1, 8, 8, true); > + C (f1, 9, 8, false); > + C (f2, 7, 8, true); > + C (f2, 8, 8, false); > + C (f2, 9, 8, true); > + C (f3, 7, 8, false); > + C (f3, 8, 8, false); > + C (f3, 9, 8, true); > + C (f4, 7, 8, true); > + C (f4, 8, 8, false); > + C (f4, 9, 8, false); > + C (f5, 7, 8, false); > + C (f5, 8, 8, true); > + C (f5, 9, 8, true); > + C (f6, 7, 8, true); > + C (f6, 8, 8, true); > + C (f6, 9, 8, false); > + C (f7, 7, 8, true); > + C (f7, 8, 8, false); > + C (f7, 9, 8, false); > + C (f8, 7, 8, false); > + C (f8, 8, 8, true); > + C (f8, 9, 8, true); > + C (f9, 7, 8, false); > + C (f9, 8, 8, true); > + C (f9, 9, 8, false); > + C (f10, 7, 8, true); > + C (f10, 8, 8, false); > + C (f10, 9, 8, true); > + C (f11, 7, 8, false); > + C (f11, 8, 8, false); > + C (f11, 9, 8, true); > + C (f12, 7, 8, true); > + C (f12, 8, 8, true); > + C (f12, 9, 8, false); > + D (f13, 4, false); > + D (f13, 5, true); > + D (f13, 6, false); > + D (f14, 4, true); > + D (f14, 5, false); > + D (f14, 6, true); > + D (f15, 4, false); > + D (f15, 5, false); > + D (f15, 6, true); > + D (f16, 4, true); > + D (f16, 5, false); > + D (f16, 6, false); > + D (f17, 4, false); > + D (f17, 5, true); > + D (f17, 6, true); > + D (f18, 4, true); > + D (f18, 5, true); > + D (f18, 6, false); > + D (f19, 4, true); > + D (f19, 5, false); > + D (f19, 6, false); > + D (f20, 4, false); > + D (f20, 5, true); > + D (f20, 6, true); > + D (f21, 4, false); > + D (f21, 5, true); > + D (f21, 6, false); > + D (f22, 4, true); > + D (f22, 5, false); > + D (f22, 6, true); > + D (f23, 4, false); > + D (f23, 5, false); > + D (f23, 6, true); > + D (f24, 4, true); > + D (f24, 5, true); > + D (f24, 6, false); > +} > --- gcc/testsuite/g++.dg/opt/pr94589-4.C.jj 2021-05-03 17:21:40.968351902 > +0200 > +++ gcc/testsuite/g++.dg/opt/pr94589-4.C 2021-05-03 17:23:13.313289481 > +0200 > @@ -0,0 +1,84 @@ > +// { dg-do run { target c++20 } } > +// { dg-options "-O2 -g -ffast-math" } > + > +#include "pr94589-2.C" > + > +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () > +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () > + > +int > +main () > +{ > + C (f1, 7.0, 8.0, false); > + C (f1, 8.0, 8.0, true); > + C (f1, 9.0, 8.0, false); > + C (f2, 7.0, 8.0, true); > + C (f2, 8.0, 8.0, false); > + C (f2, 9.0, 8.0, true); > + C (f3, 7.0, 8.0, false); > + C (f3, 8.0, 8.0, false); > + C (f3, 9.0, 8.0, true); > + C (f4, 7.0, 8.0, true); > + C (f4, 8.0, 8.0, false); > + C (f4, 9.0, 8.0, false); > + C (f5, 7.0, 8.0, false); > + C (f5, 8.0, 8.0, true); > + C (f5, 9.0, 8.0, true); > + C (f6, 7.0, 8.0, true); > + C (f6, 8.0, 8.0, true); > + C (f6, 9.0, 8.0, false); > + C (f7, 7.0, 8.0, true); > + C (f7, 8.0, 8.0, false); > + C (f7, 9.0, 8.0, false); > + C (f8, 7.0, 8.0, false); > + C (f8, 8.0, 8.0, true); > + C (f8, 9.0, 8.0, true); > + C (f9, 7.0, 8.0, false); > + C (f9, 8.0, 8.0, true); > + C (f9, 9.0, 8.0, false); > + C (f10, 7.0, 8.0, true); > + C (f10, 8.0, 8.0, false); > + C (f10, 9.0, 8.0, true); > + C (f11, 7.0, 8.0, false); > + C (f11, 8.0, 8.0, false); > + C (f11, 9.0, 8.0, true); > + C (f12, 7.0, 8.0, true); > + C (f12, 8.0, 8.0, true); > + C (f12, 9.0, 8.0, false); > + D (f13, 4.0, false); > + D (f13, 5.0, true); > + D (f13, 6.0, false); > + D (f14, 4.0, true); > + D (f14, 5.0, false); > + D (f14, 6.0, true); > + D (f15, 4.0, false); > + D (f15, 5.0, false); > + D (f15, 6.0, true); > + D (f16, 4.0, true); > + D (f16, 5.0, false); > + D (f16, 6.0, false); > + D (f17, 4.0, false); > + D (f17, 5.0, true); > + D (f17, 6.0, true); > + D (f18, 4.0, true); > + D (f18, 5.0, true); > + D (f18, 6.0, false); > + D (f19, 4.0, true); > + D (f19, 5.0, false); > + D (f19, 6.0, false); > + D (f20, 4.0, false); > + D (f20, 5.0, true); > + D (f20, 6.0, true); > + D (f21, 4.0, false); > + D (f21, 5.0, true); > + D (f21, 6.0, false); > + D (f22, 4.0, true); > + D (f22, 5.0, false); > + D (f22, 6.0, true); > + D (f23, 4.0, false); > + D (f23, 5.0, false); > + D (f23, 6.0, true); > + D (f24, 4.0, true); > + D (f24, 5.0, true); > + D (f24, 6.0, false); > +} > > Jakub > > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)