[clang] eb237ff - [PowerPC] Add XL Compat fetch builtins

Jinsong Ji via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 27 19:52:49 PDT 2021


Author: Jinsong Ji
Date: 2021-06-28T02:52:32Z
New Revision: eb237ffca821839374574b2195c865765ebf5d09

URL: https://github.com/llvm/llvm-project/commit/eb237ffca821839374574b2195c865765ebf5d09
DIFF: https://github.com/llvm/llvm-project/commit/eb237ffca821839374574b2195c865765ebf5d09.diff

LOG: [PowerPC] Add XL Compat fetch builtins

Prototype
```
unsigned int __fetch_and_add (volatile unsigned int* addr, unsigned int
val);
unsigned long __fetch_and_addlp (volatile unsigned long* addr, unsigned
long val);
```
Ref:
https://www.ibm.com/docs/en/xl-c-and-cpp-linux/16.1.1?topic=functions-fetch

Reviewed By: #powerpc, w2yehia, lkail

Differential Revision: https://reviews.llvm.org/D104991

Added: 
    clang/test/CodeGen/builtins-ppc-xlcompat-fetch-error.c
    clang/test/CodeGen/builtins-ppc-xlcompat-fetch.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 47b485473342b..e07632d415109 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -47,6 +47,14 @@ 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_fetch_and_add, "UiUiD*Ui", "")
+BUILTIN(__builtin_ppc_fetch_and_addlp, "ULiULiD*ULi", "")
+BUILTIN(__builtin_ppc_fetch_and_and, "UiUiD*Ui", "")
+BUILTIN(__builtin_ppc_fetch_and_andlp, "ULiULiD*ULi", "")
+BUILTIN(__builtin_ppc_fetch_and_or, "UiUiD*Ui", "")
+BUILTIN(__builtin_ppc_fetch_and_orlp, "ULiULiD*ULi", "")
+BUILTIN(__builtin_ppc_fetch_and_swap, "UiUiD*Ui", "")
+BUILTIN(__builtin_ppc_fetch_and_swaplp, "ULiULiD*ULi", "")
 
 BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
 

diff  --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index e051826c52168..6860b5e5d02fa 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -100,6 +100,14 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   Builder.defineMacro("__compare_and_swap", "__builtin_ppc_compare_and_swap");
   Builder.defineMacro("__compare_and_swaplp",
                       "__builtin_ppc_compare_and_swaplp");
+  Builder.defineMacro("__fetch_and_add", "__builtin_ppc_fetch_and_add");
+  Builder.defineMacro("__fetch_and_addlp", "__builtin_ppc_fetch_and_addlp");
+  Builder.defineMacro("__fetch_and_and", "__builtin_ppc_fetch_and_and");
+  Builder.defineMacro("__fetch_and_andlp", "__builtin_ppc_fetch_and_andlp");
+  Builder.defineMacro("__fetch_and_or", "__builtin_ppc_fetch_and_or");
+  Builder.defineMacro("__fetch_and_orlp", "__builtin_ppc_fetch_and_orlp");
+  Builder.defineMacro("__fetch_and_swap", "__builtin_ppc_fetch_and_swap");
+  Builder.defineMacro("__fetch_and_swaplp", "__builtin_ppc_fetch_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 97f2db9bec2c8..2e9454921ffa8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -15440,6 +15440,27 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
         llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Monotonic, true);
     return Pair.second;
   }
+  case PPC::BI__builtin_ppc_fetch_and_add:
+  case PPC::BI__builtin_ppc_fetch_and_addlp: {
+    return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E,
+                                 llvm::AtomicOrdering::Monotonic);
+  }
+  case PPC::BI__builtin_ppc_fetch_and_and:
+  case PPC::BI__builtin_ppc_fetch_and_andlp: {
+    return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E,
+                                 llvm::AtomicOrdering::Monotonic);
+  }
+
+  case PPC::BI__builtin_ppc_fetch_and_or:
+  case PPC::BI__builtin_ppc_fetch_and_orlp: {
+    return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E,
+                                 llvm::AtomicOrdering::Monotonic);
+  }
+  case PPC::BI__builtin_ppc_fetch_and_swap:
+  case PPC::BI__builtin_ppc_fetch_and_swaplp: {
+    return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E,
+                                 llvm::AtomicOrdering::Monotonic);
+  }
   }
 }
 

diff  --git a/clang/test/CodeGen/builtins-ppc-xlcompat-fetch-error.c b/clang/test/CodeGen/builtins-ppc-xlcompat-fetch-error.c
new file mode 100644
index 0000000000000..a5124e3c10e93
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-xlcompat-fetch-error.c
@@ -0,0 +1,17 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -target-cpu pwr8 \
+// RUN:  -verify %s
+
+void test_builtin_ppc_fetch_and_add2() {
+  volatile int a = 0;
+  unsigned int b = 0;
+
+  __fetch_and_add(&a, b); // expected-warning {{passing 'volatile int *' to parameter of type 'volatile unsigned int *' converts between pointers to integer types with 
diff erent sign}}
+}
+
+void test_builtin_ppc_fetch_and_addlp() {
+  volatile long a = 0;
+  unsigned long b = 0;
+
+  __fetch_and_addlp(&a, b); // expected-warning {{passing 'volatile long *' to parameter of type 'volatile unsigned long *' converts between pointers to integer types with 
diff erent sign}}
+}

diff  --git a/clang/test/CodeGen/builtins-ppc-xlcompat-fetch.c b/clang/test/CodeGen/builtins-ppc-xlcompat-fetch.c
new file mode 100644
index 0000000000000..7d0b674b39c25
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-xlcompat-fetch.c
@@ -0,0 +1,120 @@
+// 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_fetch_and_add(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw add i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_add(unsigned int a, unsigned int b) {
+  __fetch_and_add(&a, b);
+}
+
+// CHECK-LABEL: @test_builtin_ppc_fetch_and_addlp(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw add i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_addlp(unsigned long a, unsigned long b) {
+  __fetch_and_addlp(&a, b);
+}
+// CHECK-LABEL: @test_builtin_ppc_fetch_and_and(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw and i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_and(unsigned int a, unsigned int b) {
+  __fetch_and_and(&a, b);
+}
+// CHECK-LABEL: @test_builtin_ppc_fetch_and_andlp(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw and i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_andlp(unsigned long a, unsigned long b) {
+  __fetch_and_andlp(&a, b);
+}
+// CHECK-LABEL: @test_builtin_ppc_fetch_and_or(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw or i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_or(unsigned int a, unsigned int b) {
+  __fetch_and_or(&a, b);
+}
+// CHECK-LABEL: @test_builtin_ppc_fetch_and_orlp(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw or i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_orlp(unsigned long a, unsigned long b) {
+  __fetch_and_orlp(&a, b);
+}
+// CHECK-LABEL: @test_builtin_ppc_fetch_and_swap(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw xchg i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_swap(unsigned int a, unsigned int b) {
+  __fetch_and_swap(&a, b);
+}
+// CHECK-LABEL: @test_builtin_ppc_fetch_and_swaplp(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[B_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:    [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw xchg i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT:    ret void
+//
+void test_builtin_ppc_fetch_and_swaplp(unsigned long a, unsigned long b) {
+  __fetch_and_swaplp(&a, b);
+}


        


More information about the cfe-commits mailing list