diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -99,7 +99,7 @@ MF.getInfo()->hasPreallocatedCall() || MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() || MFI.hasStackMap() || MFI.hasPatchPoint() || - MFI.hasCopyImplyingStackAdjustment()); + (MFI.hasCopyImplyingStackAdjustment() && isWin64Prologue(MF))); } static unsigned getSUBriOpcode(bool IsLP64, int64_t Imm) { @@ -1286,6 +1286,10 @@ "MF used frame lowering for wrong subtarget"); const Function &Fn = MF.getFunction(); const bool IsWin64CC = STI.isCallingConvWin64(Fn.getCallingConv()); + + if (MF.getFrameInfo().hasCopyImplyingStackAdjustment()) + return isWin64Prologue(MF); + return Is64Bit && !IsWin64CC && !Fn.hasFnAttribute(Attribute::NoRedZone); } @@ -1475,11 +1479,10 @@ // stack pointer (we fit in the Red Zone). We also check that we don't // push and pop from the stack. if (has128ByteRedZone(MF) && !TRI->hasStackRealignment(MF) && - !MFI.hasVarSizedObjects() && // No dynamic alloca. - !MFI.adjustsStack() && // No calls. - !EmitStackProbeCall && // No stack probes. - !MFI.hasCopyImplyingStackAdjustment() && // Don't push and pop. - !MF.shouldSplitStack()) { // Regular stack + !MFI.hasVarSizedObjects() && // No dynamic alloca. + !MFI.adjustsStack() && // No calls. + !EmitStackProbeCall && // No stack probes. + !MF.shouldSplitStack()) { // Regular stack uint64_t MinSize = X86FI->getCalleeSavedFrameSize() - X86FI->getTCReturnAddrDelta(); if (HasFP) MinSize += SlotSize; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -27262,8 +27262,8 @@ case llvm::Intrinsic::x86_flags_read_u64: case llvm::Intrinsic::x86_flags_write_u32: case llvm::Intrinsic::x86_flags_write_u64: { - // We need a frame pointer because this will get lowered to a PUSH/POP - // sequence. + // We may need a frame pointer for winCFI because this will get lowered + // to a PUSH/POP sequence. MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); MFI.setHasCopyImplyingStackAdjustment(true); // Don't do anything here, we will expand these intrinsics out later diff --git a/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll --- a/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll +++ b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll @@ -11,14 +11,8 @@ } ; CHECK-LABEL: read_flags: -; CHECK: pushq %rbp -; CHECK: .seh_pushreg %rbp -; CHECK: movq %rsp, %rbp -; CHECK: .seh_setframe %rbp, 0 -; CHECK: .seh_endprologue -; CHECK-NEXT: pushfq +; CHECK: pushfq ; CHECK-NEXT: popq %rax -; CHECK-NEXT: popq %rbp define void @write_flags(i64 %arg) { entry: @@ -27,11 +21,5 @@ } ; CHECK-LABEL: write_flags: -; CHECK: pushq %rbp -; CHECK: .seh_pushreg %rbp -; CHECK: movq %rsp, %rbp -; CHECK: .seh_setframe %rbp, 0 -; CHECK: .seh_endprologue -; CHECK-NEXT: pushq %rcx +; CHECK: pushq %rcx ; CHECK-NEXT: popfq -; CHECK-NEXT: popq %rbp diff --git a/llvm/test/CodeGen/X86/x86-flags-intrinsics-redzone.ll b/llvm/test/CodeGen/X86/x86-flags-intrinsics-redzone.ll --- a/llvm/test/CodeGen/X86/x86-flags-intrinsics-redzone.ll +++ b/llvm/test/CodeGen/X86/x86-flags-intrinsics-redzone.ll @@ -10,31 +10,27 @@ define dso_local i32 @read_eflags(i64 noundef %z) local_unnamed_addr #0 { ; CHECK-LABEL: read_eflags: ; 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: subq $32, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 40 ; CHECK-NEXT: movzbl %dil, %eax ; CHECK-NEXT: movabsq $72340172838076673, %rcx # imm = 0x101010101010101 ; CHECK-NEXT: imulq %rax, %rcx -; CHECK-NEXT: movq %rcx, -8(%rbp) -; CHECK-NEXT: movq %rcx, -16(%rbp) -; CHECK-NEXT: movq %rcx, -24(%rbp) -; CHECK-NEXT: movq %rcx, -32(%rbp) +; CHECK-NEXT: movq %rcx, 24(%rsp) +; CHECK-NEXT: movq %rcx, 16(%rsp) +; CHECK-NEXT: movq %rcx, 8(%rsp) +; CHECK-NEXT: movq %rcx, (%rsp) ; CHECK-NEXT: pushfq ; CHECK-NEXT: popq %r8 ; CHECK-NEXT: movsbq %al, %rdi -; CHECK-NEXT: movsbl -1(%rbp), %eax +; CHECK-NEXT: movsbl 31(%rsp), %eax ; CHECK-NEXT: addl %r8d, %edi ; CHECK-NEXT: addl %eax, %edi -; CHECK-NEXT: leaq -2(%rbp), %rdx +; CHECK-NEXT: leaq 30(%rsp), %rdx ; CHECK-NEXT: movq $-30, %rsi ; CHECK-NEXT: .p2align 4, 0x90 ; CHECK-NEXT: .LBB0_1: # %for.body6.for.body6_crit_edge ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-NEXT: movsbl -1(%rbp,%rsi), %eax +; CHECK-NEXT: movsbl 31(%rsp,%rsi), %eax ; CHECK-NEXT: movsbl (%rdx), %ecx ; CHECK-NEXT: addl %r8d, %eax ; CHECK-NEXT: addl %ecx, %eax @@ -43,7 +39,7 @@ ; CHECK-NEXT: je .LBB0_3 ; CHECK-NEXT: # %bb.2: # %for.body6.for.body6_crit_edge.1 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: movsbl (%rbp,%rsi), %ecx +; CHECK-NEXT: movsbl 32(%rsp,%rsi), %ecx ; CHECK-NEXT: movsbl -1(%rdx), %edi ; CHECK-NEXT: addl %r8d, %ecx ; CHECK-NEXT: addl %edi, %ecx @@ -54,8 +50,7 @@ ; CHECK-NEXT: jmp .LBB0_1 ; CHECK-NEXT: .LBB0_3: # %for.cond.cleanup5 ; CHECK-NEXT: addq $32, %rsp -; CHECK-NEXT: popq %rbp -; CHECK-NEXT: .cfi_def_cfa %rsp, 8 +; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %foo = alloca [32 x i8], align 8 diff --git a/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll b/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll --- a/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll +++ b/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll @@ -11,11 +11,8 @@ } ; CHECK-LABEL: _read_flags: -; CHECK: pushl %ebp -; CHECK-NEXT: movl %esp, %ebp -; CHECK-NEXT: pushfl +; CHECK: pushfl ; CHECK-NEXT: popl %eax -; CHECK-NEXT: popl %ebp define x86_fastcallcc void @write_flags(i32 inreg %arg) { entry: @@ -24,8 +21,5 @@ } ; CHECK-LABEL: @write_flags@4: -; CHECK: pushl %ebp -; CHECK-NEXT: movl %esp, %ebp -; CHECK-NEXT: pushl %ecx +; CHECK: pushl %ecx ; CHECK-NEXT: popfl -; CHECK-NEXT: popl %ebp