[llvm] 70391b3 - [PowerPC] FP compare and test XL compat builtins.

Quinn Pham via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 28 09:01:58 PDT 2021


Author: Quinn Pham
Date: 2021-09-28T11:01:51-05:00
New Revision: 70391b3468b8a4a07b49df88d7fa88c9644cda77

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

LOG: [PowerPC] FP compare and test XL compat builtins.

This patch is in a series of patches to provide builtins for
compatability with the XL compiler. This patch adds builtins for compare
exponent and test data class operations on floating point values.

Reviewed By: #powerpc, lei

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

Added: 
    clang/test/CodeGen/builtins-ppc-xlcompat-test.c
    llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-test.ll

Modified: 
    clang/include/clang/Basic/BuiltinsPPC.def
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Basic/Targets/PPC.cpp
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/Sema/SemaChecking.cpp
    clang/test/CodeGen/builtins-ppc-xlcompat-pwr9-error.c
    llvm/include/llvm/IR/IntrinsicsPowerPC.td
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index ba865def5b48a..76c953272b4db 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -96,6 +96,11 @@ BUILTIN(__builtin_ppc_swdiv_nochk, "ddd", "")
 BUILTIN(__builtin_ppc_swdivs_nochk, "fff", "")
 BUILTIN(__builtin_ppc_alignx, "vIivC*", "nc")
 BUILTIN(__builtin_ppc_rdlam, "UWiUWiUWiUWIi", "nc")
+BUILTIN(__builtin_ppc_compare_exp_uo, "idd", "")
+BUILTIN(__builtin_ppc_compare_exp_lt, "idd", "")
+BUILTIN(__builtin_ppc_compare_exp_gt, "idd", "")
+BUILTIN(__builtin_ppc_compare_exp_eq, "idd", "")
+BUILTIN(__builtin_ppc_test_data_class, "idIi", "t")
 // Compare
 BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "")
 BUILTIN(__builtin_ppc_cmprb, "iCIiii", "")

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5a3eab540d1fe..07c5e85913712 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9778,8 +9778,12 @@ def err_mips_builtin_requires_msa : Error<
   "this builtin requires 'msa' ASE, please use -mmsa">;
 def err_ppc_builtin_only_on_arch : Error<
   "this builtin is only valid on POWER%0 or later CPUs">;
+def err_ppc_builtin_requires_vsx : Error<
+  "this builtin requires VSX to be enabled">;
 def err_ppc_invalid_use_mma_type : Error<
   "invalid use of PPC MMA type">;
+def err_ppc_invalid_test_data_class_type : Error<
+  "expected a 'float' or 'double' for the first argument">;
 def err_x86_builtin_invalid_rounding : Error<
   "invalid rounding argument">;
 def err_x86_builtin_invalid_scale : Error<

diff  --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 8f16f3d9b475c..8ada8c5106b31 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -238,6 +238,11 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
   Builder.defineMacro("__addex", "__builtin_ppc_addex");
   Builder.defineMacro("__cmplxl", "__builtin_complex");
+  Builder.defineMacro("__compare_exp_uo", "__builtin_ppc_compare_exp_uo");
+  Builder.defineMacro("__compare_exp_lt", "__builtin_ppc_compare_exp_lt");
+  Builder.defineMacro("__compare_exp_gt", "__builtin_ppc_compare_exp_gt");
+  Builder.defineMacro("__compare_exp_eq", "__builtin_ppc_compare_exp_eq");
+  Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class");
 }
 
 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index cd08f5ffe6411..fe532a7d24988 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -16077,6 +16077,17 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
                            *this, E, Intrinsic::sqrt,
                            Intrinsic::experimental_constrained_sqrt))
         .getScalarVal();
+  case PPC::BI__builtin_ppc_test_data_class:
+    llvm::Type *ArgType = EmitScalarExpr(E->getArg(0))->getType();
+    unsigned IntrinsicID;
+    if (ArgType->isDoubleTy())
+      IntrinsicID = Intrinsic::ppc_test_data_class_d;
+    else if (ArgType->isFloatTy())
+      IntrinsicID = Intrinsic::ppc_test_data_class_f;
+    else
+      llvm_unreachable("Invalid Argument Type");
+    return Builder.CreateCall(CGM.getIntrinsic(IntrinsicID), Ops,
+                              "test_data_class");
   }
 }
 

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f2452618c8b16..a6ea2bf2c0f3c 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3490,6 +3490,28 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
   case PPC::BI__builtin_vsx_xxgenpcvwm:
   case PPC::BI__builtin_vsx_xxgenpcvdm:
     return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3);
