[LLVMdev] Why can't comparisons with negative zero be simplified?

Sean Silva chisophugis at gmail.com
Tue Jul 7 20:11:45 PDT 2015


On Tue, Jul 7, 2015 at 7:33 AM, Robison, Arch <arch.robison at intel.com>
wrote:

>  I concur with your analysis.
>
>
>
> I was planning to just extend the applicability of the current transform
> by just taking on more cases where the inverse image is a single value.
> Though if someone else wants to take on the general range case, I’m happy
> to step aside. :-)
>

If you have access to the test case for which this optimization was missing
cases (at least -0), can you hack in some code in FoldFCmp_IntToFP_Cst to
see how many times we are actually bailing out of here in your test case
due to not handling the fully general case?  If it's a lot, it is probably
worth filing a bugzilla (please CC me if you do).

-- Sean Silva


>
>
> - Arch
>
>
>
> *From:* Sean Silva [mailto:chisophugis at gmail.com]
> *Sent:* Monday, July 6, 2015 6:10 PM
> *To:* Robison, Arch
> *Cc:* llvmdev at cs.uiuc.edu
> *Subject:* Re: [LLVMdev] Why can't comparisons with negative zero be
> simplified?
>
>
>
> The way FoldFCmp_IntToFP_Cst works is confusing to me. What it is trying
> to do basically boils down to taking the set of real numbers where fcmp(?,
> Cst) is true, then finding the inverse image under the mapping [us]itofp of
> that set (i.e. all the integers (of the relevant type) that can map to
> values in that set under the operation [us]itofp). That inverse image is
> guaranteed to be contiguous, so at most two integer comparisons suffice. If
> the inverse image is just a single value, then a single equality comparison
> suffices. If the inverse image includes the {maximal,minimal}
> {signed,unsigned} integer, then a single integer order comparison suffices.
>
>
>
> So e.g. consider
>
>   fcmp oeq double (uitofp x) Cst
>
> With Cst = 2^62 + ulp(2^62)), i.e. 2^62*(0b1.0000....1), where the final 1
> is in the least significant bit.
>
>
>
> Then the set of real numbers for which `fcmp oeq double
> roundToFloat(realNumber) Cst` yields true is the open interval (a,b) where
>
> a = 2^62 + .5*ulp(2^62)
>
> b = 2^62 + 1.5*ulp(2^62)
>
> i.e. the open interval bracketed by Cst +/- .5*ulp(Cst)
>
> (assuming round to nearest ties to even rounding mode)
>
> However, since ulp(Cst) = ulp(2^62) = 2^62 * 2^-52 = 2^10, this means that
> this range covers
>
> (2^62 + (1/2)*2^10, 2^62 + (3/2)*2^10) = [2^62 + (1/2)*2^10 + 1, 2^62 +
> (3/2)*2^10 - 1] which contains 1022 integers, so a range comparison is
> needed.
>
> (note: for Cst = 2^62, the interval is only half as large on the low side
> since Cst lies on the boundary where the exponent changes, i.e. the
> interval is [Cst - .25*ulp(Cst), Cst + .5*ulp(Cst)]; the closed interval is
> due to 2^62 being even)
>
>
>
> This of course requires baking in a rounding mode, but we are already
> doing that anyway.
>
>
>
> -- Sean Silva
>
>
>
> On Mon, Jul 6, 2015 at 2:13 PM, Robison, Arch <arch.robison at intel.com>
> wrote:
>
>  In InstCombineCompares.cpp, routine InstCombiner::FoldFCmp_IntToFP_Cst,
> there are these lines:
>
>
>
>   // Comparisons with zero are a special case where we know we won't lose
>
>   // information.
>
>   bool IsCmpZero = RHS.isPosZero();
>
>
>
>   // If the conversion would lose info, don't hack on this.
>
>   if ((int)InputSize > MantissaWidth && !IsCmpZero)
>
>     return nullptr;
>
>
>
> Why check for positive zero instead of checking for any kind of zero?  My
> reading of IEEE 754-2008 is that floating-point comparison operations
> cannot distinguish a negative zero from a positive zero.  Further
> supporting this is that fact that http://llvm.org/docs/LangRef.html
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_docs_LangRef.html&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=Mfk2qtn1LTDThVkh6-oGglNfMADXfJdty4_bhmuhMHA&m=ZaWNNVon_US-YjLoXztqD5ve4xvIIhIXYdnk3Xqwz8w&s=xonYObEo1TXUyjK3RYC4Pg3kAaSvaYy_Lnvaiq5G1N0&e=>
> describes the difference between “ordered” and “unordered” as pertaining to
> QNAN operands,
>
> with no mention of negative zero.
>
>
>
> I tried fixing the issue, but then the following test in
> cast-int-fcmp-eq-0.ll fails:
>
>
>
> ; CHECK-LABEL: @i32_cast_cmp_oeq_int_n0_uitofp(
>
> ; CHECK: uitofp
>
> ; CHECK: fcmp oeq
>
> define i1 @i32_cast_cmp_oeq_int_n0_uitofp(i32 %i) {
>
>   %f = uitofp i32 %i to float
>
>   %cmp = fcmp oeq float %f, -0.0
>
>   ret i1 %cmp
>
> }
>
>
>
> Is this test really justified, or is it just reinforcing an oversight?
>
>
>
> - Arch D. Robison
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150707/9e39d405/attachment.html>


More information about the llvm-dev mailing list