forked from rust-lang/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[llvm][AArch64] Insert "bti j" after call to setjmp
Some implementations of setjmp will end with a br instead of a ret. This means that the next instruction after a call to setjmp must be a "bti j" (j for jump) to make this work when branch target identification is enabled. The BTI extension was added in armv8.5-a but the bti instruction is in the hint space. This means we can emit it for any architecture version as long as branch target enforcement flags are passed. The starting point for the hint number is 32 then call adds 2, jump adds 4. Hence "hint rust-lang#36" for a "bti j" (and "hint rust-lang#34" for the "bti c" you see at the start of functions). The existing Arm command line option -mno-bti-at-return-twice has been applied to AArch64 as well. Support is added to SelectionDAG Isel and GlobalIsel. FastIsel will defer to SelectionDAG. Based on the change done for M profile Arm in https://reviews.llvm.org/D112427 Fixes llvm#48888 Reviewed By: danielkiss Differential Revision: https://reviews.llvm.org/D121707
- Loading branch information
1 parent
a451a29
commit eb5ecbb
Showing
14 changed files
with
276 additions
and
5 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
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
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
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,51 @@ | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefix=NOBTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel < %s | FileCheck %s --check-prefix=NOBTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -fast-isel < %s | FileCheck %s --check-prefix=NOBTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+no-bti-at-return-twice < %s | \ | ||
; RUN: FileCheck %s --check-prefix=NOBTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel -mattr=+no-bti-at-return-twice < %s | \ | ||
; RUN: FileCheck %s --check-prefix=NOBTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -fast-isel -mattr=+no-bti-at-return-twice < %s | \ | ||
; RUN: FileCheck %s --check-prefix=NOBTI | ||
|
||
; Same as setjmp-bti.ll except that we do not enable branch target enforcement for this | ||
; module. There should be no combination of options that leads to a bti being emitted. | ||
|
||
; C source | ||
; -------- | ||
; extern int setjmp(void*); | ||
; extern void notsetjmp(void); | ||
; | ||
; void bbb(void) { | ||
; setjmp(0); | ||
; int (*fnptr)(void*) = setjmp; | ||
; fnptr(0); | ||
; notsetjmp(); | ||
; } | ||
|
||
define void @bbb() { | ||
; NOBTI-LABEL: bbb: | ||
; NOBTI: bl setjmp | ||
; NOBTI-NOT: hint #36 | ||
; NOBTI: blr x{{[0-9]+}} | ||
; NOBTI-NOT: hint #36 | ||
; NOBTI: bl notsetjmp | ||
; NOBTI-NOT: hint #36 | ||
|
||
entry: | ||
%fnptr = alloca i32 (i8*)*, align 8 | ||
%call = call i32 @setjmp(i8* noundef null) #0 | ||
store i32 (i8*)* @setjmp, i32 (i8*)** %fnptr, align 8 | ||
%0 = load i32 (i8*)*, i32 (i8*)** %fnptr, align 8 | ||
%call1 = call i32 %0(i8* noundef null) #0 | ||
call void @notsetjmp() | ||
ret void | ||
} | ||
|
||
declare i32 @setjmp(i8* noundef) #0 | ||
declare void @notsetjmp() | ||
|
||
attributes #0 = { returns_twice } | ||
|
||
; !llvm.module.flags = !{!0} | ||
; !0 = !{i32 1, !"branch-target-enforcement", 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,83 @@ | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -enable-machine-outliner < %s | FileCheck %s --check-prefix=BTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel -enable-machine-outliner < %s | \ | ||
; RUN: FileCheck %s --check-prefix=BTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -fast-isel -enable-machine-outliner < %s | \ | ||
; RUN: FileCheck %s --check-prefix=BTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -enable-machine-outliner -mattr=+no-bti-at-return-twice < %s | \ | ||
; RUN: FileCheck %s --check-prefix=NOBTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel -enable-machine-outliner -mattr=+no-bti-at-return-twice < %s | \ | ||
; RUN: FileCheck %s --check-prefix=NOBTI | ||
; RUN: llc -mtriple=aarch64-none-linux-gnu -fast-isel -enable-machine-outliner -mattr=+no-bti-at-return-twice < %s | \ | ||
; RUN: FileCheck %s --check-prefix=NOBTI | ||
|
||
; Check that the outliner does not split up the call to setjmp and the bti after it. | ||
; When we do not insert a bti, it is allowed to move the setjmp call into an outlined function. | ||
|
||
; C source | ||
; -------- | ||
; extern int setjmp(void*); | ||
; | ||
; int f(int a, int b, int c, int d) { | ||
; setjmp(0); | ||
; return 1 + a * (a + b) / (c + d); | ||
; } | ||
; | ||
; int g(int a, int b, int c, int d) { | ||
; setjmp(0); | ||
; return 2 + a * (a + b) / (c + d); | ||
; } | ||
|
||
define i32 @f(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) { | ||
; BTI-LABEL: f: | ||
; BTI: bl OUTLINED_FUNCTION_1 | ||
; BTI-NEXT: bl setjmp | ||
; BTI-NEXT: hint #36 | ||
; BTI-NEXT: bl OUTLINED_FUNCTION_0 | ||
|
||
; NOBTI: f: | ||
; NOBTI: bl OUTLINED_FUNCTION_0 | ||
; NOBTI-NEXT: bl OUTLINED_FUNCTION_1 | ||
|
||
entry: | ||
%call = call i32 @setjmp(i8* noundef null) #0 | ||
%add = add nsw i32 %b, %a | ||
%mul = mul nsw i32 %add, %a | ||
%add1 = add nsw i32 %d, %c | ||
%div = sdiv i32 %mul, %add1 | ||
%add2 = add nsw i32 %div, 1 | ||
ret i32 %add2 | ||
} | ||
|
||
declare i32 @setjmp(i8* noundef) #0 | ||
|
||
define i32 @g(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) { | ||
; BTI-LABEL: g: | ||
; BTI: bl OUTLINED_FUNCTION_1 | ||
; BTI-NEXT: bl setjmp | ||
; BTI-NEXT: hint #36 | ||
; BTI-NEXT: bl OUTLINED_FUNCTION_0 | ||
|
||
; NOBTI: g: | ||
; NOBTI: bl OUTLINED_FUNCTION_0 | ||
; NOBTI-NEXT: bl OUTLINED_FUNCTION_1 | ||
|
||
entry: | ||
%call = call i32 @setjmp(i8* noundef null) #0 | ||
%add = add nsw i32 %b, %a | ||
%mul = mul nsw i32 %add, %a | ||
%add1 = add nsw i32 %d, %c | ||
%div = sdiv i32 %mul, %add1 | ||
%add2 = add nsw i32 %div, 2 | ||
ret i32 %add2 | ||
} | ||
|
||
; NOBTI-LABEL: OUTLINED_FUNCTION_0: | ||
; NOBTI: b setjmp | ||
; NOBTI: OUTLINED_FUNCTION_1: | ||
; NOBTI-LABEL: ret | ||
|
||
attributes #0 = { returns_twice } | ||
|
||
!llvm.module.flags = !{!0} | ||
|
||
!0 = !{i32 1, !"branch-target-enforcement", i32 1} |
Oops, something went wrong.