[llvm-dev] Arm jump-table and inline asm label give relocation error

Artyom Goncharov via llvm-dev llvm-dev at lists.llvm.org
Mon Jan 7 06:24:38 PST 2019

Hi all,

Given sample

source_filename = “sample.ll"
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
target triple = "thumbv7-apple-ios9.1.0"

define hidden i32 @sample(i32) {
  br label %b

  %f = select i1 1, i32 2, i32 1
  switch i32 %f, label %c [
    i32 0, label %g
    i32 1, label %j
    i32 2, label %e
    i32 3, label %d

  br label %a

  br label %b

  br label %a

  call void asm sideeffect "this_is_the_label:", ""()
  br label %a

  br label %a

  br label %a

Running: "clang -cc1  -x ir ./sample.ll -triple thumbv7-apple-ios9.1.0 -emit-obj -disable-llvm-passes -target-abi apcs-gnu -mfloat-abi soft -O0 -o sample.o.ll”, I get: "fatal error: error in backend: expected relocatable expression”.

After sitting on it for some time I figured it can be fixed by just prefixing the label with “L” which makes it private global symbol. Otherwise the label forms a new atom (MCMachOStreamer::FinishImpl) which conflicts with fix-up evaluation (MCAssembler::evaluateFixup) for jump-table entry, e.g. given fix-up

LBB2_10 - (LCPI2_0 + 4)) / 2

LCPI2_0 is the switch block “b”, assigned atom “sample"
LBB2_10 is the target block “d” and will be assigned atom named “this_is_the_label”, but really it should be “sample”, so somewhere (MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl) deep down symbols resolution atoms from both symbols mismatch.

The question here is whether this behaviour is expected. It seems to me any label defined within inline asm must have MCSymbol::IsTemporary set otherwise no way to resolve these fix-ups. 

More information about the llvm-dev mailing list