[clang] [lld] [lld-macho][draft]Allow folding entries with identical FDE (PR #216895)
Vy Nguyen via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 17:58:00 PDT 2026
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/216895
>From 48bc3a4580675833dc69afcb8d6a4328644b6ce2 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 14 May 2026 15:36:16 -0400
Subject: [PATCH 1/6] [codegen]Ensure __builtin_trap() has an unreachable
---
clang/lib/CodeGen/CGBuiltin.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 20f99f489c55f..678985ebb55e1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4022,6 +4022,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
case Builtin::BI__builtin_trap:
EmitTrapCall(Intrinsic::trap);
+ if (Builder.GetInsertBlock()) {
+ Builder.CreateUnreachable();
+ // Dummy block for the ret void - it'll be clened up
+ llvm::BasicBlock *DeadBB = createBasicBlock("dead.trap");
+ EmitBlock(DeadBB);
+ }
return RValue::get(nullptr);
case Builtin::BI__builtin_verbose_trap: {
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
>From 8d9683bb815903f607fef8bb372f1033f1128ea8 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Mon, 17 Aug 2026 21:17:55 -0400
Subject: [PATCH 2/6] [lld-macho]Allow folding functions with the same Dwarf
FDE
This is done by normalising the embedded reloc data during ICF comparison and hashing.
(modified version of pr/213778)
---
lld/MachO/ICF.cpp | 76 +++++++++++++++++++++-----------
lld/test/MachO/fold-dwarf-lsda.s | 6 +--
2 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index 8e9eb1d4e7950..60df53327b834 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -91,6 +91,32 @@ ICF::ICF(std::vector<ConcatInputSection *> &inputs) {
// FIXME(gkm): implement keep-unique attributes
// FIXME(gkm): implement address-significance tables for MachO object files
+static bool isFoldableWithAddendsRemoved(const ConcatInputSection *isec) {
+ return isCfStringSection(isec) || isClassRefsSection(isec) ||
+ isSelRefsSection(isec) || isEhFrameSection(isec);
+}
+
+// Make a normalized copy of a section's bytes by zeroing out the embedded relocs.
+// Return it in the given &buf
+static void getNormalizedData(const ConcatInputSection *isec,
+ SmallVectorImpl<uint8_t> &buf) {
+ buf.assign(isec->data.begin(), isec->data.end());
+ for (const Relocation &r : isec->relocs)
+ target->relocateOne(buf.data() + r.offset, r, /*va=*/0, /*relocVA=*/0);
+}
+
+static bool compareData(const ConcatInputSection *ia,
+ const ConcatInputSection *ib) {
+ if (ia->data == ib->data)
+ return true;
+ if (!isFoldableWithAddendsRemoved(ia))
+ return false;
+ SmallVector<uint8_t, 64> bufA, bufB;
+ getNormalizedData(ia, bufA);
+ getNormalizedData(ib, bufB);
+ return bufA == bufB;
+}
+
// Compare "non-moving" parts of two ConcatInputSections, namely everything
// except references to other ConcatInputSections.
bool ICF::equalsConstant(const ConcatInputSection *ia,
@@ -100,7 +126,7 @@ bool ICF::equalsConstant(const ConcatInputSection *ia,
// We can only fold within the same OutputSection.
if (ia->parent != ib->parent)
return false;
- if (ia->data != ib->data)
+ if (!compareData(ia, ib))
return false;
auto f = [](const Relocation &ra, const Relocation &rb) {
if (ra.type != rb.type)
@@ -573,9 +599,9 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
// Reset the thunk counter for each run of ICF.
icfThunkCounter = 0;
for (ConcatInputSection *isec : inputSections) {
- bool isFoldableWithAddendsRemoved = isCfStringSection(isec) ||
- isClassRefsSection(isec) ||
- isSelRefsSection(isec);
+ bool isUnconditionallyCoalescedData = isCfStringSection(isec) ||
+ isClassRefsSection(isec) ||
+ isSelRefsSection(isec);
// NOTE: __objc_selrefs is typically marked as no_dead_strip by MC, but we
// can still fold it.
bool hasFoldableFlags = (isSelRefsSection(isec) ||
@@ -596,7 +622,6 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
// Happens to match isFoldableWithAddendsRemoved today, but expresses a
// different intent (ld64's coalescing semantics, not addend stripping),
// so the two may diverge as either list grows.
- bool isUnconditionallyCoalescedData = isFoldableWithAddendsRemoved;
bool isSafeThunksCode =
config->icfLevel == ICFLevel::safe_thunks && isCodeSec;
bool keepUniqueAllowsFolding =
@@ -604,7 +629,7 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
// FIXME: consider non-code __text sections as foldable?
bool isFoldable = (!onlyCfStrings || isCfStringSection(isec)) &&
- (isCodeSec || isFoldableWithAddendsRemoved ||
+ (isCodeSec || isFoldableWithAddendsRemoved(isec) ||
isGccExceptTabSection(isec)) &&
keepUniqueAllowsFolding && !isec->hasAltEntry &&
!isec->shouldOmitFromOutput() && hasFoldableFlags;
@@ -613,32 +638,33 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
for (Defined *d : isec->symbols)
if (d->unwindEntry())
foldable.push_back(d->unwindEntry());
-
- // Some sections have embedded addends that foil ICF's hashing / equality
- // checks. (We can ignore embedded addends when doing ICF because the same
- // information gets recorded in our Reloc structs.) We therefore create a
- // mutable copy of the section data and zero out the embedded addends
- // before performing any hashing / equality checks.
- if (isFoldableWithAddendsRemoved) {
- // We have to do this copying serially as the BumpPtrAllocator is not
- // thread-safe. FIXME: Make a thread-safe allocator.
- MutableArrayRef<uint8_t> copy = isec->data.copy(bAlloc());
- for (const Relocation &r : isec->relocs)
- target->relocateOne(copy.data() + r.offset, r, /*va=*/0,
- /*relocVA=*/0);
- isec->data = copy;
- }
- } else if (!isEhFrameSection(isec)) {
- // EH frames are gathered as foldables from unwindEntry above; give a
- // unique ID to everything else.
+ } else if (isEhFrameSection(isec)) {
+ // __eh_frame contains two types of records: FDEs and CIEs.
+ // Functions point to FDEs, which are already collected above via unwindEntry().
+ // CIEs are shared headers and are not attached to individual functions.
+ // Collect only CIEs here so they can also be hashed and deduplicated.
+ auto *obj = dyn_cast_or_null<ObjFile>(isec->getFile());
+ if (!onlyCfStrings && obj && !obj->fdes.contains(isec) &&
+ !isec->shouldOmitFromOutput())
+ foldable.push_back(isec);
+ } else {
+ // Give a unique ID to everything else.
isec->icfEqClass[0] = ++icfUniqueID;
}
}
parallelForEach(foldable, [](ConcatInputSection *isec) {
assert(isec->icfEqClass[0] == 0); // don't overwrite a unique ID!
+ uint64_t hash;
+ if (isFoldableWithAddendsRemoved(isec)) {
+ SmallVector<uint8_t, 64> stackBuf;
+ getNormalizedData(isec, stackBuf);
+ hash = xxh3_64bits(stackBuf);
+ } else {
+ hash = xxh3_64bits(isec->data);
+ }
// Turn-on the top bit to guarantee that valid hashes have no collisions
// with the small-integer unique IDs for ICF-ineligible sections
- isec->icfEqClass[0] = xxh3_64bits(isec->data) | (1ull << 31);
+ isec->icfEqClass[0] = hash | (1ull << 31);
});
// Now that every input section is either hashed or marked as unique, run the
// segregation algorithm to detect foldable subsections.
diff --git a/lld/test/MachO/fold-dwarf-lsda.s b/lld/test/MachO/fold-dwarf-lsda.s
index e651fa81b8b7a..0451bc8aae266 100644
--- a/lld/test/MachO/fold-dwarf-lsda.s
+++ b/lld/test/MachO/fold-dwarf-lsda.s
@@ -22,7 +22,7 @@
# POST: [[#%x,EXCEPT_ADDR:]] l O __TEXT,__gcc_except_tab GCC_except_table0
# POST: [[#%x,EXCEPT_ADDR]] l O __TEXT,__gcc_except_tab GCC_except_table1
# POST: [[#%.16x,F0_ADDR:]] g F __TEXT,__text _f0
-# POST: [[#%.16x,F1_ADDR:]] g F __TEXT,__text _f1
+# POST: [[#%.16x,F0_ADDR]] g F __TEXT,__text _f1
# POST: [[#%.16x,G_ADDR:]] g F __TEXT,__text _g
# POST-LABEL: .eh_frame contents:
@@ -32,10 +32,6 @@
# POST: Format: DWARF32
# POST: LSDA Address: [[#%.16x,EXCEPT_ADDR]]
-# POST: {{.*}} FDE cie={{.+}} pc=[[#%x,F1_ADDR]]...{{.+}}
-# POST Format: DWARF32
-# POST LSDA Address: [[#%.16x,EXCEPT_ADDR]]
-
.section __TEXT,__text,regular,pure_instructions
.globl _f0
_f0:
>From d8dcc9b5c3e50b2cee6dbc50187670367b7e99ff Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Tue, 18 Aug 2026 11:35:45 -0400
Subject: [PATCH 3/6] Revert "[codegen]Ensure __builtin_trap() has an
unreachable"
This reverts commit 48bc3a4580675833dc69afcb8d6a4328644b6ce2.
---
clang/lib/CodeGen/CGBuiltin.cpp | 6 ------
1 file changed, 6 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index efcc33ac1f564..3f7b090315f5e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4068,12 +4068,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
case Builtin::BI__builtin_trap:
EmitTrapCall(Intrinsic::trap);
- if (Builder.GetInsertBlock()) {
- Builder.CreateUnreachable();
- // Dummy block for the ret void - it'll be clened up
- llvm::BasicBlock *DeadBB = createBasicBlock("dead.trap");
- EmitBlock(DeadBB);
- }
return RValue::get(nullptr);
case Builtin::BI__builtin_verbose_trap: {
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
>From e3e70cdb8a2fe7181351bcefea3b5e16fe2a9dcf Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Tue, 18 Aug 2026 13:40:10 -0400
Subject: [PATCH 4/6] add tests
---
lld/test/MachO/icf-fold-dwarf-frame.s | 173 ++++++++++++++++++++++++++
lld/test/MachO/icf.s | 10 +-
2 files changed, 176 insertions(+), 7 deletions(-)
create mode 100644 lld/test/MachO/icf-fold-dwarf-frame.s
diff --git a/lld/test/MachO/icf-fold-dwarf-frame.s b/lld/test/MachO/icf-fold-dwarf-frame.s
new file mode 100644
index 0000000000000..34fdc3cc55f42
--- /dev/null
+++ b/lld/test/MachO/icf-fold-dwarf-frame.s
@@ -0,0 +1,173 @@
+# REQUIRES: aarch64
+
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11 %s -o %t.o
+# RUN: %lld -arch arm64 %t.o -o %t.dylib -undefined dynamic_lookup --icf=all
+# RUN: llvm-objdump --macho --syms --dwarf=frames --unwind-info %t.dylib | FileCheck %s
+
+# CHECK-LABEL: SYMBOL TABLE:
+# CHECK-DAG: [[#%.16x,FOLD0:]] {{.*}} __TEXT,__text _foldA
+# CHECK-DAG: [[#FOLD0]] {{.*}} __TEXT,__text _foldB
+# CHECK-DAG: [[#FOLD0]] {{.*}} __TEXT,__text _foldC
+# CHECK-NOT: [[#FOLD0]] {{.*}} __TEXT,__text _diffLSDA
+# CHECK-NOT: [[#FOLD0]] {{.*}} __TEXT,__text _diffPersonality
+# CHECK-NOT: [[#FOLD0]] {{.*}} __TEXT,__text _diffCFI
+# CHECK-DAG: [[#%.16x,FOLD1:]] {{.*}} __TEXT,__gcc_except_tab GCC_except_table0
+# CHECK-DAG: [[#FOLD1]] {{.*}} __TEXT,__gcc_except_tab GCC_except_table1
+# CHECK-NOT: [[#FOLD1]] {{.*}} __TEXT,__gcc_except_tab GCC_except_table2
+
+# CHECK-LABEL: Contents of __unwind_info section:
+
+# CHECK-LABEL: .eh_frame contents:
+# CHECK: {{^}}[[#%.8x,CIE0:]] {{.*}} CIE
+# CHECK: FDE cie=[[#%.8x,CIE0]]
+# CHECK: FDE cie=[[#%.8x,CIE0]]
+# CHECK: FDE cie=[[#%.8x,CIE0]]
+# CHECK: FDE cie=[[#%.8x,CIE0]]
+# CHECK: {{^}}[[#%.8x,CIE1:]] {{.*}} CIE
+# CHECK: FDE cie=[[#%.8x,CIE1]]
+# CHECK: FDE cie=[[#%.8x,CIE1]]
+
+# Due to padding, we need to emit a throwaway FDE for each personality, so that
+# subsequent FDEs are the same size and can be folded
+# TODO: Could we detect padding differences and fold anyway?
+_padA:
+ .cfi_startproc
+ .cfi_personality 155, _p0
+ .cfi_lsda 16, Lexception0
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset w30, -16
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+_padB:
+ .cfi_startproc
+ .cfi_personality 155, _p1
+ .cfi_lsda 16, Lexception0
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset w30, -16
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+_foldA:
+ .cfi_startproc
+ .cfi_personality 155, _p0
+ .cfi_lsda 16, Lexception0
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset w30, -16
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+_foldB:
+ .cfi_startproc
+ .cfi_personality 155, _p0
+ .cfi_lsda 16, Lexception0
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset w30, -16
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+# LSDA points to a different symbol, but the contents are the same as Lexception1 so it can be folded
+_foldC:
+ .cfi_startproc
+ .cfi_personality 155, _p0
+ .cfi_lsda 16, Lexception1
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset w30, -16
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+# Different LSDAs cannot be folded
+_diffLSDA:
+ .cfi_startproc
+ .cfi_personality 155, _p0
+ .cfi_lsda 16, Lexception2
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset w30, -16
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+_diffPersonality:
+ .cfi_startproc
+ .cfi_personality 155, _p1
+ .cfi_lsda 16, Lexception0
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset w30, -16
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+_diffCFI:
+ .cfi_startproc
+ .cfi_personality 155, _p0
+ .cfi_lsda 16, Lexception0
+ str x30, [sp, #-16]!
+ .cfi_def_cfa_offset 160
+ .cfi_offset w30, -160
+ bl _may_throw
+ ldr x30, [sp], #16
+ ret
+ .cfi_endproc
+
+.section __TEXT,__gcc_except_tab
+.p2align 2
+GCC_except_table0:
+Lexception0:
+ .byte 0xFF
+ .byte 0x9B
+ .uleb128 Lttbase0-Lttbaseref0
+Lttbaseref0:
+ .byte 1
+ .uleb128 0
+ .p2align 2
+ .long 0
+Lttbase0:
+
+# Contents are identical to above. It should be folded
+.p2align 2
+GCC_except_table1:
+Lexception1:
+ .byte 0xFF
+ .byte 0x9B
+ .uleb128 Lttbase1-Lttbaseref1
+Lttbaseref1:
+ .byte 1
+ .uleb128 0
+ .p2align 2
+ .long 0
+Lttbase1:
+
+.p2align 2
+GCC_except_table2:
+Lexception2:
+ .byte 0xFF
+ .byte 0x9B
+ .uleb128 Lttbase2-Lttbaseref2
+Lttbaseref2:
+ .byte 1
+ .uleb128 1
+ .byte 0xAA
+ .p2align 2
+ .long 0
+Lttbase2:
+
+.subsections_via_symbols
diff --git a/lld/test/MachO/icf.s b/lld/test/MachO/icf.s
index 68ed369188e91..9db2a864be836 100644
--- a/lld/test/MachO/icf.s
+++ b/lld/test/MachO/icf.s
@@ -40,8 +40,8 @@
# CHECK: [[#%x,HAS_UNWIND_4:]] l F __TEXT,__text _has_unwind_4
# CHECK: [[#%x,HAS_ABS_PERSONALITY_1:]] l F __TEXT,__text _has_abs_personality_1
# CHECK: [[#%x,HAS_ABS_PERSONALITY_2:]] l F __TEXT,__text _has_abs_personality_2
-# CHECK: [[#%x,HAS_EH_FRAME_1:]] l F __TEXT,__text _has_eh_frame_1
-# CHECK: [[#%x,HAS_EH_FRAME_2:]] l F __TEXT,__text _has_eh_frame_2
+# CHECK: [[#%x,HAS_EH_FRAME_2:]] l F __TEXT,__text _has_eh_frame_1
+# CHECK: [[#%x,HAS_EH_FRAME_2]] l F __TEXT,__text _has_eh_frame_2
# CHECK: [[#%x,HAS_EH_FRAME_3:]] l F __TEXT,__text _has_eh_frame_3
# CHECK: [[#%x,MUTALLY_RECURSIVE_2:]] l F __TEXT,__text _mutually_recursive_1
# CHECK: [[#%x,MUTALLY_RECURSIVE_2]] l F __TEXT,__text _mutually_recursive_2
@@ -55,8 +55,6 @@
# CHECK: [[#%x,GCC_EXCEPT_0]] l O __TEXT,__gcc_except_tab GCC_except_table1
# CHECK: [[#%x,GCC_EXCEPT_2:]] l O __TEXT,__gcc_except_tab GCC_except_table2
-## Check that we don't accidentally dedup distinct EH frames.
-# CHECK: FDE {{.*}} pc=[[#%x,HAS_EH_FRAME_1]]
# CHECK: FDE {{.*}} pc=[[#%x,HAS_EH_FRAME_2]]
# CHECK: FDE {{.*}} pc=[[#%x,HAS_EH_FRAME_3]]
@@ -89,7 +87,7 @@
# CHECK: callq 0x[[#%x,HAS_UNWIND_4]] <_has_unwind_4>
# CHECK: callq 0x[[#%x,HAS_ABS_PERSONALITY_1]] <_has_abs_personality_1>
# CHECK: callq 0x[[#%x,HAS_ABS_PERSONALITY_2]] <_has_abs_personality_2>
-# CHECK: callq 0x[[#%x,HAS_EH_FRAME_1]] <_has_eh_frame_1>
+# CHECK: callq 0x[[#%x,HAS_EH_FRAME_2]] <_has_eh_frame_2>
# CHECK: callq 0x[[#%x,HAS_EH_FRAME_2]] <_has_eh_frame_2>
# CHECK: callq 0x[[#%x,HAS_EH_FRAME_3]] <_has_eh_frame_3>
# CHECK: callq 0x[[#%x,MUTALLY_RECURSIVE_2]] <_mutually_recursive_2>
@@ -261,8 +259,6 @@ _has_abs_personality_2:
_abs_personality_1 = 0x1
_abs_personality_2 = 0x2
-## In theory _has_eh_frame_{1, 2} can be dedup'ed, but we don't support this
-## yet.
_has_eh_frame_1:
.cfi_startproc
.cfi_def_cfa_offset 8
>From b6594941d8d0d1ea69cce0334891ecf0bb89a389 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <1762963+oontvoo at users.noreply.github.com>
Date: Tue, 18 Aug 2026 20:21:19 -0400
Subject: [PATCH 5/6] Apply suggestion from @ellishg
Co-authored-by: Ellis Hoag <ellis.sparky.hoag at gmail.com>
---
lld/MachO/ICF.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index 60df53327b834..ac540e31d761e 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -107,6 +107,8 @@ static void getNormalizedData(const ConcatInputSection *isec,
static bool compareData(const ConcatInputSection *ia,
const ConcatInputSection *ib) {
+ if (ia->data.size() != ib->data.size())
+ return false;
if (ia->data == ib->data)
return true;
if (!isFoldableWithAddendsRemoved(ia))
>From 95e3d3a1ef31360e34f129b04d06c9702c99e58d Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Tue, 18 Aug 2026 20:57:42 -0400
Subject: [PATCH 6/6] fix crash on arm64 and add assert
---
lld/MachO/ICF.cpp | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index ac540e31d761e..0b9d3e9faf723 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -101,8 +101,11 @@ static bool isFoldableWithAddendsRemoved(const ConcatInputSection *isec) {
static void getNormalizedData(const ConcatInputSection *isec,
SmallVectorImpl<uint8_t> &buf) {
buf.assign(isec->data.begin(), isec->data.end());
- for (const Relocation &r : isec->relocs)
- target->relocateOne(buf.data() + r.offset, r, /*va=*/0, /*relocVA=*/0);
+ for (const Relocation &r : isec->relocs) {
+ size_t size = 1ULL << r.length;
+ if (r.offset + size <= buf.size())
+ memset(buf.data() + r.offset, 0, size);
+ }
}
static bool compareData(const ConcatInputSection *ia,
@@ -113,6 +116,8 @@ static bool compareData(const ConcatInputSection *ia,
return true;
if (!isFoldableWithAddendsRemoved(ia))
return false;
+ assert(isFoldableWithAddendsRemoved(ib));
+
SmallVector<uint8_t, 64> bufA, bufB;
getNormalizedData(ia, bufA);
getNormalizedData(ib, bufB);
More information about the llvm-commits
mailing list