aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@nextmovesoftware.com>2024-05-22 16:45:48 +0100
committerRoger Sayle <roger@nextmovesoftware.com>2024-05-22 16:45:48 +0100
commita3b16e73a2d5b2d4d20ef6f2fd164cea633bbec8 (patch)
treea019997a59b4280823969eacf0c36fbe35b02852 /gcc
parent26df7b4684e201e66c09dd018603a248ddc5f437 (diff)
downloadgcc-a3b16e73a2d5b2d4d20ef6f2fd164cea633bbec8.zip
gcc-a3b16e73a2d5b2d4d20ef6f2fd164cea633bbec8.tar.gz
gcc-a3b16e73a2d5b2d4d20ef6f2fd164cea633bbec8.tar.bz2
i386: Correct insn_cost of movabsq.
This single line patch fixes a strange quirk/glitch in i386's rtx_costs, which considers an instruction loading a 64-bit constant to be significantly cheaper than loading a 32-bit (or smaller) constant. Consider the two functions: unsigned long long foo() { return 0x0123456789abcdefULL; } unsigned int bar() { return 10; } and the corresponding lines from combine's dump file: insn_cost 1 for #: r98:DI=0x123456789abcdef insn_cost 4 for #: ax:SI=0xa The same issue can be seen in -dP assembler output. movabsq $81985529216486895, %rax # 5 [c=1 l=10] *movdi_internal/4 The problem is that pattern_costs interpretation of rtx_costs contains "return cost > 0 ? cost : COSTS_N_INSNS (1)" where a zero value (for example a register or small immediate constant) is considered special, and equivalent to a single instruction, but all other values are treated as verbatim. Hence to x86_64's 10-byte long movabsq instruction slightly more expensive than a simple constant, rtx_costs needs to return COSTS_N_INSNS(1)+1 and not 1. With this change, the insn_cost of movabsq is the intended value 5: insn_cost 5 for #: r98:DI=0x123456789abcdef and movabsq $81985529216486895, %rax # 5 [c=5 l=10] *movdi_internal/4 2024-05-22 Roger Sayle <roger@nextmovesoftware.com> gcc/ChangeLog * config/i386/i386.cc (ix86_rtx_costs) <case CONST_INT>: A CONST_INT that isn't x86_64_immediate_operand requires an extra (expensive) movabsq insn to load, so return COSTS_N_INSNS (1) + 1.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/i386.cc3
1 files changed, 2 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 69cd4ae..3e2a3a1 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -21562,7 +21562,8 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
if (x86_64_immediate_operand (x, VOIDmode))
*total = 0;
else
- *total = 1;
+ /* movabsq is slightly more expensive than a simple instruction. */
+ *total = COSTS_N_INSNS (1) + 1;
return true;
case CONST_DOUBLE: