middle-end: Correct calculation of mul_widen_cost and mul_highpart_cost.
This patch fixes a subtle bug in the depths of GCC's synth_mult, where the middle-end queries whether (how well) the target supports widening and highpart multiplications by calling targetm.rtx_costs. The code in init_expmed and init_expmed_one_mode iterates over various RTL patterns querying the cost of each. To avoid generating & garbage collecting too much junk, it reuses the same RTL over and over, but adjusting the modes between each call. Alas this reuse of state is a little fragile, and at some point a change to init_expmed_one_conv has resulted in the state (mode of a register) being changed, but not reset before being used again. Using the old software engineering/defensive programming maxim of "why fix a bug just once, if it can be fixed in multiple places", this patch both restores the original value in init_expmed_one_conv, and also sets it to the expected value in init_expmed_one_mode. This should hopefully signal the need to be careful of invariants for anyone modifying this code in future. 2020-08-09 Roger Sayle <roger@nextmovesoftware.com> gcc/ChangeLog * expmed.c (init_expmed_one_conv): Restore all->reg's mode. (init_expmed_one_mode): Set all->reg to desired mode. gcc/testsuite/ChangeLog PR target/71321 * gcc.target/i386/pr71321.c: Check that the code doesn't use the 4B zero displacement lea, not that it uses lea.
This commit is contained in:
parent
94d4f4387d
commit
71197a5d13
2 changed files with 4 additions and 2 deletions
|
@ -155,6 +155,8 @@ init_expmed_one_conv (struct init_expmed_rtl *all, scalar_int_mode to_mode,
|
|||
PUT_MODE (all->reg, from_mode);
|
||||
set_convert_cost (to_mode, from_mode, speed,
|
||||
set_src_cost (which, to_mode, speed));
|
||||
/* Restore all->reg's mode. */
|
||||
PUT_MODE (all->reg, to_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -229,6 +231,7 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
|
|||
if (GET_MODE_CLASS (int_mode_to) == MODE_INT
|
||||
&& GET_MODE_WIDER_MODE (int_mode_to).exists (&wider_mode))
|
||||
{
|
||||
PUT_MODE (all->reg, mode);
|
||||
PUT_MODE (all->zext, wider_mode);
|
||||
PUT_MODE (all->wide_mult, wider_mode);
|
||||
PUT_MODE (all->wide_lshr, wider_mode);
|
||||
|
|
|
@ -12,5 +12,4 @@ unsigned cvt_to_2digit_ascii(uint8_t i)
|
|||
{
|
||||
return cvt_to_2digit(i, 10) + 0x0a3030;
|
||||
}
|
||||
/* { dg-final { scan-assembler-times "lea.\t\\(%\[0-9a-z\]+,%\[0-9a-z\]+,4" 3 } } */
|
||||
/* { dg-final { scan-assembler-times "lea.\t\\(%\[0-9a-z\]+,%\[0-9a-z\]+,8" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "lea.*0" } } */
|
||||
|
|
Loading…
Add table
Reference in a new issue