diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst index 96f3247780b3b..84ff1cea757e0 100644 --- a/llvm/docs/CommandGuide/llvm-objcopy.rst +++ b/llvm/docs/CommandGuide/llvm-objcopy.rst @@ -179,6 +179,10 @@ multiple file formats. specified ```` values. Can be specified multiple times to update multiple sections. +.. option:: --verbose + + List all object files modified. + Supported flag names are `alloc`, `load`, `noload`, `readonly`, `exclude`, `debug`, `code`, `data`, `rom`, `share`, `contents`, `merge`, `strings`, and `large`. Not all flags are meaningful for all object file formats or target diff --git a/llvm/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h index aea9cd6f9a9c7..83ad4590d9c72 100644 --- a/llvm/include/llvm/ObjCopy/CommonConfig.h +++ b/llvm/include/llvm/ObjCopy/CommonConfig.h @@ -274,6 +274,7 @@ struct CommonConfig { bool StripNonAlloc = false; bool StripSections = false; bool StripUnneeded = false; + bool Verbose = false; bool Weaken = false; bool DecompressDebugSections = false; diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp index f810bbf639300..6eec21216aca3 100644 --- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp +++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp @@ -547,7 +547,7 @@ static Error replaceAndRemoveSections(const CommonConfig &Config, }; } - if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred)) + if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred, Config.Verbose)) return E; if (Error E = Obj.compressOrDecompressSections(Config)) @@ -783,6 +783,7 @@ static Error verifyNoteSection(StringRef Name, endianness Endianness, // system. The only priority is that keeps/copies overrule removes. static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig, ElfType OutputElfType, Object &Obj) { + Obj.VerboseOutput = Config.Verbose; if (Config.OutputArch) { Obj.Machine = Config.OutputArch->EMachine; Obj.OSABI = Config.OutputArch->OSABI; @@ -791,7 +792,7 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig, if (!Config.SplitDWO.empty() && Config.ExtractDWO) { return Obj.removeSections( ELFConfig.AllowBrokenLinks, - [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); }); + [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); }, Config.Verbose); } // Dump sections before add/remove for compatibility with GNU objcopy. diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp index e5de17e093dfd..fece7a88b2aa5 100644 --- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp +++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp @@ -766,14 +766,20 @@ Error SymbolTableSection::removeSymbols( function_ref ToRemove) { Symbols.erase( std::remove_if(std::begin(Symbols) + 1, std::end(Symbols), - [ToRemove](const SymPtr &Sym) { return ToRemove(*Sym); }), - std::end(Symbols)); + [&](const SymPtr &Sym) { + if (ToRemove(*Sym)) { + if(VerboseOutput) + outs() << "Symbols Removed:" << Sym->Name<< "\n"; + return true; + } + return false; + })); + auto PrevSize = Size; Size = Symbols.size() * EntrySize; if (Size < PrevSize) IndicesChanged = true; assignIndices(); - return Error::success(); } void SymbolTableSection::replaceSectionReferences( @@ -2195,7 +2201,7 @@ Error Object::updateSectionData(SectionBase &S, ArrayRef Data) { } Error Object::removeSections( - bool AllowBrokenLinks, std::function ToRemove) { + bool AllowBrokenLinks, std::function ToRemove, bool VerboseOutput) { auto Iter = std::stable_partition( std::begin(Sections), std::end(Sections), [=](const SecPtr &Sec) { @@ -2230,6 +2236,9 @@ Error Object::removeSections( for (auto &RemoveSec : make_range(Iter, std::end(Sections))) { for (auto &Segment : Segments) Segment->removeSection(RemoveSec.get()); + if (VerboseOutput) { + outs() << "removed section: " << (RemoveSec.get()->Name); + } RemoveSec->onRemove(); RemoveSections.insert(RemoveSec.get()); } @@ -2273,17 +2282,20 @@ Error Object::replaceSections( if (Error E = removeSections( /*AllowBrokenLinks=*/false, - [=](const SectionBase &Sec) { return FromTo.count(&Sec) > 0; })) + [=](const SectionBase &Sec) { return FromTo.count(&Sec) > 0; }, false)) return E; llvm::sort(Sections, SectionIndexLess); return Error::success(); } Error Object::removeSymbols(function_ref ToRemove) { - if (SymbolTable) - for (const SecPtr &Sec : Sections) + if (SymbolTable){ + for (const SecPtr &Sec : Sections){ if (Error E = Sec->removeSymbols(ToRemove)) return E; + outs() << "removed symbols:" << Sec->Name; + } + } return Error::success(); } @@ -2570,7 +2582,7 @@ static Error removeUnneededSections(Object &Obj) { : Obj.SymbolTable->getStrTab(); return Obj.removeSections(false, [&](const SectionBase &Sec) { return &Sec == Obj.SymbolTable || &Sec == StrTab; - }); + }, false); } template Error ELFWriter::finalize() { @@ -2624,7 +2636,7 @@ template Error ELFWriter::finalize() { if (Error E = Obj.removeSections(false /*AllowBrokenLinks*/, [this](const SectionBase &Sec) { return &Sec == Obj.SectionIndexTable; - })) + }, false)) return E; } } diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.h b/llvm/lib/ObjCopy/ELF/ELFObject.h index d8f79a4b1a3cc..bcda100343813 100644 --- a/llvm/lib/ObjCopy/ELF/ELFObject.h +++ b/llvm/lib/ObjCopy/ELF/ELFObject.h @@ -814,6 +814,8 @@ class SymbolTableSection : public SectionBase { void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; } void assignIndices(); +private: + bool VerboseOutput; protected: std::vector> Symbols; StringTableSection *SymbolNames = nullptr; @@ -856,6 +858,7 @@ class SymbolTableSection : public SectionBase { static bool classof(const SectionBase *S) { return S->OriginalType == ELF::SHT_SYMTAB; } + bool getVerboseOutput() { return VerboseOutput; } }; struct Relocation { @@ -1195,6 +1198,7 @@ class Object { uint32_t Flags; bool HadShdrs = true; + bool VerboseOutput; bool MustBeRelocatable = false; StringTableSection *SectionNames = nullptr; SymbolTableSection *SymbolTable = nullptr; @@ -1224,7 +1228,7 @@ class Object { ConstRange segments() const { return make_pointee_range(Segments); } Error removeSections(bool AllowBrokenLinks, - std::function ToRemove); + std::function ToRemove, bool VerboseOutput); Error compressOrDecompressSections(const CommonConfig &Config); Error replaceSections(const DenseMap &FromTo); Error removeSymbols(function_ref ToRemove); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 508aef63a3128..3e245532d1f5a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2871,7 +2871,33 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) { simplifyAndOrWithOpReplaced(Op1, Op0, Constant::getAllOnesValue(Ty), /*SimplifyOnly*/ false, *this)) return BinaryOperator::CreateAnd(Op0, V); - + // I is the 'and' instruction +if (auto *Add = dyn_cast(I.getOperand(0))) { + if (Add->getOpcode() == Instruction::Add) { + Value *LHS = Add->getOperand(0); // should be shl + ConstantInt *AddConst = dyn_cast(Add->getOperand(1)); + ConstantInt *AndConst = dyn_cast(I.getOperand(1)); + if (AddConst && AndConst) { + // check if AddConst is 47 and AndConst is -32 + if (AddConst->equalsInt(47) && AndConst->getSExtValue() == -32) { + // Check if LHS is shl i64 %a, 5 + if (auto *Shl = dyn_cast(LHS)) { + if (Shl->getOpcode() == Instruction::Shl) { + ConstantInt *ShlConst = dyn_cast(Shl->getOperand(1)); + if (ShlConst && ShlConst->equalsInt(5)) { + // You've matched the pattern! + // Replace with: shl i64 (add i64 %a, 1), 5 + IRBuilder<> Builder(&I); + Value *NewAdd = Builder.CreateAdd(Shl->getOperand(0), ConstantInt::get(I.getType(), 1)); + Value *NewShl = Builder.CreateShl(NewAdd, ShlConst); + I.replaceAllUsesWith(NewShl); + } + } + } + } + } + } +} return nullptr; } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index c7023eb79b04e..c488f0c16f2e1 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -255,33 +255,6 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) { } } - // mul (shr exact X, N), (2^N + 1) -> add (X, shr exact (X, N)) - { - Value *NewOp; - const APInt *ShiftC; - const APInt *MulAP; - if (BitWidth > 2 && - match(&I, m_Mul(m_Exact(m_Shr(m_Value(NewOp), m_APInt(ShiftC))), - m_APInt(MulAP))) && - (*MulAP - 1).isPowerOf2() && *ShiftC == MulAP->logBase2()) { - Value *BinOp = Op0; - BinaryOperator *OpBO = cast(Op0); - - // mul nuw (ashr exact X, N) -> add nuw (X, lshr exact (X, N)) - if (HasNUW && OpBO->getOpcode() == Instruction::AShr && OpBO->hasOneUse()) - BinOp = Builder.CreateLShr(NewOp, ConstantInt::get(Ty, *ShiftC), "", - /*isExact=*/true); - - auto *NewAdd = BinaryOperator::CreateAdd(NewOp, BinOp); - if (HasNSW && (HasNUW || OpBO->getOpcode() == Instruction::LShr || - ShiftC->getZExtValue() < BitWidth - 1)) - NewAdd->setHasNoSignedWrap(true); - - NewAdd->setHasNoUnsignedWrap(HasNUW); - return NewAdd; - } - } - if (Op0->hasOneUse() && match(Op1, m_NegatedPower2())) { // Interpret X * (-1<(m_APInt(C1), m_APInt(C2)))) && + match(Op1, m_OneUse(m_URem(m_Value(X), Op0))) && + match(Op2, m_OneUse(m_UDiv(Op1, m_APInt(C2))))) { + + Value *XDivC2 = Builder.CreateUDiv(X, ConstantInt::get(X->getType(), *C2)); + Value *Result = Builder.CreateURem(XDivC2, ConstantInt::get(X->getType(), *C1)); + return replaceInstUsesWith(I, Result); +} + return nullptr; } @@ -2071,7 +2055,7 @@ convertFSqrtDivIntoFMul(CallInst *CI, Instruction *X, // instructions in R2 and get the most common fpmath metadata and fast-math // flags on it. auto *FSqrt = cast(CI->clone()); - FSqrt->insertBefore(CI->getIterator()); + FSqrt->insertBefore(CI); auto *R2FPMathMDNode = (*R2.begin())->getMetadata(LLVMContext::MD_fpmath); FastMathFlags R2FMF = (*R2.begin())->getFastMathFlags(); // Common FMF for (Instruction *I : R2) { diff --git a/llvm/tools/llvm-objcopy/CommonOpts.td b/llvm/tools/llvm-objcopy/CommonOpts.td index c247c93f6e0f2..5b15191f54605 100644 --- a/llvm/tools/llvm-objcopy/CommonOpts.td +++ b/llvm/tools/llvm-objcopy/CommonOpts.td @@ -117,6 +117,8 @@ def regex def version : Flag<["--"], "version">, HelpText<"Print the version and exit.">; +def verbose : Flag<["--"], "verbose">, + HelpText<"Prints the removed symbols and sections">; def V : Flag<["-"], "V">, Alias, HelpText<"Alias for --version">; diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp index 0d209590655ef..7a0d719756081 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -1103,6 +1103,7 @@ objcopy::parseObjcopyOptions(ArrayRef ArgsArr, OBJCOPY_verify_note_sections, OBJCOPY_no_verify_note_sections, true); Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug); + Config.Verbose = InputArgs.hasArg(OBJCOPY_verbose); ELFConfig.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols); MachOConfig.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined); Config.DecompressDebugSections = @@ -1586,6 +1587,7 @@ objcopy::parseStripOptions(ArrayRef RawArgsArr, Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu); MachOConfig.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols); Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug); + Config.Verbose = InputArgs.hasArg(STRIP_verbose); ELFConfig.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols); MachOConfig.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined);