aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-09-10 18:53:34 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-09-10 18:53:34 +0000
commit5bf671d658572f2de62bde5767e63873cb5fc708 (patch)
treefa9bace9652920533dec17d1e227c3fb3929fa8b
parente3fb157234c40dfa2746dbb08edd8730cc4b78c4 (diff)
downloadsrc-5bf671d658572f2de62bde5767e63873cb5fc708.tar.gz
src-5bf671d658572f2de62bde5767e63873cb5fc708.zip
Vendor import of llvm-project branch release/15.x llvmorg-15.0.0-9-g1c73596d3454.vendor/llvm-project/llvmorg-15.0.0-9-g1c73596d3454
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp19
-rw-r--r--clang/lib/Sema/SemaExpr.cpp5
-rw-r--r--llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h30
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp5
-rw-r--r--llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp302
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp11
-rw-r--r--llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp28
7 files changed, 336 insertions, 64 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 5991cf23d5dc..cf6549e2a5bd 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2329,25 +2329,6 @@ private:
!PrevToken->MatchingParen)
return TT_PointerOrReference;
- // For "} &&"
- if (PrevToken->is(tok::r_brace) && Tok.is(tok::ampamp)) {
- const FormatToken *MatchingLBrace = PrevToken->MatchingParen;
-
- // We check whether there is a TemplateCloser(">") to indicate it's a
- // template or not. If it's not a template, "&&" is likely a reference
- // operator.
- // struct {} &&ref = {};
- if (!MatchingLBrace)
- return TT_PointerOrReference;
- FormatToken *BeforeLBrace = MatchingLBrace->getPreviousNonComment();
- if (!BeforeLBrace || BeforeLBrace->isNot(TT_TemplateCloser))
- return TT_PointerOrReference;
-
- // If it is a template, "&&" is a binary operator.
- // enable_if<>{} && ...
- return TT_BinaryOperator;
- }
-
if (PrevToken->Tok.isLiteral() ||
PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
tok::kw_false, tok::r_brace)) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0e24237faae5..83081bbf0aa0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17600,6 +17600,11 @@ static void RemoveNestedImmediateInvocation(
DRSet.erase(E);
return E;
}
+ ExprResult TransformLambdaExpr(LambdaExpr *E) {
+ // Do not rebuild lambdas to avoid creating a new type.
+ // Lambdas have already been processed inside their eval context.
+ return E;
+ }
bool AlwaysRebuild() { return false; }
bool ReplacingOriginal() { return true; }
bool AllowSkippingCXXConstructExpr() {
diff --git a/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h b/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h
index 26686143af95..a54f8f5d2db8 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/MarkupFilter.h
@@ -26,11 +26,14 @@
namespace llvm {
namespace symbolize {
+class LLVMSymbolizer;
+
/// Filter to convert parsed log symbolizer markup elements into human-readable
/// text.
class MarkupFilter {
public:
- MarkupFilter(raw_ostream &OS, Optional<bool> ColorsEnabled = llvm::None);
+ MarkupFilter(raw_ostream &OS, LLVMSymbolizer &Symbolizer,
+ Optional<bool> ColorsEnabled = llvm::None);
/// Filters a line containing symbolizer markup and writes the human-readable
/// results to the output stream.
@@ -57,6 +60,7 @@ private:
uint64_t ModuleRelativeAddr;
bool contains(uint64_t Addr) const;
+ uint64_t getModuleRelativeAddr(uint64_t Addr) const;
};
// An informational module line currently being constructed. As many mmap
@@ -67,6 +71,15 @@ private:
SmallVector<const MMap *> MMaps = {};
};
+ // The semantics of a possible program counter value.
+ enum class PCType {
+ // The address is a return address and must be adjusted to point to the call
+ // itself.
+ ReturnAddress,
+ // The address is the precise location in the code and needs no adjustment.
+ PreciseCode,
+ };
+
bool tryContextualElement(const MarkupNode &Node,
const SmallVector<MarkupNode> &DeferredNodes);
bool tryMMap(const MarkupNode &Element,
@@ -83,6 +96,9 @@ private:
bool tryPresentation(const MarkupNode &Node);
bool trySymbol(const MarkupNode &Node);
+ bool tryPC(const MarkupNode &Node);
+ bool tryBackTrace(const MarkupNode &Node);
+ bool tryData(const MarkupNode &Node);
bool trySGR(const MarkupNode &Node);
@@ -91,6 +107,9 @@ private:
void restoreColor();
void resetColor();
+ void printRawElement(const MarkupNode &Element);
+ void printValue(Twine Value);
+
Optional<Module> parseModule(const MarkupNode &Element) const;
Optional<MMap> parseMMap(const MarkupNode &Element) const;
@@ -99,19 +118,26 @@ private:
Optional<uint64_t> parseSize(StringRef Str) const;
Optional<SmallVector<uint8_t>> parseBuildID(StringRef Str) const;
Optional<std::string> parseMode(StringRef Str) const;
+ Optional<PCType> parsePCType(StringRef Str) const;
+ Optional<uint64_t> parseFrameNumber(StringRef Str) const;
bool checkTag(const MarkupNode &Node) const;
bool checkNumFields(const MarkupNode &Element, size_t Size) const;
bool checkNumFieldsAtLeast(const MarkupNode &Element, size_t Size) const;
+ bool checkNumFieldsAtMost(const MarkupNode &Element, size_t Size) const;
void reportTypeError(StringRef Str, StringRef TypeName) const;
void reportLocation(StringRef::iterator Loc) const;
- const MMap *overlappingMMap(const MMap &Map) const;
+ const MMap *getOverlappingMMap(const MMap &Map) const;
+ const MMap *getContainingMMap(uint64_t Addr) const;
+
+ uint64_t adjustAddr(uint64_t Addr, PCType Type) const;
StringRef lineEnding() const;
raw_ostream &OS;
+ LLVMSymbolizer &Symbolizer;
const bool ColorsEnabled;
MarkupParser Parser;
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 42a141e8876b..a7f9382478d4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7163,9 +7163,8 @@ static SDValue extractShiftForRotate(SelectionDAG &DAG, SDValue OppShift,
SDValue ExtractFrom, SDValue &Mask,
const SDLoc &DL) {
assert(OppShift && ExtractFrom && "Empty SDValue");
- assert(
- (OppShift.getOpcode() == ISD::SHL || OppShift.getOpcode() == ISD::SRL) &&
- "Existing shift must be valid as a rotate half");
+ if (OppShift.getOpcode() != ISD::SHL && OppShift.getOpcode() != ISD::SRL)
+ return SDValue();
ExtractFrom = stripConstantMask(DAG, ExtractFrom, Mask);
diff --git a/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
index 91a51485026e..d96c0c85d5bd 100644
--- a/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
@@ -20,11 +20,14 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/Symbolize/Markup.h"
+#include "llvm/DebugInfo/Symbolize/Symbolize.h"
#include "llvm/Debuginfod/Debuginfod.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
@@ -32,9 +35,11 @@
using namespace llvm;
using namespace llvm::symbolize;
-MarkupFilter::MarkupFilter(raw_ostream &OS, Optional<bool> ColorsEnabled)
- : OS(OS), ColorsEnabled(ColorsEnabled.value_or(
- WithColor::defaultAutoDetectFunction()(OS))) {}
+MarkupFilter::MarkupFilter(raw_ostream &OS, LLVMSymbolizer &Symbolizer,
+ Optional<bool> ColorsEnabled)
+ : OS(OS), Symbolizer(Symbolizer),
+ ColorsEnabled(
+ ColorsEnabled.value_or(WithColor::defaultAutoDetectFunction()(OS))) {}
void MarkupFilter::filter(StringRef Line) {
this->Line = Line;
@@ -94,10 +99,10 @@ bool MarkupFilter::tryMMap(const MarkupNode &Node,
if (!ParsedMMap)
return true;
- if (const MMap *M = overlappingMMap(*ParsedMMap)) {
+ if (const MMap *M = getOverlappingMMap(*ParsedMMap)) {
WithColor::error(errs())
- << formatv("overlapping mmap: #{0:x} [{1:x},{2:x})\n", M->Mod->ID,
- M->Addr, M->Addr + M->Size);
+ << formatv("overlapping mmap: #{0:x} [{1:x}-{2:x}]\n", M->Mod->ID,
+ M->Addr, M->Addr + M->Size - 1);
reportLocation(Node.Fields[0].begin());
return true;
}
@@ -160,18 +165,17 @@ bool MarkupFilter::tryModule(const MarkupNode &Node,
filterNode(Node);
beginModuleInfoLine(&Module);
OS << "; BuildID=";
- highlightValue();
- OS << toHex(Module.BuildID, /*LowerCase=*/true);
- highlight();
+ printValue(toHex(Module.BuildID, /*LowerCase=*/true));
return true;
}
void MarkupFilter::beginModuleInfoLine(const Module *M) {
highlight();
OS << "[[[ELF module";
- highlightValue();
- OS << formatv(" #{0:x} \"{1}\"", M->ID, M->Name);
- highlight();
+ printValue(formatv(" #{0:x} ", M->ID));
+ OS << '"';
+ printValue(M->Name);
+ OS << '"';
MIL = ModuleInfoLine{M};
}
@@ -182,14 +186,13 @@ void MarkupFilter::endAnyModuleInfoLine() {
return A->Addr < B->Addr;
});
for (const MMap *M : MIL->MMaps) {
- OS << (M == MIL->MMaps.front() ? ' ' : '-');
- highlightValue();
- OS << formatv("{0:x}", M->Addr);
- highlight();
- OS << '(';
- highlightValue();
- OS << M->Mode;
- highlight();
+ OS << (M == MIL->MMaps.front() ? ' ' : ',');
+ OS << '[';
+ printValue(formatv("{0:x}", M->Addr));
+ OS << '-';
+ printValue(formatv("{0:x}", M->Addr + M->Size - 1));
+ OS << "](";
+ printValue(M->Mode);
OS << ')';
}
OS << "]]]" << lineEnding();
@@ -210,7 +213,13 @@ void MarkupFilter::filterNode(const MarkupNode &Node) {
}
bool MarkupFilter::tryPresentation(const MarkupNode &Node) {
- return trySymbol(Node);
+ if (trySymbol(Node))
+ return true;
+ if (tryPC(Node))
+ return true;
+ if (tryBackTrace(Node))
+ return true;
+ return tryData(Node);
}
bool MarkupFilter::trySymbol(const MarkupNode &Node) {
@@ -225,6 +234,172 @@ bool MarkupFilter::trySymbol(const MarkupNode &Node) {
return true;
}
+bool MarkupFilter::tryPC(const MarkupNode &Node) {
+ if (Node.Tag != "pc")
+ return false;
+ if (!checkNumFieldsAtLeast(Node, 1))
+ return true;
+ if (!checkNumFieldsAtMost(Node, 2))
+ return true;
+
+ Optional<uint64_t> Addr = parseAddr(Node.Fields[0]);
+ if (!Addr)
+ return true;
+
+ // PC addresses that aren't part of a backtrace are assumed to be precise code
+ // locations.
+ PCType Type = PCType::PreciseCode;
+ if (Node.Fields.size() == 2) {
+ Optional<PCType> ParsedType = parsePCType(Node.Fields[1]);
+ if (!ParsedType)
+ return true;
+ Type = *ParsedType;
+ }
+ *Addr = adjustAddr(*Addr, Type);
+
+ const MMap *MMap = getContainingMMap(*Addr);
+ if (!MMap) {
+ WithColor::error() << "no mmap covers address\n";
+ reportLocation(Node.Fields[0].begin());
+ printRawElement(Node);
+ return true;
+ }
+
+ Expected<DILineInfo> LI = Symbolizer.symbolizeCode(
+ MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)});
+ if (!LI) {
+ WithColor::defaultErrorHandler(LI.takeError());
+ printRawElement(Node);
+ return true;
+ }
+ if (!*LI) {
+ printRawElement(Node);
+ return true;
+ }
+
+ highlight();
+ printValue(LI->FunctionName);
+ OS << '[';
+ printValue(LI->FileName);
+ OS << ':';
+ printValue(Twine(LI->Line));
+ OS << ']';
+ restoreColor();
+ return true;
+}
+
+bool MarkupFilter::tryBackTrace(const MarkupNode &Node) {
+ if (Node.Tag != "bt")
+ return false;
+ if (!checkNumFieldsAtLeast(Node, 2))
+ return true;
+ if (!checkNumFieldsAtMost(Node, 3))
+ return true;
+
+ Optional<uint64_t> FrameNumber = parseFrameNumber(Node.Fields[0]);
+ if (!FrameNumber)
+ return true;
+
+ Optional<uint64_t> Addr = parseAddr(Node.Fields[1]);
+ if (!Addr)
+ return true;
+
+ // Backtrace addresses are assumed to be return addresses by default.
+ PCType Type = PCType::ReturnAddress;
+ if (Node.Fields.size() == 3) {
+ Optional<PCType> ParsedType = parsePCType(Node.Fields[2]);
+ if (!ParsedType)
+ return true;
+ Type = *ParsedType;
+ }
+ *Addr = adjustAddr(*Addr, Type);
+
+ const MMap *MMap = getContainingMMap(*Addr);
+ if (!MMap) {
+ WithColor::error() << "no mmap covers address\n";
+ reportLocation(Node.Fields[0].begin());
+ printRawElement(Node);
+ return true;
+ }
+ uint64_t MRA = MMap->getModuleRelativeAddr(*Addr);
+
+ Expected<DIInliningInfo> II =
+ Symbolizer.symbolizeInlinedCode(MMap->Mod->BuildID, {MRA});
+ if (!II) {
+ WithColor::defaultErrorHandler(II.takeError());
+ printRawElement(Node);
+ return true;
+ }
+
+ highlight();
+ for (unsigned I = 0, E = II->getNumberOfFrames(); I != E; ++I) {
+ auto Header = formatv("{0, +6}", formatv("#{0}", FrameNumber)).sstr<16>();
+ // Don't highlight the # sign as a value.
+ size_t NumberIdx = Header.find("#") + 1;
+ OS << Header.substr(0, NumberIdx);
+ printValue(Header.substr(NumberIdx));
+ if (I == E - 1) {
+ OS << " ";
+ } else {
+ OS << '.';
+ printValue(formatv("{0, -2}", I + 1));
+ }
+ printValue(formatv(" {0:x16} ", *Addr));
+
+ DILineInfo LI = II->getFrame(I);
+ if (LI) {
+ printValue(LI.FunctionName);
+ OS << ' ';
+ printValue(LI.FileName);
+ OS << ':';
+ printValue(Twine(LI.Line));
+ OS << ':';
+ printValue(Twine(LI.Column));
+ OS << ' ';
+ }
+ OS << '(';
+ printValue(MMap->Mod->Name);
+ OS << "+";
+ printValue(formatv("{0:x}", MRA));
+ OS << ')';
+ if (I != E - 1)
+ OS << lineEnding();
+ }
+ restoreColor();
+ return true;
+}
+
+bool MarkupFilter::tryData(const MarkupNode &Node) {
+ if (Node.Tag != "data")
+ return false;
+ if (!checkNumFields(Node, 1))
+ return true;
+ Optional<uint64_t> Addr = parseAddr(Node.Fields[0]);
+ if (!Addr)
+ return true;
+
+ const MMap *MMap = getContainingMMap(*Addr);
+ if (!MMap) {
+ WithColor::error() << "no mmap covers address\n";
+ reportLocation(Node.Fields[0].begin());
+ printRawElement(Node);
+ return true;
+ }
+
+ Expected<DIGlobal> Symbol = Symbolizer.symbolizeData(
+ MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)});
+ if (!Symbol) {
+ WithColor::defaultErrorHandler(Symbol.takeError());
+ printRawElement(Node);
+ return true;
+ }
+
+ highlight();
+ OS << Symbol->Name;
+ restoreColor();
+ return true;
+}
+
bool MarkupFilter::trySGR(const MarkupNode &Node) {
if (Node.Text == "\033[0m") {
resetColor();
@@ -297,6 +472,24 @@ void MarkupFilter::resetColor() {
OS.resetColor();
}
+void MarkupFilter::printRawElement(const MarkupNode &Element) {
+ highlight();
+ OS << "[[[";
+ printValue(Element.Tag);
+ for (StringRef Field : Element.Fields) {
+ OS << ':';
+ printValue(Field);
+ }
+ OS << "]]]";
+ restoreColor();
+}
+
+void MarkupFilter::printValue(Twine Value) {
+ highlightValue();
+ OS << Value;
+ highlight();
+}
+
// This macro helps reduce the amount of indirection done through Optional
// below, since the usual case upon returning a None Optional is to return None.
#define ASSIGN_OR_RETURN_NONE(TYPE, NAME, EXPR) \
@@ -392,6 +585,16 @@ Optional<uint64_t> MarkupFilter::parseSize(StringRef Str) const {
return ID;
}
+// Parse a frame number (%i in the spec).
+Optional<uint64_t> MarkupFilter::parseFrameNumber(StringRef Str) const {
+ uint64_t ID;
+ if (Str.getAsInteger(10, ID)) {
+ reportTypeError(Str, "frame number");
+ return None;
+ }
+ return ID;
+}
+
// Parse a build ID (%x in the spec).
Optional<SmallVector<uint8_t>> MarkupFilter::parseBuildID(StringRef Str) const {
std::string Bytes;
@@ -430,6 +633,17 @@ Optional<std::string> MarkupFilter::parseMode(StringRef Str) const {
return Str.lower();
}
+Optional<MarkupFilter::PCType> MarkupFilter::parsePCType(StringRef Str) const {
+ Optional<MarkupFilter::PCType> Type =
+ StringSwitch<Optional<MarkupFilter::PCType>>(Str)
+ .Case("ra", MarkupFilter::PCType::ReturnAddress)
+ .Case("pc", MarkupFilter::PCType::PreciseCode)
+ .Default(None);
+ if (!Type)
+ reportTypeError(Str, "PC type");
+ return Type;
+}
+
bool MarkupFilter::checkTag(const MarkupNode &Node) const {
if (any_of(Node.Tag, [](char C) { return C < 'a' || C > 'z'; })) {
WithColor::error(errs()) << "tags must be all lowercase characters\n";
@@ -442,7 +656,7 @@ bool MarkupFilter::checkTag(const MarkupNode &Node) const {
bool MarkupFilter::checkNumFields(const MarkupNode &Element,
size_t Size) const {
if (Element.Fields.size() != Size) {
- WithColor::error(errs()) << "expected " << Size << " fields; found "
+ WithColor::error(errs()) << "expected " << Size << " field(s); found "
<< Element.Fields.size() << "\n";
reportLocation(Element.Tag.end());
return false;
@@ -454,7 +668,19 @@ bool MarkupFilter::checkNumFieldsAtLeast(const MarkupNode &Element,
size_t Size) const {
if (Element.Fields.size() < Size) {
WithColor::error(errs())
- << "expected at least " << Size << " fields; found "
+ << "expected at least " << Size << " field(s); found "
+ << Element.Fields.size() << "\n";
+ reportLocation(Element.Tag.end());
+ return false;
+ }
+ return true;
+}
+
+bool MarkupFilter::checkNumFieldsAtMost(const MarkupNode &Element,
+ size_t Size) const {
+ if (Element.Fields.size() > Size) {
+ WithColor::error(errs())
+ << "expected at most " << Size << " field(s); found "
<< Element.Fields.size() << "\n";
reportLocation(Element.Tag.end());
return false;
@@ -479,7 +705,8 @@ void MarkupFilter::reportLocation(StringRef::iterator Loc) const {
// Checks for an existing mmap that overlaps the given one and returns a
// pointer to one of them.
-const MarkupFilter::MMap *MarkupFilter::overlappingMMap(const MMap &Map) const {
+const MarkupFilter::MMap *
+MarkupFilter::getOverlappingMMap(const MMap &Map) const {
// If the given map contains the start of another mmap, they overlap.
auto I = MMaps.upper_bound(Map.Addr);
if (I != MMaps.end() && Map.contains(I->second.Addr))
@@ -495,6 +722,28 @@ const MarkupFilter::MMap *MarkupFilter::overlappingMMap(const MMap &Map) const {
return nullptr;
}
+// Returns the MMap that contains the given address or nullptr if none.
+const MarkupFilter::MMap *MarkupFilter::getContainingMMap(uint64_t Addr) const {
+ // Find the first mmap starting >= Addr.
+ auto I = MMaps.lower_bound(Addr);
+ if (I != MMaps.end() && I->second.contains(Addr))
+ return &I->second;
+
+ // The previous mmap is the last one starting < Addr.
+ if (I == MMaps.begin())
+ return nullptr;
+ --I;
+ return I->second.contains(Addr) ? &I->second : nullptr;
+}
+
+uint64_t MarkupFilter::adjustAddr(uint64_t Addr, PCType Type) const {
+ // Decrementing return addresses by one moves them into the call instruction.
+ // The address doesn't have to be the start of the call instruction, just some
+ // byte on the inside. Subtracting one avoids needing detailed instruction
+ // length information here.
+ return Type == MarkupFilter::PCType::ReturnAddress ? Addr - 1 : Addr;
+}
+
StringRef MarkupFilter::lineEnding() const {
return Line.endswith("\r\n") ? "\r\n" : "\n";
}
@@ -502,3 +751,8 @@ StringRef MarkupFilter::lineEnding() const {
bool MarkupFilter::MMap::contains(uint64_t Addr) const {
return this->Addr <= Addr && Addr < this->Addr + Size;
}
+
+// Returns the module-relative address for a given virtual address.
+uint64_t MarkupFilter::MMap::getModuleRelativeAddr(uint64_t Addr) const {
+ return Addr - this->Addr + ModuleRelativeAddr;
+}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index bf520a560404..c0a94cc758bb 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4600,9 +4600,16 @@ void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
case Intrinsic::amdgcn_mbcnt_hi: {
const GCNSubtarget &ST =
DAG.getMachineFunction().getSubtarget<GCNSubtarget>();
- // These return at most the wavefront size - 1.
+ // These return at most the (wavefront size - 1) + src1
+ // As long as src1 is an immediate we can calc known bits
+ KnownBits Src1Known = DAG.computeKnownBits(Op.getOperand(2), Depth + 1);
+ unsigned Src1ValBits = Src1Known.countMaxActiveBits();
+ unsigned MaxActiveBits = std::max(Src1ValBits, ST.getWavefrontSizeLog2());
+ // Cater for potential carry
+ MaxActiveBits += Src1ValBits ? 1 : 0;
unsigned Size = Op.getValueType().getSizeInBits();
- Known.Zero.setHighBits(Size - ST.getWavefrontSizeLog2());
+ if (MaxActiveBits < Size)
+ Known.Zero.setHighBits(Size - MaxActiveBits);
break;
}
case Intrinsic::amdgcn_workitem_id_x:
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 7ec70e42f1c1..34c93be67f80 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -366,8 +366,8 @@ static SmallVector<uint8_t> parseBuildIDArg(const opt::InputArgList &Args,
}
// Symbolize markup from stdin and write the result to stdout.
-static void filterMarkup(const opt::InputArgList &Args) {
- MarkupFilter Filter(outs(), parseColorArg(Args));
+static void filterMarkup(const opt::InputArgList &Args, LLVMSymbolizer &Symbolizer) {
+ MarkupFilter Filter(outs(), Symbolizer, parseColorArg(Args));
std::string InputString;
while (std::getline(std::cin, InputString)) {
InputString += '\n';
@@ -437,8 +437,19 @@ int main(int argc, char **argv) {
}
}
+ LLVMSymbolizer Symbolizer(Opts);
+
+ // A debuginfod lookup could succeed if a HTTP client is available and at
+ // least one backing URL is configured.
+ bool ShouldUseDebuginfodByDefault =
+ HTTPClient::isAvailable() &&
+ !ExitOnErr(getDefaultDebuginfodUrls()).empty();
+ if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod,
+ ShouldUseDebuginfodByDefault))
+ enableDebuginfod(Symbolizer);
+
if (Args.hasArg(OPT_filter_markup)) {
- filterMarkup(Args);
+ filterMarkup(Args, Symbolizer);
return 0;
}
@@ -458,17 +469,6 @@ int main(int argc, char **argv) {
}
SmallVector<uint8_t> BuildID = parseBuildIDArg(Args, OPT_build_id_EQ);
- LLVMSymbolizer Symbolizer(Opts);
-
- // A debuginfod lookup could succeed if a HTTP client is available and at
- // least one backing URL is configured.
- bool ShouldUseDebuginfodByDefault =
- HTTPClient::isAvailable() &&
- !ExitOnErr(getDefaultDebuginfodUrls()).empty();
- if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod,
- ShouldUseDebuginfodByDefault))
- enableDebuginfod(Symbolizer);
-
std::unique_ptr<DIPrinter> Printer;
if (Style == OutputStyle::GNU)
Printer = std::make_unique<GNUPrinter>(outs(), errs(), Config);