Luís Marques 0781e93a6e [CodeGen][RISCV] Fix clang/test/CodeGen/atomic_ops.c for RISC-V
By default the RISC-V target doesn't have the atomics standard extension
enabled. The first RUN line in `clang/test/CodeGen/atomic_ops.c` didn't
specify a target triple, which meant that on RISC-V Linux hosts it would
target RISC-V, but because it used clang cc1 we didn't get the toolchain
driver functionality to automatically turn on the extensions implied by
the target triple (riscv64-linux includes atomics). This would cause the
test to fail on RISC-V hosts.

This patch changes the test to have RUN lines for two explicit targets,
one with native atomics and one without. To work around FileCheck
limitations and more accurately match the output, some tests now have
separate prefixes for the two cases.

Reviewers: jyknight, eli.friedman, lenary, efriedma
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D74847
2020-02-21 19:29:57 +00:00

110 lines
2.8 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*
// LIBCALL: mul nsw i32
// LIBCALL: i1 @__atomic_compare_exchange(i32 4,
i /= 2;
// NATIVE: sdiv i32
// NATIVE: cmpxchg i32*
// LIBCALL: sdiv i32
// LIBCALL: i1 @__atomic_compare_exchange(i32 4,
j /= x;
// NATIVE: sdiv i32
// NATIVE: cmpxchg i16*
// LIBCALL: sdiv i32
// LIBCALL: i1 @__atomic_compare_exchange(i32 2,
}
extern _Atomic _Bool b;
_Bool bar() {
// NATIVE-LABEL: @bar
// NATIVE: %[[load:.*]] = load atomic i8, i8* @b seq_cst
// 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
// LIBCALL-LABEL: @baz
// LIBCALL: call void @__atomic_store
x += y;
}
_Atomic(int) compound_add(_Atomic(int) in) {
// CHECK-LABEL: @compound_add
// CHECK: [[OLD:%.*]] = atomicrmw add i32* {{.*}}, i32 5 seq_cst
// 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
// 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
// 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
// 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
// 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
// NATIVE: ret i32 [[NEW]]
// LIBCALL-LABEL: @compound_mul
// LIBCALL: i1 @__atomic_compare_exchange(i32 4,
return (in *= 5);
}