Index: llvm/lib/Transforms/Utils/BuildLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -1216,6 +1216,13 @@ return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr"); } +static void setCallingConvAndAttrs(CallInst *&CI, const Value *V) { + if (const Function *F = dyn_cast(V)) { + CI->setCallingConv(F->getCallingConv()); + CI->setAttributes(F->getAttributes()); + } +} + static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType, ArrayRef ParamTypes, ArrayRef Operands, IRBuilderBase &B, @@ -1230,9 +1237,7 @@ FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType); inferLibFuncAttributes(M, FuncName, *TLI); CallInst *CI = B.CreateCall(Callee, Operands, FuncName); - if (const Function *F = - dyn_cast(Callee.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); + setCallingConvAndAttrs(CI, Callee.getCallee()->stripPointerCasts()); return CI; } @@ -1312,9 +1317,7 @@ Dst = castToCStr(Dst, B); Src = castToCStr(Src, B); CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize}); - if (const Function *F = - dyn_cast(MemCpy.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); + setCallingConvAndAttrs(CI, MemCpy.getCallee()->stripPointerCasts()); return CI; } @@ -1456,10 +1459,7 @@ CI->setAttributes(Attrs.removeAttribute(B.getContext(), AttributeList::FunctionIndex, Attribute::Speculatable)); - if (const Function *F = - dyn_cast(Callee.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - + setCallingConvAndAttrs(CI, Callee.getCallee()->stripPointerCasts()); return CI; } @@ -1501,10 +1501,7 @@ CI->setAttributes(Attrs.removeAttribute(B.getContext(), AttributeList::FunctionIndex, Attribute::Speculatable)); - if (const Function *F = - dyn_cast(Callee.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - + setCallingConvAndAttrs(CI, Callee.getCallee()->stripPointerCasts()); return CI; } @@ -1548,9 +1545,7 @@ "chari"), PutCharName); - if (const Function *F = - dyn_cast(PutChar.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); + setCallingConvAndAttrs(CI, PutChar.getCallee()->stripPointerCasts()); return CI; } @@ -1565,9 +1560,7 @@ M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy()); inferLibFuncAttributes(M, PutsName, *TLI); CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName); - if (const Function *F = - dyn_cast(PutS.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); + setCallingConvAndAttrs(CI, PutS.getCallee()->stripPointerCasts()); return CI; } @@ -1585,10 +1578,7 @@ Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, "chari"); CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); + setCallingConvAndAttrs(CI, F.getCallee()->stripPointerCasts()); return CI; } @@ -1604,10 +1594,7 @@ if (File->getType()->isPointerTy()) inferLibFuncAttributes(M, FPutsName, *TLI); CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); + setCallingConvAndAttrs(CI, F.getCallee()->stripPointerCasts()); return CI; } @@ -1628,10 +1615,7 @@ CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, ConstantInt::get(DL.getIntPtrType(Context), 1), File}); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); + setCallingConvAndAttrs(CI, F.getCallee()->stripPointerCasts()); return CI; } @@ -1647,11 +1631,7 @@ DL.getIntPtrType(Context)); inferLibFuncAttributes(M, MallocName, *TLI); CallInst *CI = B.CreateCall(Malloc, Num, MallocName); - - if (const Function *F = - dyn_cast(Malloc.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - + setCallingConvAndAttrs(CI, Malloc.getCallee()->stripPointerCasts()); return CI; } @@ -1668,10 +1648,6 @@ CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType); inferLibFuncAttributes(M, CallocName, TLI); CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName); - - if (const auto *F = - dyn_cast(Calloc.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - + setCallingConvAndAttrs(CI, Calloc.getCallee()->stripPointerCasts()); return CI; } Index: llvm/test/Transforms/InstCombine/libcall-param-attrs.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstCombine/libcall-param-attrs.ll @@ -0,0 +1,30 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +; REQUIRES: systemz-registered-target +; +; Check that instcombiner creates libcalls with parameter extensions per the +; prototype. + +declare dso_local i8* @strchr(i8*, i32) local_unnamed_addr #1 +declare dso_local i8* @memchr(i8*, i32 signext, i64) +declare void @llvm.assume(i1 noundef) +@0 = private unnamed_addr constant [21 x i8] c"000000000000000000000", align 2 +define void @fun0(i32 %arg1) { +; CHECK: define void @fun0 +; CHECK: call i8* @memchr{{.*}}, i32 signext %arg1, i64 22) +bb: + %i = call i8* @strchr(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @0, i64 0, i64 0), i32 signext %arg1) + %i3 = icmp ne i8* %i, null + call void @llvm.assume(i1 %i3) + ret void +} + +declare dso_local double @pow(double, double) +define void @fun1(i32* %i5) { +; CHECK: define void @fun1 +; CHECK: call double @ldexp{{.*}}, i32 signext %i19) +bb: + %i19 = load i32, i32* %i5, align 4 + %i20 = sitofp i32 %i19 to double + %i21 = call double @pow(double 2.000000e+00, double %i20) + ret void +}