[WebAssembly] Implement __builtin_wasm_tls_base intrinsic
authorGuanzhong Chen <gzchen@google.com>
Thu, 18 Jul 2019 17:53:22 +0000 (17:53 +0000)
committerGuanzhong Chen <gzchen@google.com>
Thu, 18 Jul 2019 17:53:22 +0000 (17:53 +0000)
Summary:
Add `__builtin_wasm_tls_base` so that LeakSanitizer can find the thread-local
block and scan through it for memory leaks.

Reviewers: tlively, aheejin, sbc100

Subscribers: dschuff, jgravelle-google, hiraditya, sunfish, cfe-commits, llvm-commits

Tags: #clang, #llvm

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

llvm-svn: 366475

clang/include/clang/Basic/BuiltinsWebAssembly.def
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/builtins-wasm.c
llvm/include/llvm/IR/IntrinsicsWebAssembly.td
llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll

index 63177f0..68cecdf 100644 (file)
@@ -31,6 +31,7 @@ TARGET_BUILTIN(__builtin_wasm_data_drop, "vIUi", "", "bulk-memory")
 
 // Thread-local storage
 TARGET_BUILTIN(__builtin_wasm_tls_size, "z", "nc", "bulk-memory")
+TARGET_BUILTIN(__builtin_wasm_tls_base, "v*", "n", "bulk-memory")
 
 // Floating point min/max
 BUILTIN(__builtin_wasm_min_f32, "fff", "nc")
index a300bab..8c7411f 100644 (file)
@@ -13924,6 +13924,10 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_tls_size, ResultType);
     return Builder.CreateCall(Callee);
   }
+  case WebAssembly::BI__builtin_wasm_tls_base: {
+    Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_tls_base);
+    return Builder.CreateCall(Callee);
+  }
   case WebAssembly::BI__builtin_wasm_throw: {
     Value *Tag = EmitScalarExpr(E->getArg(0));
     Value *Obj = EmitScalarExpr(E->getArg(1));
index 8a17fb3..8f8e7a9 100644 (file)
@@ -44,6 +44,11 @@ __SIZE_TYPE__ tls_size() {
   // WEBASSEMBLY64: call i64 @llvm.wasm.tls.size.i64()
 }
 
+void *tls_base() {
+  return __builtin_wasm_tls_base();
+  // WEBASSEMBLY: call i8* @llvm.wasm.tls.base()
+}
+
 void throw(void *obj) {
   return __builtin_wasm_throw(0, obj);
   // WEBASSEMBLY32: call void @llvm.wasm.throw(i32 0, i8* %{{.*}})
index 1b89272..0dc68a5 100644 (file)
@@ -133,4 +133,9 @@ def int_wasm_tls_size :
             [],
             [IntrNoMem, IntrSpeculatable]>;
 
+def int_wasm_tls_base :
+  Intrinsic<[llvm_ptr_ty],
+            [],
+            [IntrReadMem]>;
+
 } // TargetPrefix = "wasm"
index 26339ea..e57e194 100644 (file)
@@ -227,6 +227,23 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
     }
     break;
   }
+  case ISD::INTRINSIC_W_CHAIN: {
+    unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
+    switch (IntNo) {
+    case Intrinsic::wasm_tls_base: {
+      MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
+      assert(PtrVT == MVT::i32 && "only wasm32 is supported for now");
+
+      MachineSDNode *TLSBase = CurDAG->getMachineNode(
+          WebAssembly::GLOBAL_GET_I32, DL, MVT::i32,
+          CurDAG->getTargetExternalSymbol("__tls_base", PtrVT),
+          Node->getOperand(0));
+      ReplaceNode(Node, TLSBase);
+      return;
+    }
+    }
+    break;
+  }
 
   default:
     break;
index 3f6d9d3..975e2ce 100644 (file)
@@ -75,6 +75,15 @@ define i32 @tls_size() {
   ret i32 %1
 }
 
+; CHECK-LABEL: tls_base:
+; CHECK-NEXT: .functype tls_base () -> (i32)
+define i8* @tls_base() {
+; CHECK-NEXT: global.get __tls_base
+; CHECK-NEXT: return
+  %1 = call i8* @llvm.wasm.tls.base()
+  ret i8* %1
+}
+
 ; CHECK: .type tls,@object
 ; TLS-NEXT: .section .tbss.tls,"",@
 ; NO-TLS-NEXT: .section .bss.tls,"",@
@@ -84,3 +93,4 @@ define i32 @tls_size() {
 @tls = internal thread_local global i32 0
 
 declare i32 @llvm.wasm.tls.size.i32()
+declare i8* @llvm.wasm.tls.base()