Okay, so I have to specify "-MObjfpc -Sh" to get it to compile due to what the code uses, and the bug still requires the use of -O2 to appear.  However... "fpc -MObjfpc -Sh -O2 -Ooregvar -alr -sr breakp.pp" produces a bad binary.

I removed the register comments so it's clearer:

    ...
# [11] pChar(result)[i] := BarSym[(progress >= (0.75 + i) / divs) or (i = int32(divs) - 1) and (progress >= 1)];
    cvtsi2ssl    %ireg16d,%mreg34ms
    movaps    %mreg34ms,%mreg35ms
    addss    _$BREAKP$_Ld1(%rip),%mreg35ms
    movl    %ireg18d,%ireg28d
    andl    $4294967295,%ireg28d
    cvtsi2ssq    %ireg28q,%mreg37ms
    movaps    %mreg35ms,%mreg38ms
    divss    %mreg37ms,%mreg38ms
    comiss    %mreg32ms,%mreg38ms
    jp    .Lj12
    jbe    .Lj10 <---- Register %ireg27q not initialised if this instruction branches to .Lj10
.Lj12:
    jmp    .Lj11
.Lj11:
    movl    %ireg18d,%ireg29d
    movslq    %ireg29d,%ireg30q
    subq    $1,%ireg30q
    movslq    %ireg16d,%ireg31q
    movq    %ireg31q,%ireg27q <---- Problem register: %ireg27q
    cmpq    %ireg27q,%ireg30q
    je    .Lj14
    jmp    .Lj15
.Lj14:
    comiss    _$BREAKP$_Ld2(%rip),%mreg32ms
    jp    .Lj17
    jae    .Lj16
.Lj17:
    jmp    .Lj15
.Lj16:
    jmp    .Lj10
.Lj15:
    jmp    .Lj13
.Lj10:
    movq    $1,%ireg32q
    jmp    .Lj18
.Lj13:
    movq    $0,%ireg32q
.Lj18:
    movq    (%ireg17q),%ireg33q
    cmpq    $0,%ireg33q
    jne    .Lj19
    leaq    FPC_EMPTYCHAR(%rip),%ireg33q
.Lj19:
    leaq TC_$P$BREAKP$_$BAR$SINGLE$LONGWORD$$ANSISTRING_$$_BARSYM(%rip),%ireg34q
    movb    (%ireg34q,%ireg32q,1),%ireg35l
    movb    %ireg35l,(%ireg33q,%ireg27q,1) <---- Problem register: %ireg27q
    cmpl    %ireg25d,%ireg16d
    jge    .Lj9
    jmp    .Lj7
.Lj9:
.Lj6:
    ...

The problem register is %ireg27q - it's not being initialised if "jbe .Lj10" branches.  By your explanation, it seems that the code generator is buggy on one of the nodes.  Thanks for the tips in isolating where it could be.  To help out, I've attached the node dump file for the test program.

Gareth aka. Kit

On 26/11/2020 19:04, Yuriy Sydorov via fpc-devel wrote:
Hi,

On 26.11.2020 17:34, J. Gareth Moreton via fpc-devel wrote:
Hi everyone,

So a couple of people have reported that -O2 sometimes produces bad code under x86_64.  So far it seems isolated to that CPU.

https://bugs.freepascal.org/view.php?id=38129

After my own investigations with the attached code, the problem still occurs even if the peephole optimizer is disabled, and the uninitialised register is being allocated within conditional code that is not always executed, rather than before or after it.

Anyone with any tips on where to dig next (register allocator, node converter etc.) would be most appreciated!

First compile with the "-Ooregvar -alr -sr" switches. You will get the assembler output with imaginary registers and notes about register allocations and de-allocations. Inspect if all is correct at this stage. If not then the a code generator of some node is buggy.

Then compile with "-Ooregvar -alr". If the issue is present only at this stage, then the bug is in the register allocator.

