<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>