aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp1
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h2
-rw-r--r--llvm/lib/CodeGen/CommandFlags.cpp9
-rw-r--r--llvm/lib/CodeGen/ExpandFp.cpp4
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Combiner.cpp4
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp14
-rw-r--r--llvm/lib/CodeGen/InlineSpiller.cpp3
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp2
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp2
-rw-r--r--llvm/lib/CodeGen/MIR2Vec.cpp366
-rw-r--r--llvm/lib/CodeGen/MachineBasicBlock.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineLICM.cpp18
-rw-r--r--llvm/lib/CodeGen/PeepholeOptimizer.cpp2
-rw-r--r--llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp45
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h1
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp15
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp5
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp33
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp3
-rw-r--r--llvm/lib/CodeGen/ShrinkWrap.cpp2
-rw-r--r--llvm/lib/CodeGen/TargetOptionsImpl.cpp2
22 files changed, 399 insertions, 138 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index e2af0c5..fefde64f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1438,6 +1438,7 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
BBFreqEnabled,
BrProbEnabled,
MF.hasBBSections() && NumMBBSectionRanges > 1,
+ // Use static_cast to avoid breakage of tests on windows.
static_cast<bool>(BBAddrMapSkipEmitBBEntries),
HasCalls,
false};
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 9288d7e..9c0b68b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -334,7 +334,7 @@ public:
const DIE &TyDIE);
protected:
- ~DwarfUnit();
+ ~DwarfUnit() override;
/// Create new static data member DIE.
DIE *getOrCreateStaticMemberDIE(const DIDerivedType *DT);
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 0522698..c1365f4 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -64,7 +64,6 @@ CGOPT_EXP(uint64_t, LargeDataThreshold)
CGOPT(ExceptionHandling, ExceptionModel)
CGOPT_EXP(CodeGenFileType, FileType)
CGOPT(FramePointerKind, FramePointerUsage)
-CGOPT(bool, EnableUnsafeFPMath)
CGOPT(bool, EnableNoInfsFPMath)
CGOPT(bool, EnableNoNaNsFPMath)
CGOPT(bool, EnableNoSignedZerosFPMath)
@@ -219,12 +218,6 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
"Enable frame pointer elimination")));
CGBINDOPT(FramePointerUsage);
- static cl::opt<bool> EnableUnsafeFPMath(
- "enable-unsafe-fp-math",
- cl::desc("Enable optimizations that may decrease FP precision"),
- cl::init(false));
- CGBINDOPT(EnableUnsafeFPMath);
-
static cl::opt<bool> EnableNoInfsFPMath(
"enable-no-infs-fp-math",
cl::desc("Enable FP math optimizations that assume no +-Infs"),
@@ -552,7 +545,6 @@ TargetOptions
codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
TargetOptions Options;
Options.AllowFPOpFusion = getFuseFPOps();
- Options.UnsafeFPMath = getEnableUnsafeFPMath();
Options.NoInfsFPMath = getEnableNoInfsFPMath();
Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
@@ -706,7 +698,6 @@ void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
if (getStackRealign())
NewAttrs.addAttribute("stackrealign");
- HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
diff --git a/llvm/lib/CodeGen/ExpandFp.cpp b/llvm/lib/CodeGen/ExpandFp.cpp
index 2b5ced3..f44eb22 100644
--- a/llvm/lib/CodeGen/ExpandFp.cpp
+++ b/llvm/lib/CodeGen/ExpandFp.cpp
@@ -1108,8 +1108,8 @@ public:
};
} // namespace
-ExpandFpPass::ExpandFpPass(const TargetMachine *TM, CodeGenOptLevel OptLevel)
- : TM(TM), OptLevel(OptLevel) {}
+ExpandFpPass::ExpandFpPass(const TargetMachine &TM, CodeGenOptLevel OptLevel)
+ : TM(&TM), OptLevel(OptLevel) {}
void ExpandFpPass::printPipeline(
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
diff --git a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
index 2cba6f0..0665437 100644
--- a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
@@ -62,7 +62,7 @@ public:
static std::unique_ptr<WorkListMaintainer>
create(Level Lvl, WorkListTy &WorkList, MachineRegisterInfo &MRI);
- virtual ~WorkListMaintainer() = default;
+ ~WorkListMaintainer() override = default;
void reportFullyCreatedInstrs() {
LLVM_DEBUG({
@@ -95,7 +95,7 @@ public:
WorkListMaintainerImpl(WorkListTy &WorkList, MachineRegisterInfo &MRI)
: WorkList(WorkList), MRI(MRI) {}
- virtual ~WorkListMaintainerImpl() = default;
+ ~WorkListMaintainerImpl() override = default;
void reset() override {
DeferList.clear();
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 884c3f1..b49040b 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -139,7 +139,7 @@ class DILocationVerifier : public GISelChangeObserver {
public:
DILocationVerifier() = default;
- ~DILocationVerifier() = default;
+ ~DILocationVerifier() override = default;
const Instruction *getCurrentInst() const { return CurrInst; }
void setCurrentInst(const Instruction *Inst) { CurrInst = Inst; }
@@ -1862,15 +1862,19 @@ bool IRTranslator::translateVectorDeinterleave2Intrinsic(
void IRTranslator::getStackGuard(Register DstReg,
MachineIRBuilder &MIRBuilder) {
+ Value *Global = TLI->getSDagStackGuard(*MF->getFunction().getParent());
+ if (!Global) {
+ LLVMContext &Ctx = MIRBuilder.getContext();
+ Ctx.diagnose(DiagnosticInfoGeneric("unable to lower stackguard"));
+ MIRBuilder.buildUndef(DstReg);
+ return;
+ }
+
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
MRI->setRegClass(DstReg, TRI->getPointerRegClass());
auto MIB =
MIRBuilder.buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
- Value *Global = TLI->getSDagStackGuard(*MF->getFunction().getParent());
- if (!Global)
- return;
-
unsigned AddrSpace = Global->getType()->getPointerAddressSpace();
LLT PtrTy = LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp
index d6e8505..c3e0964 100644
--- a/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/llvm/lib/CodeGen/InlineSpiller.cpp
@@ -721,6 +721,9 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineInstr &MI) {
// Allocate a new register for the remat.
Register NewVReg = Edit->createFrom(Original);
+ // Constrain it to the register class of MI.
+ MRI.constrainRegClass(NewVReg, MRI.getRegClass(VirtReg.reg()));
+
// Finally we can rematerialize OrigMI before MI.
SlotIndex DefIdx =
Edit->rematerializeAt(*MI.getParent(), MI, NewVReg, RM, TRI);
diff --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
index b655375..94e3a82 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
@@ -69,7 +69,7 @@ public:
static char ID;
LiveDebugValuesLegacy();
- ~LiveDebugValuesLegacy() = default;
+ ~LiveDebugValuesLegacy() override = default;
/// Calculate the liveness information for the given machine function.
bool runOnMachineFunction(MachineFunction &MF) override;
diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
index b9ea03f..1c4b2f9 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
@@ -1094,7 +1094,7 @@ public:
/// Default construct and initialize the pass.
VarLocBasedLDV();
- ~VarLocBasedLDV();
+ ~VarLocBasedLDV() override;
/// Print to ostream with a message.
void printVarLocInMBB(const MachineFunction &MF, const VarLocInMBB &V,
diff --git a/llvm/lib/CodeGen/MIR2Vec.cpp b/llvm/lib/CodeGen/MIR2Vec.cpp
index 99be1fc0..00b37e7 100644
--- a/llvm/lib/CodeGen/MIR2Vec.cpp
+++ b/llvm/lib/CodeGen/MIR2Vec.cpp
@@ -42,6 +42,13 @@ static cl::opt<std::string>
cl::opt<float> OpcWeight("mir2vec-opc-weight", cl::Optional, cl::init(1.0),
cl::desc("Weight for machine opcode embeddings"),
cl::cat(MIR2VecCategory));
+cl::opt<float> CommonOperandWeight(
+ "mir2vec-common-operand-weight", cl::Optional, cl::init(1.0),
+ cl::desc("Weight for common operand embeddings"), cl::cat(MIR2VecCategory));
+cl::opt<float>
+ RegOperandWeight("mir2vec-reg-operand-weight", cl::Optional, cl::init(1.0),
+ cl::desc("Weight for register operand embeddings"),
+ cl::cat(MIR2VecCategory));
cl::opt<MIR2VecKind> MIR2VecEmbeddingKind(
"mir2vec-kind", cl::Optional,
cl::values(clEnumValN(MIR2VecKind::Symbolic, "symbolic",
@@ -56,26 +63,52 @@ cl::opt<MIR2VecKind> MIR2VecEmbeddingKind(
// Vocabulary
//===----------------------------------------------------------------------===//
-MIRVocabulary::MIRVocabulary(VocabMap &&OpcodeEntries,
- const TargetInstrInfo &TII)
- : TII(TII) {
+MIRVocabulary::MIRVocabulary(VocabMap &&OpcodeMap, VocabMap &&CommonOperandMap,
+ VocabMap &&PhysicalRegisterMap,
+ VocabMap &&VirtualRegisterMap,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI)
+ : TII(TII), TRI(TRI), MRI(MRI) {
buildCanonicalOpcodeMapping();
-
unsigned CanonicalOpcodeCount = UniqueBaseOpcodeNames.size();
assert(CanonicalOpcodeCount > 0 &&
"No canonical opcodes found for target - invalid vocabulary");
- Layout.OperandBase = CanonicalOpcodeCount;
- generateStorage(OpcodeEntries);
+
+ buildRegisterOperandMapping();
+
+ // Define layout of vocabulary sections
+ Layout.OpcodeBase = 0;
+ Layout.CommonOperandBase = CanonicalOpcodeCount;
+ // We expect same classes for physical and virtual registers
+ Layout.PhyRegBase = Layout.CommonOperandBase + std::size(CommonOperandNames);
+ Layout.VirtRegBase = Layout.PhyRegBase + RegisterOperandNames.size();
+
+ generateStorage(OpcodeMap, CommonOperandMap, PhysicalRegisterMap,
+ VirtualRegisterMap);
Layout.TotalEntries = Storage.size();
}
-Expected<MIRVocabulary> MIRVocabulary::create(VocabMap &&Entries,
- const TargetInstrInfo &TII) {
- if (Entries.empty())
+Expected<MIRVocabulary>
+MIRVocabulary::create(VocabMap &&OpcodeMap, VocabMap &&CommonOperandMap,
+ VocabMap &&PhyRegMap, VocabMap &&VirtRegMap,
+ const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI) {
+ if (OpcodeMap.empty() || CommonOperandMap.empty() || PhyRegMap.empty() ||
+ VirtRegMap.empty())
return createStringError(errc::invalid_argument,
"Empty vocabulary entries provided");
- return MIRVocabulary(std::move(Entries), TII);
+ MIRVocabulary Vocab(std::move(OpcodeMap), std::move(CommonOperandMap),
+ std::move(PhyRegMap), std::move(VirtRegMap), TII, TRI,
+ MRI);
+
+ // Validate Storage after construction
+ if (!Vocab.Storage.isValid())
+ return createStringError(errc::invalid_argument,
+ "Failed to create valid vocabulary storage");
+ Vocab.ZeroEmbedding = Embedding(Vocab.Storage.getDimension(), 0.0);
+ return std::move(Vocab);
}
std::string MIRVocabulary::extractBaseOpcodeName(StringRef InstrName) {
@@ -122,22 +155,74 @@ unsigned MIRVocabulary::getCanonicalOpcodeIndex(unsigned Opcode) const {
return getCanonicalIndexForBaseName(BaseOpcode);
}
+unsigned
+MIRVocabulary::getCanonicalIndexForOperandName(StringRef OperandName) const {
+ auto It = std::find(std::begin(CommonOperandNames),
+ std::end(CommonOperandNames), OperandName);
+ assert(It != std::end(CommonOperandNames) &&
+ "Operand name not found in common operands");
+ return Layout.CommonOperandBase +
+ std::distance(std::begin(CommonOperandNames), It);
+}
+
+unsigned
+MIRVocabulary::getCanonicalIndexForRegisterClass(StringRef RegName,
+ bool IsPhysical) const {
+ auto It = std::find(RegisterOperandNames.begin(), RegisterOperandNames.end(),
+ RegName);
+ assert(It != RegisterOperandNames.end() &&
+ "Register name not found in register operands");
+ unsigned LocalIndex = std::distance(RegisterOperandNames.begin(), It);
+ return (IsPhysical ? Layout.PhyRegBase : Layout.VirtRegBase) + LocalIndex;
+}
+
std::string MIRVocabulary::getStringKey(unsigned Pos) const {
assert(Pos < Layout.TotalEntries && "Position out of bounds in vocabulary");
- // For now, all entries are opcodes since we only have one section
- if (Pos < Layout.OperandBase && Pos < UniqueBaseOpcodeNames.size()) {
+ // Handle opcodes section
+ if (Pos < Layout.CommonOperandBase) {
// Convert canonical index back to base opcode name
auto It = UniqueBaseOpcodeNames.begin();
std::advance(It, Pos);
+ assert(It != UniqueBaseOpcodeNames.end() &&
+ "Canonical index out of bounds in opcode section");
return *It;
}
- llvm_unreachable("Invalid position in vocabulary");
- return "";
+ auto getLocalIndex = [](unsigned Pos, size_t BaseOffset, size_t Bound,
+ const char *Msg) {
+ unsigned LocalIndex = Pos - BaseOffset;
+ assert(LocalIndex < Bound && Msg);
+ return LocalIndex;
+ };
+
+ // Handle common operands section
+ if (Pos < Layout.PhyRegBase) {
+ unsigned LocalIndex = getLocalIndex(
+ Pos, Layout.CommonOperandBase, std::size(CommonOperandNames),
+ "Local index out of bounds in common operands");
+ return CommonOperandNames[LocalIndex].str();
+ }
+
+ // Handle physical registers section
+ if (Pos < Layout.VirtRegBase) {
+ unsigned LocalIndex =
+ getLocalIndex(Pos, Layout.PhyRegBase, RegisterOperandNames.size(),
+ "Local index out of bounds in physical registers");
+ return "PhyReg_" + RegisterOperandNames[LocalIndex];
+ }
+
+ // Handle virtual registers section
+ unsigned LocalIndex =
+ getLocalIndex(Pos, Layout.VirtRegBase, RegisterOperandNames.size(),
+ "Local index out of bounds in virtual registers");
+ return "VirtReg_" + RegisterOperandNames[LocalIndex];
}
-void MIRVocabulary::generateStorage(const VocabMap &OpcodeMap) {
+void MIRVocabulary::generateStorage(const VocabMap &OpcodeMap,
+ const VocabMap &CommonOperandsMap,
+ const VocabMap &PhyRegMap,
+ const VocabMap &VirtRegMap) {
// Helper for handling missing entities in the vocabulary.
// Currently, we use a zero vector. In the future, we will throw an error to
@@ -151,14 +236,14 @@ void MIRVocabulary::generateStorage(const VocabMap &OpcodeMap) {
// Initialize opcode embeddings section
unsigned EmbeddingDim = OpcodeMap.begin()->second.size();
- std::vector<Embedding> OpcodeEmbeddings(Layout.OperandBase,
+ std::vector<Embedding> OpcodeEmbeddings(Layout.CommonOperandBase,
Embedding(EmbeddingDim));
// Populate opcode embeddings using canonical mapping
for (auto COpcodeName : UniqueBaseOpcodeNames) {
if (auto It = OpcodeMap.find(COpcodeName); It != OpcodeMap.end()) {
auto COpcodeIndex = getCanonicalIndexForBaseName(COpcodeName);
- assert(COpcodeIndex < Layout.OperandBase &&
+ assert(COpcodeIndex < Layout.CommonOperandBase &&
"Canonical index out of bounds");
OpcodeEmbeddings[COpcodeIndex] = It->second;
} else {
@@ -166,8 +251,39 @@ void MIRVocabulary::generateStorage(const VocabMap &OpcodeMap) {
}
}
- // TODO: Add operand/argument embeddings as additional sections
- // This will require extending the vocabulary format and layout
+ // Initialize common operand embeddings section
+ std::vector<Embedding> CommonOperandEmbeddings(std::size(CommonOperandNames),
+ Embedding(EmbeddingDim));
+ unsigned OperandIndex = 0;
+ for (const auto &CommonOperandName : CommonOperandNames) {
+ if (auto It = CommonOperandsMap.find(CommonOperandName.str());
+ It != CommonOperandsMap.end()) {
+ CommonOperandEmbeddings[OperandIndex] = It->second;
+ } else {
+ handleMissingEntity(CommonOperandName);
+ }
+ ++OperandIndex;
+ }
+
+ // Helper lambda for creating register operand embeddings
+ auto createRegisterEmbeddings = [&](const VocabMap &RegMap) {
+ std::vector<Embedding> RegEmbeddings(TRI.getNumRegClasses(),
+ Embedding(EmbeddingDim));
+ unsigned RegOperandIndex = 0;
+ for (const auto &RegOperandName : RegisterOperandNames) {
+ if (auto It = RegMap.find(RegOperandName); It != RegMap.end())
+ RegEmbeddings[RegOperandIndex] = It->second;
+ else
+ handleMissingEntity(RegOperandName);
+ ++RegOperandIndex;
+ }
+ return RegEmbeddings;
+ };
+
+ // Initialize register operand embeddings sections
+ std::vector<Embedding> PhyRegEmbeddings = createRegisterEmbeddings(PhyRegMap);
+ std::vector<Embedding> VirtRegEmbeddings =
+ createRegisterEmbeddings(VirtRegMap);
// Scale the vocabulary sections based on the provided weights
auto scaleVocabSection = [](std::vector<Embedding> &Embeddings,
@@ -176,9 +292,20 @@ void MIRVocabulary::generateStorage(const VocabMap &OpcodeMap) {
Embedding *= Weight;
};
scaleVocabSection(OpcodeEmbeddings, OpcWeight);
-
- std::vector<std::vector<Embedding>> Sections(1);
- Sections[0] = std::move(OpcodeEmbeddings);
+ scaleVocabSection(CommonOperandEmbeddings, CommonOperandWeight);
+ scaleVocabSection(PhyRegEmbeddings, RegOperandWeight);
+ scaleVocabSection(VirtRegEmbeddings, RegOperandWeight);
+
+ std::vector<std::vector<Embedding>> Sections(
+ static_cast<unsigned>(Section::MaxSections));
+ Sections[static_cast<unsigned>(Section::Opcodes)] =
+ std::move(OpcodeEmbeddings);
+ Sections[static_cast<unsigned>(Section::CommonOperands)] =
+ std::move(CommonOperandEmbeddings);
+ Sections[static_cast<unsigned>(Section::PhyRegisters)] =
+ std::move(PhyRegEmbeddings);
+ Sections[static_cast<unsigned>(Section::VirtRegisters)] =
+ std::move(VirtRegEmbeddings);
Storage = ir2vec::VocabStorage(std::move(Sections));
}
@@ -199,46 +326,130 @@ void MIRVocabulary::buildCanonicalOpcodeMapping() {
<< " unique base opcodes\n");
}
-Expected<MIRVocabulary>
-MIRVocabulary::createDummyVocabForTest(const TargetInstrInfo &TII,
- unsigned Dim) {
+void MIRVocabulary::buildRegisterOperandMapping() {
+ // Check if already built
+ if (!RegisterOperandNames.empty())
+ return;
+
+ for (unsigned RC = 0; RC < TRI.getNumRegClasses(); ++RC) {
+ const TargetRegisterClass *RegClass = TRI.getRegClass(RC);
+ if (!RegClass)
+ continue;
+
+ // Get the register class name
+ StringRef ClassName = TRI.getRegClassName(RegClass);
+ RegisterOperandNames.push_back(ClassName.str());
+ }
+}
+
+unsigned MIRVocabulary::getCommonOperandIndex(
+ MachineOperand::MachineOperandType OperandType) const {
+ assert(OperandType != MachineOperand::MO_Register &&
+ "Expected non-register operand type");
+ assert(OperandType > MachineOperand::MO_Register &&
+ OperandType < MachineOperand::MO_Last && "Operand type out of bounds");
+ return static_cast<unsigned>(OperandType) - 1;
+}
+
+unsigned MIRVocabulary::getRegisterOperandIndex(Register Reg) const {
+ assert(!RegisterOperandNames.empty() && "Register operand mapping not built");
+ assert(Reg.isValid() && "Invalid register; not expected here");
+ assert((Reg.isPhysical() || Reg.isVirtual()) &&
+ "Expected a physical or virtual register");
+
+ const TargetRegisterClass *RegClass = nullptr;
+
+ // For physical registers, use TRI to get minimal register class as a
+ // physical register can belong to multiple classes. For virtual
+ // registers, use MRI to uniquely identify the assigned register class.
+ if (Reg.isPhysical())
+ RegClass = TRI.getMinimalPhysRegClass(Reg);
+ else
+ RegClass = MRI.getRegClass(Reg);
+
+ if (RegClass)
+ return RegClass->getID();
+ // Fallback for registers without a class (shouldn't happen)
+ llvm_unreachable("Register operand without a valid register class");
+ return 0;
+}
+
+Expected<MIRVocabulary> MIRVocabulary::createDummyVocabForTest(
+ const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI, unsigned Dim) {
assert(Dim > 0 && "Dimension must be greater than zero");
float DummyVal = 0.1f;
- // Create dummy embeddings for all canonical opcode names
- VocabMap DummyVocabMap;
+ VocabMap DummyOpcMap, DummyOperandMap, DummyPhyRegMap, DummyVirtRegMap;
+
+ // Process opcodes directly without creating temporary vocabulary
for (unsigned Opcode = 0; Opcode < TII.getNumOpcodes(); ++Opcode) {
std::string BaseOpcode = extractBaseOpcodeName(TII.getName(Opcode));
- if (DummyVocabMap.count(BaseOpcode) == 0) {
- // Only add if not already present
- DummyVocabMap[BaseOpcode] = Embedding(Dim, DummyVal);
+ if (DummyOpcMap.count(BaseOpcode) == 0) { // Only add if not already present
+ DummyOpcMap[BaseOpcode] = Embedding(Dim, DummyVal);
DummyVal += 0.1f;
}
}
- // Create and return vocabulary with dummy embeddings
- return MIRVocabulary::create(std::move(DummyVocabMap), TII);
+ // Add common operands
+ for (const auto &CommonOperandName : CommonOperandNames) {
+ DummyOperandMap[CommonOperandName.str()] = Embedding(Dim, DummyVal);
+ DummyVal += 0.1f;
+ }
+
+ // Process register classes directly
+ for (unsigned RC = 0; RC < TRI.getNumRegClasses(); ++RC) {
+ const TargetRegisterClass *RegClass = TRI.getRegClass(RC);
+ if (!RegClass)
+ continue;
+
+ std::string ClassName = TRI.getRegClassName(RegClass);
+ DummyPhyRegMap[ClassName] = Embedding(Dim, DummyVal);
+ DummyVirtRegMap[ClassName] = Embedding(Dim, DummyVal);
+ DummyVal += 0.1f;
+ }
+
+ // Create vocabulary directly without temporary instance
+ return MIRVocabulary::create(
+ std::move(DummyOpcMap), std::move(DummyOperandMap),
+ std::move(DummyPhyRegMap), std::move(DummyVirtRegMap), TII, TRI, MRI);
}
//===----------------------------------------------------------------------===//
-// MIR2VecVocabLegacyAnalysis Implementation
+// MIR2VecVocabProvider and MIR2VecVocabLegacyAnalysis
//===----------------------------------------------------------------------===//
-char MIR2VecVocabLegacyAnalysis::ID = 0;
-INITIALIZE_PASS_BEGIN(MIR2VecVocabLegacyAnalysis, "mir2vec-vocab-analysis",
- "MIR2Vec Vocabulary Analysis", false, true)
-INITIALIZE_PASS_DEPENDENCY(MachineModuleInfoWrapperPass)
-INITIALIZE_PASS_END(MIR2VecVocabLegacyAnalysis, "mir2vec-vocab-analysis",
- "MIR2Vec Vocabulary Analysis", false, true)
+Expected<mir2vec::MIRVocabulary>
+MIR2VecVocabProvider::getVocabulary(const Module &M) {
+ VocabMap OpcVocab, CommonOperandVocab, PhyRegVocabMap, VirtRegVocabMap;
-StringRef MIR2VecVocabLegacyAnalysis::getPassName() const {
- return "MIR2Vec Vocabulary Analysis";
+ if (Error Err = readVocabulary(OpcVocab, CommonOperandVocab, PhyRegVocabMap,
+ VirtRegVocabMap))
+ return std::move(Err);
+
+ for (const auto &F : M) {
+ if (F.isDeclaration())
+ continue;
+
+ if (auto *MF = MMI.getMachineFunction(F)) {
+ auto &Subtarget = MF->getSubtarget();
+ if (const auto *TII = Subtarget.getInstrInfo())
+ if (const auto *TRI = Subtarget.getRegisterInfo())
+ return mir2vec::MIRVocabulary::create(
+ std::move(OpcVocab), std::move(CommonOperandVocab),
+ std::move(PhyRegVocabMap), std::move(VirtRegVocabMap), *TII, *TRI,
+ MF->getRegInfo());
+ }
+ }
+ return createStringError(errc::invalid_argument,
+ "No machine functions found in module");
}
-Error MIR2VecVocabLegacyAnalysis::readVocabulary() {
- // TODO: Extend vocabulary format to support multiple sections
- // (opcodes, operands, etc.) similar to IR2Vec structure
+Error MIR2VecVocabProvider::readVocabulary(VocabMap &OpcodeVocab,
+ VocabMap &CommonOperandVocab,
+ VocabMap &PhyRegVocabMap,
+ VocabMap &VirtRegVocabMap) {
if (VocabFile.empty())
return createStringError(
errc::invalid_argument,
@@ -255,39 +466,47 @@ Error MIR2VecVocabLegacyAnalysis::readVocabulary() {
if (!ParsedVocabValue)
return ParsedVocabValue.takeError();
- unsigned Dim = 0;
+ unsigned OpcodeDim = 0, CommonOperandDim = 0, PhyRegOperandDim = 0,
+ VirtRegOperandDim = 0;
if (auto Err = ir2vec::VocabStorage::parseVocabSection(
- "entities", *ParsedVocabValue, StrVocabMap, Dim))
+ "Opcodes", *ParsedVocabValue, OpcodeVocab, OpcodeDim))
return Err;
- return Error::success();
-}
-
-Expected<mir2vec::MIRVocabulary>
-MIR2VecVocabLegacyAnalysis::getMIR2VecVocabulary(const Module &M) {
- if (StrVocabMap.empty()) {
- if (Error Err = readVocabulary()) {
- return std::move(Err);
- }
- }
+ if (auto Err = ir2vec::VocabStorage::parseVocabSection(
+ "CommonOperands", *ParsedVocabValue, CommonOperandVocab,
+ CommonOperandDim))
+ return Err;
- // Get machine module info to access machine functions and target info
- MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+ if (auto Err = ir2vec::VocabStorage::parseVocabSection(
+ "PhysicalRegisters", *ParsedVocabValue, PhyRegVocabMap,
+ PhyRegOperandDim))
+ return Err;
- // Find first available machine function to get target instruction info
- for (const auto &F : M) {
- if (F.isDeclaration())
- continue;
+ if (auto Err = ir2vec::VocabStorage::parseVocabSection(
+ "VirtualRegisters", *ParsedVocabValue, VirtRegVocabMap,
+ VirtRegOperandDim))
+ return Err;
- if (auto *MF = MMI.getMachineFunction(F)) {
- const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
- return mir2vec::MIRVocabulary::create(std::move(StrVocabMap), *TII);
- }
+ // All sections must have the same embedding dimension
+ if (!(OpcodeDim == CommonOperandDim && CommonOperandDim == PhyRegOperandDim &&
+ PhyRegOperandDim == VirtRegOperandDim)) {
+ return createStringError(
+ errc::illegal_byte_sequence,
+ "MIR2Vec vocabulary sections have different dimensions");
}
- // No machine functions available - return error
- return createStringError(errc::invalid_argument,
- "No machine functions found in module");
+ return Error::success();
+}
+
+char MIR2VecVocabLegacyAnalysis::ID = 0;
+INITIALIZE_PASS_BEGIN(MIR2VecVocabLegacyAnalysis, "mir2vec-vocab-analysis",
+ "MIR2Vec Vocabulary Analysis", false, true)
+INITIALIZE_PASS_DEPENDENCY(MachineModuleInfoWrapperPass)
+INITIALIZE_PASS_END(MIR2VecVocabLegacyAnalysis, "mir2vec-vocab-analysis",
+ "MIR2Vec Vocabulary Analysis", false, true)
+
+StringRef MIR2VecVocabLegacyAnalysis::getPassName() const {
+ return "MIR2Vec Vocabulary Analysis";
}
//===----------------------------------------------------------------------===//
@@ -351,9 +570,14 @@ Embedding SymbolicMIREmbedder::computeEmbeddings(const MachineInstr &MI) const {
if (MI.isDebugInstr())
return Embedding(Dimension, 0);
- // Todo: Add operand/argument contributions
+ // Opcode embedding
+ Embedding InstructionEmbedding = Vocab[MI.getOpcode()];
+
+ // Add operand contributions
+ for (const MachineOperand &MO : MI.operands())
+ InstructionEmbedding += Vocab[MO];
- return Vocab[MI.getOpcode()];
+ return InstructionEmbedding;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 1cb57a4..ba0b025 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -1137,7 +1137,7 @@ public:
MF.setDelegate(this);
}
- ~SlotIndexUpdateDelegate() {
+ ~SlotIndexUpdateDelegate() override {
MF.resetDelegate(this);
for (auto MI : Insertions)
Indexes->insertMachineInstrInMaps(*MI);
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index 7acddff..729e73c 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -932,12 +932,11 @@ void MachineLICMImpl::InitRegPressure(MachineBasicBlock *BB) {
void MachineLICMImpl::UpdateRegPressure(const MachineInstr *MI,
bool ConsiderUnseenAsDef) {
auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/true, ConsiderUnseenAsDef);
- for (const auto &RPIdAndCost : Cost) {
- unsigned Class = RPIdAndCost.first;
- if (static_cast<int>(RegPressure[Class]) < -RPIdAndCost.second)
+ for (const auto &[Class, Weight] : Cost) {
+ if (static_cast<int>(RegPressure[Class]) < -Weight)
RegPressure[Class] = 0;
else
- RegPressure[Class] += RPIdAndCost.second;
+ RegPressure[Class] += Weight;
}
}
@@ -1215,11 +1214,10 @@ bool MachineLICMImpl::IsCheapInstruction(MachineInstr &MI) const {
/// given cost matrix can cause high register pressure.
bool MachineLICMImpl::CanCauseHighRegPressure(
const SmallDenseMap<unsigned, int> &Cost, bool CheapInstr) {
- for (const auto &RPIdAndCost : Cost) {
- if (RPIdAndCost.second <= 0)
+ for (const auto &[Class, Weight] : Cost) {
+ if (Weight <= 0)
continue;
- unsigned Class = RPIdAndCost.first;
int Limit = RegLimit[Class];
// Don't hoist cheap instructions if they would increase register pressure,
@@ -1228,7 +1226,7 @@ bool MachineLICMImpl::CanCauseHighRegPressure(
return true;
for (const auto &RP : BackTrace)
- if (static_cast<int>(RP[Class]) + RPIdAndCost.second >= Limit)
+ if (static_cast<int>(RP[Class]) + Weight >= Limit)
return true;
}
@@ -1246,8 +1244,8 @@ void MachineLICMImpl::UpdateBackTraceRegPressure(const MachineInstr *MI) {
// Update register pressure of blocks from loop header to current block.
for (auto &RP : BackTrace)
- for (const auto &RPIdAndCost : Cost)
- RP[RPIdAndCost.first] += RPIdAndCost.second;
+ for (const auto &[Class, Weight] : Cost)
+ RP[Class] += Weight;
}
/// Return true if it is potentially profitable to hoist the given loop
diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
index e1d39d6..493d8df 100644
--- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
@@ -196,7 +196,7 @@ public:
CopyRewriter(MachineInstr &MI) : Rewriter(MI) {
assert(MI.isCopy() && "Expected copy instruction");
}
- virtual ~CopyRewriter() = default;
+ ~CopyRewriter() override = default;
bool getNextRewritableSource(RegSubRegPair &Src,
RegSubRegPair &Dst) override {
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index f54e2f2..620d3d3 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -593,7 +593,7 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
case Intrinsic::log:
Changed |= forEachCall(F, [&](CallInst *CI) {
Type *Ty = CI->getArgOperand(0)->getType();
- if (!isa<ScalableVectorType>(Ty))
+ if (!TM || !isa<ScalableVectorType>(Ty))
return false;
const TargetLowering *TL = TM->getSubtargetImpl(F)->getTargetLowering();
unsigned Op = TL->IntrinsicIDToISD(F.getIntrinsicID());
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 310d35d..d2ea652 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2476,16 +2476,17 @@ static bool canFoldInAddressingMode(SDNode *N, SDNode *Use, SelectionDAG &DAG,
/// masked vector operation if the target supports it.
static SDValue foldSelectWithIdentityConstant(SDNode *N, SelectionDAG &DAG,
bool ShouldCommuteOperands) {
- // Match a select as operand 1. The identity constant that we are looking for
- // is only valid as operand 1 of a non-commutative binop.
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
+
+ // Match a select as operand 1. The identity constant that we are looking for
+ // is only valid as operand 1 of a non-commutative binop.
if (ShouldCommuteOperands)
std::swap(N0, N1);
- unsigned SelOpcode = N1.getOpcode();
- if ((SelOpcode != ISD::VSELECT && SelOpcode != ISD::SELECT) ||
- !N1.hasOneUse())
+ SDValue Cond, TVal, FVal;
+ if (!sd_match(N1, m_OneUse(m_SelectLike(m_Value(Cond), m_Value(TVal),
+ m_Value(FVal)))))
return SDValue();
// We can't hoist all instructions because of immediate UB (not speculatable).
@@ -2493,11 +2494,9 @@ static SDValue foldSelectWithIdentityConstant(SDNode *N, SelectionDAG &DAG,
if (!DAG.isSafeToSpeculativelyExecuteNode(N))
return SDValue();
+ unsigned SelOpcode = N1.getOpcode();
unsigned Opcode = N->getOpcode();
EVT VT = N->getValueType(0);
- SDValue Cond = N1.getOperand(0);
- SDValue TVal = N1.getOperand(1);
- SDValue FVal = N1.getOperand(2);
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// This transform increases uses of N0, so freeze it to be safe.
@@ -13856,12 +13855,11 @@ static SDValue tryToFoldExtendSelectLoad(SDNode *N, const TargetLowering &TLI,
Opcode == ISD::ANY_EXTEND) &&
"Expected EXTEND dag node in input!");
- if (!(N0->getOpcode() == ISD::SELECT || N0->getOpcode() == ISD::VSELECT) ||
- !N0.hasOneUse())
+ SDValue Cond, Op1, Op2;
+ if (!sd_match(N0, m_OneUse(m_SelectLike(m_Value(Cond), m_Value(Op1),
+ m_Value(Op2)))))
return SDValue();
- SDValue Op1 = N0->getOperand(1);
- SDValue Op2 = N0->getOperand(2);
if (!isCompatibleLoad(Op1, Opcode) || !isCompatibleLoad(Op2, Opcode))
return SDValue();
@@ -13883,7 +13881,7 @@ static SDValue tryToFoldExtendSelectLoad(SDNode *N, const TargetLowering &TLI,
SDValue Ext1 = DAG.getNode(Opcode, DL, VT, Op1);
SDValue Ext2 = DAG.getNode(Opcode, DL, VT, Op2);
- return DAG.getSelect(DL, VT, N0->getOperand(0), Ext1, Ext2);
+ return DAG.getSelect(DL, VT, Cond, Ext1, Ext2);
}
/// Try to fold a sext/zext/aext dag node into a ConstantSDNode or
@@ -17462,8 +17460,8 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
// fold (fsub (fpext (fneg (fmul, x, y))), z)
// -> (fneg (fma (fpext x), (fpext y), z))
// Note: This could be removed with appropriate canonicalization of the
- // input expression into (fneg (fadd (fpext (fmul, x, y)), z). However, the
- // orthogonal flags -fp-contract=fast and -enable-unsafe-fp-math prevent
+ // input expression into (fneg (fadd (fpext (fmul, x, y)), z)). However, the
+ // command line flag -fp-contract=fast and fast-math flag contract prevent
// from implementing the canonicalization in visitFSUB.
if (matcher.match(N0, ISD::FP_EXTEND)) {
SDValue N00 = N0.getOperand(0);
@@ -17487,7 +17485,7 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
// -> (fneg (fma (fpext x)), (fpext y), z)
// Note: This could be removed with appropriate canonicalization of the
// input expression into (fneg (fadd (fpext (fmul, x, y)), z). However, the
- // orthogonal flags -fp-contract=fast and -enable-unsafe-fp-math prevent
+ // command line flag -fp-contract=fast and fast-math flag contract prevent
// from implementing the canonicalization in visitFSUB.
if (matcher.match(N0, ISD::FNEG)) {
SDValue N00 = N0.getOperand(0);
@@ -29620,13 +29618,14 @@ static SDValue takeInexpensiveLog2(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
}
// c ? X : Y -> c ? Log2(X) : Log2(Y)
- if ((Op.getOpcode() == ISD::SELECT || Op.getOpcode() == ISD::VSELECT) &&
- Op.hasOneUse()) {
- if (SDValue LogX = takeInexpensiveLog2(DAG, DL, VT, Op.getOperand(1),
- Depth + 1, AssumeNonZero))
- if (SDValue LogY = takeInexpensiveLog2(DAG, DL, VT, Op.getOperand(2),
- Depth + 1, AssumeNonZero))
- return DAG.getSelect(DL, VT, Op.getOperand(0), LogX, LogY);
+ SDValue Cond, TVal, FVal;
+ if (sd_match(Op, m_OneUse(m_SelectLike(m_Value(Cond), m_Value(TVal),
+ m_Value(FVal))))) {
+ if (SDValue LogX =
+ takeInexpensiveLog2(DAG, DL, VT, TVal, Depth + 1, AssumeNonZero))
+ if (SDValue LogY =
+ takeInexpensiveLog2(DAG, DL, VT, FVal, Depth + 1, AssumeNonZero))
+ return DAG.getSelect(DL, VT, Cond, LogX, LogY);
}
// log2(umin(X, Y)) -> umin(log2(X), log2(Y))
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 603dc34..9656a30 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -890,6 +890,7 @@ private:
SDValue ScalarizeVecRes_UnaryOpWithExtraInput(SDNode *N);
SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N);
SDValue ScalarizeVecRes_LOAD(LoadSDNode *N);
+ SDValue ScalarizeVecRes_ATOMIC_LOAD(AtomicSDNode *N);
SDValue ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N);
SDValue ScalarizeVecRes_VSELECT(SDNode *N);
SDValue ScalarizeVecRes_SELECT(SDNode *N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 3b5f83f..bb4a8d9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -69,6 +69,9 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
R = ScalarizeVecRes_UnaryOpWithExtraInput(N);
break;
case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
+ case ISD::ATOMIC_LOAD:
+ R = ScalarizeVecRes_ATOMIC_LOAD(cast<AtomicSDNode>(N));
+ break;
case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break;
case ISD::SCALAR_TO_VECTOR: R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break;
case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_InregOp(N); break;
@@ -475,6 +478,18 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
return Op;
}
+SDValue DAGTypeLegalizer::ScalarizeVecRes_ATOMIC_LOAD(AtomicSDNode *N) {
+ SDValue Result = DAG.getAtomicLoad(
+ N->getExtensionType(), SDLoc(N), N->getMemoryVT().getVectorElementType(),
+ N->getValueType(0).getVectorElementType(), N->getChain(), N->getBasePtr(),
+ N->getMemOperand());
+
+ // Legalize the chain result - switch anything that used the old chain to
+ // use the new one.
+ ReplaceValueWith(SDValue(N, 1), Result.getValue(1));
+ return Result;
+}
+
SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
assert(N->isUnindexed() && "Indexed vector load?");
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 90edaf3..379242e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -8620,7 +8620,10 @@ SDValue SelectionDAG::getMemBasePlusOffset(SDValue Ptr, SDValue Offset,
if (TLI->shouldPreservePtrArith(this->getMachineFunction().getFunction(),
BasePtrVT))
return getNode(ISD::PTRADD, DL, BasePtrVT, Ptr, Offset, Flags);
- return getNode(ISD::ADD, DL, BasePtrVT, Ptr, Offset, Flags);
+ // InBounds only applies to PTRADD, don't set it if we generate ADD.
+ SDNodeFlags AddFlags = Flags;
+ AddFlags.setInBounds(false);
+ return getNode(ISD::ADD, DL, BasePtrVT, Ptr, Offset, AddFlags);
}
/// Returns true if memcpy source is constant data.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 20a0efd..bfa566a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1977,8 +1977,13 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
if (const Instruction *Inst = dyn_cast<Instruction>(V)) {
Register InReg = FuncInfo.InitializeRegForValue(Inst);
+ std::optional<CallingConv::ID> CallConv;
+ auto *CI = dyn_cast<CallInst>(Inst);
+ if (CI && !CI->isInlineAsm())
+ CallConv = CI->getCallingConv();
+
RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg,
- Inst->getType(), std::nullopt);
+ Inst->getType(), CallConv);
SDValue Chain = DAG.getEntryNode();
return RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
}
@@ -3126,12 +3131,16 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
if (TLI.useLoadStackGuardNode(M)) {
Guard = getLoadStackGuard(DAG, dl, Chain);
} else {
- const Value *IRGuard = TLI.getSDagStackGuard(M);
- SDValue GuardPtr = getValue(IRGuard);
-
- Guard = DAG.getLoad(PtrMemTy, dl, Chain, GuardPtr,
- MachinePointerInfo(IRGuard, 0), Align,
- MachineMemOperand::MOVolatile);
+ if (const Value *IRGuard = TLI.getSDagStackGuard(M)) {
+ SDValue GuardPtr = getValue(IRGuard);
+ Guard = DAG.getLoad(PtrMemTy, dl, Chain, GuardPtr,
+ MachinePointerInfo(IRGuard, 0), Align,
+ MachineMemOperand::MOVolatile);
+ } else {
+ LLVMContext &Ctx = *DAG.getContext();
+ Ctx.diagnose(DiagnosticInfoGeneric("unable to lower stackguard"));
+ Guard = DAG.getPOISON(PtrMemTy);
+ }
}
// Perform the comparison via a getsetcc.
@@ -4381,6 +4390,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
if (NW.hasNoUnsignedWrap() ||
(int64_t(Offset) >= 0 && NW.hasNoUnsignedSignedWrap()))
Flags |= SDNodeFlags::NoUnsignedWrap;
+ Flags.setInBounds(NW.isInBounds());
N = DAG.getMemBasePlusOffset(
N, DAG.getConstant(Offset, dl, N.getValueType()), dl, Flags);
@@ -4424,6 +4434,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
if (NW.hasNoUnsignedWrap() ||
(Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()))
Flags.setNoUnsignedWrap(true);
+ Flags.setInBounds(NW.isInBounds());
OffsVal = DAG.getSExtOrTrunc(OffsVal, dl, N.getValueType());
@@ -4493,6 +4504,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
// pointer index type (add nuw).
SDNodeFlags AddFlags;
AddFlags.setNoUnsignedWrap(NW.hasNoUnsignedWrap());
+ AddFlags.setInBounds(NW.isInBounds());
N = DAG.getMemBasePlusOffset(N, IdxN, dl, AddFlags);
}
@@ -7319,6 +7331,13 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
Res = DAG.getPtrExtOrTrunc(Res, sdl, PtrTy);
} else {
const Value *Global = TLI.getSDagStackGuard(M);
+ if (!Global) {
+ LLVMContext &Ctx = *DAG.getContext();
+ Ctx.diagnose(DiagnosticInfoGeneric("unable to lower stackguard"));
+ setValue(&I, DAG.getPOISON(PtrTy));
+ return;
+ }
+
Align Align = DAG.getDataLayout().getPrefTypeAlign(Global->getType());
Res = DAG.getLoad(PtrTy, sdl, Chain, getValue(Global),
MachinePointerInfo(Global, 0), Align,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 39cbfad..77377d3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -689,6 +689,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
if (getFlags().hasSameSign())
OS << " samesign";
+ if (getFlags().hasInBounds())
+ OS << " inbounds";
+
if (getFlags().hasNonNeg())
OS << " nneg";
diff --git a/llvm/lib/CodeGen/ShrinkWrap.cpp b/llvm/lib/CodeGen/ShrinkWrap.cpp
index 826e412..8358105 100644
--- a/llvm/lib/CodeGen/ShrinkWrap.cpp
+++ b/llvm/lib/CodeGen/ShrinkWrap.cpp
@@ -319,7 +319,7 @@ bool ShrinkWrapImpl::useOrDefCSROrFI(const MachineInstr &MI, RegScavenger *RS,
return isa<GlobalValue>(UO);
}
if (const PseudoSourceValue *PSV = Op->getPseudoValue())
- return PSV->isJumpTable();
+ return PSV->isJumpTable() || PSV->isConstantPool();
return false;
};
// Load/store operations may access the stack indirectly when we previously
diff --git a/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
index 5eb86e7..049efe8 100644
--- a/llvm/lib/CodeGen/TargetOptionsImpl.cpp
+++ b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
@@ -51,7 +51,7 @@ bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const {
/// HonorSignDependentRoundingFPMath - Return true if the codegen must assume
/// that the rounding mode of the FPU can change from its default.
bool TargetOptions::HonorSignDependentRoundingFPMath() const {
- return !UnsafeFPMath && HonorSignDependentRoundingFPMathOption;
+ return HonorSignDependentRoundingFPMathOption;
}
/// NOTE: There are targets that still do not support the debug entry values