Index: include/llvm/Transforms/Utils/SimplifyLibCalls.h =================================================================== --- include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -138,6 +138,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/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1572,6 +1572,22 @@ return B.CreateSelect(Cond, V, B.getInt32(0)); } +Value *LibCallSimplifier::optimizeFls(CallInst *CI, IRBuilder<> &B) { + Function *Callee = CI->getCalledFunction(); + if (!checkIntUnaryReturnAndParam(Callee)) + return nullptr; + Value *Op = CI->getArgOperand(0); + + // Constant fold. + if (ConstantInt *CI = dyn_cast(Op)) { + if (CI->isZero()) // fls(0) -> 0. + return B.getInt32(0); + // fls(c) -> 32 - ctlz(c) + return B.getInt32(32 - CI->getValue().countLeadingZeros()); + } + return nullptr; +} + Value *LibCallSimplifier::optimizeAbs(CallInst *CI, IRBuilder<> &B) { Function *Callee = CI->getCalledFunction(); FunctionType *FT = Callee->getFunctionType(); @@ -2157,6 +2173,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 =================================================================== --- test/Transforms/InstCombine/fls.ll +++ test/Transforms/InstCombine/fls.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target triple = "x86_64-unknown-freebsd11.0" + +define i32 @myfls() { +entry: + %call = call i32 @fls(i32 42) #2 + ret i32 %call +} + +declare i32 @fls(i32) + +; CHECK-LABEL: define i32 @myfls( +; CHECK: ret i32 6 +; CHECK: }