]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Add target feature for atomics
authorDerek Schuff <dschuff@google.com>
Wed, 30 Aug 2017 18:07:45 +0000 (18:07 +0000)
committerDerek Schuff <dschuff@google.com>
Wed, 30 Aug 2017 18:07:45 +0000 (18:07 +0000)
Summary:
This tracks the WebAssembly threads feature proposal at
https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312145 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
lib/Target/WebAssembly/WebAssembly.td
lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
lib/Target/WebAssembly/WebAssemblyInstrFormats.td
lib/Target/WebAssembly/WebAssemblyInstrInfo.td
lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp
lib/Target/WebAssembly/WebAssemblySubtarget.cpp
lib/Target/WebAssembly/WebAssemblySubtarget.h
test/CodeGen/WebAssembly/atomics.ll [new file with mode: 0644]

index 4d676c32a09c511dce6b6449cbad36d6798e79b0..6a1bd8d0ddb4be85e9cdc9c09cc89a87fecf2dc1 100644 (file)
@@ -128,6 +128,7 @@ inline unsigned GetDefaultP2Align(unsigned Opcode) {
   case WebAssembly::LOAD32_S_I64:
   case WebAssembly::LOAD32_U_I64:
   case WebAssembly::STORE32_I64:
+  case WebAssembly::ATOMIC_LOAD_I32:
     return 2;
   case WebAssembly::LOAD_I64:
   case WebAssembly::LOAD_F64:
index f647349d759bf96ead924d7d236079c90d27a0f3..50445b77f18a64be09ad02508a6e48c247cdae81 100644 (file)
@@ -25,6 +25,8 @@ include "llvm/Target/Target.td"
 
 def FeatureSIMD128 : SubtargetFeature<"simd128", "HasSIMD128", "true",
                                       "Enable 128-bit SIMD">;
+def FeatureAtomics : SubtargetFeature<"atomics", "HasAtomics", "true",
+                                      "Enable Atomics">;
 
 //===----------------------------------------------------------------------===//
 // Architectures.
@@ -55,7 +57,8 @@ def : ProcessorModel<"mvp", NoSchedModel, []>;
 def : ProcessorModel<"generic", NoSchedModel, []>;
 
 // Latest and greatest experimental version of WebAssembly. Bugs included!
-def : ProcessorModel<"bleeding-edge", NoSchedModel, [FeatureSIMD128]>;
+def : ProcessorModel<"bleeding-edge", NoSchedModel,
+                      [FeatureSIMD128, FeatureAtomics]>;
 
 //===----------------------------------------------------------------------===//
 // Target Declaration
index 7724a75bec2da4953c76c9e90cd1072aee26e451..5615ec184d74ed611860a8f757ea8db02a5343b6 100644 (file)
@@ -146,6 +146,8 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
 
   // Trap lowers to wasm unreachable
   setOperationAction(ISD::TRAP, MVT::Other, Legal);
+
+  setMaxAtomicSizeInBitsSupported(64);
 }
 
 FastISel *WebAssemblyTargetLowering::createFastISel(
index 64415658ed8175817c23c7b486bec8b3d98c5b93..fd50f59c44b506e4273f4159c76a0ad386c32542 100644 (file)
 ///
 //===----------------------------------------------------------------------===//
 
-// TODO: Implement atomic instructions.
-
-//===----------------------------------------------------------------------===//
-// Atomic fences
-//===----------------------------------------------------------------------===//
-
-// TODO: add atomic fences here...
-
 //===----------------------------------------------------------------------===//
 // Atomic loads
 //===----------------------------------------------------------------------===//
 
-// TODO: add atomic loads here...
+let Defs = [ARGUMENTS] in {
+// TODO: add the rest of the atomic loads
+// TODO: factor out 0xfe atomic prefix?
+def ATOMIC_LOAD_I32 : ATOMIC_I<(outs I32:$dst),
+                        (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
+                        [], "i32.atomic.load\t$dst, ${off}(${addr})${p2align}",
+                        0xfe10>;
+} // Defs = [ARGUMENTS]
+
+// Select loads with no constant offset.
+let Predicates = [HasAtomics] in {
+def : Pat<(i32 (atomic_load I32:$addr)), (ATOMIC_LOAD_I32 0, 0, $addr)>;
+}
 
 //===----------------------------------------------------------------------===//
 // Atomic stores
@@ -45,3 +49,4 @@
 // Store-release-exclusives.
 
 // And clear exclusive.
+
index 5b249840257154a5526b065036d0d09f5587dbae..4f41fcc232e9e2d40d610e1aec9b4af00adac8fd 100644 (file)
@@ -32,6 +32,10 @@ class SIMD_I<dag oops, dag iops, list<dag> pattern,
              string asmstr = "", bits<32> inst = -1>
     : I<oops, iops, pattern, asmstr, inst>, Requires<[HasSIMD128]>;
 
+class ATOMIC_I<dag oops, dag iops, list<dag> pattern,
+               string asmstr = "", bits<32> inst = -1>
+    : I<oops, iops, pattern, asmstr, inst>, Requires<[HasAtomics]>;
+
 // Unary and binary instructions, for the local types that WebAssembly supports.
 multiclass UnaryInt<SDNode node, string name, bits<32> i32Inst, bits<32> i64Inst> {
   def _I32 : I<(outs I32:$dst), (ins I32:$src),
index fa2146f7db84d1e827635c0fe00e38c0988d509b..bc4e542c4fbb25173ded254506079afb5ca1b1fb 100644 (file)
@@ -20,6 +20,8 @@ def HasAddr32 : Predicate<"!Subtarget->hasAddr64()">;
 def HasAddr64 : Predicate<"Subtarget->hasAddr64()">;
 def HasSIMD128 : Predicate<"Subtarget->hasSIMD128()">,
                            AssemblerPredicate<"FeatureSIMD128", "simd128">;
+def HasAtomics : Predicate<"Subtarget->hasAtomics()">,
+                           AssemblerPredicate<"FeatureAtomics", "atomics">;
 
 //===----------------------------------------------------------------------===//
 // WebAssembly-specific DAG Node Types.
index b1385f409fd33381aff268de13691f761cd35dea..a418f65e0ee4e2d00a3856f570e469c929340baf 100644 (file)
@@ -96,6 +96,7 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
       case WebAssembly::LOAD16_U_I64:
       case WebAssembly::LOAD32_S_I64:
       case WebAssembly::LOAD32_U_I64:
+      case WebAssembly::ATOMIC_LOAD_I32:
         RewriteP2Align(MI, WebAssembly::LoadP2AlignOperandNo);
         break;
       case WebAssembly::STORE_I32:
index ce39051b055583a88457e094a21d92b510029c3f..6fae72cdeae263fcb8edce07cb93713f828dcba2 100644 (file)
@@ -41,7 +41,7 @@ WebAssemblySubtarget::WebAssemblySubtarget(const Triple &TT,
                                            const std::string &FS,
                                            const TargetMachine &TM)
     : WebAssemblyGenSubtargetInfo(TT, CPU, FS), HasSIMD128(false),
-      CPUString(CPU), TargetTriple(TT), FrameLowering(),
+      HasAtomics(false), CPUString(CPU), TargetTriple(TT), FrameLowering(),
       InstrInfo(initializeSubtargetDependencies(FS)), TSInfo(),
       TLInfo(TM, *this) {}
 
index f530a290fa0e6037a8963ef860c9b365d5d5be01..a69989dd955ca5d13eeae8e12afa32d8f871a970 100644 (file)
@@ -30,6 +30,7 @@ namespace llvm {
 
 class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo {
   bool HasSIMD128;
+  bool HasAtomics;
 
   /// String name of used CPU.
   std::string CPUString;
@@ -74,6 +75,7 @@ public:
   // Predicates used by WebAssemblyInstrInfo.td.
   bool hasAddr64() const { return TargetTriple.isArch64Bit(); }
   bool hasSIMD128() const { return HasSIMD128; }
+  bool hasAtomics() const { return HasAtomics; }
 
   /// Parses features string setting specified subtarget options. Definition of
   /// function is auto generated by tblgen.
diff --git a/test/CodeGen/WebAssembly/atomics.ll b/test/CodeGen/WebAssembly/atomics.ll
new file mode 100644 (file)
index 0000000..1845187
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt 
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=+atomics | FileCheck %s
+
+; Test that atomic loads are assembled properly.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+; CHECK-LABEL: load_i32_atomic:
+; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .result i32{{$}}
+; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
+; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($pop[[L0]]){{$}}
+; CHECK-NEXT: return $pop[[NUM]]{{$}}
+
+define i32 @load_i32_atomic(i32 *%p) {
+  %v = load atomic i32, i32* %p seq_cst, align 4
+  ret i32 %v
+}