Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down Expand Up @@ -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()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be doing anything with the context function

auto DstReg = MI.getOperand(0).getReg();
auto SrcReg = MI.getOperand(1).getReg();
auto ExtReg = MRI.createVirtualRegister(&X86::RFP80RegClass);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no auto

Helper.MIRBuilder.buildFPExt(ExtReg, SrcReg);
Helper.MIRBuilder.buildCopy(DstReg, ExtReg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no fneg here

Copy link
Contributor Author

@JaydeepChauhan14 JaydeepChauhan14 Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix #162269 (comment) issue added these changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't follow. This is just broken

MI.eraseFromParent();
return true;
}
return false;
}

bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
MachineInstr &MI) const {
return true;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
116 changes: 116 additions & 0 deletions llvm/test/CodeGen/X86/GlobalISel/isel-fneg.mir
Original file line number Diff line number Diff line change
@@ -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
...
30 changes: 27 additions & 3 deletions llvm/test/CodeGen/X86/isel-fneg.ll
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading