From deed3da9af697ecf073aea855ecce2d22d85ef71 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 12 Apr 2017 20:09:47 +0200 Subject: [PATCH] re PR tree-optimization/79390 (10% performance drop in SciMark2 LU after r242550) PR tree-optimization/79390 * optabs.c (emit_conditional_move): If the preferred op2/op3 operand order does not result in usable sequence, retry with reversed operand order. * gcc.target/i386/pr70465-2.c: Xfail the scan-assembler-not test. From-SVN: r246882 --- gcc/ChangeLog | 5 ++ gcc/optabs.c | 80 ++++++++++++++--------- gcc/testsuite/ChangeLog | 3 + gcc/testsuite/gcc.target/i386/pr70465-2.c | 2 +- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index efd66a6272a..fd40a2a2f97 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2017-04-12 Jakub Jelinek + PR tree-optimization/79390 + * optabs.c (emit_conditional_move): If the preferred op2/op3 operand + order does not result in usable sequence, retry with reversed operand + order. + PR sanitizer/80403 PR sanitizer/80404 PR sanitizer/80405 diff --git a/gcc/optabs.c b/gcc/optabs.c index 1afd593ae15..48e37f8bb40 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -4258,12 +4258,15 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, if (cmode == VOIDmode) cmode = GET_MODE (op0); + enum rtx_code orig_code = code; + bool swapped = false; if (swap_commutative_operands_p (op2, op3) && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL)) != UNKNOWN)) { std::swap (op2, op3); code = reversed; + swapped = true; } if (mode == VOIDmode) @@ -4272,45 +4275,62 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, icode = direct_optab_handler (movcc_optab, mode); if (icode == CODE_FOR_nothing) - return 0; + return NULL_RTX; if (!target) target = gen_reg_rtx (mode); - code = unsignedp ? unsigned_condition (code) : code; - comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1); - - /* We can get const0_rtx or const_true_rtx in some circumstances. Just - return NULL and let the caller figure out how best to deal with this - situation. */ - if (!COMPARISON_P (comparison)) - return NULL_RTX; - - saved_pending_stack_adjust save; - save_pending_stack_adjust (&save); - last = get_last_insn (); - do_pending_stack_adjust (); - prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), - GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN, - &comparison, &cmode); - if (comparison) + for (int pass = 0; ; pass++) { - struct expand_operand ops[4]; + code = unsignedp ? unsigned_condition (code) : code; + comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1); - create_output_operand (&ops[0], target, mode); - create_fixed_operand (&ops[1], comparison); - create_input_operand (&ops[2], op2, mode); - create_input_operand (&ops[3], op3, mode); - if (maybe_expand_insn (icode, 4, ops)) + /* We can get const0_rtx or const_true_rtx in some circumstances. Just + punt and let the caller figure out how best to deal with this + situation. */ + if (COMPARISON_P (comparison)) { - if (ops[0].value != target) - convert_move (target, ops[0].value, false); - return target; + saved_pending_stack_adjust save; + save_pending_stack_adjust (&save); + last = get_last_insn (); + do_pending_stack_adjust (); + prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), + GET_CODE (comparison), NULL_RTX, unsignedp, + OPTAB_WIDEN, &comparison, &cmode); + if (comparison) + { + struct expand_operand ops[4]; + + create_output_operand (&ops[0], target, mode); + create_fixed_operand (&ops[1], comparison); + create_input_operand (&ops[2], op2, mode); + create_input_operand (&ops[3], op3, mode); + if (maybe_expand_insn (icode, 4, ops)) + { + if (ops[0].value != target) + convert_move (target, ops[0].value, false); + return target; + } + } + delete_insns_since (last); + restore_pending_stack_adjust (&save); } + + if (pass == 1) + return NULL_RTX; + + /* If the preferred op2/op3 order is not usable, retry with other + operand order, perhaps it will expand successfully. */ + if (swapped) + code = orig_code; + else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1, + NULL)) + != UNKNOWN) + code = reversed; + else + return NULL_RTX; + std::swap (op2, op3); } - delete_insns_since (last); - restore_pending_stack_adjust (&save); - return NULL_RTX; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9dce05e3117..b1594f22791 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-04-12 Jakub Jelinek + PR tree-optimization/79390 + * gcc.target/i386/pr70465-2.c: Xfail the scan-assembler-not test. + PR sanitizer/80403 PR sanitizer/80404 PR sanitizer/80405 diff --git a/gcc/testsuite/gcc.target/i386/pr70465-2.c b/gcc/testsuite/gcc.target/i386/pr70465-2.c index 71b683aad70..d60386d39ce 100644 --- a/gcc/testsuite/gcc.target/i386/pr70465-2.c +++ b/gcc/testsuite/gcc.target/i386/pr70465-2.c @@ -1,7 +1,7 @@ /* PR target/70465 */ /* { dg-do compile } */ /* { dg-options "-Ofast -mfpmath=387 -fomit-frame-pointer" } */ -/* { dg-final { scan-assembler-not "fxch\t%st.1" } } */ +/* { dg-final { scan-assembler-not "fxch\t%st.1" { xfail *-*-* } } } */ extern float d[1024]; -- 2.30.2