[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