[llvm] [X86][GlobalISel] Added support for FNEG (PR #167919)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 21 23:07:31 PST 2025
https://github.com/JaydeepChauhan14 updated https://github.com/llvm/llvm-project/pull/167919
>From 0afcaf4494690d670422e5355f3ed92638b734a7 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 13 Nov 2025 09:29:20 -0800
Subject: [PATCH 1/4] [X86][GlobalISel] Added support for FNEG
---
.../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 23 ++++
llvm/lib/Target/X86/GISel/X86LegalizerInfo.h | 3 +
.../Target/X86/GISel/X86RegisterBankInfo.cpp | 1 +
.../test/CodeGen/X86/GlobalISel/isel-fneg.mir | 116 ++++++++++++++++++
llvm/test/CodeGen/X86/isel-fneg.ll | 30 ++++-
5 files changed, 170 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/GlobalISel/isel-fneg.mir
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index e792b1bce3c5c..dee75a39acc59 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -126,6 +126,13 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
G_FSINCOS, G_FCEIL, G_FFLOOR})
.libcall();
+ getActionDefinitionsBuilder(G_FNEG)
+ .legalFor(UseX87 && !HasSSE1, {s32})
+ .legalFor(UseX87 && !HasSSE2, {s64})
+ .legalFor(UseX87, {s80})
+ .customFor(UseX87 && !Is64Bit, {s32})
+ .lowerFor({s32, s64});
+
getActionDefinitionsBuilder(G_FSQRT)
.legalFor(HasSSE1 || UseX87, {s32})
.legalFor(HasSSE2 || UseX87, {s64})
@@ -993,6 +1000,22 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
return true;
}
+bool X86LegalizerInfo::legalizeFNEG(MachineInstr &MI, MachineRegisterInfo &MRI,
+ LegalizerHelper &Helper) const {
+ bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();
+ bool Is64Bit = Subtarget.is64Bit();
+ if (UseX87 && !Is64Bit && MI.getMF()->getFunction().getReturnType()->isFloatTy()) {
+ auto DstReg = MI.getOperand(0).getReg();
+ auto SrcReg = MI.getOperand(1).getReg();
+ auto ExtReg = MRI.createVirtualRegister(&X86::RFP80RegClass);
+ Helper.MIRBuilder.buildFPExt(ExtReg, SrcReg);
+ Helper.MIRBuilder.buildCopy(DstReg, ExtReg);
+ MI.eraseFromParent();
+ return true;
+ }
+ return false;
+}
+
bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
MachineInstr &MI) const {
return true;
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
index 09c727c8e8685..2bd35b6d5c58b 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
@@ -60,6 +60,9 @@ class X86LegalizerInfo : public LegalizerInfo {
bool legalizeSETROUNDING(MachineInstr &MI, MachineRegisterInfo &MRI,
LegalizerHelper &Helper) const;
+
+ bool legalizeFNEG(MachineInstr &MI, MachineRegisterInfo &MRI,
+ LegalizerHelper &Helper) const;
};
} // namespace llvm
#endif
diff --git a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
index b23d791501729..4cb7b5cc6775c 100644
--- a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
@@ -292,6 +292,7 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
switch (Opc) {
case TargetOpcode::G_FSQRT:
case TargetOpcode::G_FPEXT:
+ case TargetOpcode::G_FNEG:
case TargetOpcode::G_FPTRUNC:
case TargetOpcode::G_FCONSTANT:
// Instruction having only floating-point operands (all scalars in
diff --git a/llvm/test/CodeGen/X86/GlobalISel/isel-fneg.mir b/llvm/test/CodeGen/X86/GlobalISel/isel-fneg.mir
new file mode 100644
index 0000000000000..7aa5478dcdd95
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/isel-fneg.mir
@@ -0,0 +1,116 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=i686-linux-gnu -run-pass=regbankselect,instruction-select %s -o - | FileCheck %s --check-prefixes GISEL-I686
+
+---
+name: fneg_f64
+alignment: 16
+legalized: true
+fixedStack:
+ - { id: 0, type: default, offset: 0, size: 8, alignment: 16, stack-id: default,
+ isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.1:
+ ; GISEL-I686-LABEL: name: fneg_f64
+ ; GISEL-I686: [[DEF:%[0-9]+]]:rfp64 = IMPLICIT_DEF
+ ; GISEL-I686-NEXT: [[CHS_Fp64_:%[0-9]+]]:rfp64 = CHS_Fp64 [[DEF]], implicit-def dead $fpsw
+ ; GISEL-I686-NEXT: $fp0 = COPY [[CHS_Fp64_]]
+ ; GISEL-I686-NEXT: RET 0, implicit $fp0
+ %1:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %0:_(s64) = IMPLICIT_DEF
+ %2:_(s64) = G_FNEG %0
+ $fp0 = COPY %2(s64)
+ RET 0, implicit $fp0
+...
+---
+name: fneg_f32
+alignment: 16
+legalized: true
+fixedStack:
+ - { id: 0, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
+ isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.1:
+ ; GISEL-I686-LABEL: name: fneg_f32
+ ; GISEL-I686: [[LD_Fp32m:%[0-9]+]]:rfp32 = nofpexcept LD_Fp32m %fixed-stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (invariant load (s32) from %fixed-stack.0, align 16)
+ ; GISEL-I686-NEXT: [[CHS_Fp32_:%[0-9]+]]:rfp32 = CHS_Fp32 [[LD_Fp32m]], implicit-def dead $fpsw
+ ; GISEL-I686-NEXT: $fp0 = COPY [[CHS_Fp32_]]
+ ; GISEL-I686-NEXT: RET 0, implicit $fp0
+ %1:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %0:_(s32) = G_LOAD %1(p0) :: (invariant load (s32) from %fixed-stack.0, align 16)
+ %2:_(s32) = G_FNEG %0
+ $fp0 = COPY %2(s32)
+ RET 0, implicit $fp0
+...
+---
+name: fneg_f64_mem
+alignment: 16
+legalized: true
+fixedStack:
+ - { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
+ isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
+ isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.1:
+ ; GISEL-I686-LABEL: name: fneg_f64_mem
+ ; GISEL-I686: [[DEF:%[0-9]+]]:rfp64 = IMPLICIT_DEF
+ ; GISEL-I686-NEXT: [[CHS_Fp64_:%[0-9]+]]:rfp64 = CHS_Fp64 [[DEF]], implicit-def dead $fpsw
+ ; GISEL-I686-NEXT: $fp0 = COPY [[CHS_Fp64_]]
+ ; GISEL-I686-NEXT: RET 0, implicit $fp0
+ %1:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ %0:_(s64) = IMPLICIT_DEF
+ %2:_(s64) = G_FNEG %0
+ $fp0 = COPY %2(s64)
+ RET 0, implicit $fp0
+...
+---
+name: fneg_f32_mem
+alignment: 16
+legalized: true
+fixedStack:
+ - { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
+ isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
+ isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.1:
+ ; GISEL-I686-LABEL: name: fneg_f32_mem
+ ; GISEL-I686: [[LD_Fp32m:%[0-9]+]]:rfp32 = nofpexcept LD_Fp32m %fixed-stack.1, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (invariant load (p0) from %fixed-stack.1)
+ ; GISEL-I686-NEXT: [[CHS_Fp32_:%[0-9]+]]:rfp32 = CHS_Fp32 [[LD_Fp32m]], implicit-def dead $fpsw
+ ; GISEL-I686-NEXT: $fp0 = COPY [[CHS_Fp32_]]
+ ; GISEL-I686-NEXT: RET 0, implicit $fp0
+ %2:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ %0:_(p0) = G_LOAD %2(p0) :: (invariant load (p0) from %fixed-stack.1, align 16)
+ %3:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %1:_(s32) = G_LOAD %3(p0) :: (invariant load (p0) from %fixed-stack.0)
+ %4:_(s32) = G_FNEG %1
+ $fp0 = COPY %4(s32)
+ RET 0, implicit $fp0
+...
+---
+name: test_fp80
+alignment: 16
+legalized: true
+fixedStack:
+ - { id: 0, type: default, offset: 0, size: 10, alignment: 16, stack-id: default,
+ isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.1:
+ ; GISEL-I686-LABEL: name: test_fp80
+ ; GISEL-I686: [[LD_Fp80m:%[0-9]+]]:rfp80 = nofpexcept LD_Fp80m %fixed-stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (invariant load (s80) from %fixed-stack.0, align 16)
+ ; GISEL-I686-NEXT: [[CHS_Fp80_:%[0-9]+]]:rfp80 = CHS_Fp80 [[LD_Fp80m]], implicit-def dead $fpsw
+ ; GISEL-I686-NEXT: $fp0 = COPY [[CHS_Fp80_]]
+ ; GISEL-I686-NEXT: RET 0, implicit $fp0
+ %1:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %0:_(s80) = G_LOAD %1(p0) :: (invariant load (s80) from %fixed-stack.0, align 16)
+ %2:_(s80) = G_FNEG %0
+ $fp0 = COPY %2(s80)
+ RET 0, implicit $fp0
+...
diff --git a/llvm/test/CodeGen/X86/isel-fneg.ll b/llvm/test/CodeGen/X86/isel-fneg.ll
index 77b3f263213a9..e77c46c9d10d8 100644
--- a/llvm/test/CodeGen/X86/isel-fneg.ll
+++ b/llvm/test/CodeGen/X86/isel-fneg.ll
@@ -1,13 +1,13 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -mtriple=i686-linux-gnu -fast-isel | FileCheck %s --check-prefixes=X86,FASTISEL-X86
; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel=0 -fast-isel=0 | FileCheck %s --check-prefixes=X86,SDAG-X86
-; DISABLED: llc < %s -mtriple=i686-linux-gnu -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefixes=X86,GISEL-X86
+; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefixes=X86,GISEL-X86
; RUN: llc < %s -mtriple=i686-linux-gnu -fast-isel -mattr=+sse | FileCheck %s --check-prefixes=X86,SSE-X86,FASTISEL-SSE-X86
; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel=0 -fast-isel=0 -mattr=+sse | FileCheck %s --check-prefixes=X86,SSE-X86,SDAG-SSE-X86
-; DISABLED: llc < %s -mtriple=i686-linux-gnu -global-isel=1 -global-isel-abort=2 -mattr=+sse | FileCheck %s --check-prefixes=X86,SSE-X86,GISEL-SSE-X86
+; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel=1 -global-isel-abort=2 -mattr=+sse | FileCheck %s --check-prefixes=X86,SSE-X86,GISEL-SSE-X86
; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel -mattr=+sse | FileCheck %s --check-prefixes=X64,SSE-X64,FASTISEL-SSE-X64
; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel=0 -fast-isel=0 -mattr=+sse | FileCheck %s --check-prefixes=X64,SSE-X64,SDAG-SSE-X64
-; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel=1 -global-isel-abort=2 -mattr=+sse | FileCheck %s --check-prefixes=X64,SSE-X64,GISEL-SSE-X64
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel=1 -global-isel-abort=1 -mattr=+sse | FileCheck %s --check-prefixes=X64,SSE-X64,GISEL-SSE-X64
define double @fneg_f64(double %x) nounwind {
; X86-LABEL: fneg_f64:
@@ -53,6 +53,12 @@ define float @fneg_f32(float %x) nounwind {
; SDAG-X86-NEXT: fchs
; SDAG-X86-NEXT: retl
;
+; GISEL-X86-LABEL: fneg_f32:
+; GISEL-X86: # %bb.0:
+; GISEL-X86-NEXT: flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT: fchs
+; GISEL-X86-NEXT: retl
+;
; SSE-X86-LABEL: fneg_f32:
; SSE-X86: # %bb.0:
; SSE-X86-NEXT: pushl %eax
@@ -143,6 +149,15 @@ define void @fneg_f32_mem(ptr %x, ptr %y) nounwind {
; SDAG-X86-NEXT: movl %edx, (%eax)
; SDAG-X86-NEXT: retl
;
+; GISEL-X86-LABEL: fneg_f32_mem:
+; GISEL-X86: # %bb.0:
+; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT: flds (%eax)
+; GISEL-X86-NEXT: fchs
+; GISEL-X86-NEXT: fstps (%ecx)
+; GISEL-X86-NEXT: retl
+;
; FASTISEL-SSE-X86-LABEL: fneg_f32_mem:
; FASTISEL-SSE-X86: # %bb.0:
; FASTISEL-SSE-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
@@ -161,6 +176,15 @@ define void @fneg_f32_mem(ptr %x, ptr %y) nounwind {
; SDAG-SSE-X86-NEXT: movl %edx, (%eax)
; SDAG-SSE-X86-NEXT: retl
;
+; GISEL-SSE-X86-LABEL: fneg_f32_mem:
+; GISEL-SSE-X86: # %bb.0:
+; GISEL-SSE-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; GISEL-SSE-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; GISEL-SSE-X86-NEXT: movl $-2147483648, %edx # imm = 0x80000000
+; GISEL-SSE-X86-NEXT: xorl (%ecx), %edx
+; GISEL-SSE-X86-NEXT: movl %edx, (%eax)
+; GISEL-SSE-X86-NEXT: retl
+;
; FASTISEL-SSE-X64-LABEL: fneg_f32_mem:
; FASTISEL-SSE-X64: # %bb.0:
; FASTISEL-SSE-X64-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
>From c409acd152c5de085f9703f1f62f8c4b27d7c89e Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 13 Nov 2025 09:36:11 -0800
Subject: [PATCH 2/4] Fixed formatting issue
---
llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp | 3 ++-
llvm/lib/Target/X86/GISel/X86LegalizerInfo.h | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index dee75a39acc59..27a3129ec67cf 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -1004,7 +1004,8 @@ bool X86LegalizerInfo::legalizeFNEG(MachineInstr &MI, MachineRegisterInfo &MRI,
LegalizerHelper &Helper) const {
bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();
bool Is64Bit = Subtarget.is64Bit();
- if (UseX87 && !Is64Bit && MI.getMF()->getFunction().getReturnType()->isFloatTy()) {
+ if (UseX87 && !Is64Bit &&
+ MI.getMF()->getFunction().getReturnType()->isFloatTy()) {
auto DstReg = MI.getOperand(0).getReg();
auto SrcReg = MI.getOperand(1).getReg();
auto ExtReg = MRI.createVirtualRegister(&X86::RFP80RegClass);
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
index 2bd35b6d5c58b..d239256fb406a 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
@@ -62,7 +62,7 @@ class X86LegalizerInfo : public LegalizerInfo {
LegalizerHelper &Helper) const;
bool legalizeFNEG(MachineInstr &MI, MachineRegisterInfo &MRI,
- LegalizerHelper &Helper) const;
+ LegalizerHelper &Helper) const;
};
} // namespace llvm
#endif
>From 77a4afe749229e5a7e77e5482d00b39f1d7bd229 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 13 Nov 2025 10:30:39 -0800
Subject: [PATCH 3/4] Address review comments1
---
.../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 36 +++++++++++++------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 27a3129ec67cf..374fb95974a62 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -630,6 +630,8 @@ bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
return legalizeGETROUNDING(MI, MRI, Helper);
case TargetOpcode::G_SET_ROUNDING:
return legalizeSETROUNDING(MI, MRI, Helper);
+ case TargetOpcode::G_FNEG:
+ return legalizeFNEG(MI, MRI, Helper);
}
llvm_unreachable("expected switch to return");
}
@@ -1004,17 +1006,29 @@ bool X86LegalizerInfo::legalizeFNEG(MachineInstr &MI, MachineRegisterInfo &MRI,
LegalizerHelper &Helper) const {
bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();
bool Is64Bit = Subtarget.is64Bit();
- if (UseX87 && !Is64Bit &&
- MI.getMF()->getFunction().getReturnType()->isFloatTy()) {
- auto DstReg = MI.getOperand(0).getReg();
- auto SrcReg = MI.getOperand(1).getReg();
- auto ExtReg = MRI.createVirtualRegister(&X86::RFP80RegClass);
- Helper.MIRBuilder.buildFPExt(ExtReg, SrcReg);
- Helper.MIRBuilder.buildCopy(DstReg, ExtReg);
- MI.eraseFromParent();
- return true;
- }
- return false;
+
+ if (!(UseX87 && !Is64Bit))
+ return false;
+
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = MI.getOperand(1).getReg();
+
+ LLT S32 = LLT::scalar(32);
+ LLT S80 = LLT::scalar(80);
+
+ if (MRI.getType(SrcReg) != S32 || MRI.getType(DstReg) != S32)
+ return false;
+
+ Register ExtReg = MRI.createGenericVirtualRegister(S80);
+ Helper.MIRBuilder.buildFPExt(ExtReg, SrcReg);
+
+ Register NegReg = MRI.createGenericVirtualRegister(S80);
+ Helper.MIRBuilder.buildFNeg(NegReg, ExtReg);
+
+ Helper.MIRBuilder.buildFPTrunc(DstReg, NegReg);
+
+ MI.eraseFromParent();
+ return true;
}
bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
>From 283813a3c8cbb26873fcb20b38d9f6299a0c1382 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Sun, 21 Dec 2025 23:07:17 -0800
Subject: [PATCH 4/4] Addressed the review comments1
---
llvm/lib/Target/X86/GISel/X86CallLowering.cpp | 3 ++
.../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 32 -------------------
llvm/lib/Target/X86/GISel/X86LegalizerInfo.h | 3 --
.../GlobalISel/irtranslator-callingconv.ll | 9 ++++--
llvm/test/CodeGen/X86/isel-fneg.ll | 4 +--
5 files changed, 11 insertions(+), 40 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86CallLowering.cpp b/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
index b07ce2b958fa0..ad81711bae1c8 100644
--- a/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
+++ b/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
@@ -109,6 +109,9 @@ struct X86OutgoingValueHandler : public CallLowering::OutgoingValueHandler {
const CCValAssign &VA) override {
MIB.addUse(PhysReg, RegState::Implicit);
Register ExtReg = extendRegister(ValVReg, VA);
+ if ((VA.getLocReg() == X86::FP0 || VA.getLocReg() == X86::FP1) &&
+ STI.getTargetLowering()->isScalarFPTypeInSSEReg(VA.getValVT()))
+ ExtReg = MIRBuilder.buildFPExt(LLT::scalar(80), ExtReg).getReg(0);
MIRBuilder.buildCopy(PhysReg, ExtReg);
}
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 1df1b86e40bdd..1b2022967147c 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -130,7 +130,6 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
.legalFor(UseX87 && !HasSSE1, {s32})
.legalFor(UseX87 && !HasSSE2, {s64})
.legalFor(UseX87, {s80})
- .customFor(UseX87 && !Is64Bit, {s32})
.lowerFor({s32, s64});
getActionDefinitionsBuilder(G_FSQRT)
@@ -631,8 +630,6 @@ bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
return legalizeGETROUNDING(MI, MRI, Helper);
case TargetOpcode::G_SET_ROUNDING:
return legalizeSETROUNDING(MI, MRI, Helper);
- case TargetOpcode::G_FNEG:
- return legalizeFNEG(MI, MRI, Helper);
}
llvm_unreachable("expected switch to return");
}
@@ -1003,35 +1000,6 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
return true;
}
-bool X86LegalizerInfo::legalizeFNEG(MachineInstr &MI, MachineRegisterInfo &MRI,
- LegalizerHelper &Helper) const {
- bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();
- bool Is64Bit = Subtarget.is64Bit();
-
- if (!(UseX87 && !Is64Bit))
- return false;
-
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcReg = MI.getOperand(1).getReg();
-
- LLT S32 = LLT::scalar(32);
- LLT S80 = LLT::scalar(80);
-
- if (MRI.getType(SrcReg) != S32 || MRI.getType(DstReg) != S32)
- return false;
-
- Register ExtReg = MRI.createGenericVirtualRegister(S80);
- Helper.MIRBuilder.buildFPExt(ExtReg, SrcReg);
-
- Register NegReg = MRI.createGenericVirtualRegister(S80);
- Helper.MIRBuilder.buildFNeg(NegReg, ExtReg);
-
- Helper.MIRBuilder.buildFPTrunc(DstReg, NegReg);
-
- MI.eraseFromParent();
- return true;
-}
-
bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
MachineInstr &MI) const {
return true;
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
index d239256fb406a..09c727c8e8685 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
@@ -60,9 +60,6 @@ class X86LegalizerInfo : public LegalizerInfo {
bool legalizeSETROUNDING(MachineInstr &MI, MachineRegisterInfo &MRI,
LegalizerHelper &Helper) const;
-
- bool legalizeFNEG(MachineInstr &MI, MachineRegisterInfo &MRI,
- LegalizerHelper &Helper) const;
};
} // namespace llvm
#endif
diff --git a/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll b/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
index a797c235c46f4..cf973aa68ffd7 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
@@ -236,7 +236,8 @@ define float @test_float_args(float %arg1, float %arg2) {
; X86-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s32) from %fixed-stack.1, align 16)
; X86-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
; X86-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (s32) from %fixed-stack.0)
- ; X86-NEXT: $fp0 = COPY [[LOAD1]](s32)
+ ; X86-NEXT: [[FPEXT:%[0-9]+]]:_(s80) = G_FPEXT [[LOAD1]](s32)
+ ; X86-NEXT: $fp0 = COPY [[FPEXT]](s80)
; X86-NEXT: RET 0, implicit $fp0
;
; X64-LABEL: name: test_float_args
@@ -257,7 +258,8 @@ define double @test_double_args(double %arg1, double %arg2) {
; X86-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s64) from %fixed-stack.1, align 16)
; X86-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
; X86-NEXT: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (s64) from %fixed-stack.0)
- ; X86-NEXT: $fp0 = COPY [[LOAD1]](s64)
+ ; X86-NEXT: [[FPEXT:%[0-9]+]]:_(s80) = G_FPEXT [[LOAD1]](s64)
+ ; X86-NEXT: $fp0 = COPY [[FPEXT]](s80)
; X86-NEXT: RET 0, implicit $fp0
;
; X64-LABEL: name: test_double_args
@@ -775,7 +777,8 @@ define float @test_call_v32f32() {
; X86-NEXT: ADJCALLSTACKUP32 4, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
; X86-NEXT: [[LOAD:%[0-9]+]]:_(<32 x s32>) = G_LOAD [[FRAME_INDEX]](p0) :: (load (<32 x s32>) from %stack.0)
; X86-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[LOAD]](<32 x s32>), [[C]](s32)
- ; X86-NEXT: $fp0 = COPY [[EVEC]](s32)
+ ; X86-NEXT: [[FPEXT:%[0-9]+]]:_(s80) = G_FPEXT [[EVEC]](s32)
+ ; X86-NEXT: $fp0 = COPY [[FPEXT]](s80)
; X86-NEXT: RET 0, implicit $fp0
;
; X64-LABEL: name: test_call_v32f32
diff --git a/llvm/test/CodeGen/X86/isel-fneg.ll b/llvm/test/CodeGen/X86/isel-fneg.ll
index e77c46c9d10d8..ef25e427dcd49 100644
--- a/llvm/test/CodeGen/X86/isel-fneg.ll
+++ b/llvm/test/CodeGen/X86/isel-fneg.ll
@@ -181,8 +181,8 @@ define void @fneg_f32_mem(ptr %x, ptr %y) nounwind {
; GISEL-SSE-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; GISEL-SSE-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; GISEL-SSE-X86-NEXT: movl $-2147483648, %edx # imm = 0x80000000
-; GISEL-SSE-X86-NEXT: xorl (%ecx), %edx
-; GISEL-SSE-X86-NEXT: movl %edx, (%eax)
+; GISEL-SSE-X86-NEXT: xorl (%eax), %edx
+; GISEL-SSE-X86-NEXT: movl %edx, (%ecx)
; GISEL-SSE-X86-NEXT: retl
;
; FASTISEL-SSE-X64-LABEL: fneg_f32_mem:
More information about the llvm-commits
mailing list