Tested spec2017 performance in Sierra Forest, Icelake, CascadeLake, at least there is no obvious regression.
Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}. OK for trunk? gcc/ChangeLog: * config/i386/x86-tune-costs.h (struct processor_costs): Adjust rtx_cost of imulq and imulw for COST_N_INSNS (4) to COST_N_INSNS (3). gcc/testsuite/ChangeLog: * gcc.target/i386/pr115749.c: New test. --- gcc/config/i386/x86-tune-costs.h | 16 ++++++++-------- gcc/testsuite/gcc.target/i386/pr115749.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr115749.c diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h index 769f334e531..2bfaee554d5 100644 --- a/gcc/config/i386/x86-tune-costs.h +++ b/gcc/config/i386/x86-tune-costs.h @@ -2182,7 +2182,7 @@ struct processor_costs skylake_cost = { COSTS_N_INSNS (1), /* variable shift costs */ COSTS_N_INSNS (1), /* constant shift costs */ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */ - COSTS_N_INSNS (4), /* HI */ + COSTS_N_INSNS (3), /* HI */ COSTS_N_INSNS (3), /* SI */ COSTS_N_INSNS (3), /* DI */ COSTS_N_INSNS (3)}, /* other */ @@ -2310,7 +2310,7 @@ struct processor_costs icelake_cost = { COSTS_N_INSNS (1), /* variable shift costs */ COSTS_N_INSNS (1), /* constant shift costs */ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */ - COSTS_N_INSNS (4), /* HI */ + COSTS_N_INSNS (3), /* HI */ COSTS_N_INSNS (3), /* SI */ COSTS_N_INSNS (3), /* DI */ COSTS_N_INSNS (3)}, /* other */ @@ -2434,9 +2434,9 @@ struct processor_costs alderlake_cost = { COSTS_N_INSNS (1), /* variable shift costs */ COSTS_N_INSNS (1), /* constant shift costs */ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */ - COSTS_N_INSNS (4), /* HI */ + COSTS_N_INSNS (3), /* HI */ COSTS_N_INSNS (3), /* SI */ - COSTS_N_INSNS (4), /* DI */ + COSTS_N_INSNS (3), /* DI */ COSTS_N_INSNS (4)}, /* other */ 0, /* cost of multiply per each bit set */ {COSTS_N_INSNS (16), /* cost of a divide/mod for QI */ @@ -3234,9 +3234,9 @@ struct processor_costs tremont_cost = { COSTS_N_INSNS (1), /* variable shift costs */ COSTS_N_INSNS (1), /* constant shift costs */ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */ - COSTS_N_INSNS (4), /* HI */ + COSTS_N_INSNS (3), /* HI */ COSTS_N_INSNS (3), /* SI */ - COSTS_N_INSNS (4), /* DI */ + COSTS_N_INSNS (3), /* DI */ COSTS_N_INSNS (4)}, /* other */ 0, /* cost of multiply per each bit set */ {COSTS_N_INSNS (16), /* cost of a divide/mod for QI */ @@ -3816,9 +3816,9 @@ struct processor_costs generic_cost = { COSTS_N_INSNS (1), /* variable shift costs */ COSTS_N_INSNS (1), /* constant shift costs */ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */ - COSTS_N_INSNS (4), /* HI */ + COSTS_N_INSNS (3), /* HI */ COSTS_N_INSNS (3), /* SI */ - COSTS_N_INSNS (4), /* DI */ + COSTS_N_INSNS (3), /* DI */ COSTS_N_INSNS (4)}, /* other */ 0, /* cost of multiply per each bit set */ {COSTS_N_INSNS (16), /* cost of a divide/mod for QI */ diff --git a/gcc/testsuite/gcc.target/i386/pr115749.c b/gcc/testsuite/gcc.target/i386/pr115749.c new file mode 100644 index 00000000000..82505d603ef --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr115749.c @@ -0,0 +1,16 @@ +/* PR target/115749 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ +/* { dg-final { scan-assembler-times "imul" 2 } } */ +/* { dg-final { scan-assembler-not "sal" } } */ + +unsigned long func(unsigned long x) +{ + return x % 240; +} + +unsigned short func2(unsigned short x) +{ + return x * 240; +} + -- 2.31.1