[PATCH] D76848: [CodeGen] Error when writing to reserved registers in inline asm

Victor Campos via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 27 04:50:08 PDT 2020


vhscampos added a comment.

I should have given more context, so let me amend that.

This patch is a fix for this bug here: https://bugs.llvm.org/show_bug.cgi?id=34165
LLVM does not warn (or error out) when inline asm is used to overwrite the frame pointer. This is problematic when the frame pointer is not omitted.

There's one exception though. When the frame pointer is in the clobber operand list, a warning is printed. This leaves the remaining two cases missing: output operand and input operand.

I decided to cover the entire range of non-clobberable registers because:

1. the infrastrucuture for it was already there. Detecting only the frame pointer would involve more code than simply covering all non-clobberable registers (create new functions, etc).
2. the already present detection, which only catches clobber operands, also covers all the non-clobberable registers.
3. GCC seems to do this. E.g. it also catches writes to the 'pc' register.

Nevertheless, I have absolutely no objections to reduce the scope to just the frame pointer if you think that would be wiser.

I look forward to read your remarks.

I will paste here some other examples and the output of GCC for them.

Example 1:

  void foo() {
    register int a __asm__("r7") = 54;
    __asm__ __volatile__("mov r0, %0": : "r"(a) : "r0");
  }

GCC output:

  teste.c: In function ‘foo’:
  teste.c:4:1: error: r7 cannot be used in asm here
   }
   ^

Clang output:

  teste.c:3:24: error: write to reserved register 'R7'
    __asm__ __volatile__("mov r0, %0" : : "r"(a) : "r0");
                         ^

Clang unpatched output: no error or warning

Example 2:

  void foo() {
    register int a __asm__("r7");
    __asm__ __volatile__("mov %0, r1": "=r"(a) : :);
  }

GCC output:

  teste.c: In function ‘foo’:
  teste.c:4:1: error: r7 cannot be used in asm here
   }
   ^

Clang output:

  teste.c:3:24: error: write to reserved register 'R7'
    __asm__ __volatile__("mov r0, %0" : : "r"(a) : "r0");
                         ^

Clang unpatched output: no error or warning

Example 3:

  void foo() {
    register int a __asm__("pc");
    __asm__ __volatile__("mov %0, r0" : "=r"(a) : : );
  }

GCC output:

  teste.c: In function ‘foo’:
  teste.c:2:16: error: the register specified for ‘a’ is not general enough to be used as a register variable
     register int a __asm__("pc");
                  ^

Clang output:

  teste.c:3:24: error: write to reserved register 'PC'
    __asm__ __volatile__("mov r0, %0" : : "r"(a) : "r0");
                         ^

Clang unpatched output: no error or warning

Example 4:

  void foo() {
    register int a __asm__("pc") = 54;
    __asm__ __volatile__("mov r0, %0" : : "r"(a) : "r0");
  }

GCC output:

  teste.c: In function ‘foo’:
  teste.c:2:16: error: the register specified for ‘a’ is not general enough to be used as a register variable
     register int a __asm__("pc") = 54;
                  ^

Clang output:

  teste.c:3:24: error: write to reserved register 'PC'
    __asm__ __volatile__("mov r0, %0" : : "r"(a) : "r0");
                         ^

Clang unpatched output: no error or warning


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76848





More information about the llvm-commits mailing list