[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