[llvm-commits] [llvm] r101075 - in /llvm/trunk: lib/Target/X86/X86InstrInfo.cpp test/CodeGen/X86/brcond.ll
Dan Gohman
gohman at apple.com
Tue Apr 13 11:15:08 PDT 2010
On Apr 13, 2010, at 2:01 AM, Bill Wendling wrote:
> On Apr 12, 2010, at 7:20 PM, Evan Cheng wrote:
>
>>> The problem lies in this bit of code in X86InstrInfo::AnalyzeBranch:
>>>
>>> // If they differ, see if they fit one of the known patterns. Theoretically,
>>> // we could handle more patterns here, but we shouldn't expect to see them
>>> // if instruction selection has done a reasonable job.
>>> if ((OldBranchCode == X86::COND_NP &&
>>> BranchCode == X86::COND_E) ||
>>> (OldBranchCode == X86::COND_E &&
>>> BranchCode == X86::COND_NP))
>>> BranchCode = X86::COND_NP_OR_E;
>>> else if ((OldBranchCode == X86::COND_P &&
>>> BranchCode == X86::COND_NE) ||
>>> (OldBranchCode == X86::COND_NE &&
>>> BranchCode == X86::COND_P))
>>> BranchCode = X86::COND_NE_OR_P;
>>> else
>>> return true;
>>>
>>> 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.
>>>
>>> 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.
>>>
>>> What is the rationale behind converting a JE/JNP and JNE/JP into COND_NE_OR_P and COND_NP_OR_E?
>>
>> 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.
>>
>> Is it possible to teach ReverseBranchCondition to do the right thing? Ain't OEQ the reverse of UNE and vice versa?
>>
> 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:
>
> define float @func2(float %x, float %y) nounwind readnone optsize ssp {
> entry:
> %0 = fpext float %x to double ; <double> [#uses=1]
> %1 = fpext float %y to double ; <double> [#uses=1]
> %2 = fmul double %0, %1 ; <double> [#uses=3]
> %3 = fcmp une double %2, 0.000000e+00 ; <i1> [#uses=1]
> br i1 %3, label %bb2, label %bb1
>
> bb1: ; preds = %entry
> %4 = fadd double %2, -1.000000e+00 ; <double> [#uses=1]
> br label %bb2
>
> bb2: ; preds = %entry, %bb1
> %.0.in = phi double [ %4, %bb1 ], [ %2, %entry ] ; <double> [#uses=1]
> %.0 = fptrunc double %.0.in to float ; <float> [#uses=1]
> ret float %.0
> }
>
> Then we generate this for the "fcmp une ..."
>
> %AL<def> = SETNPr %EFLAGS<imp-use>
> %CL<def> = SETEr %EFLAGS<imp-use,kill>
> TEST8rr %CL<kill>, %AL<kill>, %EFLAGS<imp-def>
> JE_4 <BB#2>, %EFLAGS<imp-use>
>
> Ick. I suppose we should instead be generating?
>
> JNP_4 <BB#2>, %EFLAGS<imp-use>
> JE_4 <BB#2>, %EFLAGS<imp-use>
This isn't equivalent. The first version jumps only if both conditions are
true, the second if either one is true.
Dan
More information about the llvm-commits
mailing list