@@ -996,6 +996,74 @@ llvm::ConstantFoldCTLZ(Register Src, const MachineRegisterInfo &MRI) {
996
996
return std::nullopt;
997
997
}
998
998
999
+ std::optional<SmallVector<APInt>>
1000
+ llvm::ConstantFoldICmp (unsigned Pred, const Register Op1, const Register Op2,
1001
+ const MachineRegisterInfo &MRI) {
1002
+ LLT Ty = MRI.getType (Op1);
1003
+ if (Ty != MRI.getType (Op2))
1004
+ return std::nullopt;
1005
+
1006
+ auto TryFoldScalar = [&MRI, Pred](Register LHS,
1007
+ Register RHS) -> std::optional<APInt> {
1008
+ auto LHSCst = getIConstantVRegVal (LHS, MRI);
1009
+ auto RHSCst = getIConstantVRegVal (RHS, MRI);
1010
+ if (!LHSCst || !RHSCst)
1011
+ return std::nullopt;
1012
+
1013
+ switch (Pred) {
1014
+ case CmpInst::Predicate::ICMP_EQ:
1015
+ return APInt (/* numBits=*/ 1 , LHSCst->eq (*RHSCst));
1016
+ case CmpInst::Predicate::ICMP_NE:
1017
+ return APInt (/* numBits=*/ 1 , LHSCst->ne (*RHSCst));
1018
+ case CmpInst::Predicate::ICMP_UGT:
1019
+ return APInt (/* numBits=*/ 1 , LHSCst->ugt (*RHSCst));
1020
+ case CmpInst::Predicate::ICMP_UGE:
1021
+ return APInt (/* numBits=*/ 1 , LHSCst->uge (*RHSCst));
1022
+ case CmpInst::Predicate::ICMP_ULT:
1023
+ return APInt (/* numBits=*/ 1 , LHSCst->ult (*RHSCst));
1024
+ case CmpInst::Predicate::ICMP_ULE:
1025
+ return APInt (/* numBits=*/ 1 , LHSCst->ule (*RHSCst));
1026
+ case CmpInst::Predicate::ICMP_SGT:
1027
+ return APInt (/* numBits=*/ 1 , LHSCst->sgt (*RHSCst));
1028
+ case CmpInst::Predicate::ICMP_SGE:
1029
+ return APInt (/* numBits=*/ 1 , LHSCst->sge (*RHSCst));
1030
+ case CmpInst::Predicate::ICMP_SLT:
1031
+ return APInt (/* numBits=*/ 1 , LHSCst->slt (*RHSCst));
1032
+ case CmpInst::Predicate::ICMP_SLE:
1033
+ return APInt (/* numBits=*/ 1 , LHSCst->sle (*RHSCst));
1034
+ default :
1035
+ return std::nullopt;
1036
+ }
1037
+ };
1038
+
1039
+ SmallVector<APInt> FoldedICmps;
1040
+
1041
+ if (Ty.isVector ()) {
1042
+ // Try to constant fold each element.
1043
+ auto *BV1 = getOpcodeDef<GBuildVector>(Op1, MRI);
1044
+ auto *BV2 = getOpcodeDef<GBuildVector>(Op2, MRI);
1045
+ if (!BV1 || !BV2)
1046
+ return std::nullopt;
1047
+ assert (BV1->getNumSources () == BV2->getNumSources () && " Invalid vectors" );
1048
+ for (unsigned I = 0 ; I < BV1->getNumSources (); ++I) {
1049
+ if (auto MaybeFold =
1050
+ TryFoldScalar (BV1->getSourceReg (I), BV2->getSourceReg (I))) {
1051
+ FoldedICmps.emplace_back (*MaybeFold);
1052
+ continue ;
1053
+ }
1054
+ return std::nullopt;
1055
+ }
1056
+ return FoldedICmps;
1057
+ }
1058
+
1059
+ if (auto MaybeCst = TryFoldScalar (Op1, Op2)) {
1060
+ FoldedICmps.emplace_back (*MaybeCst);
1061
+ return FoldedICmps;
1062
+ }
1063
+
1064
+ return std::nullopt;
1065
+ }
1066
+
999
1067
bool llvm::isKnownToBeAPowerOfTwo (Register Reg, const MachineRegisterInfo &MRI,
1000
1068
GISelKnownBits *KB) {
1001
1069
std::optional<DefinitionAndSourceRegister> DefSrcReg =
0 commit comments