[llvm-commits] [llvm] r162174 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/fcmp.ll

Nick Lewycky nicholas at mxc.ca
Sun Aug 19 00:53:50 PDT 2012


Benjamin Kramer wrote:
> Author: d0k
> Date: Sat Aug 18 15:06:47 2012
> New Revision: 162174
>
> URL: http://llvm.org/viewvc/llvm-project?rev=162174&view=rev
> Log:
> InstCombine: Add a couple of fabs identities for comparing with 0.0.
>
> Modified:
>      llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
>      llvm/trunk/test/Transforms/InstCombine/fcmp.ll
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=162174&r1=162173&r2=162174&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Sat Aug 18 15:06:47 2012
> @@ -17,6 +17,7 @@
>   #include "llvm/Analysis/InstructionSimplify.h"
>   #include "llvm/Analysis/MemoryBuiltins.h"
>   #include "llvm/Target/TargetData.h"
> +#include "llvm/Target/TargetLibraryInfo.h"
>   #include "llvm/Support/ConstantRange.h"
>   #include "llvm/Support/GetElementPtrTypeIterator.h"
>   #include "llvm/Support/PatternMatch.h"
> @@ -2985,6 +2986,44 @@
>                   return Res;
>           }
>           break;
> +      case Instruction::Call: {
> +        CallInst *CI = cast<CallInst>(LHSI);
> +        LibFunc::Func Func;
> +        // Various optimization for fabs compared with zero.
> +        if (RHSC->isNullValue()&&  CI->hasOneUse()&&
> +            TLI->getLibFunc(CI->getCalledFunction()->getName(), Func)&&
> +            TLI->has(Func)) {
> +          if (Func == LibFunc::fabs || Func == LibFunc::fabsf ||
> +              Func == LibFunc::fabsl) {
> +            switch (I.getPredicate()) {
> +            default: break;
> +            // fabs(x)<  0 -->  false
> +            case FCmpInst::FCMP_OLT:
> +              return ReplaceInstUsesWith(I, Builder->getFalse());
> +            // fabs(x)>  0 -->  x != 0
> +            case FCmpInst::FCMP_OGT:
> +              return new FCmpInst(FCmpInst::FCMP_ONE, CI->getArgOperand(0),
> +                                  RHSC);
> +            // fabs(x)<= 0 -->  x == 0
> +            case FCmpInst::FCMP_OLE:
> +              return new FCmpInst(FCmpInst::FCMP_OEQ, CI->getArgOperand(0),
> +                                  RHSC);
> +            // fabs(x)>= 0 -->  !isnan(x)
> +            case FCmpInst::FCMP_OGE:
> +              return new FCmpInst(FCmpInst::FCMP_ORD, CI->getArgOperand(0),
> +                                  RHSC);
> +            // fabs(x) == 0 -->  x == 0
> +            // fabs(x) != 0 -->  x != 0
> +            case FCmpInst::FCMP_OEQ:
> +            case FCmpInst::FCMP_UEQ:
> +            case FCmpInst::FCMP_ONE:
> +            case FCmpInst::FCMP_UNE:
> +              return new FCmpInst(I.getPredicate(), CI->getArgOperand(0),
> +                                  RHSC);
> +            }
> +          }
> +        }
> +      }

There's nothing wrong with this, but I wish it weren't being 
special-cased. We should start adding floating-point analysis to 
ValueTracking, and this is an excellent time. I suggest an API where you 
hand it an fpmath computation (could be a call or an instruction) and it 
tells you whether it is known not to be:
   isInf, isNan, == 0, positive non-zero, negative non-zero
That will grow over time, both in solving power and in callsites.

Nick

>         }
>     }
>
>
> Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=162174&r1=162173&r2=162174&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Sat Aug 18 15:06:47 2012
> @@ -69,3 +69,85 @@
>   ; CHECK: @test8
>   ; CHECK-NEXT: fcmp olt float %x, 0.000000e+00
>   }
> +
> +declare double @fabs(double) nounwind readnone
> +
> +define i32 @test9(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp olt double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test9
> +; CHECK-NOT: fabs
> +; CHECK: ret i32 0
> +}
> +
> +define i32 @test10(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp ole double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test10
> +; CHECK-NOT: fabs
> +; CHECK: fcmp oeq double %a, 0.000000e+00
> +}
> +
> +define i32 @test11(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp ogt double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test11
> +; CHECK-NOT: fabs
> +; CHECK: fcmp one double %a, 0.000000e+00
> +}
> +
> +define i32 @test12(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp oge double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test12
> +; CHECK-NOT: fabs
> +; CHECK: fcmp ord double %a, 0.000000e+00
> +}
> +
> +define i32 @test13(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp une double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test13
> +; CHECK-NOT: fabs
> +; CHECK: fcmp une double %a, 0.000000e+00
> +}
> +
> +define i32 @test14(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp oeq double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test14
> +; CHECK-NOT: fabs
> +; CHECK: fcmp oeq double %a, 0.000000e+00
> +}
> +
> +define i32 @test15(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp one double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test15
> +; CHECK-NOT: fabs
> +; CHECK: fcmp one double %a, 0.000000e+00
> +}
> +
> +define i32 @test16(double %a) nounwind {
> +  %call = tail call double @fabs(double %a) nounwind
> +  %cmp = fcmp ueq double %call, 0.000000e+00
> +  %conv = zext i1 %cmp to i32
> +  ret i32 %conv
> +; CHECK: @test16
> +; CHECK-NOT: fabs
> +; CHECK: fcmp ueq double %a, 0.000000e+00
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list