Index: include/llvm/Transforms/Utils/SimplifyLibCalls.h =================================================================== --- include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -137,6 +137,7 @@ // 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); Index: lib/Analysis/TargetLibraryInfo.cpp =================================================================== --- lib/Analysis/TargetLibraryInfo.cpp +++ lib/Analysis/TargetLibraryInfo.cpp @@ -986,6 +986,9 @@ 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 @@ 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: Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1545,6 +1545,21 @@ return B.CreateSelect(Cond, V, B.getInt32(0)); } +Value *LibCallSimplifier::optimizeFls(CallInst *CI, IRBuilder<> &B) { + Value *Op = CI->getArgOperand(0); + + // Constant fold. + if (ConstantInt *CI = dyn_cast(Op)) { + if (CI->isZero()) // fls(0) -> 0. + return B.getInt32(0); + + // fls(ty c) -> sizeInBits(ty) - ctlz(c) + return B.getInt32(CI->getType()->getBitWidth() - + CI->getValue().countLeadingZeros()); + } + return nullptr; +} + Value *LibCallSimplifier::optimizeAbs(CallInst *CI, IRBuilder<> &B) { // abs(x) -> x >s -1 ? x : -x Value *Op = CI->getArgOperand(0); @@ -2081,6 +2096,10 @@ 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: Index: test/Transforms/InstCombine/fls.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/fls.ll @@ -0,0 +1,36 @@ +; 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 +} + +declare i32 @fls(i32) +declare i32 @flsl(i64) +declare i32 @flsll(i64)