
The ability to specify alignment was recently added, and it's an important property which we should ensure is set as expected by Clang. (Especially before making further changes to Clang's code in this area.) But, because it's on the end of the lines, the existing tests all ignore it. Therefore, update all the tests to also verify the expected alignment for atomicrmw and cmpxchg. While I was in there, I also updated uses of 'load atomic' and 'store atomic', and added the memory ordering, where that was missing.
117 lines
3.3 KiB
C
117 lines
3.3 KiB
C
// RUN: %clang_cc1 -triple x86_64 -emit-llvm %s \
|
|
// RUN: -o - | FileCheck -check-prefixes=CHECK,NATIVE %s
|
|
// RUN: %clang_cc1 -triple riscv32 -target-feature -a -emit-llvm %s \
|
|
// RUN: -o - | FileCheck -check-prefixes=CHECK,LIBCALL %s
|
|
|
|
void foo(int x)
|
|
{
|
|
_Atomic(int) i = 0;
|
|
_Atomic(short) j = 0;
|
|
// Check that multiply / divides on atomics produce a cmpxchg loop
|
|
i *= 2;
|
|
// NATIVE: mul nsw i32
|
|
// NATIVE: cmpxchg i32* {{.*}} seq_cst, align 4
|
|
// LIBCALL: mul nsw i32
|
|
// LIBCALL: i1 @__atomic_compare_exchange(i32 4,
|
|
i /= 2;
|
|
// NATIVE: sdiv i32
|
|
// NATIVE: cmpxchg i32* {{.*}} seq_cst, align 4
|
|
// LIBCALL: sdiv i32
|
|
// LIBCALL: i1 @__atomic_compare_exchange(i32 4,
|
|
j /= x;
|
|
// NATIVE: sdiv i32
|
|
// NATIVE: cmpxchg i16* {{.*}} seq_cst, align 2
|
|
// LIBCALL: sdiv i32
|
|
// LIBCALL: i1 @__atomic_compare_exchange(i32 2,
|
|
|
|
}
|
|
|
|
// LIBCALL: declare void @__atomic_load(i32, i8*, i8*, i32) [[LC_ATTRS:#[0-9]+]]
|
|
// LIBCALL: declare i1 @__atomic_compare_exchange(i32, i8*, i8*, i8*, i32, i32) [[LC_ATTRS:#[0-9]+]]
|
|
|
|
extern _Atomic _Bool b;
|
|
|
|
_Bool bar() {
|
|
// NATIVE-LABEL: @bar
|
|
// NATIVE: %[[load:.*]] = load atomic i8, i8* @b seq_cst, align 1
|
|
// NATIVE: %[[tobool:.*]] = trunc i8 %[[load]] to i1
|
|
// NATIVE: ret i1 %[[tobool]]
|
|
// LIBCALL-LABEL: @bar
|
|
// LIBCALL: call void @__atomic_load(i32 1, i8* @b, i8* %atomic-temp, i32 5)
|
|
// LIBCALL: %[[load:.*]] = load i8, i8* %atomic-temp
|
|
// LIBCALL: %[[tobool:.*]] = trunc i8 %[[load]] to i1
|
|
// LIBCALL: ret i1 %[[tobool]]
|
|
|
|
return b;
|
|
}
|
|
|
|
extern _Atomic(_Complex int) x;
|
|
|
|
void baz(int y) {
|
|
// NATIVE-LABEL: @baz
|
|
// NATIVE: store atomic i64 {{.*}} seq_cst, align 8
|
|
// LIBCALL-LABEL: @baz
|
|
// LIBCALL: call void @__atomic_store
|
|
|
|
x += y;
|
|
}
|
|
|
|
// LIBCALL: declare void @__atomic_store(i32, i8*, i8*, i32) [[LC_ATTRS:#[0-9]+]]
|
|
|
|
_Atomic(int) compound_add(_Atomic(int) in) {
|
|
// CHECK-LABEL: @compound_add
|
|
// CHECK: [[OLD:%.*]] = atomicrmw add i32* {{.*}}, i32 5 seq_cst, align 4
|
|
// CHECK: [[NEW:%.*]] = add i32 [[OLD]], 5
|
|
// CHECK: ret i32 [[NEW]]
|
|
|
|
return (in += 5);
|
|
}
|
|
|
|
_Atomic(int) compound_sub(_Atomic(int) in) {
|
|
// CHECK-LABEL: @compound_sub
|
|
// CHECK: [[OLD:%.*]] = atomicrmw sub i32* {{.*}}, i32 5 seq_cst, align 4
|
|
// CHECK: [[NEW:%.*]] = sub i32 [[OLD]], 5
|
|
// CHECK: ret i32 [[NEW]]
|
|
|
|
return (in -= 5);
|
|
}
|
|
|
|
_Atomic(int) compound_xor(_Atomic(int) in) {
|
|
// CHECK-LABEL: @compound_xor
|
|
// CHECK: [[OLD:%.*]] = atomicrmw xor i32* {{.*}}, i32 5 seq_cst, align 4
|
|
// CHECK: [[NEW:%.*]] = xor i32 [[OLD]], 5
|
|
// CHECK: ret i32 [[NEW]]
|
|
|
|
return (in ^= 5);
|
|
}
|
|
|
|
_Atomic(int) compound_or(_Atomic(int) in) {
|
|
// CHECK-LABEL: @compound_or
|
|
// CHECK: [[OLD:%.*]] = atomicrmw or i32* {{.*}}, i32 5 seq_cst, align 4
|
|
// CHECK: [[NEW:%.*]] = or i32 [[OLD]], 5
|
|
// CHECK: ret i32 [[NEW]]
|
|
|
|
return (in |= 5);
|
|
}
|
|
|
|
_Atomic(int) compound_and(_Atomic(int) in) {
|
|
// CHECK-LABEL: @compound_and
|
|
// CHECK: [[OLD:%.*]] = atomicrmw and i32* {{.*}}, i32 5 seq_cst, align 4
|
|
// CHECK: [[NEW:%.*]] = and i32 [[OLD]], 5
|
|
// CHECK: ret i32 [[NEW]]
|
|
|
|
return (in &= 5);
|
|
}
|
|
|
|
_Atomic(int) compound_mul(_Atomic(int) in) {
|
|
// NATIVE-LABEL: @compound_mul
|
|
// NATIVE: cmpxchg i32* {{%.*}}, i32 {{%.*}}, i32 [[NEW:%.*]] seq_cst seq_cst, align 4
|
|
// NATIVE: ret i32 [[NEW]]
|
|
// LIBCALL-LABEL: @compound_mul
|
|
// LIBCALL: i1 @__atomic_compare_exchange(i32 4,
|
|
|
|
return (in *= 5);
|
|
}
|
|
|
|
// LIBCALL: [[LC_ATTRS]] = { nounwind willreturn }
|