Skip to content

Instantly share code, notes, and snippets.

@waywardmonkeys
Created February 26, 2013 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waywardmonkeys/5040802 to your computer and use it in GitHub Desktop.
Save waywardmonkeys/5040802 to your computer and use it in GitHub Desktop.
emscripten bug with volatile atomic ops.
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <atomic>
// struct atomic_flag
// void atomic_flag_clear(volatile atomic_flag*);
// void atomic_flag_clear(atomic_flag*);
#include <atomic>
#include <cassert>
int main()
{
{
std::atomic_flag f;
f.test_and_set();
atomic_flag_clear(&f);
assert(f.test_and_set() == 0);
}
{
volatile std::atomic_flag f;
f.test_and_set();
atomic_flag_clear(&f);
assert(f.test_and_set() == 0);
}
}
; ModuleID = 'test.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
target triple = "i386-pc-linux-gnu"
%"struct.std::__1::atomic_flag" = type { i8 }
@.str = private unnamed_addr constant [27 x i8] c"atomic_flag_clear.pass.cpp\00", align 1
@__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1
@.str1 = private unnamed_addr constant [22 x i8] c"f.test_and_set() == 0\00", align 1
define i32 @main() ssp {
entry:
%this.addr.i52 = alloca %"struct.std::__1::atomic_flag"*, align 4
%__m.addr.i53 = alloca i32, align 4
%.atomictmp.i54 = alloca i8, align 1
%.atomicdst.i55 = alloca i8, align 1
%this.addr.i.i43 = alloca %"struct.std::__1::atomic_flag"*, align 4
%__m.addr.i.i44 = alloca i32, align 4
%.atomictmp.i.i45 = alloca i8, align 1
%__o.addr.i46 = alloca %"struct.std::__1::atomic_flag"*, align 4
%this.addr.i31 = alloca %"struct.std::__1::atomic_flag"*, align 4
%__m.addr.i32 = alloca i32, align 4
%.atomictmp.i33 = alloca i8, align 1
%.atomicdst.i34 = alloca i8, align 1
%this.addr.i.i27 = alloca %"struct.std::__1::atomic_flag"*, align 4
%this.addr.i28 = alloca %"struct.std::__1::atomic_flag"*, align 4
%this.addr.i14 = alloca %"struct.std::__1::atomic_flag"*, align 4
%__m.addr.i15 = alloca i32, align 4
%.atomictmp.i16 = alloca i8, align 1
%.atomicdst.i17 = alloca i8, align 1
%this.addr.i.i12 = alloca %"struct.std::__1::atomic_flag"*, align 4
%__m.addr.i.i = alloca i32, align 4
%.atomictmp.i.i = alloca i8, align 1
%__o.addr.i = alloca %"struct.std::__1::atomic_flag"*, align 4
%this.addr.i10 = alloca %"struct.std::__1::atomic_flag"*, align 4
%__m.addr.i = alloca i32, align 4
%.atomictmp.i = alloca i8, align 1
%.atomicdst.i = alloca i8, align 1
%this.addr.i.i = alloca %"struct.std::__1::atomic_flag"*, align 4
%this.addr.i = alloca %"struct.std::__1::atomic_flag"*, align 4
%retval = alloca i32, align 4
%f = alloca %"struct.std::__1::atomic_flag", align 1
%f2 = alloca %"struct.std::__1::atomic_flag", align 1
store i32 0, i32* %retval
store %"struct.std::__1::atomic_flag"* %f, %"struct.std::__1::atomic_flag"** %this.addr.i, align 4
%this1.i = load %"struct.std::__1::atomic_flag"** %this.addr.i
store %"struct.std::__1::atomic_flag"* %this1.i, %"struct.std::__1::atomic_flag"** %this.addr.i.i, align 4
%this1.i.i = load %"struct.std::__1::atomic_flag"** %this.addr.i.i
store %"struct.std::__1::atomic_flag"* %f, %"struct.std::__1::atomic_flag"** %this.addr.i52, align 4
store i32 5, i32* %__m.addr.i53, align 4
%this1.i56 = load %"struct.std::__1::atomic_flag"** %this.addr.i52
%__a_.i57 = getelementptr inbounds %"struct.std::__1::atomic_flag"* %this1.i56, i32 0, i32 0
%0 = load i32* %__m.addr.i53, align 4
store i8 1, i8* %.atomictmp.i54
switch i32 %0, label %monotonic.i58 [
i32 1, label %acquire.i59
i32 2, label %acquire.i59
i32 3, label %release.i60
i32 4, label %acqrel.i61
i32 5, label %seqcst.i62
]
monotonic.i58: ; preds = %entry
%1 = load i8* %.atomictmp.i54, align 1
%2 = atomicrmw xchg i8* %__a_.i57, i8 %1 monotonic
store i8 %2, i8* %.atomicdst.i55, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
acquire.i59: ; preds = %entry, %entry
%3 = load i8* %.atomictmp.i54, align 1
%4 = atomicrmw xchg i8* %__a_.i57, i8 %3 acquire
store i8 %4, i8* %.atomicdst.i55, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
release.i60: ; preds = %entry
%5 = load i8* %.atomictmp.i54, align 1
%6 = atomicrmw xchg i8* %__a_.i57, i8 %5 release
store i8 %6, i8* %.atomicdst.i55, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
acqrel.i61: ; preds = %entry
%7 = load i8* %.atomictmp.i54, align 1
%8 = atomicrmw xchg i8* %__a_.i57, i8 %7 acq_rel
store i8 %8, i8* %.atomicdst.i55, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
seqcst.i62: ; preds = %entry
%9 = load i8* %.atomictmp.i54, align 1
%10 = atomicrmw xchg i8* %__a_.i57, i8 %9 seq_cst
store i8 %10, i8* %.atomicdst.i55, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64: ; preds = %seqcst.i62, %acqrel.i61, %release.i60, %acquire.i59, %monotonic.i58
%11 = load i8* %.atomicdst.i55
%tobool.i63 = trunc i8 %11 to i1
store %"struct.std::__1::atomic_flag"* %f, %"struct.std::__1::atomic_flag"** %__o.addr.i46, align 4
%12 = load %"struct.std::__1::atomic_flag"** %__o.addr.i46, align 4
store %"struct.std::__1::atomic_flag"* %12, %"struct.std::__1::atomic_flag"** %this.addr.i.i43, align 4
store i32 5, i32* %__m.addr.i.i44, align 4
%this1.i.i47 = load %"struct.std::__1::atomic_flag"** %this.addr.i.i43
%__a_.i.i48 = getelementptr inbounds %"struct.std::__1::atomic_flag"* %this1.i.i47, i32 0, i32 0
%13 = load i32* %__m.addr.i.i44, align 4
store i8 0, i8* %.atomictmp.i.i45
switch i32 %13, label %monotonic.i.i49 [
i32 3, label %release.i.i50
i32 5, label %seqcst.i.i51
]
monotonic.i.i49: ; preds = %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
%14 = load i8* %.atomictmp.i.i45, align 1
store atomic i8 %14, i8* %__a_.i.i48 monotonic, align 1
br label %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
release.i.i50: ; preds = %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
%15 = load i8* %.atomictmp.i.i45, align 1
store atomic i8 %15, i8* %__a_.i.i48 release, align 1
br label %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
seqcst.i.i51: ; preds = %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit64
%16 = load i8* %.atomictmp.i.i45, align 1
store atomic i8 %16, i8* %__a_.i.i48 seq_cst, align 1
br label %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit: ; preds = %seqcst.i.i51, %release.i.i50, %monotonic.i.i49
store %"struct.std::__1::atomic_flag"* %f, %"struct.std::__1::atomic_flag"** %this.addr.i31, align 4
store i32 5, i32* %__m.addr.i32, align 4
%this1.i35 = load %"struct.std::__1::atomic_flag"** %this.addr.i31
%__a_.i36 = getelementptr inbounds %"struct.std::__1::atomic_flag"* %this1.i35, i32 0, i32 0
%17 = load i32* %__m.addr.i32, align 4
store i8 1, i8* %.atomictmp.i33
switch i32 %17, label %monotonic.i37 [
i32 1, label %acquire.i38
i32 2, label %acquire.i38
i32 3, label %release.i39
i32 4, label %acqrel.i40
i32 5, label %seqcst.i41
]
monotonic.i37: ; preds = %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
%18 = load i8* %.atomictmp.i33, align 1
%19 = atomicrmw xchg i8* %__a_.i36, i8 %18 monotonic
store i8 %19, i8* %.atomicdst.i34, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
acquire.i38: ; preds = %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit, %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
%20 = load i8* %.atomictmp.i33, align 1
%21 = atomicrmw xchg i8* %__a_.i36, i8 %20 acquire
store i8 %21, i8* %.atomicdst.i34, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
release.i39: ; preds = %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
%22 = load i8* %.atomictmp.i33, align 1
%23 = atomicrmw xchg i8* %__a_.i36, i8 %22 release
store i8 %23, i8* %.atomicdst.i34, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
acqrel.i40: ; preds = %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
%24 = load i8* %.atomictmp.i33, align 1
%25 = atomicrmw xchg i8* %__a_.i36, i8 %24 acq_rel
store i8 %25, i8* %.atomicdst.i34, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
seqcst.i41: ; preds = %_ZNSt3__117atomic_flag_clearEPNS_11atomic_flagE.exit
%26 = load i8* %.atomictmp.i33, align 1
%27 = atomicrmw xchg i8* %__a_.i36, i8 %26 seq_cst
store i8 %27, i8* %.atomicdst.i34, align 1
br label %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit: ; preds = %seqcst.i41, %acqrel.i40, %release.i39, %acquire.i38, %monotonic.i37
%28 = load i8* %.atomicdst.i34
%tobool.i42 = trunc i8 %28 to i1
%conv = zext i1 %tobool.i42 to i32
%cmp = icmp eq i32 %conv, 0
br i1 %cmp, label %cond.true, label %cond.false
cond.true: ; preds = %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
br label %cond.end
cond.false: ; preds = %_ZNSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
call void @__assert_func(i8* getelementptr inbounds ([27 x i8]* @.str, i32 0, i32 0), i32 26, i8* getelementptr inbounds ([11 x i8]* @__PRETTY_FUNCTION__.main, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8]* @.str1, i32 0, i32 0))
br label %cond.end
cond.end: ; preds = %cond.false, %cond.true
store %"struct.std::__1::atomic_flag"* %f2, %"struct.std::__1::atomic_flag"** %this.addr.i28, align 4
%this1.i29 = load %"struct.std::__1::atomic_flag"** %this.addr.i28
store %"struct.std::__1::atomic_flag"* %this1.i29, %"struct.std::__1::atomic_flag"** %this.addr.i.i27, align 4
%this1.i.i30 = load %"struct.std::__1::atomic_flag"** %this.addr.i.i27
store %"struct.std::__1::atomic_flag"* %f2, %"struct.std::__1::atomic_flag"** %this.addr.i14, align 4
store i32 5, i32* %__m.addr.i15, align 4
%this1.i18 = load %"struct.std::__1::atomic_flag"** %this.addr.i14
%__a_.i19 = getelementptr inbounds %"struct.std::__1::atomic_flag"* %this1.i18, i32 0, i32 0
%29 = load i32* %__m.addr.i15, align 4
store i8 1, i8* %.atomictmp.i16
switch i32 %29, label %monotonic.i20 [
i32 1, label %acquire.i21
i32 2, label %acquire.i21
i32 3, label %release.i22
i32 4, label %acqrel.i23
i32 5, label %seqcst.i24
]
monotonic.i20: ; preds = %cond.end
%30 = load i8* %.atomictmp.i16, align 1
%31 = atomicrmw volatile xchg i8* %__a_.i19, i8 %30 monotonic
store i8 %31, i8* %.atomicdst.i17, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
acquire.i21: ; preds = %cond.end, %cond.end
%32 = load i8* %.atomictmp.i16, align 1
%33 = atomicrmw volatile xchg i8* %__a_.i19, i8 %32 acquire
store i8 %33, i8* %.atomicdst.i17, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
release.i22: ; preds = %cond.end
%34 = load i8* %.atomictmp.i16, align 1
%35 = atomicrmw volatile xchg i8* %__a_.i19, i8 %34 release
store i8 %35, i8* %.atomicdst.i17, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
acqrel.i23: ; preds = %cond.end
%36 = load i8* %.atomictmp.i16, align 1
%37 = atomicrmw volatile xchg i8* %__a_.i19, i8 %36 acq_rel
store i8 %37, i8* %.atomicdst.i17, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
seqcst.i24: ; preds = %cond.end
%38 = load i8* %.atomictmp.i16, align 1
%39 = atomicrmw volatile xchg i8* %__a_.i19, i8 %38 seq_cst
store i8 %39, i8* %.atomicdst.i17, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26: ; preds = %seqcst.i24, %acqrel.i23, %release.i22, %acquire.i21, %monotonic.i20
%40 = load i8* %.atomicdst.i17
%tobool.i25 = trunc i8 %40 to i1
store %"struct.std::__1::atomic_flag"* %f2, %"struct.std::__1::atomic_flag"** %__o.addr.i, align 4
%41 = load %"struct.std::__1::atomic_flag"** %__o.addr.i, align 4
store %"struct.std::__1::atomic_flag"* %41, %"struct.std::__1::atomic_flag"** %this.addr.i.i12, align 4
store i32 5, i32* %__m.addr.i.i, align 4
%this1.i.i13 = load %"struct.std::__1::atomic_flag"** %this.addr.i.i12
%__a_.i.i = getelementptr inbounds %"struct.std::__1::atomic_flag"* %this1.i.i13, i32 0, i32 0
%42 = load i32* %__m.addr.i.i, align 4
store i8 0, i8* %.atomictmp.i.i
switch i32 %42, label %monotonic.i.i [
i32 3, label %release.i.i
i32 5, label %seqcst.i.i
]
monotonic.i.i: ; preds = %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
%43 = load i8* %.atomictmp.i.i, align 1
store atomic volatile i8 %43, i8* %__a_.i.i monotonic, align 1
br label %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
release.i.i: ; preds = %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
%44 = load i8* %.atomictmp.i.i, align 1
store atomic volatile i8 %44, i8* %__a_.i.i release, align 1
br label %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
seqcst.i.i: ; preds = %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit26
%45 = load i8* %.atomictmp.i.i, align 1
store atomic volatile i8 %45, i8* %__a_.i.i seq_cst, align 1
br label %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit: ; preds = %seqcst.i.i, %release.i.i, %monotonic.i.i
store %"struct.std::__1::atomic_flag"* %f2, %"struct.std::__1::atomic_flag"** %this.addr.i10, align 4
store i32 5, i32* %__m.addr.i, align 4
%this1.i11 = load %"struct.std::__1::atomic_flag"** %this.addr.i10
%__a_.i = getelementptr inbounds %"struct.std::__1::atomic_flag"* %this1.i11, i32 0, i32 0
%46 = load i32* %__m.addr.i, align 4
store i8 1, i8* %.atomictmp.i
switch i32 %46, label %monotonic.i [
i32 1, label %acquire.i
i32 2, label %acquire.i
i32 3, label %release.i
i32 4, label %acqrel.i
i32 5, label %seqcst.i
]
monotonic.i: ; preds = %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
%47 = load i8* %.atomictmp.i, align 1
%48 = atomicrmw volatile xchg i8* %__a_.i, i8 %47 monotonic
store i8 %48, i8* %.atomicdst.i, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
acquire.i: ; preds = %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit, %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
%49 = load i8* %.atomictmp.i, align 1
%50 = atomicrmw volatile xchg i8* %__a_.i, i8 %49 acquire
store i8 %50, i8* %.atomicdst.i, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
release.i: ; preds = %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
%51 = load i8* %.atomictmp.i, align 1
%52 = atomicrmw volatile xchg i8* %__a_.i, i8 %51 release
store i8 %52, i8* %.atomicdst.i, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
acqrel.i: ; preds = %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
%53 = load i8* %.atomictmp.i, align 1
%54 = atomicrmw volatile xchg i8* %__a_.i, i8 %53 acq_rel
store i8 %54, i8* %.atomicdst.i, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
seqcst.i: ; preds = %_ZNSt3__117atomic_flag_clearEPVNS_11atomic_flagE.exit
%55 = load i8* %.atomictmp.i, align 1
%56 = atomicrmw volatile xchg i8* %__a_.i, i8 %55 seq_cst
store i8 %56, i8* %.atomicdst.i, align 1
br label %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit: ; preds = %seqcst.i, %acqrel.i, %release.i, %acquire.i, %monotonic.i
%57 = load i8* %.atomicdst.i
%tobool.i = trunc i8 %57 to i1
%conv5 = zext i1 %tobool.i to i32
%cmp6 = icmp eq i32 %conv5, 0
br i1 %cmp6, label %cond.true7, label %cond.false8
cond.true7: ; preds = %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
br label %cond.end9
cond.false8: ; preds = %_ZNVSt3__111atomic_flag12test_and_setENS_12memory_orderE.exit
call void @__assert_func(i8* getelementptr inbounds ([27 x i8]* @.str, i32 0, i32 0), i32 32, i8* getelementptr inbounds ([11 x i8]* @__PRETTY_FUNCTION__.main, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8]* @.str1, i32 0, i32 0))
br label %cond.end9
cond.end9: ; preds = %cond.false8, %cond.true7
%58 = load i32* %retval
ret i32 %58
}
declare void @__assert_func(i8*, i32, i8*, i8*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment