Skip to content

Conversation

@circYuan
Copy link
Contributor

@circYuan circYuan commented Nov 3, 2025

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Nov 3, 2025

@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-llvm-globalisel

Author: Chuan-Yue Yuan (circYuan)

Changes

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

3 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+5)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/fp-fcanonicalize.ll (+66)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir (+2-2)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index b1794b78a3e2a..d68dc3c8d991f 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -636,6 +636,11 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
       .libcallFor({{s32, s32}, {s64, s32}})
       .libcallFor(ST.is64Bit(), {s128, s32});
 
+  getActionDefinitionsBuilder(G_FCANONICALIZE)
+      .legalFor(ST.hasStdExtF(), {s32})
+      .legalFor(ST.hasStdExtD(), {s64})
+      .legalFor(ST.hasStdExtZfh(), {s16});
+
   getActionDefinitionsBuilder(G_VASTART).customFor({p0});
 
   // va_list must be a pointer, but most sized types are pretty easy to handle
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/fp-fcanonicalize.ll b/llvm/test/CodeGen/RISCV/GlobalISel/fp-fcanonicalize.ll
new file mode 100644
index 0000000000000..d983082083ecb
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/fp-fcanonicalize.ll
@@ -0,0 +1,66 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; FIXME: @llvm.canonicalize doesn't support soft-float abi yet.
+; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-FP16-RV64
+; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-FP16-RV32
+
+declare half @llvm.fcanonicalize.f16(half)
+declare float @llvm.fcanonicalize.f32(float)
+declare double @llvm.fcanonicalize.f64(double)
+
+define half @fcanonicalize_f16(half %x) {
+; CHECK-LABEL: fcanonicalize_f16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmin.h fa0, fa0, fa0
+; CHECK-NEXT:    ret
+  %z = call half @llvm.canonicalize.f16(half %x)
+  ret half %z
+}
+
+define half @fcanonicalize_f16_nnan(half %x) {
+; CHECK-LABEL: fcanonicalize_f16_nnan:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmin.h fa0, fa0, fa0
+; CHECK-NEXT:    ret
+  %z = call nnan half @llvm.canonicalize.f16(half %x)
+  ret half %z
+}
+
+define float @fcanonicalize_f32(float %x) {
+; CHECK-LABEL: fcanonicalize_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmin.s fa0, fa0, fa0
+; CHECK-NEXT:    ret
+  %z = call float @llvm.canonicalize.f32(float %x)
+  ret float %z
+}
+
+define float @fcanonicalize_f32_nnan(float %x) {
+; CHECK-LABEL: fcanonicalize_f32_nnan:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmin.s fa0, fa0, fa0
+; CHECK-NEXT:    ret
+  %z = call nnan float @llvm.canonicalize.f32(float %x)
+  ret float %z
+}
+
+define double @fcanonicalize_f64(double %x) {
+; CHECK-LABEL: fcanonicalize_f64:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmin.d fa0, fa0, fa0
+; CHECK-NEXT:    ret
+  %z = call double @llvm.canonicalize.f64(double %x)
+  ret double %z
+}
+
+define double @fcanonicalize_f64_nnan(double %x) {
+; CHECK-LABEL: fcanonicalize_f64_nnan:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fmin.d fa0, fa0, fa0
+; CHECK-NEXT:    ret
+  %z = call nnan double @llvm.canonicalize.f64(double %x)
+  ret double %z
+}
+
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK-FP16-RV32: {{.*}}
+; CHECK-FP16-RV64: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index da7546e12e58b..5f9b647112a50 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -587,8 +587,8 @@
 # DEBUG-NEXT: .. the first uncovered type index: 2, OK
 # DEBUG-NEXT: .. the first uncovered imm index: 0, OK
 # DEBUG-NEXT: G_FCANONICALIZE (opcode {{[0-9]+}}): 1 type index, 0 imm indices
-# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
-# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. the first uncovered type index: 1, OK
+# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
 # DEBUG-NEXT: G_FMINNUM (opcode {{[0-9]+}}): 1 type index
 # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
 # DEBUG-NEXT: .. the first uncovered type index: 1, OK

@circYuan circYuan force-pushed the gisel-fcanonicalize branch from 42e9921 to 06ecbca Compare November 3, 2025 13:24
@topperc topperc self-requested a review November 3, 2025 19:37
Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

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

LGTM

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.

3 participants