117 lines · c
1// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \2// RUN: -triple x86_64--windows -Oz -emit-llvm -target-feature +cx16 %s -o - \3// RUN: | FileCheck %s --check-prefixes=CHECK4 5// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \6// RUN: -triple aarch64--windows -Oz -emit-llvm %s -o - \7// RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-AARCH648 9// Ensure that we emit _Interlocked atomic operations specifying natural10// alignment, even when clang's usual alignment derivation would result in a11// lower alignment value.12 13// intrin.h needs size_t, but -ffreestanding prevents us from getting it from14// stddef.h. Work around it with this typedef.15typedef __SIZE_TYPE__ size_t;16 17#include <intrin.h>18 19#pragma pack(1)20typedef struct {21 char a;22 short b;23 long c;24 long long d;25 void *p;26} X;27 28_Static_assert(sizeof(X) == 23, "");29_Static_assert(__alignof__(X) == 1, "");30 31// CHECK-LABEL: @test_InterlockedExchangePointer(32// CHECK: atomicrmw {{.*}} align 833void *test_InterlockedExchangePointer(X *x) {34 return _InterlockedExchangePointer(&x->p, 0);35}36 37// CHECK-LABEL: @test_InterlockedExchange8(38// CHECK: atomicrmw {{.*}} align 139char test_InterlockedExchange8(X *x) {40 return _InterlockedExchange8(&x->a, 0);41}42 43// CHECK-LABEL: @test_InterlockedExchange16(44// CHECK: atomicrmw {{.*}} align 245short test_InterlockedExchange16(X *x) {46 return _InterlockedExchange16(&x->b, 0);47}48 49// CHECK-LABEL: @test_InterlockedExchange(50// CHECK: atomicrmw {{.*}} align 451long test_InterlockedExchange(X *x) {52 return _InterlockedExchange(&x->c, 0);53}54 55// CHECK-LABEL: @test_InterlockedExchange64(56// CHECK: atomicrmw {{.*}} align 857long long test_InterlockedExchange64(X *x) {58 return _InterlockedExchange64(&x->d, 0);59}60 61// CHECK-LABEL: @test_InterlockedIncrement(62// CHECK: atomicrmw {{.*}} align 463long test_InterlockedIncrement(X *x) {64 return _InterlockedIncrement(&x->c);65}66 67// CHECK-LABEL: @test_InterlockedDecrement16(68// CHECK: atomicrmw {{.*}} align 269short test_InterlockedDecrement16(X *x) {70 return _InterlockedDecrement16(&x->b);71}72 73 74// CHECK-LABEL: @test_InterlockedCompareExchangePointer(75// CHECK: cmpxchg {{.*}} align 876void *test_InterlockedCompareExchangePointer(X *x) {77 return _InterlockedCompareExchangePointer(&x->p, 0, 0);78}79 80// CHECK-LABEL: @test_InterlockedCompareExchange8(81// CHECK: cmpxchg {{.*}} align 182char test_InterlockedCompareExchange8(X *x) {83 return _InterlockedCompareExchange8(&x->a, 0, 0);84}85 86// CHECK-LABEL: @test_InterlockedCompareExchange16(87// CHECK: cmpxchg {{.*}} align 288short test_InterlockedCompareExchange16(X *x) {89 return _InterlockedCompareExchange16(&x->b, 0, 0);90}91 92// CHECK-LABEL: @test_InterlockedCompareExchange(93// CHECK: cmpxchg {{.*}} align 494long test_InterlockedCompareExchange(X *x) {95 return _InterlockedCompareExchange(&x->c, 0, 0);96}97 98// CHECK-LABEL: @test_InterlockedCompareExchange64(99// CHECK: cmpxchg {{.*}} align 8100long long test_InterlockedCompareExchange64(X *x) {101 return _InterlockedCompareExchange64(&x->d, 0, 0);102}103 104#ifdef __aarch64__105// CHECK-AARCH64-LABEL: @test_InterlockedAdd(106// CHECK-AARCH64: atomicrmw {{.*}} align 4107long test_InterlockedAdd(X *x) {108 return _InterlockedAdd(&x->c, 4);109}110 111// CHECK-AARCH64-LABEL: @test_InterlockedAdd64(112// CHECK-AARCH64: atomicrmw {{.*}} align 8113long test_InterlockedAdd64(X *x) {114 return _InterlockedAdd64((volatile long long*)&x->c, 4);115}116#endif117