Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[X86] Use single add/sub for large stack offsets
For large stack offsets the compiler generates multiple immediate mode sub/add instructions in the prologue/epilogue. This patch makes the compiler place the final amount to be added/subtracted into a register, which is then added/substracted with a single operation. Differential Revision: http://reviews.llvm.org/D7226 llvm-svn: 227458
- Loading branch information
Robert Lougher
committed
Jan 29, 2015
1 parent
a749b3e
commit c69cfee
Showing
2 changed files
with
105 additions
and
13 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
; RUN: llc < %s -mtriple=x86_64-linux-unknown | FileCheck %s --check-prefix=CHECK-64 | ||
; RUN: llc < %s -mtriple=i386-linux-unknown | FileCheck %s --check-prefix=CHECK-32 | ||
|
||
; Test that a large stack offset uses a single add/sub instruction to | ||
; adjust the stack pointer. | ||
|
||
define void @foo() nounwind { | ||
; CHECK-64-LABEL: foo: | ||
; CHECK-64: movabsq $50000000{{..}}, %rax | ||
; CHECK-64-NEXT: subq %rax, %rsp | ||
; CHECK-64-NOT: subq $2147483647, %rsp | ||
; CHECK-64: movabsq $50000000{{..}}, [[RAX:%r..]] | ||
; CHECK-64-NEXT: addq [[RAX]], %rsp | ||
|
||
; CHECK-32-LABEL: foo: | ||
; CHECK-32: movl $50000000{{..}}, %eax | ||
; CHECK-32-NEXT: subl %eax, %esp | ||
; CHECK-32-NOT: subl $2147483647, %esp | ||
; CHECK-32: movl $50000000{{..}}, [[EAX:%e..]] | ||
; CHECK-32-NEXT: addl [[EAX]], %esp | ||
%1 = alloca [5000000000 x i8], align 16 | ||
%2 = getelementptr inbounds [5000000000 x i8]* %1, i32 0, i32 0 | ||
call void @bar(i8* %2) | ||
ret void | ||
} | ||
|
||
; Verify that we do not clobber the return value. | ||
|
||
define i32 @foo2() nounwind { | ||
; CHECK-64-LABEL: foo2: | ||
; CHECK-64: movl $10, %eax | ||
; CHECK-64-NOT: movabsq ${{.*}}, %rax | ||
|
||
; CHECK-32-LABEL: foo2: | ||
; CHECK-32: movl $10, %eax | ||
; CHECK-32-NOT: movl ${{.*}}, %eax | ||
%1 = alloca [5000000000 x i8], align 16 | ||
%2 = getelementptr inbounds [5000000000 x i8]* %1, i32 0, i32 0 | ||
call void @bar(i8* %2) | ||
ret i32 10 | ||
} | ||
|
||
; Verify that we do not clobber EAX when using inreg attribute | ||
|
||
define i32 @foo3(i32 inreg %x) nounwind { | ||
; CHECK-64-LABEL: foo3: | ||
; CHECK-64: movabsq $50000000{{..}}, %rax | ||
; CHECK-64-NEXT: subq %rax, %rsp | ||
|
||
; CHECK-32-LABEL: foo3: | ||
; CHECK-32: subl $2147483647, %esp | ||
; CHECK-32-NOT: movl ${{.*}}, %eax | ||
%1 = alloca [5000000000 x i8], align 16 | ||
%2 = getelementptr inbounds [5000000000 x i8]* %1, i32 0, i32 0 | ||
call void @bar(i8* %2) | ||
ret i32 %x | ||
} | ||
|
||
declare void @bar(i8*) |