[PowerPC] Store, load, move from and to registers related builtins
authorAlbion Fung <albionapc@gmail.com>
Tue, 20 Jul 2021 20:20:03 +0000 (15:20 -0500)
committerAlbion Fung <albionapc@gmail.com>
Tue, 20 Jul 2021 20:46:14 +0000 (15:46 -0500)
This patch implements store, load, move from and to registers related
builtins, as well as the builtin for stfiw. The patch aims to provide
feature parady with xlC on AIX.

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

16 files changed:
clang/include/clang/Basic/BuiltinsPPC.def
clang/lib/Basic/Targets/PPC.cpp
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/Sema/SemaChecking.cpp
clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c
clang/test/CodeGen/builtins-ppc-xlcompat-move-tofrom-regs.c [new file with mode: 0644]
clang/test/CodeGen/builtins-ppc-xlcompat-prefetch.c [new file with mode: 0644]
clang/test/CodeGen/builtins-ppc-xlcompat-stfiw.c [new file with mode: 0644]
llvm/include/llvm/IR/IntrinsicsPowerPC.td
llvm/lib/Target/PowerPC/PPC.td
llvm/lib/Target/PowerPC/PPCInstrInfo.td
llvm/lib/Target/PowerPC/PPCInstrVSX.td
llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll
llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-stfiw.ll [new file with mode: 0644]
llvm/test/CodeGen/builtins-ppc-xlcompat-move-tofrom-regs.ll [new file with mode: 0644]
llvm/test/CodeGen/builtins-ppc-xlcompat-prefetch.ll [new file with mode: 0644]

index 5f8bbf6..10743ac 100644 (file)
@@ -59,8 +59,11 @@ 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_lharx, "isD*", "")
+BUILTIN(__builtin_ppc_lbarx, "UiUcD*", "")
 BUILTIN(__builtin_ppc_stdcx, "iLiD*Li", "")
 BUILTIN(__builtin_ppc_stwcx, "iiD*i", "")
+BUILTIN(__builtin_ppc_sthcx, "isD*s", "")
 BUILTIN(__builtin_ppc_tdw, "vLLiLLiIUi", "")
 BUILTIN(__builtin_ppc_tw, "viiIUi", "")
 BUILTIN(__builtin_ppc_trap, "vi", "")
@@ -117,6 +120,11 @@ BUILTIN(__builtin_ppc_fnmsub, "dddd", "")
 BUILTIN(__builtin_ppc_fnmsubs, "ffff", "")
 BUILTIN(__builtin_ppc_fre, "dd", "")
 BUILTIN(__builtin_ppc_fres, "ff", "")
+BUILTIN(__builtin_ppc_dcbtstt, "vv*", "")
+BUILTIN(__builtin_ppc_dcbtt, "vv*", "")
+BUILTIN(__builtin_ppc_mftbu, "Ui","")
+BUILTIN(__builtin_ppc_mfmsr, "Ui", "")
+BUILTIN(__builtin_ppc_stfiw, "viC*d", "")
 
 BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
 
index f4e646a..dd8e92e 100644 (file)
@@ -118,8 +118,12 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   Builder.defineMacro("__fetch_and_swaplp", "__builtin_ppc_fetch_and_swaplp");
   Builder.defineMacro("__ldarx", "__builtin_ppc_ldarx");
   Builder.defineMacro("__lwarx", "__builtin_ppc_lwarx");
+  Builder.defineMacro("__lharx", "__builtin_ppc_lharx");
+  Builder.defineMacro("__lbarx", "__builtin_ppc_lbarx");
+  Builder.defineMacro("__stfiw", "__builtin_ppc_stfiw");
   Builder.defineMacro("__stdcx", "__builtin_ppc_stdcx");
   Builder.defineMacro("__stwcx", "__builtin_ppc_stwcx");
