Skip to content

Commit d79311b

Browse files
committed
interlockedbittestand{set,reset}64_{acq,rel,nf} support for AArch64
1 parent 4f991cc commit d79311b

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,6 +2588,24 @@ def InterlockedBittestAndReset_rel : MSLangBuiltin {
25882588
let Prototype = "unsigned char(msint32_t volatile*, msint32_t)";
25892589
}
25902590

2591+
def InterlockedBittestAndReset64_acq : MSLangBuiltin {
2592+
let Spellings = ["_interlockedbittestandreset64_acq"];
2593+
let Attributes = [NoThrow];
2594+
let Prototype = "unsigned char(int64_t volatile*, int64_t)";
2595+
}
2596+
2597+
def InterlockedBittestAndReset64_nf : MSLangBuiltin {
2598+
let Spellings = ["_interlockedbittestandreset64_nf"];
2599+
let Attributes = [NoThrow];
2600+
let Prototype = "unsigned char(int64_t volatile*, int64_t)";
2601+
}
2602+
2603+
def InterlockedBittestAndReset64_rel : MSLangBuiltin {
2604+
let Spellings = ["_interlockedbittestandreset64_rel"];
2605+
let Attributes = [NoThrow];
2606+
let Prototype = "unsigned char(int64_t volatile*, int64_t)";
2607+
}
2608+
25912609
def InterlockedBittestAndSet : MSLangBuiltin, MSInt32_64Template {
25922610
let Spellings = ["_interlockedbittestandset"];
25932611
let Attributes = [NoThrow];
@@ -2612,6 +2630,24 @@ def InterlockedBittestAndSet_rel : MSLangBuiltin {
26122630
let Prototype = "unsigned char(msint32_t volatile*, msint32_t)";
26132631
}
26142632

2633+
def InterlockedBittestAndSet64_acq : MSLangBuiltin {
2634+
let Spellings = ["_interlockedbittestandset64_acq"];
2635+
let Attributes = [NoThrow];
2636+
let Prototype = "unsigned char(int64_t volatile*, int64_t)";
2637+
}
2638+
2639+
def InterlockedBittestAndSet64_nf : MSLangBuiltin {
2640+
let Spellings = ["_interlockedbittestandset64_nf"];
2641+
let Attributes = [NoThrow];
2642+
let Prototype = "unsigned char(int64_t volatile*, int64_t)";
2643+
}
2644+
2645+
def InterlockedBittestAndSet64_rel : MSLangBuiltin {
2646+
let Spellings = ["_interlockedbittestandset64_rel"];
2647+
let Attributes = [NoThrow];
2648+
let Prototype = "unsigned char(int64_t volatile*, int64_t)";
2649+
}
2650+
26152651
def IsoVolatileLoad : MSLangBuiltin, Int8_16_32_64Template {
26162652
let Spellings = ["__iso_volatile_load"];
26172653
let Attributes = [NoThrow];

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1589,7 +1589,7 @@ BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) {
15891589
case Builtin::BI_interlockedbittestandset:
15901590
return {Set, Sequential, false};
15911591

1592-
// X86-specific 64-bit variants.
1592+
// 64-bit variants.
15931593
case Builtin::BI_bittest64:
15941594
return {TestOnly, Unlocked, true};
15951595
case Builtin::BI_bittestandcomplement64:
@@ -1616,6 +1616,18 @@ BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) {
16161616
return {Reset, Release, false};
16171617
case Builtin::BI_interlockedbittestandreset_nf:
16181618
return {Reset, NoFence, false};
1619+
case Builtin::BI_interlockedbittestandreset64_acq:
1620+
return {Reset, Acquire, false};
1621+
case Builtin::BI_interlockedbittestandreset64_rel:
1622+
return {Reset, Release, false};
1623+
case Builtin::BI_interlockedbittestandreset64_nf:
1624+
return {Reset, NoFence, false};
1625+
case Builtin::BI_interlockedbittestandset64_acq:
1626+
return {Set, Acquire, false};
1627+
case Builtin::BI_interlockedbittestandset64_rel:
1628+
return {Set, Release, false};
1629+
case Builtin::BI_interlockedbittestandset64_nf:
1630+
return {Set, NoFence, false};
16191631
}
16201632
llvm_unreachable("expected only bittest intrinsics");
16211633
}
@@ -5538,7 +5550,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
55385550
case Builtin::BI_bittestandset:
55395551
case Builtin::BI_interlockedbittestandreset:
55405552
case Builtin::BI_interlockedbittestandreset64:
5553+
case Builtin::BI_interlockedbittestandreset64_acq:
5554+
case Builtin::BI_interlockedbittestandreset64_rel:
5555+
case Builtin::BI_interlockedbittestandreset64_nf:
55415556
case Builtin::BI_interlockedbittestandset64:
5557+
case Builtin::BI_interlockedbittestandset64_acq:
5558+
case Builtin::BI_interlockedbittestandset64_rel:
5559+
case Builtin::BI_interlockedbittestandset64_nf:
55425560
case Builtin::BI_interlockedbittestandset:
55435561
case Builtin::BI_interlockedbittestandset_acq:
55445562
case Builtin::BI_interlockedbittestandset_rel:

