[llvm] 3e230d1 - Revert "[WebAssembly] Refactor and fix emission of external IR global decls"

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 31 12:21:09 PST 2022


Author: Sam Clegg
Date: 2022-01-31T12:20:56-08:00
New Revision: 3e230d15eba5e565988695788f71dd2e24f79015

URL: https://github.com/llvm/llvm-project/commit/3e230d15eba5e565988695788f71dd2e24f79015
DIFF: https://github.com/llvm/llvm-project/commit/3e230d15eba5e565988695788f71dd2e24f79015.diff

LOG: Revert "[WebAssembly] Refactor and fix emission of external IR global decls"

This reverts commit 00bf4755e90c89963a135739218ef49c2417109f.

This change broke the emscripten builder (among other things):

https://ci.chromium.org/ui/p/emscripten-releases/builders/try/linux/b8823500584349280721/overview

Sample failure:

```
test_unistd_unlink (test_core.core0) ...
wasm-ld: error: symbol type mismatch: __stdio_write
>>> defined as WASM_SYMBOL_TYPE_FUNCTION in /usr/local/google/home/sbc/dev/wasm/emscripten/cache/sysroot/lib/wasm32-emscripten/libc-debug.a(__stdio_write.o)
>>> defined as WASM_SYMBOL_TYPE_DATA in /usr/local/google/home/sbc/dev/wasm/emscripten/cache/sysroot/lib/wasm32-emscripten/libc-debug.a(stderr.o)
```

Added: 
    

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
    llvm/lib/Target/WebAssembly/WebAssemblyMCLowerPrePass.cpp
    llvm/test/CodeGen/WebAssembly/externref-tableget.ll
    llvm/test/CodeGen/WebAssembly/externref-tableset.ll
    llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
    llvm/test/CodeGen/WebAssembly/funcref-tableget.ll
    llvm/test/CodeGen/WebAssembly/funcref-tableset.ll
    llvm/test/CodeGen/WebAssembly/global-get.ll
    llvm/test/CodeGen/WebAssembly/global-set.ll
    llvm/test/MC/WebAssembly/assembler-binary.ll
    llvm/test/MC/WebAssembly/stack-ptr-mclower.ll

Removed: 
    llvm/test/CodeGen/WebAssembly/table-types.ll


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 589e3a1aad293..bf326e5106be4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -188,11 +188,18 @@ void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
     WebAssembly::wasmSymbolSetType(Sym, GlobalVT, VTs);
   }
 
+  // If the GlobalVariable refers to a table, we handle it here instead of
+  // in emitExternalDecls
+  if (Sym->isTable()) {
+    getTargetStreamer()->emitTableType(Sym);
+    return;
+  }
+
   emitVisibility(Sym, GV->getVisibility(), !GV->isDeclaration());
-  emitSymbolType(Sym);
   if (GV->hasInitializer()) {
     assert(getSymbolPreferLocal(*GV) == Sym);
     emitLinkage(GV, Sym);
+    getTargetStreamer()->emitGlobalType(Sym);
     OutStreamer->emitLabel(Sym);
     // TODO: Actually emit the initializer value.  Otherwise the global has the
     // default value for its type (0, ref.null, etc).
@@ -264,47 +271,31 @@ MCSymbol *WebAssemblyAsmPrinter::getOrCreateWasmSymbol(StringRef Name) {
   return WasmSym;
 }
 
-void WebAssemblyAsmPrinter::emitSymbolType(const MCSymbolWasm *Sym) {
-  Optional<wasm::WasmSymbolType> WasmTy = Sym->getType();
-  if (!WasmTy)
-    return;
-
-  switch (WasmTy.getValue()) {
-  case wasm::WASM_SYMBOL_TYPE_GLOBAL:
-    getTargetStreamer()->emitGlobalType(Sym);
-    break;
-  case wasm::WASM_SYMBOL_TYPE_TAG:
-    getTargetStreamer()->emitTagType(Sym);
-    break;
-  case wasm::WASM_SYMBOL_TYPE_TABLE:
-    getTargetStreamer()->emitTableType(Sym);
-    break;
-  default:
-    break; // We only handle globals, tags and tables here
-  }
-}
-
 void WebAssemblyAsmPrinter::emitExternalDecls(const Module &M) {
   if (signaturesEmitted)
     return;
   signaturesEmitted = true;
 
   // Normally symbols for globals get discovered as the MI gets lowered,
-  // but we need to know about them ahead of time. This will however,
-  // only find symbols that have been used. Unused symbols from globals will
-  // not be found here.
+  // but we need to know about them ahead of time.
   MachineModuleInfoWasm &MMIW = MMI->getObjFileInfo<MachineModuleInfoWasm>();
   for (const auto &Name : MMIW.MachineSymbolsUsed) {
     getOrCreateWasmSymbol(Name.getKey());
   }
 
   for (auto &It : OutContext.getSymbols()) {
-    // Emit .globaltype, .tagtype, or .tabletype declarations for extern
-    // declarations, i.e. those that have only been declared (but not defined)
-    // in the current module
+    // Emit .globaltype, .tagtype, or .tabletype declarations.
     auto Sym = cast<MCSymbolWasm>(It.getValue());
-    if (!Sym->isDefined())
-      emitSymbolType(Sym);
+    if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
+      // .globaltype already handled by emitGlobalVariable for defined
+      // variables; here we make sure the types of external wasm globals get
+      // written to the file.
+      if (Sym->isUndefined())
+        getTargetStreamer()->emitGlobalType(Sym);
+    } else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_TAG)
+      getTargetStreamer()->emitTagType(Sym);
+    else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_TABLE)
+      getTargetStreamer()->emitTableType(Sym);
   }
 
   DenseSet<MCSymbol *> InvokeSymbols;
@@ -371,8 +362,10 @@ void WebAssemblyAsmPrinter::emitExternalDecls(const Module &M) {
     }
   }
 }
-
+  
 void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
+  emitExternalDecls(M);
+
   // When a function's address is taken, a TABLE_INDEX relocation is emitted
   // against the function symbol at the use site.  However the relocation
   // doesn't explicitly refer to the table.  In the future we may want to
@@ -539,8 +532,6 @@ void WebAssemblyAsmPrinter::EmitTargetFeatures(Module &M) {
 }
 
 void WebAssemblyAsmPrinter::emitConstantPool() {
-  const Module *M = MMI->getModule();
-  emitExternalDecls(*M);
   assert(MF->getConstantPool()->getConstants().empty() &&
          "WebAssembly disables constant pools");
 }
@@ -549,6 +540,17 @@ void WebAssemblyAsmPrinter::emitJumpTableInfo() {
   // Nothing to do; jump tables are incorporated into the instruction stream.
 }
 
+void WebAssemblyAsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *Sym)
+  const {
+  AsmPrinter::emitLinkage(GV, Sym);
+  // This gets called before the function label and type are emitted.
+  // We use it to emit signatures of external functions.
+  // FIXME casts!
+  const_cast<WebAssemblyAsmPrinter *>(this)
+    ->emitExternalDecls(*MMI->getModule());
+}
+
+
 void WebAssemblyAsmPrinter::emitFunctionBodyStart() {
   const Function &F = MF->getFunction();
   SmallVector<MVT, 1> ResultVTs;

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
index fd15c8d793db7..6b2f2000a0bd9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
@@ -66,10 +66,10 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter {
   void emitEndOfAsmFile(Module &M) override;
   void EmitProducerInfo(Module &M);
   void EmitTargetFeatures(Module &M);
-  void emitSymbolType(const MCSymbolWasm *Sym);
   void emitGlobalVariable(const GlobalVariable *GV) override;
   void emitJumpTableInfo() override;
   void emitConstantPool() override;
+  void emitLinkage(const GlobalValue *, MCSymbol *) const override;
   void emitFunctionBodyStart() override;
   void emitInstruction(const MachineInstr *MI) override;
   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCLowerPrePass.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCLowerPrePass.cpp
index 21f6fd37d4026..37ac8e75f4b79 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCLowerPrePass.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCLowerPrePass.cpp
@@ -65,9 +65,6 @@ ModulePass *llvm::createWebAssemblyMCLowerPrePass() {
 // for all functions before AsmPrinter. If this way of doing things is ever
 // suboptimal, we could opt to make it a MachineFunctionPass and instead use
 // something like createBarrierNoopPass() to enforce ordering.
-//
-// The information stored here is essential for emitExternalDecls in the Wasm
-// AsmPrinter
 bool WebAssemblyMCLowerPrePass::runOnModule(Module &M) {
   auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
   if (!MMIWP)

diff  --git a/llvm/test/CodeGen/WebAssembly/externref-tableget.ll b/llvm/test/CodeGen/WebAssembly/externref-tableget.ll
index 655cbdf9a4730..1161b6e3659ac 100644
--- a/llvm/test/CodeGen/WebAssembly/externref-tableget.ll
+++ b/llvm/test/CodeGen/WebAssembly/externref-tableget.ll
@@ -73,5 +73,4 @@ define %externref @get_externref_from_table_with_var_offset2(i32 %i) {
   ret %externref %ref
 }
 
-; CHECK:       .tabletype externref_table, externref
-; CHECK-LABEL: externref_table:
+; CHECK: .tabletype externref_table, externref

diff  --git a/llvm/test/CodeGen/WebAssembly/externref-tableset.ll b/llvm/test/CodeGen/WebAssembly/externref-tableset.ll
index e22f5d054e418..bd5ad6942fcda 100644
--- a/llvm/test/CodeGen/WebAssembly/externref-tableset.ll
+++ b/llvm/test/CodeGen/WebAssembly/externref-tableset.ll
@@ -94,5 +94,4 @@ define void @set_externref_table_with_id_from_call(%externref %g) {
   ret void
 }
 
-;       CHECK: .tabletype externref_table, externref
-; CHECK-LABEL: externref_table:
+; CHECK: .tabletype externref_table, externref

diff  --git a/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll b/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
index 37076db6da427..4b5a9b42f68bc 100644
--- a/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
+++ b/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
@@ -5,9 +5,16 @@
 
 @funcref_table = local_unnamed_addr addrspace(1) global [0 x %funcref] undef
 
-;  CHECK: .tabletype  __funcref_call_table, funcref, 1
-
 define void @call_funcref_from_table(i32 %i) {
+  %p = getelementptr [0 x %funcref], [0 x %funcref] addrspace (1)* @funcref_table, i32 0, i32 %i
+  %ref = load %funcref, %funcref addrspace(1)* %p
+  %fn = bitcast %funcref %ref to %funcptr
+  call addrspace(20) void %fn()
+  ret void
+}
+
+; CHECK: .tabletype      __funcref_call_table, funcref, 1
+
 ; CHECK-LABEL: call_funcref_from_table:
 ; CHECK-NEXT: .functype       call_funcref_from_table (i32) -> ()
 ; CHECK-NEXT: i32.const       0
@@ -20,13 +27,6 @@ define void @call_funcref_from_table(i32 %i) {
 ; CHECK-NEXT: ref.null_func
 ; CHECK-NEXT: table.set       __funcref_call_table
 ; CHECK-NEXT: end_function
-  %p = getelementptr [0 x %funcref], [0 x %funcref] addrspace (1)* @funcref_table, i32 0, i32 %i
-  %ref = load %funcref, %funcref addrspace(1)* %p
-  %fn = bitcast %funcref %ref to %funcptr
-  call addrspace(20) void %fn()
-  ret void
-}
 
-;       CHECK: .tabletype funcref_table, funcref
-; CHECK-LABEL: funcref_table:
+; CHECK: .tabletype     funcref_table, funcref
 

diff  --git a/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll b/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll
index a34ba0f7c3b0c..63cd69a2e9ffa 100644
--- a/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll
+++ b/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll
@@ -72,5 +72,4 @@ define %funcref @get_funcref_from_table_with_var_offset2(i32 %i) {
   ret %funcref %ref
 }
 
-;       CHECK: .tabletype funcref_table, funcref
-; CHECK-LABEL: funcref_table:
+; CHECK: .tabletype funcref_table, funcref

diff  --git a/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll b/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll
index 257594dc7df0b..ddc6c3e26b67d 100644
--- a/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll
+++ b/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll
@@ -78,5 +78,4 @@ define void @set_funcref_table_with_var_offset2(%funcref %g, i32 %i) {
   ret void
 }
 
-;       CHECK: .tabletype funcref_table, funcref
-; CHECK-LABEL: funcref_table:
+; CHECK: .tabletype funcref_table, funcref

diff  --git a/llvm/test/CodeGen/WebAssembly/global-get.ll b/llvm/test/CodeGen/WebAssembly/global-get.ll
index 07477e690c683..a31b1f1c30ebd 100644
--- a/llvm/test/CodeGen/WebAssembly/global-get.ll
+++ b/llvm/test/CodeGen/WebAssembly/global-get.ll
@@ -54,26 +54,28 @@ define i32 @return_extern_i32_global() {
 }
 
 
-; CHECK: .globaltype i32_global, i32
 ; CHECK: .globl i32_global
+; CHECK: .globaltype i32_global, i32
 ; CHECK-LABEL: i32_global:
 
-; CHECK: .globaltype i64_global, i64
 ; CHECK: .globl i64_global
+; CHECK: .globaltype i64_global, i64
 ; CHECK-LABEL: i64_global:
 
-; CHECK: .globaltype f32_global, f32
 ; CHECK: .globl f32_global
+; CHECK: .globaltype f32_global, f32
 ; CHECK-LABEL: f32_global:
 
-; CHECK: .globaltype f64_global, f64
 ; CHECK: .globl f64_global
+; CHECK: .globaltype f64_global, f64
 ; CHECK-LABEL: f64_global:
 
-; CHECK: .globaltype i32_external_used, i32
+; FIXME: are we still expecting these to be emitted?
+
 ; CHECK-NOT: .global i32_external_used
+; CHECK-NOT: .globaltype i32_external_used, i32
 ; CHECK-NOT: i32_external_used:
 
-; CHECK: .globaltype i32_external_unused, i32
 ; CHECK-NOT: .global i32_external_unused
+; CHECK-NOT: .globaltype i32_external_unused, i32
 ; CHECK-NOT: i32_external_unused:

diff  --git a/llvm/test/CodeGen/WebAssembly/global-set.ll b/llvm/test/CodeGen/WebAssembly/global-set.ll
index 44a9acebe9818..54034e476fd66 100644
--- a/llvm/test/CodeGen/WebAssembly/global-set.ll
+++ b/llvm/test/CodeGen/WebAssembly/global-set.ll
@@ -45,18 +45,18 @@ define void @set_f64_global(double %v) {
   ret void
 }
 
-; CHECK: .globaltype i32_global, i32
 ; CHECK: .globl i32_global
+; CHECK: .globaltype i32_global, i32
 ; CHECK-LABEL: i32_global:
 
-; CHECK: .globaltype i64_global, i64
 ; CHECK: .globl i64_global
+; CHECK: .globaltype i64_global, i64
 ; CHECK-LABEL: i64_global:
 
-; CHECK: .globaltype f32_global, f32
 ; CHECK: .globl f32_global
+; CHECK: .globaltype f32_global, f32
 ; CHECK-LABEL: f32_global:
 
-; CHECK: .globaltype f64_global, f64
 ; CHECK: .globl f64_global
+; CHECK: .globaltype f64_global, f64
 ; CHECK-LABEL: f64_global:

diff  --git a/llvm/test/CodeGen/WebAssembly/table-types.ll b/llvm/test/CodeGen/WebAssembly/table-types.ll
deleted file mode 100644
index f4a66629df43a..0000000000000
--- a/llvm/test/CodeGen/WebAssembly/table-types.ll
+++ /dev/null
@@ -1,37 +0,0 @@
-; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
-
-%extern = type opaque
-%externref = type %extern addrspace(10)* ;; addrspace 10 is nonintegral
-
-%func = type void ()
-%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
-
-; CHECK: .tabletype eref_table, externref
-; CHECK-NEXT: .globl eref_table
-; CHECK-LABEL: eref_table:
- at eref_table = local_unnamed_addr addrspace(1) global [0 x %externref] undef
-
-; CHECK-NOT: .globl .Lprivate_eref_table
-; CHECK: .tabletype .Lprivate_eref_table, externref
-; CHECK-LABEL: .Lprivate_eref_table:
- at private_eref_table = private local_unnamed_addr addrspace(1) global [0 x %externref] undef
-
-; CHECK: .tabletype extern_eref_table, externref
-; CHECK-NOT: .globl extern_eref_table
-; CHECK-NOT: extern_eref_table:
- at extern_eref_table = external addrspace(1) global [0 x %externref]
-
-; CHECK: .tabletype fref_table, funcref
-; CHECK-NEXT: .globl fref_table
-; CHECK-LABEL: fref_table:
- at fref_table = local_unnamed_addr addrspace(1) global [0 x %funcref] undef
-
-; CHECK-NOT: .globl .Lprivate_fref_table
-; CHECK: .tabletype .Lprivate_fref_table, funcref
-; CHECK-LABEL: .Lprivate_fref_table:
- at private_fref_table = private local_unnamed_addr addrspace(1) global [0 x %funcref] undef
-
-; CHECK: .tabletype extern_fref_table, funcref
-; CHECK-NOT: .globl extern_fref_table
-; CHECK-NOT: extern_fref_table:
- at extern_fref_table = external addrspace(1) global [0 x %funcref]

diff  --git a/llvm/test/MC/WebAssembly/assembler-binary.ll b/llvm/test/MC/WebAssembly/assembler-binary.ll
index c3d6bd588d24a..e5dcd270603ea 100644
--- a/llvm/test/MC/WebAssembly/assembler-binary.ll
+++ b/llvm/test/MC/WebAssembly/assembler-binary.ll
@@ -22,8 +22,8 @@ entry:
 
 ; ASM:     	.text
 ; ASM:      	.file	"assembler-binary.ll"
-; ASM:       	.functype	bar () -> ()
 ; ASM:      	.globl	foo
+; ASM:       	.functype	bar () -> ()
 ; ASM:      foo:
 ; ASM-NEXT: 	.functype	foo (i32) -> ()
 ; ASM-NEXT: 	call	bar

diff  --git a/llvm/test/MC/WebAssembly/stack-ptr-mclower.ll b/llvm/test/MC/WebAssembly/stack-ptr-mclower.ll
index c4b5b08109b14..d8280a9edb99a 100644
--- a/llvm/test/MC/WebAssembly/stack-ptr-mclower.ll
+++ b/llvm/test/MC/WebAssembly/stack-ptr-mclower.ll
@@ -8,7 +8,7 @@ define hidden void @bar() #0 {
 }
 
 ; Function that uses explict stack, and should generate a reference to
-; __stack_pointer, along with the corresponding relocation entry.
+; __stack_pointer, along with the corresponding reloction entry.
 define hidden void @foo() #0 {
 entry:
   alloca i32, align 4
@@ -17,10 +17,10 @@ entry:
 
 ; CHECK:              .text
 ; CHECK-NEXT:         .file   "stack-ptr-mclower.ll"
-; CHECK-NEXT:         .globaltype     __stack_pointer, [[PTR]]
 ; CHECK-NEXT:         .section        .text.bar,"",@
 ; CHECK-NEXT:         .hidden bar
 ; CHECK-NEXT:         .globl  bar
+; CHECK-NEXT:         .globaltype     __stack_pointer, [[PTR]]
 ; CHECK-NEXT:         .type   bar, at function
 ; CHECK-NEXT: bar:
 ; CHECK-NEXT:         .functype       bar () -> ()


        


More information about the llvm-commits mailing list