From 801fa8e6b9eb2398a051752bb0e9d81279360d14 Mon Sep 17 00:00:00 2001 From: Guanzhong Chen Date: Thu, 18 Jul 2019 17:53:22 +0000 Subject: [PATCH] [WebAssembly] Implement __builtin_wasm_tls_base intrinsic 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 | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 4 ++++ clang/test/CodeGen/builtins-wasm.c | 5 +++++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td | 5 +++++ llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp | 17 +++++++++++++++++ llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll | 10 ++++++++++ 6 files changed, 42 insertions(+) diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index 63177f0..68cecdf 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -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") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a300bab..8c7411fc 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -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)); diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c index 8a17fb3..8f8e7a9 100644 --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -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* %{{.*}}) diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td index 1b89272..0dc68a5 100644 --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -133,4 +133,9 @@ def int_wasm_tls_size : [], [IntrNoMem, IntrSpeculatable]>; +def int_wasm_tls_base : + Intrinsic<[llvm_ptr_ty], + [], + [IntrReadMem]>; + } // TargetPrefix = "wasm" diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp index 26339ea..e57e194 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp @@ -227,6 +227,23 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) { } break; } + case ISD::INTRINSIC_W_CHAIN: { + unsigned IntNo = cast(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; diff --git a/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll b/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll index 3f6d9d3..975e2ce 100644 --- a/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll +++ b/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll @@ -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() -- 2.7.4