clang/lib/Headers/intrin.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,18 @@ static __inline__ void __DEFAULT_FN_ATTRS __nop(void) {
370370
\*----------------------------------------------------------------------------*/
371371
#if defined(__aarch64__) || defined(__arm64ec__)
372372
unsigned __int64 __getReg(int);
373+
unsigned char _interlockedbittestandreset_acq(long volatile *, long);
374+
unsigned char _interlockedbittestandreset_nf(long volatile *, long);
375+
unsigned char _interlockedbittestandreset_rel(long volatile *, long);
376+
unsigned char _interlockedbittestandreset64_acq(__int64 volatile *, __int64);
377+
unsigned char _interlockedbittestandreset64_nf(__int64 volatile *, __int64);
378+
unsigned char _interlockedbittestandreset64_rel(__int64 volatile *, __int64);
379+
unsigned char _interlockedbittestandset_acq(long volatile *, long);
380+
unsigned char _interlockedbittestandset_nf(long volatile *, long);
381+
unsigned char _interlockedbittestandset_rel(long volatile *, long);
382+
unsigned char _interlockedbittestandset64_acq(__int64 volatile *, __int64);
383+
unsigned char _interlockedbittestandset64_nf(__int64 volatile *, __int64);
384+
unsigned char _interlockedbittestandset64_rel(__int64 volatile *, __int64);
373385
long _InterlockedAdd(long volatile *Addend, long Value);
374386
__int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value);
375387
__int64 _ReadStatusReg(int);

clang/lib/Sema/SemaChecking.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2364,6 +2364,17 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
23642364
return ExprError();
23652365
break;
23662366

2367+
// The 64-bit acquire, release, and no fence variants are AArch64 only.
2368+
case Builtin::BI_interlockedbittestandreset64_acq:
2369+
case Builtin::BI_interlockedbittestandreset64_rel:
2370+
case Builtin::BI_interlockedbittestandreset64_nf:
2371+
case Builtin::BI_interlockedbittestandset64_acq:
2372+
case Builtin::BI_interlockedbittestandset64_rel:
2373+
case Builtin::BI_interlockedbittestandset64_nf:
2374+
if (CheckBuiltinTargetInSupported(*this, TheCall, {llvm::Triple::aarch64}))
2375+
return ExprError();
2376+
break;
2377+
23672378
case Builtin::BI__builtin_set_flt_rounds:
23682379
if (CheckBuiltinTargetInSupported(
23692380
*this, TheCall,

clang/test/CodeGen/bittest-intrin.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=X64
22
// RUN: %clang_cc1 -fms-extensions -triple thumbv7-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=ARM
3-
// RUN: %clang_cc1 -fms-extensions -triple aarch64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=ARM
3+
// RUN: %clang_cc1 -fms-extensions -triple aarch64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=ARM64 -check-prefix=ARM
44

55
volatile unsigned char sink = 0;
66
void test32(long *base, long idx) {
@@ -33,6 +33,17 @@ void test_arm(long *base, long idx) {
3333
}
3434
#endif
3535

36+
#if defined(_M_ARM64)
37+
void test_arm64(__int64 *base, __int64 idx) {
38+
sink = _interlockedbittestandreset64_acq(base, idx);
39+
sink = _interlockedbittestandreset64_rel(base, idx);
40+
sink = _interlockedbittestandreset64_nf(base, idx);
41+
sink = _interlockedbittestandset64_acq(base, idx);
42+
sink = _interlockedbittestandset64_rel(base, idx);
43+
sink = _interlockedbittestandset64_nf(base, idx);
44+
}
45+
#endif
46+
3647
// X64-LABEL: define dso_local void @test32(ptr noundef %base, i32 noundef %idx)
3748
// X64: call i8 asm sideeffect "btl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
3849
// X64: call i8 asm sideeffect "btcl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %{{.*}}, i32 {{.*}})
@@ -127,3 +138,11 @@ void test_arm(long *base, long idx) {
127138
// ARM: atomicrmw or ptr %{{.*}}, i8 {{.*}} acquire, align 1
128139
// ARM: atomicrmw or ptr %{{.*}}, i8 {{.*}} release, align 1
129140
// ARM: atomicrmw or ptr %{{.*}}, i8 {{.*}} monotonic, align 1
141+
142+
// ARM64-LABEL: define dso_local void @test_arm64(ptr noundef %base, i64 noundef %idx)
143+
// ARM64: atomicrmw and ptr %{{.*}}, i8 {{.*}} acquire, align 1
144+
// ARM64: atomicrmw and ptr %{{.*}}, i8 {{.*}} release, align 1
145+
// ARM64: atomicrmw and ptr %{{.*}}, i8 {{.*}} monotonic, align 1
146+
// ARM64: atomicrmw or ptr %{{.*}}, i8 {{.*}} acquire, align 1
147+
// ARM64: atomicrmw or ptr %{{.*}}, i8 {{.*}} release, align 1
148+
// ARM64: atomicrmw or ptr %{{.*}}, i8 {{.*}} monotonic, align 1

0 commit comments

Comments
 (0)