Skip to content

Commit 9affa17

Browse files
authored
[NVPTX] Add support for calling aliases (#81170)
The current implementation of aliases tries to remove all the aliases in the module to prevent the generic version of `AsmPrinter` from emitting them incorrectly. Unfortunately, if the aliases are used this will fail. Instead let's override the function to print aliases directly. In addition, the declarations of the alias functions must occur before the uses. To fix this we emit alias declarations as part of `emitDeclarations` and only emit the `.alias` directives at the end (where we can assume the aliasee has also already been declared).
1 parent 8c106a1 commit 9affa17

File tree

5 files changed

+70
-45
lines changed

5 files changed

+70
-45
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ class AsmPrinter : public MachineFunctionPass {
897897
virtual void emitModuleCommandLines(Module &M);
898898

899899
GCMetadataPrinter *getOrCreateGCPrinter(GCStrategy &S);
900-
void emitGlobalAlias(Module &M, const GlobalAlias &GA);
900+
virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA);
901901
void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
902902

903903
private:

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2127,7 +2127,7 @@ void AsmPrinter::emitGlobalGOTEquivs() {
21272127
emitGlobalVariable(GV);
21282128
}
21292129

2130-
void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) {
2130+
void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {
21312131
MCSymbol *Name = getSymbol(&GA);
21322132
bool IsFunction = GA.getValueType()->isFunctionTy();
21332133
// Treat bitcasts of functions as functions also. This is important at least

llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "llvm/IR/DebugLoc.h"
5858
#include "llvm/IR/DerivedTypes.h"
5959
#include "llvm/IR/Function.h"
60+
#include "llvm/IR/GlobalAlias.h"
6061
#include "llvm/IR/GlobalValue.h"
6162
#include "llvm/IR/GlobalVariable.h"
6263
#include "llvm/IR/Instruction.h"
@@ -605,14 +606,33 @@ void NVPTXAsmPrinter::emitVirtualRegister(unsigned int vr,
605606
O << getVirtualRegisterName(vr);
606607
}
607608

609+
void NVPTXAsmPrinter::emitAliasDeclaration(const GlobalAlias *GA,
610+
raw_ostream &O) {
611+
const Function *F = dyn_cast_or_null<Function>(GA->getAliaseeObject());
612+
if (!F || isKernelFunction(*F) || F->isDeclaration())
613+
report_fatal_error(
614+
"NVPTX aliasee must be a non-kernel function definition");
615+
616+
if (GA->hasLinkOnceLinkage() || GA->hasWeakLinkage() ||
617+
GA->hasAvailableExternallyLinkage() || GA->hasCommonLinkage())
618+
report_fatal_error("NVPTX aliasee must not be '.weak'");
619+
620+
emitDeclarationWithName(F, getSymbol(GA), O);
621+
}
622+
608623
void NVPTXAsmPrinter::emitDeclaration(const Function *F, raw_ostream &O) {
624+
emitDeclarationWithName(F, getSymbol(F), O);
625+
}
626+
627+
void NVPTXAsmPrinter::emitDeclarationWithName(const Function *F, MCSymbol *S,
628+
raw_ostream &O) {
609629
emitLinkageDirective(F, O);
610630
if (isKernelFunction(*F))
611631
O << ".entry ";
612632
else
613633
O << ".func ";
614634
printReturnValStr(F, O);
615-
getSymbol(F)->print(O, MAI);
635+
S->print(O, MAI);
616636
O << "\n";
617637
emitFunctionParamList(F, O);
618638
O << "\n";
@@ -759,6 +779,8 @@ void NVPTXAsmPrinter::emitDeclarations(const Module &M, raw_ostream &O) {
759779
}
760780
seenMap[&F] = true;
761781
}
782+
for (const GlobalAlias &GA : M.aliases())
783+
emitAliasDeclaration(&GA, O);
762784
}
763785

764786
static bool isEmptyXXStructor(GlobalVariable *GV) {
@@ -853,25 +875,9 @@ void NVPTXAsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {
853875
raw_svector_ostream OS(Str);
854876

855877
MCSymbol *Name = getSymbol(&GA);
856-
const Function *F = dyn_cast<Function>(GA.getAliasee());
857-
if (!F || isKernelFunction(*F))
858-
report_fatal_error("NVPTX aliasee must be a non-kernel function");
859-
860-
if (GA.hasLinkOnceLinkage() || GA.hasWeakLinkage() ||
861-
GA.hasAvailableExternallyLinkage() || GA.hasCommonLinkage())
862-
report_fatal_error("NVPTX aliasee must not be '.weak'");
863-
864-
OS << "\n";
865-
emitLinkageDirective(F, OS);
866-
OS << ".func ";
867-
printReturnValStr(F, OS);
868-
OS << Name->getName();
869-
emitFunctionParamList(F, OS);
870-
if (shouldEmitPTXNoReturn(F, TM))
871-
OS << "\n.noreturn";
872-
OS << ";\n";
873878

874-
OS << ".alias " << Name->getName() << ", " << F->getName() << ";\n";
879+
OS << ".alias " << Name->getName() << ", " << GA.getAliaseeObject()->getName()
880+
<< ";\n";
875881

876882
OutStreamer->emitRawText(OS.str());
877883
}
@@ -932,16 +938,6 @@ bool NVPTXAsmPrinter::doFinalization(Module &M) {
932938
GlobalsEmitted = true;
933939
}
934940

935-
// If we have any aliases we emit them at the end.
936-
SmallVector<GlobalAlias *> AliasesToRemove;
937-
for (GlobalAlias &Alias : M.aliases()) {
938-
emitGlobalAlias(M, Alias);
939-
AliasesToRemove.push_back(&Alias);
940-
}
941-
942-
for (GlobalAlias *A : AliasesToRemove)
943-
A->eraseFromParent();
944-
945941
// call doFinalization
946942
bool ret = AsmPrinter::doFinalization(M);
947943

llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/IR/DebugLoc.h"
2828
#include "llvm/IR/DerivedTypes.h"
2929
#include "llvm/IR/Function.h"
30+
#include "llvm/IR/GlobalAlias.h"
3031
#include "llvm/IR/GlobalValue.h"
3132
#include "llvm/IR/Value.h"
3233
#include "llvm/MC/MCExpr.h"
@@ -174,7 +175,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter {
174175
void printModuleLevelGV(const GlobalVariable *GVar, raw_ostream &O,
175176
bool processDemoted, const NVPTXSubtarget &STI);
176177
void emitGlobals(const Module &M);
177-
void emitGlobalAlias(const Module &M, const GlobalAlias &GA);
178+
void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override;
178179
void emitHeader(Module &M, raw_ostream &O, const NVPTXSubtarget &STI);
179180
void emitKernelFunctionDirectives(const Function &F, raw_ostream &O) const;
180181
void emitVirtualRegister(unsigned int vr, raw_ostream &);
@@ -222,6 +223,8 @@ class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter {
222223
void emitLinkageDirective(const GlobalValue *V, raw_ostream &O);
223224
void emitDeclarations(const Module &, raw_ostream &O);
224225
void emitDeclaration(const Function *, raw_ostream &O);
226+
void emitAliasDeclaration(const GlobalAlias *, raw_ostream &O);
227+
void emitDeclarationWithName(const Function *, MCSymbol *, raw_ostream &O);
225228
void emitDemotedVars(const Function *, raw_ostream &);
226229

227230
bool lowerImageHandleOperand(const MachineInstr *MI, unsigned OpNo,

llvm/test/CodeGen/NVPTX/alias.ll

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
; RUN: llc < %s -march=nvptx64 -mcpu=sm_30 -mattr=+ptx64 | FileCheck %s
2+
; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mcpu=sm_30 -mattr=+ptx64 | %ptxas-verify %}
23

34
define i32 @a() { ret i32 0 }
45
@b = internal alias i32 (), ptr @a
56
@c = internal alias i32 (), ptr @a
7+
@d = internal alias i32 (), ptr @c
68

79
define void @foo(i32 %0, ptr %1) { ret void }
810
@bar = alias i32 (), ptr @foo
@@ -12,8 +14,37 @@ define void @noreturn() #0 {
1214
}
1315
@noreturn_alias = alias i32 (), ptr @noreturn
1416

17+
define i32 @z() {
18+
%val = call i32 @b()
19+
ret i32 %val
20+
}
21+
22+
1523
attributes #0 = { noreturn }
1624

25+
; CHECK: .visible .func (.param .b32 func_retval0) b
26+
; CHECK-NEXT: ()
27+
; CHECK-NEXT: ;
28+
29+
; CHECK: .visible .func (.param .b32 func_retval0) c
30+
; CHECK-NEXT: ()
31+
; CHECK-NEXT: ;
32+
33+
; CHECK: .visible .func (.param .b32 func_retval0) d
34+
; CHECK-NEXT: ()
35+
; CHECK-NEXT: ;
36+
37+
; CHECK: .visible .func bar
38+
; CHECK-NEXT: (
39+
; CHECK-NEXT: .param .b32 foo_param_0,
40+
; CHECK-NEXT: .param .b64 foo_param_1
41+
; CHECK-NEXT: )
42+
; CHECK-NEXT: ;
43+
44+
; CHECK: .visible .func noreturn_alias
45+
; CHECK-NEXT: ()
46+
; CHECK-NEXT: .noreturn;
47+
1748
; CHECK: .visible .func (.param .b32 func_retval0) a()
1849

1950
; CHECK: .visible .func foo(
@@ -24,18 +55,13 @@ attributes #0 = { noreturn }
2455
; CHECK: .visible .func noreturn()
2556
; CHECK-NEXT: .noreturn
2657

27-
; CHECK: .visible .func (.param .b32 func_retval0) b();
28-
; CHECK-NEXT: .alias b, a;
58+
; CHECK: .visible .func (.param .b32 func_retval0) z()
59+
; CHECK: call.uni (retval0),
60+
; CHECK-NEXT: b,
2961

30-
; CHECK: .visible .func (.param .b32 func_retval0) c();
31-
; CHECK-NEXT: .alias c, a;
3262

33-
; CHECK: .visible .func bar(
34-
; CHECK-NEXT: .param .b32 foo_param_0,
35-
; CHECK-NEXT: .param .b64 foo_param_1
36-
; CHECK-NEXT: );
37-
; CHECK-NEXT: .alias bar, foo;
38-
39-
; CHECK: .visible .func noreturn_alias()
40-
; CHECK-NEXT: .noreturn;
41-
; CHECK-NEXT: .alias noreturn_alias, noreturn;
63+
; CHECK: .alias b, a;
64+
; CHECK: .alias c, a;
65+
; CHECK: .alias d, a;
66+
; CHECK: .alias bar, foo;
67+
; CHECK: .alias noreturn_alias, noreturn;

0 commit comments

Comments
 (0)