Skip to content

Commit cbd2e16

Browse files
authored
merge main into amd-staging (llvm#3819)
2 parents d032949 + 9c78f52 commit cbd2e16

File tree

20 files changed

+507
-173
lines changed

20 files changed

+507
-173
lines changed

clang/test/AST/ByteCode/vectors.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both -flax-vector-conversions=none %s
2-
// RUN: %clang_cc1 -verify=ref,both -flax-vector-conversions=none %s
1+
// RUN: %clang_cc1 -Wno-c++20-extensions -fexperimental-new-constant-interpreter -verify=expected,both -flax-vector-conversions=none %s
2+
// RUN: %clang_cc1 -Wno-c++20-extensions -verify=ref,both -flax-vector-conversions=none %s
33

44
typedef int __attribute__((vector_size(16))) VI4;
55
constexpr VI4 A = {1,2,3,4};
@@ -147,7 +147,7 @@ namespace {
147147
namespace Assign {
148148
constexpr int a2() {
149149
VI a = {0, 0, 0, 0};
150-
VI b; // both-warning {{C++20 extension}}
150+
VI b;
151151

152152
b = {1,1,1,1};
153153
return b[0] + b[1] + b[2] + b[3];
@@ -161,7 +161,7 @@ namespace Assign {
161161

162162
constexpr bool invalid() {
163163
v2int16_t a = {0, 0};
164-
v2int_t b; // both-warning {{C++20 extension}}
164+
v2int_t b;
165165
b = a; // both-error {{incompatible type}}
166166

167167
return true;

compiler-rt/test/asan/TestCases/Windows/heaprealloc_alloc_zero.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
// RUN: %clang_cl_asan %Od %MT -o %t %s
22
// RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s
3-
// UNSUPPORTED: asan-64-bits
43
#include <cassert>
54
#include <iostream>
5+
#include <sanitizer/allocator_interface.h>
66
#include <windows.h>
77

88
int main() {
99
void *ptr = malloc(0);
1010
if (ptr)
1111
std::cerr << "allocated!\n";
12-
((char *)ptr)[0] = '\xff'; //check this 'allocate 1 instead of 0' hack hasn't changed
12+
13+
// Check the 'allocate 1 instead of 0' hack hasn't changed
14+
// Note that as of b3452d90b043a398639e62b0ab01aa339cc649de, dereferencing
15+
// the pointer will be detected as a heap-buffer-overflow.
16+
if (__sanitizer_get_allocated_size(ptr) != 1)
17+
return 1;
1318

1419
free(ptr);
1520

lldb/include/lldb/Core/Disassembler.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,26 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>,
566566
const Disassembler &operator=(const Disassembler &) = delete;
567567
};
568568

569+
/// Tracks live variable annotations across instructions and produces
570+
/// per-instruction "events" like `name = RDI` or `name = <undef>`.
571+
class VariableAnnotator {
572+
struct VarState {
573+
/// Display name.
574+
std::string name;
575+
/// Last printed location (empty means <undef>).
576+
std::string last_loc;
577+
};
578+
579+
// Live state from the previous instruction, keyed by Variable::GetID().
580+
llvm::DenseMap<lldb::user_id_t, VarState> Live_;
581+
582+
public:
583+
/// Compute annotation strings for a single instruction and update `Live_`.
584+
/// Returns only the events that should be printed *at this instruction*.
585+
std::vector<std::string> annotate(Instruction &inst, Target &target,
586+
const lldb::ModuleSP &module_sp);
587+
};
588+
569589
} // namespace lldb_private
570590

571591
#endif // LLDB_CORE_DISASSEMBLER_H

lldb/source/Core/Disassembler.cpp

Lines changed: 123 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,127 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine(
286286
return false;
287287
}
288288

289+
// For each instruction, this block attempts to resolve in-scope variables
290+
// and determine if the current PC falls within their
291+
// DWARF location entry. If so, it prints a simplified annotation using the
292+
// variable name and its resolved location (e.g., "var = reg; " ).
293+
//
294+
// Annotations are only included if the variable has a valid DWARF location
295+
// entry, and the location string is non-empty after filtering. Decoding
296+
// errors and DWARF opcodes are intentionally omitted to keep the output
297+
// concise and user-friendly.
298+
//
299+
// The goal is to give users helpful live variable hints alongside the
300+
// disassembled instruction stream, similar to how debug information
301+
// enhances source-level debugging.
302+
std::vector<std::string>
303+
VariableAnnotator::annotate(Instruction &inst, Target &target,
304+
const lldb::ModuleSP &module_sp) {
305+
std::vector<std::string> events;
306+
307+
// If we lost module context, everything becomes <undef>.
308+
if (!module_sp) {
309+
for (const auto &KV : Live_)
310+
events.emplace_back(llvm::formatv("{0} = <undef>", KV.second.name).str());
311+
Live_.clear();
312+
return events;
313+
}
314+
315+
// Resolve function/block at this *file* address.
316+
SymbolContext sc;
317+
const Address &iaddr = inst.GetAddress();
318+
const auto mask = eSymbolContextFunction | eSymbolContextBlock;
319+
if (!module_sp->ResolveSymbolContextForAddress(iaddr, mask, sc) ||
320+
!sc.function) {
321+
// No function context: everything dies here.
322+
for (const auto &KV : Live_)
323+
events.emplace_back(llvm::formatv("{0} = <undef>", KV.second.name).str());
324+
Live_.clear();
325+
return events;
326+
}
327+
328+
// Collect in-scope variables for this instruction into Current.
329+
VariableList var_list;
330+
// Innermost block containing iaddr.
331+
if (Block *B = sc.block) {
332+
auto filter = [](Variable *v) -> bool { return v && !v->IsArtificial(); };
333+
B->AppendVariables(/*can_create*/ true,
334+
/*get_parent_variables*/ true,
335+
/*stop_if_block_is_inlined_function*/ false,
336+
/*filter*/ filter,
337+
/*variable_list*/ &var_list);
338+
}
339+
340+
const lldb::addr_t pc_file = iaddr.GetFileAddress();
341+
const lldb::addr_t func_file = sc.function->GetAddress().GetFileAddress();
342+
343+
// ABI from Target (pretty reg names if plugin exists). Safe to be null.
344+
lldb::ABISP abi_sp = ABI::FindPlugin(nullptr, target.GetArchitecture());
345+
ABI *abi = abi_sp.get();
346+
347+
llvm::DIDumpOptions opts;
348+
opts.ShowAddresses = false;
349+
// Prefer "register-only" output when we have an ABI.
350+
opts.PrintRegisterOnly = static_cast<bool>(abi_sp);
351+
352+
llvm::DenseMap<lldb::user_id_t, VarState> Current;
353+
354+
for (size_t i = 0, e = var_list.GetSize(); i != e; ++i) {
355+
lldb::VariableSP v = var_list.GetVariableAtIndex(i);
356+
if (!v || v->IsArtificial())
357+
continue;
358+
359+
const char *nm = v->GetName().AsCString();
360+
llvm::StringRef name = nm ? nm : "<anon>";
361+
362+
DWARFExpressionList &exprs = v->LocationExpressionList();
363+
if (!exprs.IsValid())
364+
continue;
365+
366+
auto entry_or_err = exprs.GetExpressionEntryAtAddress(func_file, pc_file);
367+
if (!entry_or_err)
368+
continue;
369+
370+
auto entry = *entry_or_err;
371+
372+
StreamString loc_ss;
373+
entry.expr->DumpLocation(&loc_ss, eDescriptionLevelBrief, abi, opts);
374+
375+
llvm::StringRef loc = llvm::StringRef(loc_ss.GetString()).trim();
376+
if (loc.empty())
377+
continue;
378+
379+
Current.try_emplace(v->GetID(),
380+
VarState{std::string(name), std::string(loc)});
381+
}
382+
383+
// Diff Live_ → Current.
384+
385+
// 1) Starts/changes: iterate Current and compare with Live_.
386+
for (const auto &KV : Current) {
387+
auto it = Live_.find(KV.first);
388+
if (it == Live_.end()) {
389+
// Newly live.
390+
events.emplace_back(
391+
llvm::formatv("{0} = {1}", KV.second.name, KV.second.last_loc).str());
392+
} else if (it->second.last_loc != KV.second.last_loc) {
393+
// Location changed.
394+
events.emplace_back(
395+
llvm::formatv("{0} = {1}", KV.second.name, KV.second.last_loc).str());
396+
}
397+
}
398+
399+
// 2) Ends: anything that was live but is not in Current becomes <undef>.
400+
for (const auto &KV : Live_) {
401+
if (!Current.count(KV.first))
402+
events.emplace_back(llvm::formatv("{0} = <undef>", KV.second.name).str());
403+
}
404+
405+
// Commit new state.
406+
Live_ = std::move(Current);
407+
return events;
408+
}
409+
289410
void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
290411
const ExecutionContext &exe_ctx,
291412
bool mixed_source_and_assembly,
@@ -382,147 +503,7 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
382503
}
383504
}
384505

385-
// Add variable location annotations to the disassembly output.
386-
//
387-
// For each instruction, this block attempts to resolve in-scope variables
388-
// and determine if the current PC falls within their
389-
// DWARF location entry. If so, it prints a simplified annotation using the
390-
// variable name and its resolved location (e.g., "var = reg; " ).
391-
//
392-
// Annotations are only included if the variable has a valid DWARF location
393-
// entry, and the location string is non-empty after filtering. Decoding
394-
// errors and DWARF opcodes are intentionally omitted to keep the output
395-
// concise and user-friendly.
396-
//
397-
// The goal is to give users helpful live variable hints alongside the
398-
// disassembled instruction stream, similar to how debug information
399-
// enhances source-level debugging.
400-
401-
struct VarState {
402-
std::string name; ///< Display name.
403-
std::string last_loc; ///< Last printed location (empty means <undef>).
404-
bool seen_this_inst = false;
405-
};
406-
407-
// Track live variables across instructions.
408-
llvm::DenseMap<lldb::user_id_t, VarState> live_vars;
409-
410-
// Stateful annotator: updates live_vars and returns only what should be
411-
// printed for THIS instruction.
412-
auto annotate_static = [&](Instruction &inst, Target &target,
413-
ModuleSP module_sp) -> std::vector<std::string> {
414-
std::vector<std::string> events;
415-
416-
// Reset per-instruction seen flags.
417-
for (auto &kv : live_vars)
418-
kv.second.seen_this_inst = false;
419-
420-
const Address &iaddr = inst.GetAddress();
421-
if (!module_sp) {
422-
// Everything previously live becomes <undef>.
423-
for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) {
424-
auto Cur = I++;
425-
events.push_back(
426-
llvm::formatv("{0} = <undef>", Cur->second.name).str());
427-
live_vars.erase(Cur);
428-
}
429-
return events;
430-
}
431-
432-
// Resolve innermost block at this *file* address.
433-
SymbolContext sc;
434-
const lldb::SymbolContextItem mask =
435-
eSymbolContextFunction | eSymbolContextBlock;
436-
if (!module_sp->ResolveSymbolContextForAddress(iaddr, mask, sc) ||
437-
!sc.function) {
438-
// No function context: everything dies here.
439-
for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) {
440-
auto Cur = I++;
441-
events.push_back(
442-
llvm::formatv("{0} = <undef>", Cur->second.name).str());
443-
live_vars.erase(Cur);
444-
}
445-
return events;
446-
}
447-
448-
Block *B = sc.block; ///< Innermost block containing iaddr.
449-
VariableList var_list;
450-
if (B) {
451-
auto filter = [](Variable *v) -> bool { return v && !v->IsArtificial(); };
452-
453-
B->AppendVariables(/*can_create*/ true,
454-
/*get_parent_variables*/ true,
455-
/*stop_if_block_is_inlined_function*/ false,
456-
/*filter*/ filter,
457-
/*variable_list*/ &var_list);
458-
}
459-
460-
const lldb::addr_t pc_file = iaddr.GetFileAddress();
461-
const lldb::addr_t func_file = sc.function->GetAddress().GetFileAddress();
462-
463-
// ABI from Target (pretty reg names if plugin exists). Safe to be null.
464-
lldb::ProcessSP no_process;
465-
lldb::ABISP abi_sp = ABI::FindPlugin(no_process, target.GetArchitecture());
466-
ABI *abi = abi_sp.get();
467-
468-
llvm::DIDumpOptions opts;
469-
opts.ShowAddresses = false;
470-
if (abi)
471-
opts.PrintRegisterOnly = true;
472-
473-
for (size_t i = 0, e = var_list.GetSize(); i != e; ++i) {
474-
lldb::VariableSP v = var_list.GetVariableAtIndex(i);
475-
if (!v || v->IsArtificial())
476-
continue;
477-
478-
const char *nm = v->GetName().AsCString();
479-
llvm::StringRef name = nm ? nm : "<anon>";
480-
481-
lldb_private::DWARFExpressionList &exprs = v->LocationExpressionList();
482-
if (!exprs.IsValid())
483-
continue;
484-
485-
auto entry_or_err = exprs.GetExpressionEntryAtAddress(func_file, pc_file);
486-
if (!entry_or_err)
487-
continue;
488-
489-
auto entry = *entry_or_err;
490-
491-
StreamString loc_ss;
492-
entry.expr->DumpLocation(&loc_ss, eDescriptionLevelBrief, abi, opts);
493-
llvm::StringRef loc = llvm::StringRef(loc_ss.GetString()).trim();
494-
if (loc.empty())
495-
continue;
496-
497-
auto ins = live_vars.insert(
498-
{v->GetID(), VarState{name.str(), loc.str(), /*seen*/ true}});
499-
if (ins.second) {
500-
// Newly live.
501-
events.push_back(llvm::formatv("{0} = {1}", name, loc).str());
502-
} else {
503-
VarState &vs = ins.first->second;
504-
vs.seen_this_inst = true;
505-
if (vs.last_loc != loc) {
506-
vs.last_loc = loc.str();
507-
events.push_back(llvm::formatv("{0} = {1}", vs.name, loc).str());
508-
}
509-
}
510-
}
511-
512-
// Anything previously live that we didn't see a location for at this inst
513-
// is now <undef>.
514-
for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) {
515-
auto Cur = I++;
516-
if (!Cur->second.seen_this_inst) {
517-
events.push_back(
518-
llvm::formatv("{0} = <undef>", Cur->second.name).str());
519-
live_vars.erase(Cur);
520-
}
521-
}
522-
523-
return events;
524-
};
525-
506+
VariableAnnotator annot;
526507
previous_symbol = nullptr;
527508
SourceLine previous_line;
528509
for (size_t i = 0; i < num_instructions_found; ++i) {
@@ -695,7 +676,7 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
695676
address_text_size);
696677

