Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -3416,12 +3416,23 @@ return false; } + /// \brief Defines how to combine AddrModes. + enum CombineType { + // All AddrModes are direct input of Select instruction. + // The new Select instruction will be created to combine the + // values of difference between AddrModes. + CombineBySelect, + // All AddrModes are accessible to origin Addr through only Phi nodes + // or there is only one AddrMode. + CombineByPhi + }; + /// \brief Combine the addressing modes we've collected into a single /// addressing mode. OnlySingleAddrMode means that only single AddrMode /// can be combined. /// \return True iff we successfully combined them or we only had one so /// didn't need to combine them anyway. - bool combineAddrModes(bool OnlySingleAddrMode) { + bool combineAddrModes(bool OnlySingleAddrMode, CombineType Type) { // If we have no AddrModes then they can't be combined. if (AddrModes.size() == 0) return false; @@ -3439,8 +3450,27 @@ if (AllAddrModesTrivial) return false; - // TODO: Combine multiple AddrModes by inserting a select or phi for the + // Combine multiple AddrModes by inserting a select or phi for the // field in which the AddrModes differ. + if (Type == CombineBySelect) { + return combineBySelect(); + } else { + assert(Type == CombineByPhi && "Unexpected combine type!"); + return combineByPhi(); + } + } + + bool combineBySelect() { + assert(AddrModes.size() == 2 && "Too many AddrModes for Select"); + // TODO: Create select basing on AddrModes. + return false; + } + + bool combineByPhi() { + // The first version supports only combine by base register. + if (DifferentField != ExtAddrMode::BaseRegField) + return false; + // TODO: Find/Create Phi node combining the difference between AddrModes. return false; } }; @@ -4595,7 +4625,9 @@ // Try to combine the AddrModes we've collected. If we couldn't collect any, // or we have multiple but either couldn't combine them or combining them // wouldn't do anything useful, bail out now. - if (!AddrModes.combineAddrModes(OnlySingleAddrMode)) { + auto CombineType = CountSelectSeen ? AddressingModeCombiner::CombineBySelect + : AddressingModeCombiner::CombineByPhi; + if (!AddrModes.combineAddrModes(OnlySingleAddrMode, CombineType)) { TPT.rollback(LastKnownGood); return false; }