[clang] 7d10dd6 - [PowerPC] Implament Load and Reserve and Store Conditional Builtins

Albion Fung via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 5 19:35:54 PDT 2021


Author: Albion Fung
Date: 2021-07-05T21:35:41-05:00
New Revision: 7d10dd60ce126a6a0a29aa1f3948f596bd6e4fb0

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

LOG: [PowerPC] Implament Load and Reserve and Store Conditional Builtins

This patch implaments the load and reserve and store conditional
builtins for the PowerPC target, in order to have feature parody with
xlC on AIX.

Differential revision: https://reviews.llvm.org/D105236

Added: 
    clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c
    clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c
    clang/test/CodeGen/builtins-ppc-xlcompat-error.c
    llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll
    llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll

Modified: 
    clang/include/clang/Basic/BuiltinsPPC.def
    clang/lib/Basic/Targets/PPC.cpp
    clang/lib/Sema/SemaChecking.cpp
    llvm/include/llvm/IR/IntrinsicsPowerPC.td
    llvm/lib/Target/PowerPC/PPCInstr64Bit.td
    llvm/lib/Target/PowerPC/PPCInstrInfo.td

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index e07632d415109..baaf5db9d1453 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -55,6 +55,10 @@ 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_ldarx, "LiLiD*", "")
+BUILTIN(__builtin_ppc_lwarx, "iiD*", "")
+BUILTIN(__builtin_ppc_stdcx, "iLiD*Li", "")
+BUILTIN(__builtin_ppc_stwcx, "iiD*i", "")
 
 BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
 

diff  --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index d431dda970222..e3c77b2e4450b 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -108,6 +108,10 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   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");
+  Builder.defineMacro("__ldarx", "__builtin_ppc_ldarx");
+  Builder.defineMacro("__lwarx", "__builtin_ppc_lwarx");
+  Builder.defineMacro("__stdcx", "__builtin_ppc_stdcx");
+  Builder.defineMacro("__stwcx", "__builtin_ppc_stwcx");
 }
 
 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d04f3017a2ef..0c9d2010e3777 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3265,6 +3265,8 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
   case PPC::BI__builtin_divde:
   case PPC::BI__builtin_divdeu:
   case PPC::BI__builtin_bpermd:
+  case PPC::BI__builtin_ppc_ldarx:
+  case PPC::BI__builtin_ppc_stdcx:
     return true;
   }
   return false;

diff  --git a/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c
new file mode 100644
index 0000000000000..80bb4de424a13
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c
@@ -0,0 +1,27 @@
+// RUN: not %clang_cc1 -triple=powerpc-unknown-aix -emit-llvm %s -o - 2>&1 |\
+// RUN: FileCheck %s --check-prefix=CHECK32-ERROR
+// RUN: %clang_cc1 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \
+// RUN: FileCheck %s --check-prefix=CHECK64
+// RUN: %clang_cc1 -triple=powerpc64le-unknown-unknown -emit-llvm %s \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK64
+// RUN: %clang_cc1 -triple=powerpc64-unknown-unknown -emit-llvm %s \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK64
+
+long test_ldarx(volatile long* a) {
+  // CHECK64-LABEL: @test_ldarx
+  // CHECK64: %0 = load i64*, i64** %a.addr, align 8
+  // CHECK64: %1 = bitcast i64* %0 to i8*
+  // CHECK64: %2 = call i64 @llvm.ppc.ldarx(i8* %1)
+  // CHECK32-ERROR: error: this builtin is only available on 64-bit targets
+  return __ldarx(a);
+}
+
+int test_stdcx(volatile long* addr, long val) {
+  // CHECK64-LABEL: @test_stdcx
+  // CHECK64: %0 = load i64*, i64** %addr.addr, align 8
+  // CHECK64: %1 = bitcast i64* %0 to i8*
+  // CHECK64: %2 = load i64, i64* %val.addr, align 8
+  // CHECK64: %3 = call i32 @llvm.ppc.stdcx(i8* %1, i64 %2)
+  // CHECK32-ERROR: error: this builtin is only available on 64-bit targets
+  return __stdcx(addr, val);
+}

diff  --git a/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c
new file mode 100644
index 0000000000000..5b807973894e0
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple=powerpc-unknown-aix -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple=powerpc64le-unknown-unknown -emit-llvm %s \
+// RUN:  -o - | FileCheck %s
+// RUN: %clang_cc1 -triple=powerpc64-unknown-unknown -emit-llvm %s \
+// RUN:  -o - | FileCheck %s
+
+int test_lwarx(volatile int* a) {
+  // CHECK: @test_lwarx
+  // CHECK: %1 = bitcast i32* %0 to i8*
+  // CHECK: %2 = call i32 @llvm.ppc.lwarx(i8* %1)
+  return __lwarx(a);
+}
+int test_stwcx(volatile int* a, int val) {
+  // CHECK: @test_stwcx
+  // CHECK: %1 = bitcast i32* %0 to i8*
+  // CHECK: %2 = load i32, i32* %val.addr, align 4
+  // CHECK: %3 = call i32 @llvm.ppc.stwcx(i8* %1, i32 %2)
+  return __stwcx(a, val);
+}

diff  --git a/clang/test/CodeGen/builtins-ppc-xlcompat-error.c b/clang/test/CodeGen/builtins-ppc-xlcompat-error.c
new file mode 100644
index 0000000000000..01ac35ca64fd7
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-xlcompat-error.c
@@ -0,0 +1,17 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -fsyntax-only \
+// RUN:   -Wall -Werror -verify %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -fsyntax-only \
+// RUN:   -Wall -Werror -verify %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -fsyntax-only \
+// RUN:   -Wall -Werror -verify %s
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -fsyntax-only \
+// RUN:   -Wall -Werror -verify %s
+
+long long lla, llb;
+int ia, ib;
+
+void test_trap(void) {
+  __tdw(lla, llb, 50); //expected-error {{argument value 50 is outside the valid range [0, 31]}}
+  __tw(ia, ib, 50); //expected-error {{argument value 50 is outside the valid range [0, 31]}}
+}

diff  --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index ca1055c0d0cba..ad6a1e8d1a7a7 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -1523,5 +1523,15 @@ let TargetPrefix = "ppc" in {
                       Intrinsic<[],[],[]>;
   def int_ppc_iospace_eieio : GCCBuiltin<"__builtin_ppc_iospace_eieio">,
                               Intrinsic<[],[],[]>;
+  def int_ppc_stdcx : GCCBuiltin<"__builtin_ppc_stdcx">,
+                      Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i64_ty],
+                                [IntrWriteMem]>;
+  def int_ppc_stwcx : GCCBuiltin<"__builtin_ppc_stwcx">,
+                      Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
+                                [IntrWriteMem]>;
+  def int_ppc_lwarx : GCCBuiltin<"__builtin_ppc_lwarx">,
+                      Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
+  def int_ppc_ldarx : GCCBuiltin<"__builtin_ppc_ldarx">,
+                      Intrinsic<[llvm_i64_ty], [llvm_ptr_ty], [IntrNoMem]>;
 }
 

diff  --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 2ea729ffdf4f7..dc6a0c1a30e1c 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -1720,3 +1720,8 @@ def SLBIEG : XForm_26<31, 466, (outs), (ins gprc:$RS, gprc:$RB),
 def SLBSYNC : XForm_0<31, 338, (outs), (ins), "slbsync", IIC_SprSLBSYNC, []>;
 
 } // IsISA3_0
+
+def : Pat<(int_ppc_stdcx ForceXForm:$dst, g8rc:$A),
+          (STDCX g8rc:$A, ForceXForm:$dst)>;
+def : Pat<(int_ppc_ldarx ForceXForm:$dst),
+          (LDARX ForceXForm:$dst)>;

diff  --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index c4bf8af943d3b..20429ee664b21 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -5411,3 +5411,8 @@ def DWBytes3210 {
 // swap the high word and low word.
 def : Pat<(i64 (bitreverse i64:$A)),
   (OR8 (RLDICR DWBytes7654.DWord, 32, 31), DWBytes3210.DWord)>;
+
+def : Pat<(int_ppc_lwarx ForceXForm:$dst),
+          (LWARX ForceXForm:$dst)>;
+def : Pat<(int_ppc_stwcx ForceXForm:$dst, gprc:$A),
+          (STWCX gprc:$A, ForceXForm:$dst)>;

diff  --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll
new file mode 100644
index 0000000000000..d845a1cea1520
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll
@@ -0,0 +1,35 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK
+
+declare i64 @llvm.ppc.ldarx(i8*)
+define dso_local i64 @test_ldarx(i64* readnone %a) {
+; CHECK-LABEL: test_ldarx:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    ldarx 3, 0, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = bitcast i64* %a to i8*
+  %1 = tail call i64 @llvm.ppc.ldarx(i8* %0)
+  ret i64 %1
+}
+
+declare i32 @llvm.ppc.stdcx(i8*, i64)
+define dso_local i64 @test(i64* %a, i64 %b) {
+; CHECK-LABEL: test:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stdcx. 4, 0, 3
+; CHECK-NEXT:    mfocrf 3, 128
+; CHECK-NEXT:    srwi 3, 3, 28
+; CHECK-NEXT:    extsw 3, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = bitcast i64* %a to i8*
+  %1 = tail call i32 @llvm.ppc.stdcx(i8* %0, i64 %b)
+  %conv = sext i32 %1 to i64
+  ret i64 %conv
+}

diff  --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll
new file mode 100644
index 0000000000000..462b57f5f7a45
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll
@@ -0,0 +1,49 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-64
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-64
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-32
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-64
+
+declare i32 @llvm.ppc.lwarx(i8*)
+define dso_local signext i32 @test_lwarx(i32* readnone %a) {
+; CHECK-64-LABEL: test_lwarx:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    lwarx 3, 0, 3
+; CHECK-64-NEXT:    extsw 3, 3
+; CHECK-64-NEXT:    blr
+;
+; CHECK-32-LABEL: test_lwarx:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    lwarx 3, 0, 3
+; CHECK-32-NEXT:    blr
+entry:
+  %0 = bitcast i32* %a to i8*
+  %1 = tail call i32 @llvm.ppc.lwarx(i8* %0)
+  ret i32 %1
+}
+
+declare i32 @llvm.ppc.stwcx(i8*, i32)
+define dso_local signext i32 @test_stwcx(i32* %a, i32 signext %b) {
+; CHECK-64-LABEL: test_stwcx:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    stwcx. 4, 0, 3
+; CHECK-64-NEXT:    mfocrf 3, 128
+; CHECK-64-NEXT:    srwi 3, 3, 28
+; CHECK-64-NEXT:    extsw 3, 3
+; CHECK-64-NEXT:    blr
+;
+; CHECK-32-LABEL: test_stwcx:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    stwcx. 4, 0, 3
+; CHECK-32-NEXT:    mfocrf 3, 128
+; CHECK-32-NEXT:    srwi 3, 3, 28
+; CHECK-32-NEXT:    blr
+entry:
+  %0 = bitcast i32* %a to i8*
+  %1 = tail call i32 @llvm.ppc.stwcx(i8* %0, i32 %b)
+  ret i32 %1
+}


        


More information about the cfe-commits mailing list