[llvm-branch-commits] [AutoUpgrade][AMDGPU] Adjust AS7 and AS9 address width to 48 bits (PR #137418)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/137418 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [AutoUpgrade][AMDGPU] Adjust AS7 and AS9 address width to 48 bits (PR #137418)
https://github.com/arichardson edited https://github.com/llvm/llvm-project/pull/137418 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang-tools-extra] [llvm] [BOLT][NFCI] Switch heatmap to using parsed basic/branch events (PR #136531)
https://github.com/aaupov edited https://github.com/llvm/llvm-project/pull/136531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang-tools-extra] [llvm] [BOLT] Switch heatmap to using parsed basic/branch events (PR #136531)
https://github.com/aaupov edited https://github.com/llvm/llvm-project/pull/136531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang-tools-extra] [llvm] [BOLT] Use parsed basic/branch events for heatmap (PR #136531)
https://github.com/aaupov edited https://github.com/llvm/llvm-project/pull/136531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang-tools-extra] [llvm] [BOLT] Use parsed basic/branch events for heatmap (PR #136531)
https://github.com/aaupov edited https://github.com/llvm/llvm-project/pull/136531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang-tools-extra] [llvm] [BOLT] Use parsed basic/branch events for heatmap (PR #136531)
https://github.com/aaupov edited https://github.com/llvm/llvm-project/pull/136531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -252,13 +252,13 @@ define amdgpu_kernel void @indirect_calls_none_agpr(i1 %cond) { } -attributes #0 = { "amdgpu-agpr-alloc"="0" } +attributes #0 = { "amdgpu-no-agpr" } arsenm wrote: Broken revert to old attribute https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
@@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { + SDLoc dl(LD); + + EVT MemoryVT = LD->getMemoryVT(); + unsigned NumElts = MemoryVT.getVectorMinNumElements(); + + EVT IntMemoryVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts); + EVT ElemVT = + EVT::getVectorVT(*DAG.getContext(), MemoryVT.getVectorElementType(), 1); + + // Create a single atomic to load all the elements at once. + SDValue Atomic = + DAG.getAtomic(ISD::ATOMIC_LOAD, dl, IntMemoryVT, IntMemoryVT, +LD->getChain(), LD->getBasePtr(), LD->getMemOperand()); + + // Instead of splitting, put all the elements back into a vector. + SmallVector Ops; + for (unsigned i = 0; i < NumElts; ++i) { +SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Atomic, + DAG.getVectorIdxConstant(i, dl)); +Elt = DAG.getBitcast(ElemVT, Elt); +Ops.push_back(Elt); + } + SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MemoryVT, Ops); + + ReplaceValueWith(SDValue(LD, 0), Concat); jofrn wrote: How do you associate both chain uses at once? Doesn't that require a TokenFactor? https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1108,47 +1108,25 @@ struct AAAMDWavesPerEU : public AAAMDSizeRangeAttribute { Function *F = getAssociatedFunction(); auto &InfoCache = static_cast(A.getInfoCache()); -auto TakeRange = [&](std::pair R) { - auto [Min, Max] = R; - ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); - IntegerRangeState RangeState(Range); - clampStateAndIndicateChange(this->getState(), RangeState); - indicateOptimisticFixpoint(); -}; - -std::pair MaxWavesPerEURange{ -1U, InfoCache.getMaxWavesPerEU(*F)}; - // If the attribute exists, we will honor it if it is not the default. if (auto Attr = InfoCache.getWavesPerEUAttr(*F)) { + std::pair MaxWavesPerEURange{ + 1U, InfoCache.getMaxWavesPerEU(*F)}; if (*Attr != MaxWavesPerEURange) { -TakeRange(*Attr); +auto [Min, Max] = *Attr; +ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); +IntegerRangeState RangeState(Range); +this->getState() = RangeState; +indicateOptimisticFixpoint(); shiltian wrote: It will not because we will not run attributor more than once thus there is no intermediate values added. If a function has the attribute, it means it has to be a kernel function (at least for now since we only allow the attribute on kernel functions) and the value is chosen by users so we will honor it. https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/138112 - This cleans up moves cir floating point type constraints to dedicated constraints file, and fixes long double verifier to use constraints directly. - Renames `CIR_AnyFloat` to `CIR_AnyFloatType`. This mirrors inbubator changes from https://github.com/llvm/clangir/pull/1594 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
@@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { + SDLoc dl(LD); + + EVT MemoryVT = LD->getMemoryVT(); + unsigned NumElts = MemoryVT.getVectorMinNumElements(); + + EVT IntMemoryVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts); + EVT ElemVT = + EVT::getVectorVT(*DAG.getContext(), MemoryVT.getVectorElementType(), 1); + + // Create a single atomic to load all the elements at once. + SDValue Atomic = + DAG.getAtomic(ISD::ATOMIC_LOAD, dl, IntMemoryVT, IntMemoryVT, +LD->getChain(), LD->getBasePtr(), LD->getMemOperand()); + + // Instead of splitting, put all the elements back into a vector. + SmallVector Ops; + for (unsigned i = 0; i < NumElts; ++i) { +SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Atomic, + DAG.getVectorIdxConstant(i, dl)); +Elt = DAG.getBitcast(ElemVT, Elt); +Ops.push_back(Elt); + } + SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MemoryVT, Ops); + + ReplaceValueWith(SDValue(LD, 0), Concat); arsenm wrote: You don't need to associate the Hi and Lo halves, you need to report the Hi and Lo halves to the caller. The only special thing you need to do here is replace the chain uses, as is done in the non-atomic load case https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
@@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { arsenm wrote: TokenFactor does not require glue operands. The most common use case for TokenFactor is pairing a modified real value with a chain https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
https://github.com/andykaylor approved this pull request. Looks good, with one minor request. https://github.com/llvm/llvm-project/pull/138112 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
https://github.com/andykaylor edited https://github.com/llvm/llvm-project/pull/138112 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
@@ -155,21 +153,14 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { format are all in use. }]; - let parameters = (ins "mlir::Type":$underlying); + let parameters = (ins AnyTypeOf<[CIR_Double, CIR_FP80, CIR_FP128], +"expects !cir.double, !cir.fp80 or !cir.fp128">:$underlying); andykaylor wrote: Can you add a test for this? It looks like the wording of the reported error will change, so we must not have a test now. https://github.com/llvm/llvm-project/pull/138112 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
@@ -110,4 +110,35 @@ def CIR_AnyFundamentalSIntType let cppFunctionName = "isFundamentalSIntType"; } +//===--===// +// Float Type predicates +//===--===// + +def CIR_AnySingleType : CIR_TypeBase<"::cir::SingleType", "single float type">; andykaylor wrote: Is there a reason for the explicit global scope? https://github.com/llvm/llvm-project/pull/138112 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
https://github.com/jofrn updated https://github.com/llvm/llvm-project/pull/120640 >From 2faa227a87fe9424c4445f2479597329fad666e8 Mon Sep 17 00:00:00 2001 From: jofrn Date: Thu, 19 Dec 2024 16:25:55 -0500 Subject: [PATCH] [SelectionDAG][X86] Split via Concat vector types for atomic load Vector types that aren't widened are 'split' via CONCAT_VECTORS so that a single ATOMIC_LOAD is issued for the entire vector at once. This change utilizes the load vectorization infrastructure in SelectionDAG in order to group the vectors. This enables SelectionDAG to translate vectors with type bfloat,half. commit-id:3a045357 --- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 + .../SelectionDAG/LegalizeVectorTypes.cpp | 32 llvm/test/CodeGen/X86/atomic-load-store.ll| 171 ++ 3 files changed, 204 insertions(+) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index bdfa5f7741ad3..7905f5a94c579 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -960,6 +960,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { void SplitVecRes_FPOp_MultiType(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_IS_FPCLASS(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi); + void SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD); void SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi); void SplitVecRes_VP_LOAD(VPLoadSDNode *LD, SDValue &Lo, SDValue &Hi); void SplitVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *SLD, SDValue &Lo, diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 43710b77b763b..06d06def893e2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -1172,6 +1172,9 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SplitVecRes_STEP_VECTOR(N, Lo, Hi); break; case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break; + case ISD::ATOMIC_LOAD: +SplitVecRes_ATOMIC_LOAD(cast(N)); +break; case ISD::LOAD: SplitVecRes_LOAD(cast(N), Lo, Hi); break; @@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { + SDLoc dl(LD); + + EVT MemoryVT = LD->getMemoryVT(); + unsigned NumElts = MemoryVT.getVectorMinNumElements(); + + EVT IntMemoryVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts); + EVT ElemVT = + EVT::getVectorVT(*DAG.getContext(), MemoryVT.getVectorElementType(), 1); + + // Create a single atomic to load all the elements at once. + SDValue Atomic = + DAG.getAtomicLoad(ISD::NON_EXTLOAD, dl, IntMemoryVT, IntMemoryVT, +LD->getChain(), LD->getBasePtr(), LD->getMemOperand()); + + // Instead of splitting, put all the elements back into a vector. + SmallVector Ops; + for (unsigned i = 0; i < NumElts; ++i) { +SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Atomic, + DAG.getVectorIdxConstant(i, dl)); +Elt = DAG.getBitcast(ElemVT, Elt); +Ops.push_back(Elt); + } + SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MemoryVT, Ops); + + ReplaceValueWith(SDValue(LD, 0), Concat); + ReplaceValueWith(SDValue(LD, 1), LD->getChain()); +} + void DAGTypeLegalizer::IncrementPointer(MemSDNode *N, EVT MemVT, MachinePointerInfo &MPI, SDValue &Ptr, uint64_t *ScaledOffset) { diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll b/llvm/test/CodeGen/X86/atomic-load-store.ll index 935d058a52f8f..227bdbf9c0747 100644 --- a/llvm/test/CodeGen/X86/atomic-load-store.ll +++ b/llvm/test/CodeGen/X86/atomic-load-store.ll @@ -204,6 +204,76 @@ define <2 x float> @atomic_vec2_float_align(ptr %x) { ret <2 x float> %ret } +define <2 x half> @atomic_vec2_half(ptr %x) { +; CHECK3-LABEL: atomic_vec2_half: +; CHECK3: ## %bb.0: +; CHECK3-NEXT:movl (%rdi), %eax +; CHECK3-NEXT:movd %eax, %xmm1 +; CHECK3-NEXT:shrl $16, %eax +; CHECK3-NEXT:pinsrw $0, %eax, %xmm2 +; CHECK3-NEXT:movdqa {{.*#+}} xmm0 = [65535,0,65535,65535,65535,65535,65535,65535] +; CHECK3-NEXT:pand %xmm0, %xmm1 +; CHECK3-NEXT:pslld $16, %xmm2 +; CHECK3-NEXT:pandn %xmm2, %xmm0 +; CHECK3-NEXT:por %xmm1, %xmm0 +; CHECK3-NEXT:retq +; +; CHECK0-LABEL: atomic_vec2_half: +; CHECK0: ## %bb.0: +; CHECK0-NEXT:movl (%rdi), %eax +; CHECK0-NEXT:movl %eax, %ecx +; CHECK0-NEXT:shrl $16, %ecx +; CHECK0-NEXT:movw %cx, %dx +; CHECK0-NEXT:## implicit-def: $ecx +; CHECK0-NEXT:movw %dx, %cx +; CHECK0-NEXT:## implicit-def: $xmm2 +; CHECK0-NEXT:pinsr
[llvm-branch-commits] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1333,6 +1308,56 @@ static void addPreloadKernArgHint(Function &F, TargetMachine &TM) { } } +/// The final check and update of the attribute 'amdgpu-waves-per-eu' based on +/// the determined 'amdgpu-flat-work-group-size' attribute. We can't do this +/// during attributor run because the two attributes grow in opposite direction, +/// we should not use any intermediate value to calculate waves per eu until we +/// have a determined flat workgroup size. +static void updateWavesPerEU(Module &M, TargetMachine &TM) { shiltian wrote: We should probably add a CGSCC pass. https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1108,47 +1108,25 @@ struct AAAMDWavesPerEU : public AAAMDSizeRangeAttribute { Function *F = getAssociatedFunction(); auto &InfoCache = static_cast(A.getInfoCache()); -auto TakeRange = [&](std::pair R) { - auto [Min, Max] = R; - ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); - IntegerRangeState RangeState(Range); - clampStateAndIndicateChange(this->getState(), RangeState); - indicateOptimisticFixpoint(); -}; - -std::pair MaxWavesPerEURange{ -1U, InfoCache.getMaxWavesPerEU(*F)}; - // If the attribute exists, we will honor it if it is not the default. if (auto Attr = InfoCache.getWavesPerEUAttr(*F)) { + std::pair MaxWavesPerEURange{ + 1U, InfoCache.getMaxWavesPerEU(*F)}; if (*Attr != MaxWavesPerEURange) { -TakeRange(*Attr); +auto [Min, Max] = *Attr; +ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); +IntegerRangeState RangeState(Range); +this->getState() = RangeState; +indicateOptimisticFixpoint(); arsenm wrote: I don't want to bake in the assumption it's only set on kernels. This is an artificial restriction we shouldn't really have. Everywhere else properly handles waves per eu on functions https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
https://github.com/shiltian edited https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1408,8 +1433,14 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM, } } - ChangeStatus Change = A.run(); - return Change == ChangeStatus::CHANGED; + bool Changed = A.run() == ChangeStatus::CHANGED; shiltian wrote: I didn't follow your question. Can you expatiate it? https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1108,47 +1108,25 @@ struct AAAMDWavesPerEU : public AAAMDSizeRangeAttribute { Function *F = getAssociatedFunction(); auto &InfoCache = static_cast(A.getInfoCache()); -auto TakeRange = [&](std::pair R) { - auto [Min, Max] = R; - ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); - IntegerRangeState RangeState(Range); - clampStateAndIndicateChange(this->getState(), RangeState); - indicateOptimisticFixpoint(); -}; - -std::pair MaxWavesPerEURange{ -1U, InfoCache.getMaxWavesPerEU(*F)}; - // If the attribute exists, we will honor it if it is not the default. if (auto Attr = InfoCache.getWavesPerEUAttr(*F)) { + std::pair MaxWavesPerEURange{ + 1U, InfoCache.getMaxWavesPerEU(*F)}; if (*Attr != MaxWavesPerEURange) { -TakeRange(*Attr); +auto [Min, Max] = *Attr; +ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); +IntegerRangeState RangeState(Range); +this->getState() = RangeState; +indicateOptimisticFixpoint(); shiltian wrote: At the moment it doesn't have that assumption though. If there is an attribute it has be from users. That part still holds. https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
https://github.com/jmorse commented: Some initial comments; I made it to about 1000 lines into LVIRReader.cpp. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [clang-doc] Track if a type is a template or builtin (PR #138067)
ilovepi wrote: @PeterChou1 can you provide some context about how you originally expected these fields to be used/consumed? Here we bake them into the representation and serialize them, but I don't see any handling of them in the original patch. How should they be used by the different backends? https://github.com/llvm/llvm-project/pull/138067 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [KeyInstr] Inline atom info (PR #133481)
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/133481 >From fde8c9e4834a2dad33c1349ef94fc90544a09b65 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Fri, 21 Mar 2025 16:49:14 + Subject: [PATCH] [KeyInstr] Inline atom info Source atom groups are identified by an atom group number and inlined-at pair, so we simply can copy the atom numbers into the caller when inlining. --- llvm/lib/IR/DebugLoc.cpp | 1 + llvm/lib/Transforms/Utils/InlineFunction.cpp | 3 +- .../KeyInstructions/Generic/inline.ll | 53 +++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp index bdea52180f74a..61f5bd8e9b0a2 100644 --- a/llvm/lib/IR/DebugLoc.cpp +++ b/llvm/lib/IR/DebugLoc.cpp @@ -129,6 +129,7 @@ DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt, // Starting from the top, rebuild the nodes to point to the new inlined-at // location (then rebuilding the rest of the chain behind it) and update the // map of already-constructed inlined-at nodes. + // Key Instructions: InlinedAt fields don't need atom info. for (const DILocation *MD : reverse(InlinedAtLocations)) Cache[MD] = Last = DILocation::getDistinct( Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 7a91620af8272..eaf57e7bf899d 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1819,7 +1819,8 @@ static DebugLoc inlineDebugLoc(DebugLoc OrigDL, DILocation *InlinedAt, DenseMap &IANodes) { auto IA = DebugLoc::appendInlinedAt(OrigDL, InlinedAt, Ctx, IANodes); return DILocation::get(Ctx, OrigDL.getLine(), OrigDL.getCol(), - OrigDL.getScope(), IA); + OrigDL.getScope(), IA, OrigDL.isImplicitCode(), + OrigDL->getAtomGroup(), OrigDL->getAtomRank()); } /// Update inlined instructions' line numbers to diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll new file mode 100644 index 0..c2663ee51a77d --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll @@ -0,0 +1,53 @@ +; RUN: opt %s -passes=inline -S -o - | FileCheck %s + +;; Inline `f` into `g`. The inlined assignment store and add should retain +;; their atom info. + +; CHECK: _Z1gi +; CHECK-NOT: _Z1fi +; CHECK: %add.i = add nsw i32 %mul.i, 1, !dbg [[G1R2:!.*]] +; CHECK-NEXT: store i32 %add.i, ptr %x.i, align 4, !dbg [[G1R1:!.*]] + +; CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2) +; CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) + +define hidden void @_Z1fi(i32 noundef %a) !dbg !11 { +entry: + %a.addr = alloca i32, align 4 + %x = alloca i32, align 4 + store i32 %a, ptr %a.addr, align 4 + %0 = load i32, ptr %a.addr, align 4, !dbg !18 + %mul = mul nsw i32 %0, 2, !dbg !18 + %add = add nsw i32 %mul, 1, !dbg !19 + store i32 %add, ptr %x, align 4, !dbg !20 + ret void, !dbg !22 +} + +define hidden void @_Z1gi(i32 noundef %b) !dbg !23 { +entry: + %b.addr = alloca i32, align 4 + store i32 %b, ptr %b.addr, align 4 + %0 = load i32, ptr %b.addr, align 4, !dbg !24 + call void @_Z1fi(i32 noundef %0), !dbg !24 + ret void, !dbg !25 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_17, file: !1, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.cpp", directory: "/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"clang version 19.0.0"} +!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!12 = !DISubroutineType(types: !13) +!13 = !{} +!18 = !DILocation(line: 2, scope: !11) +!19 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) +!20 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 1) +!22 = !DILocation(line: 3, scope: !11, atomGroup: 2, atomRank: 1) +!23 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!24 = !DILocation(line: 5, scope: !23) +!25 = !DILocation(line: 6, scope: !23, atomGroup: 1, atomRank: 1) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lis
[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add Mustache template assets (PR #138059)
ilovepi wrote: I appreciate this is a lot of CSS and templates. I have this here in the stack, so that hopefully I can leverage these to bootstrap unittests for the HTMLMustacheGenerator in subsequent patches. https://github.com/llvm/llvm-project/pull/138059 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add HTMLMustacheGenerator.cpp (PR #138060)
ilovepi wrote: Testing in this patch will have to be limited to unit tests, if we can bootstrap anything at all. https://github.com/llvm/llvm-project/pull/138060 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update clang-doc tool to enable mustache templates (PR #138066)
ilovepi wrote: I'm wondering if this should be earlier in the stack to facilitate better testing. https://github.com/llvm/llvm-project/pull/138066 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AtomicExpand] Add bitcasts when expanding load atomic vector (PR #120716)
@@ -2066,9 +2066,23 @@ bool AtomicExpandImpl::expandAtomicOpToLibcall( I->replaceAllUsesWith(V); } else if (HasResult) { Value *V; -if (UseSizedLibcall) - V = Builder.CreateBitOrPointerCast(Result, I->getType()); -else { +if (UseSizedLibcall) { + // Add bitcasts from Result's scalar type to I's vector type + if (I->getType()->getScalarType()->isPointerTy() && + I->getType()->isVectorTy() && !Result->getType()->isVectorTy()) { +unsigned AS = + cast(I->getType()->getScalarType())->getAddressSpace(); +ElementCount EC = cast(I->getType())->getElementCount(); +Value *BC = Builder.CreateBitCast( +Result, +VectorType::get(IntegerType::get(Ctx, DL.getPointerSizeInBits(AS)), arsenm wrote: Use DL.getIntPtrType. You can also avoid all of the vector logic with Type::getWithNewType https://github.com/llvm/llvm-project/pull/120716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AtomicExpand] Add bitcasts when expanding load atomic vector (PR #120716)
@@ -2066,9 +2066,23 @@ bool AtomicExpandImpl::expandAtomicOpToLibcall( I->replaceAllUsesWith(V); } else if (HasResult) { Value *V; -if (UseSizedLibcall) - V = Builder.CreateBitOrPointerCast(Result, I->getType()); -else { +if (UseSizedLibcall) { + // Add bitcasts from Result's scalar type to I's vector type + if (I->getType()->getScalarType()->isPointerTy() && + I->getType()->isVectorTy() && !Result->getType()->isVectorTy()) { +unsigned AS = + cast(I->getType()->getScalarType())->getAddressSpace(); arsenm wrote: use dyn_cast instead of is* + cast. There's also isPtrOrPtrVectorTy https://github.com/llvm/llvm-project/pull/120716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1333,6 +1308,56 @@ static void addPreloadKernArgHint(Function &F, TargetMachine &TM) { } } +/// The final check and update of the attribute 'amdgpu-waves-per-eu' based on +/// the determined 'amdgpu-flat-work-group-size' attribute. We can't do this +/// during attributor run because the two attributes grow in opposite direction, +/// we should not use any intermediate value to calculate waves per eu until we +/// have a determined flat workgroup size. +static void updateWavesPerEU(Module &M, TargetMachine &TM) { + for (Function &F : M) { +const GCNSubtarget &ST = TM.getSubtarget(F); arsenm wrote: Skip declarations https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1408,8 +1433,14 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM, } } - ChangeStatus Change = A.run(); - return Change == ChangeStatus::CHANGED; + bool Changed = A.run() == ChangeStatus::CHANGED; arsenm wrote: Can this be more refined on waves per eu or flat workgroup size changing? https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1333,6 +1308,56 @@ static void addPreloadKernArgHint(Function &F, TargetMachine &TM) { } } +/// The final check and update of the attribute 'amdgpu-waves-per-eu' based on +/// the determined 'amdgpu-flat-work-group-size' attribute. We can't do this +/// during attributor run because the two attributes grow in opposite direction, +/// we should not use any intermediate value to calculate waves per eu until we +/// have a determined flat workgroup size. +static void updateWavesPerEU(Module &M, TargetMachine &TM) { + for (Function &F : M) { +const GCNSubtarget &ST = TM.getSubtarget(F); + +auto FlatWgrpSizeAttr = +AMDGPU::getIntegerPairAttribute(F, "amdgpu-flat-work-group-size"); + +unsigned MinWavesPerEU = ST.getMinWavesPerEU(); +unsigned MaxWavesPerEU = ST.getMaxWavesPerEU(); + +unsigned MinFlatWgrpSize = ST.getMinFlatWorkGroupSize(); +unsigned MaxFlatWgrpSize = ST.getMaxFlatWorkGroupSize(); +if (FlatWgrpSizeAttr.has_value()) { + MinFlatWgrpSize = FlatWgrpSizeAttr->first; + MaxFlatWgrpSize = *(FlatWgrpSizeAttr->second); +} + +// Start with the max range. +unsigned Min = MinWavesPerEU; +unsigned Max = MinWavesPerEU; + +// Compute the range from flat workgroup size. `getWavesPerEU` will also +// account for the 'amdgpu-waves-er-eu' attribute. +auto [MinFromFlatWgrpSize, MaxFromFlatWgrpSize] = +ST.getWavesPerEU(F, std::make_pair(MinFlatWgrpSize, MaxFlatWgrpSize)); arsenm wrote: ```suggestion ST.getWavesPerEU(F, {MinFlatWgrpSize, MaxFlatWgrpSize}); ``` https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1108,47 +1108,25 @@ struct AAAMDWavesPerEU : public AAAMDSizeRangeAttribute { Function *F = getAssociatedFunction(); auto &InfoCache = static_cast(A.getInfoCache()); -auto TakeRange = [&](std::pair R) { - auto [Min, Max] = R; - ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); - IntegerRangeState RangeState(Range); - clampStateAndIndicateChange(this->getState(), RangeState); - indicateOptimisticFixpoint(); -}; - -std::pair MaxWavesPerEURange{ -1U, InfoCache.getMaxWavesPerEU(*F)}; - // If the attribute exists, we will honor it if it is not the default. if (auto Attr = InfoCache.getWavesPerEUAttr(*F)) { + std::pair MaxWavesPerEURange{ + 1U, InfoCache.getMaxWavesPerEU(*F)}; if (*Attr != MaxWavesPerEURange) { -TakeRange(*Attr); +auto [Min, Max] = *Attr; +ConstantRange Range(APInt(32, Min), APInt(32, Max + 1)); +IntegerRangeState RangeState(Range); +this->getState() = RangeState; +indicateOptimisticFixpoint(); arsenm wrote: Won't this prevent further refining of the callee's bounds? https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [KeyInstr][SimplifyCFG] Remap atoms when folding br to common succ into pred (PR #133482)
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/133482 >From 958c0d775bc696df74b847b106ccd2531d5e12e2 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Mon, 24 Mar 2025 13:48:07 + Subject: [PATCH] [KeyInstr][SimplifyCFG] Remap atoms when folding br to common succ into pred SimplifyCFG folds `b` into `a`. +---+ | v --> a --> b --> c --> d --> | ^ +-+ Remap source atoms in `b` so that the duplicated instructions are analysed independently to determine is_stmt positions. This is necessary as the contents of `b` may be folded into multiple preds in this way. Add multi-pred test. --- llvm/include/llvm/IR/DebugLoc.h | 10 +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 32 ++-- .../Generic/simplifycfg-branch-fold.ll| 81 +++ 3 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll diff --git a/llvm/include/llvm/IR/DebugLoc.h b/llvm/include/llvm/IR/DebugLoc.h index c22d3e9b10d27..7fdedc4acd919 100644 --- a/llvm/include/llvm/IR/DebugLoc.h +++ b/llvm/include/llvm/IR/DebugLoc.h @@ -76,6 +76,16 @@ namespace llvm { LLVMContext &Ctx, DenseMap &Cache); +/// Return true if the source locations match, ignoring isImplicitCode and +/// source atom info. +bool isSameSourceLocation(const DebugLoc &Other) const { + if (get() == Other.get()) +return true; + return ((bool)*this == (bool)Other) && getLine() == Other.getLine() && + getCol() == Other.getCol() && getScope() == Other.getScope() && + getInlinedAt() == Other.getInlinedAt(); +} + unsigned getLine() const; unsigned getCol() const; MDNode *getScope() const; diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 8094697cdd13a..327b7b36245b1 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -73,6 +73,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LockstepReverseIterator.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -1129,13 +1130,17 @@ static void cloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( Instruction *NewBonusInst = BonusInst.clone(); -if (!isa(BonusInst) && -PTI->getDebugLoc() != NewBonusInst->getDebugLoc()) { - // Unless the instruction has the same !dbg location as the original - // branch, drop it. When we fold the bonus instructions we want to make - // sure we reset their debug locations in order to avoid stepping on - // dead code caused by folding dead branches. - NewBonusInst->setDebugLoc(DebugLoc()); +if (!isa(BonusInst)) { + if (!NewBonusInst->getDebugLoc().isSameSourceLocation( + PTI->getDebugLoc())) { +// Unless the instruction has the same !dbg location as the original +// branch, drop it. When we fold the bonus instructions we want to make +// sure we reset their debug locations in order to avoid stepping on +// dead code caused by folding dead branches. +NewBonusInst->setDebugLoc(DebugLoc()); + } else if (const DebugLoc &DL = NewBonusInst->getDebugLoc()) { +mapAtomInstance(DL, VMap); + } } RemapInstruction(NewBonusInst, VMap, @@ -1182,6 +1187,19 @@ static void cloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( U.set(NewBonusInst); } } + + // Key Instructions: We may have propagated atom info into the pred. If the + // pred's terminator already has atom info do nothing as merging would drop + // one atom group anyway. If it doesn't, propagte the remapped atom group + // from BB's terminator. + if (auto &PredDL = PredBlock->getTerminator()->getDebugLoc()) { +auto &DL = BB->getTerminator()->getDebugLoc(); +if (!PredDL->getAtomGroup() && DL && DL->getAtomGroup() && +PredDL.isSameSourceLocation(DL)) { + PredBlock->getTerminator()->setDebugLoc(DL); + RemapSourceAtom(PredBlock->getTerminator(), VMap); +} + } } bool SimplifyCFGOpt::performValueComparisonIntoPredecessorFolding( diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll new file mode 100644 index 0..8746f242007c3 --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll @@ -0,0 +1,81 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt %s -S -passes=simplifycfg -b
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
xlauko wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/138112?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#138112** https://app.graphite.dev/github/pr/llvm/llvm-project/138112?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/138112?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#138106** https://app.graphite.dev/github/pr/llvm/llvm-project/138106?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/138112 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
https://github.com/xlauko ready_for_review https://github.com/llvm/llvm-project/pull/138112 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
llvmbot wrote: @llvm/pr-subscribers-clangir Author: Henrich Lauko (xlauko) Changes - This cleans up moves cir floating point type constraints to dedicated constraints file, and fixes long double verifier to use constraints directly. - Renames `CIR_AnyFloat` to `CIR_AnyFloatType`. This mirrors inbubator changes from https://github.com/llvm/clangir/pull/1594 --- Full diff: https://github.com/llvm/llvm-project/pull/138112.diff 4 Files Affected: - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td (+29) - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.h (-1) - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.td (+7-16) - (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (-20) ``diff diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index 3b8cb20da8edb..274b9e509f0d6 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -110,4 +110,33 @@ def CIR_AnyFundamentalSIntType let cppFunctionName = "isFundamentalSIntType"; } +//===--===// +// Float Type predicates +//===--===// + +def CIR_AnySingleType : CIR_TypeBase<"::cir::SingleType", "single float type">; +def CIR_AnyFP32Type : TypeAlias; + +def CIR_AnyDoubleType : CIR_TypeBase<"::cir::DoubleType", "double float type">; +def CIR_AnyFP64Type : TypeAlias; + +def CIR_AnyFP16Type : CIR_TypeBase<"::cir::FP16Type", "f16 type">; +def CIR_AnyBFloat16Type : CIR_TypeBase<"::cir::BF16Type", "bf16 type">; +def CIR_AnyFP80Type : CIR_TypeBase<"::cir::FP80Type", "f80 type">; +def CIR_AnyFP128Type : CIR_TypeBase<"::cir::FP128Type", "f128 type">; +def CIR_AnyLongDoubleType : CIR_TypeBase<"::cir::LongDoubleType", +"long double type">; + +def CIR_AnyFloatType : AnyTypeOf<[ +CIR_AnySingleType, CIR_AnyDoubleType, CIR_AnyFP16Type, +CIR_AnyBFloat16Type, CIR_AnyFP80Type, CIR_AnyFP128Type, +CIR_AnyLongDoubleType +]> { +let cppFunctionName = "isAnyFloatingPointType"; +} + +def CIR_AnyIntOrFloat : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType]>; + + + #endif // CLANG_CIR_DIALECT_IR_CIRTYPECONSTRAINTS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 2e32765c1e941..3845fd2a4b67d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -26,7 +26,6 @@ struct RecordTypeStorage; bool isValidFundamentalIntWidth(unsigned width); -bool isAnyFloatingPointType(mlir::Type t); bool isFPOrFPVectorTy(mlir::Type); } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index d9f05c9aea63d..959e2cd822e76 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -80,12 +80,10 @@ def CIR_IntType : CIR_Type<"Int", "int", // FloatType //===--===// -class CIR_FloatType -: CIR_Type, -DeclareTypeInterfaceMethods, - ]> {} +class CIR_FloatType : CIR_Type, + DeclareTypeInterfaceMethods +]>; def CIR_Single : CIR_FloatType<"Single", "float"> { let summary = "CIR single-precision 32-bit float type"; @@ -155,21 +153,14 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { format are all in use. }]; - let parameters = (ins "mlir::Type":$underlying); + let parameters = (ins AnyTypeOf<[CIR_Double, CIR_FP80, CIR_FP128], +"expects !cir.double, !cir.fp80 or !cir.fp128">:$underlying); let assemblyFormat = [{ `<` $underlying `>` }]; - - let genVerifyDecl = 1; } -// Constraints - -def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128, - CIR_LongDouble, CIR_FP16, CIR_BFloat16]>; -def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>; - //===--===// // PointerType //===--===// @@ -518,7 +509,7 @@ def CIRRecordType : Type< def CIR_AnyType : AnyTypeOf<[ CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType, - CIR_AnyFloat, CIR_PointerType, CIR_FuncType, CIR_RecordType + CIR_AnyFloatType, CIR_PointerType, CIR_FuncType, CIR_RecordType ]>; #endif // MLIR_CIR_DIALECT_CIR_TYPES diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 7d960c21d7251..9a44f923ac143 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -550,26 +550,6 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, .getABIAlignment(dataLayout, params); }
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Henrich Lauko (xlauko) Changes - This cleans up moves cir floating point type constraints to dedicated constraints file, and fixes long double verifier to use constraints directly. - Renames `CIR_AnyFloat` to `CIR_AnyFloatType`. This mirrors inbubator changes from https://github.com/llvm/clangir/pull/1594 --- Full diff: https://github.com/llvm/llvm-project/pull/138112.diff 4 Files Affected: - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td (+29) - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.h (-1) - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.td (+7-16) - (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (-20) ``diff diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index 3b8cb20da8edb..274b9e509f0d6 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -110,4 +110,33 @@ def CIR_AnyFundamentalSIntType let cppFunctionName = "isFundamentalSIntType"; } +//===--===// +// Float Type predicates +//===--===// + +def CIR_AnySingleType : CIR_TypeBase<"::cir::SingleType", "single float type">; +def CIR_AnyFP32Type : TypeAlias; + +def CIR_AnyDoubleType : CIR_TypeBase<"::cir::DoubleType", "double float type">; +def CIR_AnyFP64Type : TypeAlias; + +def CIR_AnyFP16Type : CIR_TypeBase<"::cir::FP16Type", "f16 type">; +def CIR_AnyBFloat16Type : CIR_TypeBase<"::cir::BF16Type", "bf16 type">; +def CIR_AnyFP80Type : CIR_TypeBase<"::cir::FP80Type", "f80 type">; +def CIR_AnyFP128Type : CIR_TypeBase<"::cir::FP128Type", "f128 type">; +def CIR_AnyLongDoubleType : CIR_TypeBase<"::cir::LongDoubleType", +"long double type">; + +def CIR_AnyFloatType : AnyTypeOf<[ +CIR_AnySingleType, CIR_AnyDoubleType, CIR_AnyFP16Type, +CIR_AnyBFloat16Type, CIR_AnyFP80Type, CIR_AnyFP128Type, +CIR_AnyLongDoubleType +]> { +let cppFunctionName = "isAnyFloatingPointType"; +} + +def CIR_AnyIntOrFloat : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType]>; + + + #endif // CLANG_CIR_DIALECT_IR_CIRTYPECONSTRAINTS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 2e32765c1e941..3845fd2a4b67d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -26,7 +26,6 @@ struct RecordTypeStorage; bool isValidFundamentalIntWidth(unsigned width); -bool isAnyFloatingPointType(mlir::Type t); bool isFPOrFPVectorTy(mlir::Type); } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index d9f05c9aea63d..959e2cd822e76 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -80,12 +80,10 @@ def CIR_IntType : CIR_Type<"Int", "int", // FloatType //===--===// -class CIR_FloatType -: CIR_Type, -DeclareTypeInterfaceMethods, - ]> {} +class CIR_FloatType : CIR_Type, + DeclareTypeInterfaceMethods +]>; def CIR_Single : CIR_FloatType<"Single", "float"> { let summary = "CIR single-precision 32-bit float type"; @@ -155,21 +153,14 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { format are all in use. }]; - let parameters = (ins "mlir::Type":$underlying); + let parameters = (ins AnyTypeOf<[CIR_Double, CIR_FP80, CIR_FP128], +"expects !cir.double, !cir.fp80 or !cir.fp128">:$underlying); let assemblyFormat = [{ `<` $underlying `>` }]; - - let genVerifyDecl = 1; } -// Constraints - -def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128, - CIR_LongDouble, CIR_FP16, CIR_BFloat16]>; -def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>; - //===--===// // PointerType //===--===// @@ -518,7 +509,7 @@ def CIRRecordType : Type< def CIR_AnyType : AnyTypeOf<[ CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_IntType, - CIR_AnyFloat, CIR_PointerType, CIR_FuncType, CIR_RecordType + CIR_AnyFloatType, CIR_PointerType, CIR_FuncType, CIR_RecordType ]>; #endif // MLIR_CIR_DIALECT_CIR_TYPES diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 7d960c21d7251..9a44f923ac143 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -550,26 +550,6 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, .getABIAlignment(dataLayout, params); } -
[llvm-branch-commits] [clang] [CIR] Refactor floating point type constraints (PR #138112)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/138112 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
@@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { + SDLoc dl(LD); + + EVT MemoryVT = LD->getMemoryVT(); + unsigned NumElts = MemoryVT.getVectorMinNumElements(); + + EVT IntMemoryVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts); + EVT ElemVT = + EVT::getVectorVT(*DAG.getContext(), MemoryVT.getVectorElementType(), 1); + + // Create a single atomic to load all the elements at once. + SDValue Atomic = + DAG.getAtomic(ISD::ATOMIC_LOAD, dl, IntMemoryVT, IntMemoryVT, +LD->getChain(), LD->getBasePtr(), LD->getMemOperand()); + + // Instead of splitting, put all the elements back into a vector. + SmallVector Ops; + for (unsigned i = 0; i < NumElts; ++i) { +SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Atomic, + DAG.getVectorIdxConstant(i, dl)); +Elt = DAG.getBitcast(ElemVT, Elt); +Ops.push_back(Elt); + } + SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MemoryVT, Ops); + + ReplaceValueWith(SDValue(LD, 0), Concat); jofrn wrote: I'm talking about chain uses of Lo and Hi. The atomic_load lowering contains this, which looks to be associating the values: ` Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1));` However, Lo and Hi are uses from getLoad/getAtomicLoad, but getAtomicLoad does not have the chain that TokenFactor wants. https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. (#135769) (PR #138142)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/138142 Backport c91c3f930cfc75eb4e8b623ecd59c807863aa6c0 Requested by: @rj-jesus >From ed9883341726233dec2a9b805ac4f411a17a374e Mon Sep 17 00:00:00 2001 From: Ricardo Jesus Date: Wed, 30 Apr 2025 08:22:38 +0100 Subject: [PATCH] [InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. (#135769) If we are attempting to combine shuffle+bitcast but the bitcast is pairable with a subsequent bitcast, we should not fold the shuffle as doing so can block further simplifications. The motivation for this is a long-standing regression affecting SIMDe on AArch64, introduced indirectly by the AlwaysInliner (1a2e77cf). Some reproducers: * https://godbolt.org/z/53qx18s6M * https://godbolt.org/z/o5e43h5M7 (cherry picked from commit c91c3f930cfc75eb4e8b623ecd59c807863aa6c0) --- .../InstCombine/InstCombineVectorOps.cpp | 16 ++--- .../InstCombine/shufflevec-bitcast.ll | 35 +++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 6860a7cd07b78..118d2d4be828f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -3029,10 +3029,18 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) { SmallVector BCs; DenseMap NewBCs; for (User *U : SVI.users()) - if (BitCastInst *BC = dyn_cast(U)) -if (!BC->use_empty()) - // Only visit bitcasts that weren't previously handled. - BCs.push_back(BC); + if (BitCastInst *BC = dyn_cast(U)) { +// Only visit bitcasts that weren't previously handled. +if (BC->use_empty()) + continue; +// Prefer to combine bitcasts of bitcasts before attempting this fold. +if (BC->hasOneUse()) { + auto *BC2 = dyn_cast(BC->user_back()); + if (BC2 && isEliminableCastPair(BC, BC2)) +continue; +} +BCs.push_back(BC); + } for (BitCastInst *BC : BCs) { unsigned BegIdx = Mask.front(); Type *TgtTy = BC->getDestTy(); diff --git a/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll b/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll index f20077243273c..877dd1eefbae4 100644 --- a/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll +++ b/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll @@ -235,3 +235,38 @@ define <3 x i4> @shuf_bitcast_wrong_size(<2 x i8> %v, i8 %x) { %r = shufflevector <4 x i4> %b, <4 x i4> undef, <3 x i32> ret <3 x i4> %r } + +; Negative test - chain of bitcasts. + +define <16 x i8> @shuf_bitcast_chain(<8 x i32> %v) { +; CHECK-LABEL: @shuf_bitcast_chain( +; CHECK-NEXT:[[S:%.*]] = shufflevector <8 x i32> [[V:%.*]], <8 x i32> poison, <4 x i32> +; CHECK-NEXT:[[C:%.*]] = bitcast <4 x i32> [[S]] to <16 x i8> +; CHECK-NEXT:ret <16 x i8> [[C]] +; + %s = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> + %a = bitcast <4 x i32> %s to <2 x i64> + %b = bitcast <2 x i64> %a to i128 + %c = bitcast i128 %b to <16 x i8> + ret <16 x i8> %c +} + +; Same as above, but showing why it's not feasable to implement the reverse +; fold in VectorCombine (see #136998). + +define <4 x i32> @shuf_bitcast_chain_2(<8 x i32> %v) { +; CHECK-LABEL: @shuf_bitcast_chain_2( +; CHECK-NEXT:[[S0:%.*]] = shufflevector <8 x i32> [[V:%.*]], <8 x i32> poison, <4 x i32> +; CHECK-NEXT:[[S1:%.*]] = shufflevector <8 x i32> [[V]], <8 x i32> poison, <4 x i32> +; CHECK-NEXT:[[R:%.*]] = or <4 x i32> [[S0]], [[S1]] +; CHECK-NEXT:ret <4 x i32> [[R]] +; + %s0 = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> + %s1 = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> + %b0 = bitcast <4 x i32> %s0 to i128 + %b1 = bitcast <4 x i32> %s1 to i128 + %c0 = bitcast i128 %b0 to <4 x i32> + %c1 = bitcast i128 %b1 to <4 x i32> + %r = or <4 x i32> %c0, %c1 + ret <4 x i32> %r +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. (#135769) (PR #138142)
llvmbot wrote: @nikic What do you think about merging this PR to the release branch? https://github.com/llvm/llvm-project/pull/138142 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. (#135769) (PR #138142)
llvmbot wrote: @llvm/pr-subscribers-llvm-transforms Author: None (llvmbot) Changes Backport c91c3f930cfc75eb4e8b623ecd59c807863aa6c0 Requested by: @rj-jesus --- Full diff: https://github.com/llvm/llvm-project/pull/138142.diff 2 Files Affected: - (modified) llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp (+12-4) - (modified) llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll (+35) ``diff diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 6860a7cd07b78..118d2d4be828f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -3029,10 +3029,18 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) { SmallVector BCs; DenseMap NewBCs; for (User *U : SVI.users()) - if (BitCastInst *BC = dyn_cast(U)) -if (!BC->use_empty()) - // Only visit bitcasts that weren't previously handled. - BCs.push_back(BC); + if (BitCastInst *BC = dyn_cast(U)) { +// Only visit bitcasts that weren't previously handled. +if (BC->use_empty()) + continue; +// Prefer to combine bitcasts of bitcasts before attempting this fold. +if (BC->hasOneUse()) { + auto *BC2 = dyn_cast(BC->user_back()); + if (BC2 && isEliminableCastPair(BC, BC2)) +continue; +} +BCs.push_back(BC); + } for (BitCastInst *BC : BCs) { unsigned BegIdx = Mask.front(); Type *TgtTy = BC->getDestTy(); diff --git a/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll b/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll index f20077243273c..877dd1eefbae4 100644 --- a/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll +++ b/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll @@ -235,3 +235,38 @@ define <3 x i4> @shuf_bitcast_wrong_size(<2 x i8> %v, i8 %x) { %r = shufflevector <4 x i4> %b, <4 x i4> undef, <3 x i32> ret <3 x i4> %r } + +; Negative test - chain of bitcasts. + +define <16 x i8> @shuf_bitcast_chain(<8 x i32> %v) { +; CHECK-LABEL: @shuf_bitcast_chain( +; CHECK-NEXT:[[S:%.*]] = shufflevector <8 x i32> [[V:%.*]], <8 x i32> poison, <4 x i32> +; CHECK-NEXT:[[C:%.*]] = bitcast <4 x i32> [[S]] to <16 x i8> +; CHECK-NEXT:ret <16 x i8> [[C]] +; + %s = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> + %a = bitcast <4 x i32> %s to <2 x i64> + %b = bitcast <2 x i64> %a to i128 + %c = bitcast i128 %b to <16 x i8> + ret <16 x i8> %c +} + +; Same as above, but showing why it's not feasable to implement the reverse +; fold in VectorCombine (see #136998). + +define <4 x i32> @shuf_bitcast_chain_2(<8 x i32> %v) { +; CHECK-LABEL: @shuf_bitcast_chain_2( +; CHECK-NEXT:[[S0:%.*]] = shufflevector <8 x i32> [[V:%.*]], <8 x i32> poison, <4 x i32> +; CHECK-NEXT:[[S1:%.*]] = shufflevector <8 x i32> [[V]], <8 x i32> poison, <4 x i32> +; CHECK-NEXT:[[R:%.*]] = or <4 x i32> [[S0]], [[S1]] +; CHECK-NEXT:ret <4 x i32> [[R]] +; + %s0 = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> + %s1 = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> + %b0 = bitcast <4 x i32> %s0 to i128 + %b1 = bitcast <4 x i32> %s1 to i128 + %c0 = bitcast i128 %b0 to <4 x i32> + %c1 = bitcast i128 %b1 to <4 x i32> + %r = or <4 x i32> %c0, %c1 + ret <4 x i32> %r +} `` https://github.com/llvm/llvm-project/pull/138142 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. (#135769) (PR #138142)
https://github.com/llvmbot milestoned https://github.com/llvm/llvm-project/pull/138142 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
@@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { + SDLoc dl(LD); + + EVT MemoryVT = LD->getMemoryVT(); + unsigned NumElts = MemoryVT.getVectorMinNumElements(); + + EVT IntMemoryVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts); + EVT ElemVT = + EVT::getVectorVT(*DAG.getContext(), MemoryVT.getVectorElementType(), 1); + + // Create a single atomic to load all the elements at once. + SDValue Atomic = + DAG.getAtomic(ISD::ATOMIC_LOAD, dl, IntMemoryVT, IntMemoryVT, +LD->getChain(), LD->getBasePtr(), LD->getMemOperand()); + + // Instead of splitting, put all the elements back into a vector. + SmallVector Ops; + for (unsigned i = 0; i < NumElts; ++i) { +SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Atomic, + DAG.getVectorIdxConstant(i, dl)); +Elt = DAG.getBitcast(ElemVT, Elt); +Ops.push_back(Elt); + } + SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MemoryVT, Ops); + + ReplaceValueWith(SDValue(LD, 0), Concat); arsenm wrote: TokenFactor of a single input is identical to the single input value. But the atomic_load lowering should not contain this. The new lowering has exactly one chain as the original load. The atomic_load is specifically not being split, only the type profile is changing https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [BOLT][NFCI] Simplify DataAggregator using traces (PR #138181)
https://github.com/aaupov created https://github.com/llvm/llvm-project/pull/138181 Trace is a triple of (branch source, branch target, fallthrough end), introduced in https://github.com/llvm/llvm-project/pull/127125. Use traces throughout branch profile handling, unifying perf parsing and pre-aggregated format handling. This in turn makes it possible to use pre-aggregated data for heatmaps. Test Plan: NFCI ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
@@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { jofrn wrote: EXTRACT_SUBVECTOR does not have chain operands, nor does DAG.getAtomicLoad. I checked a few others too, but do we not need to use a TokenFactor if you are saying we do not have to associate them? https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)
@@ -1421,6 +1424,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDValue(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) { + SDLoc dl(LD); + + EVT MemoryVT = LD->getMemoryVT(); + unsigned NumElts = MemoryVT.getVectorMinNumElements(); + + EVT IntMemoryVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts); + EVT ElemVT = + EVT::getVectorVT(*DAG.getContext(), MemoryVT.getVectorElementType(), 1); + + // Create a single atomic to load all the elements at once. + SDValue Atomic = + DAG.getAtomic(ISD::ATOMIC_LOAD, dl, IntMemoryVT, IntMemoryVT, +LD->getChain(), LD->getBasePtr(), LD->getMemOperand()); + + // Instead of splitting, put all the elements back into a vector. + SmallVector Ops; + for (unsigned i = 0; i < NumElts; ++i) { +SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Atomic, + DAG.getVectorIdxConstant(i, dl)); +Elt = DAG.getBitcast(ElemVT, Elt); +Ops.push_back(Elt); + } + SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MemoryVT, Ops); + + ReplaceValueWith(SDValue(LD, 0), Concat); arsenm wrote: There are not multiple chains. The original atomic_load had a chain output and a chain result. The new coerced load has a different output chain, which you replace with the new result chain. The type coercion code is chain free and doesn't care https://github.com/llvm/llvm-project/pull/120640 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] e8e1d2c - Revert "[NFC] Precommit: Autogenerate checks for an LSV test (#138155)"
Author: Anshil Gandhi Date: 2025-05-01T12:09:08-04:00 New Revision: e8e1d2cd5b345070ed2aba7977685e18bbe0c594 URL: https://github.com/llvm/llvm-project/commit/e8e1d2cd5b345070ed2aba7977685e18bbe0c594 DIFF: https://github.com/llvm/llvm-project/commit/e8e1d2cd5b345070ed2aba7977685e18bbe0c594.diff LOG: Revert "[NFC] Precommit: Autogenerate checks for an LSV test (#138155)" This reverts commit 0e9740ea1783ceaf8686b13ab7bf9278f34aef6a. Added: Modified: llvm/test/Transforms/LoadStoreVectorizer/AMDGPU/merge-vectors.ll Removed: llvm/test/Transforms/LoadStoreVectorizer/AMDGPU/merge-vectors-complex.ll diff --git a/llvm/test/Transforms/LoadStoreVectorizer/AMDGPU/merge-vectors-complex.ll b/llvm/test/Transforms/LoadStoreVectorizer/AMDGPU/merge-vectors-complex.ll deleted file mode 100644 index a6a6deb8d9899..0 --- a/llvm/test/Transforms/LoadStoreVectorizer/AMDGPU/merge-vectors-complex.ll +++ /dev/null @@ -1,114 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt -mtriple=amdgcn-amd-amdhsa -passes=load-store-vectorizer -S -o - %s | FileCheck %s - -define void @merge_i32_2i16_float_4i8(ptr addrspace(1) %ptr1, ptr addrspace(2) %ptr2) { -; CHECK-LABEL: define void @merge_i32_2i16_float_4i8( -; CHECK-SAME: ptr addrspace(1) [[PTR1:%.*]], ptr addrspace(2) [[PTR2:%.*]]) { -; CHECK-NEXT:[[GEP1:%.*]] = getelementptr inbounds i32, ptr addrspace(1) [[PTR1]], i64 0 -; CHECK-NEXT:[[LOAD1:%.*]] = load i32, ptr addrspace(1) [[GEP1]], align 4 -; CHECK-NEXT:[[GEP2:%.*]] = getelementptr inbounds <2 x i16>, ptr addrspace(1) [[PTR1]], i64 1 -; CHECK-NEXT:[[LOAD2:%.*]] = load <2 x i16>, ptr addrspace(1) [[GEP2]], align 4 -; CHECK-NEXT:[[GEP3:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[PTR1]], i64 2 -; CHECK-NEXT:[[LOAD3:%.*]] = load float, ptr addrspace(1) [[GEP3]], align 4 -; CHECK-NEXT:[[GEP4:%.*]] = getelementptr inbounds <4 x i8>, ptr addrspace(1) [[PTR1]], i64 3 -; CHECK-NEXT:[[LOAD4:%.*]] = load <4 x i8>, ptr addrspace(1) [[GEP4]], align 4 -; CHECK-NEXT:[[STORE_GEP1:%.*]] = getelementptr inbounds i32, ptr addrspace(2) [[PTR2]], i64 0 -; CHECK-NEXT:store i32 [[LOAD1]], ptr addrspace(2) [[STORE_GEP1]], align 4 -; CHECK-NEXT:[[STORE_GEP2:%.*]] = getelementptr inbounds <2 x i16>, ptr addrspace(2) [[PTR2]], i64 1 -; CHECK-NEXT:store <2 x i16> [[LOAD2]], ptr addrspace(2) [[STORE_GEP2]], align 4 -; CHECK-NEXT:[[STORE_GEP3:%.*]] = getelementptr inbounds float, ptr addrspace(2) [[PTR2]], i64 2 -; CHECK-NEXT:store float [[LOAD3]], ptr addrspace(2) [[STORE_GEP3]], align 4 -; CHECK-NEXT:[[STORE_GEP4:%.*]] = getelementptr inbounds <4 x i8>, ptr addrspace(2) [[PTR2]], i64 3 -; CHECK-NEXT:store <4 x i8> [[LOAD4]], ptr addrspace(2) [[STORE_GEP4]], align 4 -; CHECK-NEXT:ret void -; - %gep1 = getelementptr inbounds i32, ptr addrspace(1) %ptr1, i64 0 - %load1 = load i32, ptr addrspace(1) %gep1, align 4 - %gep2 = getelementptr inbounds <2 x i16>, ptr addrspace(1) %ptr1, i64 1 - %load2 = load <2 x i16>, ptr addrspace(1) %gep2, align 4 - %gep3 = getelementptr inbounds float, ptr addrspace(1) %ptr1, i64 2 - %load3 = load float, ptr addrspace(1) %gep3, align 4 - %gep4 = getelementptr inbounds <4 x i8>, ptr addrspace(1) %ptr1, i64 3 - %load4 = load <4 x i8>, ptr addrspace(1) %gep4, align 4 - %store.gep1 = getelementptr inbounds i32, ptr addrspace(2) %ptr2, i64 0 - store i32 %load1, ptr addrspace(2) %store.gep1, align 4 - %store.gep2 = getelementptr inbounds <2 x i16>, ptr addrspace(2) %ptr2, i64 1 - store <2 x i16> %load2, ptr addrspace(2) %store.gep2, align 4 - %store.gep3 = getelementptr inbounds float, ptr addrspace(2) %ptr2, i64 2 - store float %load3, ptr addrspace(2) %store.gep3, align 4 - %store.gep4 = getelementptr inbounds <4 x i8>, ptr addrspace(2) %ptr2, i64 3 - store <4 x i8> %load4, ptr addrspace(2) %store.gep4, align 4 - ret void -} - -define void @merge_fp_v2half_type(ptr addrspace(1) %ptr1, ptr addrspace(2) %ptr2) { -; CHECK-LABEL: define void @merge_fp_v2half_type( -; CHECK-SAME: ptr addrspace(1) [[PTR1:%.*]], ptr addrspace(2) [[PTR2:%.*]]) { -; CHECK-NEXT:[[GEP1:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[PTR1]], i64 0 -; CHECK-NEXT:[[LOAD1:%.*]] = load float, ptr addrspace(1) [[GEP1]], align 4 -; CHECK-NEXT:[[GEP2:%.*]] = getelementptr inbounds <2 x half>, ptr addrspace(1) [[PTR1]], i64 1 -; CHECK-NEXT:[[LOAD2:%.*]] = load <2 x half>, ptr addrspace(1) [[GEP2]], align 4 -; CHECK-NEXT:[[STORE_GEP1:%.*]] = getelementptr inbounds i32, ptr addrspace(2) [[PTR2]], i64 0 -; CHECK-NEXT:store float [[LOAD1]], ptr addrspace(2) [[STORE_GEP1]], align 4 -; CHECK-NEXT:[[STORE_GEP2:%.*]] = getelementptr inbounds <2 x half>, ptr addrspace(2) [[PTR2]], i64 1 -; CHECK-NEXT:store <2 x half> [[LOAD2]], ptr addrspace
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -4,17 +4,17 @@ declare void @llvm.memcpy.p1.p4.i32(ptr addrspace(1) nocapture, ptr addrspace(4) nocapture, i32, i1) #0 -@lds.i32 = unnamed_addr addrspace(3) global i32 poison, align 4 -@lds.arr = unnamed_addr addrspace(3) global [256 x i32] poison, align 4 +@lds.i32 = unnamed_addr addrspace(3) global i32 undef, align 4 +@lds.arr = unnamed_addr addrspace(3) global [256 x i32] undef, align 4 arsenm wrote: These are unnecessarily regressing from poison to undef https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
https://github.com/arsenm edited https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1333,6 +1308,56 @@ static void addPreloadKernArgHint(Function &F, TargetMachine &TM) { } } +/// The final check and update of the attribute 'amdgpu-waves-per-eu' based on +/// the determined 'amdgpu-flat-work-group-size' attribute. We can't do this +/// during attributor run because the two attributes grow in opposite direction, +/// we should not use any intermediate value to calculate waves per eu until we +/// have a determined flat workgroup size. +static void updateWavesPerEU(Module &M, TargetMachine &TM) { arsenm wrote: It just occurred to me that AMDGPUAttributor is only a Module pass. Should we add or replace it with a CGSCC pass? https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [LoopVectorizer] Bundle partial reductions inside VPMulAccumulateReductionRecipe (PR #136173)
@@ -2056,55 +2056,6 @@ class VPReductionPHIRecipe : public VPHeaderPHIRecipe, } }; -/// A recipe for forming partial reductions. In the loop, an accumulator and SamTebbs33 wrote: I've pre-committed the NFC but rebasing Elvis's changes on top of that has been pretty challenging considering the number of commits on that branch. So I will cherry-pick the NFC on to this branch and it'll just go away once Elvis's PR lands and I rebase this PR on top of main. https://github.com/llvm/llvm-project/pull/136173 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [LoopVectorizer] Bundle partial reductions inside VPMulAccumulateReductionRecipe (PR #136173)
@@ -4923,9 +4923,7 @@ InstructionCost AArch64TTIImpl::getPartialReductionCost( return Invalid; break; case 16: - if (AccumEVT == MVT::i64) -Cost *= 2; - else if (AccumEVT != MVT::i32) + if (AccumEVT != MVT::i32) MacDue wrote: If we allow this case make sure to rename the test from "not_dotp" to "dotp". https://github.com/llvm/llvm-project/pull/136173 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG][X86] Widen <2 x T> vector types for atomic load (PR #120598)
@@ -1200,6 +1200,13 @@ def : Pat<(i16 (atomic_load_16 addr:$src)), (MOV16rm addr:$src)>; def : Pat<(i32 (atomic_load_32 addr:$src)), (MOV32rm addr:$src)>; def : Pat<(i64 (atomic_load_64 addr:$src)), (MOV64rm addr:$src)>; +def : Pat<(v4i32 (scalar_to_vector (i32 (anyext (i16 (atomic_load_16 addr:$src)), + (MOVDI2PDIrm addr:$src)>; // load atomic <2 x i8> +def : Pat<(v4i32 (scalar_to_vector (i32 (atomic_load_32 addr:$src, + (MOVDI2PDIrm addr:$src)>; // load atomic <2 x i16> +def : Pat<(v2i64 (scalar_to_vector (i64 (atomic_load_64 addr:$src, + (MOV64toPQIrm addr:$src)>; // load atomic <2 x i32,float> arsenm wrote: Yes https://github.com/llvm/llvm-project/pull/120598 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AtomicExpand] Add bitcasts when expanding load atomic vector (PR #120716)
@@ -2066,9 +2066,23 @@ bool AtomicExpandImpl::expandAtomicOpToLibcall( I->replaceAllUsesWith(V); } else if (HasResult) { Value *V; -if (UseSizedLibcall) - V = Builder.CreateBitOrPointerCast(Result, I->getType()); -else { +if (UseSizedLibcall) { + // Add bitcasts from Result's scalar type to I's vector type + if (I->getType()->getScalarType()->isPointerTy() && + I->getType()->isVectorTy() && !Result->getType()->isVectorTy()) { +unsigned AS = + cast(I->getType()->getScalarType())->getAddressSpace(); +ElementCount EC = cast(I->getType())->getElementCount(); +Value *BC = Builder.CreateBitCast( +Result, +VectorType::get(IntegerType::get(Ctx, DL.getPointerSizeInBits(AS)), +EC)); +Value *IntToPtr = Builder.CreateIntToPtr( +BC, VectorType::get(PointerType::get(Ctx, AS), EC)); +V = Builder.CreateBitOrPointerCast(IntToPtr, I->getType()); arsenm wrote: This final CreateBitOrPointerCast is a no-op? https://github.com/llvm/llvm-project/pull/120716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [LoopVectorizer] Bundle partial reductions inside VPMulAccumulateReductionRecipe (PR #136173)
@@ -4923,9 +4923,7 @@ InstructionCost AArch64TTIImpl::getPartialReductionCost( return Invalid; break; case 16: - if (AccumEVT == MVT::i64) -Cost *= 2; - else if (AccumEVT != MVT::i32) + if (AccumEVT != MVT::i32) SamTebbs33 wrote: Good spot. Done. https://github.com/llvm/llvm-project/pull/136173 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [KeyInstr] Inline atom info (PR #133481)
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/133481 >From fde8c9e4834a2dad33c1349ef94fc90544a09b65 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Fri, 21 Mar 2025 16:49:14 + Subject: [PATCH 1/2] [KeyInstr] Inline atom info Source atom groups are identified by an atom group number and inlined-at pair, so we simply can copy the atom numbers into the caller when inlining. --- llvm/lib/IR/DebugLoc.cpp | 1 + llvm/lib/Transforms/Utils/InlineFunction.cpp | 3 +- .../KeyInstructions/Generic/inline.ll | 53 +++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp index bdea52180f74a..61f5bd8e9b0a2 100644 --- a/llvm/lib/IR/DebugLoc.cpp +++ b/llvm/lib/IR/DebugLoc.cpp @@ -129,6 +129,7 @@ DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt, // Starting from the top, rebuild the nodes to point to the new inlined-at // location (then rebuilding the rest of the chain behind it) and update the // map of already-constructed inlined-at nodes. + // Key Instructions: InlinedAt fields don't need atom info. for (const DILocation *MD : reverse(InlinedAtLocations)) Cache[MD] = Last = DILocation::getDistinct( Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 7a91620af8272..eaf57e7bf899d 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1819,7 +1819,8 @@ static DebugLoc inlineDebugLoc(DebugLoc OrigDL, DILocation *InlinedAt, DenseMap &IANodes) { auto IA = DebugLoc::appendInlinedAt(OrigDL, InlinedAt, Ctx, IANodes); return DILocation::get(Ctx, OrigDL.getLine(), OrigDL.getCol(), - OrigDL.getScope(), IA); + OrigDL.getScope(), IA, OrigDL.isImplicitCode(), + OrigDL->getAtomGroup(), OrigDL->getAtomRank()); } /// Update inlined instructions' line numbers to diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll new file mode 100644 index 0..c2663ee51a77d --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll @@ -0,0 +1,53 @@ +; RUN: opt %s -passes=inline -S -o - | FileCheck %s + +;; Inline `f` into `g`. The inlined assignment store and add should retain +;; their atom info. + +; CHECK: _Z1gi +; CHECK-NOT: _Z1fi +; CHECK: %add.i = add nsw i32 %mul.i, 1, !dbg [[G1R2:!.*]] +; CHECK-NEXT: store i32 %add.i, ptr %x.i, align 4, !dbg [[G1R1:!.*]] + +; CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2) +; CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) + +define hidden void @_Z1fi(i32 noundef %a) !dbg !11 { +entry: + %a.addr = alloca i32, align 4 + %x = alloca i32, align 4 + store i32 %a, ptr %a.addr, align 4 + %0 = load i32, ptr %a.addr, align 4, !dbg !18 + %mul = mul nsw i32 %0, 2, !dbg !18 + %add = add nsw i32 %mul, 1, !dbg !19 + store i32 %add, ptr %x, align 4, !dbg !20 + ret void, !dbg !22 +} + +define hidden void @_Z1gi(i32 noundef %b) !dbg !23 { +entry: + %b.addr = alloca i32, align 4 + store i32 %b, ptr %b.addr, align 4 + %0 = load i32, ptr %b.addr, align 4, !dbg !24 + call void @_Z1fi(i32 noundef %0), !dbg !24 + ret void, !dbg !25 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_17, file: !1, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.cpp", directory: "/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"clang version 19.0.0"} +!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!12 = !DISubroutineType(types: !13) +!13 = !{} +!18 = !DILocation(line: 2, scope: !11) +!19 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) +!20 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 1) +!22 = !DILocation(line: 3, scope: !11, atomGroup: 2, atomRank: 1) +!23 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!24 = !DILocation(line: 5, scope: !23) +!25 = !DILocation(line: 6, scope: !23, atomGroup: 1, atomRank: 1) >From c89fa2bef4e9c966fcf1e2cc51b4c6ef1d65a37c Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Thu, 1 May 2025
[llvm-branch-commits] [llvm] [KeyInstr] Merge atoms in DILocation::getMergedLocation (PR #133480)
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/133480 >From 2c538d7ba71f82c49800331d996316a96696aee2 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Fri, 21 Mar 2025 11:52:30 + Subject: [PATCH] [KeyInstr] Merge atoms in DILocation::getMergedLocation NFC for builds with LLVM_EXPERIMENTAL_KEY_INSTRUCTIONS=OFF (default). In an ideal world we would be able to track that the merged location is used in multiple source atoms. We can't do this though, so instead we arbitrarily but deterministically pick one. In cases where the InlinedAt field is unchanged we keep the atom with the lowest non-zero rank (highest precedence). If the ranks are equal we choose the smaller non-zero group number (arbitrary choice). In cases where the InlinedAt field is adjusted we generate a new atom group. Keeping the group wouldn't make sense (a source atom is identified by the group number and InlinedAt pair) but discarding the atom info could result in missed is_stmts. Add unittest in MetadataTest.cpp. --- llvm/lib/IR/DebugInfoMetadata.cpp | 54 ++-- llvm/unittests/IR/MetadataTest.cpp | 134 + 2 files changed, 182 insertions(+), 6 deletions(-) diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index e3b105a6ac109..30ad9c11b2614 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -302,11 +302,15 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { // Merge the two locations if possible, using the supplied // inlined-at location for the created location. - auto MergeLocPair = [&C](const DILocation *L1, const DILocation *L2, - DILocation *InlinedAt) -> DILocation * { + auto *LocAIA = LocA->getInlinedAt(); + auto *LocBIA = LocB->getInlinedAt(); + auto MergeLocPair = [&C, LocAIA, + LocBIA](const DILocation *L1, const DILocation *L2, + DILocation *InlinedAt) -> DILocation * { if (L1 == L2) return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(), - InlinedAt); + InlinedAt, L1->isImplicitCode(), + L1->getAtomGroup(), L1->getAtomRank()); // If the locations originate from different subprograms we can't produce // a common location. @@ -342,8 +346,44 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { bool SameCol = L1->getColumn() == L2->getColumn(); unsigned Line = SameLine ? L1->getLine() : 0; unsigned Col = SameLine && SameCol ? L1->getColumn() : 0; - -return DILocation::get(C, Line, Col, Scope, InlinedAt); +bool IsImplicitCode = L1->isImplicitCode() && L2->isImplicitCode(); +uint64_t Group = 0; +uint64_t Rank = 0; +if (SameLine) { + if (L1->getAtomGroup() || L2->getAtomGroup()) { +// If we're preserving the same matching inlined-at field we can +// preserve the atom. +if (LocBIA == LocAIA && InlinedAt == LocBIA) { + // Deterministically keep the lowest non-zero ranking atom group + // number. + // FIXME: It would be nice if we could track that an instruction + // belongs to two source atoms. + bool UseL1Atom = [L1, L2]() { +if (L1->getAtomRank() == L2->getAtomRank()) { + // Arbitrarily choose the lowest non-zero group number. + if (!L1->getAtomGroup() || !L2->getAtomGroup()) +return !L2->getAtomGroup(); + return L1->getAtomGroup() < L2->getAtomGroup(); +} +// Choose the lowest non-zero rank. +if (!L1->getAtomRank() || !L2->getAtomRank()) + return !L2->getAtomRank(); +return L1->getAtomRank() < L2->getAtomRank(); + }(); + Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup(); + Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank(); +} else { + // If either instruction is part of a source atom, reassign it a new + // atom group. This essentially regresses to non-key-instructions + // behaviour (now that it's the only instruction in its group it'll + // probably get is_stmt applied). + Group = C.incNextAtomGroup(); + Rank = 1; +} + } +} +return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode, + Group, Rank); }; DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr; @@ -370,7 +410,9 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { // historically picked A's scope, and a nullptr inlined-at location, so that // behavior is mimicked here but I am not sure if this is always the correct // way to handle this. - return DILocation::get(C, 0, 0, LocA
[llvm-branch-commits] [llvm] 08f8efd - Revert "[clang] Add scoped enum support to `StreamingDiagnostic` (#138089)"
Author: Vlad Serebrennikov Date: 2025-05-01T18:10:57+04:00 New Revision: 08f8efd49c7043fc8bda811041168106009612e9 URL: https://github.com/llvm/llvm-project/commit/08f8efd49c7043fc8bda811041168106009612e9 DIFF: https://github.com/llvm/llvm-project/commit/08f8efd49c7043fc8bda811041168106009612e9.diff LOG: Revert "[clang] Add scoped enum support to `StreamingDiagnostic` (#138089)" This reverts commit 001cc34275111df842edbaa874b7319eef930c81. Added: Modified: clang/include/clang/Basic/Diagnostic.h clang/include/clang/Sema/Sema.h clang/lib/AST/ODRDiagsEmitter.cpp clang/lib/Parse/ParseDecl.cpp clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParsePragma.cpp clang/lib/Parse/Parser.cpp clang/lib/Sema/SemaAccess.cpp clang/lib/Sema/SemaCUDA.cpp clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaDeclObjC.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaInit.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaStmt.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Sema/SemaType.cpp clang/lib/Sema/TreeTransform.h llvm/include/llvm/ADT/STLForwardCompat.h Removed: diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 92ab61b95a7c6..19524856a9bb3 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -1429,22 +1429,6 @@ operator<<(const StreamingDiagnostic &DB, T *DC) { return DB; } -// Convert scope enums to their underlying type, so that we don't have -// clutter the emitting code with `llvm::to_underlying()`. -// We also need to disable implicit conversion for the first argument, -// because classes that derive from StreamingDiagnostic define their own -// templated operator<< that accept a wide variety of types, leading -// to ambiguity. -template -inline std::enable_if_t< -std::is_same_v, StreamingDiagnostic> && -llvm::is_scoped_enum_v>, -const StreamingDiagnostic &> -operator<<(const T &DB, U &&SE) { - DB << llvm::to_underlying(SE); - return DB; -} - inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, SourceLocation L) { DB.AddSourceRange(CharSourceRange::getTokenRange(L)); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 003583f84cf97..28313f45b1228 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -220,6 +220,11 @@ enum class AssignmentAction { Casting, Passing_CFAudited }; +inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, + const AssignmentAction &AA) { + DB << llvm::to_underlying(AA); + return DB; +} namespace threadSafety { class BeforeSet; @@ -15466,6 +15471,12 @@ void Sema::PragmaStack::Act(SourceLocation PragmaLocation, llvm::StringRef StackSlotLabel, AlignPackInfo Value); +inline const StreamingDiagnostic & +operator<<(const StreamingDiagnostic &DB, Sema::StringEvaluationContext Ctx) { + DB << llvm::to_underlying(Ctx); + return DB; +} + } // end namespace clang #endif diff --git a/clang/lib/AST/ODRDiagsEmitter.cpp b/clang/lib/AST/ODRDiagsEmitter.cpp index 74f3881ed3c96..37f0f68c92355 100644 --- a/clang/lib/AST/ODRDiagsEmitter.cpp +++ b/clang/lib/AST/ODRDiagsEmitter.cpp @@ -461,8 +461,10 @@ bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod( } if (FirstMethod->getImplementationControl() != SecondMethod->getImplementationControl()) { -DiagError(ControlLevel) << FirstMethod->getImplementationControl(); -DiagNote(ControlLevel) << SecondMethod->getImplementationControl(); +DiagError(ControlLevel) +<< llvm::to_underlying(FirstMethod->getImplementationControl()); +DiagNote(ControlLevel) << llvm::to_underlying( +SecondMethod->getImplementationControl()); return true; } if (FirstMethod->isThisDeclarationADesignatedInitializer() != diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index cd6464678c4b5..9dd9d9c637592 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2578,7 +2578,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate && D.isFirstDeclarator()) { Diag(CommaLoc, diag::err_multiple_template_declarators) - << TemplateInfo.Kind; + << llvm::to_underlying(TemplateInfo.Kind); } // Parse the next declarator. dif
[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add optional parameters for RootConstants (PR #138007)
@@ -82,6 +82,8 @@ class RootSignatureParser { struct ParsedConstantParams { std::optional Reg; std::optional Num32BitConstants; +std::optional Space; joaosaffran wrote: Space is used whenever we have registers, shouldn't this be an optional field in the registers struct? https://github.com/llvm/llvm-project/pull/138007 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add optional parameters for RootConstants (PR #138007)
@@ -255,7 +255,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) { TEST_F(ParseHLSLRootSignatureTest, ValidParseRootConsantsTest) { joaosaffran wrote: I would suggest having tests cases for mandatory and optional fields. Also test cases to verify the error cases as well, if possible https://github.com/llvm/llvm-project/pull/138007 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add mandatory parameters for RootConstants (PR #138002)
https://github.com/joaosaffran commented: Can we add tests to verify error scenarios as well? https://github.com/llvm/llvm-project/pull/138002 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. (#135769) (PR #138142)
https://github.com/nikic approved this pull request. https://github.com/llvm/llvm-project/pull/138142 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [KeyInstr] Merge atoms in DILocation::getMergedLocation (PR #133480)
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/133480 >From 2c538d7ba71f82c49800331d996316a96696aee2 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Fri, 21 Mar 2025 11:52:30 + Subject: [PATCH 1/3] [KeyInstr] Merge atoms in DILocation::getMergedLocation NFC for builds with LLVM_EXPERIMENTAL_KEY_INSTRUCTIONS=OFF (default). In an ideal world we would be able to track that the merged location is used in multiple source atoms. We can't do this though, so instead we arbitrarily but deterministically pick one. In cases where the InlinedAt field is unchanged we keep the atom with the lowest non-zero rank (highest precedence). If the ranks are equal we choose the smaller non-zero group number (arbitrary choice). In cases where the InlinedAt field is adjusted we generate a new atom group. Keeping the group wouldn't make sense (a source atom is identified by the group number and InlinedAt pair) but discarding the atom info could result in missed is_stmts. Add unittest in MetadataTest.cpp. --- llvm/lib/IR/DebugInfoMetadata.cpp | 54 ++-- llvm/unittests/IR/MetadataTest.cpp | 134 + 2 files changed, 182 insertions(+), 6 deletions(-) diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index e3b105a6ac109..30ad9c11b2614 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -302,11 +302,15 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { // Merge the two locations if possible, using the supplied // inlined-at location for the created location. - auto MergeLocPair = [&C](const DILocation *L1, const DILocation *L2, - DILocation *InlinedAt) -> DILocation * { + auto *LocAIA = LocA->getInlinedAt(); + auto *LocBIA = LocB->getInlinedAt(); + auto MergeLocPair = [&C, LocAIA, + LocBIA](const DILocation *L1, const DILocation *L2, + DILocation *InlinedAt) -> DILocation * { if (L1 == L2) return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(), - InlinedAt); + InlinedAt, L1->isImplicitCode(), + L1->getAtomGroup(), L1->getAtomRank()); // If the locations originate from different subprograms we can't produce // a common location. @@ -342,8 +346,44 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { bool SameCol = L1->getColumn() == L2->getColumn(); unsigned Line = SameLine ? L1->getLine() : 0; unsigned Col = SameLine && SameCol ? L1->getColumn() : 0; - -return DILocation::get(C, Line, Col, Scope, InlinedAt); +bool IsImplicitCode = L1->isImplicitCode() && L2->isImplicitCode(); +uint64_t Group = 0; +uint64_t Rank = 0; +if (SameLine) { + if (L1->getAtomGroup() || L2->getAtomGroup()) { +// If we're preserving the same matching inlined-at field we can +// preserve the atom. +if (LocBIA == LocAIA && InlinedAt == LocBIA) { + // Deterministically keep the lowest non-zero ranking atom group + // number. + // FIXME: It would be nice if we could track that an instruction + // belongs to two source atoms. + bool UseL1Atom = [L1, L2]() { +if (L1->getAtomRank() == L2->getAtomRank()) { + // Arbitrarily choose the lowest non-zero group number. + if (!L1->getAtomGroup() || !L2->getAtomGroup()) +return !L2->getAtomGroup(); + return L1->getAtomGroup() < L2->getAtomGroup(); +} +// Choose the lowest non-zero rank. +if (!L1->getAtomRank() || !L2->getAtomRank()) + return !L2->getAtomRank(); +return L1->getAtomRank() < L2->getAtomRank(); + }(); + Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup(); + Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank(); +} else { + // If either instruction is part of a source atom, reassign it a new + // atom group. This essentially regresses to non-key-instructions + // behaviour (now that it's the only instruction in its group it'll + // probably get is_stmt applied). + Group = C.incNextAtomGroup(); + Rank = 1; +} + } +} +return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode, + Group, Rank); }; DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr; @@ -370,7 +410,9 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { // historically picked A's scope, and a nullptr inlined-at location, so that // behavior is mimicked here but I am not sure if this is always the correct // way to handle this. - return DILocation::get(C, 0, 0,
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; + + // We assume a constante increase between instructions. + const unsigned OffsetIncrease = 4; + void updateLineOffset() { CurrentOffset += OffsetIncrease; } + + // An anonymous type for index type. + LVType *NodeIndexType = nullptr; + + std::unique_ptr DbgValueRanges; + + // Record the last assigned file index for each compile unit. + using LVIndexFiles = std::map; + LVIndexFiles IndexFiles; jmorse wrote: It wasn't immediately obvious to me that this is a per-CU counter of the /next/ FileID to assign to a new file that gets discovered. I think it's worth recording in the comment here that this data-structure is to aid mapping DIFiles onto a DWARF-like file table, to explain what's going on. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -728,14 +514,16 @@ void LVDWARFReader::createLineAndFileRecords( for (const DWARFDebugLine::FileNameEntry &Entry : Lines->Prologue.FileNames) { std::string Directory; - if (Lines->getDirectoryForEntry(Entry, Directory)) -Directory = transformPath(Directory); + Lines->getDirectoryForEntry(Entry, Directory); if (Directory.empty()) Directory = std::string(CompileUnit->getCompilationDirectory()); - std::string File = transformPath(dwarf::toStringRef(Entry.Name)); + // Take just the filename component, as it may be contain the full + // path that would be added to the already existing path in Directory. jmorse wrote: This is a functional change to the DWARF reader, is it related to adding the IRReader, or can we defer it to some other patch instead? https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). jmorse wrote: It's not clear to me what this means (more elaborated comment please). https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -2124,6 +2125,138 @@ layout and given the number of matches. - Total 71 8 +IR (Textual representation and bitcode) SUPPORT +~~~ +The below example is used to show the IR output generated by +:program:`llvm-debuginfo-analyzer`. We compiled the example for a +IR 64-bit target with Clang (-O0 -g --target=x86_64-linux): + +.. code-block:: c++ + + 1 using INTPTR = const int *; + 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { + 3if (ParamBool) { + 4 typedef int INTEGER; + 5 const INTEGER CONSTANT = 7; + 6 return CONSTANT; + 7} + 8return ParamUnsigned; + 9 } + +PRINT BASIC DETAILS +^^^ +The following command prints basic details for all the logical elements +sorted by the debug information internal offset; it includes its lexical +level and debug info format. + +.. code-block:: none + + llvm-debuginfo-analyzer --attribute=level,format + --output-sort=offset + --print=scopes,symbols,types,lines,instructions + test-clang.ll + +or + +.. code-block:: none + + llvm-debuginfo-analyzer --attribute=level,format + --output-sort=offset + --print=elements + test-clang.ll + +Each row represents an element that is present within the debug +information. The first column represents the scope level, followed by +the associated line number (if any), and finally the description of +the element. + +.. code-block:: none + + Logical View: + [000] {File} 'test-clang.ll' -> Textual IR + + [001] {CompileUnit} 'test.cpp' + [002] 2 {Function} extern not_inlined 'foo' -> 'int' + [003] {Block} + [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' + [004] 5 {Line} + [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32' + [004] 6 {Line} + [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33' + [004] 6 {Line} + [004] {Code} 'br label %return, !dbg !33' + [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' + [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' + [003] 2 {Parameter} 'ParamBool' -> 'bool' + [003] 4 {TypeAlias} 'INTEGER' -> 'int' + [003] 2 {Line} + [003] {Code} '%retval = alloca i32, align 4' + [003] {Code} '%ParamPtr.addr = alloca ptr, align 8' + [003] {Code} '%ParamUnsigned.addr = alloca i32, align 4' + [003] {Code} '%ParamBool.addr = alloca i8, align 1' + [003] {Code} '%CONSTANT = alloca i32, align 4' + [003] {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8' + [003] {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4' + [003] {Code} '%storedv = zext i1 %ParamBool to i8' + [003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1' + [003] 8 {Line} + [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34' + [003] 8 {Line} + [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35' + [003] 8 {Line} + [003] {Code} 'br label %return, !dbg !35' + [003] 9 {Line} + [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36' + [003] 9 {Line} + [003] {Code} 'ret i32 %2, !dbg !36' + [003] 3 {Line} + [003] 3 {Line} + [003] 3 {Line} + [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26' + [002] 1 {TypeAlias} 'INTPTR' -> '* const int' + +SELECT LOGICAL ELEMENTS +^^^ +The following prints all *instructions*, *symbols* and *types* that +contain **'block'** or **'.store'** in their names or types, using a tab +layout and given the number of matches. + +.. code-block:: none jmorse wrote: I wonder if there's a more illustrative example to motivate the reader -- is it possible to search for "INTPTR" and discover both the type alias and the parameter? That's the sort of query I think I'd end up making: "I can see this type in the output format, but why is it present? -> Ah, it's a parameter to a function". (The current example is fine, I'm just trying to imagine a better one). https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; + + // We assume a constante increase between instructions. + const unsigned OffsetIncrease = 4; + void updateLineOffset() { CurrentOffset += OffsetIncrease; } + + // An anonymous type for index type. + LVType *NodeIndexType = nullptr; + + std::unique_ptr DbgValueRanges; + + // Record the last assigned file index for each compile unit. + using LVIndexFiles = std::map; + LVIndexFiles IndexFiles; + + void updateFileIndex(LVScopeCompileUnit *CompileUnit, size_t FileIndex) { +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter == IndexFiles.end()) + IndexFiles.emplace(CompileUnit, FileIndex); +else + Iter->second = FileIndex; + } + + // Get the current assigned index file for the given compile unit. + size_t getFileIndex(LVScopeCompileUnit *CompileUnit) { +size_t FileIndex = 0; +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter != IndexFiles.end()) + FileIndex = Iter->second; +return FileIndex; + } + + // Collect the compile unit metadata files. + using LVCompileUnitFiles = std::map; + LVCompileUnitFiles CompileUnitFiles; + + size_t getOrCreateSourceID(const DIFile *File); + + // Associate the logical elements to metadata objects. + using LVMDObjects = std::map; + LVMDObjects MDObjects; + + void addMD(const MDNode *MD, LVElement *Element) { +if (MDObjects.find(MD) == MDObjects.end()) + MDObjects.emplace(MD, Element); + } + LVElement *getElementForSeenMD(const MDNode *MD) const { +LVMDObjects::const_iterator Iter = MDObjects.find(MD); +return Iter != MDObjects.end() ? Iter->second : nullptr; + } + LVScope *getScopeForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVSymbol *getSymbolForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVType *getTypeForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVType *getLineForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + + // Inlined concrete scopes with its associated inlined abstract scopes. jmorse wrote: ```suggestion // Inlined concrete scopes mapped to the associated inlined abstract scopes. ``` https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -56,6 +61,17 @@ Error LVReaderHandler::createReader(StringRef Filename, LVReaders &Readers, return std::make_unique(Filename, FileFormatName, Pdb, W, ExePath); } +if (isa(Input)) { + IRObjectFile *Ir = cast(Input); + return std::make_unique(Filename, FileFormatName, Ir, W); +} +if (isa(Input)) { + // If the filename extension is '.ll' create a IR reader. jmorse wrote: ```suggestion // If the filename extension is '.ll' create an IR reader. ``` https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
https://github.com/jmorse edited https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { jmorse wrote: This is a style thing, but I really appreciate other parts of LLVM where all the data-members are declared at the top of the class definition, so that you can get a view of what information the class contains before moving on to the methods. If this isn't the style that debuginfo-analyzer uses elsewhere, then it's fine to leave it as it is and stay consistent. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -29,7 +30,9 @@ namespace logicalview { using LVReaders = std::vector>; using ArgVector = std::vector; -using PdbOrObj = PointerUnion; +using PdbOrObjOrIr = +PointerUnion; jmorse wrote: I feel we should be able to invent a more symbolic name for this type -- something like "InputHandle" perhaps? That communicates more about the purpose of the type than just a list of types it might be. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; + + // We assume a constante increase between instructions. jmorse wrote: ```suggestion // We assume a constant instruction-size increase between instructions. ``` https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { jmorse wrote: Given that DIFiles are unique'd by LLVM, I can forsee a situation where the same DIFile pointer is used in two DICompileUnits with (theoretically) two different FileIndex numbers, but this will only store one FileIndex number and return it for either DICompileUnit. Will this cause problems in the rest of llvm-debuginfo-analyzer? https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. jmorse wrote: The DWARF differences are something that llvm-debuginfo-analyzer abstracts over, thus we probably don't need to mention it here. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; jmorse wrote: IMO the more natural approach is to store the current DWLang code and test it each time to see whether it's Fortran -- it's a style thing, but IMO better signals that Fortran isn't special, instead the input language is significant and some parts of llvm-debuginfo-analyzer test for whether the input is fortran. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { jmorse wrote: I think this can be `end()` instead of `cend()` -- both are correct, but `cend` is abnormal and there's no need to attract attention to it here. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1333,6 +1308,56 @@ static void addPreloadKernArgHint(Function &F, TargetMachine &TM) { } } +/// The final check and update of the attribute 'amdgpu-waves-per-eu' based on +/// the determined 'amdgpu-flat-work-group-size' attribute. We can't do this +/// during attributor run because the two attributes grow in opposite direction, +/// we should not use any intermediate value to calculate waves per eu until we +/// have a determined flat workgroup size. +static void updateWavesPerEU(Module &M, TargetMachine &TM) { + for (Function &F : M) { +const GCNSubtarget &ST = TM.getSubtarget(F); + +auto FlatWgrpSizeAttr = arsenm wrote: no auto https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
https://github.com/arsenm commented: Tests look like they were reverted to some old revision and lost updates https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)
@@ -1408,8 +1433,14 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM, } } - ChangeStatus Change = A.run(); - return Change == ChangeStatus::CHANGED; + bool Changed = A.run() == ChangeStatus::CHANGED; + + if (Changed && (LTOPhase == ThinOrFullLTOPhase::None || + LTOPhase == ThinOrFullLTOPhase::FullLTOPostLink || + LTOPhase == ThinOrFullLTOPhase::ThinLTOPostLink)) arsenm wrote: Comment why this is skipping the prelink cases? https://github.com/llvm/llvm-project/pull/123995 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [KeyInstr] Add Atom Group waterline to LLVMContext (PR #133478)
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/133478 >From 511ee0a22ab388a8794dd4f487a23615eb4ad800 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 18 Mar 2025 16:50:17 + Subject: [PATCH 1/5] [KeyInstr] Add Atom Group waterline to LLVMContext The waterline is managed through DILocation creation, LLVMContext::incNextAtomGroup, and LLVMContext::updateAtomGroupWaterline. Add unittest. --- llvm/include/llvm/IR/LLVMContext.h | 8 +++ llvm/lib/IR/DebugInfoMetadata.cpp | 3 +++ llvm/lib/IR/LLVMContext.cpp| 8 +++ llvm/lib/IR/LLVMContextImpl.h | 10 llvm/unittests/IR/MetadataTest.cpp | 38 ++ 5 files changed, 67 insertions(+) diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h index bbd125fd38cf1..d3cdd31e0b12f 100644 --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/include/llvm/IR/LLVMContext.h @@ -335,6 +335,14 @@ class LLVMContext { StringRef getDefaultTargetFeatures(); void setDefaultTargetFeatures(StringRef Features); + /// Key Instructions: update the highest number atom group emitted for any + /// function. + void updateAtomGroupWaterline(uint64_t G); + + /// Key Instructions: get the next free atom group number and increment + /// the global tracker. + uint64_t incNextAtomGroup(); + private: // Module needs access to the add/removeModule methods. friend class Module; diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index f4f9fca38945c..aefda2f7be0b0 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -67,6 +67,9 @@ DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits"); #endif + if (AtomRank) +C.updateAtomGroupWaterline(AtomGroup + 1); + assert((MDs.size() == 1 || MDs.size() == 2) && "Expected a scope and optional inlined-at"); // Set line and column. diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index 447e5d92e0b99..4781085b30431 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -377,3 +377,11 @@ StringRef LLVMContext::getDefaultTargetFeatures() { void LLVMContext::setDefaultTargetFeatures(StringRef Features) { pImpl->DefaultTargetFeatures = Features; } + +void LLVMContext::updateAtomGroupWaterline(uint64_t V) { + pImpl->NextAtomGroup = std::max(pImpl->NextAtomGroup, V); +} + +uint64_t LLVMContext::incNextAtomGroup() { + return pImpl->NextAtomGroup++; +} diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 99f0d8837de52..5a52d41834095 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1832,6 +1832,16 @@ class LLVMContextImpl { std::string DefaultTargetCPU; std::string DefaultTargetFeatures; + + /// The next available source atom group number. The front end is responsible + /// for assigning source atom numbers, but certain optimisations need to + /// assign new group numbers to a set of instructions. Most often code + /// duplication optimisations like loop unroll. Tracking a global maximum + /// value means we can know (cheaply) we're never using a group number that's + /// already used within this function. + /// + /// Start a 1 because 0 means the source location isn't part of an atom group. + uint64_t NextAtomGroup = 1; }; } // end namespace llvm diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 94cebb0406598..8a1c1f9d306c6 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -6,6 +6,7 @@ // //===--===// +#include "../lib/IR/LLVMContextImpl.h" #include "llvm/IR/Metadata.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -1366,6 +1367,43 @@ TEST_F(DILocationTest, discriminatorSpecialCases) { EXPECT_EQ(std::nullopt, L4->cloneByMultiplyingDuplicationFactor(0x1000)); } +TEST_F(DILocationTest, KeyInstructions) { + Context.pImpl->NextAtomGroup = 1; + + EXPECT_EQ(Context.pImpl->NextAtomGroup, 1u); + DILocation *A1 = DILocation::get(Context, 1, 0, getSubprogram(), nullptr, false, 1, 2); + // The group is only applied to the DILocation if the build has opted into + // the additional DILocation fields needed for the feature. +#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS + EXPECT_EQ(A1->getAtomGroup(), 1u); + EXPECT_EQ(A1->getAtomRank(), 2u); +#else + EXPECT_EQ(A1->getAtomGroup(), 0u); + EXPECT_EQ(A1->getAtomRank(), 0u); +#endif + + // Group number 1 has been "used" so next available is 2. + EXPECT_EQ(Context.pImpl->NextAtomGroup, 2u); + + // Set a group number higher than current + 1, then check the waterline. + DILocation::get(Context, 2, 0, getSubprogram(), nullptr, false, 5, 1); + EXPECT_EQ(C
[llvm-branch-commits] [llvm] [KeyInstr] Merge atoms in DILocation::getMergedLocation (PR #133480)
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/133480 >From 2c538d7ba71f82c49800331d996316a96696aee2 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Fri, 21 Mar 2025 11:52:30 + Subject: [PATCH 1/4] [KeyInstr] Merge atoms in DILocation::getMergedLocation NFC for builds with LLVM_EXPERIMENTAL_KEY_INSTRUCTIONS=OFF (default). In an ideal world we would be able to track that the merged location is used in multiple source atoms. We can't do this though, so instead we arbitrarily but deterministically pick one. In cases where the InlinedAt field is unchanged we keep the atom with the lowest non-zero rank (highest precedence). If the ranks are equal we choose the smaller non-zero group number (arbitrary choice). In cases where the InlinedAt field is adjusted we generate a new atom group. Keeping the group wouldn't make sense (a source atom is identified by the group number and InlinedAt pair) but discarding the atom info could result in missed is_stmts. Add unittest in MetadataTest.cpp. --- llvm/lib/IR/DebugInfoMetadata.cpp | 54 ++-- llvm/unittests/IR/MetadataTest.cpp | 134 + 2 files changed, 182 insertions(+), 6 deletions(-) diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index e3b105a6ac109..30ad9c11b2614 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -302,11 +302,15 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { // Merge the two locations if possible, using the supplied // inlined-at location for the created location. - auto MergeLocPair = [&C](const DILocation *L1, const DILocation *L2, - DILocation *InlinedAt) -> DILocation * { + auto *LocAIA = LocA->getInlinedAt(); + auto *LocBIA = LocB->getInlinedAt(); + auto MergeLocPair = [&C, LocAIA, + LocBIA](const DILocation *L1, const DILocation *L2, + DILocation *InlinedAt) -> DILocation * { if (L1 == L2) return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(), - InlinedAt); + InlinedAt, L1->isImplicitCode(), + L1->getAtomGroup(), L1->getAtomRank()); // If the locations originate from different subprograms we can't produce // a common location. @@ -342,8 +346,44 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { bool SameCol = L1->getColumn() == L2->getColumn(); unsigned Line = SameLine ? L1->getLine() : 0; unsigned Col = SameLine && SameCol ? L1->getColumn() : 0; - -return DILocation::get(C, Line, Col, Scope, InlinedAt); +bool IsImplicitCode = L1->isImplicitCode() && L2->isImplicitCode(); +uint64_t Group = 0; +uint64_t Rank = 0; +if (SameLine) { + if (L1->getAtomGroup() || L2->getAtomGroup()) { +// If we're preserving the same matching inlined-at field we can +// preserve the atom. +if (LocBIA == LocAIA && InlinedAt == LocBIA) { + // Deterministically keep the lowest non-zero ranking atom group + // number. + // FIXME: It would be nice if we could track that an instruction + // belongs to two source atoms. + bool UseL1Atom = [L1, L2]() { +if (L1->getAtomRank() == L2->getAtomRank()) { + // Arbitrarily choose the lowest non-zero group number. + if (!L1->getAtomGroup() || !L2->getAtomGroup()) +return !L2->getAtomGroup(); + return L1->getAtomGroup() < L2->getAtomGroup(); +} +// Choose the lowest non-zero rank. +if (!L1->getAtomRank() || !L2->getAtomRank()) + return !L2->getAtomRank(); +return L1->getAtomRank() < L2->getAtomRank(); + }(); + Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup(); + Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank(); +} else { + // If either instruction is part of a source atom, reassign it a new + // atom group. This essentially regresses to non-key-instructions + // behaviour (now that it's the only instruction in its group it'll + // probably get is_stmt applied). + Group = C.incNextAtomGroup(); + Rank = 1; +} + } +} +return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode, + Group, Rank); }; DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr; @@ -370,7 +410,9 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { // historically picked A's scope, and a nullptr inlined-at location, so that // behavior is mimicked here but I am not sure if this is always the correct // way to handle this. - return DILocation::get(C, 0, 0,
[llvm-branch-commits] [llvm] [KeyInstr] Merge atoms in DILocation::getMergedLocation (PR #133480)
OCHyams wrote: @SLTozer are you happy with my responses to your inline comments? And a few weeks ago offline we discussed that the slightly not-nfc change to preserve isImplicitCode is probably ok. Are you still happy with that? @jmorse I used some early-exits in the lambda - does that look ok? I can try to separate some bits out if you'd prefer (I'm currently erring on the side of keeping all the context in one place). I added comments to the function arguments to highlight which integer is which (I prefer this approach rather than introducing more boilerplate for code that won't often be touched, but I'm happy to alter further if needed). Slightly annoyingly this pushes the unittest calls over the column limit... I could shorten "AtomGroup" and "AtomRank" to just "Atom" and "Rank", but "Rank" feels too nebulous? https://github.com/llvm/llvm-project/pull/133480 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -121,7 +121,24 @@ class LVReader { #undef LV_OBJECT_ALLOCATOR + // Scopes with ranges for current compile unit. It is used to find a line jmorse wrote: (for the benefit of any other reviewers, these have been hoisted out of the object-file and DWARF readers to be more generic) https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [BOLT][NFCI] Simplify DataAggregator using traces (PR #138181)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- bolt/include/bolt/Profile/DataAggregator.h bolt/lib/Profile/DataAggregator.cpp `` View the diff from clang-format here. ``diff diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp index 4e42e0d80..f74cf0264 100644 --- a/bolt/lib/Profile/DataAggregator.cpp +++ b/bolt/lib/Profile/DataAggregator.cpp @@ -1469,7 +1469,7 @@ void DataAggregator::processBranchEvents() { NamedRegionTimer T("processBranch", "Processing branch events", TimerGroupName, TimerGroupDesc, opts::TimeAggregator); - for (const auto &[Trace, Info]: Traces) { + for (const auto &[Trace, Info] : Traces) { if (Trace.From != Trace.To) doBranch(Trace.From, Trace.To, Info.TakenCount, Info.MispredCount); if (Trace.FallthroughEnd) `` https://github.com/llvm/llvm-project/pull/138181 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add optional parameters for RootConstants (PR #138007)
@@ -255,7 +255,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) { TEST_F(ParseHLSLRootSignatureTest, ValidParseRootConsantsTest) { inbelic wrote: Sure, I can add more. Just wasn't sure what the right balance is, as many of the error reports are already tested. I guess more tests never hurt tho. Will update. https://github.com/llvm/llvm-project/pull/138007 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add optional parameters for RootConstants (PR #138007)
@@ -82,6 +82,8 @@ class RootSignatureParser { struct ParsedConstantParams { std::optional Reg; std::optional Num32BitConstants; +std::optional Space; inbelic wrote: I think having it separate maps closer and clearer to the metadata and parameter specification https://github.com/llvm/llvm-project/pull/138007 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [llvm] Introduce callee_type metadata (PR #87573)
@@ -5096,6 +5097,23 @@ void Verifier::visitCallsiteMetadata(Instruction &I, MDNode *MD) { visitCallStackMetadata(MD); } +void Verifier::visitCalleeTypeMetadata(Instruction &I, MDNode *MD) { + Check(isa(I), "!callee_type metadata should only exist on calls", +&I); + CallBase *CB = cast(&I); + Check(CB->isIndirectCall(), +"!callee_type metadata should only exist on indirect function calls", +&I); nikic wrote: This cannot be a verifier rule, because it would mean that performing a RAUW operation can result in a verifier failure. https://github.com/llvm/llvm-project/pull/87573 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits