diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 35 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/PatchableFunction.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/StackColoring.cpp | 19 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/TargetPassConfig.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/IR/Verifier.cpp | 21 | ||||
| -rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMMCInstLower.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 97 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h | 14 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp | 69 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 18 |
17 files changed, 206 insertions, 137 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 6f9aa4dd79fd5..3516f4a7b3703 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -706,6 +706,21 @@ void AsmPrinter::EmitFunctionHeader() { } } + // Emit M NOPs for -fpatchable-function-entry=N,M where M>0. We arbitrarily + // place prefix data before NOPs. + unsigned PatchableFunctionPrefix = 0; + (void)F.getFnAttribute("patchable-function-prefix") + .getValueAsString() + .getAsInteger(10, PatchableFunctionPrefix); + if (PatchableFunctionPrefix) { + CurrentPatchableFunctionEntrySym = + OutContext.createLinkerPrivateTempSymbol(); + OutStreamer->EmitLabel(CurrentPatchableFunctionEntrySym); + emitNops(PatchableFunctionPrefix); + } else { + CurrentPatchableFunctionEntrySym = CurrentFnBegin; + } + // Emit the function descriptor. This is a virtual function to allow targets // to emit their specific function descriptor. if (MAI->needsFunctionDescriptors()) @@ -1167,7 +1182,7 @@ void AsmPrinter::EmitFunctionBody() { // unspecified. if (Noop.getOpcode()) { OutStreamer->AddComment("avoids zero-length function"); - OutStreamer->EmitInstruction(Noop, getSubtargetInfo()); + emitNops(1); } } @@ -2797,6 +2812,13 @@ void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { OS << Offset; } +void AsmPrinter::emitNops(unsigned N) { + MCInst Nop; + MF->getSubtarget().getInstrInfo()->getNoop(Nop); + for (; N; --N) + EmitToStreamer(*OutStreamer, Nop); +} + //===----------------------------------------------------------------------===// // Symbol Lowering Routines. //===----------------------------------------------------------------------===// @@ -3199,7 +3221,14 @@ void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, void AsmPrinter::emitPatchableFunctionEntries() { const Function &F = MF->getFunction(); - if (!F.hasFnAttribute("patchable-function-entry")) + unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0; + (void)F.getFnAttribute("patchable-function-prefix") + .getValueAsString() + .getAsInteger(10, PatchableFunctionPrefix); + (void)F.getFnAttribute("patchable-function-entry") + .getValueAsString() + .getAsInteger(10, PatchableFunctionEntry); + if (!PatchableFunctionPrefix && !PatchableFunctionEntry) return; const unsigned PointerSize = getPointerSize(); if (TM.getTargetTriple().isOSBinFormatELF()) { @@ -3228,7 +3257,7 @@ void AsmPrinter::emitPatchableFunctionEntries() { "__patchable_function_entries", ELF::SHT_PROGBITS, Flags)); } EmitAlignment(Align(PointerSize)); - OutStreamer->EmitSymbolValue(CurrentFnBegin, PointerSize); + OutStreamer->EmitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize); } } diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index f05afd0587461..003db39fe5f9d 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -6122,6 +6122,7 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { BasicBlock *StartBlock = SI->getParent(); BasicBlock::iterator SplitPt = ++(BasicBlock::iterator(LastSI)); BasicBlock *EndBlock = StartBlock->splitBasicBlock(SplitPt, "select.end"); + BFI->setBlockFreq(EndBlock, BFI->getBlockFreq(StartBlock).getFrequency()); // Delete the unconditional branch that was just created by the split. StartBlock->getTerminator()->eraseFromParent(); diff --git a/llvm/lib/CodeGen/PatchableFunction.cpp b/llvm/lib/CodeGen/PatchableFunction.cpp index 1d6069c505541..a8466396f9b89 100644 --- a/llvm/lib/CodeGen/PatchableFunction.cpp +++ b/llvm/lib/CodeGen/PatchableFunction.cpp @@ -57,10 +57,15 @@ static bool doesNotGeneratecode(const MachineInstr &MI) { bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) { if (MF.getFunction().hasFnAttribute("patchable-function-entry")) { MachineBasicBlock &FirstMBB = *MF.begin(); - MachineInstr &FirstMI = *FirstMBB.begin(); const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); - BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(), - TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER)); + if (FirstMBB.empty()) { + BuildMI(&FirstMBB, DebugLoc(), + TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER)); + } else { + MachineInstr &FirstMI = *FirstMBB.begin(); + BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(), + TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER)); + } return true; } diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp index b6e81116286fb..40bc36c3030bd 100644 --- a/llvm/lib/CodeGen/StackColoring.cpp +++ b/llvm/lib/CodeGen/StackColoring.cpp @@ -960,6 +960,7 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) { } // Remap all instructions to the new stack slots. + std::vector<std::vector<MachineMemOperand *>> SSRefs(MFI->getObjectIndexEnd()); for (MachineBasicBlock &BB : *MF) for (MachineInstr &I : BB) { // Skip lifetime markers. We'll remove them soon. @@ -1025,6 +1026,16 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) { SmallVector<MachineMemOperand *, 2> NewMMOs; bool ReplaceMemOps = false; for (MachineMemOperand *MMO : I.memoperands()) { + // Collect MachineMemOperands which reference + // FixedStackPseudoSourceValues with old frame indices. + if (const auto *FSV = dyn_cast_or_null<FixedStackPseudoSourceValue>( + MMO->getPseudoValue())) { + int FI = FSV->getFrameIndex(); + auto To = SlotRemap.find(FI); + if (To != SlotRemap.end()) + SSRefs[FI].push_back(MMO); + } + // If this memory location can be a slot remapped here, // we remove AA information. bool MayHaveConflictingAAMD = false; @@ -1062,6 +1073,14 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) { I.setMemRefs(*MF, NewMMOs); } + // Rewrite MachineMemOperands that reference old frame indices. + for (auto E : enumerate(SSRefs)) { + const PseudoSourceValue *NewSV = + MF->getPSVManager().getFixedStack(SlotRemap[E.index()]); + for (MachineMemOperand *Ref : E.value()) + Ref->setValue(NewSV); + } + // Update the location of C++ catch objects for the MSVC personality routine. if (WinEHFuncInfo *EHInfo = MF->getWinEHFuncInfo()) for (WinEHTryBlockMapEntry &TBME : EHInfo->TryBlockMap) diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index 41cb511ad9b47..d08d05d4b2edb 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -956,6 +956,12 @@ void TargetPassConfig::addMachinePasses() { if (getOptLevel() != CodeGenOpt::None) addBlockPlacement(); + // Insert before XRay Instrumentation. + addPass(&FEntryInserterID, false); + + addPass(&XRayInstrumentationID, false); + addPass(&PatchableFunctionID, false); + addPreEmitPass(); if (TM->Options.EnableIPRA) @@ -968,12 +974,6 @@ void TargetPassConfig::addMachinePasses() { addPass(&StackMapLivenessID, false); addPass(&LiveDebugValuesID, false); - // Insert before XRay Instrumentation. - addPass(&FEntryInserterID, false); - - addPass(&XRayInstrumentationID, false); - addPass(&PatchableFunctionID, false); - if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None && EnableMachineOutliner != NeverOutline) { bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index d15b70d71b473..61707cc835041 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1852,16 +1852,25 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V); } + if (Attrs.hasFnAttribute("patchable-function-prefix")) { + StringRef S = Attrs + .getAttribute(AttributeList::FunctionIndex, + "patchable-function-prefix") + .getValueAsString(); + unsigned N; + if (S.getAsInteger(10, N)) + CheckFailed( + "\"patchable-function-prefix\" takes an unsigned integer: " + S, V); + } if (Attrs.hasFnAttribute("patchable-function-entry")) { - StringRef S0 = Attrs - .getAttribute(AttributeList::FunctionIndex, - "patchable-function-entry") - .getValueAsString(); - StringRef S = S0; + StringRef S = Attrs + .getAttribute(AttributeList::FunctionIndex, + "patchable-function-entry") + .getValueAsString(); unsigned N; if (S.getAsInteger(10, N)) CheckFailed( - "\"patchable-function-entry\" takes an unsigned integer: " + S0, V); + "\"patchable-function-entry\" takes an unsigned integer: " + S, V); } } diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index b30137aafb8d1..75ec279755647 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -217,6 +217,13 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, } assert(getBackendPtr() && "Expected assembler backend"); + bool IsTarget = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsTarget; + + if (IsTarget) + return getBackend().evaluateTargetFixup(*this, Layout, Fixup, DF, Target, + Value, WasForced); + bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 00e321f9b8509..b8953583a310d 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -250,8 +250,7 @@ void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI) .getValueAsString() .getAsInteger(10, Num)) return; - for (; Num; --Num) - EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0)); + emitNops(Num); return; } diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp index 3156bb4469638..bc91d628f0b46 100644 --- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp +++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp @@ -1325,6 +1325,19 @@ canRenameUpToDef(MachineInstr &FirstMI, LiveRegUnits &UsedInBetween, // For defs, check if we can rename the first def of RegToRename. if (FoundDef) { + // For some pseudo instructions, we might not generate code in the end + // (e.g. KILL) and we would end up without a correct def for the rename + // register. + // TODO: This might be overly conservative and we could handle those cases + // in multiple ways: + // 1. Insert an extra copy, to materialize the def. + // 2. Skip pseudo-defs until we find an non-pseudo def. + if (MI.isPseudo()) { + LLVM_DEBUG(dbgs() << " Cannot rename pseudo instruction " << MI + << "\n"); + return false; + } + for (auto &MOP : MI.operands()) { if (!MOP.isReg() || !MOP.isDef() || MOP.isDebug() || !MOP.getReg() || !TRI->regsOverlap(MOP.getReg(), RegToRename)) diff --git a/llvm/lib/Target/ARM/ARMMCInstLower.cpp b/llvm/lib/Target/ARM/ARMMCInstLower.cpp index c92689f4942e5..8e01b998d9001 100644 --- a/llvm/lib/Target/ARM/ARMMCInstLower.cpp +++ b/llvm/lib/Target/ARM/ARMMCInstLower.cpp @@ -207,10 +207,7 @@ void ARMAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::Bcc).addImm(20) .addImm(ARMCC::AL).addReg(0)); - MCInst Noop; - Subtarget->getInstrInfo()->getNoop(Noop); - for (int8_t I = 0; I < NoopsInSledCount; I++) - OutStreamer->EmitInstruction(Noop, getSubtargetInfo()); + emitNops(NoopsInSledCount); OutStreamer->EmitLabel(Target); recordSled(CurSled, MI, Kind); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 5881a0a86ef77..373d0ccb18576 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -9,6 +9,7 @@ #include "RISCVAsmBackend.h" #include "RISCVMCExpr.h" #include "llvm/ADT/APInt.h" +#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" @@ -28,8 +29,6 @@ using namespace llvm; bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) { - bool ShouldForce = false; - switch (Fixup.getTargetKind()) { default: break; @@ -44,40 +43,9 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_gd_hi20: return true; - case RISCV::fixup_riscv_pcrel_lo12_i: - case RISCV::fixup_riscv_pcrel_lo12_s: - // For pcrel_lo12, force a relocation if the target of the corresponding - // pcrel_hi20 is not in the same fragment. - const MCFixup *T = cast<RISCVMCExpr>(Fixup.getValue())->getPCRelHiFixup(); - if (!T) { - Asm.getContext().reportError(Fixup.getLoc(), - "could not find corresponding %pcrel_hi"); - return false; - } - - switch (T->getTargetKind()) { - default: - llvm_unreachable("Unexpected fixup kind for pcrel_lo12"); - break; - case RISCV::fixup_riscv_got_hi20: - case RISCV::fixup_riscv_tls_got_hi20: - case RISCV::fixup_riscv_tls_gd_hi20: - ShouldForce = true; - break; - case RISCV::fixup_riscv_pcrel_hi20: { - MCFragment *TFragment = T->getValue()->findAssociatedFragment(); - MCFragment *FixupFragment = Fixup.getValue()->findAssociatedFragment(); - assert(FixupFragment && "We should have a fragment for this fixup"); - ShouldForce = - !TFragment || TFragment->getParent() != FixupFragment->getParent(); - break; - } - } - break; } - return ShouldForce || STI.getFeatureBits()[RISCV::FeatureRelax] || - ForceRelocs; + return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs; } bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, @@ -284,6 +252,67 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, } } +bool RISCVAsmBackend::evaluateTargetFixup( + const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, + const MCFragment *DF, const MCValue &Target, uint64_t &Value, + bool &WasForced) { + const MCFixup *AUIPCFixup; + const MCFragment *AUIPCDF; + MCValue AUIPCTarget; + switch (Fixup.getTargetKind()) { + default: + llvm_unreachable("Unexpected fixup kind!"); + case RISCV::fixup_riscv_pcrel_hi20: + AUIPCFixup = &Fixup; + AUIPCDF = DF; + AUIPCTarget = Target; + break; + case RISCV::fixup_riscv_pcrel_lo12_i: + case RISCV::fixup_riscv_pcrel_lo12_s: { + AUIPCFixup = cast<RISCVMCExpr>(Fixup.getValue())->getPCRelHiFixup(&AUIPCDF); + if (!AUIPCFixup) { + Asm.getContext().reportError(Fixup.getLoc(), + "could not find corresponding %pcrel_hi"); + return true; + } + + // MCAssembler::evaluateFixup will emit an error for this case when it sees + // the %pcrel_hi, so don't duplicate it when also seeing the %pcrel_lo. + const MCExpr *AUIPCExpr = AUIPCFixup->getValue(); + if (!AUIPCExpr->evaluateAsRelocatable(AUIPCTarget, &Layout, AUIPCFixup)) + return true; + break; + } + } + + if (!AUIPCTarget.getSymA() || AUIPCTarget.getSymB()) + return false; + + const MCSymbolRefExpr *A = AUIPCTarget.getSymA(); + const MCSymbol &SA = A->getSymbol(); + if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) + return false; + + auto *Writer = Asm.getWriterPtr(); + if (!Writer) + return false; + + bool IsResolved = Writer->isSymbolRefDifferenceFullyResolvedImpl( + Asm, SA, *AUIPCDF, false, true); + if (!IsResolved) + return false; + + Value = Layout.getSymbolOffset(SA) + AUIPCTarget.getConstant(); + Value -= Layout.getFragmentOffset(AUIPCDF) + AUIPCFixup->getOffset(); + + if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget)) { + WasForced = true; + return false; + } + + return true; +} + void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef<char> Data, uint64_t Value, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index 254249c87dc88..1c3c587355a20 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -65,6 +65,11 @@ public: const MCAsmLayout &Layout, MCAlignFragment &AF) override; + bool evaluateTargetFixup(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFixup &Fixup, const MCFragment *DF, + const MCValue &Target, uint64_t &Value, + bool &WasForced) override; + void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef<char> Data, uint64_t Value, bool IsResolved, @@ -101,9 +106,12 @@ public: { "fixup_riscv_hi20", 12, 20, 0 }, { "fixup_riscv_lo12_i", 20, 12, 0 }, { "fixup_riscv_lo12_s", 0, 32, 0 }, - { "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_riscv_pcrel_hi20", 12, 20, + MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget }, + { "fixup_riscv_pcrel_lo12_i", 20, 12, + MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget }, + { "fixup_riscv_pcrel_lo12_s", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget }, { "fixup_riscv_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_tprel_hi20", 12, 20, 0 }, { "fixup_riscv_tprel_lo12_i", 20, 12, 0 }, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp index 7aa9b5e7d6839..2a6f372e50bee 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp @@ -47,7 +47,7 @@ void RISCVMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { OS << ')'; } -const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { +const MCFixup *RISCVMCExpr::getPCRelHiFixup(const MCFragment **DFOut) const { MCValue AUIPCLoc; if (!getSubExpr()->evaluateAsRelocatable(AUIPCLoc, nullptr, nullptr)) return nullptr; @@ -81,6 +81,8 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_gd_hi20: case RISCV::fixup_riscv_pcrel_hi20: + if (DFOut) + *DFOut = DF; return &F; } } @@ -88,74 +90,9 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { return nullptr; } -bool RISCVMCExpr::evaluatePCRelLo(MCValue &Res, const MCAsmLayout *Layout, - const MCFixup *Fixup) const { - // VK_RISCV_PCREL_LO has to be handled specially. The MCExpr inside is - // actually the location of a auipc instruction with a VK_RISCV_PCREL_HI fixup - // pointing to the real target. We need to generate an MCValue in the form of - // (<real target> + <offset from this fixup to the auipc fixup>). The Fixup - // is pcrel relative to the VK_RISCV_PCREL_LO fixup, so we need to add the - // offset to the VK_RISCV_PCREL_HI Fixup from VK_RISCV_PCREL_LO to correct. - - // Don't try to evaluate if the fixup will be forced as a relocation (e.g. - // as linker relaxation is enabled). If we evaluated pcrel_lo in this case, - // the modified fixup will be converted into a relocation that no longer - // points to the pcrel_hi as the linker requires. - auto &RAB = - static_cast<RISCVAsmBackend &>(Layout->getAssembler().getBackend()); - if (RAB.willForceRelocations()) - return false; - - MCValue AUIPCLoc; - if (!getSubExpr()->evaluateAsValue(AUIPCLoc, *Layout)) - return false; - - const MCSymbolRefExpr *AUIPCSRE = AUIPCLoc.getSymA(); - // Don't try to evaluate %pcrel_hi/%pcrel_lo pairs that cross fragment - // boundries. - if (!AUIPCSRE || - findAssociatedFragment() != AUIPCSRE->findAssociatedFragment()) - return false; - - const MCSymbol *AUIPCSymbol = &AUIPCSRE->getSymbol(); - if (!AUIPCSymbol) - return false; - - const MCFixup *TargetFixup = getPCRelHiFixup(); - if (!TargetFixup) - return false; - - if ((unsigned)TargetFixup->getKind() != RISCV::fixup_riscv_pcrel_hi20) - return false; - - MCValue Target; - if (!TargetFixup->getValue()->evaluateAsValue(Target, *Layout)) - return false; - - if (!Target.getSymA() || !Target.getSymA()->getSymbol().isInSection()) - return false; - - if (&Target.getSymA()->getSymbol().getSection() != - findAssociatedFragment()->getParent()) - return false; - - // We must use TargetFixup rather than AUIPCSymbol here. They will almost - // always have the same offset, except for the case when AUIPCSymbol is at - // the end of a fragment and the fixup comes from offset 0 in the next - // fragment. - uint64_t AUIPCOffset = TargetFixup->getOffset(); - - Res = MCValue::get(Target.getSymA(), nullptr, - Target.getConstant() + (Fixup->getOffset() - AUIPCOffset)); - return true; -} - bool RISCVMCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const { - if (Kind == VK_RISCV_PCREL_LO && evaluatePCRelLo(Res, Layout, Fixup)) - return true; - if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) return false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h index 921df376f3dfc..167e7d553e7d3 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h @@ -46,9 +46,6 @@ private: int64_t evaluateAsInt64(int64_t Value) const; - bool evaluatePCRelLo(MCValue &Res, const MCAsmLayout *Layout, - const MCFixup *Fixup) const; - explicit RISCVMCExpr(const MCExpr *Expr, VariantKind Kind) : Expr(Expr), Kind(Kind) {} @@ -61,11 +58,11 @@ public: const MCExpr *getSubExpr() const { return Expr; } /// Get the corresponding PC-relative HI fixup that a VK_RISCV_PCREL_LO - /// points to. + /// points to, and optionally the fragment containing it. /// /// \returns nullptr if this isn't a VK_RISCV_PCREL_LO pointing to a /// known PC-relative HI fixup. - const MCFixup *getPCRelHiFixup() const; + const MCFixup *getPCRelHiFixup(const MCFragment **DFOut) const; void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 3b416ce3d3f4d..f6bc52968a33e 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -24,14 +24,14 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" +using namespace llvm; + #define GEN_CHECK_COMPRESS_INSTR #include "RISCVGenCompressInstEmitter.inc" #define GET_INSTRINFO_CTOR_DTOR #include "RISCVGenInstrInfo.inc" -using namespace llvm; - RISCVInstrInfo::RISCVInstrInfo(RISCVSubtarget &STI) : RISCVGenInstrInfo(RISCV::ADJCALLSTACKDOWN, RISCV::ADJCALLSTACKUP), STI(STI) {} diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index ebf9d24eecc41..c288a7d8d4037 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -1439,9 +1439,12 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { if (PrevSI->isUnordered() && equivalentAddressValues(PrevSI->getOperand(1), SI.getOperand(1))) { ++NumDeadStore; - ++BBI; + // Manually add back the original store to the worklist now, so it will + // be processed after the operands of the removed store, as this may + // expose additional DSE opportunities. + Worklist.Add(&SI); eraseInstFromFunction(*PrevSI); - continue; + return nullptr; } break; } diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index aabd974cd73e4..479bca83b51e4 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -377,6 +377,18 @@ static Value *isOneOf(const InstructionsState &S, Value *Op) { return S.OpValue; } +/// \returns true if \p Opcode is allowed as part of of the main/alternate +/// instruction for SLP vectorization. +/// +/// Example of unsupported opcode is SDIV that can potentially cause UB if the +/// "shuffled out" lane would result in division by zero. +static bool isValidForAlternation(unsigned Opcode) { + if (Instruction::isIntDivRem(Opcode)) + return false; + + return true; +} + /// \returns analysis of the Instructions in \p VL described in /// InstructionsState, the Opcode that we suppose the whole list /// could be vectorized even if its structure is diverse. @@ -399,7 +411,8 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL, if (IsBinOp && isa<BinaryOperator>(VL[Cnt])) { if (InstOpcode == Opcode || InstOpcode == AltOpcode) continue; - if (Opcode == AltOpcode) { + if (Opcode == AltOpcode && isValidForAlternation(InstOpcode) && + isValidForAlternation(Opcode)) { AltOpcode = InstOpcode; AltIndex = Cnt; continue; @@ -411,6 +424,9 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL, if (InstOpcode == Opcode || InstOpcode == AltOpcode) continue; if (Opcode == AltOpcode) { + assert(isValidForAlternation(Opcode) && + isValidForAlternation(InstOpcode) && + "Cast isn't safe for alternation, logic needs to be updated!"); AltOpcode = InstOpcode; AltIndex = Cnt; continue; |
