Skip to content
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

[Coverage][WebAssembly] Add initial support for WebAssembly/WASI #111332

Merged
merged 9 commits into from
Oct 14, 2024

Conversation

kateinoigakukun
Copy link
Member

@kateinoigakukun kateinoigakukun commented Oct 7, 2024

Currently, WebAssembly/WASI target does not provide direct support for code coverage.
This patch set fixes several issues to unlock the feature. The main changes are:

  1. Port compiler-rt/lib/profile to WebAssembly/WASI.
  2. Adjust profile metadata sections for Wasm object file format.
    • [CodeGen] Emit __llvm_covmap and __llvm_covfun as custom sections instead of data segments.
    • [lld] Align the interval space of custom sections at link time.
    • [llvm-cov] Copy misaligned custom section data if the start address is not aligned.
    • [llvm-cov] Read __llvm_prf_names from data segments
  3. [clang] Link with profile runtime libraries if requested

See each commit message for more details and rationale.
This is part of the effort to add code coverage support in Wasm target of Swift toolchain.

This patch adds initial support for WebAssembly/WASI to the profile
runtime library on the top of wasi-libc. This is a part of the ongoing
patch series to add coverage support for WebAssembly/WASI.

The patch includes the following changes:
* Add wasm32-wasi to the list of supported architectures/OSes.
* Exclude unsupported features for WASI: flock, madvise, uname.
* Enable some user-space emulation provided by wasi-libc: mmap, getpid
@llvmbot llvmbot added clang Clang issues not falling into any other category compiler-rt lld backend:WebAssembly clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' mc Machine (object) code lld:wasm PGO Profile Guided Optimizations llvm:transforms labels Oct 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 7, 2024

@llvm/pr-subscribers-mc
@llvm/pr-subscribers-pgo
@llvm/pr-subscribers-lld
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-webassembly

Author: Yuta Saito (kateinoigakukun)

Changes

Currently, WebAssembly/WASI target does not provide direct support for code coverage.
This patch set fixes several issues to unlock the feature. The main changes are:

  1. Port compiler-rt/lib/profile to WebAssembly/WASI.
  2. Adjust profile metadata sections for Wasm object file format.
    • [CodeGen] Emit __llvm_covmap and __llvm_covfun as custom sections instead of data segments.
    • [lld] Align the interval space of custom sections at link time.
    • [llvm-cov] Copy misaligned custom section data if the start address is not aligned.
    • [llvm-cov] Read __llvm_prf_names from data segments
  3. [clang] Link with profile runtime libraries if requested

See each commit message for more details and rationale.


Patch is 22.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111332.diff

21 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/WebAssembly.cpp (+2)
  • (modified) compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake (+1-1)
  • (modified) compiler-rt/cmake/config-ix.cmake (+1-1)
  • (modified) compiler-rt/lib/profile/CMakeLists.txt (+24)
  • (modified) compiler-rt/lib/profile/GCDAProfiling.c (+1-1)
  • (modified) compiler-rt/lib/profile/InstrProfilingPlatformLinux.c (+2-2)
  • (modified) compiler-rt/lib/profile/InstrProfilingPlatformOther.c (+1-1)
  • (modified) compiler-rt/lib/profile/InstrProfilingPort.h (+1-1)
  • (modified) compiler-rt/lib/profile/InstrProfilingUtil.c (+8-4)
  • (added) lld/test/wasm/custom-section-align.s (+31)
  • (modified) lld/wasm/InputChunks.h (+6-4)
  • (modified) lld/wasm/InputFiles.cpp (+16-2)
  • (modified) lld/wasm/OutputSections.cpp (+1)
  • (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+5-1)
  • (modified) llvm/lib/MC/MCContext.cpp (+5)
  • (modified) llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp (+64-9)
  • (modified) llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp (+2-2)
  • (added) llvm/test/CodeGen/WebAssembly/profile.ll (+47)
  • (added) llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.wasm32 ()
  • (added) llvm/test/tools/llvm-cov/Inputs/binary-formats.wasm.proftext (+4)
  • (modified) llvm/test/tools/llvm-cov/binary-formats.c (+6)
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 9aec11e69fde1d..44a6894d30fb29 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -163,6 +163,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
   }
 
+  ToolChain.addProfileRTLibs(Args, CmdArgs);
+
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 809e9277156912..d00d39518104bf 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -77,7 +77,7 @@ set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${RISCV64})
 set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64})
 set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64}
     ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
-    ${RISCV32} ${RISCV64} ${LOONGARCH64})
+    ${RISCV32} ${RISCV64} ${LOONGARCH64} ${WASM32})
 set(ALL_CTX_PROFILE_SUPPORTED_ARCH ${X86_64})
 if (OS_NAME MATCHES "FreeBSD")
   set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index a93a88a9205001..a494e0532a50bc 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -822,7 +822,7 @@ else()
 endif()
 
 if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
-    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX")
+    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|WASI")
   set(COMPILER_RT_HAS_PROFILE TRUE)
 else()
   set(COMPILER_RT_HAS_PROFILE FALSE)
diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt
index ef23492514898b..a6402f80b890a2 100644
--- a/compiler-rt/lib/profile/CMakeLists.txt
+++ b/compiler-rt/lib/profile/CMakeLists.txt
@@ -38,6 +38,17 @@ int main() {
 
 " COMPILER_RT_TARGET_HAS_FCNTL_LCK)
 
+CHECK_CXX_SOURCE_COMPILES("
+#include <sys/file.h>
+
+int fd;
+int main() {
+  flock(fd, LOCK_EX);
+  return 0;
+}
+
+" COMPILER_RT_TARGET_HAS_FLOCK)
+
 CHECK_CXX_SOURCE_COMPILES("
 #include <sys/utsname.h>
 int main() {
@@ -93,6 +104,13 @@ if(FUCHSIA OR UNIX)
      -Wno-pedantic)
 endif()
 
+if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
+  set(EXTRA_FLAGS
+      ${EXTRA_FLAGS}
+      -D_WASI_EMULATED_MMAN
+      -D_WASI_EMULATED_GETPID)
+endif()
+
 if(COMPILER_RT_TARGET_HAS_ATOMICS)
  set(EXTRA_FLAGS
      ${EXTRA_FLAGS}
@@ -105,6 +123,12 @@ if(COMPILER_RT_TARGET_HAS_FCNTL_LCK)
      -DCOMPILER_RT_HAS_FCNTL_LCK=1)
 endif()
 
+if(COMPILER_RT_TARGET_HAS_FLOCK)
+  set(EXTRA_FLAGS
+      ${EXTRA_FLAGS}
+      -DCOMPILER_RT_HAS_FLOCK=1)
+endif()
+
 if(COMPILER_RT_TARGET_HAS_UNAME)
  set(EXTRA_FLAGS
      ${EXTRA_FLAGS}
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
index d6e2175169e4a5..a207ddf97c8831 100644
--- a/compiler-rt/lib/profile/GCDAProfiling.c
+++ b/compiler-rt/lib/profile/GCDAProfiling.c
@@ -584,7 +584,7 @@ void llvm_reset_counters(void) {
   }
 }
 
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(__wasi__)
 COMPILER_RT_VISIBILITY
 pid_t __gcov_fork() {
   pid_t parent_pid = getpid();
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
index b766436497b741..a9791eebabc9df 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
@@ -8,9 +8,9 @@
 
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
     (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
-    defined(_AIX)
+    defined(_AIX) || defined(__wasm__)
 
-#if !defined(_AIX)
+#if !defined(_AIX) && !defined(__wasm__)
 #include <elf.h>
 #include <link.h>
 #endif
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
index aa79a5641ceca6..e873e9ffbfc6d7 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
@@ -8,7 +8,7 @@
 
 #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) &&     \
     !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) &&       \
-    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
+    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) && !defined(__wasm__)
 
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/compiler-rt/lib/profile/InstrProfilingPort.h b/compiler-rt/lib/profile/InstrProfilingPort.h
index ed0905cc5f2022..8715a3b0d2a6f0 100644
--- a/compiler-rt/lib/profile/InstrProfilingPort.h
+++ b/compiler-rt/lib/profile/InstrProfilingPort.h
@@ -54,7 +54,7 @@
 #endif
 
 #define COMPILER_RT_MAX_HOSTLEN 128
-#ifdef __ORBIS__
+#if defined(__ORBIS__) || defined(__wasi__)
 #define COMPILER_RT_GETHOSTNAME(Name, Len) ((void)(Name), (void)(Len), (-1))
 #else
 #define COMPILER_RT_GETHOSTNAME(Name, Len) lprofGetHostName(Name, Len)
diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.c b/compiler-rt/lib/profile/InstrProfilingUtil.c
index 642393d432d7ea..95ec4080ba2504 100644
--- a/compiler-rt/lib/profile/InstrProfilingUtil.c
+++ b/compiler-rt/lib/profile/InstrProfilingUtil.c
@@ -152,9 +152,11 @@ COMPILER_RT_VISIBILITY int lprofLockFd(int fd) {
     }
   }
   return 0;
-#else
+#elif defined(COMPILER_RT_HAS_FLOCK)
   flock(fd, LOCK_EX);
   return 0;
+#else
+  return 0;
 #endif
 }
 
@@ -177,9 +179,11 @@ COMPILER_RT_VISIBILITY int lprofUnlockFd(int fd) {
     }
   }
   return 0;
-#else
+#elif defined(COMPILER_RT_HAS_FLOCK)
   flock(fd, LOCK_UN);
   return 0;
+#else
+  return 0;
 #endif
 }
 
@@ -353,8 +357,8 @@ COMPILER_RT_VISIBILITY void lprofRestoreSigKill(void) {
 
 COMPILER_RT_VISIBILITY int lprofReleaseMemoryPagesToOS(uintptr_t Begin,
                                                        uintptr_t End) {
-#if defined(__ve__)
-  // VE doesn't support madvise.
+#if defined(__ve__) || defined(__wasi__)
+  // VE and WASI doesn't support madvise.
   return 0;
 #else
   size_t PageSize = getpagesize();
diff --git a/lld/test/wasm/custom-section-align.s b/lld/test/wasm/custom-section-align.s
new file mode 100644
index 00000000000000..0e46177f4cdb79
--- /dev/null
+++ b/lld/test/wasm/custom-section-align.s
@@ -0,0 +1,31 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --no-entry %t.o -o %t.wasm
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+# Check that "__llvm_covfun" custom section is aligned to 8 bytes.
+
+        .section        .custom_section.__llvm_covfun,"GR",@,__covrec_A
+        .int32  1
+        .int8   2
+# pad   .int8   0
+#       .int8   0
+#       .int8   0
+
+        .section        .custom_section.__llvm_covfun,"GR",@,__covrec_B
+        .int32  3
+
+# CHECK:      - Type:            CUSTOM
+# CHECK-NEXT:   Name:            __llvm_covfun
+# CHECK-NEXT:   Payload:         '010000000200000003000000'
+
+# Check that regular custom sections are not aligned.
+        .section        .custom_section.foo,"GR",@,foo_A
+        .int32  1
+        .int8   2
+
+        .section        .custom_section.foo,"GR",@,foo_B
+        .int32  3
+
+# CHECK:      - Type:            CUSTOM
+# CHECK-NEXT:   Name:            foo
+# CHECK-NEXT:   Payload:         '010000000203000000'
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index 14eb008c212fb5..d6769bcf5c8232 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -177,8 +177,9 @@ class MergeInputChunk : public InputChunk {
     inputSectionOffset = seg.SectionOffset;
   }
 
-  MergeInputChunk(const WasmSection &s, ObjFile *f)
-      : InputChunk(f, Merge, s.Name, 0, llvm::wasm::WASM_SEG_FLAG_STRINGS) {
+  MergeInputChunk(const WasmSection &s, ObjFile *f, uint32_t alignment)
+      : InputChunk(f, Merge, s.Name, alignment,
+                   llvm::wasm::WASM_SEG_FLAG_STRINGS) {
     assert(s.Type == llvm::wasm::WASM_SEC_CUSTOM);
     comdat = s.Comdat;
     rawData = s.Content;
@@ -234,6 +235,7 @@ class SyntheticMergedChunk : public InputChunk {
 
   void addMergeChunk(MergeInputChunk *ms) {
     comdat = ms->getComdat();
+    alignment = std::max(alignment, ms->alignment);
     ms->parent = this;
     chunks.push_back(ms);
   }
@@ -337,8 +339,8 @@ class SyntheticFunction : public InputFunction {
 // Represents a single Wasm Section within an input file.
 class InputSection : public InputChunk {
 public:
-  InputSection(const WasmSection &s, ObjFile *f)
-      : InputChunk(f, InputChunk::Section, s.Name),
+  InputSection(const WasmSection &s, ObjFile *f, uint32_t alignment)
+      : InputChunk(f, InputChunk::Section, s.Name, alignment),
         tombstoneValue(getTombstoneForSection(s.Name)), section(s) {
     assert(section.Type == llvm::wasm::WASM_SEC_CUSTOM);
     comdat = section.Comdat;
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index de8e707ab2b497..a60deba9113cd4 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -18,6 +18,7 @@
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/Wasm.h"
+#include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TarWriter.h"
 #include "llvm/Support/raw_ostream.h"
@@ -451,6 +452,18 @@ void SharedFile::parse() {
   }
 }
 
+/// Returns the alignment for a custom section. This is used to concatenate
+/// custom sections with the same name into a single custom section.
+static uint32_t getCustomSectionAlignment(const WasmSection &sec) {
+  // TODO: Add a section attribute for alignment in the linking spec.
+  if (sec.Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm) ||
+      sec.Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm)) {
+    // llvm-cov assumes that coverage metadata sections are 8-byte aligned.
+    return 8;
+  }
+  return 1;
+}
+
 WasmFileBase::WasmFileBase(Kind k, MemoryBufferRef m) : InputFile(k, m) {
   // Parse a memory buffer as a wasm file.
   LLVM_DEBUG(dbgs() << "Reading object: " << toString(this) << "\n");
@@ -520,10 +533,11 @@ void ObjFile::parse(bool ignoreComdats) {
       dataSection = &section;
     } else if (section.Type == WASM_SEC_CUSTOM) {
       InputChunk *customSec;
+      uint32_t alignment = getCustomSectionAlignment(section);
       if (shouldMerge(section))
-        customSec = make<MergeInputChunk>(section, this);
+        customSec = make<MergeInputChunk>(section, this, alignment);
       else
-        customSec = make<InputSection>(section, this);
+        customSec = make<InputSection>(section, this, alignment);
       customSec->discarded = isExcludedByComdat(customSec);
       customSections.emplace_back(customSec);
       customSections.back()->setRelocations(section.Relocations);
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index b0b2446cb56bfc..e4f75829ec4c3e 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -244,6 +244,7 @@ void CustomSection::finalizeContents() {
 
   for (InputChunk *section : inputSections) {
     assert(!section->discarded);
+    payloadSize = alignTo(payloadSize, section->alignment);
     section->outSecOff = payloadSize;
     payloadSize += section->getSize();
   }
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 0d3e4ba5662e01..ce50a3c19ffe04 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2171,7 +2171,11 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
   // This could be avoided if all data segements (the wasm sense) were
   // represented as their own sections (in the llvm sense).
   // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138
-  if (Name == ".llvmcmd" || Name == ".llvmbc")
+  if (Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm,
+                                      /*AddSegmentInfo=*/false) ||
+      Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm,
+                                      /*AddSegmentInfo=*/false) ||
+      Name == ".llvmbc" || Name == ".llvmcmd")
     Kind = SectionKind::getMetadata();
 
   StringRef Group = "";
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index ac3946b6ef46f3..b97f9d9f5fed0f 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -757,6 +757,11 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
   if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
     GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
     GroupSym->setComdat(true);
+    if (K.isMetadata() && !GroupSym->getType().has_value()) {
+      // Comdat group symbol associated with a custom section is a section
+      // symbol (not a data symbol).
+      GroupSym->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
+    }
   }
 
   return getWasmSection(Section, K, Flags, GroupSym, UniqueID);
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index bc4e780fb67a60..347578ad5fbfbe 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -18,12 +18,14 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/Wasm.h"
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compression.h"
@@ -1075,6 +1077,53 @@ lookupSections(ObjectFile &OF, InstrProfSectKind IPSK) {
   return Sections;
 }
 
+/// Find a section that matches \p Name and is allocatable at runtime.
+///
+/// Returns the contents of the section and its start offset in the object file.
+static Expected<std::pair<StringRef, uint64_t>>
+lookupAllocatableSection(ObjectFile &OF, InstrProfSectKind IPSK) {
+  // On Wasm, allocatable sections can live only in data segments.
+  if (auto *WOF = dyn_cast<WasmObjectFile>(&OF)) {
+    std::vector<const WasmSegment *> Segments;
+    auto ObjFormat = OF.getTripleObjectFormat();
+    auto Name =
+        getInstrProfSectionName(IPSK, ObjFormat, /*AddSegmentInfo=*/false);
+    for (const auto &DebugName : WOF->debugNames()) {
+      if (DebugName.Type != wasm::NameType::DATA_SEGMENT ||
+          DebugName.Name != Name)
+        continue;
+      if (DebugName.Index >= WOF->dataSegments().size())
+        return make_error<CoverageMapError>(coveragemap_error::malformed);
+      auto &Segment = WOF->dataSegments()[DebugName.Index];
+      Segments.push_back(&Segment);
+    }
+    if (Segments.empty())
+      return make_error<CoverageMapError>(coveragemap_error::no_data_found);
+    if (Segments.size() != 1)
+      return make_error<CoverageMapError>(coveragemap_error::malformed);
+
+    const auto &Segment = *Segments.front();
+    auto &Data = Segment.Data;
+    StringRef Content(reinterpret_cast<const char *>(Data.Content.data()),
+                      Data.Content.size());
+    return std::make_pair(Content, Segment.SectionOffset);
+  }
+
+  // On other object file types, delegate to lookupSections to find the section.
+  auto Sections = lookupSections(OF, IPSK);
+  if (!Sections)
+    return Sections.takeError();
+  if (Sections->size() != 1)
+    return make_error<CoverageMapError>(
+        coveragemap_error::malformed,
+        "the size of coverage mapping section is not one");
+  auto &Section = Sections->front();
+  auto ContentsOrErr = Section.getContents();
+  if (!ContentsOrErr)
+    return ContentsOrErr.takeError();
+  return std::make_pair(*ContentsOrErr, Section.getAddress());
+}
+
 static Expected<std::unique_ptr<BinaryCoverageReader>>
 loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
                  StringRef CompilationDir = "",
@@ -1105,23 +1154,20 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
 
   // Look for the sections that we are interested in.
   auto ProfileNames = std::make_unique<InstrProfSymtab>();
-  std::vector<SectionRef> NamesSectionRefs;
   // If IPSK_name is not found, fallback to search for IPK_covname, which is
   // used when binary correlation is enabled.
-  auto NamesSection = lookupSections(*OF, IPSK_name);
+  auto NamesSection = lookupAllocatableSection(*OF, IPSK_name);
   if (auto E = NamesSection.takeError()) {
     consumeError(std::move(E));
-    NamesSection = lookupSections(*OF, IPSK_covname);
+    NamesSection = lookupAllocatableSection(*OF, IPSK_covname);
     if (auto E = NamesSection.takeError())
       return std::move(E);
   }
-  NamesSectionRefs = *NamesSection;
 
-  if (NamesSectionRefs.size() != 1)
-    return make_error<CoverageMapError>(
-        coveragemap_error::malformed,
-        "the size of coverage mapping section is not one");
-  if (Error E = ProfileNames->create(NamesSectionRefs.back()))
+  uint64_t NamesAddress;
+  StringRef NamesContent;
+  std::tie(NamesContent, NamesAddress) = *NamesSection;
+  if (Error E = ProfileNames->create(NamesContent, NamesAddress))
     return std::move(E);
 
   auto CoverageSection = lookupSections(*OF, IPSK_covmap);
@@ -1136,6 +1182,15 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
     return CoverageMappingOrErr.takeError();
   StringRef CoverageMapping = CoverageMappingOrErr.get();
 
+  // If the coverage mapping section is not aligned to 8 bytes, copy it to a
+  // new buffer that is. Wasm format typically has unaligned section contents
+  // because it doesn't have a good way to insert padding bytes.
+  std::unique_ptr<MemoryBuffer> CoverageMappingBufferOwner;
+  if (!isAddrAligned(Align(8), CoverageMapping.data())) {
+    CoverageMappingBufferOwner = MemoryBuffer::getMemBufferCopy(CoverageMapping);
+    CoverageMapping = CoverageMappingBufferOwner->getBuffer();
+  }
+
   // Look for the coverage records section (Version4 only).
   auto CoverageRecordsSections = lookupSections(*OF, IPSK_covfun);
 
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 1c95a4606ecc56..b875f851a57e9f 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -1406,9 +1406,9 @@ static inline Constant *getFuncAddrForProfData(Function *Fn) {
 
 static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) {
   // compiler-rt uses linker support to get data/counters/name start/end for
-  // ELF, COFF, Mach-O and XCOFF.
+  // ELF, COFF, Mach-O, XCOFF, and Wasm.
   if (TT.isOSBinFormatELF() || TT.isOSBinFormatCOFF() ||
-      TT.isOSBinFormatMachO() || TT.isOSBinFormatXCOFF())
+      TT.isOSBinFormatMachO() || TT.isOSBinFormatXCOFF() || TT.isOSBinFormatWasm())
     return false;
 
   return true;
diff --git a/llvm/test/CodeGen/WebAssembly/profile.ll b/llvm/test/CodeGen/WebAssembly/profile.ll
new file mode 100644
index 00000000000000..27802cc3bf3567
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/profile.ll
@@ -0,0 +1,47 @@
+; RUN: llc < %s --filetype=obj | obj2yaml | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+$__covrec_A = comdat any
+$__covrec_B = comdat any
+
+@__covrec_A = linkonce_odr hidden constant <{ i64, i32, i64, i64, [4 x i8] }> <{
+    i64 -1978722966671112904,
+    i32 4,
+    i64 0,
+    i64 -8102528905418564625,
+    [4 x i8] c"\01\01\04\11"
+}>, section "__llvm_covfun", comdat, align 8
+@__covrec_B = linkonce_odr hidden constant <{ i64, i32, i64, i64, [4 x i8] }> <{
+    i64 8006510647218728891,
+    i32 9,
+    i64 0,
+    i64 -8102528905418564625,
+    [4 x i8] c"\01\01\00\01"
+}>, section "__llvm_covfun", comdat, align 8
+@__llvm_coverage_mapping = private constant { { i32, i32, i32, i32 }, [4 x i8] } {
+    { i32, i32, i32, i32 } { i32 0, i32 87, i32 0, i32 5 },
+    [4 x i8] c"\01\01\00\02"
+}, section "__llvm_covmap", align 8
+
+; CHECK:      - T...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Oct 7, 2024

@llvm/pr-subscribers-lld-wasm

Author: Yuta Saito (kateinoigakukun)

Changes

Currently, WebAssembly/WASI target does not provide direct support for code coverage.
This patch set fixes several issues to unlock the feature. The main changes are:

  1. Port compiler-rt/lib/profile to WebAssembly/WASI.
  2. Adjust profile metadata sections for Wasm object file format.
    • [CodeGen] Emit __llvm_covmap and __llvm_covfun as custom sections instead of data segments.
    • [lld] Align the interval space of custom sections at link time.
    • [llvm-cov] Copy misaligned custom section data if the start address is not aligned.
    • [llvm-cov] Read __llvm_prf_names from data segments
  3. [clang] Link with profile runtime libraries if requested

See each commit message for more details and rationale.


Patch is 22.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111332.diff

21 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/WebAssembly.cpp (+2)
  • (modified) compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake (+1-1)
  • (modified) compiler-rt/cmake/config-ix.cmake (+1-1)
  • (modified) compiler-rt/lib/profile/CMakeLists.txt (+24)
  • (modified) compiler-rt/lib/profile/GCDAProfiling.c (+1-1)
  • (modified) compiler-rt/lib/profile/InstrProfilingPlatformLinux.c (+2-2)
  • (modified) compiler-rt/lib/profile/InstrProfilingPlatformOther.c (+1-1)
  • (modified) compiler-rt/lib/profile/InstrProfilingPort.h (+1-1)
  • (modified) compiler-rt/lib/profile/InstrProfilingUtil.c (+8-4)
  • (added) lld/test/wasm/custom-section-align.s (+31)
  • (modified) lld/wasm/InputChunks.h (+6-4)
  • (modified) lld/wasm/InputFiles.cpp (+16-2)
  • (modified) lld/wasm/OutputSections.cpp (+1)
  • (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+5-1)
  • (modified) llvm/lib/MC/MCContext.cpp (+5)
  • (modified) llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp (+64-9)
  • (modified) llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp (+2-2)
  • (added) llvm/test/CodeGen/WebAssembly/profile.ll (+47)
  • (added) llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.wasm32 ()
  • (added) llvm/test/tools/llvm-cov/Inputs/binary-formats.wasm.proftext (+4)
  • (modified) llvm/test/tools/llvm-cov/binary-formats.c (+6)
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 9aec11e69fde1d..44a6894d30fb29 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -163,6 +163,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
   }
 
+  ToolChain.addProfileRTLibs(Args, CmdArgs);
+
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 809e9277156912..d00d39518104bf 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -77,7 +77,7 @@ set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${RISCV64})
 set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64})
 set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64}
     ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
-    ${RISCV32} ${RISCV64} ${LOONGARCH64})
+    ${RISCV32} ${RISCV64} ${LOONGARCH64} ${WASM32})
 set(ALL_CTX_PROFILE_SUPPORTED_ARCH ${X86_64})
 if (OS_NAME MATCHES "FreeBSD")
   set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index a93a88a9205001..a494e0532a50bc 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -822,7 +822,7 @@ else()
 endif()
 
 if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
-    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX")
+    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|WASI")
   set(COMPILER_RT_HAS_PROFILE TRUE)
 else()
   set(COMPILER_RT_HAS_PROFILE FALSE)
diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt
index ef23492514898b..a6402f80b890a2 100644
--- a/compiler-rt/lib/profile/CMakeLists.txt
+++ b/compiler-rt/lib/profile/CMakeLists.txt
@@ -38,6 +38,17 @@ int main() {
 
 " COMPILER_RT_TARGET_HAS_FCNTL_LCK)
 
+CHECK_CXX_SOURCE_COMPILES("
+#include <sys/file.h>
+
+int fd;
+int main() {
+  flock(fd, LOCK_EX);
+  return 0;
+}
+
+" COMPILER_RT_TARGET_HAS_FLOCK)
+
 CHECK_CXX_SOURCE_COMPILES("
 #include <sys/utsname.h>
 int main() {
@@ -93,6 +104,13 @@ if(FUCHSIA OR UNIX)
      -Wno-pedantic)
 endif()
 
+if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
+  set(EXTRA_FLAGS
+      ${EXTRA_FLAGS}
+      -D_WASI_EMULATED_MMAN
+      -D_WASI_EMULATED_GETPID)
+endif()
+
 if(COMPILER_RT_TARGET_HAS_ATOMICS)
  set(EXTRA_FLAGS
      ${EXTRA_FLAGS}
@@ -105,6 +123,12 @@ if(COMPILER_RT_TARGET_HAS_FCNTL_LCK)
      -DCOMPILER_RT_HAS_FCNTL_LCK=1)
 endif()
 
+if(COMPILER_RT_TARGET_HAS_FLOCK)
+  set(EXTRA_FLAGS
+      ${EXTRA_FLAGS}
+      -DCOMPILER_RT_HAS_FLOCK=1)
+endif()
+
 if(COMPILER_RT_TARGET_HAS_UNAME)
  set(EXTRA_FLAGS
      ${EXTRA_FLAGS}
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
index d6e2175169e4a5..a207ddf97c8831 100644
--- a/compiler-rt/lib/profile/GCDAProfiling.c
+++ b/compiler-rt/lib/profile/GCDAProfiling.c
@@ -584,7 +584,7 @@ void llvm_reset_counters(void) {
   }
 }
 
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(__wasi__)
 COMPILER_RT_VISIBILITY
 pid_t __gcov_fork() {
   pid_t parent_pid = getpid();
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
index b766436497b741..a9791eebabc9df 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
@@ -8,9 +8,9 @@
 
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
     (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
-    defined(_AIX)
+    defined(_AIX) || defined(__wasm__)
 
-#if !defined(_AIX)
+#if !defined(_AIX) && !defined(__wasm__)
 #include <elf.h>
 #include <link.h>
 #endif
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
index aa79a5641ceca6..e873e9ffbfc6d7 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
@@ -8,7 +8,7 @@
 
 #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) &&     \
     !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) &&       \
-    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
+    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) && !defined(__wasm__)
 
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/compiler-rt/lib/profile/InstrProfilingPort.h b/compiler-rt/lib/profile/InstrProfilingPort.h
index ed0905cc5f2022..8715a3b0d2a6f0 100644
--- a/compiler-rt/lib/profile/InstrProfilingPort.h
+++ b/compiler-rt/lib/profile/InstrProfilingPort.h
@@ -54,7 +54,7 @@
 #endif
 
 #define COMPILER_RT_MAX_HOSTLEN 128
-#ifdef __ORBIS__
+#if defined(__ORBIS__) || defined(__wasi__)
 #define COMPILER_RT_GETHOSTNAME(Name, Len) ((void)(Name), (void)(Len), (-1))
 #else
 #define COMPILER_RT_GETHOSTNAME(Name, Len) lprofGetHostName(Name, Len)
diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.c b/compiler-rt/lib/profile/InstrProfilingUtil.c
index 642393d432d7ea..95ec4080ba2504 100644
--- a/compiler-rt/lib/profile/InstrProfilingUtil.c
+++ b/compiler-rt/lib/profile/InstrProfilingUtil.c
@@ -152,9 +152,11 @@ COMPILER_RT_VISIBILITY int lprofLockFd(int fd) {
     }
   }
   return 0;
-#else
+#elif defined(COMPILER_RT_HAS_FLOCK)
   flock(fd, LOCK_EX);
   return 0;
+#else
+  return 0;
 #endif
 }
 
@@ -177,9 +179,11 @@ COMPILER_RT_VISIBILITY int lprofUnlockFd(int fd) {
     }
   }
   return 0;
-#else
+#elif defined(COMPILER_RT_HAS_FLOCK)
   flock(fd, LOCK_UN);
   return 0;
+#else
+  return 0;
 #endif
 }
 
@@ -353,8 +357,8 @@ COMPILER_RT_VISIBILITY void lprofRestoreSigKill(void) {
 
 COMPILER_RT_VISIBILITY int lprofReleaseMemoryPagesToOS(uintptr_t Begin,
                                                        uintptr_t End) {
-#if defined(__ve__)
-  // VE doesn't support madvise.
+#if defined(__ve__) || defined(__wasi__)
+  // VE and WASI doesn't support madvise.
   return 0;
 #else
   size_t PageSize = getpagesize();
diff --git a/lld/test/wasm/custom-section-align.s b/lld/test/wasm/custom-section-align.s
new file mode 100644
index 00000000000000..0e46177f4cdb79
--- /dev/null
+++ b/lld/test/wasm/custom-section-align.s
@@ -0,0 +1,31 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --no-entry %t.o -o %t.wasm
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+# Check that "__llvm_covfun" custom section is aligned to 8 bytes.
+
+        .section        .custom_section.__llvm_covfun,"GR",@,__covrec_A
+        .int32  1
+        .int8   2
+# pad   .int8   0
+#       .int8   0
+#       .int8   0
+
+        .section        .custom_section.__llvm_covfun,"GR",@,__covrec_B
+        .int32  3
+
+# CHECK:      - Type:            CUSTOM
+# CHECK-NEXT:   Name:            __llvm_covfun
+# CHECK-NEXT:   Payload:         '010000000200000003000000'
+
+# Check that regular custom sections are not aligned.
+        .section        .custom_section.foo,"GR",@,foo_A
+        .int32  1
+        .int8   2
+
+        .section        .custom_section.foo,"GR",@,foo_B
+        .int32  3
+
+# CHECK:      - Type:            CUSTOM
+# CHECK-NEXT:   Name:            foo
+# CHECK-NEXT:   Payload:         '010000000203000000'
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index 14eb008c212fb5..d6769bcf5c8232 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -177,8 +177,9 @@ class MergeInputChunk : public InputChunk {
     inputSectionOffset = seg.SectionOffset;
   }
 
-  MergeInputChunk(const WasmSection &s, ObjFile *f)
-      : InputChunk(f, Merge, s.Name, 0, llvm::wasm::WASM_SEG_FLAG_STRINGS) {
+  MergeInputChunk(const WasmSection &s, ObjFile *f, uint32_t alignment)
+      : InputChunk(f, Merge, s.Name, alignment,
+                   llvm::wasm::WASM_SEG_FLAG_STRINGS) {
     assert(s.Type == llvm::wasm::WASM_SEC_CUSTOM);
     comdat = s.Comdat;
     rawData = s.Content;
@@ -234,6 +235,7 @@ class SyntheticMergedChunk : public InputChunk {
 
   void addMergeChunk(MergeInputChunk *ms) {
     comdat = ms->getComdat();
+    alignment = std::max(alignment, ms->alignment);
     ms->parent = this;
     chunks.push_back(ms);
   }
@@ -337,8 +339,8 @@ class SyntheticFunction : public InputFunction {
 // Represents a single Wasm Section within an input file.
 class InputSection : public InputChunk {
 public:
-  InputSection(const WasmSection &s, ObjFile *f)
-      : InputChunk(f, InputChunk::Section, s.Name),
+  InputSection(const WasmSection &s, ObjFile *f, uint32_t alignment)
+      : InputChunk(f, InputChunk::Section, s.Name, alignment),
         tombstoneValue(getTombstoneForSection(s.Name)), section(s) {
     assert(section.Type == llvm::wasm::WASM_SEC_CUSTOM);
     comdat = section.Comdat;
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index de8e707ab2b497..a60deba9113cd4 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -18,6 +18,7 @@
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/Wasm.h"
+#include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TarWriter.h"
 #include "llvm/Support/raw_ostream.h"
@@ -451,6 +452,18 @@ void SharedFile::parse() {
   }
 }
 
+/// Returns the alignment for a custom section. This is used to concatenate
+/// custom sections with the same name into a single custom section.
+static uint32_t getCustomSectionAlignment(const WasmSection &sec) {
+  // TODO: Add a section attribute for alignment in the linking spec.
+  if (sec.Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm) ||
+      sec.Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm)) {
+    // llvm-cov assumes that coverage metadata sections are 8-byte aligned.
+    return 8;
+  }
+  return 1;
+}
+
 WasmFileBase::WasmFileBase(Kind k, MemoryBufferRef m) : InputFile(k, m) {
   // Parse a memory buffer as a wasm file.
   LLVM_DEBUG(dbgs() << "Reading object: " << toString(this) << "\n");
@@ -520,10 +533,11 @@ void ObjFile::parse(bool ignoreComdats) {
       dataSection = &section;
     } else if (section.Type == WASM_SEC_CUSTOM) {
       InputChunk *customSec;
+      uint32_t alignment = getCustomSectionAlignment(section);
       if (shouldMerge(section))
-        customSec = make<MergeInputChunk>(section, this);
+        customSec = make<MergeInputChunk>(section, this, alignment);
       else
-        customSec = make<InputSection>(section, this);
+        customSec = make<InputSection>(section, this, alignment);
       customSec->discarded = isExcludedByComdat(customSec);
       customSections.emplace_back(customSec);
       customSections.back()->setRelocations(section.Relocations);
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index b0b2446cb56bfc..e4f75829ec4c3e 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -244,6 +244,7 @@ void CustomSection::finalizeContents() {
 
   for (InputChunk *section : inputSections) {
     assert(!section->discarded);
+    payloadSize = alignTo(payloadSize, section->alignment);
     section->outSecOff = payloadSize;
     payloadSize += section->getSize();
   }
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 0d3e4ba5662e01..ce50a3c19ffe04 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2171,7 +2171,11 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
   // This could be avoided if all data segements (the wasm sense) were
   // represented as their own sections (in the llvm sense).
   // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138
-  if (Name == ".llvmcmd" || Name == ".llvmbc")
+  if (Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm,
+                                      /*AddSegmentInfo=*/false) ||
+      Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm,
+                                      /*AddSegmentInfo=*/false) ||
+      Name == ".llvmbc" || Name == ".llvmcmd")
     Kind = SectionKind::getMetadata();
 
   StringRef Group = "";
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index ac3946b6ef46f3..b97f9d9f5fed0f 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -757,6 +757,11 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
   if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
     GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
     GroupSym->setComdat(true);
+    if (K.isMetadata() && !GroupSym->getType().has_value()) {
+      // Comdat group symbol associated with a custom section is a section
+      // symbol (not a data symbol).
+      GroupSym->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
+    }
   }
 
   return getWasmSection(Section, K, Flags, GroupSym, UniqueID);
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index bc4e780fb67a60..347578ad5fbfbe 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -18,12 +18,14 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/Wasm.h"
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compression.h"
@@ -1075,6 +1077,53 @@ lookupSections(ObjectFile &OF, InstrProfSectKind IPSK) {
   return Sections;
 }
 
+/// Find a section that matches \p Name and is allocatable at runtime.
+///
+/// Returns the contents of the section and its start offset in the object file.
+static Expected<std::pair<StringRef, uint64_t>>
+lookupAllocatableSection(ObjectFile &OF, InstrProfSectKind IPSK) {
+  // On Wasm, allocatable sections can live only in data segments.
+  if (auto *WOF = dyn_cast<WasmObjectFile>(&OF)) {
+    std::vector<const WasmSegment *> Segments;
+    auto ObjFormat = OF.getTripleObjectFormat();
+    auto Name =
+        getInstrProfSectionName(IPSK, ObjFormat, /*AddSegmentInfo=*/false);
+    for (const auto &DebugName : WOF->debugNames()) {
+      if (DebugName.Type != wasm::NameType::DATA_SEGMENT ||
+          DebugName.Name != Name)
+        continue;
+      if (DebugName.Index >= WOF->dataSegments().size())
+        return make_error<CoverageMapError>(coveragemap_error::malformed);
+      auto &Segment = WOF->dataSegments()[DebugName.Index];
+      Segments.push_back(&Segment);
+    }
+    if (Segments.empty())
+      return make_error<CoverageMapError>(coveragemap_error::no_data_found);
+    if (Segments.size() != 1)
+      return make_error<CoverageMapError>(coveragemap_error::malformed);
+
+    const auto &Segment = *Segments.front();
+    auto &Data = Segment.Data;
+    StringRef Content(reinterpret_cast<const char *>(Data.Content.data()),
+                      Data.Content.size());
+    return std::make_pair(Content, Segment.SectionOffset);
+  }
+
+  // On other object file types, delegate to lookupSections to find the section.
+  auto Sections = lookupSections(OF, IPSK);
+  if (!Sections)
+    return Sections.takeError();
+  if (Sections->size() != 1)
+    return make_error<CoverageMapError>(
+        coveragemap_error::malformed,
+        "the size of coverage mapping section is not one");
+  auto &Section = Sections->front();
+  auto ContentsOrErr = Section.getContents();
+  if (!ContentsOrErr)
+    return ContentsOrErr.takeError();
+  return std::make_pair(*ContentsOrErr, Section.getAddress());
+}
+
 static Expected<std::unique_ptr<BinaryCoverageReader>>
 loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
                  StringRef CompilationDir = "",
@@ -1105,23 +1154,20 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
 
   // Look for the sections that we are interested in.
   auto ProfileNames = std::make_unique<InstrProfSymtab>();
-  std::vector<SectionRef> NamesSectionRefs;
   // If IPSK_name is not found, fallback to search for IPK_covname, which is
   // used when binary correlation is enabled.
-  auto NamesSection = lookupSections(*OF, IPSK_name);
+  auto NamesSection = lookupAllocatableSection(*OF, IPSK_name);
   if (auto E = NamesSection.takeError()) {
     consumeError(std::move(E));
-    NamesSection = lookupSections(*OF, IPSK_covname);
+    NamesSection = lookupAllocatableSection(*OF, IPSK_covname);
     if (auto E = NamesSection.takeError())
       return std::move(E);
   }
-  NamesSectionRefs = *NamesSection;
 
-  if (NamesSectionRefs.size() != 1)
-    return make_error<CoverageMapError>(
-        coveragemap_error::malformed,
-        "the size of coverage mapping section is not one");
-  if (Error E = ProfileNames->create(NamesSectionRefs.back()))
+  uint64_t NamesAddress;
+  StringRef NamesContent;
+  std::tie(NamesContent, NamesAddress) = *NamesSection;
+  if (Error E = ProfileNames->create(NamesContent, NamesAddress))
     return std::move(E);
 
   auto CoverageSection = lookupSections(*OF, IPSK_covmap);
@@ -1136,6 +1182,15 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
     return CoverageMappingOrErr.takeError();
   StringRef CoverageMapping = CoverageMappingOrErr.get();
 
+  // If the coverage mapping section is not aligned to 8 bytes, copy it to a
+  // new buffer that is. Wasm format typically has unaligned section contents
+  // because it doesn't have a good way to insert padding bytes.
+  std::unique_ptr<MemoryBuffer> CoverageMappingBufferOwner;
+  if (!isAddrAligned(Align(8), CoverageMapping.data())) {
+    CoverageMappingBufferOwner = MemoryBuffer::getMemBufferCopy(CoverageMapping);
+    CoverageMapping = CoverageMappingBufferOwner->getBuffer();
+  }
+
   // Look for the coverage records section (Version4 only).
   auto CoverageRecordsSections = lookupSections(*OF, IPSK_covfun);
 
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 1c95a4606ecc56..b875f851a57e9f 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -1406,9 +1406,9 @@ static inline Constant *getFuncAddrForProfData(Function *Fn) {
 
 static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) {
   // compiler-rt uses linker support to get data/counters/name start/end for
-  // ELF, COFF, Mach-O and XCOFF.
+  // ELF, COFF, Mach-O, XCOFF, and Wasm.
   if (TT.isOSBinFormatELF() || TT.isOSBinFormatCOFF() ||
-      TT.isOSBinFormatMachO() || TT.isOSBinFormatXCOFF())
+      TT.isOSBinFormatMachO() || TT.isOSBinFormatXCOFF() || TT.isOSBinFormatWasm())
     return false;
 
   return true;
diff --git a/llvm/test/CodeGen/WebAssembly/profile.ll b/llvm/test/CodeGen/WebAssembly/profile.ll
new file mode 100644
index 00000000000000..27802cc3bf3567
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/profile.ll
@@ -0,0 +1,47 @@
+; RUN: llc < %s --filetype=obj | obj2yaml | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+$__covrec_A = comdat any
+$__covrec_B = comdat any
+
+@__covrec_A = linkonce_odr hidden constant <{ i64, i32, i64, i64, [4 x i8] }> <{
+    i64 -1978722966671112904,
+    i32 4,
+    i64 0,
+    i64 -8102528905418564625,
+    [4 x i8] c"\01\01\04\11"
+}>, section "__llvm_covfun", comdat, align 8
+@__covrec_B = linkonce_odr hidden constant <{ i64, i32, i64, i64, [4 x i8] }> <{
+    i64 8006510647218728891,
+    i32 9,
+    i64 0,
+    i64 -8102528905418564625,
+    [4 x i8] c"\01\01\00\01"
+}>, section "__llvm_covfun", comdat, align 8
+@__llvm_coverage_mapping = private constant { { i32, i32, i32, i32 }, [4 x i8] } {
+    { i32, i32, i32, i32 } { i32 0, i32 87, i32 0, i32 5 },
+    [4 x i8] c"\01\01\00\02"
+}, section "__llvm_covmap", align 8
+
+; CHECK:      - T...
[truncated]

Copy link

github-actions bot commented Oct 7, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@kateinoigakukun kateinoigakukun force-pushed the yt/wasm-coverage-upstream branch from ed504c7 to ef76026 Compare October 7, 2024 03:05
Use `InstrProfilingPlatformLinux.c` for Wasm as well as Wasm format
has encapsulation symbols (`__start_` and `__stop_`) similar to ELF.
This unlocks several additional profile features like value profiling.
…ions

This patch makes `__llvm_covmap` and `__llvm_covfun` as custom sections
in the wasm object file because they will not be referenced at runtime
but just used by `llvm-cov` post-processing tools. The same approach is
used in the ELF object file to emit them without `SHF_ALLOC` flag.

Those sections have their associated comdat group symbols, which are
section symbols (not data symbols) in the wasm object file. This patch
also sets the symbol type explicitly not to hit an assertion in the
`WasmObjectWriter::writeOneObject` ("data symbols must live in a data
section").
This patch aligns the `__llvm_{covfun,covmap}` sections to 8 bytes at
the linking stage. This is required because llvm-cov assumes that
records in the sections are 8-byte aligned. Unfortunately, custom
sections does not have an alignment attribute in the WebAssembly linking
spec, so we temporarily do a special case for the metadata sections.
In the future, we should generalize this to support alignment for
relocatable custom sections.
Wasm format does not have a good way to insert padding bytes to align
the start of a section contents because the size of each section header
depends on the size of the section contents (leb128 encoding). This
design makes it difficult to align section contents to a specific
alignment to load them by post-processing tools like llvm-cov.
This patch copies the coverage mapping section to a new buffer that is
aligned to 8 bytes if the original section is not aligned. This is
not an ideal solution but it works for now.
@kateinoigakukun kateinoigakukun force-pushed the yt/wasm-coverage-upstream branch 2 times, most recently from ca1c78b to 779d88c Compare October 7, 2024 07:59
On WebAssembly, most coverage metadata contents read by llvm-cov (like
`__llvm_covmap` and `__llvm_covfun`) are stored in custom sections
because they are not referenced at runtime. However, `__llvm_prf_names`
is referenced at runtime by the profile runtime library and is read
by llvm-cov post-processing tools, so it needs to be stored in a data
segment, which is allocatable at runtime and accessible by tools as long
as "name" section is present in the binary.

This patch changes the way llvm-cov reads `__llvm_prf_names` on
WebAssembly. Instead of looking for a section, it looks for a data
segment with the same name.
This patch teaches the WebAssembly toolchain to link with the profile
runtime libraries if profile instrumentation is requested. With this
change, the following command will work with profile rt installed:

```
$ clang -target wasm32-unknown-wasi -fprofile-instr-generate \
  -lwasi-emulated-getpid -lwasi-emulated-mman -o foo.wasm foo.c
```
compiler-rt/lib/profile/GCDAProfiling.c Outdated Show resolved Hide resolved
lld/wasm/InputChunks.h Show resolved Hide resolved
Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lld changes lgtm

lld/wasm/InputFiles.cpp Outdated Show resolved Hide resolved
@kateinoigakukun kateinoigakukun merged commit d4efc3e into llvm:main Oct 14, 2024
9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 14, 2024

LLVM Buildbot has detected a new failure on builder sanitizer-windows running on sanitizer-windows while building clang,compiler-rt,lld,llvm at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/107/builds/3945

Here is the relevant piece of the build log for the reference
Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/sanitizer-windows.py ...' (failure)
...
  Unsupported      : 233 (36.01%)
  Passed           : 401 (61.98%)
  Expectedly Failed:  13 (2.01%)

1 warning(s) in tests
[123/126] Running the profile tests
llvm-lit.py: C:\b\slave\sanitizer-windows\llvm-project\llvm\utils\lit\lit\llvm\config.py:57: note: using lit tools: C:\gnuwin32\bin
llvm-lit.py: C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\lit.common.cfg.py:60: warning: Path reported by clang does not exist: "C:\b\slave\sanitizer-windows\build\stage1\lib\clang\20\lib\x86_64-pc-windows-msvc". This path was found by running ['C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe', '--target=x86_64-pc-windows-msvc', '-print-runtime-dir'].
-- Testing: 150 tests, 16 workers --
Testing: 
FAIL: Profile-x86_64 :: instrprof-binary-correlate.c (2 of 150)
******************** TEST 'Profile-x86_64 :: instrprof-binary-correlate.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 3
C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe       -Wl,-incremental:no -o C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal -fprofile-instr-generate -fcoverage-mapping C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-main.cpp C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-foo.cpp
# executed command: C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe -Wl,-incremental:no -o 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal' -fprofile-instr-generate -fcoverage-mapping 'C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-main.cpp' 'C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-foo.cpp'
# RUN: at line 4
env LLVM_PROFILE_FILE=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw  C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal
# executed command: env 'LLVM_PROFILE_FILE=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw' 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal'
# RUN: at line 5
llvm-profdata merge -o C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw
# executed command: llvm-profdata merge -o 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata' 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw'
# RUN: at line 6
llvm-cov report --instr-profile=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal > C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.report
# executed command: llvm-cov report '--instr-profile=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata' 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal'
# .---command stderr------------
# | error: failed to load coverage: 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal': profile uses zlib compression but the profile reader was built without zlib support
# `-----------------------------
# error: command failed with exit status: 1

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80
FAIL: Profile-x86_64 :: instrprof-set-file-object.c (144 of 150)
******************** TEST 'Profile-x86_64 :: instrprof-set-file-object.c' FAILED ********************
Exit Code: 2

Command Output (stdout):
--
# RUN: at line 2
C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe       -Wl,-incremental:no  -fprofile-instr-generate -fcoverage-mapping -o C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-set-file-object.c.tmp C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile\instrprof-set-file-object.c
# executed command: C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe -Wl,-incremental:no -fprofile-instr-generate -fcoverage-mapping -o 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-set-file-object.c.tmp' 'C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile\instrprof-set-file-object.c'
# .---command stderr------------
# | C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile\instrprof-set-file-object.c:16:13: warning: 'fopen' is deprecated: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations]
# |    16 |   FILE *F = fopen(argv[1], "w+b");
Step 8 (stage 1 check) failure: stage 1 check (failure)
...
  Unsupported      : 233 (36.01%)
  Passed           : 401 (61.98%)
  Expectedly Failed:  13 (2.01%)

1 warning(s) in tests
[123/126] Running the profile tests
llvm-lit.py: C:\b\slave\sanitizer-windows\llvm-project\llvm\utils\lit\lit\llvm\config.py:57: note: using lit tools: C:\gnuwin32\bin
llvm-lit.py: C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\lit.common.cfg.py:60: warning: Path reported by clang does not exist: "C:\b\slave\sanitizer-windows\build\stage1\lib\clang\20\lib\x86_64-pc-windows-msvc". This path was found by running ['C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe', '--target=x86_64-pc-windows-msvc', '-print-runtime-dir'].
-- Testing: 150 tests, 16 workers --
Testing: 
FAIL: Profile-x86_64 :: instrprof-binary-correlate.c (2 of 150)
******************** TEST 'Profile-x86_64 :: instrprof-binary-correlate.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 3
C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe       -Wl,-incremental:no -o C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal -fprofile-instr-generate -fcoverage-mapping C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-main.cpp C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-foo.cpp
# executed command: C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe -Wl,-incremental:no -o 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal' -fprofile-instr-generate -fcoverage-mapping 'C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-main.cpp' 'C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile/Inputs/instrprof-debug-info-correlate-foo.cpp'
# RUN: at line 4
env LLVM_PROFILE_FILE=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw  C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal
# executed command: env 'LLVM_PROFILE_FILE=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw' 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal'
# RUN: at line 5
llvm-profdata merge -o C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw
# executed command: llvm-profdata merge -o 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata' 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.profraw'
# RUN: at line 6
llvm-cov report --instr-profile=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal > C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.report
# executed command: llvm-cov report '--instr-profile=C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal.profdata' 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal'
# .---command stderr------------
# | error: failed to load coverage: 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-binary-correlate.c.tmp.normal': profile uses zlib compression but the profile reader was built without zlib support
# `-----------------------------
# error: command failed with exit status: 1

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80
FAIL: Profile-x86_64 :: instrprof-set-file-object.c (144 of 150)
******************** TEST 'Profile-x86_64 :: instrprof-set-file-object.c' FAILED ********************
Exit Code: 2

Command Output (stdout):
--
# RUN: at line 2
C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe       -Wl,-incremental:no  -fprofile-instr-generate -fcoverage-mapping -o C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-set-file-object.c.tmp C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile\instrprof-set-file-object.c
# executed command: C:/b/slave/sanitizer-windows/build/stage1/./bin/clang.exe -Wl,-incremental:no -fprofile-instr-generate -fcoverage-mapping -o 'C:\b\slave\sanitizer-windows\build\stage1\projects\compiler-rt\test\profile\Profile-x86_64\Output\instrprof-set-file-object.c.tmp' 'C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile\instrprof-set-file-object.c'
# .---command stderr------------
# | C:\b\slave\sanitizer-windows\llvm-project\compiler-rt\test\profile\instrprof-set-file-object.c:16:13: warning: 'fopen' is deprecated: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations]
# |    16 |   FILE *F = fopen(argv[1], "w+b");

@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 14, 2024

LLVM Buildbot has detected a new failure on builder clang-ppc64le-rhel running on ppc64le-clang-rhel-test while building clang,compiler-rt,lld,llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/145/builds/2476

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
170.755 [21/9/6251] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/InputChunks.cpp.o
171.007 [21/8/6252] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/Symbols.cpp.o
171.090 [21/7/6253] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/OutputSections.cpp.o
171.258 [21/6/6254] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/MapFile.cpp.o
172.094 [21/5/6255] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/SymbolTable.cpp.o
174.237 [21/4/6256] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/Driver.cpp.o
174.257 [21/3/6257] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/SyntheticSections.cpp.o
174.264 [21/2/6258] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o
177.666 [21/1/6259] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/Writer.cpp.o
177.743 [20/1/6260] Linking CXX shared library lib/liblldWasm.so.20.0git
FAILED: lib/liblldWasm.so.20.0git 
: && /home/docker/llvm-external-buildbots/clang.17.0.6/bin/clang++ --gcc-toolchain=/gcc-toolchain/usr -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete -Wl,--color-diagnostics   -Wl,--gc-sections -shared -Wl,-soname,liblldWasm.so.20.0git -o lib/liblldWasm.so.20.0git tools/lld/wasm/CMakeFiles/lldWasm.dir/Driver.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/InputChunks.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/LTO.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/MapFile.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/MarkLive.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/OutputSections.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/OutputSegment.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Relocations.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/SymbolTable.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Symbols.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/SyntheticSections.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Writer.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/WriterUtils.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib:"  lib/liblldCommon.so.20.0git  lib/libLLVMAArch64CodeGen.so.20.0git  lib/libLLVMAArch64AsmParser.so.20.0git  lib/libLLVMAArch64Disassembler.so.20.0git  lib/libLLVMAMDGPUCodeGen.so.20.0git  lib/libLLVMAMDGPUAsmParser.so.20.0git  lib/libLLVMAMDGPUDisassembler.so.20.0git  lib/libLLVMARMCodeGen.so.20.0git  lib/libLLVMARMAsmParser.so.20.0git  lib/libLLVMARMDisassembler.so.20.0git  lib/libLLVMAVRCodeGen.so.20.0git  lib/libLLVMAVRAsmParser.so.20.0git  lib/libLLVMAVRDesc.so.20.0git  lib/libLLVMAVRDisassembler.so.20.0git  lib/libLLVMAVRInfo.so.20.0git  lib/libLLVMBPFCodeGen.so.20.0git  lib/libLLVMBPFAsmParser.so.20.0git  lib/libLLVMBPFDesc.so.20.0git  lib/libLLVMBPFDisassembler.so.20.0git  lib/libLLVMBPFInfo.so.20.0git  lib/libLLVMHexagonCodeGen.so.20.0git  lib/libLLVMHexagonAsmParser.so.20.0git  lib/libLLVMHexagonDisassembler.so.20.0git  lib/libLLVMLanaiCodeGen.so.20.0git  lib/libLLVMLanaiAsmParser.so.20.0git  lib/libLLVMLanaiDisassembler.so.20.0git  lib/libLLVMLoongArchCodeGen.so.20.0git  lib/libLLVMLoongArchAsmParser.so.20.0git  lib/libLLVMLoongArchDisassembler.so.20.0git  lib/libLLVMMipsCodeGen.so.20.0git  lib/libLLVMMipsAsmParser.so.20.0git  lib/libLLVMMipsDesc.so.20.0git  lib/libLLVMMipsDisassembler.so.20.0git  lib/libLLVMMipsInfo.so.20.0git  lib/libLLVMMSP430CodeGen.so.20.0git  lib/libLLVMMSP430AsmParser.so.20.0git  lib/libLLVMMSP430Desc.so.20.0git  lib/libLLVMMSP430Disassembler.so.20.0git  lib/libLLVMMSP430Info.so.20.0git  lib/libLLVMNVPTXCodeGen.so.20.0git  lib/libLLVMNVPTXDesc.so.20.0git  lib/libLLVMNVPTXInfo.so.20.0git  lib/libLLVMPowerPCCodeGen.so.20.0git  lib/libLLVMPowerPCAsmParser.so.20.0git  lib/libLLVMPowerPCDesc.so.20.0git  lib/libLLVMPowerPCDisassembler.so.20.0git  lib/libLLVMPowerPCInfo.so.20.0git  lib/libLLVMRISCVCodeGen.so.20.0git  lib/libLLVMRISCVAsmParser.so.20.0git  lib/libLLVMRISCVDisassembler.so.20.0git  lib/libLLVMSparcCodeGen.so.20.0git  lib/libLLVMSparcAsmParser.so.20.0git  lib/libLLVMSparcDesc.so.20.0git  lib/libLLVMSparcDisassembler.so.20.0git  lib/libLLVMSparcInfo.so.20.0git  lib/libLLVMSystemZCodeGen.so.20.0git  lib/libLLVMSystemZAsmParser.so.20.0git  lib/libLLVMSystemZDisassembler.so.20.0git  lib/libLLVMVECodeGen.so.20.0git  lib/libLLVMVEAsmParser.so.20.0git  lib/libLLVMVEDesc.so.20.0git  lib/libLLVMVEDisassembler.so.20.0git  lib/libLLV
/libLLVMWebAssemblyDisassembler.so.20.0git  lib/libLLVMWebAssemblyUtils.so.20.0git  lib/libLLVMX86CodeGen.so.20.0git  lib/libLLVMX86AsmParser.so.20.0git  lib/libLLVMX86Desc.so.20.0git  lib/libLLVMX86Disassembler.so.20.0git  lib/libLLVMX86Info.so.20.0git  lib/libLLVMXCoreCodeGen.so.20.0git  lib/libLLVMXCoreDesc.so.20.0git  lib/libLLVMXCoreDisassembler.so.20.0git  lib/libLLVMXCoreInfo.so.20.0git  lib/libLLVMLTO.so.20.0git  lib/libLLVMOption.so.20.0git  lib/libLLVMPasses.so.20.0git  lib/libLLVMAArch64Desc.so.20.0git  lib/libLLVMAArch64Info.so.20.0git  lib/libLLVMAArch64Utils.so.20.0git  lib/libLLVMAMDGPUDesc.so.20.0git  lib/libLLVMAMDGPUInfo.so.20.0git  lib/libLLVMAMDGPUUtils.so.20.0git  lib/libLLVMARMDesc.so.20.0git  lib/libLLVMARMInfo.so.20.0git  lib/libLLVMARMUtils.so.20.0git  lib/libLLVMHexagonDesc.so.20.0git  lib/libLLVMHexagonInfo.so.20.0git  lib/libLLVMLanaiDesc.so.20.0git  lib/libLLVMLanaiInfo.so.20.0git  lib/libLLVMLoongArchDesc.so.20.0git  lib/libLLVMLoongArchInfo.so.20.0git  lib/libLLVMRISCVDesc.so.20.0git  lib/libLLVMRISCVInfo.so.20.0git  lib/libLLVMSystemZDesc.so.20.0git  lib/libLLVMSystemZInfo.so.20.0git  lib/libLLVMWebAssemblyDesc.so.20.0git  lib/libLLVMWebAssemblyInfo.so.20.0git  lib/libLLVMObject.so.20.0git  lib/libLLVMMC.so.20.0git  lib/libLLVMCore.so.20.0git  lib/libLLVMBinaryFormat.so.20.0git  lib/libLLVMTargetParser.so.20.0git  lib/libLLVMSupport.so.20.0git  lib/libLLVMDemangle.so.20.0git  -Wl,-rpath-link,/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/lib && :
ld.lld: error: undefined symbol: llvm::getInstrProfSectionName[abi:cxx11](llvm::InstrProfSectKind, llvm::Triple::ObjectFormatType, bool)
>>> referenced by InputFiles.cpp
>>>               tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o:(lld::wasm::ObjFile::parse(bool))
>>> referenced by InputFiles.cpp
>>>               tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o:(lld::wasm::ObjFile::parse(bool))
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 14, 2024

LLVM Buildbot has detected a new failure on builder bolt-x86_64-ubuntu-shared running on bolt-worker while building clang,compiler-rt,lld,llvm at step 6 "test-build-bolt-check-bolt".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/151/builds/2770

Here is the relevant piece of the build log for the reference
Step 6 (test-build-bolt-check-bolt) failure: test (failure)
...
14.139 [366/18/1225] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/ToolChains/PPCLinux.cpp.o
14.143 [365/18/1226] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/ToolChains/InterfaceStubs.cpp.o
14.159 [364/18/1227] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/ASTConsumers.cpp.o
14.159 [363/18/1228] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/ToolChains/ZOS.cpp.o
14.177 [362/18/1229] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/ToolChains/PPCFreeBSD.cpp.o
14.181 [361/18/1230] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/Types.cpp.o
14.203 [360/18/1231] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/Writer.cpp.o
14.208 [359/18/1232] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/XRayArgs.cpp.o
14.216 [358/18/1233] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/DiagnosticRenderer.cpp.o
14.264 [357/18/1234] Linking CXX shared library lib/liblldWasm.so.20.0git
FAILED: lib/liblldWasm.so.20.0git 
: && /usr/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete -fuse-ld=lld -Wl,--color-diagnostics   -Wl,--gc-sections -shared -Wl,-soname,liblldWasm.so.20.0git -o lib/liblldWasm.so.20.0git tools/lld/wasm/CMakeFiles/lldWasm.dir/Driver.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/InputChunks.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/LTO.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/MapFile.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/MarkLive.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/OutputSections.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/OutputSegment.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Relocations.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/SymbolTable.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Symbols.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/SyntheticSections.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Writer.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/WriterUtils.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:/home/worker/bolt-worker2/bolt-x86_64-ubuntu-shared/build/lib:"  lib/liblldCommon.so.20.0git  lib/libLLVMX86CodeGen.so.20.0git  lib/libLLVMX86AsmParser.so.20.0git  lib/libLLVMX86Desc.so.20.0git  lib/libLLVMX86Disassembler.so.20.0git  lib/libLLVMX86Info.so.20.0git  lib/libLLVMAArch64CodeGen.so.20.0git  lib/libLLVMAArch64AsmParser.so.20.0git  lib/libLLVMAArch64Disassembler.so.20.0git  lib/libLLVMRISCVCodeGen.so.20.0git  lib/libLLVMRISCVAsmParser.so.20.0git  lib/libLLVMRISCVDisassembler.so.20.0git  lib/libLLVMLTO.so.20.0git  lib/libLLVMOption.so.20.0git  lib/libLLVMPasses.so.20.0git  lib/libLLVMAArch64Desc.so.20.0git  lib/libLLVMAArch64Info.so.20.0git  lib/libLLVMAArch64Utils.so.20.0git  lib/libLLVMRISCVDesc.so.20.0git  lib/libLLVMRISCVInfo.so.20.0git  lib/libLLVMObject.so.20.0git  lib/libLLVMMC.so.20.0git  lib/libLLVMCore.so.20.0git  lib/libLLVMBinaryFormat.so.20.0git  lib/libLLVMTargetParser.so.20.0git  lib/libLLVMSupport.so.20.0git  lib/libLLVMDemangle.so.20.0git  -Wl,-rpath-link,/home/worker/bolt-worker2/bolt-x86_64-ubuntu-shared/build/lib && :
ld.lld: error: undefined symbol: llvm::getInstrProfSectionName[abi:cxx11](llvm::InstrProfSectKind, llvm::Triple::ObjectFormatType, bool)
>>> referenced by InputFiles.cpp
>>>               tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o:(lld::wasm::ObjFile::parse(bool))
>>> referenced by InputFiles.cpp
>>>               tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o:(lld::wasm::ObjFile::parse(bool))
collect2: error: ld returned 1 exit status
14.415 [357/17/1235] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/DependencyGraph.cpp.o
14.539 [357/16/1236] Building CXX object tools/clang/lib/Serialization/CMakeFiles/obj.clangSerialization.dir/GeneratePCH.cpp.o
14.586 [357/15/1237] Building CXX object tools/clang/lib/Serialization/CMakeFiles/obj.clangSerialization.dir/ASTReader.cpp.o
14.640 [357/14/1238] Building CXX object tools/clang/lib/Serialization/CMakeFiles/obj.clangSerialization.dir/ASTWriter.cpp.o
14.642 [357/13/1239] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/ASTMerge.cpp.o
14.647 [357/12/1240] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/DependencyFile.cpp.o
14.655 [357/11/1241] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/ChainedIncludesSource.cpp.o
14.658 [357/10/1242] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/ASTUnit.cpp.o
14.672 [357/9/1243] Building CXX object tools/clang/tools/driver/CMakeFiles/clang.dir/cc1_main.cpp.o
14.691 [357/8/1244] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CreateInvocationFromCommandLine.cpp.o
14.741 [357/7/1245] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CompilerInstance.cpp.o
14.775 [357/6/1246] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/FrontendAction.cpp.o
14.796 [357/5/1247] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/FrontendActions.cpp.o
16.296 [357/4/1248] Building CXX object tools/clang/lib/Frontend/CMakeFiles/obj.clangFrontend.dir/CompilerInvocation.cpp.o
16.699 [357/3/1249] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/ToolChains/WebAssembly.cpp.o
16.759 [357/2/1250] Building CXX object tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/ToolChains/HIPUtility.cpp.o
24.950 [357/1/1251] Building CXX object tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CoverageMappingGen.cpp.o
ninja: build stopped: subcommand failed.

@glandium
Copy link
Contributor

I bisected a bustage building clang with PGO on Windows to this change. While building clang with a profile-generate-enabled build of clang to gather a profile, the compiler crashes with:

PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Exception Code: 0xC0000005
 #0 0x00007ff6786ac4b7 llvm::object::COFFObjectFile::getFeatures(void) const (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x43ac4b7)
 #1 0x00007ff6786ac2c4 llvm::object::COFFObjectFile::getFeatures(void) const (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x43ac2c4)
 #2 0x00007ff675f61b78 llvm::object::isNotObjectErrorInvalidFileType(class llvm::Error) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x1c61b78)
 #3 0x00007ff675f619cf llvm::object::isNotObjectErrorInvalidFileType(class llvm::Error) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x1c619cf)
 #4 0x00007ff67b9451d5 clang::tooling::parseIWYUPragma(char const *) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x76451d5)
 #5 0x00007ff67b9452c1 clang::tooling::parseIWYUPragma(char const *) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x76452c1)
 #6 0x00007ff67b944f79 clang::tooling::parseIWYUPragma(char const *) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x7644f79)
 #7 0x00007ff67b942979 clang::tooling::parseIWYUPragma(char const *) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x7642979)
 #8 0x00007ff67b9429f1 clang::tooling::parseIWYUPragma(char const *) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x76429f1)
 #9 0x00007ff67b9428e3 clang::tooling::parseIWYUPragma(char const *) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x76428e3)
#10 0x00007ff67b93227b clang::tooling::parseIWYUPragma(char const *) (D:\task_172897772250463\fetches\clang\bin\clang-cl.EXE+0x763227b)
#11 0x00007ffc74784cb0 (C:\Windows\System32\KERNEL32.DLL+0x14cb0)
#12 0x00007ffc7517ecdb (C:\Windows\SYSTEM32\ntdll.dll+0x7ecdb)

In the rare case where it doesn't crash, after the successful build, llvm-profdata merge fails with

D:\task_172895232291267\fetches\llvm-project/build/profiles\15750880694198762592_0.profraw: ??$_Emplace_reallocate@V?$unique_ptr@VSymbolicFile@object@llvm@@U?$default_delete@VSymbolicFile@object@llvm@@@std@@@std@@@?$vector@V?$unique_ptr@VSymbolicFile@object@llvm@@U?$default_delete@VSymbolicFile@object@llvm@@@std@@@std@@V?$allocator@V?$unique_ptr@VSymbolicFile@object@llvm@@U?$default_delete@VSymbolicFile@object@llvm@@@std@@@std@@@2@@std@@AEAAPEAV?$unique_ptr@VSymbolicFile@object@llvm@@U?$default_delete@VSymbolicFile@object@llvm@@@std@@@1@QEAV21@$$QEAV21@@Z: function value site count change detected (counter mismatch)
Make sure that all profile data to be merged is generated from the same binary. 
warning: D:\task_172895232291267\fetches\llvm-project/build/profiles\10821587162318259349_0.profraw: malformed instrumentation profile data: total size is not multiples of quardword
error: no profile can be merged 

@kateinoigakukun
Copy link
Member Author

@glandium Thank you for sharing. I'm trying to reproduce the issue on my side.

@kateinoigakukun
Copy link
Member Author

@glandium Would you mind sharing CMake configuration? or is there any CI with that setup?

@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 15, 2024

LLVM Buildbot has detected a new failure on builder bolt-aarch64-ubuntu-clang-shared running on bolt-worker-aarch64 while building clang,compiler-rt,lld,llvm at step 8 "test-build-bolt-check-bolt".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/126/builds/809

Here is the relevant piece of the build log for the reference
Step 8 (test-build-bolt-check-bolt) failure: test (failure)
...
55.081 [644/6/959] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaLoongArch.cpp.o
55.082 [643/6/960] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaInit.cpp.o
55.115 [642/6/961] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaMSP430.cpp.o
55.122 [641/6/962] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaM68k.cpp.o
55.134 [640/6/963] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaMIPS.cpp.o
55.198 [639/6/964] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaNVPTX.cpp.o
55.241 [638/6/965] Building CXX object tools/lld/wasm/CMakeFiles/lldWasm.dir/Writer.cpp.o
55.295 [637/6/966] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenACC.cpp.o
55.416 [636/6/967] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenCL.cpp.o
55.430 [635/6/968] Linking CXX shared library lib/liblldWasm.so.20.0git
FAILED: lib/liblldWasm.so.20.0git 
: && /usr/bin/clang++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete -fuse-ld=mold -Wl,--color-diagnostics   -Wl,--gc-sections -shared -Wl,-soname,liblldWasm.so.20.0git -o lib/liblldWasm.so.20.0git tools/lld/wasm/CMakeFiles/lldWasm.dir/Driver.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/InputChunks.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/LTO.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/MapFile.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/MarkLive.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/OutputSections.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/OutputSegment.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Relocations.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/SymbolTable.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Symbols.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/SyntheticSections.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/Writer.cpp.o tools/lld/wasm/CMakeFiles/lldWasm.dir/WriterUtils.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:/home/worker/buildbot-aarch64/bolt-aarch64-ubuntu-clang-shared/build/lib:"  lib/liblldCommon.so.20.0git  lib/libLLVMX86CodeGen.so.20.0git  lib/libLLVMX86AsmParser.so.20.0git  lib/libLLVMX86Desc.so.20.0git  lib/libLLVMX86Disassembler.so.20.0git  lib/libLLVMX86Info.so.20.0git  lib/libLLVMAArch64CodeGen.so.20.0git  lib/libLLVMAArch64AsmParser.so.20.0git  lib/libLLVMAArch64Disassembler.so.20.0git  lib/libLLVMRISCVCodeGen.so.20.0git  lib/libLLVMRISCVAsmParser.so.20.0git  lib/libLLVMRISCVDisassembler.so.20.0git  lib/libLLVMLTO.so.20.0git  lib/libLLVMOption.so.20.0git  lib/libLLVMPasses.so.20.0git  lib/libLLVMAArch64Desc.so.20.0git  lib/libLLVMAArch64Info.so.20.0git  lib/libLLVMAArch64Utils.so.20.0git  lib/libLLVMRISCVDesc.so.20.0git  lib/libLLVMRISCVInfo.so.20.0git  lib/libLLVMObject.so.20.0git  lib/libLLVMMC.so.20.0git  lib/libLLVMCore.so.20.0git  lib/libLLVMBinaryFormat.so.20.0git  lib/libLLVMTargetParser.so.20.0git  lib/libLLVMSupport.so.20.0git  lib/libLLVMDemangle.so.20.0git  -Wl,-rpath-link,/home/worker/buildbot-aarch64/bolt-aarch64-ubuntu-clang-shared/build/lib && :
mold: error: undefined symbol: llvm::getInstrProfSectionName[abi:cxx11](llvm::InstrProfSectKind, llvm::Triple::ObjectFormatType, bool)
>>> referenced by InputFiles.cpp
>>>               tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o:(lld::wasm::ObjFile::parse(bool))>>> referenced by InputFiles.cpp
>>>               tools/lld/wasm/CMakeFiles/lldWasm.dir/InputFiles.cpp.o:(lld::wasm::ObjFile::parse(bool))
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
55.544 [635/5/969] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaLookup.cpp.o
55.631 [635/4/970] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaModule.cpp.o
55.696 [635/3/971] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaObjC.cpp.o
55.705 [635/2/972] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaObjCProperty.cpp.o
56.118 [635/1/973] Building CXX object tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/SemaOpenMP.cpp.o
ninja: build stopped: subcommand failed.

@glandium
Copy link
Contributor

@glandium Would you mind sharing CMake configuration? or is there any CI with that setup?

These are the relevant cmake commands from our CI:
The following configures the profile-generate build:

cmake -GNinja -DCMAKE_C_COMPILER=D:/task_172902843210201/fetches/clang/bin/clang-cl.EXE -DCMAKE_CXX_COMPILER=D:/task_172902843210201/fetches/clang/bin/clang-cl.EXE -DCMAKE_ASM_COMPILER=D:/task_172902843210201/fetches/clang/bin/clang-cl.EXE -DCMAKE_AR=D:/task_172902843210201/fetches/clang/bin/llvm-lib.EXE -DCMAKE_C_FLAGS_INIT=-fms-compatibility-version=19.27 -DCMAKE_CXX_FLAGS_INIT=-fms-compatibility-version=19.27 -DCMAKE_ASM_FLAGS_INIT= -DCMAKE_EXE_LINKER_FLAGS_INIT= -DCMAKE_SHARED_LINKER_FLAGS_INIT= -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=D:\task_172902843210201\fetches\llvm-project/build/stage2/clang -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF -DLLVM_ENABLE_ASSERTIONS=OFF -DLLVM_ENABLE_BINDINGS=OFF -DLLVM_ENABLE_CURL=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_LLD=ON -DCLANG_REPOSITORY_STRING=taskcluster-GmCYuF0pTCePTggmh_Mtlw -DLLVM_TOOL_LLI_BUILD=OFF -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DLLVM_ENABLE_PROJECTS=clang;lld -DLLVM_BUILD_INSTRUMENTED=IR -DLLVM_BUILD_RUNTIME=No D:\task_172902843210201\fetches\llvm-project/llvm

The following configures the build that fails, using the clang built with the above configuration:

cmake -GNinja -DCMAKE_C_COMPILER=D:/task_172902843210201/fetches/llvm-project/build/stage2/clang/bin/clang-cl.exe -DCMAKE_CXX_COMPILER=D:/task_172902843210201/fetches/llvm-project/build/stage2/clang/bin/clang-cl.exe -DCMAKE_ASM_COMPILER=D:/task_172902843210201/fetches/llvm-project/build/stage2/clang/bin/clang-cl.exe -DCMAKE_AR=D:/task_172902843210201/fetches/clang/bin/llvm-lib.EXE -DCMAKE_C_FLAGS_INIT=-fms-compatibility-version=19.27 -DCMAKE_CXX_FLAGS_INIT=-fms-compatibility-version=19.27 -DCMAKE_ASM_FLAGS_INIT= -DCMAKE_EXE_LINKER_FLAGS_INIT= -DCMAKE_SHARED_LINKER_FLAGS_INIT= -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=D:\task_172902843210201\fetches\llvm-project/build/stage3/clang -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF -DLLVM_ENABLE_ASSERTIONS=OFF -DLLVM_ENABLE_BINDINGS=OFF -DLLVM_ENABLE_CURL=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_LLD=ON -DCLANG_REPOSITORY_STRING=taskcluster-GmCYuF0pTCePTggmh_Mtlw -DLLVM_ENABLE_PROJECTS=clang;lld;clang-tools-extra -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DLLVM_ENABLE_LIBXML2=FORCE_ON -DLIBXML2_DEFINITIONS=-DLIBXML_STATIC -DLIBXML2_INCLUDE_DIR=D:/task_172902843210201/fetches/libxml2/include/libxml2 -DLIBXML2_LIBRARIES=D:/task_172902843210201/fetches/libxml2/lib/libxml2s.lib D:\task_172902843210201\fetches\llvm-project/llvm

@mstorsjo
Copy link
Member

I also bisected errors on Windows, down to this commit.

The errors show up when running the compiler-rt testsuite, like this: https://github.com/mstorsjo/llvm-mingw/actions/runs/11356888872/job/31598676534
A number of tests fail, where llvm-cov errors out with profile uses zlib compression but the profile reader was built without zlib support.

This can be reproduced with something as small as llvm-cov show coverage_comments.cpp.exe -instr-profile coverage_comments.cpp.tmp.profdata. Binaries of llvm-cov from before this change work fine, while binaries from after it produce this error.

@mstorsjo
Copy link
Member

I also bisected errors on Windows, down to this commit.

The errors show up when running the compiler-rt testsuite, like this: https://github.com/mstorsjo/llvm-mingw/actions/runs/11356888872/job/31598676534 A number of tests fail, where llvm-cov errors out with profile uses zlib compression but the profile reader was built without zlib support.

This can be reproduced with something as small as llvm-cov show coverage_comments.cpp.exe -instr-profile coverage_comments.cpp.tmp.profdata. Binaries of llvm-cov from before this change work fine, while binaries from after it produce this error.

This issue can be reproduced with a few prebuilt files: https://martin.st/temp/profile/

Download those three files, build llvm-cov (on Linux or anywhere), and execute this:

$ llvm-cov show coverage_comments.cpp.exe -instr-profile coverage_comments.cpp.tmp.profdata

Before this breaking change, you'll get this:

error: C:/path/to/llvm-project/compiler-rt/test/profile/coverage_comments.cpp: No such file or directory
warning: The file 'C:/path/to/llvm-project/compiler-rt/test/profile/coverage_comments.cpp' isn't covered.

After this change, you instead get this:

error: failed to load coverage: 'coverage_comments.cpp.exe': failed to uncompress data (zlib)

Can someone revert this change to get things back into working order?

@kateinoigakukun
Copy link
Member Author

kateinoigakukun commented Oct 16, 2024

@mstorsjo Thank you for your detail report and sorry for your inconvenience. I opened a PR to revert the root cause: #112520

kateinoigakukun added a commit that referenced this pull request Oct 16, 2024
…ments" (#112520)

This reverts commit efc9dd4 in order to
fix Windows test failure:
#111332 (comment)
DanielCChen pushed a commit to DanielCChen/llvm-project that referenced this pull request Oct 16, 2024
…m#111332)

Currently, WebAssembly/WASI target does not provide direct support for
code coverage.
This patch set fixes several issues to unlock the feature. The main
changes are:

1. Port `compiler-rt/lib/profile` to WebAssembly/WASI.
2. Adjust profile metadata sections for Wasm object file format.
- [CodeGen] Emit `__llvm_covmap` and `__llvm_covfun` as custom sections
instead of data segments.
    - [lld] Align the interval space of custom sections at link time.
- [llvm-cov] Copy misaligned custom section data if the start address is
not aligned.
    - [llvm-cov] Read `__llvm_prf_names` from data segments
3. [clang] Link with profile runtime libraries if requested

See each commit message for more details and rationale.
This is part of the effort to add code coverage support in Wasm target
of Swift toolchain.
bricknerb pushed a commit to bricknerb/llvm-project that referenced this pull request Oct 17, 2024
…m#111332)

Currently, WebAssembly/WASI target does not provide direct support for
code coverage.
This patch set fixes several issues to unlock the feature. The main
changes are:

1. Port `compiler-rt/lib/profile` to WebAssembly/WASI.
2. Adjust profile metadata sections for Wasm object file format.
- [CodeGen] Emit `__llvm_covmap` and `__llvm_covfun` as custom sections
instead of data segments.
    - [lld] Align the interval space of custom sections at link time.
- [llvm-cov] Copy misaligned custom section data if the start address is
not aligned.
    - [llvm-cov] Read `__llvm_prf_names` from data segments
3. [clang] Link with profile runtime libraries if requested

See each commit message for more details and rationale.
This is part of the effort to add code coverage support in Wasm target
of Swift toolchain.
bricknerb pushed a commit to bricknerb/llvm-project that referenced this pull request Oct 17, 2024
@ZequanWu
Copy link
Contributor

ZequanWu commented Oct 21, 2024

Hi. this change caused chromium windows pgo build to fail: https://issues.chromium.org/issues/373478548 and we see the profile runtime error message:

LLVM Profile Error: Invalid profile data to merge
LLVM Profile Error: Profile Merging of file default_16487515506031793746_0.profraw failed: File exists
LLVM Profile Error: Failed to write file "default_16487515506031793746_0.profraw": File exists

Looks like profile writing race condition. Though this change touched compiler-rt/lib/profile/InstrProfilingUtil.c, I don't see how this will affect windows.

@aeubanks
Copy link
Contributor

perhaps the flock cmake check doesn't work on windows for some reason? maybe wrong include?

@ZequanWu
Copy link
Contributor

ZequanWu commented Oct 21, 2024

Oh, I see, there are windows version of flock in WindowsMMap.h, and this new macro COMPILER_RT_HAS_FLOCK is defined here: https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/profile/CMakeLists.txt#L41-L50

@ZequanWu
Copy link
Contributor

Given there's already an implementation of flock in compiler-rt/lib/profile/WindowsMMap.c. Setting COMPILER_RT_TARGET_HAS_FLOCK according to this

CHECK_CXX_SOURCE_COMPILES("
#include <sys/file.h>
int fd;
int main() {
flock(fd, LOCK_EX);
return 0;
}
" COMPILER_RT_TARGET_HAS_FLOCK)
doesn't look right to me.

@mstorsjo
Copy link
Member

Hi. this change caused chromium windows pgo build to fail: https://issues.chromium.org/issues/373478548 and we see the profile runtime error message:

LLVM Profile Error: Invalid profile data to merge
LLVM Profile Error: Profile Merging of file default_16487515506031793746_0.profraw failed: File exists
LLVM Profile Error: Failed to write file "default_16487515506031793746_0.profraw": File exists

Looks like profile writing race condition. Though this change touched compiler-rt/lib/profile/InstrProfilingUtil.c, I don't see how this will affect windows.

I would expect that #112695 fixes that issue.

EricWF pushed a commit to efcs/llvm-project that referenced this pull request Oct 22, 2024
…m#111332)

Currently, WebAssembly/WASI target does not provide direct support for
code coverage.
This patch set fixes several issues to unlock the feature. The main
changes are:

1. Port `compiler-rt/lib/profile` to WebAssembly/WASI.
2. Adjust profile metadata sections for Wasm object file format.
- [CodeGen] Emit `__llvm_covmap` and `__llvm_covfun` as custom sections
instead of data segments.
    - [lld] Align the interval space of custom sections at link time.
- [llvm-cov] Copy misaligned custom section data if the start address is
not aligned.
    - [llvm-cov] Read `__llvm_prf_names` from data segments
3. [clang] Link with profile runtime libraries if requested

See each commit message for more details and rationale.
This is part of the effort to add code coverage support in Wasm target
of Swift toolchain.
EricWF pushed a commit to efcs/llvm-project that referenced this pull request Oct 22, 2024
kateinoigakukun added a commit to kateinoigakukun/llvm-project that referenced this pull request Oct 24, 2024
…m#111332)

Currently, WebAssembly/WASI target does not provide direct support for
code coverage.
This patch set fixes several issues to unlock the feature. The main
changes are:

1. Port `compiler-rt/lib/profile` to WebAssembly/WASI.
2. Adjust profile metadata sections for Wasm object file format.
- [CodeGen] Emit `__llvm_covmap` and `__llvm_covfun` as custom sections
instead of data segments.
    - [lld] Align the interval space of custom sections at link time.
- [llvm-cov] Copy misaligned custom section data if the start address is
not aligned.
    - [llvm-cov] Read `__llvm_prf_names` from data segments
3. [clang] Link with profile runtime libraries if requested

See each commit message for more details and rationale.
This is part of the effort to add code coverage support in Wasm target
of Swift toolchain.
kateinoigakukun added a commit to kateinoigakukun/llvm-project that referenced this pull request Oct 24, 2024
…ments" (llvm#112520)

This reverts commit efc9dd4 in order to
fix Windows test failure:
llvm#111332 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:WebAssembly clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category compiler-rt lld:wasm lld llvm:transforms mc Machine (object) code PGO Profile Guided Optimizations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants