Skip to content

Commit e25f199

Browse files
v-klochkovmlychkov
andauthored
[ESIMD] Fix compilation from static libraries (#5826)
* [ESIMD] Fix compilation from static libraries. sycl-post-link previously removed "llvm.used" global, but that was not enough as the initializer of "llvm.used" was not deleted and some elements of initializer used kernels. As a result the GenXSPIRVWriterAdaptor did not transform the kernel arguments properly thinking that the kernel was called from inside the module, which was not true. Removing the initializer fixed the issue. Signed-off-by: Vyacheslav N Klochkov <[email protected]> Co-authored-by: Mikhail Lychkov <[email protected]>
1 parent 9aefea0 commit e25f199

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

llvm/tools/sycl-post-link/sycl-post-link.cpp

+37-5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "llvm/Transforms/InstCombine/InstCombine.h"
4848
#include "llvm/Transforms/Scalar.h"
4949
#include "llvm/Transforms/Utils/Cloning.h"
50+
#include "llvm/Transforms/Utils/GlobalStatus.h"
5051

5152
#include <algorithm>
5253
#include <map>
@@ -833,6 +834,40 @@ class ModuleSplitter {
833834
size_t totalSplits() { return GMap.size(); }
834835
};
835836

837+
// Removes the global variable "llvm.used" and returns true on success.
838+
// "llvm.used" is a global constant array containing references to kernels
839+
// available in the module and callable from host code. The elements of
840+
// the array are ConstantExpr bitcast to i8*.
841+
// The variable must be removed as it is a) has done the job to the moment
842+
// of this function call and b) the references to the kernels callable from
843+
// host must not have users.
844+
static bool removeSYCLKernelsConstRefArray(GlobalVariable *GV) {
845+
assert(GV->getGlobalIdentifier() == "llvm.used" &&
846+
"Unexpected global value is passed for removal, should be llvm.used");
847+
assert(GV->user_empty() && "Unexpected llvm.used users");
848+
Constant *Initializer = GV->getInitializer();
849+
GV->setInitializer(nullptr);
850+
GV->eraseFromParent();
851+
852+
// Destroy the initializer and all operands of it.
853+
SmallVector<Constant *, 8> IOperands;
854+
for (auto It = Initializer->op_begin(); It != Initializer->op_end(); It++)
855+
IOperands.push_back(cast<Constant>(*It));
856+
assert(llvm::isSafeToDestroyConstant(Initializer) &&
857+
"Cannot remove initializer of llvm.used global");
858+
Initializer->destroyConstant();
859+
for (auto It = IOperands.begin(); It != IOperands.end(); It++) {
860+
assert(llvm::isSafeToDestroyConstant(*It) &&
861+
"Cannot remove an element of initializer of llvm.used global");
862+
auto F = cast<Function>((*It)->getOperand(0));
863+
(*It)->destroyConstant();
864+
// Remove unused kernel declarations to avoid LLVM IR check fails.
865+
if (F->isDeclaration())
866+
F->eraseFromParent();
867+
}
868+
return true;
869+
}
870+
836871
using TableFiles = std::map<StringRef, string_vector>;
837872

838873
TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
@@ -849,11 +884,8 @@ TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
849884
// issue remove "llvm.used" from the input module before performing any other
850885
// actions.
851886
bool IsLLVMUsedRemoved = false;
852-
if (GlobalVariable *GV = M->getGlobalVariable("llvm.used")) {
853-
assert(GV->user_empty() && "unexpected llvm.used users");
854-
GV->eraseFromParent();
855-
IsLLVMUsedRemoved = true;
856-
}
887+
if (GlobalVariable *GV = M->getGlobalVariable("llvm.used"))
888+
IsLLVMUsedRemoved = removeSYCLKernelsConstRefArray(GV);
857889

858890
if (IsEsimd && LowerEsimd)
859891
lowerEsimdConstructs(*M);

0 commit comments

Comments
 (0)