Skip to content

Commit f102fb0

Browse files
Jenkinsronlieb
authored andcommitted
merge main into amd-staging
Change-Id: I253d0ab91c9bc14c39fb246487b508feff28bc14
2 parents eb1a4a6 + 91fdfec commit f102fb0

File tree

22 files changed

+305
-38
lines changed

22 files changed

+305
-38
lines changed

compiler-rt/lib/lsan/lsan_common.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ static void ReportUnsuspendedThreads(const SuspendedThreadsList &) {}
702702

703703
# else // !SANITIZER_FUCHSIA
704704

705-
static void ReportUnsuspendedThreads(
705+
static bool ReportUnsuspendedThreads(
706706
const SuspendedThreadsList &suspended_threads) {
707707
InternalMmapVector<tid_t> threads(suspended_threads.ThreadCount());
708708
for (uptr i = 0; i < suspended_threads.ThreadCount(); ++i)
@@ -713,13 +713,17 @@ static void ReportUnsuspendedThreads(
713713
InternalMmapVector<tid_t> unsuspended;
714714
GetRunningThreadsLocked(&unsuspended);
715715

716+
bool succeded = true;
716717
for (auto os_id : unsuspended) {
717718
uptr i = InternalLowerBound(threads, os_id);
718-
if (i >= threads.size() || threads[i] != os_id)
719+
if (i >= threads.size() || threads[i] != os_id) {
720+
succeded = false;
719721
Report(
720722
"Running thread %zu was not suspended. False leaks are possible.\n",
721723
os_id);
724+
}
722725
}
726+
return succeded;
723727
}
724728

725729
# endif // !SANITIZER_FUCHSIA
@@ -729,7 +733,18 @@ static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,
729733
CheckForLeaksParam *param = reinterpret_cast<CheckForLeaksParam *>(arg);
730734
CHECK(param);
731735
CHECK(!param->success);
732-
ReportUnsuspendedThreads(suspended_threads);
736+
if (!ReportUnsuspendedThreads(suspended_threads)) {
737+
switch (flags()->thread_suspend_fail) {
738+
case 0:
739+
param->success = true;
740+
return;
741+
case 1:
742+
break;
743+
case 2:
744+
// Will crash on return.
745+
return;
746+
}
747+
}
733748
ClassifyAllChunks(suspended_threads, &param->frontier, param->caller_tid,
734749
param->caller_sp);
735750
ForEachChunk(CollectLeaksCb, &param->leaks);

compiler-rt/lib/lsan/lsan_flags.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,7 @@ LSAN_FLAG(bool, use_poisoned, false,
4444
LSAN_FLAG(bool, log_pointers, false, "Debug logging")
4545
LSAN_FLAG(bool, log_threads, false, "Debug logging")
4646
LSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
47+
LSAN_FLAG(int, thread_suspend_fail, 1,
48+
"Behaviour if thread suspendion all thread (0 - "
49+
"abandon leak checking, 1 - continue with leak checking (reported "
50+
"leaks can be false), 2 - crash (for debugging LSAN)).")

compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ bool ThreadSuspender::SuspendAllThreads() {
217217
switch (thread_lister.ListThreads(&threads)) {
218218
case ThreadLister::Error:
219219
ResumeAllThreads();
220+
Report("Failed to list threads\n");
220221
return false;
221222
case ThreadLister::Incomplete:
222223
retry = true;
@@ -228,6 +229,8 @@ bool ThreadSuspender::SuspendAllThreads() {
228229
if (SuspendThread(tid))
229230
retry = true;
230231
}
232+
if (retry)
233+
VReport(1, "SuspendAllThreads retry: %d\n", i);
231234
}
232235
return suspended_threads_list_.ThreadCount();
233236
}

lld/MachO/SyntheticSections.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,16 @@ void SymtabSection::emitStabs() {
12291229
if (defined->isAbsolute())
12301230
continue;
12311231

1232+
// Never generate a STABS entry for a symbol that has been ICF'ed using a
1233+
// thunk, just as we do for fully ICF'ed functions. Otherwise, we end up
1234+
// generating invalid DWARF as dsymutil will assume the entire function
1235+
// body is at that location, when, in reality, only the thunk is
1236+
// present. This will end up causing overlapping DWARF entries.
1237+
// TODO: Find an implementation that works in combination with
1238+
// `--keep-icf-stabs`.
1239+
if (defined->identicalCodeFoldingKind == Symbol::ICFFoldKind::Thunk)
1240+
continue;
1241+
12321242
// Constant-folded symbols go in the executable's symbol table, but don't
12331243
// get a stabs entry unless --keep-icf-stabs flag is specified
12341244
if (!config->keepICFStabs &&
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
; REQUIRES: aarch64
2+
3+
;;; Build the
4+
; RUN: rm -rf %t; mkdir %t
5+
; RUN: llc -filetype=obj %s -O3 -o %t/icf-obj-safe-thunks-dwarf.o -enable-machine-outliner=never -mtriple arm64-apple-macos -addrsig
6+
; RUN: %lld -arch arm64 -lSystem --icf=safe_thunks -dylib -o %t/icf-safe-dwarf.dylib %t/icf-obj-safe-thunks-dwarf.o
7+
8+
;;; Check that we generate valid dSYM
9+
; RUN: dsymutil %t/icf-safe-dwarf.dylib -o %t/icf-safe.dSYM
10+
; RUN: llvm-dwarfdump --verify %t/icf-safe.dSYM | FileCheck %s --check-prefix=VERIFY-DSYM
11+
; VERIFY-DSYM: No errors.
12+
13+
;;; Check that we don't generate STABS entries (N_FUN) for ICF'ed function thunks
14+
; RUN: dsymutil -s %t/icf-safe-dwarf.dylib | FileCheck %s --check-prefix=VERIFY-STABS
15+
; VERIFY-STABS-NOT: N_FUN{{.*}}_func_B
16+
; VERIFY-STABS-NOT: N_FUN{{.*}}_func_C
17+
18+
;;; Check that we do generate STABS entries (N_FUN) for non-ICF'ed functions
19+
; VERIFY-STABS: N_FUN{{.*}}_func_A
20+
; VERIFY-STABS: N_FUN{{.*}}_take_func_addr
21+
22+
23+
; ModuleID = 'icf-safe-thunks-dwarf.cpp'
24+
source_filename = "icf-safe-thunks-dwarf.cpp"
25+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
26+
target triple = "arm64-apple-macosx11.0.0"
27+
28+
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
29+
define i32 @func_A() #0 !dbg !13 {
30+
entry:
31+
ret i32 1
32+
}
33+
34+
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
35+
define i32 @func_B() #0 !dbg !18 {
36+
entry:
37+
ret i32 1
38+
}
39+
40+
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
41+
define i32 @func_C() #0 !dbg !20 {
42+
entry:
43+
ret i32 1
44+
}
45+
46+
; Function Attrs: mustprogress noinline nounwind optnone ssp uwtable(sync)
47+
define i64 @take_func_addr() #0 !dbg !22 {
48+
entry:
49+
%val = alloca i64, align 8
50+
store i64 0, ptr %val, align 8
51+
%0 = load i64, ptr %val, align 8
52+
%add = add i64 %0, ptrtoint (ptr @func_A to i64)
53+
store i64 %add, ptr %val, align 8
54+
%1 = load i64, ptr %val, align 8
55+
%add1 = add i64 %1, ptrtoint (ptr @func_B to i64)
56+
store i64 %add1, ptr %val, align 8
57+
%2 = load i64, ptr %val, align 8
58+
%add2 = add i64 %2, ptrtoint (ptr @func_C to i64)
59+
store i64 %add2, ptr %val, align 8
60+
%3 = load i64, ptr %val, align 8
61+
ret i64 %3
62+
}
63+
64+
attributes #0 = { noinline nounwind }
65+
66+
!llvm.dbg.cu = !{!0}
67+
!llvm.module.flags = !{!6, !7, !8, !9, !10, !11}
68+
!llvm.ident = !{!12}
69+
70+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
71+
!1 = !DIFile(filename: "icf-safe-thunks-dwarf.cpp", directory: "/tmp/test")
72+
!6 = !{i32 7, !"Dwarf Version", i32 4}
73+
!7 = !{i32 2, !"Debug Info Version", i32 3}
74+
!8 = !{i32 1, !"wchar_size", i32 4}
75+
!9 = !{i32 8, !"PIC Level", i32 2}
76+
!10 = !{i32 7, !"uwtable", i32 1}
77+
!11 = !{i32 7, !"frame-pointer", i32 1}
78+
!12 = !{!"clang version 20.0.0"}
79+
!13 = distinct !DISubprogram(name: "func_A", scope: !1, file: !1, line: 4, type: !14, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
80+
!14 = !DISubroutineType(types: !15)
81+
!15 = !{}
82+
!18 = distinct !DISubprogram(name: "func_B", scope: !1, file: !1, line: 5, type: !14, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
83+
!20 = distinct !DISubprogram(name: "func_C", scope: !1, file: !1, line: 6, type: !14, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
84+
!22 = distinct !DISubprogram(name: "take_func_addr", scope: !1, file: !1, line: 8, type: !14, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
85+
86+
87+
88+
89+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
90+
;;;;;;;;;;;;;; Generate the above LLVM IR with the below script ;;;;;;;;;;;;;;;
91+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
92+
; #!/bin/bash
93+
; set -ex
94+
; TOOLCHAIN_BIN="llvm-project/build/Debug/bin"
95+
;
96+
; # Create icf-safe-thunks-dwarf.cpp file
97+
; cat > icf-safe-thunks-dwarf.cpp <<EOF
98+
; #define ATTR __attribute__((noinline)) extern "C"
99+
; typedef unsigned long long ULL;
100+
;
101+
; ATTR int func_A() { return 1; }
102+
; ATTR int func_B() { return 1; }
103+
; ATTR int func_C() { return 1; }
104+
;
105+
; ATTR ULL take_func_addr() {
106+
; ULL val = 0;
107+
; val += (ULL)(void*)func_A;
108+
; val += (ULL)(void*)func_B;
109+
; val += (ULL)(void*)func_C;
110+
; return val;
111+
; }
112+
; EOF
113+
;
114+
; $TOOLCHAIN_BIN/clang -target arm64-apple-macos11.0 -S -emit-llvm -g \
115+
; icf-safe-thunks-dwarf.cpp

lldb/source/Commands/CommandObjectSession.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ class CommandObjectSessionSave : public CommandObjectParsed {
1919
: CommandObjectParsed(interpreter, "session save",
2020
"Save the current session transcripts to a file.\n"
2121
"If no file if specified, transcripts will be "
22-
"saved to a temporary file.",
22+
"saved to a temporary file.\n"
23+
"Note: transcripts will only be saved if "
24+
"interpreter.save-transcript is true.\n",
2325
"session save [file]") {
2426
AddSimpleArgumentList(eArgTypePath, eArgRepeatOptional);
2527
}

lldb/source/Interpreter/CommandInterpreter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,6 +3308,10 @@ bool CommandInterpreter::SaveTranscript(
33083308
result.SetStatus(eReturnStatusSuccessFinishNoResult);
33093309
result.AppendMessageWithFormat("Session's transcripts saved to %s\n",
33103310
output_file->c_str());
3311+
if (!GetSaveTranscript())
3312+
result.AppendError(
3313+
"Note: the setting interpreter.save-transcript is set to false, so the "
3314+
"transcript might not have been recorded.");
33113315

33123316
if (GetOpenTranscriptInEditor() && Host::IsInteractiveGraphicSession()) {
33133317
const FileSpec file_spec;

lldb/source/Interpreter/InterpreterProperties.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ let Definition = "interpreter" in {
1616
def SaveSessionOnQuit: Property<"save-session-on-quit", "Boolean">,
1717
Global,
1818
DefaultFalse,
19-
Desc<"If true, LLDB will save the session's transcripts before quitting.">;
19+
Desc<"If true, LLDB will save the session's transcripts before quitting. Note: transcripts will only be saved if interpreter.save-transcript is true.">;
2020
def OpenTranscriptInEditor: Property<"open-transcript-in-editor", "Boolean">,
2121
Global,
2222
DefaultTrue,

lldb/test/API/commands/session/save/TestSessionSave.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def test_session_save(self):
8585
interpreter.HandleCommand("session save", res)
8686
self.assertTrue(res.Succeeded())
8787
raw += self.raw_transcript_builder(cmd, res)
88+
# Also check that we don't print an error message about an empty transcript.
89+
self.assertNotIn("interpreter.save-transcript is set to false", res.GetError())
8890

8991
with open(os.path.join(td.name, os.listdir(td.name)[0]), "r") as file:
9092
content = file.read()
@@ -93,6 +95,36 @@ def test_session_save(self):
9395
for line in lines:
9496
self.assertIn(line, content)
9597

98+
@no_debug_info_test
99+
def test_session_save_no_transcript_warning(self):
100+
interpreter = self.dbg.GetCommandInterpreter()
101+
102+
self.runCmd("settings set interpreter.save-transcript false")
103+
104+
# These commands won't be saved, so are arbitrary.
105+
commands = [
106+
"p 1",
107+
"settings set interpreter.save-session-on-quit true",
108+
"fr v",
109+
"settings set interpreter.echo-comment-commands true",
110+
]
111+
112+
for command in commands:
113+
res = lldb.SBCommandReturnObject()
114+
interpreter.HandleCommand(command, res)
115+
116+
output_file = self.getBuildArtifact("my-session")
117+
118+
res = lldb.SBCommandReturnObject()
119+
interpreter.HandleCommand("session save " + output_file, res)
120+
self.assertTrue(res.Succeeded())
121+
# We should warn about the setting being false.
122+
self.assertIn("interpreter.save-transcript is set to false", res.GetError())
123+
self.assertTrue(
124+
os.path.getsize(output_file) == 0,
125+
"Output file should be empty since we didn't save the transcript.",
126+
)
127+
96128
@no_debug_info_test
97129
def test_session_save_on_quit(self):
98130
raw = ""

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,49 @@ RISCVTTIImpl::getConstantPoolLoadCost(Type *Ty, TTI::TargetCostKind CostKind) {
343343
/*AddressSpace=*/0, CostKind);
344344
}
345345

346+
InstructionCost
347+
RISCVTTIImpl::isMultipleInsertSubvector(VectorType *Tp, ArrayRef<int> Mask,
348+
TTI::TargetCostKind CostKind) {
349+
if (!isa<FixedVectorType>(Tp))
350+
return InstructionCost::getInvalid();
351+
std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
352+
if (LT.second.getScalarSizeInBits() == 1)
353+
return InstructionCost::getInvalid();
354+
// Try to guess SubTp.
355+
for (unsigned SubVecSize = 1, E = Mask.size(); SubVecSize < E;
356+
SubVecSize <<= 1) {
357+
if (E % SubVecSize != 0)
358+
continue;
359+
SmallVector<int> RepeatedPattern(createSequentialMask(0, SubVecSize, 0));
360+
bool Skip = false;
361+
for (unsigned I = 0; I != E; I += SubVecSize)
362+
if (!Mask.slice(I, SubVecSize).equals(RepeatedPattern)) {
363+
Skip = true;
364+
break;
365+
}
366+
if (Skip)
367+
continue;
368+
InstructionCost Cost = 0;
369+
unsigned NumSlides = Log2_32(E / SubVecSize);
370+
// The cost of extraction from a subvector is 0 if the index is 0.
371+
for (unsigned I = 0; I != NumSlides; ++I) {
372+
unsigned InsertIndex = SubVecSize * (1 << I);
373+
FixedVectorType *SubTp = FixedVectorType::get(
374+
cast<FixedVectorType>(Tp)->getElementType(), InsertIndex);
375+
FixedVectorType *DesTp =
376+
FixedVectorType::getDoubleElementsVectorType(SubTp);
377+
std::pair<InstructionCost, MVT> DesLT = getTypeLegalizationCost(DesTp);
378+
// Add the cost of whole vector register move because the destination
379+
// vector register group for vslideup cannot overlap the source.
380+
Cost += DesLT.first * TLI->getLMULCost(DesLT.second);
381+
Cost += getShuffleCost(TTI::SK_InsertSubvector, DesTp, {}, CostKind,
382+
InsertIndex, SubTp);
383+
}
384+
return Cost;
385+
}
386+
return InstructionCost::getInvalid();
387+
}
388+
346389
static VectorType *getVRGatherIndexType(MVT DataVT, const RISCVSubtarget &ST,
347390
LLVMContext &C) {
348391
assert((DataVT.getScalarSizeInBits() != 8 ||
@@ -394,6 +437,10 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
394437
LT.second, CostKind);
395438
}
396439
}
440+
if (InstructionCost Cost =
441+
isMultipleInsertSubvector(Tp, Mask, CostKind);
442+
Cost.isValid())
443+
return Cost;
397444
}
398445
// vrgather + cost of generating the mask constant.
399446
// We model this for an unknown mask with a single vrgather.

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
5555
/// type.
5656
InstructionCost getConstantPoolLoadCost(Type *Ty,
5757
TTI::TargetCostKind CostKind);
58+
59+
/// Return the cost if a shufflevector can be consist of multiple vslideup.
60+
/// Otherwise, return InstructionCost::getInvalid().
61+
InstructionCost isMultipleInsertSubvector(VectorType *Tp, ArrayRef<int> Mask,
62+
TTI::TargetCostKind CostKind);
63+
5864
public:
5965
explicit RISCVTTIImpl(const RISCVTargetMachine *TM, const Function &F)
6066
: BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),

llvm/lib/TargetParser/Host.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,7 +1991,8 @@ struct RISCVHwProbe {
19911991
};
19921992
const StringMap<bool> sys::getHostCPUFeatures() {
19931993
RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
1994-
{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}};
1994+
{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},
1995+
{/*RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF=*/9, 0}};
19951996
int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
19961997
/*pair_count=*/std::size(Query), /*cpu_count=*/0,
19971998
/*cpus=*/0, /*flags=*/0);
@@ -2047,9 +2048,26 @@ const StringMap<bool> sys::getHostCPUFeatures() {
20472048
Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
20482049
Features["zihintpause"] =
20492050
ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
2050-
2051-
// TODO: set unaligned-scalar-mem if RISCV_HWPROBE_KEY_MISALIGNED_PERF returns
2052-
// RISCV_HWPROBE_MISALIGNED_FAST.
2051+
Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X
2052+
Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F
2053+
Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X
2054+
Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F
2055+
Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D
2056+
Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP
2057+
Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA
2058+
Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB
2059+
Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD
2060+
Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF
2061+
Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP
2062+
Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS
2063+
2064+
// Check whether the processor supports fast misaligned scalar memory access.
2065+
// NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on
2066+
// Linux 6.11 or later. If it is not recognized, the key field will be cleared
2067+
// to -1.
2068+
if (Query[2].Key != -1 &&
2069+
Query[2].Value == /*RISCV_HWPROBE_MISALIGNED_SCALAR_FAST=*/3)
2070+
Features["unaligned-scalar-mem"] = true;
20532071

20542072
return Features;
20552073
}

0 commit comments

Comments
 (0)