This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]