summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLogan Chien <tzuhsiang.chien@gmail.com>2014-03-26 17:35:01 +0000
committerLogan Chien <tzuhsiang.chien@gmail.com>2014-03-26 17:35:01 +0000
commit74798a34e67258b9bd23df1b39e0c854a355e1c1 (patch)
tree39ebb7e29836caf13b69849ed3a67865ec33790d
parented2cd39b81d09c424217dcf60917a059379cc867 (diff)
downloadbcm5719-llvm-74798a34e67258b9bd23df1b39e0c854a355e1c1.tar.gz
bcm5719-llvm-74798a34e67258b9bd23df1b39e0c854a355e1c1.zip
Fix atomic libcall.
This commit fixes a cast instruction assertion failure due to the incompatible type cast. This will only happen when the target requires atomic libcalls. llvm-svn: 204834
-rw-r--r--clang/lib/CodeGen/CGAtomic.cpp6
-rw-r--r--clang/test/CodeGen/atomic-ops-libcall.c37
2 files changed, 41 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 3e996f377a8..7c7c80c5707 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -577,6 +577,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
Args.add(RValue::get(EmitCastToVoidPtr(Ptr)), getContext().VoidPtrTy);
std::string LibCallName;
+ QualType LoweredMemTy =
+ MemTy->isPointerType() ? getContext().getIntPtrType() : MemTy;
QualType RetTy;
bool HaveRetTy = false;
switch (E->getOp()) {
@@ -632,7 +634,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
case AtomicExpr::AO__c11_atomic_fetch_add:
case AtomicExpr::AO__atomic_fetch_add:
LibCallName = "__atomic_fetch_add";
- AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
+ AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy,
E->getExprLoc());
break;
// T __atomic_fetch_and_N(T *mem, T val, int order)
@@ -653,7 +655,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
case AtomicExpr::AO__c11_atomic_fetch_sub:
case AtomicExpr::AO__atomic_fetch_sub:
LibCallName = "__atomic_fetch_sub";
- AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
+ AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy,
E->getExprLoc());
break;
// T __atomic_fetch_xor_N(T *mem, T val, int order)
diff --git a/clang/test/CodeGen/atomic-ops-libcall.c b/clang/test/CodeGen/atomic-ops-libcall.c
new file mode 100644
index 00000000000..2a2ff5e80fc
--- /dev/null
+++ b/clang/test/CodeGen/atomic-ops-libcall.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 < %s -triple armv5e-none-linux-gnueabi -emit-llvm -O1 | FileCheck %s
+
+enum memory_order {
+ memory_order_relaxed, memory_order_consume, memory_order_acquire,
+ memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+};
+
+int *test_c11_atomic_fetch_add_int_ptr(_Atomic(int *) *p) {
+ // CHECK: test_c11_atomic_fetch_add_int_ptr
+ // CHECK: {{%[^ ]*}} = tail call i32* @__atomic_fetch_add_4(i8* {{%[0-9]+}}, i32 12, i32 5)
+ return __c11_atomic_fetch_add(p, 3, memory_order_seq_cst);
+}
+
+int *test_c11_atomic_fetch_sub_int_ptr(_Atomic(int *) *p) {
+ // CHECK: test_c11_atomic_fetch_sub_int_ptr
+ // CHECK: {{%[^ ]*}} = tail call i32* @__atomic_fetch_sub_4(i8* {{%[0-9]+}}, i32 20, i32 5)
+ return __c11_atomic_fetch_sub(p, 5, memory_order_seq_cst);
+}
+
+int test_c11_atomic_fetch_add_int(_Atomic(int) *p) {
+ // CHECK: test_c11_atomic_fetch_add_int
+ // CHECK: {{%[^ ]*}} = tail call i32 bitcast (i32* (i8*, i32, i32)* @__atomic_fetch_add_4 to i32 (i8*, i32, i32)*)(i8* {{%[0-9]+}}, i32 3, i32 5)
+ return __c11_atomic_fetch_add(p, 3, memory_order_seq_cst);
+}
+
+int test_c11_atomic_fetch_sub_int(_Atomic(int) *p) {
+ // CHECK: test_c11_atomic_fetch_sub_int
+ // CHECK: {{%[^ ]*}} = tail call i32 bitcast (i32* (i8*, i32, i32)* @__atomic_fetch_sub_4 to i32 (i8*, i32, i32)*)(i8* {{%[0-9]+}}, i32 5, i32 5)
+ return __c11_atomic_fetch_sub(p, 5, memory_order_seq_cst);
+}
+
+int *fp2a(int **p) {
+ // CHECK: @fp2a
+ // CHECK: {{%[^ ]*}} = tail call i32* @__atomic_fetch_sub_4(i8* {{%[0-9]+}}, i32 4, i32 0)
+ // Note, the GNU builtins do not multiply by sizeof(T)!
+ return __atomic_fetch_sub(p, 4, memory_order_relaxed);
+}
OpenPOWER on IntegriCloud