Skip to content

[X86][GlobalIsel] support G_FABS #136718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 25, 2025
Merged

[X86][GlobalIsel] support G_FABS #136718

merged 16 commits into from
Jun 25, 2025

Conversation

mahesh-attarde
Copy link
Contributor

Adds support for G_FABS for f80.

@mahesh-attarde mahesh-attarde changed the title [X86][GlobalIsel] support fabs for f80 [X86][GlobalIsel] support G_FABS for f80 Apr 22, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 22, 2025

@llvm/pr-subscribers-llvm-globalisel

Author: Mahesh-Attarde (mahesh-attarde)

Changes

Adds support for G_FABS for f80.


Full diff: https://github.com/llvm/llvm-project/pull/136718.diff

2 Files Affected:

  • (modified) llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp (+5)
  • (added) llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll (+20)
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index f008cb1bea839..d8c1fb5717df8 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -466,6 +466,11 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
                (UseX87 && typeInSet(0, {s80})(Query));
       });
 
+  //TODO: f32 and f64 FABS require xmm support
+  getActionDefinitionsBuilder(G_FABS)
+      .legalFor(UseX87, {s8, s80})
+      .lower();
+
   // fp comparison
   getActionDefinitionsBuilder(G_FCMP)
       .legalFor(HasSSE1 || UseX87, {s8, s32})
diff --git a/llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll b/llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll
new file mode 100644
index 0000000000000..39ce3a492a33c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=x86_64-linux -mattr=+x87,-sse,-sse2 | FileCheck %s -check-prefixes=X64
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -global-isel -mattr=+x87,-sse,-sse2  | FileCheck %s -check-prefixes=GISEL
+
+define x86_fp80 @test_x86_fp80_abs(x86_fp80 %arg) {
+; X64-LABEL: test_x86_fp80_abs:
+; X64:       # %bb.0:
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fabs
+; X64-NEXT:    retq
+;
+; GISEL-LABEL: test_x86_fp80_abs:
+; GISEL:       # %bb.0:
+; GISEL-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GISEL-NEXT:    fabs
+; GISEL-NEXT:    retq
+  %abs = tail call x86_fp80 @llvm.fabs.f80(x86_fp80 %arg)
+  ret x86_fp80 %abs
+}

@llvmbot
Copy link
Member

llvmbot commented Apr 22, 2025

@llvm/pr-subscribers-backend-x86

Author: Mahesh-Attarde (mahesh-attarde)

Changes

Adds support for G_FABS for f80.


Full diff: https://github.com/llvm/llvm-project/pull/136718.diff

2 Files Affected:

  • (modified) llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp (+5)
  • (added) llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll (+20)
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index f008cb1bea839..d8c1fb5717df8 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -466,6 +466,11 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
                (UseX87 && typeInSet(0, {s80})(Query));
       });
 
+  //TODO: f32 and f64 FABS require xmm support
+  getActionDefinitionsBuilder(G_FABS)
+      .legalFor(UseX87, {s8, s80})
+      .lower();
+
   // fp comparison
   getActionDefinitionsBuilder(G_FCMP)
       .legalFor(HasSSE1 || UseX87, {s8, s32})
diff --git a/llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll b/llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll
new file mode 100644
index 0000000000000..39ce3a492a33c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/fabs-scalar.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=x86_64-linux -mattr=+x87,-sse,-sse2 | FileCheck %s -check-prefixes=X64
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -global-isel -mattr=+x87,-sse,-sse2  | FileCheck %s -check-prefixes=GISEL
+
+define x86_fp80 @test_x86_fp80_abs(x86_fp80 %arg) {
+; X64-LABEL: test_x86_fp80_abs:
+; X64:       # %bb.0:
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fabs
+; X64-NEXT:    retq
+;
+; GISEL-LABEL: test_x86_fp80_abs:
+; GISEL:       # %bb.0:
+; GISEL-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GISEL-NEXT:    fabs
+; GISEL-NEXT:    retq
+  %abs = tail call x86_fp80 @llvm.fabs.f80(x86_fp80 %arg)
+  ret x86_fp80 %abs
+}

Copy link

github-actions bot commented Apr 22, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@@ -0,0 +1,20 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
; RUN: llc < %s -mtriple=x86_64-linux -mattr=+x87,-sse,-sse2 | FileCheck %s -check-prefixes=X64
Copy link
Contributor

Choose a reason for hiding this comment

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

use explicit -global-isel=0 for dag run lines. don't need -verify-machineinstrs

Copy link
Collaborator

Choose a reason for hiding this comment

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

why not llvm/test/CodeGen/X86/isel-fabs.ll ?

