X86: relax EFLAGS liveness check when generating stack probes.
authorTim Northover <tnorthover@apple.com>
Tue, 22 Nov 2022 11:27:05 +0000 (11:27 +0000)
committerTim Northover <tnorthover@apple.com>
Wed, 30 Nov 2022 11:44:39 +0000 (11:44 +0000)
The probes are all inserted at the iterator passed into the functions, so
that's where any EFLAGS clobbering will happen and where we need it to be dead.

Fixes: https://github.com/llvm/llvm-project/issues/59121

llvm/lib/Target/X86/X86FrameLowering.cpp
llvm/test/CodeGen/X86/probe-stack-eflags.ll

index b6fa3d5..2f1f21f 100644 (file)
@@ -733,7 +733,8 @@ void X86FrameLowering::emitStackProbeInlineGenericLoop(
     uint64_t AlignOffset) const {
   assert(Offset && "null offset");
 
-  assert(!MBB.isLiveIn(X86::EFLAGS) &&
+  assert(MBB.computeRegisterLiveness(TRI, X86::EFLAGS, MBBI) !=
+             MachineBasicBlock::LQR_Live &&
          "Inline stack probe loop will clobber live EFLAGS.");
 
   const bool NeedsDwarfCFI = needsDwarfCFI(MF);
@@ -873,7 +874,8 @@ void X86FrameLowering::emitStackProbeInlineWindowsCoreCLR64(
   const TargetInstrInfo &TII = *STI.getInstrInfo();
   const BasicBlock *LLVM_BB = MBB.getBasicBlock();
 
-  assert(!MBB.isLiveIn(X86::EFLAGS) &&
+  assert(MBB.computeRegisterLiveness(TRI, X86::EFLAGS, MBBI) !=
+             MachineBasicBlock::LQR_Live &&
          "Inline stack probe loop will clobber live EFLAGS.");
 
   // RAX contains the number of bytes of desired stack adjustment.
@@ -1112,7 +1114,8 @@ void X86FrameLowering::emitStackProbeCall(
     report_fatal_error("Emitting stack probe calls on 64-bit with the large "
                        "code model and indirect thunks not yet implemented.");
 
-  assert(!MBB.isLiveIn(X86::EFLAGS) &&
+  assert(MBB.computeRegisterLiveness(TRI, X86::EFLAGS, MBBI) !=
+             MachineBasicBlock::LQR_Live &&
          "Stack probe calls will clobber live EFLAGS.");
 
   unsigned CallOp;
index 28432ef..cc1839b 100644 (file)
@@ -75,4 +75,41 @@ exit2: ; preds = %bb70.i, %bb13.i
   ret i32 %.1.i
 }
 
+define void @CSE_eflags_live(i64 %length) "probe-stack"="__chkstk_darwin" {
+; CHECK-LABEL: CSE_eflags_live:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movq %rsp, %rbp
+; CHECK-NEXT:    .cfi_def_cfa_register %rbp
+; CHECK-NEXT:    testq %rdi, %rdi
+; CHECK-NEXT:    je .LBB1_2
+; CHECK-NEXT:  # %bb.1: # %if.end6
+; CHECK-NEXT:    movq $-1, %rax
+; CHECK-NEXT:    cmovnsq %rdi, %rax
+; CHECK-NEXT:    addq $15, %rax
+; CHECK-NEXT:    andq $-16, %rax
+; CHECK-NEXT:    callq __chkstk_darwin
+; CHECK-NEXT:    subq %rax, %rsp
+; CHECK-NEXT:  .LBB1_2: # %cleanup78
+; CHECK-NEXT:    movq %rbp, %rsp
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
+; CHECK-NEXT:    retq
+entry:
+  %cmp4 = icmp eq i64 %length, 0
+  br i1 %cmp4, label %cleanup78, label %if.end6
+
+if.end6:
+  %0 = tail call i64 @llvm.smax.i64(i64 %length, i64 -1)
+  %vla = alloca i8, i64 %0, align 16
+  br label %cleanup78
+
+cleanup78:
+  ret void
+}
+
+declare i64 @llvm.smax.i64(i64, i64)
+
 attributes #0 = { nounwind "probe-stack"="inline-asm" }