83 lines · cpp
1// RUN: %clang_cc1 -emit-llvm -triple=wasm32-unknown-unknown -target-feature +atomics -target-feature +bulk-memory -o - %s \2// RUN: | FileCheck %s -check-prefix=WEBASSEMBLY323// RUN: %clang_cc1 -emit-llvm -triple=wasm64-unknown-unknown -target-feature +atomics -target-feature +bulk-memory -o - %s \4// RUN: | FileCheck %s -check-prefix=WEBASSEMBLY645 6// Test that we don't create common blocks.7int tentative;8// WEBASSEMBLY32: @tentative = global i32 0, align 49// WEBASSEMBLY64: @tentative = global i32 0, align 410 11// Test that WebAssembly uses the ARM-style ABI in which the static12// variable's guard variable is tested via "load i8 and test the13// bottom bit" rather than the Itanium/x86 ABI which uses "load i814// and compare with zero".15int f();16void g() {17 static int a = f();18}19// WEBASSEMBLY32-LABEL: @_Z1gv()20// WEBASSEMBLY32: %[[R0:.+]] = load atomic i8, ptr @_ZGVZ1gvE1a acquire, align 421// WEBASSEMBLY32-NEXT: %[[R1:.+]] = and i8 %[[R0]], 122// WEBASSEMBLY32-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 023// WEBASSEMBLY32-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],24// WEBASSEMBLY32: [[CHECK]]25// WEBASSEMBLY32: call i32 @__cxa_guard_acquire26// WEBASSEMBLY32: [[END]]27// WEBASSEMBLY32: call void @__cxa_guard_release28//29// WEBASSEMBLY64-LABEL: @_Z1gv()30// WEBASSEMBLY64: %[[R0:.+]] = load atomic i8, ptr @_ZGVZ1gvE1a acquire, align 831// WEBASSEMBLY64-NEXT: %[[R1:.+]] = and i8 %[[R0]], 132// WEBASSEMBLY64-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 033// WEBASSEMBLY64-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],34// WEBASSEMBLY64: [[CHECK]]35// WEBASSEMBLY64: call i32 @__cxa_guard_acquire36// WEBASSEMBLY64: [[END]]37// WEBASSEMBLY64: call void @__cxa_guard_release38 39// Test various aspects of static constructor calls.40struct A {41 A();42};43 44A theA;45 46// WEBASSEMBLY32: define internal void @__cxx_global_var_init() #3 {47// WEBASSEMBLY32: call noundef ptr @_ZN1AC1Ev(ptr {{[^,]*}} @theA)48// WEBASSEMBLY32: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {49// WEBASSEMBLY32: call void @__cxx_global_var_init()50//51// WEBASSEMBLY64: define internal void @__cxx_global_var_init() #3 {52// WEBASSEMBLY64: call noundef ptr @_ZN1AC1Ev(ptr {{[^,]*}} @theA)53// WEBASSEMBLY64: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {54// WEBASSEMBLY64: call void @__cxx_global_var_init()55 56// RUN: %clang_cc1 -emit-llvm -triple=wasm32-unknown-unknown -target-feature +bulk-memory -o - %s \57// RUN: | FileCheck %s -check-prefix=NOATOMICS58// RUN: %clang_cc1 -emit-llvm -triple=wasm64-unknown-unknown -target-feature +bulk-memory -o - %s \59// RUN: | FileCheck %s -check-prefix=NOATOMICS60 61// NOATOMICS-LABEL: @_Z1gv()62// NOATOMICS: %[[R0:.+]] = load i8, ptr @_ZGVZ1gvE1a, align 163// NOATOMICS-NEXT: %guard.uninitialized = icmp eq i8 %[[R0]], 064// NOATOMICS-NEXT: br i1 %guard.uninitialized, label %[[CHECK:.+]], label %[[END:.+]],65// NOATOMICS: [[CHECK]]:66// NOATOMICS-NOT: __cxa_guard_acquire67// NOATOMICS: [[END]]:68// NOATOMICS-NEXT: ret void69 70// RUN: %clang_cc1 -emit-llvm -triple=wasm32-unknown-unknown -target-feature +atomics -o - %s \71// RUN: | FileCheck %s -check-prefix=NOBULKMEM72// RUN: %clang_cc1 -emit-llvm -triple=wasm64-unknown-unknown -target-feature +atomics -o - %s \73// RUN: | FileCheck %s -check-prefix=NOBULKMEM74 75// NOBULKMEM-LABEL: @_Z1gv()76// NOBULKMEM: %[[R0:.+]] = load i8, ptr @_ZGVZ1gvE1a, align 177// NOBULKMEM-NEXT: %guard.uninitialized = icmp eq i8 %[[R0]], 078// NOBULKMEM-NEXT: br i1 %guard.uninitialized, label %[[CHECK:.+]], label %[[END:.+]],79// NOBULKMEM: [[CHECK]]:80// NOBULKMEM-NOT: __cxa_guard_acquire81// NOBULKMEM: [[END]]:82// NOBULKMEM-NEXT: ret void83