[llvm] ac93a4e - [PowerPC][GISel]fcmp support

Chen Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 4 23:49:24 PST 2023


Author: Chen Zheng
Date: 2023-01-05T07:45:29Z
New Revision: ac93a4e77d1e60958b775ce5c68dd4b81d0e2050

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

LOG: [PowerPC][GISel]fcmp support

This patch also includes:
1: CRRegBank support
2: Some workarounds in PPC table gen for anyext/setcc patterns
   selection.

Reviewed By: arsenm

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

Added: 
    llvm/test/CodeGen/PowerPC/GlobalISel/fcmp.ll

Modified: 
    llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
    llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
    llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
    llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
    llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
    llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
    llvm/lib/Target/PowerPC/PPCInstrInfo.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
index a23fe7a451619..d737eec570eb3 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
@@ -99,7 +99,7 @@ static const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank *RB) {
   if (RB->getID() == PPC::GPRRegBankID) {
     if (Ty.getSizeInBits() == 64)
       return &PPC::G8RCRegClass;
-    if (Ty.getSizeInBits() == 32)
+    if (Ty.getSizeInBits() <= 32)
       return &PPC::GPRCRegClass;
   }
   if (RB->getID() == PPC::FPRRegBankID) {
@@ -108,6 +108,12 @@ static const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank *RB) {
     if (Ty.getSizeInBits() == 64)
       return &PPC::F8RCRegClass;
   }
+  if (RB->getID() == PPC::CRRegBankID) {
+    if (Ty.getSizeInBits() == 1)
+      return &PPC::CRBITRCRegClass;
+    if (Ty.getSizeInBits() == 4)
+      return &PPC::CRRCRegClass;
+  }
 
   llvm_unreachable("Unknown RegBank!");
 }

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
index 0fb12ab4c6589..1a25fcde8815d 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
@@ -20,6 +20,7 @@ using namespace LegalizeActions;
 PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
   using namespace TargetOpcode;
   const LLT P0 = LLT::pointer(0, 64);
+  const LLT S1 = LLT::scalar(1);
   const LLT S8 = LLT::scalar(8);
   const LLT S16 = LLT::scalar(16);
   const LLT S32 = LLT::scalar(32);
@@ -28,8 +29,8 @@ PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
   getActionDefinitionsBuilder(G_CONSTANT)
       .legalFor({S32, S64})
       .clampScalar(0, S64, S64);
-  getActionDefinitionsBuilder({G_ZEXT, G_SEXT})
-      .legalForCartesianProduct({S64}, {S8, S16, S32})
+  getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
+      .legalForCartesianProduct({S64}, {S1, S8, S16, S32})
       .clampScalar(0, S64, S64);
   getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
       .legalFor({S64})
@@ -41,6 +42,9 @@ PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
   getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
       .legalFor({S32, S64});
 
+  getActionDefinitionsBuilder(G_FCMP).legalForCartesianProduct({S1},
+                                                               {S32, S64});
+
   getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
       .legalForCartesianProduct({S64}, {S32, S64});
 

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
index af74ec98c5d39..69d9a04109a56 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
@@ -48,6 +48,9 @@ PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
   case PPC::VSSRCRegClassID:
   case PPC::F4RCRegClassID:
     return getRegBank(PPC::FPRRegBankID);
+  case PPC::CRRCRegClassID:
+  case PPC::CRBITRCRegClassID:
+    return getRegBank(PPC::CRRegBankID);
   default:
     llvm_unreachable("Unexpected register class");
   }
@@ -87,6 +90,7 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     // Extension ops.
   case TargetOpcode::G_SEXT:
   case TargetOpcode::G_ZEXT:
+  case TargetOpcode::G_ANYEXT:
     assert(NumOperands <= 3 &&
            "This code is for instructions with 3 or less operands");
     OperandsMapping = getValueMapping(PMI_GPR64);
@@ -102,6 +106,15 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     OperandsMapping = getValueMapping(Size == 32 ? PMI_FPR32 : PMI_FPR64);
     break;
   }
+  case TargetOpcode::G_FCMP: {
+    unsigned CmpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
+
+    OperandsMapping = getOperandsMapping(
+        {getValueMapping(PMI_CR), nullptr,
+         getValueMapping(CmpSize == 32 ? PMI_FPR32 : PMI_FPR64),
+         getValueMapping(CmpSize == 32 ? PMI_FPR32 : PMI_FPR64)});
+    break;
+  }
   case TargetOpcode::G_CONSTANT:
     OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});
     break;

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
index f06a15affb400..885bdcb758165 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
@@ -32,6 +32,7 @@ class PPCGenRegisterBankInfo : public RegisterBankInfo {
     PMI_GPR64 = 2,
     PMI_FPR32 = 3,
     PMI_FPR64 = 4,
+    PMI_CR = 5,
     PMI_Min = PMI_GPR32,
   };
 

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
index b5f39e4dc618c..16f3bd8cf4a75 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
@@ -15,3 +15,5 @@
 def GPRRegBank : RegisterBank<"GPR", [G8RC, G8RC_NOX0]>;
 /// Floating point Registers
 def FPRRegBank : RegisterBank<"FPR", [VSSRC]>;
+/// Condition Registers
+def CRRegBank : RegisterBank<"CR", [CRRC]>;

diff  --git a/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def b/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
index 897fe25bbe6c0..f7e79ae71ebd1 100644
--- a/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
+++ b/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
@@ -22,6 +22,8 @@ RegisterBankInfo::PartialMapping PPCGenRegisterBankInfo::PartMappings[]{
     {0, 32, PPC::FPRRegBank},
     // 3: FPR 64-bit value
     {0, 64, PPC::FPRRegBank},
+    // 4: CR 4-bit value
+    {0, 4, PPC::CRRegBank},
 };
 
 // ValueMappings.
