[llvm] fb294c0 - [MC] Fold A-B when A's fragment precedes B's fragment
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 22 12:24:24 PDT 2023
Author: Fangrui Song
Date: 2023-06-22T12:24:19-07:00
New Revision: fb294c0612a12f2a39be90df0c3a22f66d4ab9f7
URL: https://github.com/llvm/llvm-project/commit/fb294c0612a12f2a39be90df0c3a22f66d4ab9f7
DIFF: https://github.com/llvm/llvm-project/commit/fb294c0612a12f2a39be90df0c3a22f66d4ab9f7.diff
LOG: [MC] Fold A-B when A's fragment precedes B's fragment
When the MCAssembler is non-null and the MCAsmLayout is null, we can fold A-B
when
* A and B are in the same fragment, or
* A's fragment suceeds B's fragment, and they are not separated by non-data fragments (D69411)
This patch allows folding when A's fragment precedes B's fragment so
that `9997b - . == 0` below can be evaluated as true:
```
nop
.arch_extension sec
9997:nop
// old behavior: error: expected absolute expression
.if 9997b - . == 0
.endif
```
Add a case to llvm/test/MC/ARM/directive-if-subtraction.s.
Note: for MCAsmStreamer, we cannot evaluate `.if . - 9997b == 0` at parse
time due to MCAsmStreamer::getAssemblerPtr returning nullptr (D45164).
Some Darwin tests check that this folding does not work. Add `.p2align 2` to
block some label difference folding or adjust the tests.
Reviewed By: nickdesaulniers
Differential Revision: https://reviews.llvm.org/D153096
Added:
Modified:
llvm/lib/MC/MCExpr.cpp
llvm/test/MC/AArch64/arm64-small-data-fixups.s
llvm/test/MC/ARM/directive-if-subtraction.s
llvm/test/MC/MachO/absolutize.s
llvm/test/MC/MachO/darwin-x86_64-reloc.s
llvm/test/MC/MachO/reloc-diff.s
Removed:
################################################################################
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index c2ecc00b5796c..b16190439c2f8 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -660,6 +660,18 @@ static void AttemptToFoldSymbolOffsetDifference(
// Try to find a constant displacement from FA to FB, add the displacement
// between the offset in FA of SA and the offset in FB of SB.
int64_t Displacement = SA.getOffset() - SB.getOffset();
+ bool Reverse = false;
+ if (FA == FB) {
+ Reverse = SA.getOffset() < SB.getOffset();
+ } else if (!isa<MCDummyFragment>(FA)) {
+ Reverse = std::find_if(std::next(FA->getIterator()), SecA.end(),
+ [&](auto &I) { return &I == FB; }) != SecA.end();
+ }
+ if (Reverse) {
+ std::swap(FA, FB);
+ Displacement *= -1;
+ }
+
bool Found = false;
for (auto FI = FB->getIterator(), FE = SecA.end(); FI != FE; ++FI) {
auto DF = dyn_cast<MCDataFragment>(FI);
@@ -678,13 +690,12 @@ static void AttemptToFoldSymbolOffsetDifference(
return;
}
}
- // If FA is found or if FA is a dummy fragment not in the fragment list,
- // (which means SA is a pending label (see flushPendingLabels)), we can
- // resolve the
diff erence.
- if (Found || isa<MCDummyFragment>(FA)) {
- Addend += Displacement;
- FinalizeFolding();
- }
+ // If the previous loop does not find FA, FA must be a dummy fragment not in
+ // the fragment list (which means SA is a pending label (see
+ // flushPendingLabels)). In either case, we can resolve the
diff erence.
+ assert(Found || isa<MCDummyFragment>(FA));
+ Addend += Reverse ? -Displacement : Displacement;
+ FinalizeFolding();
}
}
diff --git a/llvm/test/MC/AArch64/arm64-small-data-fixups.s b/llvm/test/MC/AArch64/arm64-small-data-fixups.s
index 43e0d5b71114d..9ecf47e96e675 100644
--- a/llvm/test/MC/AArch64/arm64-small-data-fixups.s
+++ b/llvm/test/MC/AArch64/arm64-small-data-fixups.s
@@ -2,6 +2,7 @@
foo:
.long 0
+ .p2align 2
bar:
.long 1
diff --git a/llvm/test/MC/ARM/directive-if-subtraction.s b/llvm/test/MC/ARM/directive-if-subtraction.s
index c3a9082fb7c02..0d0ba5bf8b1b0 100644
--- a/llvm/test/MC/ARM/directive-if-subtraction.s
+++ b/llvm/test/MC/ARM/directive-if-subtraction.s
@@ -14,6 +14,16 @@ orr r1, r1, #1
orr r1, r1, #2
.endif
+nop
+.arch_extension sec
+9997:nop
+.if 9997b - . == 0
+// ASM: :[[#@LINE-1]]:5: error: expected absolute expression
+// DISASM: orr r1, r1, #2
+orr r1, r1, #1
+.else
+orr r1, r1, #2
+.endif
@ RUN: not llvm-mc -filetype=obj -triple arm-linux-gnueabihf --defsym=ERR=1 %s -o /dev/null 2>&1 | FileCheck --check-prefix=ARM-ERR %s
@ RUN: not llvm-mc -filetype=obj -triple thumbv7a-linux-gnueabihf --defsym=ERR=1 %s -o /dev/null 2>&1 | FileCheck --check-prefix=THUMB2-ERR %s
diff --git a/llvm/test/MC/MachO/absolutize.s b/llvm/test/MC/MachO/absolutize.s
index 7a2eee903df26..593d6e63e668c 100644
--- a/llvm/test/MC/MachO/absolutize.s
+++ b/llvm/test/MC/MachO/absolutize.s
@@ -94,7 +94,7 @@ Ldata_expr_2 = Ldata_d - Ldata_c
// CHECK: Offset: 383
// CHECK: Alignment: 0
// CHECK: RelocationOffset: 0x1C4
-// CHECK: RelocationCount: 3
+// CHECK: RelocationCount: 1
// CHECK: Type: Regular (0x0)
// CHECK: Attributes [ (0x0)
// CHECK: ]
@@ -115,8 +115,6 @@ Ldata_expr_2 = Ldata_d - Ldata_c
// CHECK: }
// CHECK: Section __data {
// CHECK: 0x28 0 2 n/a GENERIC_RELOC_VANILLA 1 0x2B
-// CHECK: 0x10 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 0x2B
-// CHECK: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 0x2F
// CHECK: }
// CHECK: ]
// CHECK: Symbols [
diff --git a/llvm/test/MC/MachO/darwin-x86_64-reloc.s b/llvm/test/MC/MachO/darwin-x86_64-reloc.s
index 2843b4f39cbe2..d5892087fbddf 100644
--- a/llvm/test/MC/MachO/darwin-x86_64-reloc.s
+++ b/llvm/test/MC/MachO/darwin-x86_64-reloc.s
@@ -176,20 +176,6 @@ L6:
// CHECK-NEXT: Symbol: _foo
// CHECK-NEXT: }
// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x9D
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 3
-// CHECK-NEXT: Type: X86_64_RELOC_SUBTRACTOR (5)
-// CHECK-NEXT: Symbol: _prev
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x9D
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 3
-// CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
-// CHECK-NEXT: Symbol: _foo
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
// CHECK-NEXT: Offset: 0x95
// CHECK-NEXT: PCRel: 0
// CHECK-NEXT: Length: 3
@@ -239,48 +225,6 @@ L6:
// CHECK-NEXT: Symbol: _prev
// CHECK-NEXT: }
// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x55
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 2
-// CHECK-NEXT: Type: X86_64_RELOC_SUBTRACTOR (5)
-// CHECK-NEXT: Symbol: _bar
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x55
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 2
-// CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
-// CHECK-NEXT: Symbol: _foo
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x4D
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 3
-// CHECK-NEXT: Type: X86_64_RELOC_SUBTRACTOR (5)
-// CHECK-NEXT: Symbol: _bar
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x4D
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 3
-// CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
-// CHECK-NEXT: Symbol: _foo
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x45
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 3
-// CHECK-NEXT: Type: X86_64_RELOC_SUBTRACTOR (5)
-// CHECK-NEXT: Symbol: _bar
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x45
-// CHECK-NEXT: PCRel: 0
-// CHECK-NEXT: Length: 3
-// CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
-// CHECK-NEXT: Symbol: _foo
-// CHECK-NEXT: }
-// CHECK-NEXT: Relocation {
// CHECK-NEXT: Offset: 0x3D
// CHECK-NEXT: PCRel: 0
// CHECK-NEXT: Length: 3
diff --git a/llvm/test/MC/MachO/reloc-
diff .s b/llvm/test/MC/MachO/reloc-
diff .s
index ba00e7bb1c9ff..13a5c17586904 100644
--- a/llvm/test/MC/MachO/reloc-
diff .s
+++ b/llvm/test/MC/MachO/reloc-
diff .s
@@ -1,6 +1,7 @@
// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | llvm-readobj -r - | FileCheck %s
_local_def:
+ .p2align 2
.globl _external_def
_external_def:
Ltemp:
@@ -22,5 +23,9 @@ Ltemp:
// CHECK-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 0x0
// CHECK-NEXT: 0x8 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 0x0
// CHECK-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 0x0
+// CHECK-NEXT: 0x4 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 0x0
+// CHECK-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 0x0
+// CHECK-NEXT: 0x0 0 2 n/a GENERIC_RELOC_SECTDIFF 1 0x0
+// CHECK-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
More information about the llvm-commits
mailing list