This repository has been archived by the owner on Feb 5, 2019. It is now read-only.
forked from luqmana/llvm
-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CodeGen] emit inline asm clobber list warnings for reserved
Summary: Currently, in line with GCC, when specifying reserved registers like sp or pc on an inline asm() clobber list, we don't always preserve the original value across the statement. And in general, overwriting reserved registers can have surprising results. For example: ``` extern int bar(int[]); int foo(int i) { int a[i]; // VLA asm volatile( "mov r7, #1" : : : "r7" ); return 1 + bar(a); } ``` Compiled for thumb, this gives: ``` $ clang --target=arm-arm-none-eabi -march=armv7a -c test.c -o - -S -O1 -mthumb ... foo: .fnstart @ %bb.0: @ %entry .save {r4, r5, r6, r7, lr} push {r4, r5, r6, r7, lr} .setfp r7, sp, #12 add r7, sp, #12 .pad #4 sub sp, #4 movs r1, #7 add.w r0, r1, r0, lsl #2 bic r0, r0, #7 sub.w r0, sp, r0 mov sp, r0 @app mov.w r7, #1 @NO_APP bl bar adds r0, #1 sub.w r4, r7, #12 mov sp, r4 pop {r4, r5, r6, r7, pc} ... ``` r7 is used as the frame pointer for thumb targets, and this function needs to restore the SP from the FP because of the variable-length stack allocation a. r7 is clobbered by the inline assembly (and r7 is included in the clobber list), but LLVM does not preserve the value of the frame pointer across the assembly block. This type of behavior is similar to GCC's and has been discussed on the bugtracker: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11807 . No consensus seemed to have been reached on the way forward. Clang behavior has briefly been discussed on the CFE mailing (starting here: http://lists.llvm.org/pipermail/cfe-dev/2018-July/058392.html). I've opted for following Eli Friedman's advice to print warnings when there are reserved registers on the clobber list so as not to diverge from GCC behavior for now. The patch uses MachineRegisterInfo's target-specific knowledge of reserved registers, just before we convert the inline asm string in the AsmPrinter. If we find a reserved register, we print a warning: ``` repro.c:6:7: warning: inline asm clobber list contains reserved registers: R7 [-Winline-asm] "mov r7, #1" ^ ``` Reviewers: eli.friedman, olista01, javed.absar, efriedma Reviewed By: efriedma Subscribers: efriedma, eraman, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D49727 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339257 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
5 changed files
with
126 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
; RUN: llc <%s -mtriple=aarch64-none-eabi 2>&1 | FileCheck %s | ||
|
||
; CHECK: warning: inline asm clobber list contains reserved registers: SP | ||
|
||
define void @foo() nounwind { | ||
call void asm sideeffect "mov x7, #1", "~{x7},~{sp}"() | ||
ret void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
; RUN: llc <%s -mtriple=arm-none-eabi 2>&1 | FileCheck %s -check-prefix=CHECK | ||
|
||
; RUN: llc <%s -mtriple=arm-none-eabi -relocation-model=rwpi 2>&1 \ | ||
; RUN: | FileCheck %s -check-prefix=RWPI | ||
|
||
; RUN: llc <%s -mtriple=arm-none-eabi --disable-fp-elim 2>&1 \ | ||
; RUN: | FileCheck %s -check-prefix=NO_FP_ELIM | ||
|
||
; CHECK: warning: inline asm clobber list contains reserved registers: SP, PC | ||
; CHECK: warning: inline asm clobber list contains reserved registers: R11 | ||
; RWPI: warning: inline asm clobber list contains reserved registers: R9, SP, PC | ||
; RWPI: warning: inline asm clobber list contains reserved registers: R11 | ||
; NO_FP_ELIM: warning: inline asm clobber list contains reserved registers: R11, SP, PC | ||
; NO_FP_ELIM: warning: inline asm clobber list contains reserved registers: R11 | ||
|
||
define void @foo() nounwind { | ||
call void asm sideeffect "mov r7, #1", | ||
"~{r9},~{r11},~{r12},~{lr},~{sp},~{pc},~{r10}"() | ||
ret void | ||
} | ||
|
||
define i32 @bar(i32 %i) { | ||
%vla = alloca i32, i32 %i, align 4 | ||
tail call void asm sideeffect "mov r7, #1", "~{r11}"() | ||
%1 = load volatile i32, i32* %vla, align 4 | ||
ret i32 %1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
; RUN: llc <%s -mtriple=x86_64-unknown-unknown -- 2>&1 | FileCheck %s | ||
|
||
; CHECK: warning: inline asm clobber list contains reserved registers: RSP, EBP | ||
|
||
define void @foo() nounwind { | ||
call void asm sideeffect "mov $$0x12, %eax", "~{eax},~{rsp},~{esi},~{ebp}"() | ||
ret void | ||
} |