@RKSimon RKSimon requested a review from e-kud April 22, 2025 16:37
//TODO: f32 and f64 FABS require xmm support
getActionDefinitionsBuilder(G_FABS)
.legalFor(UseX87, {s8, s80})
.lower();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does lower generate the selectable code? Then we probably can add tests for float and double as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+x87,-sse,-sse2 restricts SDAG Isel for float and double. It requires SSE.
exact message SSE register return with SSE disabled.

Copy link
Contributor

Choose a reason for hiding this comment

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

that error comes from the globalisel code, not sdag. You can also just stop testing with those features forced off

Copy link
Contributor

Choose a reason for hiding this comment

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

We use X87 with and without SSE for s80. So there is no need forcing -sse.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that error comes from the globalisel code, not sdag. You can also just stop testing with those features forced off
@arsenm It appeared without gisel too.
https://godbolt.org/z/Goc3zs9qe
@e-kud I can drop using -sse 👍

;
; GISEL-LABEL: test_double_abs:
; GISEL: # %bb.0:
; GISEL-NEXT: movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@e-kud is that expected with Global Pointer ?

Copy link
Contributor

@e-kud e-kud Apr 24, 2025

Choose a reason for hiding this comment

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

I've meant loading global variable using PLT when we need an extra load. I assume here the issue is that we can't select andq with the such large constant and we end up with mov + and. We can't select andps as SDAG. It requires to insert a value in a vector but we can't select this instruction yet because the index is of pointer type. Here was an attempt to allow matching with pointer type #111503. I'm still trying to find a good change to enable selection of vectors.

So, I'd say yes, this is expected but because of vectors, not global variables.

;
; GISEL-LABEL: test_double_abs:
; GISEL: # %bb.0:
; GISEL-NEXT: movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
Copy link
Contributor

@e-kud e-kud Apr 24, 2025

Choose a reason for hiding this comment

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

I've meant loading global variable using PLT when we need an extra load. I assume here the issue is that we can't select andq with the such large constant and we end up with mov + and. We can't select andps as SDAG. It requires to insert a value in a vector but we can't select this instruction yet because the index is of pointer type. Here was an attempt to allow matching with pointer type #111503. I'm still trying to find a good change to enable selection of vectors.

So, I'd say yes, this is expected but because of vectors, not global variables.

@@ -0,0 +1,52 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -global-isel=0 -mattr=+x87,+sse,+sse2 -o - | FileCheck %s --check-prefix=X64
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -global-isel=1 -mattr=+x87,+sse,+sse2 -o - | FileCheck %s -check-prefixes=GISEL
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a common prefix for SDAG and GISEL? Usually we use X64 or X86 as a common prefix and something like X64-SDAG/GISEL as unique ones.

@mahesh-attarde
Copy link
Contributor Author

I am working on i686 test. There seems to be something off. I am collecting information on it.

 bb.0 (%ir-block.0):
  renamable $eax = MOV32ri 2147483647
  renamable $eax = AND32rm killed renamable $eax(tied-def 0), %fixed-stack.0, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (invariant load (s32) from %fixed-stack.0)
  $fp0 = COPY killed renamable $eax
  RET 0, implicit killed $fp0

This code results, This is part of lowerReturn in GISEL. I suspect fp0 should not even be created. Let me know if I am wrong.

llc: /llvm-project/llvm/lib/Target/X86/X86FloatingPoint.cpp:317: unsigned int getFPReg(const llvm::MachineOperand&): Assertion `Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!"' failed. 

@@ -466,6 +466,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
(UseX87 && typeInSet(0, {s80})(Query));
});

getActionDefinitionsBuilder(G_FABS).legalFor(UseX87, {s8, s80}).lower();
Copy link
Contributor

Choose a reason for hiding this comment

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

There is only one type index, and s8 is not a valid floating point type

@mahesh-attarde
Copy link
Contributor Author

I am working on i686 test. There seems to be something off. I am collecting information on it.

 bb.0 (%ir-block.0):
  renamable $eax = MOV32ri 2147483647
  renamable $eax = AND32rm killed renamable $eax(tied-def 0), %fixed-stack.0, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (invariant load (s32) from %fixed-stack.0)
  $fp0 = COPY killed renamable $eax
  RET 0, implicit killed $fp0

This code results, This is part of lowerReturn in GISEL. I suspect fp0 should not even be created. Let me know if I am wrong.

llc: /llvm-project/llvm/lib/Target/X86/X86FloatingPoint.cpp:317: unsigned int getFPReg(const llvm::MachineOperand&): Assertion `Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!"' failed. 

It turns out Fp0 here is because of C calling convention with X87 enabled. we have defined it in calling covn td file. We might be missing RET register handling since we only look for ret reg as EAX or RAX in lowerReturn.

; RUN: llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X64
; RUN: llc < %s -mtriple=i686-- -mattr=-x87 | FileCheck %s --check-prefixes=SDAG-X86
; RUN: llc < %s -mtriple=x86_64-- -mattr=-x87 | FileCheck %s --check-prefixes=X64
; RUN: llc < %s -mtriple=x86_64-- -mattr=-x87 -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefixes=X64,FASTISEL-X64
Copy link
Collaborator

