[clang] f3ef4f5 - [PowerPC] Add XL compat __compare_and_swap builtins
Jinsong Ji via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 24 18:32:02 PDT 2021
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);
+}
+
More information about the cfe-commits
mailing list