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

Artyom Goncharov via llvm-dev
Mon, 07 Jan 2019 14:24:38 -0000

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

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
  ]

c:
  br label %a

a:
  br label %b

e:
  br label %a

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

g:
  br label %a

j:
  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.