This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR optimization/11637 (x86)
> There's nothing wrong with the movsf_1 pattern.
Oops! You're right, I was still in the SPARC world.
> I *think* what happened is that the CONST_DOUBLE in question was marked as
> one of [DXT]Fmode for some reason, thus hitting the
>
> /* These float cases don't actually occur as immediate operands. */
> else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
> ...
> else if (GET_CODE (x) == CONST_DOUBLE
> && (GET_MODE (x) == XFmode || GET_MODE (x) == TFmode))
> ...
>
> cases in i386.c:print_operand.
Indeed, that's what happens.
> So there are actually two bugs:
> (1) that print_operand uses real_to_decimal at all,
The two if-blocks go back to v1.1, print_operands was put by rth instead of
REAL_VALUE_TYPE r;
char dstr[30];
REAL_VALUE_FROM_CONST_DOUBLE (r, x);
REAL_VALUE_TO_DECIMAL (r, dstr, -1);
> (2) that we a non-SFmode CONST_DOUBLE at this point.
A bogus REG_EQUAL note issued by the combiner, rematerialized by reload.
Here's the sequence of events: the combiner temporarily combines
(insn 11 4 15 0 0x401a35ac (set (reg/v:SF 59)
(mem/u/f:SF (symbol_ref/u:SI ("*.LC0")) [3 S4 A32])) 61 {*movsf_1}
(nil)
(expr_list:REG_EQUAL (const_double:SF -858993408 [0xcccccd00]
5.00000007450580596923828125e-2 [0x0.cccccdp-4])
(nil)))
(insn 15 11 22 0 0x401a35ac (set (reg:DF 61)
(float_extend:DF (reg/v:SF 59))) 91 {*extendsfdf2_1} (insn_list 11
(nil))
(expr_list:REG_UNUSED (reg:DF 61)
(expr_list:REG_EQUAL (const_double:DF -858993408 [0xcccccd00]
5.00000007450580596923828125e-2 [0x0.cccccdp-4])
(nil))))
into
(parallel [
(set (reg:DF 61)
(const_double:DF -858993408 [0xcccccd00]
5.00000007450580596923828125e-2 [0x0.cccccdp-4]))
(set (reg/v:SF 59)
(mem/u/f:SF (symbol_ref/u:SI ("*.LC0")) [3 S4 A32]))
])
Since it can't recognize the new pattern, it cleverly(!) remarks that there
is a REG_UNUSED note for reg 61, so it removes the first SET:
(note 11 4 15 0 NOTE_INSN_DELETED)
(insn 15 11 22 0 0x401a35ac (set (reg/v:SF 59)
(mem/u/f:SF (symbol_ref/u:SI ("*.LC0")) [3 S4 A32])) 61 {*movsf_1}
(nil)
(expr_list:REG_EQUAL (const_double:DF -858993408 [0xcccccd00]
5.00000007450580596923828125e-2 [0x0.cccccdp-4])
(nil)))
And, although there is a non-trivial machinery to update REG_NOTES and
LOG_LINKS, it only kills the REG_UNUSED note.
I can think of two fixes:
(1) further tweak the aforementioned machinery to remove the REG_EQUAL note
in that case,
(2) simply prevent the combiner from removing the first SET, because it may
invalid the attached LOG_LINKS and REG_NOTES.
--
Eric Botcazou