aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@nextmovesoftware.com>2022-05-23 08:47:42 +0100
committerRoger Sayle <roger@nextmovesoftware.com>2022-05-23 08:47:42 +0100
commit7707d7fddf7d6858399c8a47b139dc4708c5d7d9 (patch)
treea426ea691f3525546d8b5bd081ddeca1b59ad1d7
parent075fb873c264a030f56793cb162c9fdecbdd1773 (diff)
downloadgcc-7707d7fddf7d6858399c8a47b139dc4708c5d7d9.zip
gcc-7707d7fddf7d6858399c8a47b139dc4708c5d7d9.tar.gz
gcc-7707d7fddf7d6858399c8a47b139dc4708c5d7d9.tar.bz2
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 <roger@nextmovesoftware.com> gcc/ChangeLog * config/i386/i386.cc (ix86_rtx_costs) <case AND>: 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. <case NOT>: Vector NOT requires more than 1 instruction (pxor). <case NEG>: Double-word negation requires 3 instructions.
-rw-r--r--gcc/config/i386/i386.cc133
1 files changed, 94 insertions, 39 deletions
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);