mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[PS4] Guarantee an instruction after a 'noreturn' call.
We need the "return address" of a noreturn call to be within the bounds of the calling function; TrapUnreachable turns 'unreachable' into a 'ud2' instruction, which has that desired effect. Differential Revision: http://reviews.llvm.org/D18414 llvm-svn: 264224
This commit is contained in:
parent
c65e0390b0
commit
082bed0b87
@ -119,7 +119,9 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
|
|||||||
// after a call to 'noreturn' function.
|
// after a call to 'noreturn' function.
|
||||||
// To prevent that, we emit a trap for 'unreachable' IR instructions.
|
// To prevent that, we emit a trap for 'unreachable' IR instructions.
|
||||||
// (which on X86, happens to be the 'ud2' instruction)
|
// (which on X86, happens to be the 'ud2' instruction)
|
||||||
if (Subtarget.isTargetWin64())
|
// On PS4, the "return address" of a 'noreturn' call must still be within
|
||||||
|
// the calling function, and TrapUnreachable is an easy way to get that.
|
||||||
|
if (Subtarget.isTargetWin64() || Subtarget.isTargetPS4())
|
||||||
this->Options.TrapUnreachable = true;
|
this->Options.TrapUnreachable = true;
|
||||||
|
|
||||||
// By default (and when -ffast-math is on), enable estimate codegen for
|
// By default (and when -ffast-math is on), enable estimate codegen for
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck -check-prefix=X64_LINUX %s
|
; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck -check-prefix=X64_LINUX %s
|
||||||
; RUN: llc -mtriple=x86_64-pc-windows < %s | FileCheck -check-prefix=X64_WINDOWS %s
|
; RUN: llc -mtriple=x86_64-pc-windows < %s | FileCheck -check-prefix=X64_WINDOWS %s
|
||||||
; RUN: llc -mtriple=x86_64-pc-windows-gnu < %s | FileCheck -check-prefix=X64_WINDOWS_GNU %s
|
; RUN: llc -mtriple=x86_64-pc-windows-gnu < %s | FileCheck -check-prefix=X64_WINDOWS_GNU %s
|
||||||
|
; RUN: llc -mtriple=x86_64-scei-ps4 < %s | FileCheck -check-prefix=PS4 %s
|
||||||
|
|
||||||
; X64_DARWIN: orq
|
; X64_DARWIN: orq
|
||||||
; X64_DARWIN-NEXT: %bb8.i329
|
; X64_DARWIN-NEXT: %bb8.i329
|
||||||
@ -15,6 +16,9 @@
|
|||||||
; X64_WINDOWS_GNU: orq %rax, %rcx
|
; X64_WINDOWS_GNU: orq %rax, %rcx
|
||||||
; X64_WINDOWS_GNU-NEXT: ud2
|
; X64_WINDOWS_GNU-NEXT: ud2
|
||||||
|
|
||||||
|
; PS4: orq %rax, %rcx
|
||||||
|
; PS4-NEXT: ud2
|
||||||
|
|
||||||
@_ZN11xercesc_2_513SchemaSymbols21fgURI_SCHEMAFORSCHEMAE = external constant [33 x i16], align 32 ; <[33 x i16]*> [#uses=1]
|
@_ZN11xercesc_2_513SchemaSymbols21fgURI_SCHEMAFORSCHEMAE = external constant [33 x i16], align 32 ; <[33 x i16]*> [#uses=1]
|
||||||
@_ZN11xercesc_2_56XMLUni16fgNotationStringE = external constant [9 x i16], align 16 ; <[9 x i16]*> [#uses=1]
|
@_ZN11xercesc_2_56XMLUni16fgNotationStringE = external constant [9 x i16], align 16 ; <[9 x i16]*> [#uses=1]
|
||||||
|
|
||||||
|
38
test/CodeGen/X86/ps4-noreturn.ll
Normal file
38
test/CodeGen/X86/ps4-noreturn.ll
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
; RUN: llc < %s -mtriple=x86_64-scei-ps4 | FileCheck %s
|
||||||
|
|
||||||
|
declare i32 @personality(...)
|
||||||
|
|
||||||
|
; Check that after the (implicitly noreturn) unwind call, there is
|
||||||
|
; another instruction. It was easy to produce 'ud2' so we check for that.
|
||||||
|
define void @foo1() personality i32 (...)* @personality {
|
||||||
|
; CHECK-LABEL: foo1:
|
||||||
|
; CHECK: .cfi_startproc
|
||||||
|
; CHECK: callq bar
|
||||||
|
; CHECK: retq
|
||||||
|
; Check for 'ud2' between noreturn call and function end.
|
||||||
|
; CHECK: callq _Unwind_Resume
|
||||||
|
; CHECK-NEXT: ud2
|
||||||
|
; CHECK-NEXT: .Lfunc_end0:
|
||||||
|
invoke void @bar()
|
||||||
|
to label %normal
|
||||||
|
unwind label %catch
|
||||||
|
normal:
|
||||||
|
ret void
|
||||||
|
catch:
|
||||||
|
%1 = landingpad { i8*, i32 } cleanup
|
||||||
|
resume { i8*, i32 } %1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @bar() #0
|
||||||
|
|
||||||
|
; Similar check after an explicit noreturn call.
|
||||||
|
define void @foo2() {
|
||||||
|
; CHECK-LABEL: foo2:
|
||||||
|
; CHECK: callq bar
|
||||||
|
; CHECK-NEXT: ud2
|
||||||
|
; CHECK-NEXT: .Lfunc_end1:
|
||||||
|
tail call void @bar()
|
||||||
|
unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { noreturn }
|
Loading…
x
Reference in New Issue
Block a user