+  Builder.defineMacro("__sthcx", "__builtin_ppc_sthcx");
   Builder.defineMacro("__tdw", "__builtin_ppc_tdw");
   Builder.defineMacro("__tw", "__builtin_ppc_tw");
   Builder.defineMacro("__trap", "__builtin_ppc_trap");
@@ -209,6 +213,10 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   Builder.defineMacro("__rdlam", "__builtin_ppc_rdlam");
   Builder.defineMacro("__setflm", "__builtin_setflm");
   Builder.defineMacro("__setrnd", "__builtin_setrnd");
+  Builder.defineMacro("__dcbtstt", "__builtin_ppc_dcbtstt");
+  Builder.defineMacro("__dcbtt", "__builtin_ppc_dcbtt");
+  Builder.defineMacro("__mftbu", "__builtin_ppc_mftbu");
+  Builder.defineMacro("__mfmsr", "__builtin_ppc_mfmsr");
 }
 
 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
index 2bc194e..1551ddd 100644 (file)
@@ -1012,6 +1012,14 @@ static llvm::Value *emitPPCLoadReserveIntrinsic(CodeGenFunction &CGF,
     AsmOS << "lwarx ";
     RetType = CGF.Int32Ty;
     break;
+  case clang::PPC::BI__builtin_ppc_lharx:
+    AsmOS << "lharx ";
+    RetType = CGF.Int16Ty;
+    break;
+  case clang::PPC::BI__builtin_ppc_lbarx:
+    AsmOS << "lbarx ";
+    RetType = CGF.Int8Ty;
+    break;
   default:
     llvm_unreachable("Expected only PowerPC load reserve intrinsics");
   }
@@ -15562,6 +15570,13 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
     return Builder.CreateExtractElement(Unpacked, Index);
   }
 
+  case PPC::BI__builtin_ppc_sthcx: {
+    llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_sthcx);
+    Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
+    Ops[1] = Builder.CreateSExt(Ops[1], Int32Ty);
+    return Builder.CreateCall(F, Ops);
+  }
+
   // The PPC MMA builtins take a pointer to a __vector_quad as an argument.
   // Some of the MMA instructions accumulate their result into an existing
   // accumulator whereas the others generate a new accumulator. So we need to
@@ -15672,6 +15687,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
   }
   case PPC::BI__builtin_ppc_ldarx:
   case PPC::BI__builtin_ppc_lwarx:
