summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2018-04-07 10:57:03 +0000
committerTim Northover <tnorthover@apple.com>2018-04-07 10:57:03 +0000
commite25e458d5233ef829f90110e1197aa3e1588faf4 (patch)
tree2b917151fc8ad32f7574c9463a83843a411430a9 /llvm/test/CodeGen
parent61061d69eacfb546283f33cba053c29bb1c1ef7e (diff)
downloadbcm5719-llvm-e25e458d5233ef829f90110e1197aa3e1588faf4.tar.gz
bcm5719-llvm-e25e458d5233ef829f90110e1197aa3e1588faf4.zip
Reapply ARM: Do not spill CSR to stack on entry to noreturn functions
Should fix UBSan bot by also checking there's no "uwtable" attribute before skipping. Otherwise the unwind table will be useless since its moves expect CSRs to actually be preserved. A noreturn nounwind function can be expected to never return in any way, and by never returning it will also never have to restore any callee-saved registers for its caller. This makes it possible to skip spills of those registers during function entry, saving some stack space and time in the process. This is rather useful for embedded targets with limited stack space. Should fix PR9970. Patch mostly by myeisha (pmb). llvm-svn: 329494
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r--llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll4
-rw-r--r--llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll2
-rw-r--r--llvm/test/CodeGen/ARM/noreturn-csr-skip.mir65
-rw-r--r--llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll2
-rw-r--r--llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll2
-rw-r--r--llvm/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll10
-rw-r--r--llvm/test/CodeGen/X86/x86-shrink-wrapping.ll2
7 files changed, 76 insertions, 11 deletions
diff --git a/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll b/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll
index 0253229c0d7..7ae739ebf4d 100644
--- a/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll
@@ -281,7 +281,7 @@ declare void @somethingElse(...)
; Shift second argument by one and store into returned register.
; ENABLE: lsl w0, w1, #1
; ENABLE: ret
-define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 {
+define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind {
entry:
%tobool = icmp eq i32 %cond, 0
br i1 %tobool, label %if.else, label %if.then
@@ -355,7 +355,7 @@ entry:
; CHECK-NEXT: lsl w0, w1, #1
; DISABLE-NEXT: add sp, sp, #16
; CHECK-NEXT: ret
-define i32 @variadicFunc(i32 %cond, i32 %count, ...) #0 {
+define i32 @variadicFunc(i32 %cond, i32 %count, ...) nounwind {
entry:
%ap = alloca i8*, align 8
%tobool = icmp eq i32 %cond, 0
diff --git a/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll b/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll
index 1985ff9b4a2..c943f60c56d 100644
--- a/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll
+++ b/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll
@@ -327,7 +327,7 @@ declare void @somethingElse(...)
; DISABLE-NEXT: pop {r4, r7, pc}
;
; ENABLE-NEXT: bx lr
-define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) "no-frame-pointer-elim"="true" #0 {
+define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) "no-frame-pointer-elim"="true" nounwind {
entry:
%tobool = icmp eq i32 %cond, 0
br i1 %tobool, label %if.else, label %if.then
diff --git a/llvm/test/CodeGen/ARM/noreturn-csr-skip.mir b/llvm/test/CodeGen/ARM/noreturn-csr-skip.mir
new file mode 100644
index 00000000000..2cf0bc80ae7
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/noreturn-csr-skip.mir
@@ -0,0 +1,65 @@
+# RUN: llc -mtriple thumbv7m-none-eabi -run-pass prologepilog %s -o - | FileCheck %s
+
+--- |
+ define void @throw() noreturn { unreachable }
+
+ define void @ret() nounwind { ret void }
+
+ define void @tables() nounwind noreturn uwtable { ret void }
+
+ define void @noret() noreturn nounwind {
+ start:
+ %p = alloca i32
+ store i32 42, i32* %p
+ unreachable
+ }
+...
+---
+# This function may return by exception. Check that $r4 is saved and restored.
+# CHECK-LABEL: name: throw
+# CHECK: killed $r4
+# CHECK: def $r4
+name: throw
+body: |
+ bb.0:
+ $r4 = IMPLICIT_DEF
+ tBX_RET 14, $noreg
+---
+---
+# This function may return. Check that $r4 is saved and restored.
+# CHECK-LABEL: name: ret
+# CHECK: killed $r4
+# CHECK: def $r4
+name: ret
+body: |
+ bb.0:
+ $r4 = IMPLICIT_DEF
+ tBX_RET 14, $noreg
+---
+---
+# This function needs correct unwind tables anyway. Check that $r4 is saved and
+# restored.
+# CHECK-LABEL: name: tables
+# CHECK: killed $r4
+# CHECK: def $r4
+name: tables
+body: |
+ bb.0:
+ $r4 = IMPLICIT_DEF
+ tBX_RET 14, $noreg
+---
+---
+# This function does not return. We need not save any CSR, but
+# other stack adjustments in the prologue are still necessary.
+# CHECK-LABEL: name: noret
+# CHECK-NOT: killed $r4
+# CHECK-NOT: def $r4
+# CHECK: $sp = frame-setup
+name: noret
+stack:
+ - { id: 0, name: p, offset: 0, size: 4, alignment: 4, local-offset: -4 }
+body: |
+ bb.0:
+ $r4 = IMPLICIT_DEF
+ tBX_RET 14, $noreg
+---
diff --git a/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll b/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll
index 2bf4b0722f9..6886b4efa85 100644
--- a/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll
+++ b/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll
@@ -328,7 +328,7 @@ declare void @somethingElse(...)
; Shift second argument by one and store into returned register.
; ENABLE: slwi 3, 4, 1
; ENABLE-NEXT: blr
-define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 {
+define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind {
entry:
%tobool = icmp eq i32 %cond, 0
br i1 %tobool, label %if.else, label %if.then
diff --git a/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll b/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll
index 471626251d5..5d93f30f417 100644
--- a/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll
+++ b/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll
@@ -374,7 +374,7 @@ declare void @somethingElse(...)
;
; ENABLE-V5T-NEXT: {{LBB[0-9_]+}}: @ %if.end
; ENABLE-NEXT: bx lr
-define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 {
+define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind {
entry:
%tobool = icmp eq i32 %cond, 0
br i1 %tobool, label %if.else, label %if.then
diff --git a/llvm/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll b/llvm/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll
index c3b12edf4ce..9d3e18efea2 100644
--- a/llvm/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll
+++ b/llvm/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll
@@ -17,10 +17,10 @@
%tupl = type [9 x i32]
-declare fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) noreturn nounwind
-declare fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) noreturn nounwind
+declare fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) nounwind
+declare fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) nounwind
-define fastcc void @l186(%tupl* %r1) noreturn nounwind {
+define fastcc void @l186(%tupl* %r1) nounwind {
entry:
%ptr1 = getelementptr %tupl, %tupl* %r1, i32 0, i32 0
%r2 = load i32, i32* %ptr1
@@ -44,10 +44,10 @@ entry:
br i1 %cond, label %true, label %false
true:
- tail call fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) noreturn nounwind
+ tail call fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) nounwind
ret void
false:
- tail call fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) noreturn nounwind
+ tail call fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) nounwind
ret void
}
diff --git a/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll b/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll
index 65a5c78a5da..cc77efae091 100644
--- a/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll
+++ b/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll
@@ -314,7 +314,7 @@ if.end: ; preds = %if.else, %for.end
; ENABLE: addl %esi, %esi
; ENABLE-NEXT: movl %esi, %eax
; ENABLE-NEXT: retq
-define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 {
+define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind {
entry:
%tobool = icmp eq i32 %cond, 0
br i1 %tobool, label %if.else, label %if.then
OpenPOWER on IntegriCloud