diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1069,7 +1069,6 @@ template bool isSignedOffset() const { if (!isImm()) return false; - if (isa(Imm.Val)) return true; if (const MCConstantExpr *CE = dyn_cast(Imm.Val)) { int64_t Val = CE->getValue(); int64_t Align = 1LL << scale; @@ -1077,7 +1076,8 @@ int64_t Min = -Align * (1LL << (width-1)); return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max); } - return false; + // Delay the checks of symbolic values until they are resolved + return true; } // checks whether this operand is an offset suitable for the LE / diff --git a/llvm/test/MC/ARM/thumb2-b.w-target.s b/llvm/test/MC/ARM/thumb2-b.w-target.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/ARM/thumb2-b.w-target.s @@ -0,0 +1,22 @@ +# RUN: llvm-mc -triple=thumbv7 -filetype=obj %s | llvm-objdump -d - | FileCheck %s + +.syntax unified + +// arm-linux-gnueabihf-objdump produced +// 0: f000 b803 b.w a <.text+0xa> +// 4: f3ff 97fa b.w fffff8 <.text+0xfffff8> + +// llvm-objdump produced the following +// CHECK: 0: 00 +// CHECK-NEXT: 1: f0 03 lsls r0, r6, #15 +// CHECK-NEXT: 3: b8 +// CHECK-NEXT: 4: ff +// CHECK-NEXT: 5: f3 +// CHECK-NEXT: 6: fa 97 str r7, [sp, #1000] +1: + b.w . + (2f - 1b + 2) + b.w 1b - 2f + 0x1000000 +2: + + + diff --git a/llvm/test/MC/ARM/thumb2-branch-ranges.s b/llvm/test/MC/ARM/thumb2-branch-ranges.s --- a/llvm/test/MC/ARM/thumb2-branch-ranges.s +++ b/llvm/test/MC/ARM/thumb2-branch-ranges.s @@ -94,3 +94,10 @@ // CHECK: [[@LINE+2]]:{{[0-9]}}: error: Relocation out of range // CHECK-LABEL: beq.w start6 beq.w start6 + +start7: +// branch to thumb function resolved at assembly time +// CHECK-NOT: error +// CHECK: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range + b.w start8 - start7 + 0x1000000 +start8: