[llvm] r357226 - [WebAssembly] Merge used feature sets, update atomics linkage policy

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 28 17:14:01 PDT 2019


Author: tlively
Date: Thu Mar 28 17:14:01 2019
New Revision: 357226

URL: http://llvm.org/viewvc/llvm-project?rev=357226&view=rev
Log:
[WebAssembly] Merge used feature sets, update atomics linkage policy

Summary:
It does not currently make sense to use WebAssembly features in some functions
but not others, so this CL adds an IR pass that takes the union of all used
feature sets and applies it to each function in the module. This allows us to
prevent atomics from being lowered away if some function has opted in to using
them. When atomics is not enabled anywhere, we detect whether there exists any
atomic operations or thread local storage that would be stripped and disallow
linking with objects that contain atomics if and only if atomics or tls are
stripped. When atomics is enabled, mark it as used but do not require it of
other objects in the link. These changes allow libraries that do not use atomics
to be built once and linked into both single-threaded and multithreaded
binaries.

Reviewers: aheejin, sbc100, dschuff

Subscribers: jgravelle-google, hiraditya, sunfish, jfb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D59625

Added:
    llvm/trunk/test/CodeGen/WebAssembly/target-features-tls.ll
Modified:
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h
    llvm/trunk/test/CodeGen/WebAssembly/target-features.ll
    llvm/trunk/test/MC/WebAssembly/array-fill.ll
    llvm/trunk/test/MC/WebAssembly/assembler-binary.ll
    llvm/trunk/test/MC/WebAssembly/bss.ll
    llvm/trunk/test/MC/WebAssembly/comdat.ll
    llvm/trunk/test/MC/WebAssembly/debug-info.ll
    llvm/trunk/test/MC/WebAssembly/explicit-sections.ll
    llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll
    llvm/trunk/test/MC/WebAssembly/visibility.ll
    llvm/trunk/test/MC/WebAssembly/weak-alias.ll
    llvm/trunk/test/MC/WebAssembly/weak.ll
    llvm/trunk/utils/TableGen/SubtargetEmitter.cpp

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Thu Mar 28 17:14:01 2019
@@ -14,6 +14,7 @@
 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
 #define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
 
+#include "../WebAssemblySubtarget.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/MC/MCInstrDesc.h"
 #include "llvm/Support/DataTypes.h"
@@ -115,9 +116,6 @@ enum TOF {
 #define GET_INSTRINFO_ENUM
 #include "WebAssemblyGenInstrInfo.inc"
 
-#define GET_SUBTARGETINFO_ENUM
-#include "WebAssemblyGenSubtargetInfo.inc"
-
 namespace llvm {
 namespace WebAssembly {
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Thu Mar 28 17:14:01 2019
@@ -33,6 +33,7 @@
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Metadata.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCSectionWasm.h"
 #include "llvm/MC/MCStreamer.h"
@@ -161,7 +162,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsm
   }
 
   EmitProducerInfo(M);
-  EmitTargetFeatures();
+  EmitTargetFeatures(M);
 }
 
 void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
@@ -215,46 +216,40 @@ void WebAssemblyAsmPrinter::EmitProducer
   }
 }
 
-void WebAssemblyAsmPrinter::EmitTargetFeatures() {
-  static const std::pair<unsigned, const char *> FeaturePairs[] = {
-      {WebAssembly::FeatureAtomics, "atomics"},
-      {WebAssembly::FeatureBulkMemory, "bulk-memory"},
-      {WebAssembly::FeatureExceptionHandling, "exception-handling"},
-      {WebAssembly::FeatureNontrappingFPToInt, "nontrapping-fptoint"},
-      {WebAssembly::FeatureSignExt, "sign-ext"},
-      {WebAssembly::FeatureSIMD128, "simd128"},
-  };
-
+void WebAssemblyAsmPrinter::EmitTargetFeatures(Module &M) {
   struct FeatureEntry {
     uint8_t Prefix;
     StringRef Name;
   };
 
-  FeatureBitset UsedFeatures =
-      static_cast<WebAssemblyTargetMachine &>(TM).getUsedFeatures();
-
-  // Calculate the features and linkage policies to emit
+  // Read target features and linkage policies from module metadata
   SmallVector<FeatureEntry, 4> EmittedFeatures;
-  for (auto &F : FeaturePairs) {
+  for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
+    std::string MDKey = (StringRef("wasm-feature-") + KV.Key).str();
+    Metadata *Policy = M.getModuleFlag(MDKey);
+    if (Policy == nullptr)
+      continue;
+
     FeatureEntry Entry;
-    Entry.Name = F.second;
-    if (F.first == WebAssembly::FeatureAtomics) {
-      // "atomics" is special: code compiled without atomics may have had its
-      // atomics lowered to nonatomic operations. Such code would be dangerous
-      // to mix with proper atomics, so it is always Required or Disallowed.
-      Entry.Prefix = UsedFeatures[F.first]
-                         ? wasm::WASM_FEATURE_PREFIX_REQUIRED
-                         : wasm::WASM_FEATURE_PREFIX_DISALLOWED;
-      EmittedFeatures.push_back(Entry);
-    } else {
-      // Other features are marked Used or not mentioned
-      if (UsedFeatures[F.first]) {
-        Entry.Prefix = wasm::WASM_FEATURE_PREFIX_USED;
-        EmittedFeatures.push_back(Entry);
-      }
-    }
+    Entry.Prefix = 0;
+    Entry.Name = KV.Key;
+
+    if (auto *MD = cast<ConstantAsMetadata>(Policy))
+      if (auto *I = cast<ConstantInt>(MD->getValue()))
+        Entry.Prefix = I->getZExtValue();
+
+    // Silently ignore invalid metadata
+    if (Entry.Prefix != wasm::WASM_FEATURE_PREFIX_USED &&
+        Entry.Prefix != wasm::WASM_FEATURE_PREFIX_REQUIRED &&
+        Entry.Prefix != wasm::WASM_FEATURE_PREFIX_DISALLOWED)
+      continue;
+
+    EmittedFeatures.push_back(Entry);
   }
 
+  if (EmittedFeatures.size() == 0)
+    return;
+
   // Emit features and linkage policies into the "target_features" section
   MCSectionWasm *FeaturesSection = OutContext.getWasmSection(
       ".custom_section.target_features", SectionKind::getMetadata());

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h Thu Mar 28 17:14:01 2019
@@ -59,7 +59,7 @@ public:
 
   void EmitEndOfAsmFile(Module &M) override;
   void EmitProducerInfo(Module &M);
-  void EmitTargetFeatures();
+  void EmitTargetFeatures(Module &M);
   void EmitJumpTableInfo() override;
   void EmitConstantPool() override;
   void EmitFunctionBodyStart() override;

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.cpp?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.cpp Thu Mar 28 17:14:01 2019
@@ -44,6 +44,11 @@ WebAssemblySubtarget::WebAssemblySubtarg
       InstrInfo(initializeSubtargetDependencies(FS)), TSInfo(),
       TLInfo(TM, *this) {}
 
+bool WebAssemblySubtarget::enableAtomicExpand() const {
+  // If atomics are disabled, atomic ops are lowered instead of expanded
+  return hasAtomics();
+}
+
 bool WebAssemblySubtarget::enableMachineScheduler() const {
   // Disable the MachineScheduler for now. Even with ShouldTrackPressure set and
   // enableMachineSchedDefaultSched overridden, it appears to have an overall

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.h?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblySubtarget.h Thu Mar 28 17:14:01 2019
@@ -22,11 +22,16 @@
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include <string>
 
+#define GET_SUBTARGETINFO_ENUM
 #define GET_SUBTARGETINFO_HEADER
 #include "WebAssemblyGenSubtargetInfo.inc"
 
 namespace llvm {
 
+// Defined in WebAssemblyGenSubtargetInfo.inc.
+extern const SubtargetFeatureKV
+    WebAssemblyFeatureKV[WebAssembly::NumSubtargetFeatures];
+
 class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo {
   enum SIMDEnum {
     NoSIMD,
@@ -77,6 +82,7 @@ public:
     return &getInstrInfo()->getRegisterInfo();
   }
   const Triple &getTargetTriple() const { return TargetTriple; }
+  bool enableAtomicExpand() const override;
   bool enableMachineScheduler() const override;
   bool useAA() const override;
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp Thu Mar 28 17:14:01 2019
@@ -26,6 +26,7 @@
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/LowerAtomic.h"
 #include "llvm/Transforms/Utils.h"
 using namespace llvm;
 
@@ -117,10 +118,6 @@ WebAssemblyTargetMachine::WebAssemblyTar
 
   initAsmInfo();
 
-  // Create a subtarget using the unmodified target machine features to
-  // initialize the used feature set with explicitly enabled features.
-  getSubtargetImpl(getTargetCPU(), getTargetFeatureString());
-
   // Note that we don't use setRequiresStructuredCFG(true). It disables
   // optimizations than we're ok with, and want, such as critical edge
   // splitting and tail merging.
@@ -134,7 +131,6 @@ WebAssemblyTargetMachine::getSubtargetIm
   auto &I = SubtargetMap[CPU + FS];
   if (!I) {
     I = llvm::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
-    UsedFeatures |= I->getFeatureBits();
   }
   return I.get();
 }
@@ -160,21 +156,123 @@ WebAssemblyTargetMachine::getSubtargetIm
 }
 
 namespace {
-class StripThreadLocal final : public ModulePass {
-  // The default thread model for wasm is single, where thread-local variables
-  // are identical to regular globals and should be treated the same. So this
-  // pass just converts all GlobalVariables to NotThreadLocal
+
+class CoalesceFeaturesAndStripAtomics final : public ModulePass {
+  // Take the union of all features used in the module and use it for each
+  // function individually, since having multiple feature sets in one module
+  // currently does not make sense for WebAssembly. If atomics are not enabled,
+  // also strip atomic operations and thread local storage.
   static char ID;
+  WebAssemblyTargetMachine *WasmTM;
 
 public:
-  StripThreadLocal() : ModulePass(ID) {}
+  CoalesceFeaturesAndStripAtomics(WebAssemblyTargetMachine *WasmTM)
+      : ModulePass(ID), WasmTM(WasmTM) {}
+
   bool runOnModule(Module &M) override {
-    for (auto &GV : M.globals())
-      GV.setThreadLocalMode(GlobalValue::ThreadLocalMode::NotThreadLocal);
+    FeatureBitset Features = coalesceFeatures(M);
+
+    std::string FeatureStr = getFeatureString(Features);
+    for (auto &F : M)
+      replaceFeatures(F, FeatureStr);
+
+    bool Stripped = false;
+    if (!Features[WebAssembly::FeatureAtomics]) {
+      Stripped |= stripAtomics(M);
+      Stripped |= stripThreadLocals(M);
+    }
+
+    recordFeatures(M, Features, Stripped);
+
+    // Conservatively assume we have made some change
     return true;
   }
+
+private:
+  FeatureBitset coalesceFeatures(const Module &M) {
+    FeatureBitset Features =
+        WasmTM
+            ->getSubtargetImpl(WasmTM->getTargetCPU(),
+                               WasmTM->getTargetFeatureString())
+            ->getFeatureBits();
+    for (auto &F : M)
+      Features |= WasmTM->getSubtargetImpl(F)->getFeatureBits();
+    return Features;
+  }
+
+  std::string getFeatureString(const FeatureBitset &Features) {
+    std::string Ret;
+    for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
+      if (Features[KV.Value])
+        Ret += (StringRef("+") + KV.Key + ",").str();
+    }
+    return Ret;
+  }
+
+  void replaceFeatures(Function &F, const std::string &Features) {
+    F.removeFnAttr("target-features");
+    F.removeFnAttr("target-cpu");
+    F.addFnAttr("target-features", Features);
+  }
+
+  bool stripAtomics(Module &M) {
+    // Detect whether any atomics will be lowered, since there is no way to tell
+    // whether the LowerAtomic pass lowers e.g. stores.
+    bool Stripped = false;
+    for (auto &F : M) {
+      for (auto &B : F) {
+        for (auto &I : B) {
+          if (I.isAtomic()) {
+            Stripped = true;
+            goto done;
+          }
+        }
+      }
+    }
+
+  done:
+    if (!Stripped)
+      return false;
+
+    LowerAtomicPass Lowerer;
+    FunctionAnalysisManager FAM;
+    for (auto &F : M)
+      Lowerer.run(F, FAM);
+
+    return true;
+  }
+
+  bool stripThreadLocals(Module &M) {
+    bool Stripped = false;
+    for (auto &GV : M.globals()) {
+      if (GV.getThreadLocalMode() !=
+          GlobalValue::ThreadLocalMode::NotThreadLocal) {
+        Stripped = true;
+        GV.setThreadLocalMode(GlobalValue::ThreadLocalMode::NotThreadLocal);
+      }
+    }
+    return Stripped;
+  }
+
+  void recordFeatures(Module &M, const FeatureBitset &Features, bool Stripped) {
+    for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
+      std::string MDKey = (StringRef("wasm-feature-") + KV.Key).str();
+      if (KV.Value == WebAssembly::FeatureAtomics && Stripped) {
+        // "atomics" is special: code compiled without atomics may have had its
+        // atomics lowered to nonatomic operations. In that case, atomics is
+        // disallowed to prevent unsafe linking with atomics-enabled objects.
+        assert(!Features[WebAssembly::FeatureAtomics]);
+        M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
+                        wasm::WASM_FEATURE_PREFIX_DISALLOWED);
+      } else if (Features[KV.Value]) {
+        // Otherwise features are marked Used or not mentioned
+        M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
+                        wasm::WASM_FEATURE_PREFIX_USED);
+      }
+    }
+  }
 };
-char StripThreadLocal::ID = 0;
+char CoalesceFeaturesAndStripAtomics::ID = 0;
 
 /// WebAssembly Code Generator Pass Configuration Options.
 class WebAssemblyPassConfig final : public TargetPassConfig {
@@ -222,16 +320,11 @@ FunctionPass *WebAssemblyPassConfig::cre
 //===----------------------------------------------------------------------===//
 
 void WebAssemblyPassConfig::addIRPasses() {
-  if (static_cast<WebAssemblyTargetMachine *>(TM)
-          ->getUsedFeatures()[WebAssembly::FeatureAtomics]) {
-    // Expand some atomic operations. WebAssemblyTargetLowering has hooks which
-    // control specifically what gets lowered.
-    addPass(createAtomicExpandPass());
-  } else {
-    // If atomics are not enabled, they get lowered to non-atomics.
-    addPass(createLowerAtomicPass());
-    addPass(new StripThreadLocal());
-  }
+  // Runs LowerAtomicPass if necessary
+  addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
+
+  // This is a no-op if atomics are not used in the module
+  addPass(createAtomicExpandPass());
 
   // Add signatures to prototype-less function declarations
   addPass(createWebAssemblyAddMissingPrototypes());

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h Thu Mar 28 17:14:01 2019
@@ -23,7 +23,6 @@ namespace llvm {
 class WebAssemblyTargetMachine final : public LLVMTargetMachine {
   std::unique_ptr<TargetLoweringObjectFile> TLOF;
   mutable StringMap<std::unique_ptr<WebAssemblySubtarget>> SubtargetMap;
-  mutable FeatureBitset UsedFeatures;
 
 public:
   WebAssemblyTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
@@ -46,8 +45,6 @@ public:
     return TLOF.get();
   }
 
-  FeatureBitset getUsedFeatures() const { return UsedFeatures; }
-
   TargetTransformInfo getTargetTransformInfo(const Function &F) override;
 
   bool usesPhysRegsForPEI() const override { return false; }

Added: llvm/trunk/test/CodeGen/WebAssembly/target-features-tls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/target-features-tls.ll?rev=357226&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/target-features-tls.ll (added)
+++ llvm/trunk/test/CodeGen/WebAssembly/target-features-tls.ll Thu Mar 28 17:14:01 2019
@@ -0,0 +1,26 @@
+; RUN: llc < %s -mattr=-atomics | FileCheck %s --check-prefixes CHECK,NO-ATOMICS
+; RUN: llc < %s -mattr=+atomics | FileCheck %s --check-prefixes CHECK,ATOMICS
+
+; Test that the target features section contains -atomics or +atomics
+; for modules that have thread local storage in their source.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+ at foo = internal thread_local global i32 0
+
+; CHECK-LABEL: .custom_section.target_features,"",@
+
+; -atomics
+; NO-ATOMICS-NEXT: .int8 1
+; NO-ATOMICS-NEXT: .int8 45
+; NO-ATOMICS-NEXT: .int8 7
+; NO-ATOMICS-NEXT: .ascii "atomics"
+; NO-ATOMICS-NEXT: .bss.foo,"",@
+
+; +atomics
+; ATOMICS-NEXT: .int8 1
+; ATOMICS-NEXT: .int8 43
+; ATOMICS-NEXT: .int8 7
+; ATOMICS-NEXT: .ascii "atomics"
+; ATOMICS-NEXT: .tbss.foo,"",@

Modified: llvm/trunk/test/CodeGen/WebAssembly/target-features.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/target-features.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/target-features.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/target-features.ll Thu Mar 28 17:14:01 2019
@@ -1,38 +1,69 @@
 ; RUN: llc < %s | FileCheck %s --check-prefixes CHECK,ATTRS
 ; RUN: llc < %s -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
-; RUN; llc < %s -mattr=+atomics | FileCheck %s --check-prefixes CHECK,ATOMICS
 ; RUN: llc < %s -mcpu=bleeding-edge | FileCheck %s --check-prefixes CHECK,BLEEDING-EDGE
 
 ; Test that codegen emits target features from the command line or
-; function attributes correctly.
+; function attributes correctly and that features are enabled for the
+; entire module if they are enabled for any function in the module.
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
 
-define void @foo() #0 {
+define void @foo(i32* %p1) #0 {
+  %a = atomicrmw min i32* undef, i32 42 seq_cst
+  %v = fptoui float undef to i32
+  store i32 %v, i32* %p1
   ret void
 }
 
-define void @bar() #1 {
+define void @bar(i32* %p1) #1 {
+  %a = atomicrmw min i32* undef, i32 42 seq_cst
+  %v = fptoui float undef to i32
+  store i32 %v, i32* %p1
   ret void
 }
 
-attributes #0 = { "target-features"="+sign-ext" }
+attributes #0 = { "target-features"="+atomics" }
 attributes #1 = { "target-features"="+nontrapping-fptoint" }
 
+
+; CHECK-LABEL: foo:
+
+; Expanded atomicrmw min
+; ATTRS:       loop
+; ATTRS:       i32.atomic.rmw.cmpxchg
+; SIMD128-NOT: i32.atomic.rmw.cmpxchg
+; ATTRS:       end_loop
+
+; nontrapping fptoint
+; ATTRS:       i32.trunc_sat_f32_u
+; SIMD128-NOT: i32.trunc_sat_f32_u
+; ATTRS:       i32.store
+
+; `bar` should be the same as `foo`
+; CHECK-LABEL: bar:
+
+; Expanded atomicrmw min
+; ATTRS:       loop
+; ATTRS:       i32.atomic.rmw.cmpxchg
+; SIMD128-NOT: i32.atomic.rmw.cmpxchg
+; ATTRS:       end_loop
+
+; nontrapping fptoint
+; ATTRS:       i32.trunc_sat_f32_u
+; SIMD128-NOT: i32.trunc_sat_f32_u
+; ATTRS:       i32.store
+
 ; CHECK-LABEL: .custom_section.target_features,"",@
 
-; -atomics, +sign_ext
-; ATTRS-NEXT: .int8 3
-; ATTRS-NEXT: .int8 45
+; +atomics, +nontrapping-fptoint
+; ATTRS-NEXT: .int8 2
+; ATTRS-NEXT: .int8 43
 ; ATTRS-NEXT: .int8 7
 ; ATTRS-NEXT: .ascii "atomics"
 ; ATTRS-NEXT: .int8 43
 ; ATTRS-NEXT: .int8 19
 ; ATTRS-NEXT: .ascii "nontrapping-fptoint"
-; ATTRS-NEXT: .int8 43
-; ATTRS-NEXT:  int8 8
-; ATTRS-NEXT: .ascii "sign-ext"
 
 ; -atomics, +simd128
 ; SIMD128-NEXT: .int8 2
@@ -43,15 +74,9 @@ attributes #1 = { "target-features"="+no
 ; SIMD128-NEXT: .int8 7
 ; SIMD128-NEXT: .ascii "simd128"
 
-; =atomics
-; ATOMICS-NEXT: .int8 1
-; ATOMICS-NEXT: .int8 61
-; ATOMICS-NEXT: .int8 7
-; ATOMICS-NEXT: .ascii "atomics"
-
-; =atomics, +nontrapping-fptoint, +sign-ext, +simd128
+; +atomics, +nontrapping-fptoint, +sign-ext, +simd128
 ; BLEEDING-EDGE-NEXT: .int8   4
-; BLEEDING-EDGE-NEXT: .int8   61
+; BLEEDING-EDGE-NEXT: .int8   43
 ; BLEEDING-EDGE-NEXT: .int8   7
 ; BLEEDING-EDGE-NEXT: .ascii  "atomics"
 ; BLEEDING-EDGE-NEXT: .int8   43

Modified: llvm/trunk/test/MC/WebAssembly/array-fill.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/array-fill.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/array-fill.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/array-fill.ll Thu Mar 28 17:14:01 2019
@@ -24,9 +24,4 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:         Name:            .data
 ; CHECK-NEXT:         Alignment:       0
 ; CHECK-NEXT:         Flags:           [ ]
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/assembler-binary.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/assembler-binary.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/assembler-binary.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/assembler-binary.ll Thu Mar 28 17:14:01 2019
@@ -87,9 +87,4 @@ entry:
 ; CHECK-NEXT:         Name:            bar
 ; CHECK-NEXT:         Flags:           [ UNDEFINED ]
 ; CHECK-NEXT:         Function:        0
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/bss.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/bss.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/bss.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/bss.ll Thu Mar 28 17:14:01 2019
@@ -78,9 +78,4 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:         Name:            .bss.bar
 ; CHECK-NEXT:         Alignment:       0
 ; CHECK-NEXT:         Flags:           [ ]
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/comdat.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/comdat.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/comdat.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/comdat.ll Thu Mar 28 17:14:01 2019
@@ -119,9 +119,4 @@ define linkonce_odr i32 @sharedFn() #1 c
 ; CHECK-NEXT:            Index:           3
 ; CHECK-NEXT:          - Kind:            DATA
 ; CHECK-NEXT:            Index:           0
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/debug-info.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/debug-info.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/debug-info.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/debug-info.ll Thu Mar 28 17:14:01 2019
@@ -130,12 +130,6 @@
 ; CHECK-NEXT:    Offset: 1021
 ; CHECK-NEXT:    Name: producers
 ; CHECK-NEXT:  }
-; CHECK-NEXT:  Section {
-; CHECK-NEXT:    Type: CUSTOM (0x0)
-; CHECK-NEXT:    Size: 10
-; CHECK-NEXT:    Offset: 1114
-; CHECK-NEXT:    Name: target_features
-; CHECK-NEXT:  }
 ; CHECK-NEXT:]
 ; CHECK-NEXT:Relocations [
 ; CHECK-NEXT:  Section (6) DATA {

Modified: llvm/trunk/test/MC/WebAssembly/explicit-sections.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/explicit-sections.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/explicit-sections.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/explicit-sections.ll Thu Mar 28 17:14:01 2019
@@ -70,9 +70,4 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:         Name:            .sec2
 ; CHECK-NEXT:         Alignment:       3
 ; CHECK-NEXT:         Flags:           [ ]
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll Thu Mar 28 17:14:01 2019
@@ -181,9 +181,4 @@ declare void @func3()
 ; CHECK-NEXT:         Symbol: 10
 ; CHECK-NEXT:       - Priority: 65535
 ; CHECK-NEXT:         Symbol: 7
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/visibility.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/visibility.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/visibility.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/visibility.ll Thu Mar 28 17:14:01 2019
@@ -25,9 +25,4 @@ entry:
 ; CHECK-NEXT:         Name:            hiddenVis
 ; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
 ; CHECK-NEXT:         Function:        1
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/weak-alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/weak-alias.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/weak-alias.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/weak-alias.ll Thu Mar 28 17:14:01 2019
@@ -207,11 +207,6 @@ entry:
 ; CHECK-NEXT:         Name:            .data.alias_address
 ; CHECK-NEXT:         Alignment:       3
 ; CHECK-NEXT:         Flags:           [ ]
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...
 
 ; CHECK-SYMS: SYMBOL TABLE:

Modified: llvm/trunk/test/MC/WebAssembly/weak.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/weak.ll?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/weak.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/weak.ll Thu Mar 28 17:14:01 2019
@@ -30,9 +30,4 @@ entry:
 ; CHECK-NEXT:         Kind:            DATA
 ; CHECK-NEXT:         Name:            weak_external_data
 ; CHECK-NEXT:         Flags:           [ BINDING_WEAK, UNDEFINED ]
-; CHECK-NEXT:   - Type:            CUSTOM
-; CHECK-NEXT:     Name:            target_features
-; CHECK-NEXT:     Features:
-; CHECK-NEXT:       - Prefix:          DISALLOWED
-; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=357226&r1=357225&r2=357226&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Thu Mar 28 17:14:01 2019
@@ -149,7 +149,7 @@ void SubtargetEmitter::Enumeration(raw_o
   unsigned N = DefList.size();
   if (N == 0)
     return;
-  if (N > MAX_SUBTARGET_FEATURES)
+  if (N + 1 > MAX_SUBTARGET_FEATURES)
     PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");
 
   OS << "namespace " << Target << " {\n";
@@ -169,6 +169,9 @@ void SubtargetEmitter::Enumeration(raw_o
     FeatureMap[Def] = i;
   }
 
+  OS << "  "
+     << "NumSubtargetFeatures = " << N << "\n";
+
   // Close enumeration and namespace
   OS << "};\n";
   OS << "} // end namespace " << Target << "\n";




More information about the llvm-commits mailing list