-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[llvm][CFI] Do not canonicalize COFF functions in a comdat #139962
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
Conversation
@llvm/pr-subscribers-llvm-transforms Author: None (PiJoules) ChangesCOFF requires that a function exists with the same name as a comdat. Not having this key function results in Full diff: https://github.com/llvm/llvm-project/pull/139962.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index d855647095550..b9e83565497c4 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -246,6 +246,18 @@ void ByteArrayBuilder::allocate(const std::set<uint64_t> &Bits,
bool lowertypetests::isJumpTableCanonical(Function *F) {
if (F->isDeclarationForLinker())
return false;
+
+ // Do not canonicalize a comdat'd COFF function because this could end up
+ // renaming the comdat key function without renaming the comdat key. We cannot
+ // rename the key in this LTO unit because other TUs may reference the
+ // original key name. To prevent this, just ignore canonicalization for
+ // comdat'd COFF functions.
+ if (F->hasComdat()) {
+ Triple TargetTriple(F->getParent()->getTargetTriple());
+ if (TargetTriple.isOSBinFormatCOFF())
+ return false;
+ }
+
auto *CI = mdconst::extract_or_null<ConstantInt>(
F->getParent()->getModuleFlag("CFI Canonical Jump Tables"));
if (!CI || !CI->isZero())
diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-canonical-jump-tables-coff.ll b/llvm/test/Transforms/LowerTypeTests/cfi-canonical-jump-tables-coff.ll
new file mode 100644
index 0000000000000..8ad5099874226
--- /dev/null
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-canonical-jump-tables-coff.ll
@@ -0,0 +1,30 @@
+; RUN: opt -S -passes=lowertypetests %s -mtriple=x86_64-pc-windows-msvc | llc -asm-verbose=false | FileCheck %s --check-prefixes=COFF,CHECK
+; RUN: opt -S -passes=lowertypetests %s -mtriple=x86_64-unknown-linux-gnu | llc -asm-verbose=false | FileCheck %s --check-prefixes=ELF,CHECK
+
+target datalayout = "e-p:64:64"
+
+; COFF-LABEL: f3:
+; ELF-LABEL: f3.cfi:
+
+; CHECK-LABEL: a:
+; COFF: .quad .L.cfi.jumptable
+; ELF: .quad f3
+
+; ELF: .set f3, .L.cfi.jumptable
+
+@a = global ptr @f3
+
+$f3 = comdat any
+
+define void @f3() comdat !type !0 {
+ ret void
+}
+
+declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) nounwind readnone
+
+define i1 @foo(ptr %p) {
+ %x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
+ ret i1 %x
+}
+
+!0 = !{i32 0, !"typeid1"}
|
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.
This would break taking the address of a function outside of the linkage unit without LTO, which is something that normally requires opting into.
// Do not canonicalize a comdat'd COFF function because this could end up | ||
// renaming the comdat key function without renaming the comdat key. We cannot | ||
// rename the key in this LTO unit because other TUs may reference the | ||
// original key name. To prevent this, just ignore canonicalization for |
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.
I don't think the name of the comdat should matter at this point, LTO happens after comdat resolution.
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.
Ah I didn't know that. So I guess as long as the key function was chosen as the prevailing symbol for the symbol table passed to LTO, then it should be fine to rename the comdat.
60886e8
to
9e6f797
Compare
Updated to rename the comdat |
COFF requires that a function exists with the same name as a comdat. Not having this key function results in `LLVM ERROR: Associative COMDAT symbol '...' does not exist.` CFI by default will attempt to canonicalize a function by appending `.cfi` to its name which allows external references to refer to the new canonical alias, but it does not change the comdat name. We can just change the comdat name since symbol resolution has already happened before LTO.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/16741 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/20125 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/16186 Here is the relevant piece of the build log for the reference
|
…139962)" This reapplies 33684ac with appropriate requires on tests. COFF requires that a function exists with the same name as a comdat. Not having this key function results in `LLVM ERROR: Associative COMDAT symbol '...' does not exist.` CFI by default will attempt to canonicalize a function by appending `.cfi` to its name which allows external references to refer to the new canonical alias, but it does not change the comdat name. We can change the comdat name since symbol and comdat resolution occurs before LTO, so we already know which symbols are prevailing.
…a comdat (#139962)" This reverts commit 33684ac. Reverting since this is breaking a bunch of builders. See the llvm-ci messages on llvm/llvm-project#139962.
COFF requires that a function exists with the same name as a comdat. Not having this key function results in
LLVM ERROR: Associative COMDAT symbol '...' does not exist.
CFI by default will attempt to canonicalize a function by appending.cfi
to its name which allows external references to refer to the new canonical alias, but it does not change the comdat name. We can change the comdat name since symbol and comdat resolution occurs before LTO, so we already know which symbols are prevailing.