xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/atomic_idempotent.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=x86-64 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=X64
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=x86 -mattr=+sse2 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=X32
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; On x86, an atomic rmw operation that does not modify the value in memory
5*9880d681SAndroid Build Coastguard Worker; (such as atomic add 0) can be replaced by an mfence followed by a mov.
6*9880d681SAndroid Build Coastguard Worker; This is explained (with the motivation for such an optimization) in
7*9880d681SAndroid Build Coastguard Worker; http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Workerdefine i8 @add8(i8* %p) {
10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: add8
11*9880d681SAndroid Build Coastguard Worker; CHECK: mfence
12*9880d681SAndroid Build Coastguard Worker; CHECK: movb
13*9880d681SAndroid Build Coastguard Worker  %1 = atomicrmw add i8* %p, i8 0 monotonic
14*9880d681SAndroid Build Coastguard Worker  ret i8 %1
15*9880d681SAndroid Build Coastguard Worker}
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerdefine i16 @or16(i16* %p) {
18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or16
19*9880d681SAndroid Build Coastguard Worker; CHECK: mfence
20*9880d681SAndroid Build Coastguard Worker; CHECK: movw
21*9880d681SAndroid Build Coastguard Worker  %1 = atomicrmw or i16* %p, i16 0 acquire
22*9880d681SAndroid Build Coastguard Worker  ret i16 %1
23*9880d681SAndroid Build Coastguard Worker}
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Workerdefine i32 @xor32(i32* %p) {
26*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: xor32
27*9880d681SAndroid Build Coastguard Worker; CHECK: mfence
28*9880d681SAndroid Build Coastguard Worker; CHECK: movl
29*9880d681SAndroid Build Coastguard Worker  %1 = atomicrmw xor i32* %p, i32 0 release
30*9880d681SAndroid Build Coastguard Worker  ret i32 %1
31*9880d681SAndroid Build Coastguard Worker}
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Workerdefine i64 @sub64(i64* %p) {
34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sub64
35*9880d681SAndroid Build Coastguard Worker; X64: mfence
36*9880d681SAndroid Build Coastguard Worker; X64: movq
37*9880d681SAndroid Build Coastguard Worker; X32-NOT: mfence
38*9880d681SAndroid Build Coastguard Worker  %1 = atomicrmw sub i64* %p, i64 0 seq_cst
39*9880d681SAndroid Build Coastguard Worker  ret i64 %1
40*9880d681SAndroid Build Coastguard Worker}
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Workerdefine i128 @or128(i128* %p) {
43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or128
44*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mfence
45*9880d681SAndroid Build Coastguard Worker  %1 = atomicrmw or i128* %p, i128 0 monotonic
46*9880d681SAndroid Build Coastguard Worker  ret i128 %1
47*9880d681SAndroid Build Coastguard Worker}
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; For 'and', the idempotent value is (-1)
50*9880d681SAndroid Build Coastguard Workerdefine i32 @and32 (i32* %p) {
51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: and32
52*9880d681SAndroid Build Coastguard Worker; CHECK: mfence
53*9880d681SAndroid Build Coastguard Worker; CHECK: movl
54*9880d681SAndroid Build Coastguard Worker  %1 = atomicrmw and i32* %p, i32 -1 acq_rel
55*9880d681SAndroid Build Coastguard Worker  ret i32 %1
56*9880d681SAndroid Build Coastguard Worker}
57