697678
if ((options & eOptionVariableAnnotations) && target_sp) {
698-
auto annotations = annotate_static(*inst, *target_sp, module_sp);
679+
auto annotations = annot.annotate(*inst, *target_sp, module_sp);
699680
if (!annotations.empty()) {
700681
const size_t annotation_column = 100;
701682
inst_line.FillLastLineToColumn(annotation_column, ' ');

llvm/lib/CodeGen/ReachingDefAnalysis.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ void ReachingDefAnalysis::printAllReachingDefs(MachineFunction &MF) {
275275

276276
bool ReachingDefAnalysis::runOnMachineFunction(MachineFunction &mf) {
277277
MF = &mf;
278-
TRI = MF->getSubtarget().getRegisterInfo();
279278
const TargetSubtargetInfo &STI = MF->getSubtarget();
280279
TRI = STI.getRegisterInfo();
281280
TII = STI.getInstrInfo();

llvm/lib/Target/ARM/ARMBlockPlacement.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ bool ARMBlockPlacement::runOnMachineFunction(MachineFunction &MF) {
218218
return false;
219219
LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Running on " << MF.getName() << "\n");
220220
MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
221-
TII = static_cast<const ARMBaseInstrInfo *>(ST.getInstrInfo());
221+
TII = ST.getInstrInfo();
222222
BBUtils = std::make_unique<ARMBasicBlockUtils>(MF);
223223
MF.RenumberBlocks();
224224
BBUtils->computeAllBlockSizes();

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21379,6 +21379,15 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
2137921379
Known = Known.sext(BitWidth);
2138021380
break;
2138121381
}
21382+
case RISCVISD::SRAW: {
21383+
KnownBits Known2;
21384+
Known = DAG.computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
21385+
Known2 = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
21386+
Known = KnownBits::ashr(Known.trunc(32), Known2.trunc(5).zext(32));
21387+
// Restore the original width by sign extending.
21388+
Known = Known.sext(BitWidth);
21389+
break;
21390+
}
2138221391
case RISCVISD::CTZW: {
2138321392
KnownBits Known2 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
2138421393
unsigned PossibleTZ = Known2.trunc(32).countMaxTrailingZeros();

0 commit comments

Comments
 (0)