Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

[ARMv6M] missing tail call opportunities and unneeded instr emitted #30202

Open Quuxplusone opened 7 years ago

Quuxplusone commented 7 years ago
Bugzilla Link PR31227
Status NEW
Importance P normal
Reported by Weiming Zhao (weimingz@codeaurora.org)
Reported on 2016-12-01 13:20:36 -0800
Last modified on 2016-12-02 15:15:16 -0800
Version trunk
Hardware PC Linux
CC efriedma@quicinc.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
test.c:

__attribute__((noinline)) static int foo(int a) {
  return a*10;
}

int caller(int b) {
  b += 10;
  return foo(b);
}

clang -mcpu=cortex-m0 -target armv6m-linux-gnueabi -S -Os test.c -o test.llvm.s

test.llvm.s:
caller:
    .fnstart
    push    {r7, lr}
    add r7, sp, #0  ==> why do we need this?
    adds    r0, #10
    bl  foo
    pop {r7, pc}

Other compilers generate:
00000006 <caller>:
   6:   300a        adds    r0, #10
   8:   e7fe        b.n 0 <foo>

LLVM generated code has 2 problems:
1. unneeded instruction "add r7, sp, #0" is emitted
2. Other compiler can do tail call. on armv6m, "b" can be thumb2 with imm11 but
still not a big range. Maybe linker can do trampoline?
Quuxplusone commented 7 years ago

"add r7, sp, #0" is to establish frame. It's OK.

Quuxplusone commented 7 years ago
From ARMSubtarget.cpp:

  // FIXME: Completely disable sibcall for Thumb1 since ThumbRegisterInfo::
  // emitEpilogue is not ready for them. Thumb tail calls also use t2B, as
  // the Thumb1 16-bit unconditional branch doesn't have sufficient relocation
  // support in the assembler and linker to be used. This would need to be
  // fixed to fully support tail calls in Thumb1.
  //
  // Doing this is tricky, since the LDM/POP instruction on Thumb doesn't take
  // LR.  This means if we need to reload LR, it takes an extra instructions,
  // which outweighs the value of the tail call; but here we don't know yet
  // whether LR is going to be used.  Probably the right approach is to
  // generate the tail call here and turn it back into CALL/RET in
  // emitEpilogue if LR is used.