<s> auto & LoadStoreBuilder = getActionDefinitionsBuilder ( { G_LOAD , G_STORE } ) . legalForTypesWithMemDesc ( { { s1 , p0 , <NUM_LIT> , <NUM_LIT> } , { s8 , p0 , <NUM_LIT> , <NUM_LIT> } , { s16 , p0 , <NUM_LIT> , <NUM_LIT> } , { s32 , p0 , <NUM_LIT> , <NUM_LIT> } , { p0 , p0 , <NUM_LIT> , <NUM_LIT> } } ) . unsupportedIfMemSizeNotPow2 ( ) ; getActionDefinitionsBuilder ( G_FRAME_INDEX ) . legalFor ( { p0 } ) ; getActionDefinitionsBuilder ( G_GLOBAL_VALUE ) . legalFor ( { p0 } ) ; auto & PhiBuilder = getActionDefinitionsBuilder ( G_PHI ) . legalFor ( { s32 , p0 } ) . minScalar ( <NUM_LIT> , s32 ) ; getActionDefinitionsBuilder ( G_PTR_ADD ) . legalFor ( { { p0 , s32 } } ) . minScalar ( <NUM_LIT> , s32 ) ; getActionDefinitionsBuilder ( G_BRCOND ) . legalFor ( { s1 } ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2Base ( ) ) { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV , G_FCONSTANT , G_FNEG } ) . legalFor ( { s32 , s64 } ) ; LoadStoreBuilder . legalForTypesWithMemDesc ( { { s64 , p0 , <NUM_LIT> , <NUM_LIT> } } ) . maxScalar ( <NUM_LIT> , s32 ) ; PhiBuilder . legalFor ( { s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . legalForCartesianProduct ( { s1 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_MERGE_VALUES ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_UNMERGE_VALUES ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( G_FPEXT ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . legalForCartesianProduct ( { s32 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . legalForCartesianProduct ( { s32 , s64 } , { s32 } ) ; } else { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV } ) . libcallFor ( { s32 , s64 } ) ; LoadStoreBuilder . maxScalar ( <NUM_LIT> , s32 ) ; for ( auto Ty : { s32 , s64 } ) setAction ( { G_FNEG , Ty } , Lower ) ; getActionDefinitionsBuilder ( G_FCONSTANT ) . customFor ( { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . customForCartesianProduct ( { s1 } , { s32 , s64 } ) ;

if ( AEABI ( ST ) ) setFCmpLibcallsAEABI ( ) ;


<s> auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < Register , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MIRBuilder . buildConstant ( LLT :: scalar ( <NUM_LIT> ) , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; } if ( Results . size ( ) != <NUM_LIT> ) {

assert ( Results . size ( ) == <NUM_LIT> && <STR_LIT> ) ;


<s> using namespace TargetOpcode ; const LLT p0 = LLT :: pointer ( <NUM_LIT> , <NUM_LIT> ) ; const LLT s1 = LLT :: scalar ( <NUM_LIT> ) ; const LLT s8 = LLT :: scalar ( <NUM_LIT> ) ; const LLT s16 = LLT :: scalar ( <NUM_LIT> ) ; const LLT s32 = LLT :: scalar ( <NUM_LIT> ) ; const LLT s64 = LLT :: scalar ( <NUM_LIT> ) ; setAction ( { G_FRAME_INDEX , p0 } , Legal ) ; for ( unsigned Op : { G_LOAD , G_STORE } ) { for ( auto Ty : { s1 , s8 , s16 , s32 , p0 } ) setAction ( { Op , Ty } , Legal ) ; setAction ( { Op , <NUM_LIT> , p0 } , Legal ) ; } for ( auto Ty : { s1 , s8 , s16 , s32 } ) setAction ( { G_ADD , Ty } , Legal ) ; for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ;


<s> getActionDefinitionsBuilder ( G_SELECT ) . legalForCartesianProduct ( { s32 , p0 } , { s1 } ) ; auto & LoadStoreBuilder = getActionDefinitionsBuilder ( { G_LOAD , G_STORE } ) . legalForTypesWithMemDesc ( { { s1 , p0 , <NUM_LIT> , <NUM_LIT> } , { s8 , p0 , <NUM_LIT> , <NUM_LIT> } , { s16 , p0 , <NUM_LIT> , <NUM_LIT> } , { s32 , p0 , <NUM_LIT> , <NUM_LIT> } , { p0 , p0 , <NUM_LIT> , <NUM_LIT> } } ) ; auto & PhiBuilder = getActionDefinitionsBuilder ( G_PHI ) . legalFor ( { s32 , p0 } ) . minScalar ( <NUM_LIT> , s32 ) ; getActionDefinitionsBuilder ( G_GEP ) . legalFor ( { { p0 , s32 } } ) ; getActionDefinitionsBuilder ( G_BRCOND ) . legalFor ( { s1 } ) ; if ( ST . isThumb ( ) ) { computeTables ( ) ; verify ( * ST . getInstrInfo ( ) ) ; return ; } getActionDefinitionsBuilder ( G_GLOBAL_VALUE ) . legalFor ( { p0 } ) ; getActionDefinitionsBuilder ( G_FRAME_INDEX ) . legalFor ( { p0 } ) ; if ( ST . hasV5TOps ( ) ) { getActionDefinitionsBuilder ( G_CTLZ ) . legalFor ( { s32 , s32 } ) . clampScalar ( <NUM_LIT> , s32 , s32 ) . clampScalar ( <NUM_LIT> , s32 , s32 ) ; getActionDefinitionsBuilder ( G_CTLZ_ZERO_UNDEF ) . lowerFor ( { s32 , s32 } ) . clampScalar ( <NUM_LIT> , s32 , s32 ) . clampScalar ( <NUM_LIT> , s32 , s32 ) ; } else { getActionDefinitionsBuilder ( G_CTLZ_ZERO_UNDEF ) . libcallFor ( { s32 , s32 } ) . clampScalar ( <NUM_LIT> , s32 , s32 ) . clampScalar ( <NUM_LIT> , s32 , s32 ) ; getActionDefinitionsBuilder ( G_CTLZ ) . lowerFor ( { s32 , s32 } ) . clampScalar ( <NUM_LIT> , s32 , s32 ) . clampScalar ( <NUM_LIT> , s32 , s32 ) ; } if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV , G_FCONSTANT , G_FNEG } ) . legalFor ( { s32 , s64 } ) ; LoadStoreBuilder . legalFor ( { { s64 , p0 } } ) ; PhiBuilder . legalFor ( { s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . legalForCartesianProduct ( { s1 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_MERGE_VALUES ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_UNMERGE_VALUES ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( G_FPEXT ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . legalForCartesianProduct ( { s32 } , { s32 , s64 } ) ;

getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . legalForCartesianProduct ( { s32 , s64 } , { s32 } ) ;


<s> assert ( ( Predicate == CmpInst :: FCMP_TRUE || Predicate == CmpInst :: FCMP_FALSE ) && <STR_LIT> ) ; MIRBuilder . buildConstant ( OriginalResult , Predicate == CmpInst :: FCMP_TRUE ? <NUM_LIT> : <NUM_LIT> ) ; MI . eraseFromParent ( ) ; return true ; } assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < Register , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MIRBuilder . buildConstant ( LLT :: scalar ( <NUM_LIT> ) , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; } if ( Results . size ( ) != <NUM_LIT> ) { assert ( Results . size ( ) == <NUM_LIT> && <STR_LIT> ) ; MIRBuilder . buildOr ( OriginalResult , Results [ <NUM_LIT> ] , Results [ <NUM_LIT> ] ) ; }


<s> static void addAndInterleaveWithUnsupported ( LegacyLegalizerInfo :: SizeAndActionsVec & result , const LegacyLegalizerInfo :: SizeAndActionsVec & v ) {

for ( unsigned i = <NUM_LIT> ; i < v . size ( ) ; ++ i ) {


<s> if ( i + <NUM_LIT> < v [ i ] . first && i + <NUM_LIT> < v . size ( ) && v [ i + <NUM_LIT> ] . first != v [ i ] . first + <NUM_LIT> ) result . push_back ( { v [ i ] . first + <NUM_LIT> , LegacyLegalizeActions :: Unsupported } ) ;


<s> auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy , <NUM_LIT> } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy , <NUM_LIT> } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy , <NUM_LIT> } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MIRBuilder . buildConstant ( LLT :: scalar ( <NUM_LIT> ) , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; } if ( Results . size ( ) != <NUM_LIT> ) { assert ( Results . size ( ) == <NUM_LIT> && <STR_LIT> ) ; MIRBuilder . buildOr ( OriginalResult , Results [ <NUM_LIT> ] , Results [ <NUM_LIT> ] ) ; } break ; } case G_FCONSTANT : { auto AsInteger = MI . getOperand ( <NUM_LIT> ) . getFPImm ( ) -> getValueAPF ( ) . bitcastToAPInt ( ) ; MIRBuilder . buildConstant ( MI . getOperand ( <NUM_LIT> ) , * ConstantInt :: get ( Ctx , AsInteger ) ) ; break ;


<s> MI . eraseFromParent ( ) ; return true ; } assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < Register , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy , <NUM_LIT> } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy , <NUM_LIT> } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy , <NUM_LIT> } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MIRBuilder . buildConstant ( LLT :: scalar ( <NUM_LIT> ) , <NUM_LIT> ) ;

MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ;


<s> FCmp32Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: UO_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGT ] = { { RTLIB :: OLE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULE ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULT ] = { { RTLIB :: OGE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNE ] = { { RTLIB :: UNE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNO ] = { { RTLIB :: UO_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_ONE ] = { { RTLIB :: OGT_F32 , CmpInst :: BAD_ICMP_PREDICATE } , { RTLIB :: OLT_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_UEQ ] = { { RTLIB :: OEQ_F32 , CmpInst :: BAD_ICMP_PREDICATE } , { RTLIB :: UO_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp64Libcalls . resize ( CmpInst :: LAST_FCMP_PREDICATE + <NUM_LIT> ) ; FCmp64Libcalls [ CmpInst :: FCMP_OEQ ] = { { RTLIB :: OEQ_F64 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp64Libcalls [ CmpInst :: FCMP_OGE ] = { { RTLIB :: OGE_F64 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp64Libcalls [ CmpInst :: FCMP_OGT ] = { { RTLIB :: OGT_F64 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp64Libcalls [ CmpInst :: FCMP_OLE ] = { { RTLIB :: OLE_F64 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp64Libcalls [ CmpInst :: FCMP_OLT ] = { { RTLIB :: OLT_F64 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp64Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: UO_F64 , CmpInst :: ICMP_EQ } } ; FCmp64Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F64 , CmpInst :: ICMP_EQ } } ; FCmp64Libcalls [ CmpInst :: FCMP_UGT ] = { { RTLIB :: OLE_F64 , CmpInst :: ICMP_EQ } } ; FCmp64Libcalls [ CmpInst :: FCMP_ULE ] = { { RTLIB :: OGT_F64 , CmpInst :: ICMP_EQ } } ; FCmp64Libcalls [ CmpInst :: FCMP_ULT ] = { { RTLIB :: OGE_F64 , CmpInst :: ICMP_EQ } } ;

FCmp64Libcalls [ CmpInst :: FCMP_UNE ] = { { RTLIB :: UNE_F64 , CmpInst :: ICMP_EQ } } ;


<s> FCmp32Libcalls [ CmpInst :: FCMP_OEQ ] = { { RTLIB :: OEQ_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_OGE ] = { { RTLIB :: OGE_F32 , CmpInst :: ICMP_SGE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OGT ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_SGT } } ; FCmp32Libcalls [ CmpInst :: FCMP_OLE ] = { { RTLIB :: OLE_F32 , CmpInst :: ICMP_SLE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OLT ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_SLT } } ; FCmp32Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: UO_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_SGE } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGT ] = { { RTLIB :: OLE_F32 , CmpInst :: ICMP_SGT } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULE ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_SLE } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULT ] = { { RTLIB :: OGE_F32 , CmpInst :: ICMP_SLT } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNE ] = { { RTLIB :: UNE_F32 , CmpInst :: ICMP_NE } } ;

FCmp32Libcalls [ CmpInst :: FCMP_UNO ] = { { RTLIB :: UO_F32 , CmpInst :: ICMP_NE } } ;


<s> FCmp32Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: UO_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_SGE } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGT ] = { { RTLIB :: OLE_F32 , CmpInst :: ICMP_SGT } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULE ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_SLE } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULT ] = { { RTLIB :: OGE_F32 , CmpInst :: ICMP_SLT } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNE ] = { { RTLIB :: UNE_F32 , CmpInst :: ICMP_NE } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNO ] = { { RTLIB :: UO_F32 , CmpInst :: ICMP_NE } } ; FCmp32Libcalls [ CmpInst :: FCMP_ONE ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_SGT } , { RTLIB :: OLT_F32 , CmpInst :: ICMP_SLT } } ; FCmp32Libcalls [ CmpInst :: FCMP_UEQ ] = { { RTLIB :: OEQ_F32 , CmpInst :: ICMP_EQ } , { RTLIB :: UO_F32 , CmpInst :: ICMP_NE } } ; FCmp64Libcalls . resize ( CmpInst :: LAST_FCMP_PREDICATE + <NUM_LIT> ) ; FCmp64Libcalls [ CmpInst :: FCMP_OEQ ] = { { RTLIB :: OEQ_F64 , CmpInst :: ICMP_EQ } } ; FCmp64Libcalls [ CmpInst :: FCMP_OGE ] = { { RTLIB :: OGE_F64 , CmpInst :: ICMP_SGE } } ; FCmp64Libcalls [ CmpInst :: FCMP_OGT ] = { { RTLIB :: OGT_F64 , CmpInst :: ICMP_SGT } } ; FCmp64Libcalls [ CmpInst :: FCMP_OLE ] = { { RTLIB :: OLE_F64 , CmpInst :: ICMP_SLE } } ; FCmp64Libcalls [ CmpInst :: FCMP_OLT ] = { { RTLIB :: OLT_F64 , CmpInst :: ICMP_SLT } } ; FCmp64Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: UO_F64 , CmpInst :: ICMP_EQ } } ;

FCmp64Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F64 , CmpInst :: ICMP_SGE } } ;


<s> LegacyLegalizerInfo :: SizeAndActionsVec result = { { <NUM_LIT> , LegacyLegalizeActions :: Unsupported } , { <NUM_LIT> , LegacyLegalizeActions :: WidenScalar } , { <NUM_LIT> , LegacyLegalizeActions :: Unsupported } , { <NUM_LIT> , LegacyLegalizeActions :: WidenScalar } , { <NUM_LIT> , LegacyLegalizeActions :: Unsupported } } ; addAndInterleaveWithUnsupported ( result , v ) ; auto Largest = result . back ( ) . first ; result . push_back ( { Largest + <NUM_LIT> , LegacyLegalizeActions :: Unsupported } ) ;


<s> { <NUM_LIT> , LegacyLegalizeActions :: Unsupported } , { <NUM_LIT> , LegacyLegalizeActions :: WidenScalar } , { <NUM_LIT> , LegacyLegalizeActions :: Unsupported } , { <NUM_LIT> , LegacyLegalizeActions :: WidenScalar } , { <NUM_LIT> , LegacyLegalizeActions :: Unsupported } } ; addAndInterleaveWithUnsupported ( result , v ) ; auto Largest = result . back ( ) . first ; result . push_back ( { Largest + <NUM_LIT> , LegacyLegalizeActions :: Unsupported } ) ;


setAction ( { G_FCMP , <NUM_LIT> , s64 } , Custom ) ;


<s> auto & Ctx = MIRBuilder . getMF ( ) . getFunction ( ) -> getContext ( ) ; assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < unsigned , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; MIRBuilder . buildConstant ( Zero , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; }

if ( Results . size ( ) != <NUM_LIT> ) {


<s> Type * ArgTy = Type :: getInt32Ty ( Ctx ) ; StructType * RetTy = StructType :: get ( Ctx , { ArgTy , ArgTy } , true ) ; auto RetVal = MRI . createGenericVirtualRegister ( getLLTForType ( * RetTy , MIRBuilder . getMF ( ) . getDataLayout ( ) ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall , { RetVal , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; MIRBuilder . buildUnmerge ( { MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) , OriginalResult } , RetVal ) ; break ; } case G_FCMP : { assert ( MRI . getType ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) == MRI . getType ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) && <STR_LIT> ) ; auto OpSize = MRI . getType ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) . getSizeInBits ( ) ; auto OriginalResult = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; auto Predicate = static_cast < CmpInst :: Predicate > ( MI . getOperand ( <NUM_LIT> ) . getPredicate ( ) ) ; auto Libcalls = getFCmpLibcalls ( Predicate , OpSize ) ; if ( Libcalls . empty ( ) ) { assert ( ( Predicate == CmpInst :: FCMP_TRUE || Predicate == CmpInst :: FCMP_FALSE ) && <STR_LIT> ) ; MIRBuilder . buildConstant ( OriginalResult , Predicate == CmpInst :: FCMP_TRUE ? <NUM_LIT> : <NUM_LIT> ) ; MI . eraseFromParent ( ) ; return true ; } auto & Ctx = MIRBuilder . getMF ( ) . getFunction ( ) -> getContext ( ) ; assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < unsigned , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ;

auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ;


<s> for ( unsigned Op : { G_SDIV , G_UDIV } ) { for ( auto Ty : { s8 , s16 } ) setAction ( { Op , Ty } , WidenScalar ) ; if ( ST . hasDivideIn<ISA_LIT>Mode ( ) ) setAction ( { Op , s32 } , Legal ) ; else setAction ( { Op , s32 } , Libcall ) ; } for ( unsigned Op : { G_SREM , G_UREM } ) if ( ST . hasDivideIn<ISA_LIT>Mode ( ) ) setAction ( { Op , s32 } , Lower ) ; else if ( AEABI ( ST ) ) setAction ( { Op , s32 } , Custom ) ; else setAction ( { Op , s32 } , Libcall ) ; for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_SELECT , s32 } , Legal ) ; setAction ( { G_SELECT , p0 } , Legal ) ; setAction ( { G_SELECT , <NUM_LIT> , s1 } , Legal ) ; setAction ( { G_BRCOND , s1 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { G_CONSTANT , Ty } , WidenScalar ) ; setAction ( { G_ICMP , s1 } , Legal ) ; for ( auto Ty : { s8 , s16 } ) setAction ( { G_ICMP , <NUM_LIT> , Ty } , WidenScalar ) ; for ( auto Ty : { s32 , p0 } ) setAction ( { G_ICMP , <NUM_LIT> , Ty } , Legal ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ; setAction ( { G_LOAD , s64 } , Legal ) ; setAction ( { G_STORE , s64 } , Legal ) ; setAction ( { G_FCMP , s1 } , Legal ) ; setAction ( { G_FCMP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_FCMP , <NUM_LIT> , s64 } , Legal ) ; } else { for ( auto Ty : { s32 , s64 } ) setAction ( { G_FADD , Ty } , Libcall ) ; setAction ( { G_FCMP , s1 } , Legal ) ; setAction ( { G_FCMP , <NUM_LIT> , s32 } , Custom ) ;


<s> setAction ( { G_FRAME_INDEX , p0 } , Legal ) ; setAction ( { G_LOAD , s32 } , Legal ) ; setAction ( { G_LOAD , <NUM_LIT> , p0 } , Legal ) ; for ( auto Ty : { s8 , s16 , s32 } ) setAction ( { G_ADD , Ty } , Legal ) ; computeTables ( ) ;


<s> setAction ( { G_LOAD , s32 } , Legal ) ; setAction ( { G_LOAD , <NUM_LIT> , p0 } , Legal ) ; for ( auto Ty : { s8 , s16 , s32 } ) setAction ( { G_ADD , Ty } , Legal ) ; computeTables ( ) ;


<s> for ( unsigned Op : { G_ADD , G_SUB , G_MUL } ) for ( auto Ty : { s1 , s8 , s16 , s32 } ) setAction ( { Op , Ty } , Legal ) ; for ( unsigned Op : { G_SDIV , G_UDIV } ) { for ( auto Ty : { s8 , s16 } ) setAction ( { Op , Ty } , Custom ) ; if ( ST . hasDivideIn<ISA_LIT>Mode ( ) ) setAction ( { Op , s32 } , Legal ) ; else setAction ( { Op , s32 } , Libcall ) ; } for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ; setAction ( { G_LOAD , s64 } , Legal ) ; setAction ( { G_STORE , s64 } , Legal ) ;


<s> else setAction ( { Op , s32 } , Libcall ) ; } for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ;

setAction ( { G_LOAD , s64 } , Legal ) ;


<s> LegalizerHelper Helper ( MIRBuilder . getMF ( ) ) ; MachineInstr * NewMI = nullptr ; Helper . MIRBuilder . recordInsertions ( [ & ] ( MachineInstr * MI ) { if ( MI -> getOpcode ( ) == G_SDIV || MI -> getOpcode ( ) == G_UDIV ) NewMI = MI ; } ) ; auto Result = Helper . widenScalar ( MI , <NUM_LIT> , LLT :: scalar ( <NUM_LIT> ) ) ; Helper . MIRBuilder . stopRecordingInsertions ( ) ; if ( Result == LegalizerHelper :: UnableToLegalize ) { return false ; } assert ( NewMI && <STR_LIT> ) ; assert ( ( NewMI -> getOpcode ( ) == G_SDIV || NewMI -> getOpcode ( ) == G_UDIV ) && <STR_LIT> ) ;

assert ( MRI . getType ( NewMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . getSizeInBits ( ) == <NUM_LIT> && <STR_LIT> ) ;


<s> if ( ! ST . useSoftFloat ( ) && ST . hasVFP2Base ( ) ) { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV , G_FCONSTANT , G_FNEG } ) . legalFor ( { s32 , s64 } ) ; LoadStoreBuilder . legalForTypesWithMemDesc ( { { s64 , p0 , <NUM_LIT> , <NUM_LIT> } } ) . maxScalar ( <NUM_LIT> , s32 ) ; PhiBuilder . legalFor ( { s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . legalForCartesianProduct ( { s1 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_MERGE_VALUES ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_UNMERGE_VALUES ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( G_FPEXT ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . legalForCartesianProduct ( { s32 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . legalForCartesianProduct ( { s32 , s64 } , { s32 } ) ; } else { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV } ) . libcallFor ( { s32 , s64 } ) ; LoadStoreBuilder . maxScalar ( <NUM_LIT> , s32 ) ; for ( auto Ty : { s32 , s64 } ) setAction ( { G_FNEG , Ty } , Lower ) ; getActionDefinitionsBuilder ( G_FCONSTANT ) . customFor ( { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . customForCartesianProduct ( { s1 } , { s32 , s64 } ) ; if ( AEABI ( ST ) ) setFCmpLibcallsAEABI ( ) ; else setFCmpLibcallsGNU ( ) ; getActionDefinitionsBuilder ( G_FPEXT ) . libcallFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . libcallFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . libcallForCartesianProduct ( { s32 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . libcallForCartesianProduct ( { s32 , s64 } , { s32 } ) ; } if ( ! ST . useSoftFloat ( ) && ST . hasVFP4Base ( ) ) getActionDefinitionsBuilder ( G_FMA ) . legalFor ( { s32 , s64 } ) ; else getActionDefinitionsBuilder ( G_FMA ) . libcallFor ( { s32 , s64 } ) ;

getActionDefinitionsBuilder ( { G_FREM , G_FPOW } ) . libcallFor ( { s32 , s64 } ) ;


<s> static void addAndInterleaveWithUnsupported ( LegalizerInfo :: SizeAndActionsVec & result , const LegalizerInfo :: SizeAndActionsVec & v ) { for ( unsigned i = <NUM_LIT> ; i < v . size ( ) ; ++ i ) { result . push_back ( v [ i ] ) ; if ( i + <NUM_LIT> < v [ i ] . first && i + <NUM_LIT> < v . size ( ) && v [ i + <NUM_LIT> ] . first != v [ i ] . first + <NUM_LIT> ) result . push_back ( { v [ i ] . first + <NUM_LIT> , LegalizerInfo :: Unsupported } ) ;


<s> result . push_back ( v [ i ] ) ; if ( i + <NUM_LIT> < v [ i ] . first && i + <NUM_LIT> < v . size ( ) && v [ i + <NUM_LIT> ] . first != v [ i ] . first + <NUM_LIT> ) result . push_back ( { v [ i ] . first + <NUM_LIT> , LegalizerInfo :: Unsupported } ) ; }


setAction ( { G_FCMP , <NUM_LIT> , s32 } , Custom ) ;


<s> case G_FCMP : { assert ( MRI . getType ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) == MRI . getType ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) && <STR_LIT> ) ; auto OpSize = MRI . getType ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) . getSizeInBits ( ) ; auto OriginalResult = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; auto Predicate = static_cast < CmpInst :: Predicate > ( MI . getOperand ( <NUM_LIT> ) . getPredicate ( ) ) ; auto Libcalls = getFCmpLibcalls ( Predicate , OpSize ) ; if ( Libcalls . empty ( ) ) { assert ( ( Predicate == CmpInst :: FCMP_TRUE || Predicate == CmpInst :: FCMP_FALSE ) && <STR_LIT> ) ; MIRBuilder . buildConstant ( OriginalResult , Predicate == CmpInst :: FCMP_TRUE ? <NUM_LIT> : <NUM_LIT> ) ; MI . eraseFromParent ( ) ; return true ; } auto & Ctx = MIRBuilder . getMF ( ) . getFunction ( ) . getContext ( ) ; assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < unsigned , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; MIRBuilder . buildConstant ( Zero , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; } if ( Results . size ( ) != <NUM_LIT> ) { assert ( Results . size ( ) == <NUM_LIT> && <STR_LIT> ) ; MIRBuilder . buildOr ( OriginalResult , Results [ <NUM_LIT> ] , Results [ <NUM_LIT> ] ) ; } break ; } }


<s> assert ( v . size ( ) >= <NUM_LIT> ) ; assert ( v [ <NUM_LIT> ] . first > <NUM_LIT> ) ; LegalizerInfo :: SizeAndActionsVec result = { { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } } ; addAndInterleaveWithUnsupported ( result , v ) ; auto Largest = result . back ( ) . first ;

result . push_back ( { Largest + <NUM_LIT> , LegalizerInfo :: Unsupported } ) ;


<s> { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } } ;

addAndInterleaveWithUnsupported ( result , v ) ;


<s> addAndInterleaveWithUnsupported ( result , v ) ; auto Largest = result . back ( ) . first ; result . push_back ( { Largest + <NUM_LIT> , LegalizerInfo :: Unsupported } ) ; return result ;


<s> const LLT s16 = LLT :: scalar ( <NUM_LIT> ) ; const LLT s32 = LLT :: scalar ( <NUM_LIT> ) ; const LLT s64 = LLT :: scalar ( <NUM_LIT> ) ; setAction ( { G_FRAME_INDEX , p0 } , Legal ) ; for ( unsigned Op : { G_LOAD , G_STORE } ) { for ( auto Ty : { s1 , s8 , s16 , s32 , p0 } ) setAction ( { Op , Ty } , Legal ) ; setAction ( { Op , <NUM_LIT> , p0 } , Legal ) ; } for ( auto Ty : { s1 , s8 , s16 , s32 } ) setAction ( { G_ADD , Ty } , Legal ) ; for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) {

setAction ( { G_FADD , s32 } , Legal ) ;


<s> getActionDefinitionsBuilder ( G_ICMP ) . legalForCartesianProduct ( { s1 } , { s32 , p0 } ) . minScalar ( <NUM_LIT> , s32 ) ; getActionDefinitionsBuilder ( G_SELECT ) . legalForCartesianProduct ( { s32 , p0 } , { s1 } ) ; auto & LoadStoreBuilder = getActionDefinitionsBuilder ( { G_LOAD , G_STORE } ) . legalForTypesWithMemDesc ( { { s1 , p0 , <NUM_LIT> , <NUM_LIT> } , { s8 , p0 , <NUM_LIT> , <NUM_LIT> } , { s16 , p0 , <NUM_LIT> , <NUM_LIT> } , { s32 , p0 , <NUM_LIT> , <NUM_LIT> } , { p0 , p0 , <NUM_LIT> , <NUM_LIT> } } ) . unsupportedIfMemSizeNotPow2 ( ) ; getActionDefinitionsBuilder ( G_FRAME_INDEX ) . legalFor ( { p0 } ) ; getActionDefinitionsBuilder ( G_GLOBAL_VALUE ) . legalFor ( { p0 } ) ; auto & PhiBuilder = getActionDefinitionsBuilder ( G_PHI ) . legalFor ( { s32 , p0 } ) . minScalar ( <NUM_LIT> , s32 ) ; getActionDefinitionsBuilder ( G_GEP ) . legalFor ( { { p0 , s32 } } ) ; getActionDefinitionsBuilder ( G_BRCOND ) . legalFor ( { s1 } ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV , G_FCONSTANT , G_FNEG } ) . legalFor ( { s32 , s64 } ) ; LoadStoreBuilder . legalForTypesWithMemDesc ( { { s64 , p0 , <NUM_LIT> , <NUM_LIT> } } ) . maxScalar ( <NUM_LIT> , s32 ) ; PhiBuilder . legalFor ( { s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . legalForCartesianProduct ( { s1 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_MERGE_VALUES ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_UNMERGE_VALUES ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( G_FPEXT ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . legalForCartesianProduct ( { s32 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . legalForCartesianProduct ( { s32 , s64 } , { s32 } ) ; } else { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV } ) . libcallFor ( { s32 , s64 } ) ; LoadStoreBuilder . maxScalar ( <NUM_LIT> , s32 ) ; for ( auto Ty : { s32 , s64 } ) setAction ( { G_FNEG , Ty } , Lower ) ; getActionDefinitionsBuilder ( G_FCONSTANT ) . customFor ( { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . customForCartesianProduct ( { s1 } , { s32 , s64 } ) ; if ( AEABI ( ST ) ) setFCmpLibcallsAEABI ( ) ;


<s> for ( auto Ty : { s1 , s8 , s16 , s32 } ) setAction ( { G_ADD , Ty } , Legal ) ; for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; if ( ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ; setAction ( { G_LOAD , s64 } , Legal ) ; setAction ( { G_STORE , s64 } , Legal ) ;


<s> for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; if ( ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ; setAction ( { G_LOAD , s64 } , Legal ) ; setAction ( { G_STORE , s64 } , Legal ) ;


<s> return true ; } assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < Register , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; MIRBuilder . buildConstant ( Zero , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; } if ( Results . size ( ) != <NUM_LIT> ) { assert ( Results . size ( ) == <NUM_LIT> && <STR_LIT> ) ; MIRBuilder . buildOr ( OriginalResult , Results [ <NUM_LIT> ] , Results [ <NUM_LIT> ] ) ;


<s> auto OpSize = MRI . getType ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) ) . getSizeInBits ( ) ; auto OriginalResult = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; auto Predicate = static_cast < CmpInst :: Predicate > ( MI . getOperand ( <NUM_LIT> ) . getPredicate ( ) ) ; auto Libcalls = getFCmpLibcalls ( Predicate , OpSize ) ; if ( Libcalls . empty ( ) ) { assert ( ( Predicate == CmpInst :: FCMP_TRUE || Predicate == CmpInst :: FCMP_FALSE ) && <STR_LIT> ) ; MIRBuilder . buildConstant ( OriginalResult , Predicate == CmpInst :: FCMP_TRUE ? <NUM_LIT> : <NUM_LIT> ) ; MI . eraseFromParent ( ) ; return true ; } assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < Register , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ;

MIRBuilder . buildConstant ( Zero , <NUM_LIT> ) ;


<s> return true ; } assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < Register , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; MIRBuilder . buildConstant ( Zero , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; }


<s> MI . eraseFromParent ( ) ; return true ; } assert ( ( OpSize == <NUM_LIT> || OpSize == <NUM_LIT> ) && <STR_LIT> ) ; auto * ArgTy = OpSize == <NUM_LIT> ? Type :: getFloatTy ( Ctx ) : Type :: getDoubleTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < Register , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; MIRBuilder . buildConstant ( Zero , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ; } if ( Results . size ( ) != <NUM_LIT> ) { assert ( Results . size ( ) == <NUM_LIT> && <STR_LIT> ) ; MIRBuilder . buildOr ( OriginalResult , Results [ <NUM_LIT> ] , Results [ <NUM_LIT> ] ) ; } break ; }


<s> } getActionDefinitionsBuilder ( G_BRCOND ) . legalFor ( { s1 } ) ; auto & PhiBuilder = getActionDefinitionsBuilder ( G_PHI ) . legalFor ( { s32 , p0 } ) . minScalar ( <NUM_LIT> , s32 ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV , G_FCONSTANT , G_FNEG } ) . legalFor ( { s32 , s64 } ) ; LoadStoreBuilder . legalFor ( { { s64 , p0 } } ) ; PhiBuilder . legalFor ( { s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . legalForCartesianProduct ( { s1 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_MERGE_VALUES ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_UNMERGE_VALUES ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( G_FPEXT ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . legalForCartesianProduct ( { s32 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . legalForCartesianProduct ( { s32 , s64 } , { s32 } ) ; } else { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV } ) . libcallFor ( { s32 , s64 } ) ; LoadStoreBuilder . maxScalar ( <NUM_LIT> , s32 ) ; for ( auto Ty : { s32 , s64 } ) setAction ( { G_FNEG , Ty } , Lower ) ; getActionDefinitionsBuilder ( G_FCONSTANT ) . customFor ( { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . customForCartesianProduct ( { s1 } , { s32 , s64 } ) ; if ( AEABI ( ST ) ) setFCmpLibcallsAEABI ( ) ; else setFCmpLibcallsGNU ( ) ; getActionDefinitionsBuilder ( G_FPEXT ) . libcallFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . libcallFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . libcallForCartesianProduct ( { s32 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . libcallForCartesianProduct ( { s32 , s64 } , { s32 } ) ; } if ( ! ST . useSoftFloat ( ) && ST . hasVFP4 ( ) ) getActionDefinitionsBuilder ( G_FMA ) . legalFor ( { s32 , s64 } ) ; else getActionDefinitionsBuilder ( G_FMA ) . libcallFor ( { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_FREM , G_FPOW } ) . libcallFor ( { s32 , s64 } ) ; computeTables ( ) ;


<s> if ( Result == LegalizerHelper :: UnableToLegalize ) { return false ; } assert ( NewMI && <STR_LIT> ) ; assert ( ( NewMI -> getOpcode ( ) == G_SDIV || NewMI -> getOpcode ( ) == G_UDIV ) && <STR_LIT> ) ; assert ( MRI . getType ( NewMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . getSizeInBits ( ) == <NUM_LIT> && <STR_LIT> ) ; Result = Helper . legalizeInstrStep ( * NewMI ) ; if ( Result == LegalizerHelper :: UnableToLegalize ) { return false ; } return true ; } case G_SREM : case G_UREM : { unsigned OriginalResult = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; auto Size = MRI . getType ( OriginalResult ) . getSizeInBits ( ) ; if ( Size != <NUM_LIT> ) return false ; auto Libcall = MI . getOpcode ( ) == G_SREM ? RTLIB :: SDIVREM_I32 : RTLIB :: UDIVREM_I32 ; auto & Ctx = MIRBuilder . getMF ( ) . getFunction ( ) -> getContext ( ) ; Type * ArgTy = Type :: getInt32Ty ( Ctx ) ; StructType * RetTy = StructType :: get ( Ctx , { ArgTy , ArgTy } , true ) ; auto RetVal = MRI . createGenericVirtualRegister ( getLLTForType ( * RetTy , MIRBuilder . getMF ( ) . getDataLayout ( ) ) ) ; auto Status = replaceWithLibcall ( MI , MIRBuilder , Libcall , { RetVal , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; MIRBuilder . buildUnmerge ( { MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) , OriginalResult } , RetVal ) ; return LegalizerHelper :: Legalized ; }


<s> setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } if ( ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ; setAction ( { G_LOAD , s64 } , Legal ) ;


getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV , G_FCONSTANT , G_FNEG } ) . legalFor ( { s32 , s64 } ) ;


<s> assert ( v . size ( ) >= <NUM_LIT> ) ; assert ( v [ <NUM_LIT> ] . first > <NUM_LIT> ) ; LegalizerInfo :: SizeAndActionsVec result = { { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } } ; addAndInterleaveWithUnsupported ( result , v ) ; auto Largest = result . back ( ) . first ; result . push_back ( { Largest + <NUM_LIT> , LegalizerInfo :: NarrowScalar } ) ; return result ;


<s> assert ( v . size ( ) >= <NUM_LIT> ) ; assert ( v [ <NUM_LIT> ] . first > <NUM_LIT> ) ; LegalizerInfo :: SizeAndActionsVec result = { { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } , { <NUM_LIT> , LegalizerInfo :: WidenScalar } , { <NUM_LIT> , LegalizerInfo :: Unsupported } } ; addAndInterleaveWithUnsupported ( result , v ) ; auto Largest = result . back ( ) . first ; result . push_back ( { Largest + <NUM_LIT> , LegalizerInfo :: NarrowScalar } ) ;


<s> setAction ( { G_SELECT , <NUM_LIT> , s1 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { G_CONSTANT , Ty } , WidenScalar ) ; setAction ( { G_ICMP , s1 } , Legal ) ; for ( auto Ty : { s8 , s16 } ) setAction ( { G_ICMP , <NUM_LIT> , Ty } , WidenScalar ) ; for ( auto Ty : { s32 , p0 } ) setAction ( { G_ICMP , <NUM_LIT> , Ty } , Legal ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ; setAction ( { G_LOAD , s64 } , Legal ) ; setAction ( { G_STORE , s64 } , Legal ) ; setAction ( { G_FCMP , s1 } , Legal ) ; setAction ( { G_FCMP , <NUM_LIT> , s32 } , Legal ) ; } else { for ( auto Ty : { s32 , s64 } ) setAction ( { G_FADD , Ty } , Libcall ) ; setAction ( { G_FCMP , s1 } , Legal ) ; setAction ( { G_FCMP , <NUM_LIT> , s32 } , Custom ) ; if ( AEABI ( ST ) ) setFCmpLibcallsAEABI ( ) ; else setFCmpLibcallsGNU ( ) ; } for ( unsigned Op : { G_FREM , G_FPOW } ) for ( auto Ty : { s32 , s64 } ) setAction ( { Op , Ty } , Libcall ) ; computeTables ( ) ;


<s> else setAction ( { Op , s32 } , Libcall ) ; for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_SELECT , s32 } , Legal ) ; setAction ( { G_SELECT , p0 } , Legal ) ; setAction ( { G_SELECT , <NUM_LIT> , s1 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { G_CONSTANT , Ty } , WidenScalar ) ; setAction ( { G_ICMP , s1 } , Legal ) ; for ( auto Ty : { s8 , s16 } ) setAction ( { G_ICMP , <NUM_LIT> , Ty } , WidenScalar ) ; for ( auto Ty : { s32 , p0 } ) setAction ( { G_ICMP , <NUM_LIT> , Ty } , Legal ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { setAction ( { G_FADD , s32 } , Legal ) ; setAction ( { G_FADD , s64 } , Legal ) ; setAction ( { G_LOAD , s64 } , Legal ) ; setAction ( { G_STORE , s64 } , Legal ) ; setAction ( { G_FCMP , s1 } , Legal ) ;

setAction ( { G_FCMP , <NUM_LIT> , s32 } , Legal ) ;


<s> <ISA_LIT>LegalizerInfo :: FCmpLibcallsList <ISA_LIT>LegalizerInfo :: getFCmpLibcalls ( CmpInst :: Predicate Predicate ) const { assert ( CmpInst :: isFPPredicate ( Predicate ) && <STR_LIT> ) ;


<s> auto Predicate = static_cast < CmpInst :: Predicate > ( MI . getOperand ( <NUM_LIT> ) . getPredicate ( ) ) ; auto Libcalls = getFCmpLibcalls ( Predicate ) ; if ( Libcalls . empty ( ) ) { assert ( ( Predicate == CmpInst :: FCMP_TRUE || Predicate == CmpInst :: FCMP_FALSE ) && <STR_LIT> ) ; MIRBuilder . buildConstant ( OriginalResult , Predicate == CmpInst :: FCMP_TRUE ? <NUM_LIT> : <NUM_LIT> ) ; return true ; } auto & Ctx = MIRBuilder . getMF ( ) . getFunction ( ) -> getContext ( ) ; auto * ArgTy = Type :: getFloatTy ( Ctx ) ; auto * RetTy = Type :: getInt32Ty ( Ctx ) ; SmallVector < unsigned , <NUM_LIT> > Results ; for ( auto Libcall : Libcalls ) { auto LibcallResult = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; auto Status = createLibcall ( MIRBuilder , Libcall . LibcallID , { LibcallResult , RetTy } , { { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } , { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , ArgTy } } ) ; if ( Status != LegalizerHelper :: Legalized ) return false ; auto ProcessedResult = Libcalls . size ( ) == <NUM_LIT> ? OriginalResult : MRI . createGenericVirtualRegister ( MRI . getType ( OriginalResult ) ) ; CmpInst :: Predicate ResultPred = Libcall . Predicate ; if ( ResultPred == CmpInst :: BAD_ICMP_PREDICATE ) { MIRBuilder . buildTrunc ( ProcessedResult , LibcallResult ) ; } else { assert ( CmpInst :: isIntPredicate ( ResultPred ) && <STR_LIT> ) ; auto Zero = MRI . createGenericVirtualRegister ( LLT :: scalar ( <NUM_LIT> ) ) ; MIRBuilder . buildConstant ( Zero , <NUM_LIT> ) ; MIRBuilder . buildICmp ( ResultPred , ProcessedResult , LibcallResult , Zero ) ; } Results . push_back ( ProcessedResult ) ;


<s> FCmp32Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: O_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGT ] = { { RTLIB :: OLE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULE ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULT ] = { { RTLIB :: OGE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNE ] = { { RTLIB :: UNE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNO ] = { { RTLIB :: UO_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_ONE ] = { { RTLIB :: OGT_F32 , CmpInst :: BAD_ICMP_PREDICATE } , { RTLIB :: OLT_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ;

FCmp32Libcalls [ CmpInst :: FCMP_UEQ ] = {


<s> { RTLIB :: OEQ_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OGE ] = { { RTLIB :: OGE_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OGT ] = { { RTLIB :: OGT_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OLE ] = { { RTLIB :: OLE_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OLT ] = { { RTLIB :: OLT_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: O_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UGT ] = { { RTLIB :: OLE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULE ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_ULT ] = { { RTLIB :: OGE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNE ] = { { RTLIB :: UNE_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_UNO ] = { { RTLIB :: UO_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ; FCmp32Libcalls [ CmpInst :: FCMP_ONE ] = { { RTLIB :: OGT_F32 , CmpInst :: BAD_ICMP_PREDICATE } , { RTLIB :: OLT_F32 , CmpInst :: BAD_ICMP_PREDICATE } } ;


<s> FCmp32Libcalls [ CmpInst :: FCMP_OEQ ] = { { RTLIB :: OEQ_F32 , CmpInst :: ICMP_EQ } } ; FCmp32Libcalls [ CmpInst :: FCMP_OGE ] = { { RTLIB :: OGE_F32 , CmpInst :: ICMP_SGE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OGT ] = { { RTLIB :: OGT_F32 , CmpInst :: ICMP_SGT } } ; FCmp32Libcalls [ CmpInst :: FCMP_OLE ] = { { RTLIB :: OLE_F32 , CmpInst :: ICMP_SLE } } ; FCmp32Libcalls [ CmpInst :: FCMP_OLT ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_SLT } } ; FCmp32Libcalls [ CmpInst :: FCMP_ORD ] = { { RTLIB :: O_F32 , CmpInst :: ICMP_EQ } } ;

FCmp32Libcalls [ CmpInst :: FCMP_UGE ] = { { RTLIB :: OLT_F32 , CmpInst :: ICMP_SGE } } ;


<s> setAction ( { Op , <NUM_LIT> , p0 } , Legal ) ; } for ( unsigned Op : { G_ADD , G_SUB , G_MUL , G_AND , G_OR , G_XOR } ) { for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , Ty } , WidenScalar ) ; setAction ( { Op , s32 } , Legal ) ; } for ( unsigned Op : { G_SDIV , G_UDIV } ) { for ( auto Ty : { s8 , s16 } ) setAction ( { Op , Ty } , WidenScalar ) ; if ( ST . hasDivideIn<ISA_LIT>Mode ( ) ) setAction ( { Op , s32 } , Legal ) ; else setAction ( { Op , s32 } , Libcall ) ; } for ( unsigned Op : { G_SREM , G_UREM } ) { for ( auto Ty : { s8 , s16 } ) setAction ( { Op , Ty } , WidenScalar ) ; if ( ST . hasDivideIn<ISA_LIT>Mode ( ) ) setAction ( { Op , s32 } , Lower ) ; else if ( AEABI ( ST ) ) setAction ( { Op , s32 } , Custom ) ; else setAction ( { Op , s32 } , Libcall ) ; } for ( unsigned Op : { G_SEXT , G_ZEXT } ) { setAction ( { Op , s32 } , Legal ) ; for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { Op , <NUM_LIT> , Ty } , Legal ) ; } setAction ( { G_GEP , p0 } , Legal ) ; setAction ( { G_GEP , <NUM_LIT> , s32 } , Legal ) ; setAction ( { G_SELECT , s32 } , Legal ) ; setAction ( { G_SELECT , p0 } , Legal ) ; setAction ( { G_SELECT , <NUM_LIT> , s1 } , Legal ) ; setAction ( { G_BRCOND , s1 } , Legal ) ; setAction ( { G_CONSTANT , s32 } , Legal ) ;

for ( auto Ty : { s1 , s8 , s16 } ) setAction ( { G_CONSTANT , Ty } , WidenScalar ) ;


<s> getActionDefinitionsBuilder ( G_GEP ) . legalFor ( { { p0 , s32 } } ) ; getActionDefinitionsBuilder ( G_SELECT ) . legalForCartesianProduct ( { s32 , p0 } , { s1 } ) ; getActionDefinitionsBuilder ( G_BRCOND ) . legalFor ( { s1 } ) ; getActionDefinitionsBuilder ( G_ICMP ) . legalForCartesianProduct ( { s1 } , { s32 , p0 } ) . minScalar ( <NUM_LIT> , s32 ) ; auto & PhiBuilder = getActionDefinitionsBuilder ( G_PHI ) . legalFor ( { s32 , p0 } ) . minScalar ( <NUM_LIT> , s32 ) ; if ( ! ST . useSoftFloat ( ) && ST . hasVFP2 ( ) ) { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV , G_FCONSTANT , G_FNEG } ) . legalFor ( { s32 , s64 } ) ; LoadStoreBuilder . legalFor ( { { s64 , p0 } } ) ; PhiBuilder . legalFor ( { s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . legalForCartesianProduct ( { s1 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_MERGE_VALUES ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_UNMERGE_VALUES ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( G_FPEXT ) . legalFor ( { { s64 , s32 } } ) ; getActionDefinitionsBuilder ( G_FPTRUNC ) . legalFor ( { { s32 , s64 } } ) ; getActionDefinitionsBuilder ( { G_FPTOSI , G_FPTOUI } ) . legalForCartesianProduct ( { s32 } , { s32 , s64 } ) ; getActionDefinitionsBuilder ( { G_SITOFP , G_UITOFP } ) . legalForCartesianProduct ( { s32 , s64 } , { s32 } ) ; } else { getActionDefinitionsBuilder ( { G_FADD , G_FSUB , G_FMUL , G_FDIV } ) . libcallFor ( { s32 , s64 } ) ; LoadStoreBuilder . maxScalar ( <NUM_LIT> , s32 ) ; for ( auto Ty : { s32 , s64 } ) setAction ( { G_FNEG , Ty } , Lower ) ; getActionDefinitionsBuilder ( G_FCONSTANT ) . customFor ( { s32 , s64 } ) ; getActionDefinitionsBuilder ( G_FCMP ) . customForCartesianProduct ( { s1 } , { s32 , s64 } ) ; if ( AEABI ( ST ) ) setFCmpLibcallsAEABI ( ) ; else setFCmpLibcallsGNU ( ) ;

getActionDefinitionsBuilder ( G_FPEXT ) . libcallFor ( { { s64 , s32 } } ) ;


<s> static void concatenateMemOperands ( MachineInstr * MI , MachineInstr * Op0 , MachineInstr * Op1 ) { assert ( MI -> memoperands_empty ( ) && <STR_LIT> ) ; size_t numMemRefs = ( Op0 -> memoperands_end ( ) - Op0 -> memoperands_begin ( ) ) + ( Op1 -> memoperands_end ( ) - Op1 -> memoperands_begin ( ) ) ; MachineFunction * MF = MI -> getParent ( ) -> getParent ( ) ; MachineSDNode :: mmo_iterator MemBegin = MF -> allocateMemRefsArray ( numMemRefs ) ; MachineSDNode :: mmo_iterator MemEnd = std :: copy ( Op0 -> memoperands_begin ( ) , Op0 -> memoperands_end ( ) , MemBegin ) ;

MemEnd = std :: copy ( Op1 -> memoperands_begin ( ) , Op1 -> memoperands_end ( ) , MemEnd ) ;


<s> MIB . addReg ( Regs [ <NUM_LIT> ] . first , RegState :: Define ) . addReg ( Regs [ <NUM_LIT> ] . first , RegState :: Define ) ; } else { MIB . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) ; } MIB . addReg ( Base ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; return MIB . getInstr ( ) ;


<s> } else { MIB . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) ; } MIB . addReg ( Base ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ;


<s> BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> && Base != <STR_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; } if ( ! TL -> isLegalAddImmediate ( Offset ) ) return nullptr ; bool KillOldBase = BaseKill && ( ! isi32Store ( Opcode ) || ! ContainsReg ( Regs , Base ) ) ; if ( isThumb1 ) { if ( Base != NewBase && ( BaseOpc == <STR_LIT> || BaseOpc == <STR_LIT> ) ) { if ( is<ISA_LIT>LowRegister ( NewBase ) && is<ISA_LIT>LowRegister ( Base ) && ! STI -> hasV6Ops ( ) ) { if ( Pred != <STR_LIT> ) return nullptr ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) ; } else BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Pred ) . addReg ( PredReg ) ; Base = NewBase ; KillOldBase = true ; } if ( BaseOpc == <STR_LIT> ) { assert ( Offset % <NUM_LIT> == <NUM_LIT> && <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Offset / <NUM_LIT> ) . addImm ( Pred ) . addReg ( PredReg ) ; } else AddDefaultT1CC ( BuildMI ( MBB , InsertBefore , DL , TII -> get ( BaseOpc ) , NewBase ) , true ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { BuildMI ( MBB , InsertBefore , DL , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; } Base = NewBase ;


<s> if ( MO . isDef ( ) && MO . getReg ( ) == <STR_LIT> && ! MO . isDead ( ) ) return true ; } return false ;


<s> unsigned SIndex = <NUM_LIT> ; unsigned EIndex = MemOps . size ( ) ; do { const MachineInstr * MI = MemOps [ SIndex ] . MI ; int Offset = MemOps [ SIndex ] . Offset ; const MachineOperand & PMO = getLoadStoreRegOp ( * MI ) ; unsigned PReg = PMO . getReg ( ) ; unsigned PRegNum = PMO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( PReg ) ; unsigned Latest = SIndex ; unsigned Earliest = SIndex ; unsigned Count = <NUM_LIT> ; bool CanMergeToLSDouble = STI -> isThumb2 ( ) && isNotVFP && isValidLSDoubleOffset ( Offset ) ; if ( STI -> isCortexM3 ( ) && isi32Load ( Opcode ) && PReg == getLoadStoreBaseOp ( * MI ) . getReg ( ) ) CanMergeToLSDouble = false ; bool CanMergeToLSMulti = true ; if ( STI -> isSwift ( ) && ! isNotVFP && ( PRegNum % <NUM_LIT> ) == <NUM_LIT> ) CanMergeToLSMulti = false ; if ( PReg == <STR_LIT> || PReg == <STR_LIT> ) CanMergeToLSMulti = CanMergeToLSDouble = false ; for ( unsigned I = SIndex + <NUM_LIT> ; I < EIndex ; ++ I , ++ Count ) { int NewOffset = MemOps [ I ] . Offset ; if ( NewOffset != Offset + ( int ) Size ) break ; const MachineOperand & MO = getLoadStoreRegOp ( * MemOps [ I ] . MI ) ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <STR_LIT> || Reg == <STR_LIT> ) break ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; bool PartOfLSMulti = CanMergeToLSMulti ; if ( PartOfLSMulti ) { if ( RegNum <= PRegNum ) PartOfLSMulti = false ; else if ( ! isNotVFP && RegNum != PRegNum + <NUM_LIT> ) PartOfLSMulti = false ; } bool PartOfLSDouble = CanMergeToLSDouble && Count <= <NUM_LIT> ; if ( ! PartOfLSMulti && ! PartOfLSDouble ) break ; CanMergeToLSMulti &= PartOfLSMulti ; CanMergeToLSDouble &= PartOfLSDouble ; unsigned Position = MemOps [ I ] . Position ; if ( Position < MemOps [ Latest ] . Position ) Latest = I ; else if ( Position > MemOps [ Earliest ] . Position ) Earliest = I ; Offset += Size ; PRegNum = RegNum ; }

MergeCandidate * Candidate = new ( Allocator . Allocate ( ) ) MergeCandidate ;


<s> unsigned Opcode = FirstMI -> getOpcode ( ) ; bool isNotVFP = isi32Load ( Opcode ) || isi32Store ( Opcode ) ; unsigned Size = getLSMultipleTransferSize ( FirstMI ) ; unsigned SIndex = <NUM_LIT> ; unsigned EIndex = MemOps . size ( ) ; do { const MachineInstr * MI = MemOps [ SIndex ] . MI ; int Offset = MemOps [ SIndex ] . Offset ; const MachineOperand & PMO = getLoadStoreRegOp ( * MI ) ; unsigned PReg = PMO . getReg ( ) ; unsigned PRegNum = PMO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( PReg ) ; unsigned Latest = SIndex ; unsigned Earliest = SIndex ; unsigned Count = <NUM_LIT> ; bool CanMergeToLSDouble = STI -> isThumb2 ( ) && isNotVFP && isValidLSDoubleOffset ( Offset ) ; if ( STI -> isCortexM3 ( ) && isi32Load ( Opcode ) && PReg == getLoadStoreBaseOp ( * MI ) . getReg ( ) ) CanMergeToLSDouble = false ; bool CanMergeToLSMulti = true ; if ( STI -> isSwift ( ) && ! isNotVFP && ( PRegNum % <NUM_LIT> ) == <NUM_LIT> ) CanMergeToLSMulti = false ; if ( PReg == <STR_LIT> || PReg == <STR_LIT> ) CanMergeToLSMulti = CanMergeToLSDouble = false ; for ( unsigned I = SIndex + <NUM_LIT> ; I < EIndex ; ++ I , ++ Count ) { int NewOffset = MemOps [ I ] . Offset ; if ( NewOffset != Offset + ( int ) Size ) break ; const MachineOperand & MO = getLoadStoreRegOp ( * MemOps [ I ] . MI ) ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <STR_LIT> || Reg == <STR_LIT> ) break ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; bool PartOfLSMulti = CanMergeToLSMulti ; if ( PartOfLSMulti ) { if ( RegNum <= PRegNum ) PartOfLSMulti = false ; else if ( ! isNotVFP && RegNum != PRegNum + <NUM_LIT> ) PartOfLSMulti = false ; } bool PartOfLSDouble = CanMergeToLSDouble && Count <= <NUM_LIT> ; if ( ! PartOfLSMulti && ! PartOfLSDouble ) break ; CanMergeToLSMulti &= PartOfLSMulti ; CanMergeToLSDouble &= PartOfLSDouble ;

unsigned Position = MemOps [ I ] . Position ;


<s> static int getMemoryOpOffset ( const MachineInstr * MI ) { unsigned Opcode = MI -> getOpcode ( ) ; bool isAM3 = Opcode == <STR_LIT> || Opcode == <STR_LIT> ; unsigned NumOperands = MI -> getDesc ( ) . getNumOperands ( ) ; unsigned OffField = MI -> getOperand ( NumOperands - <NUM_LIT> ) . getImm ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) return OffField ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) return OffField * <NUM_LIT> ; int Offset = isAM3 ? <STR_LIT> ( OffField ) : <STR_LIT> ( OffField ) * <NUM_LIT> ;

<STR_LIT> Op = isAM3 ? <STR_LIT> ( OffField ) : <STR_LIT> ( OffField ) ;


<s> MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg , getDefRegState ( true ) | getDeadRegState ( RegDeadKill ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) | getUndefRegState ( BaseUndef ) ) ;

MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ;


<s> MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg , getDefRegState ( true ) | getDeadRegState ( RegDeadKill ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) | getUndefRegState ( BaseUndef ) ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg , getKillRegState ( RegDeadKill ) | getUndefRegState ( RegUndef ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) | getUndefRegState ( BaseUndef ) ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; }


<s> MBBI = std :: prev ( I ) ; if ( FixInvalidRegPairOp ( MBB , MBBI ) ) continue ; ++ Position ; if ( isMemoryOp ( * MBBI ) ) { unsigned Opcode = MBBI -> getOpcode ( ) ; const MachineOperand & MO = MBBI -> getOperand ( <NUM_LIT> ) ; unsigned Reg = MO . getReg ( ) ; unsigned Base = getLoadStoreBaseOp ( * MBBI ) . getReg ( ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MBBI , PredReg ) ; int Offset = getMemoryOpOffset ( MBBI ) ; if ( CurrBase == <NUM_LIT> ) { CurrBase = Base ; CurrOpc = Opcode ; CurrPred = Pred ; MemOps . push_back ( MemOpQueueEntry ( MBBI , Offset , Position ) ) ; continue ; } if ( CurrOpc == Opcode && CurrBase == Base && CurrPred == Pred ) { bool Overlap = false ; if ( isLoadSingle ( Opcode ) ) { Overlap = ( Base == Reg ) ; if ( ! Overlap ) { for ( const MemOpQueueEntry & E : MemOps ) { if ( TRI -> regsOverlap ( Reg , E . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Overlap = true ; break ; } } } } if ( ! Overlap ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( MBBI , Offset , Position ) ) ; continue ; } else { MemOpQueue :: iterator MI , ME ; for ( MI = MemOps . begin ( ) , ME = MemOps . end ( ) ; MI != ME ; ++ MI ) { if ( Offset < MI -> Offset ) { break ; } if ( Offset == MI -> Offset ) { MI = ME ; break ; } } if ( MI != MemOps . end ( ) ) { MemOps . insert ( MI , MemOpQueueEntry ( MBBI , Offset , Position ) ) ; continue ; } } } } MBBI = I ; -- Position ; } else if ( MBBI -> isDebugValue ( ) ) { continue ; } else if ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) { MergeBaseCandidates . push_back ( MBBI ) ; } if ( MemOps . size ( ) > <NUM_LIT> ) { FormCandidates ( MemOps ) ; CurrBase = <NUM_LIT> ; CurrOpc = ~ <NUM_LIT> ; CurrPred = <STR_LIT> ; MemOps . clear ( ) ; } } if ( MemOps . size ( ) > <NUM_LIT> ) FormCandidates ( MemOps ) ;

auto LessThan = [ ] ( const MergeCandidate * M0 , const MergeCandidate * M1 ) {


<s> MemOpQueueEntry ( MachineInstr * MI , int Offset , unsigned Position ) : MI ( MI ) , Offset ( Offset ) , Position ( Position ) {


<s> MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) ) ; if ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) { MIB . addOperand ( Reg0Op ) . addOperand ( Reg1Op ) . addReg ( BaseOp . getReg ( ) , RegState :: Define ) ; } else { assert ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) ; MIB . addReg ( BaseOp . getReg ( ) , RegState :: Define ) . addOperand ( Reg0Op ) . addOperand ( Reg1Op ) ; } MIB . addReg ( BaseOp . getReg ( ) , RegState :: Kill ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; assert ( TII -> get ( Opcode ) . getNumOperands ( ) == <NUM_LIT> && TII -> get ( NewOpc ) . getNumOperands ( ) == <NUM_LIT> && <STR_LIT> ) ;

for ( const MachineOperand & MO : MI . implicit_operands ( ) ) MIB . addOperand ( MO ) ;


<s> if ( isThumb1 ) return false ; const MachineOperand & BaseOP = MI -> getOperand ( <NUM_LIT> ) ; unsigned Base = BaseOP . getReg ( ) ; bool BaseKill = BaseOP . isKill ( ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; unsigned Opcode = MI -> getOpcode ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) == Base ) return false ; int Bytes = getLSMultipleTransferSize ( MI ) ; MachineBasicBlock & MBB = * MI -> getParent ( ) ; MachineBasicBlock :: iterator MBBI ( MI ) ; int Offset ; MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; <STR_LIT> Mode = getLoadStoreMultipleSubMode ( Opcode ) ; if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset ) ; if ( ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != Bytes ) && ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != - Bytes ) ) return false ; } MBB . erase ( MergeInstr ) ; unsigned NewOpc = getUpdatingLSMultipleOpcode ( Opcode , Mode ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) ) . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) ; for ( unsigned OpNum = <NUM_LIT> , e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . addOperand ( MI -> getOperand ( OpNum ) ) ; MIB -> setMemRefs ( MI -> memoperands_begin ( ) , MI -> memoperands_end ( ) ) ; MBB . erase ( MBBI ) ; return true ;


<s> if ( Cand . CanMergeToLSDouble ) Merged = CreateLoadStoreDouble ( MBB , InsertBefore , Offset , Base , BaseKill , Opcode , Pred , PredReg , DL , Regs ) ; if ( ! Merged && Cand . CanMergeToLSMulti ) Merged = CreateLoadStoreMulti ( MBB , InsertBefore , Offset , Base , BaseKill , Opcode , Pred , PredReg , DL , Regs ) ; if ( ! Merged ) return nullptr ; iterator EarliestI ( Cand . Instrs [ Cand . EarliestMIIdx ] ) ; bool EarliestAtBegin = false ; if ( EarliestI == MBB . begin ( ) ) { EarliestAtBegin = true ; } else { EarliestI = std :: prev ( EarliestI ) ; } for ( MachineInstr * MI : Cand . Instrs ) MBB . erase ( MI ) ; if ( EarliestAtBegin ) EarliestI = MBB . begin ( ) ; else EarliestI = std :: next ( EarliestI ) ; auto FixupRange = make_range ( EarliestI , iterator ( Merged ) ) ; if ( isLoadSingle ( Opcode ) ) { for ( MachineInstr & MI : FixupRange ) { for ( unsigned & ImpDefReg : ImpDefs ) { for ( MachineOperand & MO : MI . implicit_operands ( ) ) { if ( ! MO . isReg ( ) || MO . getReg ( ) != ImpDefReg ) continue ;

if ( MO . readsReg ( ) ) MO . setIsUndef ( ) ;


<s> if ( isThumb1 ) return false ; if ( MBB . empty ( ) ) return false ; MachineBasicBlock :: iterator MBBI = MBB . getLastNonDebugInstr ( ) ; if ( MBBI != MBB . begin ( ) && ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) ) { MachineBasicBlock :: iterator PrevI = std :: prev ( MBBI ) ; while ( PrevI -> isDebugValue ( ) && PrevI != MBB . begin ( ) ) -- PrevI ; MachineInstr * PrevMI = PrevI ; unsigned Opcode = PrevMI -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { MachineOperand & MO = PrevMI -> getOperand ( PrevMI -> getNumOperands ( ) - <NUM_LIT> ) ; if ( MO . getReg ( ) != <STR_LIT> ) return false ; unsigned NewOpc = ( isThumb2 ? <STR_LIT> : <STR_LIT> ) ; assert ( ( ( isThumb2 && Opcode == <STR_LIT> ) || Opcode == <STR_LIT> ) && <STR_LIT> ) ; PrevMI -> setDesc ( TII -> get ( NewOpc ) ) ; MO . setReg ( <STR_LIT> ) ; PrevMI -> copyImplicitOps ( * MBB . getParent ( ) , & * MBBI ) ;


<s> while ( PrevI -> isDebugValue ( ) && PrevI != MBB . begin ( ) ) -- PrevI ; MachineInstr * PrevMI = PrevI ; unsigned Opcode = PrevMI -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { MachineOperand & MO = PrevMI -> getOperand ( PrevMI -> getNumOperands ( ) - <NUM_LIT> ) ; if ( MO . getReg ( ) != <STR_LIT> ) return false ; unsigned NewOpc = ( isThumb2 ? <STR_LIT> : <STR_LIT> ) ; assert ( ( ( isThumb2 && Opcode == <STR_LIT> ) || Opcode == <STR_LIT> ) && <STR_LIT> ) ; PrevMI -> setDesc ( TII -> get ( NewOpc ) ) ; MO . setReg ( <STR_LIT> ) ; PrevMI -> copyImplicitOps ( * MBB . getParent ( ) , & * MBBI ) ; MBB . erase ( MBBI ) ; return true ; }


<s> void <ISA_LIT>LoadStoreOpt :: moveLiveRegsBefore ( const MachineBasicBlock & MBB , MachineBasicBlock :: const_iterator Before ) { if ( ! LiveRegsValid ) { LiveRegs . init ( TRI ) ; LiveRegs . addLiveOuts ( & MBB , true ) ; LiveRegPos = MBB . end ( ) ; LiveRegsValid = true ; } while ( LiveRegPos != Before ) { -- LiveRegPos ;

LiveRegs . stepBackward ( * LiveRegPos ) ;


<s> SmallVector < unsigned , <NUM_LIT> > StBases ; unsigned Loc = <NUM_LIT> ; MachineBasicBlock :: iterator MBBI = MBB -> begin ( ) ; MachineBasicBlock :: iterator E = MBB -> end ( ) ; while ( MBBI != E ) { for ( ; MBBI != E ; ++ MBBI ) { MachineInstr * MI = MBBI ; if ( MI -> isCall ( ) || MI -> isTerminator ( ) ) { ++ MBBI ; break ; } if ( ! MI -> isDebugValue ( ) ) MI2LocMap [ MI ] = ++ Loc ; if ( ! isMemoryOp ( * MI ) ) continue ; unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) != <STR_LIT> ) continue ; int Opc = MI -> getOpcode ( ) ; bool isLd = isLoadSingle ( Opc ) ; unsigned Base = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; int Offset = getMemoryOpOffset ( MI ) ; bool StopHere = false ; if ( isLd ) { DenseMap < unsigned , SmallVector < MachineInstr * , <NUM_LIT> > > :: iterator BI = Base2LdsMap . find ( Base ) ; if ( BI != Base2LdsMap . end ( ) ) { for ( unsigned i = <NUM_LIT> , e = BI -> second . size ( ) ; i != e ; ++ i ) { if ( Offset == getMemoryOpOffset ( BI -> second [ i ] ) ) { StopHere = true ; break ; } } if ( ! StopHere ) BI -> second . push_back ( MI ) ; } else { Base2LdsMap [ Base ] . push_back ( MI ) ; LdBases . push_back ( Base ) ; } } else { DenseMap < unsigned , SmallVector < MachineInstr * , <NUM_LIT> > > :: iterator BI = Base2StsMap . find ( Base ) ; if ( BI != Base2StsMap . end ( ) ) { for ( unsigned i = <NUM_LIT> , e = BI -> second . size ( ) ; i != e ; ++ i ) { if ( Offset == getMemoryOpOffset ( BI -> second [ i ] ) ) { StopHere = true ;


<s> if ( ! StopHere ) BI -> second . push_back ( MI ) ; } else { Base2StsMap [ Base ] . push_back ( MI ) ; StBases . push_back ( Base ) ; } } if ( StopHere ) { -- Loc ; break ; } } for ( unsigned i = <NUM_LIT> , e = LdBases . size ( ) ; i != e ; ++ i ) { unsigned Base = LdBases [ i ] ; SmallVectorImpl < MachineInstr * > & Lds = Base2LdsMap [ Base ] ; if ( Lds . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Lds , Base , true , MI2LocMap ) ; } for ( unsigned i = <NUM_LIT> , e = StBases . size ( ) ; i != e ; ++ i ) { unsigned Base = StBases [ i ] ; SmallVectorImpl < MachineInstr * > & Sts = Base2StsMap [ Base ] ; if ( Sts . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Sts , Base , false , MI2LocMap ) ; } if ( MBBI != E ) { Base2LdsMap . clear ( ) ; Base2StsMap . clear ( ) ;


<s> MachineInstr * FirstOp = nullptr ; MachineInstr * LastOp = nullptr ; int LastOffset = <NUM_LIT> ; unsigned LastOpcode = <NUM_LIT> ; unsigned LastBytes = <NUM_LIT> ; unsigned NumMove = <NUM_LIT> ; for ( int i = Ops . size ( ) - <NUM_LIT> ; i >= <NUM_LIT> ; -- i ) { MachineInstr * Op = Ops [ i ] ; unsigned Loc = MI2LocMap [ Op ] ; if ( Loc <= FirstLoc ) { FirstLoc = Loc ; FirstOp = Op ; } if ( Loc >= LastLoc ) { LastLoc = Loc ; LastOp = Op ; } unsigned LSMOpcode = getLoadStoreMultipleOpcode ( Op -> getOpcode ( ) , <STR_LIT> ) ; if ( LastOpcode && LSMOpcode != LastOpcode ) break ; int Offset = getMemoryOpOffset ( Op ) ; unsigned Bytes = getLSMultipleTransferSize ( Op ) ; if ( LastBytes ) { if ( Bytes != LastBytes || Offset != ( LastOffset + ( int ) Bytes ) ) break ; } LastOffset = Offset ; LastBytes = Bytes ; LastOpcode = LSMOpcode ; if ( ++ NumMove == <NUM_LIT> ) break ; } if ( NumMove <= <NUM_LIT> ) Ops . pop_back ( ) ; else { SmallPtrSet < MachineInstr * , <NUM_LIT> > MemOps ; SmallSet < unsigned , <NUM_LIT> > MemRegs ; for ( int i = NumMove - <NUM_LIT> ; i >= <NUM_LIT> ; -- i ) { MemOps . insert ( Ops [ i ] ) ; MemRegs . insert ( Ops [ i ] -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } bool DoMove = ( LastLoc - FirstLoc ) <= NumMove * <NUM_LIT> ; if ( DoMove ) DoMove = IsSafeAndProfitableToMove ( isLd , Base , FirstOp , LastOp , MemOps , MemRegs , TRI ) ; if ( ! DoMove ) { for ( unsigned i = <NUM_LIT> ; i != NumMove ; ++ i ) Ops . pop_back ( ) ; } else { MachineBasicBlock :: iterator InsertPos = isLd ? FirstOp : LastOp ; while ( InsertPos != MBB -> end ( ) && ( MemOps . count ( InsertPos ) || InsertPos -> isDebugValue ( ) ) ) ++ InsertPos ; MachineInstr * Op0 = Ops . back ( ) ; MachineInstr * Op1 = Ops [ Ops . size ( ) - <NUM_LIT> ] ; unsigned FirstReg = <NUM_LIT> , SecondReg = <NUM_LIT> ; unsigned BaseReg = <NUM_LIT> , PredReg = <NUM_LIT> ; <STR_LIT> Pred = <STR_LIT> ; bool isT2 = false ;


<s> TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const <ISA_LIT>Subtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ;


<s> for ( auto Use : Prev -> uses ( ) ) if ( Use . isKill ( ) ) { AddDefaultPred ( BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( Use . getReg ( ) , RegState :: Kill ) ) . copyImplicitOps ( & * MBBI ) ;


<s> isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ;

Modified |= LoadStoreMultipleOpti ( MBB ) ;


<s> for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( STI -> hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; if ( isThumb1 ) Modified |= CombineMovBx ( MBB ) ; }


<s> NewOpc = <STR_LIT> ; } else if ( Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; } else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else { return false ; } if ( ! Op0 -> hasOneMemOperand ( ) || ( * Op0 -> memoperands_begin ( ) ) -> isVolatile ( ) ) return false ; unsigned Align = ( * Op0 -> memoperands_begin ( ) ) -> getAlignment ( ) ; const Function * Func = MF -> getFunction ( ) ; unsigned ReqAlign = STI -> hasV6Ops ( ) ? TD -> getABITypeAlignment ( Type :: getInt64Ty ( Func -> getContext ( ) ) ) : <NUM_LIT> ; if ( Align < ReqAlign ) return false ; int OffImm = getMemoryOpOffset ( * Op0 ) ; if ( isT2 ) { int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm <= - Limit ) || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ;


<s> isT2 = true ; } else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else { return false ; } if ( ! Op0 -> hasOneMemOperand ( ) || ( * Op0 -> memoperands_begin ( ) ) -> isVolatile ( ) ) return false ; unsigned Align = ( * Op0 -> memoperands_begin ( ) ) -> getAlignment ( ) ; const Function * Func = MF -> getFunction ( ) ; unsigned ReqAlign = STI -> hasV6Ops ( ) ? TD -> getABITypeAlignment ( Type :: getInt64Ty ( Func -> getContext ( ) ) ) : <NUM_LIT> ; if ( Align < ReqAlign ) return false ; int OffImm = getMemoryOpOffset ( * Op0 ) ; if ( isT2 ) { int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm <= - Limit ) || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; Offset = OffImm ; } else { <STR_LIT> AddSub = <STR_LIT> ; if ( OffImm < <NUM_LIT> ) { AddSub = <STR_LIT> ; OffImm = - OffImm ; } int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; Offset = <STR_LIT> ( AddSub , OffImm ) ; } FirstReg = Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; SecondReg = Op1 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( FirstReg == SecondReg ) return false ; BaseReg = Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Pred = getInstrPredicate ( * Op0 , PredReg ) ; dl = Op0 -> getDebugLoc ( ) ; return true ;


<s> MachineBasicBlock :: iterator MBBI = MBB . getFirstTerminator ( ) ; if ( MBBI == MBB . begin ( ) || MBBI == MBB . end ( ) || MBBI -> getOpcode ( ) != <STR_LIT> ) return false ; MachineBasicBlock :: iterator Prev = MBBI ; -- Prev ; if ( Prev -> getOpcode ( ) != <STR_LIT> || ! Prev -> definesRegister ( <STR_LIT> ) ) return false ; for ( auto Use : Prev -> uses ( ) ) if ( Use . isKill ( ) ) { AddDefaultPred ( BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( Use . getReg ( ) , RegState :: Kill ) ) . copyImplicitOps ( * MBBI ) ; MBB . erase ( MBBI ) ; MBB . erase ( Prev ) ;


<s> AddDefaultPred ( BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( Use . getReg ( ) , RegState :: Kill ) ) . copyImplicitOps ( * MBBI ) ; MBB . erase ( MBBI ) ; MBB . erase ( Prev ) ; return true ;


<s> static bool ContainsReg ( const ArrayRef < std :: pair < unsigned , bool >> & Regs , unsigned Reg ) {

for ( const std :: pair < unsigned , bool > & R : Regs ) if ( R . first == Reg ) return true ;


<s> if ( PreAlloc ) return new <ISA_LIT>PreAllocLoadStoreOpt ( ) ;


<s> MachineInstr * <ISA_LIT>LoadStoreOpt :: CreateLoadStoreDouble ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator InsertBefore , int Offset , unsigned Base , bool BaseKill , unsigned Opcode , <STR_LIT> Pred , unsigned PredReg , const DebugLoc & DL , ArrayRef < std :: pair < unsigned , bool >> Regs ) const { bool IsLoad = isi32Load ( Opcode ) ; assert ( ( IsLoad || isi32Store ( Opcode ) ) && <STR_LIT> ) ; unsigned LoadStoreOpcode = IsLoad ? <STR_LIT> : <STR_LIT> ; assert ( Regs . size ( ) == <NUM_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( MBB , InsertBefore , DL , TII -> get ( LoadStoreOpcode ) ) ; if ( IsLoad ) { MIB . addReg ( Regs [ <NUM_LIT> ] . first , RegState :: Define ) . addReg ( Regs [ <NUM_LIT> ] . first , RegState :: Define ) ; } else {

MIB . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) ;


<s> assert ( ( IsLoad || isi32Store ( Opcode ) ) && <STR_LIT> ) ; unsigned LoadStoreOpcode = IsLoad ? <STR_LIT> : <STR_LIT> ; assert ( Regs . size ( ) == <NUM_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( MBB , InsertBefore , DL , TII -> get ( LoadStoreOpcode ) ) ; if ( IsLoad ) { MIB . addReg ( Regs [ <NUM_LIT> ] . first , RegState :: Define ) . addReg ( Regs [ <NUM_LIT> ] . first , RegState :: Define ) ; } else { MIB . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) . addReg ( Regs [ <NUM_LIT> ] . first , getKillRegState ( Regs [ <NUM_LIT> ] . second ) ) ; }

MIB . addReg ( Base ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ;


<s> if ( isThumb1 && isi32Load ( Opcode ) && ContainsReg ( Regs , Base ) ) { assert ( Base != <STR_LIT> && <STR_LIT> ) ; if ( Opcode == <STR_LIT> ) { Writeback = false ; } else if ( Opcode == <STR_LIT> ) { return nullptr ; } } <STR_LIT> Mode = <STR_LIT> ; bool isNotVFP = isi32Load ( Opcode ) || isi32Store ( Opcode ) ; bool haveIBAndDA = isNotVFP && ! isThumb2 && ! isThumb1 ; if ( Offset == <NUM_LIT> && haveIBAndDA ) { Mode = <STR_LIT> ; } else if ( Offset == - <NUM_LIT> * ( int ) NumRegs + <NUM_LIT> && haveIBAndDA ) { Mode = <STR_LIT> ; } else if ( Offset == - <NUM_LIT> * ( int ) NumRegs && isNotVFP && ! isThumb1 ) { Mode = <STR_LIT> ; } else if ( Offset != <NUM_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { if ( ! getLoadStoreMultipleOpcode ( Opcode , Mode ) ) return nullptr ; if ( NumRegs <= <NUM_LIT> ) return nullptr ; if ( ! SafeToClobberCPSR ) return nullptr ; unsigned NewBase ; if ( isi32Load ( Opcode ) ) { NewBase = Regs [ NumRegs - <NUM_LIT> ] . first ; Writeback = false ; } else { moveLiveRegsBefore ( MBB , InsertBefore ) ; if ( ! isLoadSingle ( Opcode ) ) for ( const std :: pair < unsigned , bool > & R : Regs ) LiveRegs . addReg ( R . first ) ; NewBase = findFreeReg ( isThumb1 ? <STR_LIT> : <STR_LIT> ) ; if ( NewBase == <NUM_LIT> ) return nullptr ; } int BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Base == <STR_LIT> ) ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; if ( Offset < <NUM_LIT> ) { Offset = - Offset ; BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> && Base != <STR_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; } if ( ! TL -> isLegalAddImmediate ( Offset ) ) return nullptr ; bool KillOldBase = BaseKill && ( ! isi32Store ( Opcode ) || ! ContainsReg ( Regs , Base ) ) ; if ( isThumb1 ) { if ( Base != NewBase && ( BaseOpc == <STR_LIT> || BaseOpc == <STR_LIT> ) ) { if ( is<ISA_LIT>LowRegister ( NewBase ) && is<ISA_LIT>LowRegister ( Base ) && ! STI -> hasV6Ops ( ) ) { if ( Pred != <STR_LIT> ) return nullptr ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) ; } else BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Pred ) . addReg ( PredReg ) ; Base = NewBase ; KillOldBase = true ; }


<s> if ( MO . isDef ( ) && MO . getReg ( ) == <STR_LIT> && ! MO . isDead ( ) ) return true ; }


<s> } for ( unsigned Reg : RegClassInfo . getOrder ( & RegClass ) ) if ( ! LiveRegs . contains ( Reg ) ) return Reg ; return <NUM_LIT> ;


<s> Offset = <NUM_LIT> ; MachineBasicBlock & MBB = * MBBI -> getParent ( ) ; MachineBasicBlock :: iterator BeginMBBI = MBB . begin ( ) ; MachineBasicBlock :: iterator EndMBBI = MBB . end ( ) ; if ( MBBI == BeginMBBI ) return EndMBBI ;

MachineBasicBlock :: iterator PrevMBBI = std :: prev ( MBBI ) ;


<s> MachineBasicBlock :: iterator PrevMBBI = std :: prev ( MBBI ) ; while ( PrevMBBI -> isDebugValue ( ) && PrevMBBI != BeginMBBI ) -- PrevMBBI ; Offset = isIncrementOrDecrement ( * PrevMBBI , Reg , Pred , PredReg ) ; return Offset == <NUM_LIT> ? EndMBBI : PrevMBBI ;


<s> bool OddDeadKill = isLd ? MI -> getOperand ( <NUM_LIT> ) . isDead ( ) : MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; bool OddUndef = MI -> getOperand ( <NUM_LIT> ) . isUndef ( ) ; bool BaseKill = BaseOp . isKill ( ) ; bool BaseUndef = BaseOp . isUndef ( ) ; bool OffKill = isT2 ? false : MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; bool OffUndef = isT2 ? false : MI -> getOperand ( <NUM_LIT> ) . isUndef ( ) ; int OffImm = getMemoryOpOffset ( * MI ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; if ( OddRegNum > EvenRegNum && OffImm == <NUM_LIT> ) { unsigned NewOpc = ( isLd ) ? ( isT2 ? <STR_LIT> : <STR_LIT> ) : ( isT2 ? <STR_LIT> : <STR_LIT> ) ; if ( isLd ) { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( EvenReg , getDefRegState ( isLd ) | getDeadRegState ( EvenDeadKill ) ) . addReg ( OddReg , getDefRegState ( isLd ) | getDeadRegState ( OddDeadKill ) ) ; ++ NumLDRD2LDM ; } else { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( EvenReg , getKillRegState ( EvenDeadKill ) | getUndefRegState ( EvenUndef ) ) . addReg ( OddReg , getKillRegState ( OddDeadKill ) | getUndefRegState ( OddUndef ) ) ; ++ NumSTRD2STM ; } } else { unsigned NewOpc = ( isLd ) ? ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) : ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) ; unsigned NewOpc2 = ( isLd ) ? ( isT2 ? ( OffImm + <NUM_LIT> < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) : ( isT2 ? ( OffImm + <NUM_LIT> < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( isLd && ( BaseKill || OffKill ) && ( TRI -> regsOverlap ( EvenReg , BaseReg ) ) ) {

assert ( ! TRI -> regsOverlap ( OddReg , BaseReg ) ) ;


<s> unsigned Size = getLSMultipleTransferSize ( FirstMI ) ; unsigned SIndex = <NUM_LIT> ; unsigned EIndex = MemOps . size ( ) ; do { const MachineInstr * MI = MemOps [ SIndex ] . MI ; int Offset = MemOps [ SIndex ] . Offset ; const MachineOperand & PMO = getLoadStoreRegOp ( * MI ) ; unsigned PReg = PMO . getReg ( ) ; unsigned PRegNum = PMO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( PReg ) ; unsigned Latest = SIndex ; unsigned Earliest = SIndex ; unsigned Count = <NUM_LIT> ; bool CanMergeToLSDouble = STI -> isThumb2 ( ) && isNotVFP && isValidLSDoubleOffset ( Offset ) ; if ( STI -> isCortexM3 ( ) && isi32Load ( Opcode ) && PReg == getLoadStoreBaseOp ( * MI ) . getReg ( ) ) CanMergeToLSDouble = false ; bool CanMergeToLSMulti = true ; if ( STI -> hasSlowOddRegister ( ) && ! isNotVFP && ( PRegNum % <NUM_LIT> ) == <NUM_LIT> ) CanMergeToLSMulti = false ; if ( PReg == <STR_LIT> || PReg == <STR_LIT> ) CanMergeToLSMulti = CanMergeToLSDouble = false ; if ( AssumeMisalignedLoadStores && ! mayCombineMisaligned ( * STI , * MI ) ) CanMergeToLSMulti = CanMergeToLSDouble = false ;

for ( unsigned I = SIndex + <NUM_LIT> ; I < EIndex ; ++ I , ++ Count ) {


<s> default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> :


<s> switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> :


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return ( MI -> getNumOperands ( ) - MI -> getDesc ( ) . getNumOperands ( ) + <NUM_LIT> ) * <NUM_LIT> ; case <STR_LIT> :


<s> unsigned NumOperands = MI . getDesc ( ) . getNumOperands ( ) ; unsigned OffField = MI . getOperand ( NumOperands - <NUM_LIT> ) . getImm ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) return OffField ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) return OffField * <NUM_LIT> ; int Offset = isAM3 ? <STR_LIT> ( OffField ) : <STR_LIT> ( OffField ) * <NUM_LIT> ; <STR_LIT> Op = isAM3 ? <STR_LIT> ( OffField ) : <STR_LIT> ( OffField ) ; if ( Op == <STR_LIT> ) return - Offset ; return Offset ;


<s> return <ISA_LIT>_PREALLOC_LOAD_STORE_OPT_NAME ;


<s> const char * getPassName ( ) const override {


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ;


<s> static void InsertLDR_STR ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , int Offset , bool isDef , const DebugLoc & DL , unsigned NewOpc , unsigned Reg , bool RegDeadKill , bool RegUndef , unsigned BaseReg , bool BaseKill , bool BaseUndef , bool OffKill , bool OffUndef , <STR_LIT> Pred , unsigned PredReg , const TargetInstrInfo * TII , bool isT2 ) {


<s> MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg , getKillRegState ( RegDeadKill ) | getUndefRegState ( RegUndef ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) | getUndefRegState ( BaseUndef ) ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ;


<s> return Opc == <STR_LIT> || isT1i32Load ( Opc ) || isT2i32Load ( Opc ) ;


<s> static bool isi32Store ( unsigned Opc ) {

return Opc == <STR_LIT> || isT1i32Store ( Opc ) || isT2i32Store ( Opc ) ;


<s> } unsigned MIPredReg ; if ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) != Reg || MI . getOperand ( <NUM_LIT> ) . getReg ( ) != Reg || getInstrPredicate ( MI , MIPredReg ) != Pred || MIPredReg != PredReg ) return <NUM_LIT> ; if ( CheckCPSRDef && definesCPSR ( MI ) ) return <NUM_LIT> ;

return MI . getOperand ( <NUM_LIT> ) . getImm ( ) * Scale ;


<s> static bool isLoadSingle ( unsigned Opc ) { return isi32Load ( Opc ) || Opc == <STR_LIT> || Opc == <STR_LIT> ;


<s> return isi32Load ( Opc ) || Opc == <STR_LIT> || Opc == <STR_LIT> ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : break ; default : return false ; } if ( ! MI . getOperand ( <NUM_LIT> ) . isReg ( ) ) return false ; if ( ! MI . hasOneMemOperand ( ) ) return false ; const MachineMemOperand & MMO = * * MI . memoperands_begin ( ) ; if ( MMO . isVolatile ( ) ) return false ; if ( MMO . getAlignment ( ) < <NUM_LIT> ) return false ; if ( MI . getOperand ( <NUM_LIT> ) . isReg ( ) && MI . getOperand ( <NUM_LIT> ) . isUndef ( ) ) return false ; if ( MI . getOperand ( <NUM_LIT> ) . isUndef ( ) ) return false ; return true ;


<s> static bool isT1i32Load ( unsigned Opc ) { return Opc == <STR_LIT> || Opc == <STR_LIT> ;


<s> static bool isT1i32Store ( unsigned Opc ) {

return Opc == <STR_LIT> || Opc == <STR_LIT> ;


<s> static bool isT2i32Store ( unsigned Opc ) { return Opc == <STR_LIT> || Opc == <STR_LIT> ;


<s> unsigned Value = abs ( Offset ) ; return ( Value % <NUM_LIT> ) == <NUM_LIT> && Value < <NUM_LIT> ;


<s> if ( TRI -> regsOverlap ( Reg , E . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Overlap = true ; break ; } } } } if ( ! Overlap ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } else { MemOpQueue :: iterator MI , ME ; for ( MI = MemOps . begin ( ) , ME = MemOps . end ( ) ; MI != ME ; ++ MI ) { if ( Offset < MI -> Offset ) { break ; } if ( Offset == MI -> Offset ) { MI = ME ; break ; } } if ( MI != MemOps . end ( ) ) { MemOps . insert ( MI , MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } } } } MBBI = I ; -- Position ; } else if ( MBBI -> isDebugValue ( ) ) { continue ; } else if ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) { MergeBaseCandidates . push_back ( & * MBBI ) ; } if ( MemOps . size ( ) > <NUM_LIT> ) { FormCandidates ( MemOps ) ; CurrBase = <NUM_LIT> ; CurrOpc = ~ <NUM_LIT> ; CurrPred = <STR_LIT> ; MemOps . clear ( ) ; } } if ( MemOps . size ( ) > <NUM_LIT> ) FormCandidates ( MemOps ) ; auto LessThan = [ ] ( const MergeCandidate * M0 , const MergeCandidate * M1 ) { return M0 -> InsertPos < M1 -> InsertPos ; } ; std :: sort ( Candidates . begin ( ) , Candidates . end ( ) , LessThan ) ; bool Changed = false ;

for ( const MergeCandidate * Candidate : Candidates ) {


<s> unsigned Opcode = MI . getOpcode ( ) ;

if ( ! isi32Load ( Opcode ) && ! isi32Store ( Opcode ) ) return true ;


<s> static bool mayCombineMisaligned ( const TargetSubtargetInfo & STI , const MachineInstr & MI ) { unsigned Opcode = MI . getOpcode ( ) ;


<s> MemOpQueueEntry ( MachineInstr & MI , int Offset , unsigned Position ) : MI ( & MI ) , Offset ( Offset ) , Position ( Position ) {