+  case PPC::BI__builtin_ppc_compare_exp_uo:
+  case PPC::BI__builtin_ppc_compare_exp_lt:
+  case PPC::BI__builtin_ppc_compare_exp_gt:
+  case PPC::BI__builtin_ppc_compare_exp_eq:
+    return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
+                            diag::err_ppc_builtin_only_on_arch, "9") ||
+           SemaFeatureCheck(*this, TheCall, "vsx",
+                            diag::err_ppc_builtin_requires_vsx);
+  case PPC::BI__builtin_ppc_test_data_class: {
+    // Check if the first argument of the __builtin_ppc_test_data_class call is
+    // valid. The argument must be either a 'float' or a 'double'.
+    QualType ArgType = TheCall->getArg(0)->getType();
+    if (ArgType != QualType(Context.FloatTy) &&
+        ArgType != QualType(Context.DoubleTy))
+      return Diag(TheCall->getBeginLoc(),
+                  diag::err_ppc_invalid_test_data_class_type);
+    return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
+                            diag::err_ppc_builtin_only_on_arch, "9") ||
+           SemaFeatureCheck(*this, TheCall, "vsx",
+                            diag::err_ppc_builtin_requires_vsx) ||
+           SemaBuiltinConstantArgRange(TheCall, 1, 0, 127);
+  }
 #define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
   case PPC::BI__builtin_##Name: \
     return SemaBuiltinPPCMMACall(TheCall, Types);

diff  --git a/clang/test/CodeGen/builtins-ppc-xlcompat-pwr9-error.c b/clang/test/CodeGen/builtins-ppc-xlcompat-pwr9-error.c
index 795e05a40e15d..da683807b60b1 100644
--- a/clang/test/CodeGen/builtins-ppc-xlcompat-pwr9-error.c
+++ b/clang/test/CodeGen/builtins-ppc-xlcompat-pwr9-error.c
@@ -11,6 +11,8 @@
 extern unsigned int ui;
 extern unsigned long long ull;
 extern long long ll;
