[clang] b389354 - [Clang][PowerPC] Add max/min intrinsics to Clang and PPC backend

Ting Wang via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 5 19:48:16 PDT 2022


Author: Ting Wang
Date: 2022-04-05T22:43:48-04:00
New Revision: b389354b285744f700fd9372c8707fa056d7cb37

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

LOG: [Clang][PowerPC] Add max/min intrinsics to Clang and PPC backend

Add support for builtin_[max|min] which has below prototype:
A builtin_max (A1, A2, A3, ...)
All arguments must have the same type; they must all be float, double, or long double.
Internally use SelectCC to get the result.

Reviewed By: qiucf

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

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

Modified: 
    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/PowerPC/builtins-ppc.c
    clang/test/Sema/builtins-ppc.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 70b0184f199f8..8a4c5b4eead27 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -152,6 +152,13 @@ BUILTIN(__builtin_ppc_mtmsr, "vUi", "")
 BUILTIN(__builtin_ppc_mtspr, "vIiULi", "")
 BUILTIN(__builtin_ppc_stfiw, "viC*d", "")
 BUILTIN(__builtin_ppc_addex, "LLiLLiLLiCIi", "")
+// select
+BUILTIN(__builtin_ppc_maxfe, "LdLdLdLd.", "t")
+BUILTIN(__builtin_ppc_maxfl, "dddd.", "t")
+BUILTIN(__builtin_ppc_maxfs, "ffff.", "t")
+BUILTIN(__builtin_ppc_minfe, "LdLdLdLd.", "t")
+BUILTIN(__builtin_ppc_minfl, "dddd.", "t")
+BUILTIN(__builtin_ppc_minfs, "ffff.", "t")
 
 BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
 

diff  --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 1eb0317af60b6..bafcc23b38334 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -247,6 +247,12 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class");
   Builder.defineMacro("__swdiv", "__builtin_ppc_swdiv");
   Builder.defineMacro("__swdivs", "__builtin_ppc_swdivs");
+  Builder.defineMacro("__builtin_maxfe", "__builtin_ppc_maxfe");
+  Builder.defineMacro("__builtin_maxfl", "__builtin_ppc_maxfl");
+  Builder.defineMacro("__builtin_maxfs", "__builtin_ppc_maxfs");
+  Builder.defineMacro("__builtin_minfe", "__builtin_ppc_minfe");
+  Builder.defineMacro("__builtin_minfl", "__builtin_ppc_minfl");
+  Builder.defineMacro("__builtin_minfs", "__builtin_ppc_minfs");
 }
 
 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8ca4b2d0bf15d..661c0a105f427 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -16302,6 +16302,18 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
     return Builder.CreateCall(CGM.getIntrinsic(IntrinsicID), Ops,
                               "test_data_class");
   }
+  case PPC::BI__builtin_ppc_maxfe:
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_maxfe), Ops);
+  case PPC::BI__builtin_ppc_maxfl:
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_maxfl), Ops);
+  case PPC::BI__builtin_ppc_maxfs:
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_maxfs), Ops);
+  case PPC::BI__builtin_ppc_minfe:
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_minfe), Ops);
+  case PPC::BI__builtin_ppc_minfl:
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_minfl), Ops);
+  case PPC::BI__builtin_ppc_minfs:
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_minfs), Ops);
   case PPC::BI__builtin_ppc_swdiv:
   case PPC::BI__builtin_ppc_swdivs:
     return Builder.CreateFDiv(Ops[0], Ops[1], "swdiv");

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7e73988c33b74..9331d169f800f 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3904,6 +3904,33 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
                             diag::err_ppc_builtin_requires_vsx) ||
            SemaBuiltinConstantArgRange(TheCall, 1, 0, 127);
   }
