From: Roger Sayle Date: Mon, 23 May 2022 07:47:42 +0000 (+0100) Subject: Some additional ix86_rtx_costs clean-ups: NEG, AND, andn and pandn. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7707d7fddf7d6858399c8a47b139dc4708c5d7d9;p=platform%2Fupstream%2Fgcc.git Some additional ix86_rtx_costs clean-ups: NEG, AND, andn and pandn. Double-word NOT requires two operations, but double-word NEG requires three operations. Using SSE, vector NOT requires a pxor with -1, but AND of NOT is cheap thanks to the existence of pandn. There's also some legacy (aka incorrect) logic explicitly testing for DImode [independently of TARGET_64BIT] in determining the cost of logic operations that's not required. 2022-05-23 Roger Sayle gcc/ChangeLog * config/i386/i386.cc (ix86_rtx_costs) : Split from XOR/IOR case. Account for two instructions for double-word operations. In case of vector pandn, account for single instruction. Likewise for integer andn with TARGET_BMI. : Vector NOT requires more than 1 instruction (pxor). : Double-word negation requires 3 instructions. --- diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 30a9cd0..daa60ac 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -20738,70 +20738,125 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, } if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode)) - { - *total = cost->addss; - return false; - } + *total = cost->addss; else if (X87_FLOAT_MODE_P (mode)) - { - *total = cost->fadd; - return false; - } + *total = cost->fadd; else if (FLOAT_MODE_P (mode)) - { - *total = ix86_vec_cost (mode, cost->addss); - return false; - } - /* FALLTHRU */ + *total = ix86_vec_cost (mode, cost->addss); + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + *total = ix86_vec_cost (mode, cost->sse_op); + else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) + *total = cost->add * 2; + else + *total = cost->add; + return false; - case AND: case IOR: case XOR: - if (GET_MODE_CLASS (mode) == MODE_INT - && GET_MODE_SIZE (mode) > UNITS_PER_WORD) + if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + *total = ix86_vec_cost (mode, cost->sse_op); + else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) + *total = cost->add * 2; + else + *total = cost->add; + return false; + + case AND: + if (address_no_seg_operand (x, mode)) { - *total = (cost->add * 2 - + (rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed) - << (GET_MODE (XEXP (x, 0)) != DImode)) - + (rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed) - << (GET_MODE (XEXP (x, 1)) != DImode))); + *total = cost->lea; return true; } - else if (code == AND - && address_no_seg_operand (x, mode)) + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) { - *total = cost->lea; - return true; + /* pandn is a single instruction. */ + if (GET_CODE (XEXP (x, 0)) == NOT) + { + *total = ix86_vec_cost (mode, cost->sse_op) + + rtx_cost (XEXP (XEXP (x, 0), 0), mode, + outer_code, opno, speed) + + rtx_cost (XEXP (x, 1), mode, + outer_code, opno, speed); + return true; + } + else if (GET_CODE (XEXP (x, 1)) == NOT) + { + *total = ix86_vec_cost (mode, cost->sse_op) + + rtx_cost (XEXP (x, 0), mode, + outer_code, opno, speed) + + rtx_cost (XEXP (XEXP (x, 1), 0), mode, + outer_code, opno, speed); + return true; + } + *total = ix86_vec_cost (mode, cost->sse_op); } - /* FALLTHRU */ - - case NEG: - if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode)) + else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) { - *total = cost->sse_op; - return false; + if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT) + { + *total = cost->add * 2 + + rtx_cost (XEXP (XEXP (x, 0), 0), mode, + outer_code, opno, speed) + + rtx_cost (XEXP (x, 1), mode, + outer_code, opno, speed); + return true; + } + else if (TARGET_BMI && GET_CODE (XEXP (x, 1)) == NOT) + { + *total = cost->add * 2 + + rtx_cost (XEXP (x, 0), mode, + outer_code, opno, speed) + + rtx_cost (XEXP (XEXP (x, 1), 0), mode, + outer_code, opno, speed); + return true; + } + *total = cost->add * 2; } - else if (X87_FLOAT_MODE_P (mode)) + else if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT) { - *total = cost->fchs; - return false; + *total = cost->add + + rtx_cost (XEXP (XEXP (x, 0), 0), mode, + outer_code, opno, speed) + + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed); + return true; } - else if (FLOAT_MODE_P (mode)) + else if (TARGET_BMI && GET_CODE (XEXP (x,1)) == NOT) { - *total = ix86_vec_cost (mode, cost->sse_op); - return false; + *total = cost->add + + rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed) + + rtx_cost (XEXP (XEXP (x, 1), 0), mode, + outer_code, opno, speed); + return true; } - /* FALLTHRU */ + else + *total = cost->add; + return false; case NOT: if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) - *total = ix86_vec_cost (mode, cost->sse_op); + // vnot is pxor -1. + *total = ix86_vec_cost (mode, cost->sse_op) + 1; else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) *total = cost->add * 2; else *total = cost->add; return false; + case NEG: + if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode)) + *total = cost->sse_op; + else if (X87_FLOAT_MODE_P (mode)) + *total = cost->fchs; + else if (FLOAT_MODE_P (mode)) + *total = ix86_vec_cost (mode, cost->sse_op); + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + *total = ix86_vec_cost (mode, cost->sse_op); + else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) + *total = cost->add * 3; + else + *total = cost->add; + return false; + case COMPARE: rtx op0, op1; op0 = XEXP (x, 0);