diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/StackLifetime.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/RuntimeLibcalls.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 117 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCWin64EH.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCWinCOFFStreamer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 17 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp | 93 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp | 5 |
18 files changed, 175 insertions, 133 deletions
diff --git a/llvm/lib/Analysis/StackLifetime.cpp b/llvm/lib/Analysis/StackLifetime.cpp index 34a7a04..b3f9994 100644 --- a/llvm/lib/Analysis/StackLifetime.cpp +++ b/llvm/lib/Analysis/StackLifetime.cpp @@ -63,7 +63,10 @@ bool StackLifetime::isAliveAfter(const AllocaInst *AI, // markers has the same size and points to the alloca start. static const AllocaInst *findMatchingAlloca(const IntrinsicInst &II, const DataLayout &DL) { - const AllocaInst *AI = cast<AllocaInst>(II.getArgOperand(1)); + const AllocaInst *AI = dyn_cast<AllocaInst>(II.getArgOperand(1)); + if (!AI) + return nullptr; + auto AllocaSize = AI->getAllocationSize(DL); if (!AllocaSize) return nullptr; diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index fd38c30..ab6fb30 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2189,8 +2189,8 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, unsigned Op = ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START : TargetOpcode::LIFETIME_END; - const AllocaInst *AI = cast<AllocaInst>(CI.getArgOperand(1)); - if (!AI->isStaticAlloca()) + const AllocaInst *AI = dyn_cast<AllocaInst>(CI.getArgOperand(1)); + if (!AI || !AI->isStaticAlloca()) return true; MIRBuilder.buildInstr(Op).addFrameIndex(getOrCreateFrameIndex(*AI)); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 306e068..ac0440f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -7598,7 +7598,9 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, if (TM.getOptLevel() == CodeGenOptLevel::None) return; - const AllocaInst *LifetimeObject = cast<AllocaInst>(I.getArgOperand(1)); + const AllocaInst *LifetimeObject = dyn_cast<AllocaInst>(I.getArgOperand(1)); + if (!LifetimeObject) + return; // First check that the Alloca is static, otherwise it won't have a // valid frame index. diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index bfe2a3d..b6e2cac 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -73,13 +73,8 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, EABI EABIVersion, StringRef ABIName) { setTargetRuntimeLibcallSets(TT, FloatABI); - if (TT.isX86() || TT.isVE() || TT.isARM() || TT.isThumb()) { - if (ExceptionModel == ExceptionHandling::SjLj) - setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); - } - - if (TT.isOSOpenBSD()) - setLibcallImpl(RTLIB::STACK_SMASH_HANDLER, RTLIB::__stack_smash_handler); + if (ExceptionModel == ExceptionHandling::SjLj) + setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); if (TT.isARM() || TT.isThumb()) { setARMLibcallNames(*this, TT, FloatABI, EABIVersion); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 3ff9895..ca3f148 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -6769,10 +6769,13 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { break; } case Intrinsic::lifetime_start: - case Intrinsic::lifetime_end: - Check(isa<AllocaInst>(Call.getArgOperand(1)), - "llvm.lifetime.start/end can only be used on alloca", &Call); + case Intrinsic::lifetime_end: { + Value *Ptr = Call.getArgOperand(1); + Check(isa<AllocaInst>(Ptr) || isa<PoisonValue>(Ptr), + "llvm.lifetime.start/end can only be used on alloca or poison", + &Call); break; + } }; // Verify that there aren't any unmediated control transfers between funclets. diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 5c8e904..d172ad1 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -945,6 +945,14 @@ bool MCAssembler::relaxFill(MCFillFragment &F) { return true; } +bool MCAssembler::relaxOrg(MCOrgFragment &F) { + uint64_t Size = computeFragmentSize(F); + if (F.getSize() == Size) + return false; + F.setSize(Size); + return true; +} + bool MCAssembler::relaxFragment(MCFragment &F) { switch(F.getKind()) { default: @@ -966,6 +974,8 @@ bool MCAssembler::relaxFragment(MCFragment &F) { return relaxCVDefRange(cast<MCCVDefRangeFragment>(F)); case MCFragment::FT_Fill: return relaxFill(cast<MCFillFragment>(F)); + case MCFragment::FT_Org: + return relaxOrg(static_cast<MCOrgFragment &>(F)); } } diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index bcc77c0..db63f19 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -46,79 +46,23 @@ MCAssembler *MCObjectStreamer::getAssemblerPtr() { return nullptr; } -constexpr size_t FragBlockSize = 16384; -// Ensure the new fragment can at least store a few bytes. -constexpr size_t NewFragHeadroom = 8; - -static_assert(NewFragHeadroom >= alignof(MCFragment)); -static_assert(FragBlockSize >= sizeof(MCFragment) + NewFragHeadroom); - -MCFragment *MCObjectStreamer::allocFragSpace(size_t Headroom) { - auto Size = std::max(FragBlockSize, sizeof(MCFragment) + Headroom); - FragSpace = Size - sizeof(MCFragment); - auto Block = std::unique_ptr<uint8_t[]>(new uint8_t[Size]); - auto *F = reinterpret_cast<MCFragment *>(Block.get()); - FragStorage.push_back(std::move(Block)); - return F; -} - void MCObjectStreamer::newFragment() { - MCFragment *F; - if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) { - auto End = reinterpret_cast<size_t>(getCurFragEnd()); - F = reinterpret_cast<MCFragment *>( - alignToPowerOf2(End, alignof(MCFragment))); - FragSpace -= size_t(F) - End + sizeof(MCFragment); - } else { - F = allocFragSpace(0); - } - new (F) MCFragment(); - addFragment(F); -} - -void MCObjectStreamer::ensureHeadroom(size_t Headroom) { - if (Headroom <= FragSpace) - return; - auto *F = allocFragSpace(Headroom); - new (F) MCFragment(); - addFragment(F); + addFragment(allocFragment<MCFragment>()); } void MCObjectStreamer::addSpecialFragment(MCFragment *Frag) { assert(Frag->getKind() != MCFragment::FT_Data && - "F should have a variable-size tail"); - // Frag is not connected to FragSpace. Before modifying CurFrag with - // addFragment(Frag), allocate an empty fragment to maintain FragSpace - // connectivity, potentially reusing CurFrag's associated space. - MCFragment *F; - if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) { - auto End = reinterpret_cast<size_t>(getCurFragEnd()); - F = reinterpret_cast<MCFragment *>( - alignToPowerOf2(End, alignof(MCFragment))); - FragSpace -= size_t(F) - End + sizeof(MCFragment); - } else { - F = allocFragSpace(0); - } - new (F) MCFragment(); - + "Frag should have a variable-size tail"); addFragment(Frag); - addFragment(F); + newFragment(); } void MCObjectStreamer::appendContents(ArrayRef<char> Contents) { - ensureHeadroom(Contents.size()); - assert(FragSpace >= Contents.size()); - llvm::copy(Contents, getCurFragEnd()); - CurFrag->FixedSize += Contents.size(); - FragSpace -= Contents.size(); + CurFrag->appendContents(Contents); } -void MCObjectStreamer::appendContents(size_t Num, uint8_t Elt) { - ensureHeadroom(Num); - MutableArrayRef<uint8_t> Data(getCurFragEnd(), Num); - llvm::fill(Data, Elt); - CurFrag->FixedSize += Num; - FragSpace -= Num; +void MCObjectStreamer::appendContents(size_t Num, char Elt) { + CurFrag->appendContents(Num, Elt); } void MCObjectStreamer::addFixup(const MCExpr *Value, MCFixupKind Kind) { @@ -171,8 +115,6 @@ void MCObjectStreamer::reset() { } EmitEHFrame = true; EmitDebugFrame = false; - FragStorage.clear(); - FragSpace = 0; SpecialFragAllocator.Reset(); MCStreamer::reset(); } @@ -202,6 +144,7 @@ void MCObjectStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) { void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { MCStreamer::emitValueImpl(Value, Size, Loc); + MCFragment *DF = getCurrentFragment(); MCDwarfLineEntry::make(this, getCurrentSectionOnly()); @@ -216,9 +159,9 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, emitIntValue(AbsValue, Size); return; } - ensureHeadroom(Size); - addFixup(Value, MCFixup::getDataKindForSize(Size)); - appendContents(Size, 0); + DF->addFixup(MCFixup::create(DF->getContents().size(), Value, + MCFixup::getDataKindForSize(Size))); + DF->appendContents(Size, 0); } MCSymbol *MCObjectStreamer::emitCFILabel() { @@ -252,7 +195,7 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { // section. MCFragment *F = CurFrag; Symbol->setFragment(F); - Symbol->setOffset(F->getFixedSize()); + Symbol->setOffset(F->getContents().size()); emitPendingAssignments(Symbol); } @@ -318,21 +261,6 @@ void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) { F0 = CurFrag; } - // To maintain connectivity between CurFrag and FragSpace when CurFrag is - // modified, allocate an empty fragment and append it to the fragment list. - // (Subsections[I].second.Tail is not connected to FragSpace.) - MCFragment *F; - if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) { - auto End = reinterpret_cast<size_t>(getCurFragEnd()); - F = reinterpret_cast<MCFragment *>( - alignToPowerOf2(End, alignof(MCFragment))); - FragSpace -= size_t(F) - End + sizeof(MCFragment); - } else { - F = allocFragSpace(0); - } - new (F) MCFragment(); - F->setParent(Section); - auto &Subsections = Section->Subsections; size_t I = 0, E = Subsections.size(); while (I != E && Subsections[I].first < Subsection) @@ -340,16 +268,13 @@ void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) { // If the subsection number is not in the sorted Subsections list, create a // new fragment list. if (I == E || Subsections[I].first != Subsection) { + auto *F = allocFragment<MCFragment>(); + F->setParent(Section); Subsections.insert(Subsections.begin() + I, {Subsection, MCSection::FragList{F, F}}); - Section->CurFragList = &Subsections[I].second; - CurFrag = F; - } else { - Section->CurFragList = &Subsections[I].second; - CurFrag = Subsections[I].second.Tail; - // Ensure CurFrag is associated with FragSpace. - addFragment(F); } + Section->CurFragList = &Subsections[I].second; + CurFrag = Section->CurFragList->Tail; // Define the section symbol at subsection 0's initial fragment if required. if (!NewSec) @@ -420,15 +345,11 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst, MCFragment *F = getCurrentFragment(); // Append the instruction to the data fragment. - size_t CodeOffset = getCurFragSize(); - SmallString<16> Content; + size_t CodeOffset = F->getContents().size(); SmallVector<MCFixup, 1> Fixups; - getAssembler().getEmitter().encodeInstruction(Inst, Content, Fixups, STI); - appendContents(Content); - if (CurFrag != F) { - F = CurFrag; - CodeOffset = 0; - } + getAssembler().getEmitter().encodeInstruction( + Inst, F->getContentsForAppending(), Fixups, STI); + F->doneAppending(); F->setHasInstructions(STI); if (Fixups.empty()) diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index c5611a38..7782dc1 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -6273,7 +6273,8 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef, // used as a symbol, or it is an absolute symbol). Sym = Parser.getContext().lookupSymbol(Name); if (Sym) { - if (!Sym->isUnset() && (!allow_redef || !Sym->isRedefinable())) + if ((Sym->isVariable() || Sym->isDefined()) && + (!allow_redef || !Sym->isRedefinable())) return Parser.Error(EqualLoc, "redefinition of '" + Name + "'"); // If the symbol is redefinable, clone it and update the symbol table // to the new symbol. Existing references to the original symbol remain diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp index a87648a..72a8dd7 100644 --- a/llvm/lib/MC/MCWin64EH.cpp +++ b/llvm/lib/MC/MCWin64EH.cpp @@ -318,9 +318,6 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { // Emit the epilog instructions. if (EnableUnwindV2) { - // Ensure the fixups and appended content apply to the same fragment. - OS->ensureHeadroom(info->EpilogMap.size() * 2); - bool IsLast = true; for (const auto &Epilog : llvm::reverse(info->EpilogMap)) { if (IsLast) { diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp index a45936b..67baba7 100644 --- a/llvm/lib/MC/MCWinCOFFStreamer.cpp +++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp @@ -279,7 +279,6 @@ void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) { void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) { visitUsedSymbol(*Symbol); const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext()); - ensureHeadroom(2); addFixup(SRE, FK_SecRel_2); appendContents(2, 0); } @@ -293,7 +292,6 @@ void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol, if (Offset) MCE = MCBinaryExpr::createAdd( MCE, MCConstantExpr::create(Offset, getContext()), getContext()); - ensureHeadroom(4); addFixup(MCE, FK_SecRel_4); // Emit 4 bytes (zeros) to the object file. appendContents(4, 0); @@ -309,7 +307,6 @@ void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol, if (Offset) MCE = MCBinaryExpr::createAdd( MCE, MCConstantExpr::create(Offset, getContext()), getContext()); - ensureHeadroom(4); addFixup(MCE, FK_Data_4); // Emit 4 bytes (zeros) to the object file. appendContents(4, 0); @@ -320,7 +317,6 @@ void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) { // Create Symbol for section number. const MCExpr *MCE = MCCOFFSectionNumberTargetExpr::create( *Symbol, this->getWriter(), getContext()); - ensureHeadroom(4); addFixup(MCE, FK_Data_4); // Emit 4 bytes (zeros) to the object file. appendContents(4, 0); @@ -331,7 +327,6 @@ void MCWinCOFFStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) { // Create Symbol for section offset. const MCExpr *MCE = MCCOFFSectionOffsetTargetExpr::create(*Symbol, getContext()); - ensureHeadroom(4); addFixup(MCE, FK_Data_4); // Emit 4 bytes (zeros) to the object file. appendContents(4, 0); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 5df70c4..4056724 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -1034,14 +1034,12 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() { void MipsTargetELFStreamer::emitGPRel32Value(const MCExpr *Value) { auto &S = getStreamer(); - S.ensureHeadroom(4); S.addFixup(Value, Mips::fixup_Mips_GPREL32); S.appendContents(4, 0); } void MipsTargetELFStreamer::emitGPRel64Value(const MCExpr *Value) { auto &S = getStreamer(); - S.ensureHeadroom(8); // fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64. S.addFixup(Value, Mips::fixup_Mips_GPREL32); S.appendContents(8, 0); @@ -1049,28 +1047,24 @@ void MipsTargetELFStreamer::emitGPRel64Value(const MCExpr *Value) { void MipsTargetELFStreamer::emitDTPRel32Value(const MCExpr *Value) { auto &S = getStreamer(); - S.ensureHeadroom(4); S.addFixup(Value, Mips::fixup_Mips_DTPREL32); S.appendContents(4, 0); } void MipsTargetELFStreamer::emitDTPRel64Value(const MCExpr *Value) { auto &S = getStreamer(); - S.ensureHeadroom(8); S.addFixup(Value, Mips::fixup_Mips_DTPREL64); S.appendContents(8, 0); } void MipsTargetELFStreamer::emitTPRel32Value(const MCExpr *Value) { auto &S = getStreamer(); - S.ensureHeadroom(4); S.addFixup(Value, Mips::fixup_Mips_TPREL32); S.appendContents(4, 0); } void MipsTargetELFStreamer::emitTPRel64Value(const MCExpr *Value) { auto &S = getStreamer(); - S.ensureHeadroom(8); S.addFixup(Value, Mips::fixup_Mips_TPREL64); S.appendContents(8, 0); } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 5265613..44a8245d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -14,6 +14,14 @@ // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// +def SDT_SetMultiple : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>, + SDTCisSameAs<1, 3>, + SDTCisPtrTy<2>, + SDTCisVT<3, XLenVT>]>; + +def qc_setwmi : RVSDNode<"QC_SETWMI", SDT_SetMultiple, + [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; + def uimm5nonzero : RISCVOp<XLenVT>, ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5, "NonZero">; @@ -27,6 +35,8 @@ def uimm5nonzero : RISCVOp<XLenVT>, }]; } +def tuimm5nonzero : TImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]>; + def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT, [{return (Imm > 3) && isUInt<5>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5, "GT3">; @@ -92,6 +102,8 @@ def uimm5slist : RISCVOp<XLenVT>, ImmLeaf<XLenVT, }]; } +def tuimm7_lsb00 : TImmLeaf<XLenVT,[{return isShiftedUInt<5, 2>(Imm);}]>; + def uimm10 : RISCVUImmLeafOp<10>; def uimm11 : RISCVUImmLeafOp<11>; @@ -1566,6 +1578,11 @@ def : QCISELECTIICCPat <SETEQ, QC_SELECTIIEQ>; def : QCISELECTIICCPat <SETNE, QC_SELECTIINE>; } // Predicates = [HasVendorXqcics, IsRV32] +let Predicates = [HasVendorXqcilsm, IsRV32] in { +def : Pat<(qc_setwmi GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7), + (QC_SETWMI GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7)>; +} // Predicates = [HasVendorXqcilsm, IsRV32] + //===----------------------------------------------------------------------===/i // Compress Instruction tablegen backend. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp index 6ecddad..041dd07 100644 --- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "RISCVSelectionDAGInfo.h" +#include "RISCVSubtarget.h" +#include "llvm/CodeGen/SelectionDAG.h" #define GET_SDNODE_DESC #include "RISCVGenSDNodeInfo.inc" @@ -62,3 +64,94 @@ void RISCVSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG, } #endif } + +SDValue RISCVSelectionDAGInfo::EmitTargetCodeForMemset( + SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline, + MachinePointerInfo DstPtrInfo) const { + const auto &Subtarget = DAG.getSubtarget<RISCVSubtarget>(); + // We currently do this only for Xqcilsm + if (!Subtarget.hasVendorXqcilsm()) + return SDValue(); + + // Do this only if we know the size at compile time. + ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size); + if (!ConstantSize) + return SDValue(); + + uint64_t NumberOfBytesToWrite = ConstantSize->getZExtValue(); + + // Do this only if it is word aligned and we write a multiple of 4 bytes. + if (!(Alignment >= 4) || !((NumberOfBytesToWrite & 3) == 0)) + return SDValue(); + + SmallVector<SDValue, 8> OutChains; + SDValue SrcValueReplicated = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Src); + int NumberOfWords = NumberOfBytesToWrite / 4; + MachineFunction &MF = DAG.getMachineFunction(); + auto Volatile = + isVolatile ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone; + + // Helper for constructing the QC_SETWMI instruction + auto getSetwmiNode = [&](uint8_t SizeWords, uint8_t OffsetSetwmi) -> SDValue { + SDValue Ops[] = {Chain, SrcValueReplicated, Dst, + DAG.getTargetConstant(SizeWords, dl, MVT::i32), + DAG.getTargetConstant(OffsetSetwmi, dl, MVT::i32)}; + MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand( + DstPtrInfo.getWithOffset(OffsetSetwmi), + MachineMemOperand::MOStore | Volatile, SizeWords * 4, Align(4)); + return DAG.getMemIntrinsicNode(RISCVISD::QC_SETWMI, dl, + DAG.getVTList(MVT::Other), Ops, MVT::i32, + BaseMemOperand); + }; + + // If i8 type and constant non-zero value. + if ((Src.getValueType() == MVT::i8) && !isNullConstant(Src)) + // Replicate byte to word by multiplication with 0x01010101. + SrcValueReplicated = + DAG.getNode(ISD::MUL, dl, MVT::i32, SrcValueReplicated, + DAG.getConstant(0x01010101ul, dl, MVT::i32)); + + // We limit a QC_SETWMI to 16 words or less to improve interruptibility. + // So for 1-16 words we use a single QC_SETWMI: + // + // QC_SETWMI reg1, N, 0(reg2) + // + // For 17-32 words we use two QC_SETWMI's with the first as 16 words and the + // second for the remainder: + // + // QC_SETWMI reg1, 16, 0(reg2) + // QC_SETWMI reg1, N, 64(reg2) + // + // For 33-48 words, we would like to use (16, 16, n), but that means the last + // QC_SETWMI needs an offset of 128 which the instruction doesn't support. + // So in this case we use a length of 15 for the second instruction and we do + // the rest with the third instruction. + // This means the maximum inlined number of words is 47 (for now): + // + // QC_SETWMI R2, R0, 16, 0 + // QC_SETWMI R2, R0, 15, 64 + // QC_SETWMI R2, R0, N, 124 + // + // For 48 words or more, call the target independent memset + if (NumberOfWords >= 48) + return SDValue(); + + if (NumberOfWords <= 16) { + // 1 - 16 words + return getSetwmiNode(NumberOfWords, 0); + } + + if (NumberOfWords <= 32) { + // 17 - 32 words + OutChains.push_back(getSetwmiNode(NumberOfWords - 16, 64)); + OutChains.push_back(getSetwmiNode(16, 0)); + } else { + // 33 - 47 words + OutChains.push_back(getSetwmiNode(NumberOfWords - 31, 124)); + OutChains.push_back(getSetwmiNode(15, 64)); + OutChains.push_back(getSetwmiNode(16, 0)); + } + + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); +} diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h index 641189f..08c8d11 100644 --- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h +++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h @@ -34,6 +34,12 @@ public: void verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const override; + SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl, + SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, Align Alignment, + bool isVolatile, bool AlwaysInline, + MachinePointerInfo DstPtrInfo) const override; + bool hasPassthruOp(unsigned Opcode) const { return GenNodeInfo.getDesc(Opcode).TSFlags & RISCVISD::HasPassthruOpMask; } diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index e87bee7..8da65c5 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1222,9 +1222,9 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) return; // Find alloca instruction that corresponds to llvm.lifetime argument. - AllocaInst *AI = cast<AllocaInst>(II.getArgOperand(1)); + AllocaInst *AI = dyn_cast<AllocaInst>(II.getArgOperand(1)); // We're interested only in allocas we can handle. - if (!ASan.isInterestingAlloca(*AI)) + if (!AI || !ASan.isInterestingAlloca(*AI)) return; bool DoPoison = (ID == Intrinsic::lifetime_end); AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison}; diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 54d9a83..7d3c940 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -3301,8 +3301,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { void handleLifetimeStart(IntrinsicInst &I) { if (!PoisonStack) return; - AllocaInst *AI = cast<AllocaInst>(I.getArgOperand(1)); - LifetimeStartList.push_back(std::make_pair(&I, AI)); + AllocaInst *AI = dyn_cast<AllocaInst>(I.getArgOperand(1)); + if (AI) + LifetimeStartList.push_back(std::make_pair(&I, AI)); } void handleBswap(IntrinsicInst &I) { diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index babd7f6..3852f1a 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -482,6 +482,9 @@ bool llvm::wouldInstructionBeTriviallyDead(const Instruction *I, if (II->isLifetimeStartOrEnd()) { auto *Arg = II->getArgOperand(1); + if (isa<PoisonValue>(Arg)) + return true; + // If the only uses of the alloca are lifetime intrinsics, then the // intrinsics are dead. return llvm::all_of(Arg->uses(), [](Use &Use) { diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp index bea76d3..472c03f 100644 --- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp +++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp @@ -155,8 +155,9 @@ void StackInfoBuilder::visit(OptimizationRemarkEmitter &ORE, return; } if (auto *II = dyn_cast<LifetimeIntrinsic>(&Inst)) { - AllocaInst *AI = cast<AllocaInst>(II->getArgOperand(1)); - if (getAllocaInterestingness(*AI) != AllocaInterestingness::kInteresting) + AllocaInst *AI = dyn_cast<AllocaInst>(II->getArgOperand(1)); + if (!AI || + getAllocaInterestingness(*AI) != AllocaInterestingness::kInteresting) return; if (II->getIntrinsicID() == Intrinsic::lifetime_start) Info.AllocasToInstrument[AI].LifetimeStart.push_back(II); |