Yuriy.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
<?xml version="1.0" encoding="utf-8"?>
<program name="breakp">
   <subroutine name="Bar(&lt;var AnsiString&gt;;const Single;LongWord):AnsiString(0);">
      <returndef>AnsiString</returndef>
      <code>
         <blockn resultdef="$void" pos="8,1" complexity="255">
            <statementn pos="9,28" complexity="255">
               <inlinen resultdef="$void" pos="9,5" complexity="255" inlinenumber="in_setlength_x">
                  <callparan resultdef="LongWord" pos="9,27" complexity="2">
                     <typeconvn resultdef="Int64" pos="9,27" complexity="1" convtype="tc_int_2_int">
                        <loadn resultdef="LongWord" pos="9,27" complexity="0">
                           <symbol>DIVS</symbol>
                        </loadn>
                     </typeconvn>
                  </callparan>
                  <callparan resultdef="AnsiString" pos="9,21" complexity="2">
                     <typeconvn resultdef="AnsiString" pos="9,21" flags="nf_absolute" complexity="1" convtype="tc_equal">
                        <loadn resultdef="AnsiString" pos="9,21" flags="nf_write" complexity="1">
                           <symbol>result</symbol>
                        </loadn>
                     </typeconvn>
                  </callparan>
               </inlinen>
            </statementn>
            <statementn pos="11,113" complexity="255">
               <forn resultdef="$void" pos="10,5" complexity="255" loopflags="lnf_testatbegin,lnf_dont_mind_loopvar_on_exit">
                  <counter>
                     <loadn resultdef="LongInt" pos="10,9" flags="nf_write" complexity="0">
                        <symbol>I</symbol>
                     </loadn>
                  </counter>
                  <first>
                     <ordconstn resultdef="LongInt" pos="10,14" complexity="0" rangecheck="FALSE">
                        <value>0</value>
                     </ordconstn>
                  </first>
                  <last>
                     <subn resultdef="LongInt" pos="10,31" complexity="1">
                        <typeconvn resultdef="LongInt" pos="10,19" flags="nf_explicit" complexity="0" convtype="tc_int_2_int">
                           <loadn resultdef="LongWord" pos="10,25" complexity="0">
                              <symbol>DIVS</symbol>
                           </loadn>
                        </typeconvn>
                        <ordconstn resultdef="LongInt" pos="10,33" flags="nf_explicit" complexity="0" rangecheck="FALSE">
                           <value>1</value>
                        </ordconstn>
                     </subn>
                  </last>
                  <assignn resultdef="$void" pos="11,9" complexity="2">
                     <vecn resultdef="Char" pos="11,22" flags="nf_write,nf_callunique" complexity="5">
                        <typeconvn resultdef="&lt;no type symbol&gt;" pos="11,9" complexity="3" convtype="tc_pointer_2_array">
                           <typeconvn resultdef="PChar" pos="11,9" flags="nf_explicit" complexity="2" convtype="tc_ansistring_2_pchar">
                              <typeconvn resultdef="AnsiString" pos="11,15" flags="nf_absolute" complexity="1" convtype="tc_equal">
                                 <loadn resultdef="AnsiString" pos="11,21" flags="nf_write" complexity="1">
                                    <symbol>result</symbol>
                                 </loadn>
                              </typeconvn>
                           </typeconvn>
                        </typeconvn>
                        <index>
                           <typeconvn resultdef="Int64" pos="11,23" complexity="1" convtype="tc_int_2_int">
                              <loadn resultdef="LongInt" pos="11,23" complexity="0">
                                 <symbol>I</symbol>
                              </loadn>
                           </typeconvn>
                        </index>
                     </vecn>
                     <vecn resultdef="Char" pos="11,35" complexity="2">
                        <loadn resultdef="&lt;no type symbol&gt;" pos="11,29" complexity="1">
                           <symbol>BARSYM</symbol>
                        </loadn>
                        <index>
                           <orn resultdef="Boolean" pos="11,68" complexity="2">
                              <gten resultdef="Boolean" pos="11,36" complexity="17">
                                 <loadn resultdef="Single" pos="11,37" complexity="0">
                                    <symbol>PROGRESS</symbol>
                                 </loadn>
                                 <slashn resultdef="Single" pos="11,60" complexity="16">
                                    <addn resultdef="Single" pos="11,49" complexity="4">
                                       <realconstn resultdef="Single" pos="11,50" complexity="2">
                                          <value> 7.5000000000000000E-001</value>
                                       </realconstn>
                                       <typeconvn resultdef="Single" pos="11,57" complexity="1" convtype="tc_int_2_real">
                                          <loadn resultdef="LongInt" pos="11,57" complexity="0">
                                             <symbol>I</symbol>
                                          </loadn>
                                       </typeconvn>
                                    </addn>
                                    <typeconvn resultdef="Single" pos="11,62" complexity="1" convtype="tc_int_2_real">
                                       <loadn resultdef="LongWord" pos="11,62" complexity="0">
                                          <symbol>DIVS</symbol>
                                       </loadn>
                                    </typeconvn>
                                 </slashn>
                              </gten>
                              <andn resultdef="Boolean" pos="11,93" complexity="2">
                                 <equaln resultdef="Boolean" pos="11,71" complexity="4">
                                    <typeconvn resultdef="Int64" pos="11,72" complexity="1" convtype="tc_int_2_int">
                                       <loadn resultdef="LongInt" pos="11,72" complexity="0">
                                          <symbol>I</symbol>
                                       </loadn>
                                    </typeconvn>
                                    <subn resultdef="Int64" pos="11,88" complexity="2">
                                       <typeconvn resultdef="Int64" pos="11,76" complexity="1" convtype="tc_int_2_int">
                                          <typeconvn resultdef="LongInt" pos="11,76" flags="nf_explicit" complexity="0" convtype="tc_int_2_int">
                                             <loadn resultdef="LongWord" pos="11,82" complexity="0">
                                                <symbol>DIVS</symbol>
                                             </loadn>
                                          </typeconvn>
                                       </typeconvn>
                                       <ordconstn resultdef="Int64" pos="11,90" complexity="0" rangecheck="FALSE">
                                          <value>1</value>
                                       </ordconstn>
                                    </subn>
                                 </equaln>
                                 <gten resultdef="Boolean" pos="11,97" complexity="2">
                                    <loadn resultdef="Single" pos="11,98" complexity="0">
                                       <symbol>PROGRESS</symbol>
                                    </loadn>
                                    <realconstn resultdef="Single" pos="11,110" complexity="2">
                                       <value> 1.0000000000000000E+000</value>
                                    </realconstn>
                                 </gten>
                              </andn>
                           </orn>
                        </index>
                     </vecn>
                  </assignn>
               </forn>
            </statementn>
         </blockn>
      </code>
   </subroutine>

   <subroutine type="initialization" name="$main; Register;" convention="Register">
      <code>
         <blockn resultdef="$void" pos="17,1" complexity="255">
            <statementn pos="18,31" complexity="255">
               <assignn resultdef="$void" pos="18,5" complexity="255">
                  <loadn resultdef="AnsiString" pos="18,5" flags="nf_write" complexity="1">
                     <symbol>S</symbol>
                  </loadn>
                  <addn resultdef="AnsiString" pos="18,23" complexity="255">
                     <calln resultdef="AnsiString" pos="18,10" complexity="255">
                        <procname>Bar(&lt;var AnsiString&gt;;const Single;LongWord):AnsiString(0);</procname>
                        <callparan resultdef="LongWord" pos="18,21" complexity="1">
                           <ordconstn resultdef="LongWord" pos="18,21" complexity="0" rangecheck="FALSE">
                              <value>10</value>
                           </ordconstn>
                        </callparan>
                        <callparan resultdef="Single" pos="18,17" complexity="2">
                           <realconstn resultdef="Single" pos="18,17" complexity="2">
                              <value> 6.9999998807907104E-001</value>
                           </realconstn>
                        </callparan>
                        <callparan pos="18,10" complexity="1">
                           <nothingn resultdef="$void" pos="18,10" complexity="0" />
                        </callparan>
                     </calln>
                     <stringconstn resultdef="AnsiString" pos="18,25" complexity="1">
                        <stringtype>ansistring</stringtype>
                        <length>4</length>
                        <value> 70%</value>
                     </stringconstn>
                  </addn>
               </assignn>
            </statementn>
            <statementn pos="19,15" complexity="255">
               <blockn resultdef="$void" pos="19,5" complexity="255">
                  <statementn pos="19,5" complexity="255">
                     <nothingn resultdef="$void" pos="19,5" complexity="0" />
                  </statementn>
                  <statementn pos="19,5" complexity="255">
                     <tempcreaten resultdef="$void" pos="19,5" complexity="0" id="$211A6C00">
                        <typedef>Pointer</typedef>
                        <tempflags>ti_may_be_in_reg</tempflags>
                        <temptype>tt_persistent</temptype>
                        <size>8</size>
                        <tempinit />
                     </tempcreaten>
                  </statementn>
                  <statementn pos="19,5" complexity="255">
                     <assignn resultdef="$void" pos="19,5" complexity="255">
                        <temprefn resultdef="Pointer" pos="19,5" flags="nf_write" complexity="1" id="$211A6C00">
                           <typedef>Pointer</typedef>
                           <tempflags>ti_may_be_in_reg</tempflags>
                           <temptype>tt_persistent</temptype>
                        </temprefn>
                        <typeconvn resultdef="Pointer" pos="19,5" complexity="255" convtype="tc_equal">
                           <calln resultdef="PText" pos="19,5" complexity="255">
                              <procname>$fpc_get_output:^Text;</procname>
                           </calln>
                        </typeconvn>
                     </assignn>
                  </statementn>
                  <statementn pos="19,5" complexity="255">
                     <calln resultdef="$void" pos="19,5" complexity="255">
                        <procname>$fpc_write_text_ansistr(LongInt;var Text;const RawByteString);</procname>
                        <callparan resultdef="RawByteString" pos="19,14" complexity="2">
                           <loadn resultdef="RawByteString" pos="19,14" complexity="1">
                              <symbol>S</symbol>
                           </loadn>
                        </callparan>
                        <callparan resultdef="Text" pos="19,5" complexity="1">
                           <typeconvn resultdef="Text" pos="19,5" flags="nf_explicit,nf_internal" complexity="1" convtype="tc_equal">
                              <derefn resultdef="$void" pos="19,5" complexity="1">
                                 <temprefn resultdef="Pointer" pos="19,5" complexity="1" id="$211A6C00">
                                    <typedef>Pointer</typedef>
                                    <tempflags>ti_may_be_in_reg</tempflags>
                                    <temptype>tt_persistent</temptype>
                                 </temprefn>
                              </derefn>
                           </typeconvn>
                        </callparan>
                        <callparan resultdef="LongInt" pos="19,5" complexity="1">
                           <ordconstn resultdef="LongInt" pos="19,5" complexity="0" rangecheck="FALSE">
                              <value>0</value>
                           </ordconstn>
                        </callparan>
                     </calln>
                  </statementn>
                  <statementn pos="19,5" complexity="255">
                     <calln resultdef="$void" pos="19,5" complexity="255">
                        <procname>$fpc_writeln_end(var Text);</procname>
                        <callparan resultdef="Text" pos="19,5" complexity="1">
                           <typeconvn resultdef="Text" pos="19,5" flags="nf_explicit,nf_internal" complexity="1" convtype="tc_equal">
                              <derefn resultdef="$void" pos="19,5" complexity="1">
                                 <temprefn resultdef="Pointer" pos="19,5" complexity="1" id="$211A6C00">
                                    <typedef>Pointer</typedef>
                                    <tempflags>ti_may_be_in_reg</tempflags>
                                    <temptype>tt_persistent</temptype>
                                 </temprefn>
                              </derefn>
                           </typeconvn>
                        </callparan>
                     </calln>
                  </statementn>
                  <statementn pos="19,5" complexity="0">
                     <tempdeleten resultdef="$void" pos="19,5" complexity="0" id="$211A6C00">
                        <typedef>Pointer</typedef>
                        <tempflags>ti_may_be_in_reg</tempflags>
                        <temptype>tt_persistent</temptype>
                        <release_to_normal>FALSE</release_to_normal>
                     </tempdeleten>
                  </statementn>
               </blockn>
            </statementn>
            <statementn pos="20,19" complexity="255">
               <blockn resultdef="$void" pos="20,5" complexity="255">
                  <statementn pos="20,5" complexity="255">
                     <nothingn resultdef="$void" pos="20,5" complexity="0" />
                  </statementn>
                  <statementn pos="20,5" complexity="255">
                     <tempcreaten resultdef="$void" pos="20,5" complexity="0" id="$211A6B80">
                        <typedef>Pointer</typedef>
                        <tempflags>ti_may_be_in_reg</tempflags>
                        <temptype>tt_persistent</temptype>
                        <size>8</size>
                        <tempinit />
                     </tempcreaten>
                  </statementn>
                  <statementn pos="20,5" complexity="255">
                     <assignn resultdef="$void" pos="20,5" complexity="255">
                        <temprefn resultdef="Pointer" pos="20,5" flags="nf_write" complexity="1" id="$211A6B80">
                           <typedef>Pointer</typedef>
                           <tempflags>ti_may_be_in_reg</tempflags>
                           <temptype>tt_persistent</temptype>
                        </temprefn>
                        <typeconvn resultdef="Pointer" pos="20,5" complexity="255" convtype="tc_equal">
                           <calln resultdef="PText" pos="20,5" complexity="255">
                              <procname>$fpc_get_output:^Text;</procname>
                           </calln>
                        </typeconvn>
                     </assignn>
                  </statementn>
                  <statementn pos="20,5" complexity="255">
                     <calln resultdef="$void" pos="20,5" complexity="255">
                        <procname>$fpc_write_text_shortstr(LongInt;var Text;const ShortString);</procname>
                        <callparan resultdef="ShortString" pos="20,18" complexity="1">
                           <stringconstn resultdef="ShortString" pos="20,18" complexity="1">
                              <stringtype>shortstring</stringtype>
                              <length>3</length>
                              <value>Odd</value>
                           </stringconstn>
                        </callparan>
                        <callparan resultdef="Text" pos="20,5" complexity="1">
                           <typeconvn resultdef="Text" pos="20,5" flags="nf_explicit,nf_internal" complexity="1" convtype="tc_equal">
                              <derefn resultdef="$void" pos="20,5" complexity="1">
                                 <temprefn resultdef="Pointer" pos="20,5" complexity="1" id="$211A6B80">
                                    <typedef>Pointer</typedef>
                                    <tempflags>ti_may_be_in_reg</tempflags>
                                    <temptype>tt_persistent</temptype>
                                 </temprefn>
                              </derefn>
                           </typeconvn>
                        </callparan>
                        <callparan resultdef="LongInt" pos="20,5" complexity="1">
                           <ordconstn resultdef="LongInt" pos="20,5" complexity="0" rangecheck="FALSE">
                              <value>0</value>
                           </ordconstn>
                        </callparan>
                     </calln>
                  </statementn>
                  <statementn pos="20,5" complexity="255">
                     <calln resultdef="$void" pos="20,5" complexity="255">
                        <procname>$fpc_writeln_end(var Text);</procname>
                        <callparan resultdef="Text" pos="20,5" complexity="1">
                           <typeconvn resultdef="Text" pos="20,5" flags="nf_explicit,nf_internal" complexity="1" convtype="tc_equal">
                              <derefn resultdef="$void" pos="20,5" complexity="1">
                                 <temprefn resultdef="Pointer" pos="20,5" complexity="1" id="$211A6B80">
                                    <typedef>Pointer</typedef>
                                    <tempflags>ti_may_be_in_reg</tempflags>
                                    <temptype>tt_persistent</temptype>
                                 </temprefn>
                              </derefn>
                           </typeconvn>
                        </callparan>
                     </calln>
                  </statementn>
                  <statementn pos="20,5" complexity="0">
                     <tempdeleten resultdef="$void" pos="20,5" complexity="0" id="$211A6B80">
                        <typedef>Pointer</typedef>
                        <tempflags>ti_may_be_in_reg</tempflags>
                        <temptype>tt_persistent</temptype>
                        <release_to_normal>FALSE</release_to_normal>
                     </tempdeleten>
                  </statementn>
               </blockn>
            </statementn>
         </blockn>
      </code>
   </subroutine>

</program>
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to