@RKSimon RKSimon Jun 3, 2025

Choose a reason for hiding this comment

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

drop unused FASTISEL-X64 checkprefix?

Copy link
Contributor Author

@mahesh-attarde mahesh-attarde Jun 3, 2025

Choose a reason for hiding this comment

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

#142558 is adding test in separate PR for DAGISEL and FASTISEL

@mahesh-attarde mahesh-attarde changed the title [X86][GlobalIsel] support G_FABS for f80 [X86][GlobalIsel] support G_FABS Jun 3, 2025
RKSimon pushed a commit that referenced this pull request Jun 5, 2025
G_FABS Test update for #136718

---------

Co-authored-by: mattarde <mattarde@intel.com>
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 5, 2025
G_FABS Test update for llvm/llvm-project#136718

---------

Co-authored-by: mattarde <mattarde@intel.com>
@mahesh-attarde
Copy link
Contributor Author

ping @e-kud @RKSimon

@@ -835,6 +841,43 @@ bool X86LegalizerInfo::legalizeNarrowingStore(MachineInstr &MI,
return true;
}

bool X86LegalizerInfo::legalizeFAbs(MachineInstr &MI,
MachineRegisterInfo &MRI,
LegalizerHelper &Helper) const {
Copy link
Collaborator

Choose a reason for hiding this comment

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

clang-format this ?

Register SrcReg = MI.getOperand(1).getReg();
Register DstReg = MI.getOperand(0).getReg();
LLT Ty = MRI.getType(DstReg);
if (Subtarget.is32Bit()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand - why are you making x86_64 use a constant pool for all float types?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For functionality of abs we are using mask, in 64 bit we have masks spans 64 bit. From ISA spec, we can only encode 32 bit immediate in instruction. so we need to load 64 bit into reg and then use reg.
Are you suggesting we only use it to double type?

Copy link
Contributor

Choose a reason for hiding this comment

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

@mahesh-attarde I think SDAG uses constant pool because of working with xmm registers. When we don't have them we still do just a simple movabs: https://godbolt.org/z/966EGMWah

@@ -41,10 +65,30 @@ define double @test_double_abs(double %arg) {
;
; FASTISEL-X86-LABEL: test_double_abs:
; FASTISEL-X86: # %bb.0:
; FASTISEL-X86-NEXT: pushl %ebp
; FASTISEL-X86-NEXT: .cfi_def_cfa_offset 8
Copy link
Collaborator

Choose a reason for hiding this comment

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

add nounwind to get rid of the cfi noise

rorth pushed a commit to rorth/llvm-project that referenced this pull request Jun 11, 2025
G_FABS Test update for llvm#136718

---------

Co-authored-by: mattarde <mattarde@intel.com>
Copy link
Contributor

@e-kud e-kud left a comment

Choose a reason for hiding this comment

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

LGTM.

; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse2,-sse | FileCheck %s --check-prefixes=X86
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse2,-sse -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefixes=X86
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse2,-sse -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=X86

define x86_fp80 @test_x86_fp80_abs(x86_fp80 %arg) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably would be nice to see how we handle floats and double without SSE.

; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse2,-sse | FileCheck %s --check-prefixes=X86
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse2,-sse -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefixes=X86
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse2,-sse -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=X86
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we add f32/f64 test coverage here? otherwise we've lost all x87-only fabs tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is known issue, we discussed it earlier while submitting test review.
#142558 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

We can store the value instead of returning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

DhruvSrivastavaX pushed a commit to DhruvSrivastavaX/lldb-for-aix that referenced this pull request Jun 12, 2025
G_FABS Test update for llvm#136718

---------

Co-authored-by: mattarde <mattarde@intel.com>
@mahesh-attarde
Copy link
Contributor Author

ping @RKSimon

@RKSimon RKSimon merged commit 0f01cd5 into llvm:main Jun 25, 2025
6 of 7 checks passed
@mahesh-attarde mahesh-attarde deleted the gisel_fabs branch June 25, 2025 09:56
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
Adds support for G_FABS for f80.

---------

Co-authored-by: mattarde <mattarde@intel.com>
Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
e-kud pushed a commit that referenced this pull request Jun 30, 2025
Fixes hidden issue in #136718. 
It removes custom selection code since problem was in RegBank
assignment
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 30, 2025
Fixes hidden issue in llvm/llvm-project#136718.
It removes custom selection code since problem was in RegBank
assignment
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
Adds support for G_FABS for f80.

---------

Co-authored-by: mattarde <mattarde@intel.com>
Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
Fixes hidden issue in llvm#136718. 
It removes custom selection code since problem was in RegBank
assignment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants