diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-01-14 01:20:03 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-01-14 01:20:03 +0000 |
commit | 3463e696fb4253a8cf16d3b5198480bbb4b10af2 (patch) | |
tree | 97e947f634d760429d4dec45b80d853d437ed718 /llvm/test | |
parent | 585025474f03f50e3b69d7ee2f4712be3613f36c (diff) | |
download | bcm5719-llvm-3463e696fb4253a8cf16d3b5198480bbb4b10af2.tar.gz bcm5719-llvm-3463e696fb4253a8cf16d3b5198480bbb4b10af2.zip |
[X86] Don't alter HasOpaqueSPAdjustment after we've relied on it
We rely on HasOpaqueSPAdjustment not changing after we've calculated
things based on it. Things like whether or not we can use 'rep;movs' to
copy bytes around, that sort of thing. If it changes, invariants in the
backend will quietly break. This situation arose when we had a call to
memcpy *and* a COPY of the FLAGS register where we would attempt to
reference local variables using %esi, a register that was clobbered by
the 'rep;movs'.
This fixes PR26124.
llvm-svn: 257730
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll b/llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll new file mode 100644 index 00000000000..ad398885728 --- /dev/null +++ b/llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll @@ -0,0 +1,53 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-pc-windows-msvc18.0.0" + +%struct.T = type { i64, [3 x i32] } + +; Function Attrs: nounwind optsize +define void @f(i8* %p, i8* %q, i32* inalloca nocapture %unused) #0 { +entry: + %g = alloca %struct.T, align 8 + %r = alloca i32, align 8 + store i32 0, i32* %r, align 4 + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %p, i8* %q, i32 24, i32 8, i1 false) + br label %while.body + +while.body: ; preds = %while.body, %entry + %load = load i32, i32* %r, align 4 + %dec = add nsw i32 %load, -1 + store i32 %dec, i32* %r, align 4 + call void @g(%struct.T* %g) + %tobool = icmp eq i32 %dec, 0 + br i1 %tobool, label %while.end, label %while.body + +while.end: ; preds = %while.body + ret void +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #1 + +declare void @g(%struct.T*) + +; CHECK-LABEL: _f: +; CHECK: pushl %ebp +; CHECK: movl %esp, %ebp +; CHECK: andl $-8, %esp +; CHECK-NOT: movl %esp, %esi +; CHECK: rep;movsl +; CHECK: leal 8(%esp), %esi + +; CHECK: decl (%esp) +; CHECK: seto %al +; CHECK: lahf +; CHECK: movl %eax, %edi +; CHECK: pushl %esi +; CHECK: calll _g +; CHECK: addl $4, %esp +; CHECK: movl %edi, %eax +; CHECK: addb $127, %al +; CHECK: sahf + +attributes #0 = { nounwind optsize } +attributes #1 = { argmemonly nounwind } |