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 @@ -660,6 +660,18 @@ // 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(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(FI); @@ -678,13 +690,12 @@ 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 difference. - if (Found || isa(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 difference. + assert(Found || isa(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 --- 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 @@ -14,6 +14,16 @@ 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 --- 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 @@ -176,20 +176,6 @@ // 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 @@ // 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: ]