+extern float f;
+extern double d;
 
 void test_builtin_ppc_cmprb() {
   int res = __builtin_ppc_cmprb(3, ui, ui); // expected-error {{argument value 3 is outside the valid range [0, 1]}}
@@ -24,3 +26,23 @@ void test_builtin_ppc_addex() {
 }
 
 #endif
+
+int test_builtin_ppc_test_data_class_d() {
+  return __builtin_ppc_test_data_class(d, -1); // expected-error {{argument value -1 is outside the valid range [0, 127]}}
+}
+
+int test_builtin_ppc_test_data_class_f() {
+  return __builtin_ppc_test_data_class(f, -1); // expected-error {{argument value -1 is outside the valid range [0, 127]}}
+}
+
+int test_test_data_class_d() {
+  return __test_data_class(d, 128); // expected-error {{argument value 128 is outside the valid range [0, 127]}}
+}
+
+int test_test_data_class_f() {
+  return __test_data_class(f, 128); // expected-error {{argument value 128 is outside the valid range [0, 127]}}
+}
+
+int test_test_data_class_type() {
+  return __test_data_class(ui, 0); // expected-error {{expected a 'float' or 'double' for the first argument}}
+}

diff  --git a/clang/test/CodeGen/builtins-ppc-xlcompat-test.c b/clang/test/CodeGen/builtins-ppc-xlcompat-test.c
new file mode 100644
index 0000000000000..d7532f2b455fb
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-xlcompat-test.c
@@ -0,0 +1,124 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s \
+// RUN:   -target-cpu pwr9 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -emit-llvm %s \
+// RUN:   -target-cpu pwr9 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s \
+// RUN:   -target-cpu pwr9 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-unknown-aix %s -emit-llvm %s \
+// RUN:   -target-cpu pwr9 -o - | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm-only %s \
+// RUN:   -target-cpu pwr8 2>&1 | FileCheck %s --check-prefix=CHECK-NONPWR9-ERR
+// RUN: not %clang_cc1 -target-feature -vsx -triple powerpc64-unknown-unknown -emit-llvm-only %s \
+// RUN:   -target-cpu pwr9 2>&1 | FileCheck %s --check-prefix=CHECK-NOVSX-ERR
+
+extern double d;
+extern float f;
+
+int test_builtin_ppc_compare_exp_uo() {
+// CHECK-LABEL:       @test_builtin_ppc_compare_exp_uo
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.uo(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __builtin_ppc_compare_exp_uo(d, d);
+}
+
+int test_builtin_ppc_compare_exp_lt() {
+// CHECK-LABEL:       @test_builtin_ppc_compare_exp_lt
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.lt(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __builtin_ppc_compare_exp_lt(d, d);
+}
+
+int test_builtin_ppc_compare_exp_gt() {
+// CHECK-LABEL:       @test_builtin_ppc_compare_exp_gt
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.gt(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __builtin_ppc_compare_exp_gt(d, d);
+}
+
+int test_builtin_ppc_compare_exp_eq() {
+// CHECK-LABEL:       @test_builtin_ppc_compare_exp_eq
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.eq(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __builtin_ppc_compare_exp_eq(d, d);
+}
+
+int test_builtin_ppc_test_data_class_d() {
+// CHECK-LABEL:       @test_builtin_ppc_test_data_class_d
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.d(double %0, i32 0)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __builtin_ppc_test_data_class(d, 0);
+}
+
+int test_builtin_ppc_test_data_class_f() {
+// CHECK-LABEL:       @test_builtin_ppc_test_data_class_f
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.f(float %0, i32 0)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __builtin_ppc_test_data_class(f, 0);
+}
+
+int test_compare_exp_uo() {
+// CHECK-LABEL:       @test_compare_exp_uo
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.uo(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __compare_exp_uo(d, d);
+}
+
+int test_compare_exp_lt() {
+// CHECK-LABEL:       @test_compare_exp_lt
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.lt(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __compare_exp_lt(d, d);
+}
+
+int test_compare_exp_gt() {
+// CHECK-LABEL:       @test_compare_exp_gt
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.gt(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __compare_exp_gt(d, d);
+}
+
+int test_compare_exp_eq() {
+// CHECK-LABEL:       @test_compare_exp_eq
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.compare.exp.eq(double %0, double %1)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __compare_exp_eq(d, d);
+}
+
+int test_test_data_class_d() {
+// CHECK-LABEL:       @test_test_data_class_d
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.d(double %0, i32 127)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __test_data_class(d, 127);
+}
+
+int test_test_data_class_f() {
+// CHECK-LABEL:       @test_test_data_class_f
+// CHECK:             [[TMP:%.*]] = call i32 @llvm.ppc.test.data.class.f(float %0, i32 127)
+// CHECK-NEXT:        ret i32 [[TMP]]
+// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
+// CHECK-NOVSX-ERR: error: this builtin requires VSX to be enabled
+  return __test_data_class(f, 127);
+}

diff  --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index b1d1009e4adfd..be2a795f26d21 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -1720,6 +1720,28 @@ let TargetPrefix = "ppc" in {
                         Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
   def int_ppc_frsqrtes : GCCBuiltin<"__builtin_ppc_frsqrtes">,
                          Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_ppc_compare_exp_uo : GCCBuiltin<"__builtin_ppc_compare_exp_uo">,
+                               Intrinsic<[llvm_i32_ty],
+                                         [llvm_double_ty, llvm_double_ty], 
+                                         [IntrNoMem]>;
+  def int_ppc_compare_exp_lt : GCCBuiltin<"__builtin_ppc_compare_exp_lt">,
+                               Intrinsic<[llvm_i32_ty], 
+                                         [llvm_double_ty, llvm_double_ty], 
+                                         [IntrNoMem]>;
+  def int_ppc_compare_exp_gt : GCCBuiltin<"__builtin_ppc_compare_exp_gt">,
+                               Intrinsic<[llvm_i32_ty],
+                                         [llvm_double_ty, llvm_double_ty], 
+                                         [IntrNoMem]>;
+  def int_ppc_compare_exp_eq : GCCBuiltin<"__builtin_ppc_compare_exp_eq">,
+                               Intrinsic<[llvm_i32_ty], 
+                                         [llvm_double_ty, llvm_double_ty], 
+                                         [IntrNoMem]>;
+  def int_ppc_test_data_class_d : Intrinsic<[llvm_i32_ty],
+                                            [llvm_double_ty, llvm_i32_ty],
+                                            [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+  def int_ppc_test_data_class_f : Intrinsic<[llvm_i32_ty],
+                                            [llvm_float_ty, llvm_i32_ty],
+                                            [IntrNoMem, ImmArg<ArgIndex<1>>]>;
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index f27219f2f09b7..6b0b6397ba609 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -10373,6 +10373,50 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
     }
     return DAG.getMergeValues(RetOps, dl);
   }
+  case Intrinsic::ppc_compare_exp_lt:
+  case Intrinsic::ppc_compare_exp_gt:
+  case Intrinsic::ppc_compare_exp_eq:
+  case Intrinsic::ppc_compare_exp_uo: {
+    unsigned Pred;
+    switch (IntrinsicID) {
+    case Intrinsic::ppc_compare_exp_lt:
+      Pred = PPC::PRED_LT;
+      break;
+    case Intrinsic::ppc_compare_exp_gt:
+      Pred = PPC::PRED_GT;
+      break;
+    case Intrinsic::ppc_compare_exp_eq:
+      Pred = PPC::PRED_EQ;
+      break;
+    case Intrinsic::ppc_compare_exp_uo:
+      Pred = PPC::PRED_UN;
+      break;
+    }
+    return SDValue(
+        DAG.getMachineNode(
+            PPC::SELECT_CC_I4, dl, MVT::i32,
+            {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
+                                        Op.getOperand(1), Op.getOperand(2)),
+                     0),
+             DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
+             DAG.getTargetConstant(Pred, dl, MVT::i32)}),
+        0);
+  }
+  case Intrinsic::ppc_test_data_class_d:
+  case Intrinsic::ppc_test_data_class_f: {
+    unsigned CmprOpc = PPC::XSTSTDCDP;
+    if (IntrinsicID == Intrinsic::ppc_test_data_class_f)
+      CmprOpc = PPC::XSTSTDCSP;
+    return SDValue(
+        DAG.getMachineNode(
+            PPC::SELECT_CC_I4, dl, MVT::i32,
+            {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
+                                        Op.getOperand(1)),
+                     0),
+             DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
+             DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
+        0);
+  }
   }
 
   // If this is a lowered altivec predicate compare, CompareOpc is set to the

diff  --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-test.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-test.ll
new file mode 100644
index 0000000000000..6ebd836f32cd8
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-test.ll
@@ -0,0 +1,99 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-unknown \
+; RUN:   -mcpu=pwr9 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown \
+; RUN:   -mcpu=pwr9 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN:   -mcpu=pwr9 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN:   -mcpu=pwr9 < %s | FileCheck %s
+
+define i32 @test_builtin_ppc_compare_exp_eq(double %d) {
+; CHECK-LABEL: test_builtin_ppc_compare_exp_eq:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xscmpexpdp 0, 1, 1
+; CHECK-NEXT:    li 3, 0
+; CHECK-NEXT:    li 4, 1
+; CHECK-NEXT:    iseleq 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call i32 @llvm.ppc.compare.exp.eq(double %d, double %d)
+  ret i32 %0
+}
+
+declare i32 @llvm.ppc.compare.exp.eq(double, double)
+
+define i32 @test_builtin_ppc_compare_exp_lt(double %d) {
+; CHECK-LABEL: test_builtin_ppc_compare_exp_lt:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xscmpexpdp 0, 1, 1
+; CHECK-NEXT:    li 3, 0
+; CHECK-NEXT:    li 4, 1
+; CHECK-NEXT:    isellt 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call i32 @llvm.ppc.compare.exp.lt(double %d, double %d)
+  ret i32 %0
+}
+
+declare i32 @llvm.ppc.compare.exp.lt(double, double)
+
+define i32 @test_builtin_ppc_compare_exp_gt(double %d) {
+; CHECK-LABEL: test_builtin_ppc_compare_exp_gt:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xscmpexpdp 0, 1, 1
+; CHECK-NEXT:    li 3, 0
+; CHECK-NEXT:    li 4, 1
+; CHECK-NEXT:    iselgt 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call i32 @llvm.ppc.compare.exp.gt(double %d, double %d)
+  ret i32 %0
+}
+
+declare i32 @llvm.ppc.compare.exp.gt(double, double)
+
+define i32 @test_builtin_ppc_compare_exp_uo(double %d) {
+; CHECK-LABEL: test_builtin_ppc_compare_exp_uo:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xscmpexpdp 0, 1, 1
+; CHECK-NEXT:    li 3, 0
+; CHECK-NEXT:    li 4, 1
+; CHECK-NEXT:    isel 3, 4, 3, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call i32 @llvm.ppc.compare.exp.uo(double %d, double %d)
+  ret i32 %0
+}
+
+declare i32 @llvm.ppc.compare.exp.uo(double, double)
+
+define i32 @test_builtin_ppc_test_data_class_d(double %d) {
+; CHECK-LABEL: test_builtin_ppc_test_data_class_d:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xststdcdp 0, 1, 0
+; CHECK-NEXT:    li 3, 0
+; CHECK-NEXT:    li 4, 1
+; CHECK-NEXT:    iseleq 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %test_data_class = tail call i32 @llvm.ppc.test.data.class.d(double %d, i32 0)
+  ret i32 %test_data_class
+}
+
+declare i32 @llvm.ppc.test.data.class.d(double, i32 immarg)
+
+define i32 @test_builtin_ppc_test_data_class_f(float %f) {
+; CHECK-LABEL: test_builtin_ppc_test_data_class_f:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xststdcsp 0, 1, 127
+; CHECK-NEXT:    li 3, 0
+; CHECK-NEXT:    li 4, 1
+; CHECK-NEXT:    iseleq 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %test_data_class = tail call i32 @llvm.ppc.test.data.class.f(float %f, i32 127)
+  ret i32 %test_data_class
+}
+
+declare i32 @llvm.ppc.test.data.class.f(float, i32 immarg)


        


More information about the llvm-commits mailing list