diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp index 741aaaee72f98..de321963dbe7a 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp @@ -954,13 +954,16 @@ Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc &fInfo) { std::string FuncName = fInfo.mangle(); Function *F = dyn_cast_or_null( M->getValueSymbolTable().lookup(FuncName)); + if (!F || F->isDeclaration()) + return nullptr; - // check formal with actual types conformance - if (F && !F->isDeclaration() && - fInfo.isCompatibleSignature(F->getFunctionType())) - return F; + if (F->hasFnAttribute(Attribute::NoBuiltin)) + return nullptr; - return nullptr; + if (!fInfo.isCompatibleSignature(F->getFunctionType())) + return nullptr; + + return F; } FunctionCallee AMDGPULibFunc::getOrInsertFunction(Module *M, @@ -969,10 +972,13 @@ FunctionCallee AMDGPULibFunc::getOrInsertFunction(Module *M, Function *F = dyn_cast_or_null( M->getValueSymbolTable().lookup(FuncName)); - // check formal with actual types conformance - if (F && !F->isDeclaration() && - fInfo.isCompatibleSignature(F->getFunctionType())) - return F; + if (F) { + if (F->hasFnAttribute(Attribute::NoBuiltin)) + return nullptr; + if (!F->isDeclaration() && + fInfo.isCompatibleSignature(F->getFunctionType())) + return F; + } FunctionType *FuncTy = fInfo.getFunctionType(*M); diff --git a/llvm/test/CodeGen/AMDGPU/simplify-libcall-nobuiltin-def.ll b/llvm/test/CodeGen/AMDGPU/simplify-libcall-nobuiltin-def.ll new file mode 100644 index 0000000000000..30dcc7a35dd61 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/simplify-libcall-nobuiltin-def.ll @@ -0,0 +1,65 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-usenative -amdgpu-use-native=all < %s | FileCheck %s + +; Verify nobuiltin is respected on a defined function. native_cos is +; marked nobuiltin, but native_sin is not. + +define float @_Z10native_sinf(float %x) { +; CHECK-LABEL: define float @_Z10native_sinf +; CHECK-SAME: (float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float asm " +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float asm "; $0 = native_sin($1)", "=v,v"(float %x) + ret float %result +} + +define float @_Z10native_cosf(float %x) nobuiltin { +; CHECK-LABEL: define float @_Z10native_cosf +; CHECK-SAME: (float [[X:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[RESULT:%.*]] = call float asm " +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float asm "; $0 = native_cos($1)", "=v,v"(float %x) + ret float %result +} + +define float @_Z3sinf(float %x) { +; CHECK-LABEL: define float @_Z3sinf +; CHECK-SAME: (float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float asm " +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float asm "; $0 = sin($1)", "=v,v"(float %x) + ret float %result +} + +define float @_Z3cosf(float %x) { +; CHECK-LABEL: define float @_Z3cosf +; CHECK-SAME: (float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float asm " +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float asm "; $0 = cos($1)", "=v,v"(float %x) + ret float %result +} + +define float @call_cos(float %x) { +; CHECK-LABEL: define float @call_cos +; CHECK-SAME: (float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float @_Z3cosf(float [[X]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float @_Z3cosf(float %x) + ret float %result +} + +define float @call_sin(float %x) { +; CHECK-LABEL: define float @call_sin +; CHECK-SAME: (float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float @_Z10native_sinf(float [[X]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float @_Z3sinf(float %x) + ret float %result +}