From d9f7a185e31d70a81775eb88db33c74b92b14697 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 6 Oct 2013 13:48:22 +0000 Subject: [PATCH] X86: Don't fold spills into SSE operations if the stack is unaligned. Regalloc can emit unaligned spills nowadays, but we can't fold the spills into SSE ops if we can't guarantee alignment. PR12250. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192064 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86InstrInfo.cpp | 4 ++ test/CodeGen/X86/unaligned-spill-folding.ll | 49 +++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/CodeGen/X86/unaligned-spill-folding.ll diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 277e043654e..6f8b0989a5f 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -4166,6 +4166,10 @@ MachineInstr* X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, const MachineFrameInfo *MFI = MF.getFrameInfo(); unsigned Size = MFI->getObjectSize(FrameIndex); unsigned Alignment = MFI->getObjectAlignment(FrameIndex); + // If the function stack isn't realigned we don't want to fold instructions + // that need increased alignment. + if (!RI.needsStackRealignment(MF)) + Alignment = std::min(Alignment, TM.getFrameLowering()->getStackAlignment()); if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { unsigned NewOpc = 0; unsigned RCSize = 0; diff --git a/test/CodeGen/X86/unaligned-spill-folding.ll b/test/CodeGen/X86/unaligned-spill-folding.ll new file mode 100644 index 00000000000..af0c59b6739 --- /dev/null +++ b/test/CodeGen/X86/unaligned-spill-folding.ll @@ -0,0 +1,49 @@ +; RUN: llc -mtriple=i386-unknown-freebsd -mattr=sse2 -stack-alignment=4 -relocation-model=pic < %s | FileCheck %s -check-prefix=UNALIGNED +; RUN: llc -mtriple=i386-unknown-freebsd -mattr=sse2 -stack-alignment=16 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALIGNED +; RUN: llc -mtriple=i386-unknown-freebsd -mattr=sse2 -stack-alignment=4 -force-align-stack -relocation-model=pic < %s | FileCheck %s -check-prefix=FORCEALIGNED + +@arr = internal unnamed_addr global [32 x i32] zeroinitializer, align 16 + +; PR12250 +define i32 @test1() { +vector.ph: + br label %vector.body + +vector.body: + %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds [32 x i32]* @arr, i32 0, i32 %index + %1 = bitcast i32* %0 to <4 x i32>* + %wide.load = load <4 x i32>* %1, align 16 + %2 = add nsw <4 x i32> %wide.load, + %3 = xor <4 x i32> %2, + %4 = add nsw <4 x i32> %3, + %5 = xor <4 x i32> %4, + %6 = add nsw <4 x i32> %5, + %7 = xor <4 x i32> %6, + %8 = add nsw <4 x i32> %7, + %9 = xor <4 x i32> %8, + store <4 x i32> %9, <4 x i32>* %1, align 16 + %index.next = add i32 %index, 4 + %10 = icmp eq i32 %index.next, 32 + br i1 %10, label %middle.block, label %vector.body + +middle.block: + ret i32 0 + +; We can't fold the spill into a padd unless the stack is aligned. Just spilling +; doesn't force stack realignment though +; UNALIGNED-LABEL: @test1 +; UNALIGNED-NOT: andl $-{{..}}, %esp +; UNALIGNED: movdqu {{.*}} # 16-byte Folded Spill +; UNALIGNED-NOT: paddd {{.*}} # 16-byte Folded Reload + +; ALIGNED-LABEL: @test1 +; ALIGNED-NOT: andl $-{{..}}, %esp +; ALIGNED: movdqa {{.*}} # 16-byte Spill +; ALIGNED: paddd {{.*}} # 16-byte Folded Reload + +; FORCEALIGNED-LABEL: @test1 +; FORCEALIGNED: andl $-{{..}}, %esp +; FORCEALIGNED: movdqa {{.*}} # 16-byte Spill +; FORCEALIGNED: paddd {{.*}} # 16-byte Folded Reload +} -- 2.34.1