+  case PPC::BI__builtin_ppc_lharx:
+  case PPC::BI__builtin_ppc_lbarx:
     return emitPPCLoadReserveIntrinsic(*this, BuiltinID, E);
   case PPC::BI__builtin_ppc_popcntb: {
     Value *ArgValue = EmitScalarExpr(E->getArg(0));
index 1b39393..075fad6 100644 (file)
@@ -3436,6 +3436,11 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
   case PPC::BI__builtin_ppc_icbt:
     return SemaFeatureCheck(*this, TheCall, "isa-v207-instructions",
                             diag::err_ppc_builtin_only_on_arch, "8");
+  case PPC::BI__builtin_ppc_sthcx:
+  case PPC::BI__builtin_ppc_lharx:
+  case PPC::BI__builtin_ppc_lbarx:
+    return SemaFeatureCheck(*this, TheCall, "isa-v207-instructions",
+                            diag::err_ppc_builtin_only_on_arch, "8");
 #define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
   case PPC::BI__builtin_##Name: \
     return SemaBuiltinPPCMMACall(TheCall, Types);
index 2ae031c..22c668f 100644 (file)
@@ -1,21 +1,48 @@
 // REQUIRES: powerpc-registered-target
-// RUN: %clang_cc1 -O2 -triple=powerpc-unknown-aix -emit-llvm %s -o - | \
-// RUN: FileCheck %s
-// RUN: %clang_cc1 -O2 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \
-// RUN: FileCheck %s
-// RUN: %clang_cc1 -O2 -triple=powerpc64le-unknown-unknown -emit-llvm %s \
-// RUN:  -o - | FileCheck %s
-// RUN: %clang_cc1 -O2 -triple=powerpc64-unknown-unknown -emit-llvm %s \
-// RUN:  -o - | FileCheck %s
+// RUN: %clang_cc1 -O2 -target-cpu pwr8 -triple=powerpc-unknown-aix \
+// RUN:  -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -O2 -target-cpu pwr8 -triple=powerpc64-unknown-aix \
+// RUN:  -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -O2 -target-cpu pwr8 -triple=powerpc64le-unknown-unknown \
+// RUN:  -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -O2 -target-cpu pwr8 -triple=powerpc64-unknown-unknown \
+// RUN:  -emit-llvm %s -o - | FileCheck %s
+// RAUN: not %clang_cc1 -O2 -target-cpu pwr7 -triple=powerpc-unknown-aix \
+// RAUN:  -emit-llvm %s -o - 2>&1 | FileCheck %s \
+// RAUN:  --check-prefix=CHECK-NON-PWR8-ERR
 
 int test_lwarx(volatile int* a) {
-  // CHECK: @test_lwarx
+  // CHECK-LABEL: @test_lwarx
   // CHECK: %0 = tail call i32 asm sideeffect "lwarx $0, ${1:y}", "=r,*Z,~{memory}"(i32* %a)
   return __lwarx(a);
 }
+
+short test_lharx(volatile short *a) {
+  // CHECK-LABEL: @test_lharx
+  // CHECK: %0 = tail call i16 asm sideeffect "lharx $0, ${1:y}", "=r,*Z,~{memory}"(i16* %a)
+  // CHECK-NON-PWR8-ERR:  error: this builtin is only valid on POWER8 or later CPUs
+  return __lharx(a);
+}
+
+char test_lbarx(volatile unsigned char *a) {
+  // CHECK-LABEL: @test_lbarx
+  // CHECK: %0 = tail call i8 asm sideeffect "lbarx $0, ${1:y}", "=r,*Z,~{memory}"(i8* %a)
+  // CHECK-NON-PWR8-ERR:  error: this builtin is only valid on POWER8 or later CPUs
+  return __lbarx(a);
+}
+
 int test_stwcx(volatile int* a, int val) {
-  // CHECK: @test_stwcx
+  // CHECK-LABEL: @test_stwcx
   // CHECK: %0 = bitcast i32* %a to i8*
   // CHECK: %1 = tail call i32 @llvm.ppc.stwcx(i8* %0, i32 %val)
   return __stwcx(a, val);
 }
+
+int test_sthcx(volatile short *a, short val) {
+  // CHECK-LABEL: @test_sthcx
+  // CHECK: %0 = bitcast i16* %a to i8*
+  // CHECK: %1 = sext i16 %val to i32
+  // CHECK: %2 = tail call i32 @llvm.ppc.sthcx(i8* %0, i32 %1)
+  // CHECK-NON-PWR8-ERR:  error: this builtin is only valid on POWER8 or later CPUs
+  return __sthcx(a, val);
+}
diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-move-tofrom-regs.c b/clang/test/CodeGen/builtins-ppc-xlcompat-move-tofrom-regs.c
new file mode 100644 (file)
index 0000000..c05b1eb
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-unknown \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-unknown \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+
+unsigned int test_mftbu(void) {
+  // CHECK-LABEL: @test_mftbu
+  // CHECK: %0 = tail call i32 @llvm.ppc.mftbu()
+  return __mftbu();
+}
+
+unsigned long test_mfmsr(void) {
+  // CHECK-LABEL: @test_mfmsr
+  // CHECK: %0 = tail call i32 @llvm.ppc.mfmsr()
+  return __mfmsr();
+}
diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-prefetch.c b/clang/test/CodeGen/builtins-ppc-xlcompat-prefetch.c
new file mode 100644 (file)
index 0000000..5b12909
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-unknown \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-unknown \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+
+extern void *vpa;
+
+void test_dcbtstt(void) {
+  // CHECK-LABEL: @test_dcbtstt
+  // CHECK: %0 = load i8*, i8** @vpa
+  // CHECK: tail call void @llvm.ppc.dcbtstt(i8* %0)
+  // CHECK: ret void
+  __dcbtstt(vpa);
+}
+
+void test_dcbtt(void) {
+  // CHECK-LABEL: @test_dcbt
+  // CHECK: %0 = load i8*, i8** @vpa
+  // CHECK: tail call void @llvm.ppc.dcbtt(i8* %0)
+  // CHECK: ret void
+  __dcbtt(vpa);
+}
diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-stfiw.c b/clang/test/CodeGen/builtins-ppc-xlcompat-stfiw.c
new file mode 100644 (file)
index 0000000..91c5ab7
--- /dev/null
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-unknown \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-unknown \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
+
+extern const int *cia;
+extern double da;
+
+void test_stfiw() {
+  // CHECK-LABEL: test_stfiw
+  // CHECK: void @llvm.ppc.stfiw(i8* %0, double %1)
+  __builtin_ppc_stfiw(cia, da);
+}
+
+void test_xl_stfiw() {
+  // CHECK-LABEL: test_xl_stfiw
+  // CHECK: void @llvm.ppc.stfiw(i8* %0, double %1)
+  __stfiw(cia, da);
+}
index 04e42c2..1af8c02 100644 (file)
@@ -1564,6 +1564,21 @@ let TargetPrefix = "ppc" in {
   def int_ppc_stwcx : GCCBuiltin<"__builtin_ppc_stwcx">,
                       Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
                                 [IntrWriteMem]>;
+  def int_ppc_sthcx
+      : Intrinsic<[llvm_i32_ty], [ llvm_ptr_ty, llvm_i32_ty ], [IntrWriteMem]>;
+  def int_ppc_dcbtstt : GCCBuiltin<"__builtin_ppc_dcbtstt">,
+                        Intrinsic<[], [llvm_ptr_ty],
+                                  [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
+  def int_ppc_dcbtt : GCCBuiltin<"__builtin_ppc_dcbtt">,
+                      Intrinsic<[], [llvm_ptr_ty],
+                                [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
+  def int_ppc_mftbu : GCCBuiltin<"__builtin_ppc_mftbu">,
+                      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+  def int_ppc_mfmsr : GCCBuiltin<"__builtin_ppc_mfmsr">,
+                      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+  def int_ppc_stfiw : GCCBuiltin<"__builtin_ppc_stfiw">,
+                      Intrinsic<[], [llvm_ptr_ty, llvm_double_ty],
+                                [IntrWriteMem]>;
   // compare
   def int_ppc_cmpeqb
       : GCCBuiltin<"__builtin_ppc_cmpeqb">,
index 96746d1..ce43ced 100644 (file)
@@ -335,7 +335,8 @@ def ProcessorFeatures {
      FeatureICBT,
      FeaturePartwordAtomic,
      FeatureQuadwordAtomic,
-     FeaturePredictableSelectIsExpensive
+     FeaturePredictableSelectIsExpensive,
+     FeatureISA2_07
     ];
 
   list<SubtargetFeature> P8SpecificFeatures = [FeatureAddiLoadFusion,
index 49dd0f8..d04d828 100644 (file)
@@ -5480,3 +5480,18 @@ def : Pat<(int_ppc_fctudz f64:$A),
         (XSCVDPUXDS $A)>;
 def : Pat<(int_ppc_fctuwz f64:$A),
         (XSCVDPUXWS $A)>;
+
+def : Pat<(int_ppc_mfmsr), (MFMSR)>;
+def : Pat<(int_ppc_mftbu), (MFTB 269)>;
+
+let Predicates = [IsISA2_07] in {
+  def : Pat<(int_ppc_sthcx ForceXForm:$dst, gprc:$A),
+          (STHCX gprc:$A, ForceXForm:$dst)>;
+}
+def : Pat<(int_ppc_dcbtstt ForceXForm:$dst),
+          (DCBTST 16, ForceXForm:$dst)>;
+def : Pat<(int_ppc_dcbtt ForceXForm:$dst),
+          (DCBT 16, ForceXForm:$dst)>;
+
+def : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT),
+          (STFIWX f64:$XT, ForceXForm:$dst)>;
index a13eb2b..f816ce9 100644 (file)
@@ -3264,6 +3264,9 @@ def : Pat<(int_ppc_extract_sig f64:$A),
           (XSXSIGDP (COPY_TO_REGCLASS $A, VSFRC))>;
 def : Pat<(f64 (int_ppc_insert_exp f64:$A, i64:$B)),
           (COPY_TO_REGCLASS (XSIEXPDP (COPY_TO_REGCLASS $A, G8RC), $B), F8RC)>;
+
+def : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT),
+          (STXSIWX f64:$XT, ForceXForm:$dst)>;
 } // HasVSX, HasP8Vector
 
 // Any big endian Power8 VSX subtarget.
index 7b16510..e967177 100644 (file)
@@ -50,3 +50,69 @@ entry:
   %1 = tail call i32 @llvm.ppc.stwcx(i8* %0, i32 %b)
   ret i32 %1
 }
+
+declare i32 @llvm.ppc.sthcx(i8*, i32)
+define dso_local signext i32 @test_sthcx(i16* %a, i16 signext %val) {
+; CHECK-64-LABEL: test_sthcx:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    sthcx. 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_sthcx:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    sthcx. 4, 0, 3
+; CHECK-32-NEXT:    mfocrf 3, 128
+; CHECK-32-NEXT:    srwi 3, 3, 28
+; CHECK-32-NEXT:    blr
+entry:
+  %0 = bitcast i16* %a to i8*
+  %1 = sext i16 %val to i32
+  %2 = tail call i32 @llvm.ppc.sthcx(i8* %0, i32 %1)
+  ret i32 %2
+}
+
+define dso_local signext i16 @test_lharx(i16* %a) {
+; CHECK-64-LABEL: test_lharx:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    #APP
+; CHECK-64-NEXT:    lharx 3, 0, 3
+; CHECK-64-NEXT:    #NO_APP
+; CHECK-64-NEXT:    extsh 3, 3
+; CHECK-64-NEXT:    blr
+;
+; CHECK-32-LABEL: test_lharx:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    #APP
+; CHECK-32-NEXT:    lharx 3, 0, 3
+; CHECK-32-NEXT:    #NO_APP
+; CHECK-32-NEXT:    extsh 3, 3
+; CHECK-32-NEXT:    blr
+entry:
+  %0 = tail call i16 asm sideeffect "lharx $0, ${1:y}", "=r,*Z,~{memory}"(i16* %a)
+  ret i16 %0
+}
+
+; Function Attrs: nounwind uwtable
+define dso_local zeroext i8 @test_lbarx(i8* %a) {
+; CHECK-64-LABEL: test_lbarx:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    #APP
+; CHECK-64-NEXT:    lbarx 3, 0, 3
+; CHECK-64-NEXT:    #NO_APP
+; CHECK-64-NEXT:    clrldi 3, 3, 56
+; CHECK-64-NEXT:    blr
+;
+; CHECK-32-LABEL: test_lbarx:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    #APP
+; CHECK-32-NEXT:    lbarx 3, 0, 3
+; CHECK-32-NEXT:    #NO_APP
+; CHECK-32-NEXT:    clrlwi 3, 3, 24
+; CHECK-32-NEXT:    blr
+entry:
+  %0 = tail call i8 asm sideeffect "lbarx $0, ${1:y}", "=r,*Z,~{memory}"(i8* %a)
+  ret i8 %0
+}
diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-stfiw.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-stfiw.ll
new file mode 100644 (file)
index 0000000..5bc5bce
--- /dev/null
@@ -0,0 +1,64 @@
+; 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
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -mcpu=pwr9 -mattr -vsx < %s | FileCheck %s --check-prefix=CHECK-NO-VSX
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -mcpu=pwr9 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-NO-VSX
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-32BIT
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN:   -mcpu=pwr8 < %s | FileCheck %s
+
+declare void @llvm.ppc.stfiw(i8*, double)
+define dso_local void @test_stfiw(i32* %cia, double %da) {
+; CHECK-LABEL: test_stfiw:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stxsiwx 1, 0, 3
+; CHECK-NEXT:    blr
+;
+; CHECK-NO-VSX-LABEL: test_stfiw:
+; CHECK-NO-VSX:       # %bb.0: # %entry
+; CHECK-NO-VSX-NEXT:    stfiwx 1, 0, 3
+; CHECK-NO-VSX-NEXT:    blr
+;
+; CHECK-32BIT-LABEL: test_stfiw:
+; CHECK-32BIT:       # %bb.0: # %entry
+; CHECK-32BIT-NEXT:    stfiwx 1, 0, 3
+; CHECK-32BIT-NEXT:    blr
+; CHECK-PWR9-LABEL: test_stfiw:
+; CHECK-PWR9:       # %bb.0: # %entry
+; CHECK-PWR9-NEXT:    stxsiwx 1, 0, 3
+; CHECK-PWR9-NEXT:    blr
+entry:
+  %0 = bitcast i32* %cia to i8*
+  tail call void @llvm.ppc.stfiw(i8* %0, double %da)
+  ret void
+}
+
+define dso_local void @test_xl_stfiw(i32* %cia, double %da) {
+; CHECK-LABEL: test_xl_stfiw:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stxsiwx 1, 0, 3
+; CHECK-NEXT:    blr
+;
+; CHECK-NO-VSX-LABEL: test_xl_stfiw:
+; CHECK-NO-VSX:       # %bb.0: # %entry
+; CHECK-NO-VSX-NEXT:    stfiwx 1, 0, 3
+; CHECK-NO-VSX-NEXT:    blr
+;
+; CHECK-32BIT-LABEL: test_xl_stfiw:
+; CHECK-32BIT:       # %bb.0: # %entry
+; CHECK-32BIT-NEXT:    stfiwx 1, 0, 3
+; CHECK-32BIT-NEXT:    blr
+; CHECK-PWR9-LABEL: test_xl_stfiw:
+; CHECK-PWR9:       # %bb.0: # %entry
+; CHECK-PWR9-NEXT:    stxsiwx 1, 0, 3
+; CHECK-PWR9-NEXT:    blr
+entry:
+  %0 = bitcast i32* %cia to i8*
+  tail call void @llvm.ppc.stfiw(i8* %0, double %da)
+  ret void
+}
diff --git a/llvm/test/CodeGen/builtins-ppc-xlcompat-move-tofrom-regs.ll b/llvm/test/CodeGen/builtins-ppc-xlcompat-move-tofrom-regs.ll
new file mode 100644 (file)
index 0000000..b3d51d6
--- /dev/null
@@ -0,0 +1,46 @@
+; 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
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-32BIT
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s
+
+declare i32 @llvm.ppc.mftbu()
+declare i32 @llvm.ppc.mfmsr()
+
+define dso_local zeroext i32 @test_mftbu() {
+; CHECK-LABEL: test_mftbu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    mftbu 3
+; CHECK-NEXT:    clrldi 3, 3, 32
+; CHECK-NEXT:    blr
+;
+; CHECK-32BIT-LABEL: test_mftbu:
+; CHECK-32BIT:       # %bb.0: # %entry
+; CHECK-32BIT-NEXT:    mftbu 3
+; CHECK-32BIT-NEXT:    blr
+entry:
+  %0 = tail call i32 @llvm.ppc.mftbu()
+  ret i32 %0
+}
+
+define dso_local i64 @test_mfmsr() {
+; CHECK-LABEL: test_mfmsr:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    mfmsr 3
+; CHECK-NEXT:    clrldi 3, 3, 32
+; CHECK-NEXT:    blr
+;
+; CHECK-32BIT-LABEL: test_mfmsr:
+; CHECK-32BIT:       # %bb.0: # %entry
+; CHECK-32BIT-NEXT:    mfmsr 4
+; CHECK-32BIT-NEXT:    li 3, 0
+; CHECK-32BIT-NEXT:    blr
+entry:
+  %0 = tail call i32 @llvm.ppc.mfmsr()
+  %conv = zext i32 %0 to i64
+  ret i64 %conv
+}
diff --git a/llvm/test/CodeGen/builtins-ppc-xlcompat-prefetch.ll b/llvm/test/CodeGen/builtins-ppc-xlcompat-prefetch.ll
new file mode 100644 (file)
index 0000000..65ce644
--- /dev/null
@@ -0,0 +1,71 @@
+; 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
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-AIX
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN:   -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-AIX64
+
+declare void @llvm.ppc.dcbtstt(i8*)
+declare void @llvm.ppc.dcbtt(i8*)
+
+@vpa = external local_unnamed_addr global i8*, align 8
+
+define dso_local void @test_dcbtstt() {
+; CHECK-LABEL: test_dcbtstt:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addis 3, 2, .LC0@toc@ha
+; CHECK-NEXT:    ld 3, .LC0@toc@l(3)
+; CHECK-NEXT:    ld 3, 0(3)
+; CHECK-NEXT:    dcbtstt 0, 3
+; CHECK-NEXT:    blr
+;
+; CHECK-AIX-LABEL: test_dcbtstt:
+; CHECK-AIX:       # %bb.0: # %entry
+; CHECK-AIX-NEXT:    lwz 3, L..C0(2) # @vpa
+; CHECK-AIX-NEXT:    lwz 3, 0(3)
+; CHECK-AIX-NEXT:    dcbtstt 0, 3
+; CHECK-AIX-NEXT:    blr
+;
+; CHECK-AIX64-LABEL: test_dcbtstt:
+; CHECK-AIX64:       # %bb.0: # %entry
+; CHECK-AIX64-NEXT:    ld 3, L..C0(2) # @vpa
+; CHECK-AIX64-NEXT:    ld 3, 0(3)
+; CHECK-AIX64-NEXT:    dcbtstt 0, 3
+; CHECK-AIX64-NEXT:    blr
+entry:
+  %0 = load i8*, i8** @vpa, align 8
+  tail call void @llvm.ppc.dcbtstt(i8* %0)
+  ret void
+}
+
+
+define dso_local void @test_dcbtt() {
+; CHECK-LABEL: test_dcbtt:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addis 3, 2, .LC0@toc@ha
+; CHECK-NEXT:    ld 3, .LC0@toc@l(3)
+; CHECK-NEXT:    ld 3, 0(3)
+; CHECK-NEXT:    dcbtt 0, 3
+; CHECK-NEXT:    blr
+;
+; CHECK-AIX-LABEL: test_dcbtt:
+; CHECK-AIX:       # %bb.0: # %entry
+; CHECK-AIX-NEXT:    lwz 3, L..C0(2) # @vpa
+; CHECK-AIX-NEXT:    lwz 3, 0(3)
+; CHECK-AIX-NEXT:    dcbtt 0, 3
+; CHECK-AIX-NEXT:    blr
+;
+; CHECK-AIX64-LABEL: test_dcbtt:
+; CHECK-AIX64:       # %bb.0: # %entry
+; CHECK-AIX64-NEXT:    ld 3, L..C0(2) # @vpa
+; CHECK-AIX64-NEXT:    ld 3, 0(3)
+; CHECK-AIX64-NEXT:    dcbtt 0, 3
+; CHECK-AIX64-NEXT:    blr
+entry:
+  %0 = load i8*, i8** @vpa, align 8
+  tail call void @llvm.ppc.dcbtt(i8* %0)
+  ret void
+}