llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.04k stars 11.98k forks source link

X86: Tail calls with function pointer indirection not folded when more than 1 parameter is passed #49386

Open llvmbot opened 3 years ago

llvmbot commented 3 years ago
Bugzilla Link 50042
Version trunk
OS All
Attachments reproducer
Reporter LLVM Bugzilla Contributor
CC @topperc,@haberman,@RKSimon,@phoebewang,@rotateright

Extended Description

The following snippet produces the assembly with function pointer table indexing folded into JMP:

typedef void (FnTy3) (void );

void dispatch15(FnTy3 *tab, intptr_t i) { tabi; }

_dispatch15: ## @​dispatch15

%bb.0: ## %entry

jmpq    *(%rdi,%rsi,8)                  ## TAILCALL

If the called function takes at least 2 parameters, indexing isn't folded.

typedef void (FnTy2) (void , intptr_t);

void dispatch1(FnTy2 *tab, intptr_t i) { tab[i](tab, i); }

_dispatch1: ## @​dispatch1

%bb.0: ## %entry

movq    (%rdi,%rsi,8), %rax
jmpq    *%rax                           ## TAILCALL
llvmbot commented 3 years ago

https://reviews.llvm.org/D101718

llvmbot commented 3 years ago

dispatch15 DAG after X86DAGToDAGISel::PreprocessISelDAG

llvmbot commented 3 years ago

dispatch1 DAG after X86DAGToDAGISel::PreprocessISelDAG craig.topper@gmail.com

llvmbot commented 3 years ago

dipatch1 and dispatch15 have a different DAG shape after X86DAGToDAGISel::PreprocessISelDAG (see attachments). There's an optimisation to "try moving call address load from outside callseq_start to just before the call to allow it to be folded." It doesn't handle a multi-parameter case for tail calls.

The following patch fixes it for me:

@@ -778,11 +778,20 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq) { LD->getExtensionType() != ISD::NON_EXTLOAD) return false;

llvmbot commented 3 years ago

assigned to @topperc