<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">On Apr 12, 2010, at 7:20 PM, Evan Cheng wrote:<br><br><blockquote type="cite"><blockquote type="cite">The problem lies in this bit of code in X86InstrInfo::AnalyzeBranch:<br><br>    // If they differ, see if they fit one of the known patterns. Theoretically,                                                                                        <br>    // we could handle more patterns here, but we shouldn't expect to see them                                                                                          <br>    // if instruction selection has done a reasonable job.                                                                                                              <br>    if ((OldBranchCode == X86::COND_NP &&<br>         BranchCode == X86::COND_E) ||<br>        (OldBranchCode == X86::COND_E &&<br>         BranchCode == X86::COND_NP))<br>      BranchCode = X86::COND_NP_OR_E;<br>    else if ((OldBranchCode == X86::COND_P &&<br>              BranchCode == X86::COND_NE) ||<br>             (OldBranchCode == X86::COND_NE &&<br>              BranchCode == X86::COND_P))<br>      BranchCode = X86::COND_NE_OR_P;<br>    else<br>      return true;<br><br>When the code in BranchFolding calls "ReverseBranchCondition", the X86 back-end isn't able to handle it. So it doesn't change the branch conditions.<br><br>If you look for the bits of code that handle COND_NP_OR_E and COND_NE_OR_P there doesn't seem to be any optimizations done with them. X86InstrInfo::InsertBranch looks at them and inserts two branches.<br><br>What is the rationale behind converting a JE/JNP and JNE/JP into COND_NE_OR_P and COND_NP_OR_E?<br></blockquote><br>I think these are used to merge two conditional branches into one and split them back out again later. It seems like a hack to allow AnalyzeBranch to handle BB with two conditional branches. They correspond to OEQ and UNE.<br><br></blockquote><blockquote type="cite">Is it possible to teach ReverseBranchCondition to do the right thing? Ain't OEQ the reverse of UNE and vice versa?<br><br></blockquote>It looks like I can safely teach GetOppositeBranchCondition to return the opposite for the two COND_* above. We do have an interesting case, though. If I change the original code to "une" instead of "oeq" like this:<div><br></div><div>define float @func2(float %x, float %y) nounwind readnone optsize ssp {<br>entry:<br>  %0 = fpext float %x to double                   ; <double> [#uses=1]<br>  %1 = fpext float %y to double                   ; <double> [#uses=1]<br>  %2 = fmul double %0, %1                         ; <double> [#uses=3]<br>  %3 = fcmp <b>une</b> double %2, 0.000000e+00           ; <i1> [#uses=1]<br>  br i1 %3, label %bb2, label %bb1<br><br>bb1:                                              ; preds = %entry<br>  %4 = fadd double %2, -1.000000e+00              ; <double> [#uses=1]<br>  br label %bb2<br><br>bb2:                                              ; preds = %entry, %bb1<br>  %.0.in = phi double [ %4, %bb1 ], [ %2, %entry ] ; <double> [#uses=1]<br>  %.0 = fptrunc double %.0.in to float            ; <float> [#uses=1]<br>  ret float %.0<br>}<br><br><div>Then we generate this for the "fcmp une ..."</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>%AL<def> = SETNPr %EFLAGS<imp-use><br><span class="Apple-tab-span" style="white-space:pre">    </span>%CL<def> = SETEr %EFLAGS<imp-use,kill><br><span class="Apple-tab-span" style="white-space:pre">        </span>TEST8rr %CL<kill>, %AL<kill>, %EFLAGS<imp-def><br><span class="Apple-tab-span" style="white-space:pre">  </span>JE_4 <BB#2>, %EFLAGS<imp-use><br><br></div><div>Ick. I suppose we should instead be generating?</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>JNP_4 <BB#2>, %EFLAGS<imp-use></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>JE_4 <BB#2>, %EFLAGS<imp-use></div><div><br></div><div>-bw</div><div><br></div></div></body></html>