@@ -1003,23 +1003,36 @@ LegalizerHelper::createSetStateLibcall(MachineIRBuilder &MIRBuilder,
1003
1003
// / the ICMP predicate that should be generated to compare with #0
1004
1004
// / after the libcall.
1005
1005
static std::pair<RTLIB::Libcall, CmpInst::Predicate>
1006
- getFCMPLibcallDesc (const CmpInst::Predicate Pred) {
1006
+ getFCMPLibcallDesc (const CmpInst::Predicate Pred, unsigned Size ) {
1007
+ #define RTLIBCASE_CMP (LibcallPrefix, ICmpPred ) \
1008
+ do { \
1009
+ switch (Size ) { \
1010
+ case 32 : \
1011
+ return {RTLIB::LibcallPrefix##32 , ICmpPred}; \
1012
+ case 64 : \
1013
+ return {RTLIB::LibcallPrefix##64 , ICmpPred}; \
1014
+ case 128 : \
1015
+ return {RTLIB::LibcallPrefix##128 , ICmpPred}; \
1016
+ default : \
1017
+ llvm_unreachable (" unexpected size" ); \
1018
+ } \
1019
+ } while (0 )
1007
1020
1008
1021
switch (Pred) {
1009
1022
case CmpInst::FCMP_OEQ:
1010
- return {RTLIB::OEQ_F128 , CmpInst::ICMP_EQ} ;
1023
+ RTLIBCASE_CMP (OEQ_F , CmpInst::ICMP_EQ) ;
1011
1024
case CmpInst::FCMP_UNE:
1012
- return {RTLIB::UNE_F128 , CmpInst::ICMP_NE} ;
1025
+ RTLIBCASE_CMP (UNE_F , CmpInst::ICMP_NE) ;
1013
1026
case CmpInst::FCMP_OGE:
1014
- return {RTLIB::OGE_F128 , CmpInst::ICMP_SGE} ;
1027
+ RTLIBCASE_CMP (OGE_F , CmpInst::ICMP_SGE) ;
1015
1028
case CmpInst::FCMP_OLT:
1016
- return {RTLIB::OLT_F128 , CmpInst::ICMP_SLT} ;
1029
+ RTLIBCASE_CMP (OLT_F , CmpInst::ICMP_SLT) ;
1017
1030
case CmpInst::FCMP_OLE:
1018
- return {RTLIB::OLE_F128 , CmpInst::ICMP_SLE} ;
1031
+ RTLIBCASE_CMP (OLE_F , CmpInst::ICMP_SLE) ;
1019
1032
case CmpInst::FCMP_OGT:
1020
- return {RTLIB::OGT_F128 , CmpInst::ICMP_SGT} ;
1033
+ RTLIBCASE_CMP (OGT_F , CmpInst::ICMP_SGT) ;
1021
1034
case CmpInst::FCMP_UNO:
1022
- return {RTLIB::UO_F128 , CmpInst::ICMP_NE} ;
1035
+ RTLIBCASE_CMP (UO_F , CmpInst::ICMP_NE) ;
1023
1036
default :
1024
1037
return {RTLIB::UNKNOWN_LIBCALL, CmpInst::BAD_ICMP_PREDICATE};
1025
1038
}
@@ -1034,21 +1047,24 @@ LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder,
1034
1047
const GFCmp *Cmp = cast<GFCmp>(&MI);
1035
1048
1036
1049
LLT OpLLT = MRI.getType (Cmp->getLHSReg ());
1037
- if (OpLLT != LLT::scalar (128 ) || OpLLT != MRI.getType (Cmp->getRHSReg ()))
1050
+ unsigned Size = OpLLT.getSizeInBits ();
1051
+ if ((Size != 32 && Size != 64 && Size != 128 ) ||
1052
+ OpLLT != MRI.getType (Cmp->getRHSReg ()))
1038
1053
return UnableToLegalize;
1039
1054
1040
1055
Type *OpType = getFloatTypeForLLT (Ctx, OpLLT);
1041
1056
1042
1057
// DstReg type is s32
1043
1058
const Register DstReg = Cmp->getReg (0 );
1059
+ LLT DstTy = MRI.getType (DstReg);
1044
1060
const auto Cond = Cmp->getCond ();
1045
1061
1046
1062
// Reference:
1047
1063
// https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html#Comparison-functions-1
1048
1064
// Generates a libcall followed by ICMP.
1049
- const auto BuildLibcall =
1050
- [&]( const RTLIB::Libcall Libcall, const CmpInst::Predicate ICmpPred,
1051
- const DstOp &Res = LLT::scalar ( 32 ) ) -> Register {
1065
+ const auto BuildLibcall = [&]( const RTLIB::Libcall Libcall,
1066
+ const CmpInst::Predicate ICmpPred,
1067
+ const DstOp &Res) -> Register {
1052
1068
// FCMP libcall always returns an i32, and needs an ICMP with #0.
1053
1069
constexpr LLT TempLLT = LLT::scalar (32 );
1054
1070
Register Temp = MRI.createGenericVirtualRegister (TempLLT);
@@ -1067,7 +1083,7 @@ LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder,
1067
1083
};
1068
1084
1069
1085
// Simple case if we have a direct mapping from predicate to libcall
1070
- if (const auto [Libcall, ICmpPred] = getFCMPLibcallDesc (Cond);
1086
+ if (const auto [Libcall, ICmpPred] = getFCMPLibcallDesc (Cond, Size );
1071
1087
Libcall != RTLIB::UNKNOWN_LIBCALL &&
1072
1088
ICmpPred != CmpInst::BAD_ICMP_PREDICATE) {
1073
1089
if (BuildLibcall (Libcall, ICmpPred, DstReg)) {
@@ -1083,11 +1099,13 @@ LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder,
1083
1099
// FCMP_UEQ: unordered or equal
1084
1100
// Convert into (FCMP_OEQ || FCMP_UNO).
1085
1101
1086
- const auto [OeqLibcall, OeqPred] = getFCMPLibcallDesc (CmpInst::FCMP_OEQ);
1087
- const auto Oeq = BuildLibcall (OeqLibcall, OeqPred);
1102
+ const auto [OeqLibcall, OeqPred] =
1103
+ getFCMPLibcallDesc (CmpInst::FCMP_OEQ, Size );
1104
+ const auto Oeq = BuildLibcall (OeqLibcall, OeqPred, DstTy);
1088
1105
1089
- const auto [UnoLibcall, UnoPred] = getFCMPLibcallDesc (CmpInst::FCMP_UNO);
1090
- const auto Uno = BuildLibcall (UnoLibcall, UnoPred);
1106
+ const auto [UnoLibcall, UnoPred] =
1107
+ getFCMPLibcallDesc (CmpInst::FCMP_UNO, Size );
1108
+ const auto Uno = BuildLibcall (UnoLibcall, UnoPred, DstTy);
1091
1109
if (Oeq && Uno)
1092
1110
MIRBuilder.buildOr (DstReg, Oeq, Uno);
1093
1111
else
@@ -1102,13 +1120,15 @@ LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder,
1102
1120
// We inverse the predicate instead of generating a NOT
1103
1121
// to save one instruction.
1104
1122
// On AArch64 isel can even select two cmp into a single ccmp.
1105
- const auto [OeqLibcall, OeqPred] = getFCMPLibcallDesc (CmpInst::FCMP_OEQ);
1123
+ const auto [OeqLibcall, OeqPred] =
1124
+ getFCMPLibcallDesc (CmpInst::FCMP_OEQ, Size );
1106
1125
const auto NotOeq =
1107
- BuildLibcall (OeqLibcall, CmpInst::getInversePredicate (OeqPred));
1126
+ BuildLibcall (OeqLibcall, CmpInst::getInversePredicate (OeqPred), DstTy );
1108
1127
1109
- const auto [UnoLibcall, UnoPred] = getFCMPLibcallDesc (CmpInst::FCMP_UNO);
1128
+ const auto [UnoLibcall, UnoPred] =
1129
+ getFCMPLibcallDesc (CmpInst::FCMP_UNO, Size );
1110
1130
const auto NotUno =
1111
- BuildLibcall (UnoLibcall, CmpInst::getInversePredicate (UnoPred));
1131
+ BuildLibcall (UnoLibcall, CmpInst::getInversePredicate (UnoPred), DstTy );
1112
1132
1113
1133
if (NotOeq && NotUno)
1114
1134
MIRBuilder.buildAnd (DstReg, NotOeq, NotUno);
@@ -1130,7 +1150,7 @@ LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder,
1130
1150
// MIRBuilder.buildFCmp(CmpInst::getInversePredicate(Pred), PredTy,
1131
1151
// Op1, Op2));
1132
1152
const auto [InversedLibcall, InversedPred] =
1133
- getFCMPLibcallDesc (CmpInst::getInversePredicate (Cond));
1153
+ getFCMPLibcallDesc (CmpInst::getInversePredicate (Cond), Size );
1134
1154
if (!BuildLibcall (InversedLibcall,
1135
1155
CmpInst::getInversePredicate (InversedPred), DstReg))
1136
1156
return UnableToLegalize;
0 commit comments