Author: Jinsong Ji Date: 2021-06-25T01:08:48Z New Revision: f3ef4f5bff26ac4196a15dad7773a03b9d6df21d
URL: https://github.com/llvm/llvm-project/commit/f3ef4f5bff26ac4196a15dad7773a03b9d6df21d DIFF: https://github.com/llvm/llvm-project/commit/f3ef4f5bff26ac4196a15dad7773a03b9d6df21d.diff LOG: [PowerPC] Add XL compat __compare_and_swap builtins Prototype int __compare_and_swap (volatile int* addr, int* old_val_addr, int new_val); int __compare_and_swaplp (volatile long* addr, long* old_val_addr, long new_val); Refer to https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=functions-compare-swap-compare-swaplp Reviewed By: w2yehia Differential Revision: https://reviews.llvm.org/D104837 Added: clang/test/CodeGen/builtins-ppc-xlcompat-cas-error.c clang/test/CodeGen/builtins-ppc-xlcompat-cas.c Modified: clang/include/clang/Basic/BuiltinsPPC.def clang/lib/Basic/Targets/PPC.cpp clang/lib/CodeGen/CGBuiltin.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 9d7f765a2133c..47b485473342b 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -45,6 +45,8 @@ BUILTIN(__builtin_ppc_dcbt, "vv*", "") BUILTIN(__builtin_ppc_dcbtst, "vv*", "") BUILTIN(__builtin_ppc_dcbz, "vv*", "") BUILTIN(__builtin_ppc_icbt, "vv*", "") +BUILTIN(__builtin_ppc_compare_and_swap, "iiD*i*i", "") +BUILTIN(__builtin_ppc_compare_and_swaplp, "iLiD*Li*Li", "") BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n") diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 3dfc0c0751e44..e051826c52168 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -97,6 +97,9 @@ static void defineXLCompatMacros(MacroBuilder &Builder) { Builder.defineMacro("__dcbtst", "__builtin_ppc_dcbtst"); Builder.defineMacro("__dcbz", "__builtin_ppc_dcbz"); Builder.defineMacro("__icbt", "__builtin_ppc_icbt"); + Builder.defineMacro("__compare_and_swap", "__builtin_ppc_compare_and_swap"); + Builder.defineMacro("__compare_and_swaplp", + "__builtin_ppc_compare_and_swaplp"); } /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index da16ee3ea722f..e8ad4e009bfb2 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -15427,6 +15427,19 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Value *Call = Builder.CreateCall(F, CallOps); return Builder.CreateAlignedStore(Call, Ops[0], MaybeAlign(64)); } + + case PPC::BI__builtin_ppc_compare_and_swap: + case PPC::BI__builtin_ppc_compare_and_swaplp: { + Address Addr = EmitPointerWithAlignment(E->getArg(0)); + Address OldValAddr = EmitPointerWithAlignment(E->getArg(1)); + Value *OldVal = Builder.CreateLoad(OldValAddr); + QualType AtomicTy = E->getArg(0)->getType()->getPointeeType(); + LValue LV = MakeAddrLValue(Addr, AtomicTy); + auto Pair = EmitAtomicCompareExchange( + LV, RValue::get(OldVal), RValue::get(Ops[2]), E->getExprLoc(), + llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Monotonic, true); + return Pair.second; + } } } diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-cas-error.c b/clang/test/CodeGen/builtins-ppc-xlcompat-cas-error.c new file mode 100644 index 0000000000000..c35c54d6b1858 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-cas-error.c @@ -0,0 +1,19 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc64-unknown-aix -target-cpu pwr8 \ +// RUN: -verify %s + +void test_builtin_ppc_compare_and_swap() { + volatile int a = 0; + long b = 0, c = 0; + + __compare_and_swap(&a, &b, c); // expected-warning {{incompatible pointer types passing 'long *' to parameter of type 'int *'}} + +} + +void test_builtin_ppc_compare_and_swaplp() { + volatile long a = 0; + int b = 0, c = 0; + + __compare_and_swaplp(&a, &b, c);// expected-warning {{incompatible pointer types passing 'int *' to parameter of type 'long *'}} + +} diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-cas.c b/clang/test/CodeGen/builtins-ppc-xlcompat-cas.c new file mode 100644 index 0000000000000..ea4b349d9a523 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-cas.c @@ -0,0 +1,47 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s + + +// CHECK-LABEL: @test_builtin_ppc_compare_and_swap( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4 +// CHECK-NEXT: store i32 [[B:%.*]], i32* [[B_ADDR]], align 4 +// CHECK-NEXT: store i32 [[C:%.*]], i32* [[C_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[C_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg weak volatile i32* [[A_ADDR]], i32 [[TMP1]], i32 [[TMP0]] monotonic monotonic, align 4 +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1 +// CHECK-NEXT: ret void +// +void test_builtin_ppc_compare_and_swap(int a, int b, int c) { + __compare_and_swap(&a, &b, c); +} + + +// CHECK-LABEL: @test_builtin_ppc_compare_and_swaplp( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8 +// CHECK-NEXT: store i64 [[B:%.*]], i64* [[B_ADDR]], align 8 +// CHECK-NEXT: store i64 [[C:%.*]], i64* [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg weak volatile i64* [[A_ADDR]], i64 [[TMP1]], i64 [[TMP0]] monotonic monotonic, align 8 +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1 +// CHECK-NEXT: ret void +// +void test_builtin_ppc_compare_and_swaplp(long a, long b, long c) { + __compare_and_swaplp(&a, &b, c); +} + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits