[PATCH] D144541: [X86] Save/restore base pointer register when it is clobbered

LuoYuanke via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 27 03:57:44 PST 2023


LuoYuanke added a comment.

> Possible alternatives:
>
> - Use ebp... but this messes with unwinding, and doesn't actually solve the issue in general (if the inline asm references function arguments, those references are ebp-relative).

Why it would mess unwinding? The cfi instruction can indicate %esi to compute CFA. The assembly code may look like below. Yes, there is still issue if inline asm references function arguments after modifying %esi.

          .cfi_startproc
  # %bb.0:                                # %entry
          pushl   %esi
          .cfi_def_cfa_offset 8
          .cfi_offset %esi, -8
          movl    %esp, %esi       // esi is the frame pointer
          .cfi_def_cfa_register %esi
          pushl   %ebx
          pushl   %ebp
          andl    $-128, %esp
          subl    $128, %esp
          movl    %esp, %ebp        // ebp is the base pointer
          .cfi_offset %ebp, -16
          .cfi_offset %ebx, -12
          ...



> - Use some other register not used by the inline asm as a temporary base pointer.

That register (other register) may also be clobbered in another inline asm. We need analyze all the inline asm of a function to choose a base pointer register.

> - We use a different prologue that avoids the need for a base pointer.  See discussion at https://github.com/llvm/llvm-project/issues/17204

It seems gcc generate special cfi information (cfi_escape) after realign stack. Don't know what ech cif_escape means. Could you write some psuedo code for the prologue?

  [llvm]$ cat t.cpp
  #include <alloca.h>
  #include <string.h>
  #include <stdint.h>
  #include <stdlib.h>
  
  extern int bar(void *p);
  long long foo(size_t size, char c, int id) {
    __attribute__((__aligned__(128))) int a;
    char *p = (char *)alloca(size);
    asm volatile ("nop"::"c"(405):);
    asm volatile ("movl %0, %1"::"r"(id), "m"(a), "S"(405):);
    p[2] = 8;
    memset(p, c, size);
    return bar(p);
  }
  
  [llvm]$ g++ t.cpp -m32 -S -O2 -o -
          .file   "t.cpp"
          .text
          .p2align 4
          .globl  _Z3foojci
          .type   _Z3foojci, @function
  _Z3foojci:
  .LFB33:
          .cfi_startproc
          leal    4(%esp), %ecx
          .cfi_def_cfa 1, 0
          andl    $-128, %esp
          pushl   -4(%ecx)
          pushl   %ebp
          movl    %esp, %ebp
          .cfi_escape 0x10,0x5,0x2,0x75,0
          pushl   %edi
          pushl   %esi
          pushl   %ebx
          pushl   %ecx
          .cfi_escape 0xf,0x3,0x75,0x70,0x6
          .cfi_escape 0x10,0x7,0x2,0x75,0x7c
          .cfi_escape 0x10,0x6,0x2,0x75,0x78
          .cfi_escape 0x10,0x3,0x2,0x75,0x74




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144541/new/

https://reviews.llvm.org/D144541



More information about the llvm-commits mailing list