Merging r267634:
authorHans Wennborg <hans@hanshq.net>
Fri, 29 Apr 2016 23:15:39 +0000 (23:15 +0000)
committerHans Wennborg <hans@hanshq.net>
Fri, 29 Apr 2016 23:15:39 +0000 (23:15 +0000)
------------------------------------------------------------------------
r267634 | qcolombet | 2016-04-26 16:44:14 -0700 (Tue, 26 Apr 2016) | 11 lines

[X86] Make sure it is safe to clobber EFLAGS, if need be, when choosing
the prologue.

Do not use basic blocks that have EFLAGS live-in as prologue if we need
to realign the stack. Realigning the stack uses AND instruction and this
clobbers EFLAGS.

An other alternative would have been to save and restore EFLAGS around
the stack realignment code, but this is likely inefficient.

Fixes PR27531.
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@268132 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FrameLowering.cpp
lib/Target/X86/X86FrameLowering.h
test/CodeGen/X86/i686-win-shrink-wrapping.ll [new file with mode: 0644]

index f5ffe0cf7e88002b8ab5896a4063fc562d345772..75894e6734cfbc8317a3fbaf6c897a795545ae6a 100644 (file)
@@ -2569,6 +2569,12 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
   }
 }
 
+bool X86FrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const {
+  assert(MBB.getParent() && "Block is not attached to a function!");
+  const MachineFunction &MF = *MBB.getParent();
+  return !TRI->needsStackRealignment(MF) || !MBB.isLiveIn(X86::EFLAGS);
+}
+
 bool X86FrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
   assert(MBB.getParent() && "Block is not attached to a function!");
 
index 3ab41b4a57890ba94e3d9806d63c086dcb8f5f3e..65fed3ddb29f4e71752836d40259f51a973f4ea0 100644 (file)
@@ -127,6 +127,16 @@ public:
   /// Check that LEA can be used on SP in an epilogue sequence for \p MF.
   bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const;
 
+  /// Check whether or not the given \p MBB can be used as a prologue
+  /// for the target.
+  /// The prologue will be inserted first in this basic block.
+  /// This method is used by the shrink-wrapping pass to decide if
+  /// \p MBB will be correctly handled by the target.
+  /// As soon as the target enable shrink-wrapping without overriding
+  /// this method, we assume that each basic block is a valid
+  /// prologue.
+  bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
+
   /// Check whether or not the given \p MBB can be used as a epilogue
   /// for the target.
   /// The epilogue will be inserted before the first terminator of that block.
diff --git a/test/CodeGen/X86/i686-win-shrink-wrapping.ll b/test/CodeGen/X86/i686-win-shrink-wrapping.ll
new file mode 100644 (file)
index 0000000..1a2cb84
--- /dev/null
@@ -0,0 +1,44 @@
+; RUN: llc %s -o - -enable-shrink-wrap=true | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
+; RUN: llc %s -o - -enable-shrink-wrap=false | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
+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.S = type { i32 }
+
+; Check that we do not use a basic block that has EFLAGS as live-in
+; if we need to realign the stack.
+; PR27531.
+; CHECK-LABEL: stackRealignment:
+; Prologue code.
+; CHECK: pushl
+; Make sure we actually perform some stack realignment.
+; CHECK: andl ${{[-0-9]+}}, %esp
+; This is the end of the entry block.
+; The prologue should have happened before that point because past
+; this point, EFLAGS is live.
+; CHECK: jg
+define x86_thiscallcc void @stackRealignment(%struct.S* %this) {
+entry:
+  %data = alloca [1 x i32], align 4
+  %d = alloca double, align 8
+  %tmp = bitcast [1 x i32]* %data to i8*
+  %arrayinit.begin = getelementptr inbounds [1 x i32], [1 x i32]* %data, i32 0, i32 0
+  %x_ = getelementptr inbounds %struct.S, %struct.S* %this, i32 0, i32 0
+  %tmp1 = load i32, i32* %x_, align 4
+  %cmp = icmp sgt i32 %tmp1, 32
+  %cond = select i1 %cmp, i32 42, i32 128
+  store i32 %cond, i32* %arrayinit.begin, align 4
+  %cmp3 = icmp slt i32 %tmp1, 32
+  br i1 %cmp3, label %cleanup, label %if.end
+
+if.end:                                           ; preds = %entry
+  %tmp2 = bitcast double* %d to i8*
+  call x86_thiscallcc void @bar(%struct.S* nonnull %this, i32* %arrayinit.begin, double* nonnull %d)
+  br label %cleanup
+
+cleanup:                                          ; preds = %if.end, %entry
+  ret void
+}
+
+; Function Attrs: optsize
+declare x86_thiscallcc void @bar(%struct.S*, i32*, double*)