diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -654,15 +654,33 @@ // 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 { + for (auto FI = FA->getIterator(), FE = SecA.end(); ++FI != FE;) { + if (&*FI == FB) { + Reverse = true; + break; + } + } + } + if (Reverse) { + std::swap(FA, FB); + Displacement *= -1; + } + for (auto FI = FB->getIterator(), FE = SecA.end(); FI != FE; ++FI) { + auto F = dyn_cast(FI); if (&*FI == FA) { - Addend += Displacement; + Addend += Reverse ? -Displacement : Displacement; return FinalizeFolding(); } - if (FI->getKind() != MCFragment::FT_Data) + // F is not a MCDataFragment. Its size cannot be determined now. Bail out. + if (!F) return; - Displacement += cast(FI)->getContents().size(); + Displacement += F->getContents().size(); } } } diff --git a/llvm/test/MC/AArch64/arm64-small-data-fixups.s b/llvm/test/MC/AArch64/arm64-small-data-fixups.s --- 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 --- a/llvm/test/MC/ARM/directive-if-subtraction.s +++ b/llvm/test/MC/ARM/directive-if-subtraction.s @@ -15,6 +15,17 @@ orr r1, r1, #2 .endif +nop +.arch_extension sec +9997:nop +.if 9997b - . == 0 +// OBJ-NOT:[[@LINE-1]]:5: error: expected absolute expression +// ASM:[[@LINE-2]]: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 diff --git a/llvm/test/MC/MachO/absolutize.s b/llvm/test/MC/MachO/absolutize.s --- a/llvm/test/MC/MachO/absolutize.s +++ b/llvm/test/MC/MachO/absolutize.s @@ -94,7 +94,7 @@ // 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 @@ // 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 --- a/llvm/test/MC/MachO/darwin-x86_64-reloc.s +++ b/llvm/test/MC/MachO/darwin-x86_64-reloc.s @@ -239,48 +239,6 @@ // 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 --- 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 @@ // 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: ]