[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