[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