Skip to content

Commit 74fa7ba

Browse files
committed
Don't remove llvm.compiler.used at sycl post link
This is removed at lowering for NVPTX/AMDGCN. TODO: check that this is working for SPIR-V.
1 parent 72a6032 commit 74fa7ba

File tree

3 files changed

+36
-74
lines changed

3 files changed

+36
-74
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
;; This test verifies llc on AMDGCN will delete the llvm.compiler.used symbol
2+
;; while keeping the symbol in the outputted ASM.
3+
4+
; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 | FileCheck %s
5+
; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 | FileCheck %s
6+
; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a | FileCheck %s
7+
8+
@keep_this = internal global i32 2, align 4
9+
@llvm.compiler.used = appending global [1 x ptr] [ptr @keep_this], section "llvm.metadata"
10+
11+
; CHECK-NOT: llvm.metadata
12+
; CHECK-NOT: llvm{{.*}}used
13+
; CHECK-NOT: llvm{{.*}}compiler{{.*}}used
14+
15+
; CHECK: .type keep_this,@object ;
16+
17+
; CHECK-NOT: llvm.metadata
18+
; CHECK-NOT: llvm{{.*}}used
19+
; CHECK-NOT: llvm{{.*}}compiler{{.*}}used
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
;; This test verifies llc on NVPTX will delete the llvm.compiler.used symbol
2+
;; while keeping the symbol in the outputted ASM.
3+
4+
; RUN: llc < %s -march=nvptx64 | FileCheck %s
5+
6+
@keep_this = internal global i32 2, align 4
7+
@llvm.compiler.used = appending global [1 x ptr] [ptr @keep_this], section "llvm.metadata"
8+
9+
; CHECK-NOT: llvm.metadata
10+
; CHECK-NOT: llvm{{.*}}used
11+
; CHECK-NOT: llvm{{.*}}compiler{{.*}}used
12+
13+
; CHECK: .global .align 4 .u32 keep_this
14+
15+
; CHECK-NOT: llvm.metadata
16+
; CHECK-NOT: llvm{{.*}}used
17+
; CHECK-NOT: llvm{{.*}}compiler{{.*}}used

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

-74
Original file line numberDiff line numberDiff line change
@@ -572,70 +572,6 @@ static bool removeSYCLKernelsConstRefArray(Module &M) {
572572
return true;
573573
}
574574

575-
// Removes all device_global variables from the llvm.compiler.used global
576-
// variable. A device_global with internal linkage will be in llvm.compiler.used
577-
// to avoid the compiler wrongfully removing it during optimizations. However,
578-
// as an effect the device_global variables will also be distributed across
579-
// binaries, even if llvm.compiler.used has served its purpose. To avoid
580-
// polluting other binaries with unused device_global variables, we remove them
581-
// from llvm.compiler.used and erase them if they have no further uses.
582-
static bool removeDeviceGlobalFromCompilerUsed(Module &M) {
583-
GlobalVariable *GV = M.getGlobalVariable("llvm.compiler.used");
584-
if (!GV)
585-
return false;
586-
587-
// Erase the old llvm.compiler.used. A new one will be created at the end if
588-
// there are other values in it (other than device_global).
589-
assert(GV->user_empty() && "Unexpected llvm.compiler.used users");
590-
Constant *Initializer = GV->getInitializer();
591-
const auto *VAT = cast<ArrayType>(GV->getValueType());
592-
GV->setInitializer(nullptr);
593-
GV->eraseFromParent();
594-
595-
// Destroy the initializer. Keep the operands so we keep the ones we need.
596-
SmallVector<Constant *, 8> IOperands;
597-
for (auto It = Initializer->op_begin(); It != Initializer->op_end(); It++)
598-
IOperands.push_back(cast<Constant>(*It));
599-
assert(llvm::isSafeToDestroyConstant(Initializer) &&
600-
"Cannot remove initializer of llvm.compiler.used global");
601-
Initializer->destroyConstant();
602-
603-
// Iterate through all operands. If they are device_global then we drop them
604-
// and erase them if they have no uses afterwards. All other values are kept.
605-
SmallVector<Constant *, 8> NewOperands;
606-
for (auto It = IOperands.begin(); It != IOperands.end(); It++) {
607-
Constant *Op = *It;
608-
auto *DG = dyn_cast<GlobalVariable>(Op->stripPointerCasts());
609-
610-
// If it is not a device_global we keep it.
611-
if (!DG || !isDeviceGlobalVariable(*DG)) {
612-
NewOperands.push_back(Op);
613-
continue;
614-
}
615-
616-
// Destroy the device_global operand.
617-
if (llvm::isSafeToDestroyConstant(Op))
618-
Op->destroyConstant();
619-
620-
// Remove device_global if it no longer has any uses.
621-
if (!DG->isConstantUsed())
622-
DG->eraseFromParent();
623-
}
624-
625-
// If we have any operands left from the original llvm.compiler.used we create
626-
// a new one with the new size.
627-
if (!NewOperands.empty()) {
628-
ArrayType *ATy = ArrayType::get(VAT->getElementType(), NewOperands.size());
629-
GlobalVariable *NGV =
630-
new GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage,
631-
ConstantArray::get(ATy, NewOperands), "");
632-
NGV->setName("llvm.compiler.used");
633-
NGV->setSection("llvm.metadata");
634-
}
635-
636-
return true;
637-
}
638-
639575
SmallVector<module_split::ModuleDesc, 2>
640576
handleESIMD(module_split::ModuleDesc &&MDesc, bool &Modified,
641577
bool &SplitOccurred) {
@@ -783,16 +719,6 @@ processInputModule(std::unique_ptr<Module> M) {
783719
// actions.
784720
Modified |= removeSYCLKernelsConstRefArray(*M.get());
785721

786-
// There may be device_global variables kept alive in "llvm.compiler.used"
787-
// to keep the optimizer from wrongfully removing them. Since it has served
788-
// its purpose, these device_global variables can be removed. If they are not
789-
// used inside the device code after they have been removed from
790-
// "llvm.compiler.used" they can be erased safely.
791-
if (auto Triple = M->getTargetTriple();
792-
Triple.find("nvptx") != std::string::npos &&
793-
Triple.find("amdgcn") != std::string::npos)
794-
Modified |= removeDeviceGlobalFromCompilerUsed(*M.get());
795-
796722
// Instrument each image scope device globals if the module has been
797723
// instrumented by sanitizer pass.
798724
if (isModuleUsingAsan(*M))

0 commit comments

Comments
 (0)