| Index: tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll
|
| diff --git a/tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll b/tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll
|
| index 3bb7131994e1fef6275d70f7a1f253b760882f52..a0b8b6c5e8c9ca0acb208e432f899a17d4ce39e1 100644
|
| --- a/tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll
|
| +++ b/tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll
|
| @@ -919,3 +919,91 @@ not_lock_free:
|
| ; CHECK: ret
|
| ; CHECK: add
|
| ; CHECK: ret
|
| +
|
| +; Test the liveness / register allocation properties of the xadd instruction.
|
| +; Make sure we model that the Src register is modified and therefore it can't
|
| +; share a register with an overlapping live range, even if the result of the
|
| +; xadd instruction is unused.
|
| +define void @test_xadd_regalloc() {
|
| +entry:
|
| + br label %body
|
| +body:
|
| + %i = phi i32 [ 1, %entry ], [ %i_plus_1, %body ]
|
| + %g = bitcast [4 x i8]* @Global32 to i32*
|
| + %unused = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %g, i32 %i, i32 6)
|
| + %i_plus_1 = add i32 %i, 1
|
| + %cmp = icmp eq i32 %i_plus_1, 1001
|
| + br i1 %cmp, label %done, label %body
|
| +done:
|
| + ret void
|
| +}
|
| +; O2-LABEL: test_xadd_regalloc
|
| +;;; Some register will be used in the xadd instruction.
|
| +; O2: lock xadd DWORD PTR {{.*}},[[REG:e..]]
|
| +;;; Make sure that register isn't used again, e.g. as the induction variable.
|
| +; O2-NOT: [[REG]]
|
| +; O2: ret
|
| +
|
| +; Do the same test for the xchg instruction instead of xadd.
|
| +define void @test_xchg_regalloc() {
|
| +entry:
|
| + br label %body
|
| +body:
|
| + %i = phi i32 [ 1, %entry ], [ %i_plus_1, %body ]
|
| + %g = bitcast [4 x i8]* @Global32 to i32*
|
| + %unused = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %g, i32 %i, i32 6)
|
| + %i_plus_1 = add i32 %i, 1
|
| + %cmp = icmp eq i32 %i_plus_1, 1001
|
| + br i1 %cmp, label %done, label %body
|
| +done:
|
| + ret void
|
| +}
|
| +; O2-LABEL: test_xchg_regalloc
|
| +;;; Some register will be used in the xchg instruction.
|
| +; O2: xchg DWORD PTR {{.*}},[[REG:e..]]
|
| +;;; Make sure that register isn't used again, e.g. as the induction variable.
|
| +; O2-NOT: [[REG]]
|
| +; O2: ret
|
| +
|
| +; Same test for cmpxchg.
|
| +define void @test_cmpxchg_regalloc() {
|
| +entry:
|
| + br label %body
|
| +body:
|
| + %i = phi i32 [ 1, %entry ], [ %i_plus_1, %body ]
|
| + %g = bitcast [4 x i8]* @Global32 to i32*
|
| + %unused = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %g, i32 %i, i32 %i, i32 6, i32 6)
|
| + %i_plus_1 = add i32 %i, 1
|
| + %cmp = icmp eq i32 %i_plus_1, 1001
|
| + br i1 %cmp, label %done, label %body
|
| +done:
|
| + ret void
|
| +}
|
| +; O2-LABEL: test_cmpxchg_regalloc
|
| +;;; eax and some other register will be used in the cmpxchg instruction.
|
| +; O2: lock cmpxchg DWORD PTR {{.*}},[[REG:e..]]
|
| +;;; Make sure eax isn't used again, e.g. as the induction variable.
|
| +; O2-NOT: eax
|
| +; O2: ret
|
| +
|
| +; Same test for cmpxchg8b.
|
| +define void @test_cmpxchg8b_regalloc() {
|
| +entry:
|
| + br label %body
|
| +body:
|
| + %i = phi i32 [ 1, %entry ], [ %i_plus_1, %body ]
|
| + %g = bitcast [8 x i8]* @Global64 to i64*
|
| + %i_64 = zext i32 %i to i64
|
| + %unused = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %g, i64 %i_64, i64 %i_64, i32 6, i32 6)
|
| + %i_plus_1 = add i32 %i, 1
|
| + %cmp = icmp eq i32 %i_plus_1, 1001
|
| + br i1 %cmp, label %done, label %body
|
| +done:
|
| + ret void
|
| +}
|
| +; O2-LABEL: test_cmpxchg8b_regalloc
|
| +;;; eax and some other register will be used in the cmpxchg instruction.
|
| +; O2: lock cmpxchg8b QWORD PTR
|
| +;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable.
|
| +; O2-NOT: {{eax|ecx|edx|ebx}}
|
| +; O2: pop ebx
|
|
|