From 37196de31e6eab348030ef08cf2c3a78af42ee83 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 17 Nov 2012 17:30:55 +0000 Subject: [PATCH] Enable inlining of 4 byte atomic ops on ppc32, 8 byte atomic ops on ppc64. Also fixes a bit/byte mismatch when checking if a target supports atomic ops of a certain size. llvm-svn: 168260 --- clang/lib/Basic/Targets.cpp | 7 ++++++- clang/lib/CodeGen/CGExpr.cpp | 9 ++++----- clang/test/CodeGen/ppc-atomics.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/ppc-atomics.c diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 305dc7c..95f7d58 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -1037,6 +1037,9 @@ public: LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; } + + // PPC32 supports atomics up to 4 bytes. + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; } virtual BuiltinVaListKind getBuiltinVaListKind() const { @@ -1065,7 +1068,9 @@ public: DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" "v128:128:128-n32:64"; - + + // PPC64 supports atomics up to 8 bytes. + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } virtual BuiltinVaListKind getBuiltinVaListKind() const { return TargetInfo::CharPtrBuiltinVaList; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 393d3b9..cb274fc4 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3166,11 +3166,10 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) { uint64_t Size = sizeChars.getQuantity(); CharUnits alignChars = getContext().getTypeAlignInChars(AtomicTy); unsigned Align = alignChars.getQuantity(); - unsigned MaxInlineWidth = - getContext().getTargetInfo().getMaxAtomicInlineWidth(); - bool UseLibcall = (Size != Align || Size > MaxInlineWidth); - - + unsigned MaxInlineWidthInBits = + getContext().getTargetInfo().getMaxAtomicInlineWidth(); + bool UseLibcall = (Size != Align || + getContext().toBits(sizeChars) > MaxInlineWidthInBits); llvm::Value *Ptr, *Order, *OrderFail = 0, *Val1 = 0, *Val2 = 0; Ptr = EmitScalarExpr(E->getPtr()); diff --git a/clang/test/CodeGen/ppc-atomics.c b/clang/test/CodeGen/ppc-atomics.c new file mode 100644 index 0000000..3fcb0fb --- /dev/null +++ b/clang/test/CodeGen/ppc-atomics.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=32 +// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=64 + +unsigned char c1, c2; +unsigned short s1, s2; +unsigned int i1, i2; +unsigned long long ll1, ll2; + +enum memory_order { + memory_order_relaxed, + memory_order_consume, + memory_order_acquire, + memory_order_release, + memory_order_acq_rel, + memory_order_seq_cst +}; + +void test1(void) { + (void)__atomic_load(&c1, &c2, memory_order_seq_cst); + (void)__atomic_load(&s1, &s2, memory_order_seq_cst); + (void)__atomic_load(&i1, &i2, memory_order_seq_cst); + (void)__atomic_load(&ll1, &ll2, memory_order_seq_cst); + +// 32: define void @test1 +// 32: load atomic i8* @c1 seq_cst +// 32: load atomic i16* @s1 seq_cst +// 32: load atomic i32* @i1 seq_cst +// 32: call void @__atomic_load(i32 8, i8* bitcast (i64* @ll1 to i8*) + +// 64: define void @test1 +// 64: load atomic i8* @c1 seq_cst +// 64: load atomic i16* @s1 seq_cst +// 64: load atomic i32* @i1 seq_cst +// 64: load atomic i64* @ll1 seq_cst +} -- 2.7.4