+  case PPC::BI__builtin_ppc_maxfe:
+  case PPC::BI__builtin_ppc_minfe:
+  case PPC::BI__builtin_ppc_maxfl:
+  case PPC::BI__builtin_ppc_minfl:
+  case PPC::BI__builtin_ppc_maxfs:
+  case PPC::BI__builtin_ppc_minfs: {
+    if (Context.getTargetInfo().getTriple().isOSAIX() &&
+        (BuiltinID == PPC::BI__builtin_ppc_maxfe ||
+         BuiltinID == PPC::BI__builtin_ppc_minfe))
+      return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type)
+             << "builtin" << true << 128 << QualType(Context.LongDoubleTy)
+             << false << Context.getTargetInfo().getTriple().str();
+    // Argument type should be exact.
+    QualType ArgType = QualType(Context.LongDoubleTy);
+    if (BuiltinID == PPC::BI__builtin_ppc_maxfl ||
+        BuiltinID == PPC::BI__builtin_ppc_minfl)
+      ArgType = QualType(Context.DoubleTy);
+    else if (BuiltinID == PPC::BI__builtin_ppc_maxfs ||
+             BuiltinID == PPC::BI__builtin_ppc_minfs)
+      ArgType = QualType(Context.FloatTy);
+    for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I)
+      if (TheCall->getArg(I)->getType() != ArgType)
+        return Diag(TheCall->getBeginLoc(),
+                    diag::err_typecheck_convert_incompatible)
+               << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0;
+    return false;
+  }
   case PPC::BI__builtin_ppc_load8r:
   case PPC::BI__builtin_ppc_store8r:
     return SemaFeatureCheck(*this, TheCall, "isa-v206-instructions",

diff  --git a/clang/test/CodeGen/PowerPC/builtins-ppc.c b/clang/test/CodeGen/PowerPC/builtins-ppc.c
index cbd53346d4b0f..adfbf27b4c8d4 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc.c
@@ -46,3 +46,31 @@ long double test_builtin_pack_ldbl(double x, double y) {
   // CHECK: call ppc_fp128 @llvm.ppc.pack.longdouble(double %0, double %1)
   return __builtin_pack_longdouble(x, y);
 }
+
+void test_builtin_ppc_maxminfe(long double a, long double b, long double c,
+                               long double d) {
+  volatile long double res;
+  // CHECK: call ppc_fp128 (ppc_fp128, ppc_fp128, ppc_fp128, ...) @llvm.ppc.maxfe(ppc_fp128 %0, ppc_fp128 %1, ppc_fp128 %2, ppc_fp128 %3)
+  res = __builtin_ppc_maxfe(a, b, c, d);
+
+  // CHECK: call ppc_fp128 (ppc_fp128, ppc_fp128, ppc_fp128, ...) @llvm.ppc.minfe(ppc_fp128 %5, ppc_fp128 %6, ppc_fp128 %7, ppc_fp128 %8)
+  res = __builtin_ppc_minfe(a, b, c, d);
+}
+
+void test_builtin_ppc_maxminfl(double a, double b, double c, double d) {
+  volatile double res;
+  // CHECK: call double (double, double, double, ...) @llvm.ppc.maxfl(double %0, double %1, double %2, double %3)
+  res = __builtin_ppc_maxfl(a, b, c, d);
+
+  // CHECK: call double (double, double, double, ...) @llvm.ppc.minfl(double %5, double %6, double %7, double %8)
+  res = __builtin_ppc_minfl(a, b, c, d);
+}
+
+void test_builtin_ppc_maxminfs(float a, float b, float c, float d) {
+  volatile float res;
+  // CHECK: call float (float, float, float, ...) @llvm.ppc.maxfs(float %0, float %1, float %2, float %3)
+  res = __builtin_ppc_maxfs(a, b, c, d);
+
+  // CHECK: call float (float, float, float, ...) @llvm.ppc.minfs(float %5, float %6, float %7, float %8)
+  res = __builtin_ppc_minfs(a, b, c, d);
+}

diff  --git a/clang/test/Sema/builtins-ppc.c b/clang/test/Sema/builtins-ppc.c
index a0550c72a7785..0f59b990331cb 100644
--- a/clang/test/Sema/builtins-ppc.c
+++ b/clang/test/Sema/builtins-ppc.c
@@ -10,6 +10,12 @@
 // RUN: -triple powerpc64le-unknown-unknown -DTEST_CRYPTO -fsyntax-only \
 // RUN: -target-feature +vsx -verify %s
 
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -DTEST_MAXMIN -fsyntax-only \
+// RUN: -verify %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -DTEST_MAXMIN -fsyntax-only \
+// RUN: -verify %s
+
 #ifdef TEST_HTM
 void test_htm() {
   __builtin_tbegin(4); // expected-error-re {{argument value {{.*}} is outside the valid range}}
@@ -54,3 +60,25 @@ vector unsigned long long test_vshasigmad_or(void)
 
 #endif
 
+#ifdef TEST_MAXMIN
+void test_maxmin() {
+  long double fe;
+  double fl;
+  float fs;
+#ifdef _AIX
+  __builtin_ppc_maxfe(fe, fe, fe, fe); // expected-error-re {{builtin requires 128 bit size 'long double' type support, but target {{.*}} does not support it}}
+  __builtin_ppc_minfe(fe, fe, fe, fe); // expected-error-re {{builtin requires 128 bit size 'long double' type support, but target {{.*}} does not support it}}
+  __builtin_ppc_maxfl(fs, fs, fs, fs); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_minfl(fs, fs, fs, fs); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_maxfs(fe, fe, fe, fe); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_minfs(fe, fe, fe, fe); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+#else
+  __builtin_ppc_maxfe(fl, fl, fl, fl); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_minfe(fl, fl, fl, fl); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_maxfl(fs, fs, fs, fs); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_minfl(fs, fs, fs, fs); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_maxfs(fe, fe, fe, fe); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+  __builtin_ppc_minfs(fe, fe, fe, fe); // expected-error-re {{passing {{.*}} to parameter of incompatible type {{.*}}}}
+#endif
+}
+#endif

diff  --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 44d2d52705d02..aa050ec6d5883 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -160,6 +160,37 @@ let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".
   def int_ppc_fctuwz
       : GCCBuiltin<"__builtin_ppc_fctuwz">,
         Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  // XL compatible select functions
+  // TODO: Add llvm_f128_ty support.
+  def int_ppc_maxfe
+      : Intrinsic<
+            [llvm_ppcf128_ty],
+            [llvm_ppcf128_ty, llvm_ppcf128_ty, llvm_ppcf128_ty, llvm_vararg_ty],
+            [IntrNoMem]>;
+  def int_ppc_maxfl
+      : Intrinsic<
+            [llvm_double_ty],
+            [llvm_double_ty, llvm_double_ty, llvm_double_ty, llvm_vararg_ty],
+            [IntrNoMem]>;
+  def int_ppc_maxfs
+      : Intrinsic<[llvm_float_ty],
+                  [llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_vararg_ty],
+                  [IntrNoMem]>;
+  def int_ppc_minfe
+      : Intrinsic<
+            [llvm_ppcf128_ty],
+            [llvm_ppcf128_ty, llvm_ppcf128_ty, llvm_ppcf128_ty, llvm_vararg_ty],
+            [IntrNoMem]>;
+  def int_ppc_minfl
+      : Intrinsic<
+            [llvm_double_ty],
+            [llvm_double_ty, llvm_double_ty, llvm_double_ty, llvm_vararg_ty],
+            [IntrNoMem]>;
+  def int_ppc_minfs
+      : Intrinsic<[llvm_float_ty],
+                  [llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_vararg_ty],
+                  [IntrNoMem]>;
 }
 
 let TargetPrefix = "ppc" in {  // All PPC intrinsics start with "llvm.ppc.".

diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index c99c68d7b018a..b126ed486b0d6 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -10563,6 +10563,30 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
                     dl, SDValue());
     return Result.first;
   }
