[llvm] f3481f4 - [X86] Only force FP usage in the presence of pushf/popf on Win64

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 9 18:23:21 PST 2022


Author: Reid Kleckner
Date: 2022-02-09T18:23:16-08:00
New Revision: f3481f43bbe2c8a24e74210d310cf3be291bf52d

URL: https://github.com/llvm/llvm-project/commit/f3481f43bbe2c8a24e74210d310cf3be291bf52d
DIFF: https://github.com/llvm/llvm-project/commit/f3481f43bbe2c8a24e74210d310cf3be291bf52d.diff

LOG: [X86] Only force FP usage in the presence of pushf/popf on Win64

This ensures that the Windows unwinder will work at every instruction
boundary, and allows other targets to read and write flags without
setting up a frame pointer.

Fixes GH-46875

Differential Revision: https://reviews.llvm.org/D119391

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86FrameLowering.cpp
    llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
    llvm/test/CodeGen/X86/x86-flags-intrinsics.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 24d920db1e8dd..2a798e2e62cb8 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -100,7 +100,7 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
           MF.getInfo<X86MachineFunctionInfo>()->hasPreallocatedCall() ||
           MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() ||
           MFI.hasStackMap() || MFI.hasPatchPoint() ||
-          MFI.hasCopyImplyingStackAdjustment());
+          (isWin64Prologue(MF) && MFI.hasCopyImplyingStackAdjustment()));
 }
 
 static unsigned getSUBriOpcode(bool IsLP64, int64_t Imm) {
@@ -1385,6 +1385,9 @@ bool X86FrameLowering::has128ByteRedZone(const MachineFunction& MF) const {
   return Is64Bit && !IsWin64CC && !Fn.hasFnAttribute(Attribute::NoRedZone);
 }
 
+/// Return true if we need to use the restricted Windows x64 prologue and
+/// epilogue code patterns that can be described with WinCFI (.seh_*
+/// directives).
 bool X86FrameLowering::isWin64Prologue(const MachineFunction &MF) const {
   return MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
 }

diff  --git a/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
index 2cc64685552df..5460f36fca670 100644
--- a/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
@@ -1,37 +1,54 @@
-; RUN: llc -verify-machineinstrs < %s | FileCheck %s
-target triple = "x86_64-pc-win32"
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple x86_64-linux < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple x86_64-windows < %s | FileCheck %s --check-prefix=WIN64
 
 declare i64 @llvm.x86.flags.read.u64()
 declare void @llvm.x86.flags.write.u64(i64)
 
 define i64 @read_flags() {
+; CHECK-LABEL: read_flags:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushfq
+; CHECK-NEXT:    popq %rax
+; CHECK-NEXT:    retq
+;
+; WIN64-LABEL: read_flags:
+; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    pushq %rbp
+; WIN64-NEXT:    .seh_pushreg %rbp
+; WIN64-NEXT:    movq %rsp, %rbp
+; WIN64-NEXT:    .seh_setframe %rbp, 0
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    pushfq
+; WIN64-NEXT:    popq %rax
+; WIN64-NEXT:    popq %rbp
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
 entry:
   %flags = call i64 @llvm.x86.flags.read.u64()
   ret i64 %flags
 }
 
-; 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-NEXT: popq    %rax
-; CHECK-NEXT: popq    %rbp
-
 define void @write_flags(i64 %arg) {
+; CHECK-LABEL: write_flags:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rdi
+; CHECK-NEXT:    popfq
+; CHECK-NEXT:    retq
+;
+; WIN64-LABEL: write_flags:
+; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    pushq %rbp
+; WIN64-NEXT:    .seh_pushreg %rbp
+; WIN64-NEXT:    movq %rsp, %rbp
+; WIN64-NEXT:    .seh_setframe %rbp, 0
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    pushq %rcx
+; WIN64-NEXT:    popfq
+; WIN64-NEXT:    popq %rbp
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
 entry:
   call void @llvm.x86.flags.write.u64(i64 %arg)
   ret void
 }
-
-; 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-NEXT: popfq
-; CHECK-NEXT: popq    %rbp

diff  --git a/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll b/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll
index e2233aec22c7c..67cf0ef6e8b8f 100644
--- a/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll
@@ -1,6 +1,10 @@
 ; RUN: llc -verify-machineinstrs < %s | FileCheck %s
 target triple = "i686-pc-win32"
 
+; Check that pushf/popf intrinsics on win32 don't need a frame pointer.
+; FIXME: These can't be autogenerated due to the fastcall function name label,
+; it seems.
+
 declare i32 @llvm.x86.flags.read.u32()
 declare void @llvm.x86.flags.write.u32(i32)
 
@@ -11,11 +15,9 @@ entry:
 }
 
 ; 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
+; CHECK-NEXT: retl
 
 define x86_fastcallcc void @write_flags(i32 inreg %arg) {
 entry:
@@ -24,8 +26,6 @@ entry:
 }
 
 ; CHECK-LABEL: @write_flags at 4:
-; CHECK:      pushl   %ebp
-; CHECK-NEXT: movl    %esp, %ebp
-; CHECK-NEXT: pushl   %ecx
+; CHECK:      pushl   %ecx
 ; CHECK-NEXT: popfl
-; CHECK-NEXT: popl    %ebp
+; CHECK-NEXT: retl


        


More information about the llvm-commits mailing list