via llvm-dev
2016-Apr-07 16:43 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
I am not entirely sure this is safe. Transforming this to an fsub could change the value stored on platforms that implement negates using arithmetic instead of with bitmath (such as ours) and either canonicalize NaNs or don’t support denormals. This is actually important because this kind of bitmath on floats is very commonly used as part of algorithms for complex math functions that need to get precise bit patterns from the source (similarly for the transformation of masking off the sign bit -> fabs). It’s also important because if the float happens to “really” be an integer, it’s highly likely we’ll end up zero-flushing it and losing the data. Example: a = load float b = bitcast a to int c = xor b, signbit d = bitcast c to float store d Personally I would feel this is safe if and only if the float is coming from an arithmetic operation — in that case, we know that doing another arithmetic operation on it should be safe, since it’s already canonalized and can’t be a denorm [if the platform doesn’t support them]. I say this coming only a few weeks after our team spent literally dozens of human-hours tracking down an extremely obscure bug involving a GL conformance test in which ints were casted to floats, manipulated with float instructions, then sent back to int, resulting in the ints being flushed to zero and the test failing. —escha> On Apr 7, 2016, at 9:09 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi Carlos - > > That sounds like a good patch. > > Warning - following the link below may remove some of the educational joy for the immediate task at hand: > http://reviews.llvm.org/D13076 <http://reviews.llvm.org/D13076> > > ...but I wouldn't worry too much, there's plenty more opportunity where that came from. :) > > Feel free to post follow-up questions here or via a patch review on Phabricator: > http://llvm.org/docs/Phabricator.html <http://llvm.org/docs/Phabricator.html> > > > On Thu, Apr 7, 2016 at 7:17 AM, Carlos Liam via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: > Hi, > > I'm interested in implementing an InstCombine optimization that I discovered and verified with Alive-NJ (with the help of the authors of Alive-NJ). The optimization is described in Alive-NJ format as follows: > > Name: xor->fsub > Pre: isSignBit(C) > %x = bitcast %A > %y = xor %x, C > %z = bitcast %y > => > %z = fsub -0.0, %A > > Effectively the optimization targets code that casts a float to an int with the same width, XORs the sign bit, and casts back to float, and replaces it with a subtraction from -0.0. > > I am not very familiar with C++ or the LLVM codebase so I would greatly appreciate some help in writing a patch adding this optimization. > > Thanks in advance. > > - CL > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160407/29f721ec/attachment.html>
Carlos Liam via llvm-dev
2016-Apr-07 17:06 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
@escha: Alive-NJ (https://github.com/rutgers-apl/alive-nj) verifies the optimization as correct for half, single and double floating-point types: carloss-mbp:alive-nj aarzee$ python run.py ~/floatcast.opt ---------- Name: /Users/aarzee/floatcast.opt#1:xor->fsub Pre: isSignBit(C) %x = bitcast %A %y = xor %x, C %z = bitcast %y => %z = fsub -0.0, %A Done: 3 Optimization is correct However, I'm not entirely familiar with the machinery behind Alive-NJ and whether the concerns you raise are covered. @Sanjay: This is what I have so far, with necessary changes marked as XXX: diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 8ca0e50..e08881d 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1748,7 +1748,7 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS, // E.g. (icmp sgt x, n) | (icmp slt x, 0) --> icmp ugt x, n if (Value *V = simplifyRangeCheck(RHS, LHS, /*Inverted=*/true)) return V; - + // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2). if (!LHSCst || !RHSCst) return nullptr; @@ -2748,5 +2748,19 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { } } + // If we are XORing the sign bit of a floating-point value, convert + // this to fsub from -0.0, then cast back to integer. + ConstantInt *CI; + if (isa<BitCastInst>(Op0C) && SrcTy->isFloatingPointTy() && + match(Op1, m_ConstantInt(CI)) && CI->isSignBit(true)) { + // XXX ^ changed to isSignBit + Module *M = I.getModule(); + Function *Fabs = Intrinsic::getDeclaration(M, Intrinsic::fabs, SrcTy); + // ^ XXX this is wrong; I need the equivalent of fsub -0.0, M + Value *Call = Builder->CreateCall(Fabs, Op0COp, "fabs"); + // ^ XXX also wrong + return CastInst::CreateBitOrPointerCast(Call, I.getType()); + } + return Changed ? &I : nullptr; } The whitespace change is an artifact from my text editor. - CL> On Apr 7, 2016, at 12:43 PM, escha at apple.com wrote: > > I am not entirely sure this is safe. Transforming this to an fsub could change the value stored on platforms that implement negates using arithmetic instead of with bitmath (such as ours) and either canonicalize NaNs or don’t support denormals. This is actually important because this kind of bitmath on floats is very commonly used as part of algorithms for complex math functions that need to get precise bit patterns from the source (similarly for the transformation of masking off the sign bit -> fabs). It’s also important because if the float happens to “really” be an integer, it’s highly likely we’ll end up zero-flushing it and losing the data. > > Example: > > a = load float > b = bitcast a to int > c = xor b, signbit > d = bitcast c to float > store d > > Personally I would feel this is safe if and only if the float is coming from an arithmetic operation — in that case, we know that doing another arithmetic operation on it should be safe, since it’s already canonalized and can’t be a denorm [if the platform doesn’t support them]. > > I say this coming only a few weeks after our team spent literally dozens of human-hours tracking down an extremely obscure bug involving a GL conformance test in which ints were casted to floats, manipulated with float instructions, then sent back to int, resulting in the ints being flushed to zero and the test failing. > > —escha > >> On Apr 7, 2016, at 9:09 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org> wrote: >> >> Hi Carlos - >> >> That sounds like a good patch. >> >> Warning - following the link below may remove some of the educational joy for the immediate task at hand: >> http://reviews.llvm.org/D13076 >> >> ...but I wouldn't worry too much, there's plenty more opportunity where that came from. :) >> >> Feel free to post follow-up questions here or via a patch review on Phabricator: >> http://llvm.org/docs/Phabricator.html >> >> >> On Thu, Apr 7, 2016 at 7:17 AM, Carlos Liam via llvm-dev <llvm-dev at lists.llvm.org> wrote: >> Hi, >> >> I'm interested in implementing an InstCombine optimization that I discovered and verified with Alive-NJ (with the help of the authors of Alive-NJ). The optimization is described in Alive-NJ format as follows: >> >> Name: xor->fsub >> Pre: isSignBit(C) >> %x = bitcast %A >> %y = xor %x, C >> %z = bitcast %y >> => >> %z = fsub -0.0, %A >> >> Effectively the optimization targets code that casts a float to an int with the same width, XORs the sign bit, and casts back to float, and replaces it with a subtraction from -0.0. >> >> I am not very familiar with C++ or the LLVM codebase so I would greatly appreciate some help in writing a patch adding this optimization. >> >> Thanks in advance. >> >> - CL >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
via llvm-dev
2016-Apr-07 17:09 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
> On Apr 7, 2016, at 10:06 AM, Carlos Liam <carlos at aarzee.me> wrote: > > @escha: > > Alive-NJ (https://github.com/rutgers-apl/alive-nj) verifies the optimization as correct for half, single and double floating-point types:The problem is that it proves it’s correct on a certain set of semantics, but not all targets will share those semantics, which is something you have to be very careful about with floating point. In some cases “correct under IEEE” means “correct under non-IEEE”, but in other cases it doesn’t. —escha
Sanjay Patel via llvm-dev
2016-Apr-07 20:46 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
Yes, if transforming the int op to an FP op induces target-dependent behavior, then we can't do this transform in InstCombine without some kind of predication. And we should revert or rein in: http://reviews.llvm.org/rL249702 As I noted in that commit message, it's not clear what the FP model of LLVM IR actually is. Based on existing IR transforms, I assumed it was IEEE-754...ish. On Thu, Apr 7, 2016 at 10:43 AM, <escha at apple.com> wrote:> I am not entirely sure this is safe. Transforming this to an fsub could > change the value stored on platforms that implement negates using > arithmetic instead of with bitmath (such as ours) and either canonicalize > NaNs or don’t support denormals. This is actually important because this > kind of bitmath on floats is very commonly used as part of algorithms for > complex math functions that need to get precise bit patterns from the > source (similarly for the transformation of masking off the sign bit -> > fabs). It’s also important because if the float happens to “really” be an > integer, it’s highly likely we’ll end up zero-flushing it and losing the > data. > > Example: > > a = load float > b = bitcast a to int > c = xor b, signbit > d = bitcast c to float > store d > > Personally I would feel this is safe if and only if the float is coming > from an arithmetic operation — in that case, we know that doing another > arithmetic operation on it should be safe, since it’s already canonalized > and can’t be a denorm [if the platform doesn’t support them]. > > I say this coming only a few weeks after our team spent literally dozens > of human-hours tracking down an extremely obscure bug involving a GL > conformance test in which ints were casted to floats, manipulated with > float instructions, then sent back to int, resulting in the ints being > flushed to zero and the test failing. > > —escha > > > On Apr 7, 2016, at 9:09 AM, Sanjay Patel via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > Hi Carlos - > > That sounds like a good patch. > > Warning - following the link below may remove some of the educational joy > for the immediate task at hand: > http://reviews.llvm.org/D13076 > > ...but I wouldn't worry too much, there's plenty more opportunity where > that came from. :) > > Feel free to post follow-up questions here or via a patch review on > Phabricator: > http://llvm.org/docs/Phabricator.html > > > On Thu, Apr 7, 2016 at 7:17 AM, Carlos Liam via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Hi, >> >> I'm interested in implementing an InstCombine optimization that I >> discovered and verified with Alive-NJ (with the help of the authors of >> Alive-NJ). The optimization is described in Alive-NJ format as follows: >> >> Name: xor->fsub >> Pre: isSignBit(C) >> %x = bitcast %A >> %y = xor %x, C >> %z = bitcast %y >> => >> %z = fsub -0.0, %A >> >> Effectively the optimization targets code that casts a float to an int >> with the same width, XORs the sign bit, and casts back to float, and >> replaces it with a subtraction from -0.0. >> >> I am not very familiar with C++ or the LLVM codebase so I would greatly >> appreciate some help in writing a patch adding this optimization. >> >> Thanks in advance. >> >> - CL >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160407/911b68af/attachment.html>
via llvm-dev
2016-Apr-07 21:27 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
I feel like a reasonable way of defining it would be that it’s IEEE-754-like, except that if the target diverges from IEEE-754 (in terms of ’missing some part of IEEE-754’ or ‘less precise than IEEE-574’ etc), the transformations we introduce shouldn’t break *other things*. e.g. if a target does not support denormals, float ops throughout LLVM are as such free to lose their denormals at any time. This doesn’t normally cause problems, but if you allow turning int ops into float ops, you now allow int operations to destroy denormals at any time, which is more powerful (and more dangerous) than the target natively defines, I think. —escha> On Apr 7, 2016, at 1:46 PM, Sanjay Patel <spatel at rotateright.com> wrote: > > Yes, if transforming the int op to an FP op induces target-dependent behavior, then we can't do this transform in InstCombine without some kind of predication. And we should revert or rein in: > http://reviews.llvm.org/rL249702 <http://reviews.llvm.org/rL249702> > > As I noted in that commit message, it's not clear what the FP model of LLVM IR actually is. Based on existing IR transforms, I assumed it was IEEE-754...ish. > > > On Thu, Apr 7, 2016 at 10:43 AM, <escha at apple.com <mailto:escha at apple.com>> wrote: > I am not entirely sure this is safe. Transforming this to an fsub could change the value stored on platforms that implement negates using arithmetic instead of with bitmath (such as ours) and either canonicalize NaNs or don’t support denormals. This is actually important because this kind of bitmath on floats is very commonly used as part of algorithms for complex math functions that need to get precise bit patterns from the source (similarly for the transformation of masking off the sign bit -> fabs). It’s also important because if the float happens to “really” be an integer, it’s highly likely we’ll end up zero-flushing it and losing the data. > > Example: > > a = load float > b = bitcast a to int > c = xor b, signbit > d = bitcast c to float > store d > > Personally I would feel this is safe if and only if the float is coming from an arithmetic operation — in that case, we know that doing another arithmetic operation on it should be safe, since it’s already canonalized and can’t be a denorm [if the platform doesn’t support them]. > > I say this coming only a few weeks after our team spent literally dozens of human-hours tracking down an extremely obscure bug involving a GL conformance test in which ints were casted to floats, manipulated with float instructions, then sent back to int, resulting in the ints being flushed to zero and the test failing. > > —escha > > >> On Apr 7, 2016, at 9:09 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >> >> Hi Carlos - >> >> That sounds like a good patch. >> >> Warning - following the link below may remove some of the educational joy for the immediate task at hand: >> http://reviews.llvm.org/D13076 <http://reviews.llvm.org/D13076> >> >> ...but I wouldn't worry too much, there's plenty more opportunity where that came from. :) >> >> Feel free to post follow-up questions here or via a patch review on Phabricator: >> http://llvm.org/docs/Phabricator.html <http://llvm.org/docs/Phabricator.html> >> >> >> On Thu, Apr 7, 2016 at 7:17 AM, Carlos Liam via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >> Hi, >> >> I'm interested in implementing an InstCombine optimization that I discovered and verified with Alive-NJ (with the help of the authors of Alive-NJ). The optimization is described in Alive-NJ format as follows: >> >> Name: xor->fsub >> Pre: isSignBit(C) >> %x = bitcast %A >> %y = xor %x, C >> %z = bitcast %y >> => >> %z = fsub -0.0, %A >> >> Effectively the optimization targets code that casts a float to an int with the same width, XORs the sign bit, and casts back to float, and replaces it with a subtraction from -0.0. >> >> I am not very familiar with C++ or the LLVM codebase so I would greatly appreciate some help in writing a patch adding this optimization. >> >> Thanks in advance. >> >> - CL >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160407/f38e7087/attachment.html>
Alex Rosenberg via llvm-dev
2016-Apr-09 01:44 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
This doesn't seem like a good idea to me. There are many architectures where those bitcasts are free operations and the xor will be executed in a shorter pipe than any FP op would. Cell SPU, for example. This could introduce new FP exceptions. It's also likely to be much worse on platforms with no FPU like early MIPS. Alex> On Apr 7, 2016, at 9:43 AM, via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > I am not entirely sure this is safe. Transforming this to an fsub could change the value stored on platforms that implement negates using arithmetic instead of with bitmath (such as ours) and either canonicalize NaNs or don’t support denormals. This is actually important because this kind of bitmath on floats is very commonly used as part of algorithms for complex math functions that need to get precise bit patterns from the source (similarly for the transformation of masking off the sign bit -> fabs). It’s also important because if the float happens to “really” be an integer, it’s highly likely we’ll end up zero-flushing it and losing the data. > > Example: > > a = load float > b = bitcast a to int > c = xor b, signbit > d = bitcast c to float > store d > > Personally I would feel this is safe if and only if the float is coming from an arithmetic operation ― in that case, we know that doing another arithmetic operation on it should be safe, since it’s already canonalized and can’t be a denorm [if the platform doesn’t support them]. > > I say this coming only a few weeks after our team spent literally dozens of human-hours tracking down an extremely obscure bug involving a GL conformance test in which ints were casted to floats, manipulated with float instructions, then sent back to int, resulting in the ints being flushed to zero and the test failing. > > ―escha > >> On Apr 7, 2016, at 9:09 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org> wrote: >> >> Hi Carlos - >> >> That sounds like a good patch. >> >> Warning - following the link below may remove some of the educational joy for the immediate task at hand: >> http://reviews.llvm.org/D13076 >> >> ...but I wouldn't worry too much, there's plenty more opportunity where that came from. :) >> >> Feel free to post follow-up questions here or via a patch review on Phabricator: >> http://llvm.org/docs/Phabricator.html >> >> >>> On Thu, Apr 7, 2016 at 7:17 AM, Carlos Liam via llvm-dev <llvm-dev at lists.llvm.org> wrote: >>> Hi, >>> >>> I'm interested in implementing an InstCombine optimization that I discovered and verified with Alive-NJ (with the help of the authors of Alive-NJ). The optimization is described in Alive-NJ format as follows: >>> >>> Name: xor->fsub >>> Pre: isSignBit(C) >>> %x = bitcast %A >>> %y = xor %x, C >>> %z = bitcast %y >>> => >>> %z = fsub -0.0, %A >>> >>> Effectively the optimization targets code that casts a float to an int with the same width, XORs the sign bit, and casts back to float, and replaces it with a subtraction from -0.0. >>> >>> I am not very familiar with C++ or the LLVM codebase so I would greatly appreciate some help in writing a patch adding this optimization. >>> >>> Thanks in advance. >>> >>> - CL >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160408/bde743aa/attachment.html>
David Chisnall via llvm-dev
2016-Apr-09 06:46 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
It’s definitely one that would need some target hooks, and is probably not actually worth doing without analysing the producers and consumers of the value. If the source and destination values need to be in floating point registers, the cost of FPR<->GPR moves is likely to be a lot higher than the cost of the subtract, even if the xor is free. If the results are going to end up in integer registers or memory, then the xor version is probably cheaper (though, even there, it may be better for register pressure to keep the results in FPRs). I’d expect that most users of this pattern are immediately followed by a branch on the result. On some architectures, that can become a branch on a floating point condition code, but on others it’s going to be a move to GPR, which means that you lose the win entirely. David> On 9 Apr 2016, at 02:44, Alex Rosenberg via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > This doesn't seem like a good idea to me. There are many architectures where those bitcasts are free operations and the xor will be executed in a shorter pipe than any FP op would. Cell SPU, for example. > > This could introduce new FP exceptions. It's also likely to be much worse on platforms with no FPU like early MIPS. > > Alex > > On Apr 7, 2016, at 9:43 AM, via llvm-dev <llvm-dev at lists.llvm.org> wrote: > >> I am not entirely sure this is safe. Transforming this to an fsub could change the value stored on platforms that implement negates using arithmetic instead of with bitmath (such as ours) and either canonicalize NaNs or don’t support denormals. This is actually important because this kind of bitmath on floats is very commonly used as part of algorithms for complex math functions that need to get precise bit patterns from the source (similarly for the transformation of masking off the sign bit -> fabs). It’s also important because if the float happens to “really” be an integer, it’s highly likely we’ll end up zero-flushing it and losing the data. >> >> Example: >> >> a = load float >> b = bitcast a to int >> c = xor b, signbit >> d = bitcast c to float >> store d >> >> Personally I would feel this is safe if and only if the float is coming from an arithmetic operation — in that case, we know that doing another arithmetic operation on it should be safe, since it’s already canonalized and can’t be a denorm [if the platform doesn’t support them]. >> >> I say this coming only a few weeks after our team spent literally dozens of human-hours tracking down an extremely obscure bug involving a GL conformance test in which ints were casted to floats, manipulated with float instructions, then sent back to int, resulting in the ints being flushed to zero and the test failing. >> >> —escha >> >>> On Apr 7, 2016, at 9:09 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org> wrote: >>> >>> Hi Carlos - >>> >>> That sounds like a good patch. >>> >>> Warning - following the link below may remove some of the educational joy for the immediate task at hand: >>> http://reviews.llvm.org/D13076 >>> >>> ...but I wouldn't worry too much, there's plenty more opportunity where that came from. :) >>> >>> Feel free to post follow-up questions here or via a patch review on Phabricator: >>> http://llvm.org/docs/Phabricator.html >>> >>> >>> On Thu, Apr 7, 2016 at 7:17 AM, Carlos Liam via llvm-dev <llvm-dev at lists.llvm.org> wrote: >>> Hi, >>> >>> I'm interested in implementing an InstCombine optimization that I discovered and verified with Alive-NJ (with the help of the authors of Alive-NJ). The optimization is described in Alive-NJ format as follows: >>> >>> Name: xor->fsub >>> Pre: isSignBit(C) >>> %x = bitcast %A >>> %y = xor %x, C >>> %z = bitcast %y >>> => >>> %z = fsub -0.0, %A >>> >>> Effectively the optimization targets code that casts a float to an int with the same width, XORs the sign bit, and casts back to float, and replaces it with a subtraction from -0.0. >>> >>> I am not very familiar with C++ or the LLVM codebase so I would greatly appreciate some help in writing a patch adding this optimization. >>> >>> Thanks in advance. >>> >>> - CL >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Daniel Sanders via llvm-dev
2016-Apr-11 11:23 UTC
[llvm-dev] Implementing a proposed InstCombine optimization
> I am not entirely sure this is safe. Transforming this to an fsub could change the value stored on platforms that implement negates using arithmetic instead of with bitmath (such as ours)I think it's probably safe for IEEE754-2008 conformant platforms because negation was clarified to be a non-arithmetic bit flip that cannot cause exceptions in that specification. However, I'm sure it's unsafe for some IEEE754-1985 platforms because it introduces exceptions when given a NaN. On MIPS, the semantics for negation depend on a configuration bit (ABS2008) but in practice the majority of MIPS environments use arithmetic negation and trigger exceptions when negating a NaN. That said, the most recently published MIPS specifications require non-arithmetic negation and drop support for the IEEE754-1985 standard.> This could introduce new FP exceptions. It's also likely to be much worse on platforms with no FPU like early MIPS.Quite a few modern implementations too. MIPS is often used in domains where having an FPU would be wasteful. From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of Alex Rosenberg via llvm-dev Sent: 09 April 2016 02:44 To: escha at apple.com Cc: Carlos Liam; llvm-dev Subject: Re: [llvm-dev] Implementing a proposed InstCombine optimization This doesn't seem like a good idea to me. There are many architectures where those bitcasts are free operations and the xor will be executed in a shorter pipe than any FP op would. Cell SPU, for example. This could introduce new FP exceptions. It's also likely to be much worse on platforms with no FPU like early MIPS. Alex On Apr 7, 2016, at 9:43 AM, via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: I am not entirely sure this is safe. Transforming this to an fsub could change the value stored on platforms that implement negates using arithmetic instead of with bitmath (such as ours) and either canonicalize NaNs or don’t support denormals. This is actually important because this kind of bitmath on floats is very commonly used as part of algorithms for complex math functions that need to get precise bit patterns from the source (similarly for the transformation of masking off the sign bit -> fabs). It’s also important because if the float happens to “really” be an integer, it’s highly likely we’ll end up zero-flushing it and losing the data. Example: a = load float b = bitcast a to int c = xor b, signbit d = bitcast c to float store d Personally I would feel this is safe if and only if the float is coming from an arithmetic operation — in that case, we know that doing another arithmetic operation on it should be safe, since it’s already canonalized and can’t be a denorm [if the platform doesn’t support them]. I say this coming only a few weeks after our team spent literally dozens of human-hours tracking down an extremely obscure bug involving a GL conformance test in which ints were casted to floats, manipulated with float instructions, then sent back to int, resulting in the ints being flushed to zero and the test failing. —escha On Apr 7, 2016, at 9:09 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: Hi Carlos - That sounds like a good patch. Warning - following the link below may remove some of the educational joy for the immediate task at hand: http://reviews.llvm.org/D13076 ...but I wouldn't worry too much, there's plenty more opportunity where that came from. :) Feel free to post follow-up questions here or via a patch review on Phabricator: http://llvm.org/docs/Phabricator.html On Thu, Apr 7, 2016 at 7:17 AM, Carlos Liam via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: Hi, I'm interested in implementing an InstCombine optimization that I discovered and verified with Alive-NJ (with the help of the authors of Alive-NJ). The optimization is described in Alive-NJ format as follows: Name: xor->fsub Pre: isSignBit(C) %x = bitcast %A %y = xor %x, C %z = bitcast %y => %z = fsub -0.0, %A Effectively the optimization targets code that casts a float to an int with the same width, XORs the sign bit, and casts back to float, and replaces it with a subtraction from -0.0. I am not very familiar with C++ or the LLVM codebase so I would greatly appreciate some help in writing a patch adding this optimization. Thanks in advance. - CL _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160411/6cb54f37/attachment.html>