+  case Intrinsic::ppc_maxfe:
+  case Intrinsic::ppc_maxfl:
+  case Intrinsic::ppc_maxfs:
+  case Intrinsic::ppc_minfe:
+  case Intrinsic::ppc_minfl:
+  case Intrinsic::ppc_minfs: {
+    EVT VT = Op.getValueType();
+    assert(
+        all_of(Op->ops().drop_front(4),
+               [VT](const SDUse &Use) { return Use.getValueType() == VT; }) &&
+        "ppc_[max|min]f[e|l|s] must have uniform type arguments");
+    ISD::CondCode CC = ISD::SETGT;
+    if (IntrinsicID == Intrinsic::ppc_minfe ||
+        IntrinsicID == Intrinsic::ppc_minfl ||
+        IntrinsicID == Intrinsic::ppc_minfs)
+      CC = ISD::SETLT;
+    unsigned I = Op.getNumOperands() - 2, Cnt = I;
+    SDValue Res = Op.getOperand(I);
+    for (--I; Cnt != 0; --Cnt, I = (--I == 0 ? (Op.getNumOperands() - 1) : I)) {
+      Res =
+          DAG.getSelectCC(dl, Res, Op.getOperand(I), Res, Op.getOperand(I), CC);
+    }
+    return Res;
+  }
   }
 
   // If this is a lowered altivec predicate compare, CompareOpc is set to the
