[llvm] r289894 - [SimplifyLibCalls] Lower fls() to llvm.ctlz().

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 15 15:45:11 PST 2016


Author: davide
Date: Thu Dec 15 17:45:11 2016
New Revision: 289894

URL: http://llvm.org/viewvc/llvm-project?rev=289894&view=rev
Log:
[SimplifyLibCalls] Lower fls() to llvm.ctlz().

Differential Revision:  https://reviews.llvm.org/D14590

Added:
    llvm/trunk/test/Transforms/InstCombine/fls.ll
Modified:
    llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
    llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp
    llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp

Modified: llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h?rev=289894&r1=289893&r2=289894&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Thu Dec 15 17:45:11 2016
@@ -137,6 +137,7 @@ private:
 
   // Integer Library Call Optimizations
   Value *optimizeFFS(CallInst *CI, IRBuilder<> &B);
+  Value *optimizeFls(CallInst *CI, IRBuilder<> &B);
   Value *optimizeAbs(CallInst *CI, IRBuilder<> &B);
   Value *optimizeIsDigit(CallInst *CI, IRBuilder<> &B);
   Value *optimizeIsAscii(CallInst *CI, IRBuilder<> &B);

Modified: llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp?rev=289894&r1=289893&r2=289894&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp Thu Dec 15 17:45:11 2016
@@ -986,6 +986,9 @@ bool TargetLibraryInfoImpl::isValidProto
   case LibFunc::ffs:
   case LibFunc::ffsl:
   case LibFunc::ffsll:
+  case LibFunc::fls:
+  case LibFunc::flsl:
+  case LibFunc::flsll:
     return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) &&
             FTy.getParamType(0)->isIntegerTy());
 
@@ -995,9 +998,6 @@ bool TargetLibraryInfoImpl::isValidProto
     return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) &&
             FTy.getReturnType() == FTy.getParamType(0));
 
-  case LibFunc::fls:
-  case LibFunc::flsl:
-  case LibFunc::flsll:
   case LibFunc::abs:
   case LibFunc::labs:
   case LibFunc::llabs:

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=289894&r1=289893&r2=289894&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Thu Dec 15 17:45:11 2016
@@ -1534,6 +1534,18 @@ Value *LibCallSimplifier::optimizeFFS(Ca
   return B.CreateSelect(Cond, V, B.getInt32(0));
 }
 
+Value *LibCallSimplifier::optimizeFls(CallInst *CI, IRBuilder<> &B) {
+  // fls(x) -> (i32)(sizeInBits(x) - llvm.ctlz(x, false))
+  Value *Op = CI->getArgOperand(0);
+  Type *ArgType = Op->getType();
+  Value *F = Intrinsic::getDeclaration(CI->getCalledFunction()->getParent(),
+                                       Intrinsic::ctlz, ArgType);
+  Value *V = B.CreateCall(F, {Op, B.getFalse()}, "ctlz");
+  V = B.CreateSub(ConstantInt::get(V->getType(), ArgType->getIntegerBitWidth()),
+                  V);
+  return B.CreateIntCast(V, CI->getType(), false);
+}
+
 Value *LibCallSimplifier::optimizeAbs(CallInst *CI, IRBuilder<> &B) {
   // abs(x) -> x >s -1 ? x : -x
   Value *Op = CI->getArgOperand(0);
@@ -2070,6 +2082,10 @@ Value *LibCallSimplifier::optimizeCall(C
     case LibFunc::ffsl:
     case LibFunc::ffsll:
       return optimizeFFS(CI, Builder);
+    case LibFunc::fls:
+    case LibFunc::flsl:
+    case LibFunc::flsll:
+      return optimizeFls(CI, Builder);
     case LibFunc::abs:
     case LibFunc::labs:
     case LibFunc::llabs:

Added: llvm/trunk/test/Transforms/InstCombine/fls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fls.ll?rev=289894&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fls.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/fls.ll Thu Dec 15 17:45:11 2016
@@ -0,0 +1,48 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target triple = "x86_64-unknown-freebsd11.0"
+
+
+; CHECK-LABEL: define i32 @myfls(
+; CHECK: ret i32 6
+; CHECK: }
+
+define i32 @myfls() {
+entry:
+  %call = call i32 @fls(i32 42)
+  ret i32 %call
+}
+
+; CHECK-LABEL: define i32 @myflsl(
+; CHECK: ret i32 6
+; CHECK: }
+
+define i32 @myflsl() {
+  %patatino = call i32 @flsl(i64 42)
+  ret i32 %patatino
+}
+
+; CHECK-LABEL: define i32 @myflsll(
+; CHECK: ret i32 6
+; CHECK: }
+
+define i32 @myflsll() {
+  %whatever = call i32 @flsll(i64 42)
+  ret i32 %whatever
+}
+
+; Lower to llvm.ctlz() if the argument is not a constant
+; CHECK-LABEL: define i32 @flsnotconst(
+; CHECK-NEXT:  %ctlz = call i64 @llvm.ctlz.i64(i64 %z, i1 false)
+; CHECK-NEXT:  %1 = sub nsw i64 64, %ctlz
+; CHECK-NEXT:  %2 = trunc i64 %1 to i32
+; CHECK-NEXT:  ret i32 %2
+
+define i32 @flsnotconst(i64 %z) {
+  %goo = call i32 @flsl(i64 %z)
+  ret i32 %goo
+}
+
+declare i32 @fls(i32)
+declare i32 @flsl(i64)
+declare i32 @flsll(i64)




More information about the llvm-commits mailing list