|
32 | 32 | #include "llvm/Support/Error.h"
|
33 | 33 | #include "llvm/Support/FileSystem.h"
|
34 | 34 | #include "llvm/Support/LineIterator.h"
|
| 35 | +#include "llvm/Support/WithColor.h" |
35 | 36 | #include "llvm/Transforms/IPO.h"
|
36 | 37 | #include "llvm/Transforms/IPO/GlobalDCE.h"
|
37 | 38 | #include "llvm/Transforms/IPO/Internalize.h"
|
@@ -298,6 +299,23 @@ void collectFunctionsAndGlobalVariablesToExtract(
|
298 | 299 | }
|
299 | 300 | }
|
300 | 301 |
|
| 302 | +static bool isIntrinsicOrBuiltin(const Function &F) { |
| 303 | + return F.isIntrinsic() || F.getName().starts_with("__") || |
| 304 | + isSpirvSyclBuiltin(F.getName()) || isESIMDBuiltin(F.getName()); |
| 305 | +} |
| 306 | + |
| 307 | +// Checks for use of undefined user functions and emits a warning message. |
| 308 | +static void checkForCallsToUndefinedFunctions(const Module &M) { |
| 309 | + if (AllowDeviceImageDependencies) |
| 310 | + return; |
| 311 | + for (const Function &F : M) { |
| 312 | + if (!isIntrinsicOrBuiltin(F) && F.isDeclaration() && !F.use_empty()) |
| 313 | + WithColor::warning() << "Undefined function " << F.getName() |
| 314 | + << " found in " << M.getName() |
| 315 | + << ". This may result in runtime errors.\n"; |
| 316 | + } |
| 317 | +} |
| 318 | + |
301 | 319 | // Check "spirv.ExecutionMode" named metadata in the module and remove nodes
|
302 | 320 | // that reference kernels that have dead prototypes or don't reference any
|
303 | 321 | // kernel at all (nullptr). Dead prototypes are removed as well.
|
@@ -382,6 +400,7 @@ ModuleDesc extractCallGraph(const ModuleDesc &MD,
|
382 | 400 | // GenXSPIRVWriterAdaptor pass that relies on this cleanup. This cleanup call
|
383 | 401 | // can be removed once that pass no longer depends on this cleanup.
|
384 | 402 | SplitM.cleanup();
|
| 403 | + checkForCallsToUndefinedFunctions(SplitM.getModule()); |
385 | 404 |
|
386 | 405 | return SplitM;
|
387 | 406 | }
|
@@ -1452,8 +1471,7 @@ bool canBeImportedFunction(const Function &F) {
|
1452 | 1471 | // in a header file. Thus SYCL IR that is a declaration
|
1453 | 1472 | // will be considered as SYCL_EXTERNAL for the purposes of
|
1454 | 1473 | // this function.
|
1455 |
| - if (F.isIntrinsic() || F.getName().starts_with("__") || |
1456 |
| - isSpirvSyclBuiltin(F.getName()) || isESIMDBuiltin(F.getName()) || |
| 1474 | + if (isIntrinsicOrBuiltin(F) || |
1457 | 1475 | (!F.isDeclaration() && !llvm::sycl::utils::isSYCLExternalFunction(&F)))
|
1458 | 1476 | return false;
|
1459 | 1477 |
|
|
0 commit comments