[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