@@ -11223,6 +11247,8 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
       Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::ppcf128,
                                     N->getOperand(2), N->getOperand(1)));
       break;
+    case Intrinsic::ppc_maxfe:
+    case Intrinsic::ppc_minfe:
     case Intrinsic::ppc_fnmsub:
     case Intrinsic::ppc_convert_f128_to_ppcf128:
       Results.push_back(LowerINTRINSIC_WO_CHAIN(SDValue(N, 0), DAG));

diff  --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-maxmin.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-maxmin.ll
new file mode 100644
index 0000000000000..fc4e1729036b8
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-maxmin.ll
@@ -0,0 +1,257 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mcpu=pwr9 -verify-machineinstrs -mtriple=powerpc64le-unknown-linux \
+; RUN:    < %s | FileCheck --check-prefixes=CHECK,CHECK-P9 %s
+; RUN: llc -mcpu=pwr8 -verify-machineinstrs -mtriple=powerpc64le-unknown-linux \
+; RUN:    < %s | FileCheck --check-prefixes=CHECK,CHECK-P8 %s
+
+declare ppc_fp128 @llvm.ppc.maxfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ...)
+define ppc_fp128 @test_maxfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d) {
+; CHECK-LABEL: test_maxfe:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    fcmpu 0, 6, 4
+; CHECK-NEXT:    fcmpu 1, 5, 3
+; CHECK-NEXT:    crand 20, 6, 1
+; CHECK-NEXT:    cror 20, 5, 20
+; CHECK-NEXT:    bc 12, 20, .LBB0_2
+; CHECK-NEXT:  # %bb.1: # %entry
+; CHECK-NEXT:    fmr 6, 4
+; CHECK-NEXT:  .LBB0_2: # %entry
+; CHECK-NEXT:    fcmpu 0, 6, 2
+; CHECK-NEXT:    bc 12, 20, .LBB0_4
+; CHECK-NEXT:  # %bb.3: # %entry
+; CHECK-NEXT:    fmr 5, 3
+; CHECK-NEXT:  .LBB0_4: # %entry
+; CHECK-NEXT:    fcmpu 1, 5, 1
+; CHECK-NEXT:    crand 20, 6, 1
+; CHECK-NEXT:    cror 20, 5, 20
+; CHECK-NEXT:    bc 12, 20, .LBB0_6
+; CHECK-NEXT:  # %bb.5: # %entry
+; CHECK-NEXT:    fmr 6, 2
+; CHECK-NEXT:  .LBB0_6: # %entry
+; CHECK-NEXT:    fcmpu 0, 6, 8
+; CHECK-NEXT:    bc 12, 20, .LBB0_8
+; CHECK-NEXT:  # %bb.7: # %entry
+; CHECK-NEXT:    fmr 5, 1
+; CHECK-NEXT:  .LBB0_8: # %entry
+; CHECK-NEXT:    fcmpu 1, 5, 7
+; CHECK-NEXT:    crand 20, 6, 1
+; CHECK-NEXT:    cror 20, 5, 20
+; CHECK-NEXT:    bc 12, 20, .LBB0_10
+; CHECK-NEXT:  # %bb.9: # %entry
+; CHECK-NEXT:    fmr 5, 7
+; CHECK-NEXT:  .LBB0_10: # %entry
+; CHECK-NEXT:    bc 12, 20, .LBB0_12
+; CHECK-NEXT:  # %bb.11: # %entry
+; CHECK-NEXT:    fmr 6, 8
+; CHECK-NEXT:  .LBB0_12: # %entry
+; CHECK-NEXT:    fmr 1, 5
+; CHECK-NEXT:    fmr 2, 6
+; CHECK-NEXT:    blr
+entry:
+  %0 = call ppc_fp128 (ppc_fp128, ppc_fp128, ppc_fp128, ...) @llvm.ppc.maxfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d)
+  ret ppc_fp128 %0
+}
+
+declare double @llvm.ppc.maxfl(double %a, double %b, double %c, ...)
+define double @test_maxfl(double %a, double %b, double %c, double %d) {
+; CHECK-P9-LABEL: test_maxfl:
+; CHECK-P9:       # %bb.0: # %entry
+; CHECK-P9-NEXT:    xsmaxcdp 0, 3, 2
+; CHECK-P9-NEXT:    xsmaxcdp 0, 0, 1
+; CHECK-P9-NEXT:    xsmaxcdp 1, 0, 4
+; CHECK-P9-NEXT:    blr
+;
+; CHECK-P8-LABEL: test_maxfl:
+; CHECK-P8:       # %bb.0: # %entry
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 2
+; CHECK-P8-NEXT:    ble 0, .LBB1_4
+; CHECK-P8-NEXT:  # %bb.1: # %entry
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 1
+; CHECK-P8-NEXT:    ble 0, .LBB1_5
+; CHECK-P8-NEXT:  .LBB1_2: # %entry
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 4
+; CHECK-P8-NEXT:    ble 0, .LBB1_6
+; CHECK-P8-NEXT:  .LBB1_3: # %entry
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+; CHECK-P8-NEXT:  .LBB1_4: # %entry
+; CHECK-P8-NEXT:    fmr 3, 2
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 1
+; CHECK-P8-NEXT:    bgt 0, .LBB1_2
+; CHECK-P8-NEXT:  .LBB1_5: # %entry
+; CHECK-P8-NEXT:    fmr 3, 1
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 4
+; CHECK-P8-NEXT:    bgt 0, .LBB1_3
+; CHECK-P8-NEXT:  .LBB1_6: # %entry
+; CHECK-P8-NEXT:    fmr 3, 4
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+entry:
+  %0 = call double (double, double, double, ...) @llvm.ppc.maxfl(double %a, double %b, double %c, double %d)
+  ret double %0
+}
+
+declare float @llvm.ppc.maxfs(float %a, float %b, float %c, ...)
+define float @test_maxfs(float %a, float %b, float %c, float %d) {
+; CHECK-P9-LABEL: test_maxfs:
+; CHECK-P9:       # %bb.0: # %entry
+; CHECK-P9-NEXT:    xsmaxcdp 0, 3, 2
+; CHECK-P9-NEXT:    xsmaxcdp 0, 0, 1
+; CHECK-P9-NEXT:    xsmaxcdp 1, 0, 4
+; CHECK-P9-NEXT:    blr
+;
+; CHECK-P8-LABEL: test_maxfs:
+; CHECK-P8:       # %bb.0: # %entry
+; CHECK-P8-NEXT:    fcmpu 0, 3, 2
+; CHECK-P8-NEXT:    ble 0, .LBB2_4
+; CHECK-P8-NEXT:  # %bb.1: # %entry
+; CHECK-P8-NEXT:    fcmpu 0, 3, 1
+; CHECK-P8-NEXT:    ble 0, .LBB2_5
+; CHECK-P8-NEXT:  .LBB2_2: # %entry
+; CHECK-P8-NEXT:    fcmpu 0, 3, 4
+; CHECK-P8-NEXT:    ble 0, .LBB2_6
+; CHECK-P8-NEXT:  .LBB2_3: # %entry
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+; CHECK-P8-NEXT:  .LBB2_4: # %entry
+; CHECK-P8-NEXT:    fmr 3, 2
+; CHECK-P8-NEXT:    fcmpu 0, 3, 1
+; CHECK-P8-NEXT:    bgt 0, .LBB2_2
+; CHECK-P8-NEXT:  .LBB2_5: # %entry
+; CHECK-P8-NEXT:    fmr 3, 1
+; CHECK-P8-NEXT:    fcmpu 0, 3, 4
+; CHECK-P8-NEXT:    bgt 0, .LBB2_3
+; CHECK-P8-NEXT:  .LBB2_6: # %entry
+; CHECK-P8-NEXT:    fmr 3, 4
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+entry:
+  %0 = call float (float, float, float, ...) @llvm.ppc.maxfs(float %a, float %b, float %c, float %d)
+  ret float %0
+}
+
+declare ppc_fp128 @llvm.ppc.minfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ...)
+define ppc_fp128 @test_minfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d) {
+; CHECK-LABEL: test_minfe:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    fcmpu 0, 6, 4
+; CHECK-NEXT:    fcmpu 1, 5, 3
+; CHECK-NEXT:    crand 20, 6, 0
+; CHECK-NEXT:    cror 20, 4, 20
+; CHECK-NEXT:    bc 12, 20, .LBB3_2
+; CHECK-NEXT:  # %bb.1: # %entry
+; CHECK-NEXT:    fmr 6, 4
+; CHECK-NEXT:  .LBB3_2: # %entry
+; CHECK-NEXT:    fcmpu 0, 6, 2
+; CHECK-NEXT:    bc 12, 20, .LBB3_4
+; CHECK-NEXT:  # %bb.3: # %entry
+; CHECK-NEXT:    fmr 5, 3
+; CHECK-NEXT:  .LBB3_4: # %entry
+; CHECK-NEXT:    fcmpu 1, 5, 1
+; CHECK-NEXT:    crand 20, 6, 0
+; CHECK-NEXT:    cror 20, 4, 20
+; CHECK-NEXT:    bc 12, 20, .LBB3_6
+; CHECK-NEXT:  # %bb.5: # %entry
+; CHECK-NEXT:    fmr 6, 2
+; CHECK-NEXT:  .LBB3_6: # %entry
+; CHECK-NEXT:    fcmpu 0, 6, 8
+; CHECK-NEXT:    bc 12, 20, .LBB3_8
+; CHECK-NEXT:  # %bb.7: # %entry
+; CHECK-NEXT:    fmr 5, 1
+; CHECK-NEXT:  .LBB3_8: # %entry
+; CHECK-NEXT:    fcmpu 1, 5, 7
+; CHECK-NEXT:    crand 20, 6, 0
+; CHECK-NEXT:    cror 20, 4, 20
+; CHECK-NEXT:    bc 12, 20, .LBB3_10
+; CHECK-NEXT:  # %bb.9: # %entry
+; CHECK-NEXT:    fmr 5, 7
+; CHECK-NEXT:  .LBB3_10: # %entry
+; CHECK-NEXT:    bc 12, 20, .LBB3_12
+; CHECK-NEXT:  # %bb.11: # %entry
+; CHECK-NEXT:    fmr 6, 8
+; CHECK-NEXT:  .LBB3_12: # %entry
+; CHECK-NEXT:    fmr 1, 5
+; CHECK-NEXT:    fmr 2, 6
+; CHECK-NEXT:    blr
+entry:
+  %0 = call ppc_fp128 (ppc_fp128, ppc_fp128, ppc_fp128, ...) @llvm.ppc.minfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d)
+  ret ppc_fp128 %0
+}
+
+declare double @llvm.ppc.minfl(double %a, double %b, double %c, ...)
+define double @test_minfl(double %a, double %b, double %c, double %d) {
+; CHECK-P9-LABEL: test_minfl:
+; CHECK-P9:       # %bb.0: # %entry
+; CHECK-P9-NEXT:    xsmincdp 0, 3, 2
+; CHECK-P9-NEXT:    xsmincdp 0, 0, 1
+; CHECK-P9-NEXT:    xsmincdp 1, 0, 4
+; CHECK-P9-NEXT:    blr
+;
+; CHECK-P8-LABEL: test_minfl:
+; CHECK-P8:       # %bb.0: # %entry
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 2
+; CHECK-P8-NEXT:    bge 0, .LBB4_4
+; CHECK-P8-NEXT:  # %bb.1: # %entry
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 1
+; CHECK-P8-NEXT:    bge 0, .LBB4_5
+; CHECK-P8-NEXT:  .LBB4_2: # %entry
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 4
+; CHECK-P8-NEXT:    bge 0, .LBB4_6
+; CHECK-P8-NEXT:  .LBB4_3: # %entry
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+; CHECK-P8-NEXT:  .LBB4_4: # %entry
+; CHECK-P8-NEXT:    fmr 3, 2
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 1
+; CHECK-P8-NEXT:    blt 0, .LBB4_2
+; CHECK-P8-NEXT:  .LBB4_5: # %entry
+; CHECK-P8-NEXT:    fmr 3, 1
+; CHECK-P8-NEXT:    xscmpudp 0, 3, 4
+; CHECK-P8-NEXT:    blt 0, .LBB4_3
+; CHECK-P8-NEXT:  .LBB4_6: # %entry
+; CHECK-P8-NEXT:    fmr 3, 4
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+entry:
+  %0 = call double (double, double, double, ...) @llvm.ppc.minfl(double %a, double %b, double %c, double %d)
+  ret double %0
+}
+
+declare float @llvm.ppc.minfs(float %a, float %b, float %c, ...)
+define float @test_minfs(float %a, float %b, float %c, float %d) {
+; CHECK-P9-LABEL: test_minfs:
+; CHECK-P9:       # %bb.0: # %entry
+; CHECK-P9-NEXT:    xsmincdp 0, 3, 2
+; CHECK-P9-NEXT:    xsmincdp 0, 0, 1
+; CHECK-P9-NEXT:    xsmincdp 1, 0, 4
+; CHECK-P9-NEXT:    blr
+;
+; CHECK-P8-LABEL: test_minfs:
+; CHECK-P8:       # %bb.0: # %entry
+; CHECK-P8-NEXT:    fcmpu 0, 3, 2
+; CHECK-P8-NEXT:    bge 0, .LBB5_4
+; CHECK-P8-NEXT:  # %bb.1: # %entry
+; CHECK-P8-NEXT:    fcmpu 0, 3, 1
+; CHECK-P8-NEXT:    bge 0, .LBB5_5
+; CHECK-P8-NEXT:  .LBB5_2: # %entry
+; CHECK-P8-NEXT:    fcmpu 0, 3, 4
+; CHECK-P8-NEXT:    bge 0, .LBB5_6
+; CHECK-P8-NEXT:  .LBB5_3: # %entry
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+; CHECK-P8-NEXT:  .LBB5_4: # %entry
+; CHECK-P8-NEXT:    fmr 3, 2
+; CHECK-P8-NEXT:    fcmpu 0, 3, 1
+; CHECK-P8-NEXT:    blt 0, .LBB5_2
+; CHECK-P8-NEXT:  .LBB5_5: # %entry
+; CHECK-P8-NEXT:    fmr 3, 1
+; CHECK-P8-NEXT:    fcmpu 0, 3, 4
+; CHECK-P8-NEXT:    blt 0, .LBB5_3
+; CHECK-P8-NEXT:  .LBB5_6: # %entry
+; CHECK-P8-NEXT:    fmr 3, 4
+; CHECK-P8-NEXT:    fmr 1, 3
+; CHECK-P8-NEXT:    blr
+entry:
+  %0 = call float (float, float, float, ...) @llvm.ppc.minfs(float %a, float %b, float %c, float %d)
+  ret float %0
+}


        


More information about the cfe-commits mailing list