Index: include/llvm/Transforms/Utils/SimplifyLibCalls.h =================================================================== --- include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -126,6 +126,8 @@ Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B); Value *optimizeRealloc(CallInst *CI, IRBuilder<> &B); Value *optimizeWcslen(CallInst *CI, IRBuilder<> &B); + Value *optimizeBCmp(CallInst *CI, IRBuilder<> &B); + Value *optimizeBCopy(CallInst *CI, IRBuilder<> &B); // Wrapper for all String/Memory Library Call Optimizations Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B); Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -2204,6 +2204,18 @@ return nullptr; } +Value *LibCallSimplifier::optimizeBCmp(CallInst *CI, IRBuilder<> &B) { + // bcmp(s1, s2, n) -> memcmp(s1, s2, n) + return emitMemCmp(CI->getOperand(0), CI->getOperand(1), CI->getOperand(2), B, + DL, TLI); +} + +Value *LibCallSimplifier::optimizeBCopy(CallInst *CI, IRBuilder<> &B) { + // bcopy(src, dst, n) -> memmove(dst, src, n) + return B.CreateMemMove(CI->getArgOperand(1), 1, CI->getArgOperand(0), 1, + CI->getArgOperand(2)); +} + bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) { LibFunc Func; SmallString<20> FloatFuncName = FuncName; @@ -2274,6 +2286,10 @@ return optimizeRealloc(CI, Builder); case LibFunc_wcslen: return optimizeWcslen(CI, Builder); + case LibFunc_bcmp: + return optimizeBCmp(CI, Builder); + case LibFunc_bcopy: + return optimizeBCopy(CI, Builder); default: break; } Index: test/Transforms/InstCombine/bcmp-bcopy.ll =================================================================== --- test/Transforms/InstCombine/bcmp-bcopy.ll +++ test/Transforms/InstCombine/bcmp-bcopy.ll @@ -0,0 +1,26 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" + +declare i32 @bcmp(i8* nocapture, i8* nocapture, i32) +declare void @bcopy(i8* nocapture readonly, i8* nocapture, i32) + +define i32 @bcmp_memcmp(i8* nocapture readonly %a, i8* nocapture readonly %b, i32 %len) { +; CHECK-LABEL: @bcmp_memcmp( +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[A:%.*]], i8* [[B:%.*]], i32 [[LEN:%.*]]) +; CHECK-NEXT: ret i32 [[MEMCMP]] +; + %call = tail call i32 @bcmp(i8* %a, i8* %b, i32 %len) #4 + ret i32 %call +} + +define void @bcopy_memmove(i8* nocapture readonly %a, i8* nocapture %b, i32 %len) { +; CHECK-LABEL: @bcopy_memmove( +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* align 1 [[B:%.*]], i8* align 1 [[A:%.*]], i32 [[LEN:%.*]], i1 false) +; CHECK-NEXT: ret void +; + tail call void @bcopy(i8* %a, i8* %b, i32 %len) #5 + ret void +} +