Merging r258221:
authorQuentin Colombet <qcolombet@apple.com>
Wed, 20 Jan 2016 01:14:03 +0000 (01:14 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Wed, 20 Jan 2016 01:14:03 +0000 (01:14 +0000)
------------------------------------------------------------------------
r258221 | qcolombet | 2016-01-19 15:29:03 -0800 (Tue, 19 Jan 2016) | 8 lines

[X86] Do not run shrink-wrapping on function with split-stack attribute or HiPE
calling convention.
The implementation of the related callbacks in the x86 backend for such
functions are not ready to deal with a prologue block that is not the entry
block of the function.

This fixes PR26107, but the longer term solution would be to fix those callbacks.

------------------------------------------------------------------------

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

lib/Target/X86/X86FrameLowering.cpp
test/CodeGen/X86/x86-shrink-wrap-unwind.ll

index 8632bb8254f9028bdb25fdc7262670633ecbd59e..7f8ce4768c00a471ecb7118788fa3f2f4dcc1eb9 100644 (file)
@@ -2031,6 +2031,10 @@ void X86FrameLowering::adjustForSegmentedStacks(
   unsigned TlsReg, TlsOffset;
   DebugLoc DL;
 
+  // To support shrink-wrapping we would need to insert the new blocks
+  // at the right place and update the branches to PrologueMBB.
+  assert(&(*MF.begin()) == &PrologueMBB && "Shrink-wrapping not supported yet");
+
   unsigned ScratchReg = GetScratchRegister(Is64Bit, IsLP64, MF, true);
   assert(!MF.getRegInfo().isLiveIn(ScratchReg) &&
          "Scratch register is live-in");
@@ -2271,6 +2275,11 @@ void X86FrameLowering::adjustForHiPEPrologue(
     MachineFunction &MF, MachineBasicBlock &PrologueMBB) const {
   MachineFrameInfo *MFI = MF.getFrameInfo();
   DebugLoc DL;
+
+  // To support shrink-wrapping we would need to insert the new blocks
+  // at the right place and update the branches to PrologueMBB.
+  assert(&(*MF.begin()) == &PrologueMBB && "Shrink-wrapping not supported yet");
+
   // HiPE-specific values
   const unsigned HipeLeafWords = 24;
   const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5;
@@ -2584,7 +2593,14 @@ bool X86FrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
 bool X86FrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
   // If we may need to emit frameless compact unwind information, give
   // up as this is currently broken: PR25614.
-  return MF.getFunction()->hasFnAttribute(Attribute::NoUnwind) || hasFP(MF);
+  return (MF.getFunction()->hasFnAttribute(Attribute::NoUnwind) || hasFP(MF)) &&
+         // The lowering of segmented stack and HiPE only support entry blocks
+         // as prologue blocks: PR26107.
+         // This limitation may be lifted if we fix:
+         // - adjustForSegmentedStacks
+         // - adjustForHiPEPrologue
+         MF.getFunction()->getCallingConv() != CallingConv::HiPE &&
+         !MF.shouldSplitStack();
 }
 
 MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers(
index 7c00f407b1e07c3a932b4258ca51183316d3c375..eb87f7101d7c52bbefb5d9a0d81e36fcb0b1b896 100644 (file)
@@ -1,11 +1,5 @@
 ; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK
 ;
-; This test checks that we do not use shrink-wrapping when
-; the function does not have any frame pointer and may unwind.
-; This is a workaround for a limitation in the emission of
-; the CFI directives, that are not correct in such case.
-; PR25614
-;
 ; Note: This test cannot be merged with the shrink-wrapping tests
 ; because the booleans set on the command line take precedence on
 ; the target logic that disable shrink-wrapping.
@@ -13,6 +7,12 @@ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
 target triple = "x86_64-apple-macosx"
 
 
+; This test checks that we do not use shrink-wrapping when
+; the function does not have any frame pointer and may unwind.
+; This is a workaround for a limitation in the emission of
+; the CFI directives, that are not correct in such case.
+; PR25614
+;
 ; No shrink-wrapping should occur here, until the CFI information are fixed.
 ; CHECK-LABEL: framelessUnwind:
 ;
@@ -151,3 +151,74 @@ false:
 }
 
 attributes #2 = { "no-frame-pointer-elim"="false" nounwind }
+
+
+; Check that we generate correct code for segmented stack.
+; We used to emit the code at the entry point of the function
+; instead of just before the prologue.
+; For now, shrink-wrapping is disabled on segmented stack functions: PR26107.
+;
+; CHECK-LABEL: segmentedStack:
+; CHECK: cmpq
+; CHECK-NEXT: ja [[ENTRY_LABEL:LBB[0-9_]+]]
+;
+; CHECK: callq ___morestack
+; CHECK-NEXT: retq
+;
+; CHECK: [[ENTRY_LABEL]]:
+; Prologue
+; CHECK: push
+;
+; In PR26107, we use to drop these two basic blocks, because
+; the segmentedStack entry block was jumping directly to
+; the place where the prologue is actually needed, which is
+; the call to memcmp.
+; Then, those two basic blocks did not have any predecessors
+; anymore and were removed.
+;
+; Check if vk1 is null
+; CHECK: testq %rdi, %rdi
+; CHECK-NEXT: je [[STRINGS_EQUAL:LBB[0-9_]+]]
+;
+; Check if vk2 is null
+; CHECK: testq %rsi, %rsi
+; CHECK-NEXT:  je [[STRINGS_EQUAL]]
+;
+; CHECK: [[STRINGS_EQUAL]]
+; CHECK-NEXT: popq
+define zeroext i1 @segmentedStack(i8* readonly %vk1, i8* readonly %vk2, i64 %key_size) #5 {
+entry:
+  %cmp.i = icmp eq i8* %vk1, null
+  %cmp1.i = icmp eq i8* %vk2, null
+  %brmerge.i = or i1 %cmp.i, %cmp1.i
+  %cmp1.mux.i = and i1 %cmp.i, %cmp1.i
+  br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i
+
+if.end4.i:                                        ; preds = %entry
+  %tmp = getelementptr inbounds i8, i8* %vk1, i64 8
+  %tmp1 = bitcast i8* %tmp to i64*
+  %tmp2 = load i64, i64* %tmp1, align 8
+  %tmp3 = getelementptr inbounds i8, i8* %vk2, i64 8
+  %tmp4 = bitcast i8* %tmp3 to i64*
+  %tmp5 = load i64, i64* %tmp4, align 8
+  %cmp.i.i = icmp eq i64 %tmp2, %tmp5
+  br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit
+
+land.rhs.i.i:                                     ; preds = %if.end4.i
+  %tmp6 = bitcast i8* %vk2 to i8**
+  %tmp7 = load i8*, i8** %tmp6, align 8
+  %tmp8 = bitcast i8* %vk1 to i8**
+  %tmp9 = load i8*, i8** %tmp8, align 8
+  %call.i.i = tail call i32 @memcmp(i8* %tmp9, i8* %tmp7, i64 %tmp2) #5
+  %cmp4.i.i = icmp eq i32 %call.i.i, 0
+  br label %__go_ptr_strings_equal.exit
+
+__go_ptr_strings_equal.exit:                      ; preds = %land.rhs.i.i, %if.end4.i, %entry
+  %retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ]
+  ret i1 %retval.0.i
+}
+
+; Function Attrs: nounwind readonly
+declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) #5
+
+attributes #5 = { nounwind readonly ssp uwtable "split-stack" }