@@ -55,6 +57,8 @@ RegisterBankInfo::ValueMapping PPCGenRegisterBankInfo::ValMappings[]{
     {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
     {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
     {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
+    // 13: CR 4-bit value.
+    {&PPCGenRegisterBankInfo::PartMappings[PMI_CR - PMI_Min], 1},
 };
 
 // TODO Too simple!

diff  --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 0b39a2b8e5873..ff21294ba846e 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -3327,9 +3327,9 @@ def : Pat<(i64 (sext i1:$in)),
 // FIXME: We should choose either a zext or a sext based on other constants
 // already around.
 def : Pat<(i32 (anyext i1:$in)),
-          (SELECT_I4 $in, (LI 1), (LI 0))>;
+          (SELECT_I4 i1:$in, (LI 1), (LI 0))>;
 def : Pat<(i64 (anyext i1:$in)),
-          (SELECT_I8 $in, (LI8 1), (LI8 0))>;
+          (SELECT_I8 i1:$in, (LI8 1), (LI8 0))>;
 
 // match setcc on i1 variables.
 // CRANDC is:
@@ -3735,34 +3735,34 @@ defm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETNE)),
 
 multiclass FSetCCPat<SDPatternOperator SetCC, ValueType Ty, I FCmp> {
   defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
-                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+                  (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_lt)>;
   defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
-                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+                  (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_lt)>;
   defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
-                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+                  (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_gt)>;
   defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
-                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+                  (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_gt)>;
   defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUNE)),
-                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+                  (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_eq)>;
   defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
-                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+                  (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_eq)>;
   defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETO)),
-                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
+                  (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_un)>;
 
   def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOLT)),
-            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+            (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_lt)>;
   def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLT)),
-            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+            (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_lt)>;
   def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOGT)),
-            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+            (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_gt)>;
   def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGT)),
-            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+            (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_gt)>;
   def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOEQ)),
-            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+            (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_eq)>;
   def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETEQ)),
-            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+            (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_eq)>;
   def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUO)),
-            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
+            (EXTRACT_SUBREG (FCmp Ty:$s1, Ty:$s2), sub_un)>;
 }
 
 let Predicates = [HasFPU] in {

diff  --git a/llvm/test/CodeGen/PowerPC/GlobalISel/fcmp.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/fcmp.ll
new file mode 100644
index 0000000000000..b1b092959e042
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/GlobalISel/fcmp.ll
@@ -0,0 +1,243 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel -o - \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s
+
+;; Note that SETUEQ, SETOGE, SETOLE, SETONE, SETULT and SETUGT should be
+;; expanded by legalize for floating-point types f32 and f64, so there are no.
+;; patterns defined in PPCInstrInfo.td file for these setcc patterns.
+
+define i1 @fcmp_false(float %a, float %b) {
+; CHECK-LABEL: fcmp_false:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    blr
+  %cmp = fcmp false float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_oeq(float %a, float %b) {
+; CHECK-LABEL: fcmp_oeq:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    iseleq r3, r4, r3
+; CHECK-NEXT:    blr
+  %cmp = fcmp oeq float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ogt(float %a, float %b) {
+; CHECK-LABEL: fcmp_ogt:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    iselgt r3, r4, r3
+; CHECK-NEXT:    blr
+  %cmp = fcmp ogt float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_olt(float %a, float %b) {
+; CHECK-LABEL: fcmp_olt:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    isellt r3, r4, r3
+; CHECK-NEXT:    blr
+  %cmp = fcmp olt float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ord(float %a, float %b) {
+; CHECK-LABEL: fcmp_ord:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, un
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp ord float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uge(float %a, float %b) {
+; CHECK-LABEL: fcmp_uge:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, lt
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp uge float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ule(float %a, float %b) {
+; CHECK-LABEL: fcmp_ule:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, gt
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp ule float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_une(float %a, float %b) {
+; CHECK-LABEL: fcmp_une:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, eq
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp une float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uno(float %a, float %b) {
+; CHECK-LABEL: fcmp_uno:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    isel r3, r4, r3, un
+; CHECK-NEXT:    blr
+  %cmp = fcmp uno float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_true(float %a, float %b) {
+; CHECK-LABEL: fcmp_true:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li r3, 1
+; CHECK-NEXT:    blr
+  %cmp = fcmp true float %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_false_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_false_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    blr
+  %cmp = fcmp false double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_oeq_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_oeq_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    iseleq r3, r4, r3
+; CHECK-NEXT:    blr
+  %cmp = fcmp oeq double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ogt_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_ogt_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    iselgt r3, r4, r3
+; CHECK-NEXT:    blr
+  %cmp = fcmp ogt double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_olt_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_olt_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    isellt r3, r4, r3
+; CHECK-NEXT:    blr
+  %cmp = fcmp olt double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ord_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_ord_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, un
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp ord double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uge_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_uge_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, lt
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp uge double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ule_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_ule_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, gt
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp ule double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_une_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_une_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    crnot 4*cr5+lt, eq
+; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
+; CHECK-NEXT:    blr
+  %cmp = fcmp une double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uno_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_uno_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fcmpu cr0, f1, f2
+; CHECK-NEXT:    li r3, 0
+; CHECK-NEXT:    li r4, 1
+; CHECK-NEXT:    isel r3, r4, r3, un
+; CHECK-NEXT:    blr
+  %cmp = fcmp uno double %a, %b
+  ret i1 %cmp
+}
+
+define i1 @fcmp_true_double(double %a, double %b) {
+; CHECK-LABEL: fcmp_true_double:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li r3, 1
+; CHECK-NEXT:    blr
+  %cmp = fcmp true double %a, %b
+  ret i1 %cmp
+}


        


More information about the llvm-commits mailing list