-
Notifications
You must be signed in to change notification settings - Fork 14.3k
release/20.x: [AsmPrinter] Always emit global equivalents if there is non-global uses (#145648) #145690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/20.x
Are you sure you want to change the base?
Conversation
…es (llvm#145648) A case found from rust-lang/rust#142752: https://llvm.godbolt.org/z/T7ce9saWh. We should emit `@bar_0` for the following code: ```llvm target triple = "x86_64-unknown-linux-gnu" @rel_0 = private unnamed_addr constant [1 x i32] [ i32 trunc (i64 sub (i64 ptrtoint (ptr @bar_0 to i64), i64 ptrtoint (ptr @rel_0 to i64)) to i32)] @bar_0 = internal unnamed_addr constant ptr @foo_0, align 8 @foo_0 = external global ptr, align 8 define void @foo(ptr %arg0) { store ptr @bar_0, ptr %arg0, align 8 ret void } ``` (cherry picked from commit 630d55c)
@nikic What do you think about merging this PR to the release branch? |
@llvm/pr-subscribers-mc Author: None (llvmbot) ChangesBackport 630d55c Requested by: @dianqk Full diff: https://github.com/llvm/llvm-project/pull/145690.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index e77abf429e6b4..c8f567e5f4195 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2139,16 +2139,20 @@ void AsmPrinter::emitFunctionBody() {
}
/// Compute the number of Global Variables that uses a Constant.
-static unsigned getNumGlobalVariableUses(const Constant *C) {
- if (!C)
+static unsigned getNumGlobalVariableUses(const Constant *C,
+ bool &HasNonGlobalUsers) {
+ if (!C) {
+ HasNonGlobalUsers = true;
return 0;
+ }
if (isa<GlobalVariable>(C))
return 1;
unsigned NumUses = 0;
for (const auto *CU : C->users())
- NumUses += getNumGlobalVariableUses(dyn_cast<Constant>(CU));
+ NumUses +=
+ getNumGlobalVariableUses(dyn_cast<Constant>(CU), HasNonGlobalUsers);
return NumUses;
}
@@ -2159,7 +2163,8 @@ static unsigned getNumGlobalVariableUses(const Constant *C) {
/// candidates are skipped and are emitted later in case at least one cstexpr
/// isn't replaced by a PC relative GOT entry access.
static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
- unsigned &NumGOTEquivUsers) {
+ unsigned &NumGOTEquivUsers,
+ bool &HasNonGlobalUsers) {
// Global GOT equivalents are unnamed private globals with a constant
// pointer initializer to another global symbol. They must point to a
// GlobalVariable or Function, i.e., as GlobalValue.
@@ -2171,7 +2176,8 @@ static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
// To be a got equivalent, at least one of its users need to be a constant
// expression used by another global variable.
for (const auto *U : GV->users())
- NumGOTEquivUsers += getNumGlobalVariableUses(dyn_cast<Constant>(U));
+ NumGOTEquivUsers +=
+ getNumGlobalVariableUses(dyn_cast<Constant>(U), HasNonGlobalUsers);
return NumGOTEquivUsers > 0;
}
@@ -2189,9 +2195,13 @@ void AsmPrinter::computeGlobalGOTEquivs(Module &M) {
for (const auto &G : M.globals()) {
unsigned NumGOTEquivUsers = 0;
- if (!isGOTEquivalentCandidate(&G, NumGOTEquivUsers))
+ bool HasNonGlobalUsers = false;
+ if (!isGOTEquivalentCandidate(&G, NumGOTEquivUsers, HasNonGlobalUsers))
continue;
-
+ // If non-global variables use it, we still need to emit it.
+ // Add 1 here, then emit it in `emitGlobalGOTEquivs`.
+ if (HasNonGlobalUsers)
+ NumGOTEquivUsers += 1;
const MCSymbol *GOTEquivSym = getSymbol(&G);
GlobalGOTEquivs[GOTEquivSym] = std::make_pair(&G, NumGOTEquivUsers);
}
diff --git a/llvm/test/MC/X86/gotpcrel-non-globals.ll b/llvm/test/MC/X86/gotpcrel-non-globals.ll
new file mode 100644
index 0000000000000..222d2d73ff728
--- /dev/null
+++ b/llvm/test/MC/X86/gotpcrel-non-globals.ll
@@ -0,0 +1,36 @@
+; RUN: llc < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+; Check that we emit the `@bar_*` symbols, and that we don't emit multiple symbols.
+
+; CHECK-LABEL: .Lrel_0:
+; CHECK: .long foo_0@GOTPCREL+0
+; CHECK-LABEL: .Lrel_1_failed:
+; CHECK: .long bar_1-foo_0
+; CHECK-LABEL: .Lrel_2:
+; CHECK: .long foo_2@GOTPCREL+0
+
+; CHECK: bar_0:
+; CHECK: bar_1:
+; CHECK: bar_2_indirect:
+
+@rel_0 = private unnamed_addr constant [1 x i32] [
+ i32 trunc (i64 sub (i64 ptrtoint (ptr @bar_0 to i64), i64 ptrtoint (ptr @rel_0 to i64)) to i32)]
+@rel_1_failed = private unnamed_addr constant [1 x i32] [
+ i32 trunc (i64 sub (i64 ptrtoint (ptr @bar_1 to i64), i64 ptrtoint (ptr @foo_0 to i64)) to i32)]
+@rel_2 = private unnamed_addr constant [1 x i32] [
+ i32 trunc (i64 sub (i64 ptrtoint (ptr @bar_2_indirect to i64), i64 ptrtoint (ptr @rel_2 to i64)) to i32)]
+@bar_0 = internal unnamed_addr constant ptr @foo_0, align 8
+@bar_1 = internal unnamed_addr constant ptr @foo_1, align 8
+@bar_2_indirect = internal unnamed_addr constant ptr @foo_2, align 8
+@foo_0 = external global ptr, align 8
+@foo_1 = external global ptr, align 8
+@foo_2 = external global ptr, align 8
+
+define void @foo(ptr %arg0, ptr %arg1) {
+ store ptr @bar_0, ptr %arg0, align 8
+ store ptr @bar_1, ptr %arg1, align 8
+ store ptr getelementptr (i8, ptr @bar_2_indirect, i32 1), ptr %arg1, align 8
+ ret void
+}
|
@llvm/pr-subscribers-backend-x86 Author: None (llvmbot) ChangesBackport 630d55c Requested by: @dianqk Full diff: https://github.com/llvm/llvm-project/pull/145690.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index e77abf429e6b4..c8f567e5f4195 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2139,16 +2139,20 @@ void AsmPrinter::emitFunctionBody() {
}
/// Compute the number of Global Variables that uses a Constant.
-static unsigned getNumGlobalVariableUses(const Constant *C) {
- if (!C)
+static unsigned getNumGlobalVariableUses(const Constant *C,
+ bool &HasNonGlobalUsers) {
+ if (!C) {
+ HasNonGlobalUsers = true;
return 0;
+ }
if (isa<GlobalVariable>(C))
return 1;
unsigned NumUses = 0;
for (const auto *CU : C->users())
- NumUses += getNumGlobalVariableUses(dyn_cast<Constant>(CU));
+ NumUses +=
+ getNumGlobalVariableUses(dyn_cast<Constant>(CU), HasNonGlobalUsers);
return NumUses;
}
@@ -2159,7 +2163,8 @@ static unsigned getNumGlobalVariableUses(const Constant *C) {
/// candidates are skipped and are emitted later in case at least one cstexpr
/// isn't replaced by a PC relative GOT entry access.
static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
- unsigned &NumGOTEquivUsers) {
+ unsigned &NumGOTEquivUsers,
+ bool &HasNonGlobalUsers) {
// Global GOT equivalents are unnamed private globals with a constant
// pointer initializer to another global symbol. They must point to a
// GlobalVariable or Function, i.e., as GlobalValue.
@@ -2171,7 +2176,8 @@ static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
// To be a got equivalent, at least one of its users need to be a constant
// expression used by another global variable.
for (const auto *U : GV->users())
- NumGOTEquivUsers += getNumGlobalVariableUses(dyn_cast<Constant>(U));
+ NumGOTEquivUsers +=
+ getNumGlobalVariableUses(dyn_cast<Constant>(U), HasNonGlobalUsers);
return NumGOTEquivUsers > 0;
}
@@ -2189,9 +2195,13 @@ void AsmPrinter::computeGlobalGOTEquivs(Module &M) {
for (const auto &G : M.globals()) {
unsigned NumGOTEquivUsers = 0;
- if (!isGOTEquivalentCandidate(&G, NumGOTEquivUsers))
+ bool HasNonGlobalUsers = false;
+ if (!isGOTEquivalentCandidate(&G, NumGOTEquivUsers, HasNonGlobalUsers))
continue;
-
+ // If non-global variables use it, we still need to emit it.
+ // Add 1 here, then emit it in `emitGlobalGOTEquivs`.
+ if (HasNonGlobalUsers)
+ NumGOTEquivUsers += 1;
const MCSymbol *GOTEquivSym = getSymbol(&G);
GlobalGOTEquivs[GOTEquivSym] = std::make_pair(&G, NumGOTEquivUsers);
}
diff --git a/llvm/test/MC/X86/gotpcrel-non-globals.ll b/llvm/test/MC/X86/gotpcrel-non-globals.ll
new file mode 100644
index 0000000000000..222d2d73ff728
--- /dev/null
+++ b/llvm/test/MC/X86/gotpcrel-non-globals.ll
@@ -0,0 +1,36 @@
+; RUN: llc < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+; Check that we emit the `@bar_*` symbols, and that we don't emit multiple symbols.
+
+; CHECK-LABEL: .Lrel_0:
+; CHECK: .long foo_0@GOTPCREL+0
+; CHECK-LABEL: .Lrel_1_failed:
+; CHECK: .long bar_1-foo_0
+; CHECK-LABEL: .Lrel_2:
+; CHECK: .long foo_2@GOTPCREL+0
+
+; CHECK: bar_0:
+; CHECK: bar_1:
+; CHECK: bar_2_indirect:
+
+@rel_0 = private unnamed_addr constant [1 x i32] [
+ i32 trunc (i64 sub (i64 ptrtoint (ptr @bar_0 to i64), i64 ptrtoint (ptr @rel_0 to i64)) to i32)]
+@rel_1_failed = private unnamed_addr constant [1 x i32] [
+ i32 trunc (i64 sub (i64 ptrtoint (ptr @bar_1 to i64), i64 ptrtoint (ptr @foo_0 to i64)) to i32)]
+@rel_2 = private unnamed_addr constant [1 x i32] [
+ i32 trunc (i64 sub (i64 ptrtoint (ptr @bar_2_indirect to i64), i64 ptrtoint (ptr @rel_2 to i64)) to i32)]
+@bar_0 = internal unnamed_addr constant ptr @foo_0, align 8
+@bar_1 = internal unnamed_addr constant ptr @foo_1, align 8
+@bar_2_indirect = internal unnamed_addr constant ptr @foo_2, align 8
+@foo_0 = external global ptr, align 8
+@foo_1 = external global ptr, align 8
+@foo_2 = external global ptr, align 8
+
+define void @foo(ptr %arg0, ptr %arg1) {
+ store ptr @bar_0, ptr %arg0, align 8
+ store ptr @bar_1, ptr %arg1, align 8
+ store ptr getelementptr (i8, ptr @bar_2_indirect, i32 1), ptr %arg1, align 8
+ ret void
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Backport 630d55c
Requested by: @dianqk