| Index: test/Transforms/NaCl/atomic/atomic_others.ll | 
| diff --git a/test/Transforms/NaCl/atomic/atomic_others.ll b/test/Transforms/NaCl/atomic/atomic_others.ll | 
| index efc834b3db8502085f37135fbcd0d9ac29e52f5a..a510d45a54a41888cc38cc7a1505f7d7d4cd384a 100644 | 
| --- a/test/Transforms/NaCl/atomic/atomic_others.ll | 
| +++ b/test/Transforms/NaCl/atomic/atomic_others.ll | 
| @@ -1,8 +1,9 @@ | 
| ; RUN: opt -nacl-rewrite-atomics -S < %s | FileCheck %s | 
| ; | 
| -; Validate that atomic non-sequentially consistent loads/stores get rewritten | 
| -; into NaCl atomic builtins with sequentially consistent memory ordering (enum | 
| -; value 6). This will change once we support other memory orderings. | 
| +; Validate that atomic non-{acquire/release/acq_rel/seq_cst} loads/stores get | 
| +; rewritten into NaCl atomic builtins with sequentially consistent memory | 
| +; ordering (enum value 6), and that acquire/release/acq_rel remain as-is (enum | 
| +; values 3/4/5). | 
| ; | 
| ; Note that monotonic doesn't exist in C11/C++11, and consume isn't implemented | 
| ; in LLVM yet. | 
| @@ -39,21 +40,91 @@ define void @test_atomic_store_unordered_i32(i32* %ptr, i32 %value) { | 
|  | 
| ; CHECK-LABEL: @test_atomic_load_acquire_i32 | 
| define i32 @test_atomic_load_acquire_i32(i32* %ptr) { | 
| -  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6) | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 3) | 
| %res = load atomic i32* %ptr acquire, align 4 | 
| ret i32 %res  ; CHECK-NEXT: ret i32 %res | 
| } | 
|  | 
| ; CHECK-LABEL: @test_atomic_store_release_i32 | 
| define void @test_atomic_store_release_i32(i32* %ptr, i32 %value) { | 
| -  ; CHECK-NEXT: call void @llvm.nacl.atomic.store.i32(i32 %value, i32* %ptr, i32 6) | 
| +  ; CHECK-NEXT: call void @llvm.nacl.atomic.store.i32(i32 %value, i32* %ptr, i32 4) | 
| store atomic i32 %value, i32* %ptr release, align 4 | 
| ret void  ; CHECK-NEXT: ret void | 
| } | 
|  | 
| -; CHECK: @test_fetch_and_add_i32 | 
| +; CHECK-LABEL: @test_fetch_and_add_i32 | 
| define i32 @test_fetch_and_add_i32(i32* %ptr, i32 %value) { | 
| -  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %value, i32 6) | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %value, i32 5) | 
| %res = atomicrmw add i32* %ptr, i32 %value acq_rel | 
| ret i32 %res  ; CHECK-NEXT: ret i32 %res | 
| } | 
| + | 
| +; Test all the valid cmpxchg orderings for success and failure. | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_seqcst_seqcst | 
| +define { i32, i1 } @test_cmpxchg_seqcst_seqcst(i32* %ptr, i32 %value) { | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 6, i32 6) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value seq_cst seq_cst | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_seqcst_acquire | 
| +define { i32, i1 } @test_cmpxchg_seqcst_acquire(i32* %ptr, i32 %value) { | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 6, i32 3) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value seq_cst acquire | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_seqcst_relaxed | 
| +define { i32, i1 } @test_cmpxchg_seqcst_relaxed(i32* %ptr, i32 %value) { | 
| +  ; Failure ordering is upgraded. | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 6, i32 6) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value seq_cst monotonic | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_acqrel_acquire | 
| +define { i32, i1 } @test_cmpxchg_acqrel_acquire(i32* %ptr, i32 %value) { | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 5, i32 3) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value acq_rel acquire | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_acqrel_relaxed | 
| +define { i32, i1 } @test_cmpxchg_acqrel_relaxed(i32* %ptr, i32 %value) { | 
| +  ; Success and failure ordering are upgraded. | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 6, i32 6) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value acq_rel monotonic | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_release_relaxed | 
| +define { i32, i1 } @test_cmpxchg_release_relaxed(i32* %ptr, i32 %value) { | 
| +  ; Success and failure ordering are upgraded. | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 6, i32 6) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value release monotonic | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_acquire_acquire | 
| +define { i32, i1 } @test_cmpxchg_acquire_acquire(i32* %ptr, i32 %value) { | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 3, i32 3) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value acquire acquire | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_acquire_relaxed | 
| +define { i32, i1 } @test_cmpxchg_acquire_relaxed(i32* %ptr, i32 %value) { | 
| +  ; Failure ordering is upgraded. | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 3, i32 3) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value acquire monotonic | 
| +  ret { i32, i1 } %res | 
| +} | 
| + | 
| +; CHECK-LABEL: @test_cmpxchg_relaxed_relaxed | 
| +define { i32, i1 } @test_cmpxchg_relaxed_relaxed(i32* %ptr, i32 %value) { | 
| +  ; Failure ordering is upgraded. | 
| +  ; CHECK-NEXT: %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 0, i32 %value, i32 6, i32 6) | 
| +  %res = cmpxchg i32* %ptr, i32 0, i32 %value monotonic monotonic | 
| +  ret { i32, i1 } %res | 
| +} | 
|  |