[llvm] [SPIRV] Lower G_FMINIMUMNUM/G_FMAXIMUMNUM to OpenCL extended inst fmin/fmax (PR #153550)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 14 00:38:18 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-spir-v
Author: Wenju He (wenju-he)
<details>
<summary>Changes</summary>
This fixes __builtin_elementwise_minimumnum/maximumnum build error in libclc when using SPIRV backend.
---
Full diff: https://github.com/llvm/llvm-project/pull/153550.diff
3 Files Affected:
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2)
- (modified) llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp (+2)
- (modified) llvm/test/CodeGen/SPIRV/instructions/intrinsics.ll (+63-8)
``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 98c7709acf938..b155c03ca5b95 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -737,9 +737,11 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
case TargetOpcode::G_FMINNUM:
case TargetOpcode::G_FMINIMUM:
+ case TargetOpcode::G_FMINIMUMNUM:
return selectExtInst(ResVReg, ResType, I, CL::fmin, GL::NMin);
case TargetOpcode::G_FMAXNUM:
case TargetOpcode::G_FMAXIMUM:
+ case TargetOpcode::G_FMAXIMUMNUM:
return selectExtInst(ResVReg, ResType, I, CL::fmax, GL::NMax);
case TargetOpcode::G_FCOPYSIGN:
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index 170bddd507e3b..e6e333fa4e8bc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -319,6 +319,8 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
G_INTRINSIC_TRUNC,
G_FMINIMUM,
G_FMAXIMUM,
+ G_FMINIMUMNUM,
+ G_FMAXIMUMNUM,
G_INTRINSIC_ROUNDEVEN})
.legalFor(allFloatScalarsAndVectors);
diff --git a/llvm/test/CodeGen/SPIRV/instructions/intrinsics.ll b/llvm/test/CodeGen/SPIRV/instructions/intrinsics.ll
index e859dee51a6c3..d721d3c13cd34 100644
--- a/llvm/test/CodeGen/SPIRV/instructions/intrinsics.ll
+++ b/llvm/test/CodeGen/SPIRV/instructions/intrinsics.ll
@@ -16,6 +16,8 @@ declare float @llvm.log10.f32(float)
declare float @llvm.log2.f32(float)
declare float @llvm.minnum.f32(float, float)
declare float @llvm.maxnum.f32(float, float)
+declare float @llvm.minimumnum.f32(float, float)
+declare float @llvm.maximumnum.f32(float, float)
declare <2 x half> @llvm.fabs.v2f16(<2 x half>)
declare <2 x half> @llvm.rint.v2f16(<2 x half>)
declare <2 x half> @llvm.nearbyint.v2f16(<2 x half>)
@@ -30,6 +32,8 @@ declare <2 x half> @llvm.exp2.v2f16(<2 x half>)
declare <2 x half> @llvm.log.v2f16(<2 x half>)
declare <2 x half> @llvm.log10.v2f16(<2 x half>)
declare <2 x half> @llvm.log2.v2f16(<2 x half>)
+declare <2 x half> @llvm.minimumnum.v2f16(<2 x half>, <2 x half>)
+declare <2 x half> @llvm.maximumnum.v2f16(<2 x half>, <2 x half>)
; CHECK-DAG: OpName %[[#SCALAR_FABS:]] "scalar_fabs"
; CHECK-DAG: OpName %[[#SCALAR_RINT:]] "scalar_rint"
@@ -47,6 +51,8 @@ declare <2 x half> @llvm.log2.v2f16(<2 x half>)
; CHECK-DAG: OpName %[[#SCALAR_LOG2:]] "scalar_log2"
; CHECK-DAG: OpName %[[#SCALAR_MINNUM:]] "scalar_minnum"
; CHECK-DAG: OpName %[[#SCALAR_MAXNUM:]] "scalar_maxnum"
+; CHECK-DAG: OpName %[[#SCALAR_MINIMUMNUM:]] "scalar_minimumnum"
+; CHECK-DAG: OpName %[[#SCALAR_MAXIMUMNUM:]] "scalar_maximumnum"
; CHECK-DAG: OpName %[[#VECTOR_FABS:]] "vector_fabs"
; CHECK-DAG: OpName %[[#VECTOR_RINT:]] "vector_rint"
; CHECK-DAG: OpName %[[#VECTOR_NEARBYINT:]] "vector_nearbyint"
@@ -61,6 +67,8 @@ declare <2 x half> @llvm.log2.v2f16(<2 x half>)
; CHECK-DAG: OpName %[[#VECTOR_LOG:]] "vector_log"
; CHECK-DAG: OpName %[[#VECTOR_LOG10:]] "vector_log10"
; CHECK-DAG: OpName %[[#VECTOR_LOG2:]] "vector_log2"
+; CHECK-DAG: OpName %[[#VECTOR_MINIMUMNUM:]] "vector_minimumnum"
+; CHECK-DAG: OpName %[[#VECTOR_MAXIMUMNUM:]] "vector_maximumnum"
; CHECK-DAG: %[[#CLEXT:]] = OpExtInstImport "OpenCL.std"
@@ -218,6 +226,53 @@ define float @scalar_log2(float %a) {
ret float %r
}
+; CHECK: %[[#SCALAR_MINNUM]] = OpFunction
+; CHECK-NEXT: %[[#A:]] = OpFunctionParameter
+; CHECK-NEXT: %[[#B:]] = OpFunctionParameter
+; CHECK: OpLabel
+; CHECK: %[[#R:]] = OpExtInst %[[#]] %[[#CLEXT]] fmin %[[#A]] %[[#B]]
+; CHECK: OpReturnValue %[[#R]]
+; CHECK-NEXT: OpFunctionEnd
+define float @scalar_minnum(float %A, float %B) {
+ %r = call float @llvm.minnum.f32(float %A, float %B)
+ ret float %r
+}
+
+; CHECK: %[[#SCALAR_MAXNUM]] = OpFunction
+; CHECK-NEXT: %[[#A:]] = OpFunctionParameter
+; CHECK-NEXT: %[[#B:]] = OpFunctionParameter
+; CHECK: OpLabel
+; CHECK: %[[#R:]] = OpExtInst %[[#]] %[[#CLEXT]] fmax %[[#A]] %[[#B]]
+; CHECK: OpReturnValue %[[#R]]
+; CHECK-NEXT: OpFunctionEnd
+define float @scalar_maxnum(float %A, float %B) {
+ %r = call float @llvm.maxnum.f32(float %A, float %B)
+ ret float %r
+}
+
+; CHECK: %[[#SCALAR_MINIMUMNUM]] = OpFunction
+; CHECK-NEXT: %[[#A:]] = OpFunctionParameter
+; CHECK-NEXT: %[[#B:]] = OpFunctionParameter
+; CHECK: OpLabel
+; CHECK: %[[#R:]] = OpExtInst %[[#]] %[[#CLEXT]] fmin %[[#A]] %[[#B]]
+; CHECK: OpReturnValue %[[#R]]
+; CHECK-NEXT: OpFunctionEnd
+define float @scalar_minimumnum(float %A, float %B) {
+ %r = call float @llvm.minimumnum.f32(float %A, float %B)
+ ret float %r
+}
+
+; CHECK: %[[#SCALAR_MAXIMUMNUM]] = OpFunction
+; CHECK-NEXT: %[[#A:]] = OpFunctionParameter
+; CHECK-NEXT: %[[#B:]] = OpFunctionParameter
+; CHECK: OpLabel
+; CHECK: %[[#R:]] = OpExtInst %[[#]] %[[#CLEXT]] fmax %[[#A]] %[[#B]]
+; CHECK: OpReturnValue %[[#R]]
+; CHECK-NEXT: OpFunctionEnd
+define float @scalar_maximumnum(float %A, float %B) {
+ %r = call float @llvm.maximumnum.f32(float %A, float %B)
+ ret float %r
+}
; CHECK: %[[#VECTOR_FABS]] = OpFunction
; CHECK-NEXT: %[[#A:]] = OpFunctionParameter
; CHECK: OpLabel
@@ -372,26 +427,26 @@ define <2 x half> @vector_log2(<2 x half> %a) {
ret <2 x half> %r
}
-; CHECK: %[[#SCALAR_MINNUM]] = OpFunction
+; CHECK: %[[#VECTOR_MINIMUMNUM]] = OpFunction
; CHECK-NEXT: %[[#A:]] = OpFunctionParameter
; CHECK-NEXT: %[[#B:]] = OpFunctionParameter
; CHECK: OpLabel
; CHECK: %[[#R:]] = OpExtInst %[[#]] %[[#CLEXT]] fmin %[[#A]] %[[#B]]
; CHECK: OpReturnValue %[[#R]]
; CHECK-NEXT: OpFunctionEnd
-define float @scalar_minnum(float %A, float %B) {
- %r = call float @llvm.minnum.f32(float %A, float %B)
- ret float %r
+define <2 x half> @vector_minimumnum(<2 x half> %A, <2 x half> %B) {
+ %r = call <2 x half> @llvm.minimumnum.v2f16(<2 x half> %A, <2 x half> %B)
+ ret <2 x half> %r
}
-; CHECK: %[[#SCALAR_MAXNUM]] = OpFunction
+; CHECK: %[[#VECTOR_MAXIMUMNUM]] = OpFunction
; CHECK-NEXT: %[[#A:]] = OpFunctionParameter
; CHECK-NEXT: %[[#B:]] = OpFunctionParameter
; CHECK: OpLabel
; CHECK: %[[#R:]] = OpExtInst %[[#]] %[[#CLEXT]] fmax %[[#A]] %[[#B]]
; CHECK: OpReturnValue %[[#R]]
; CHECK-NEXT: OpFunctionEnd
-define float @scalar_maxnum(float %A, float %B) {
- %r = call float @llvm.maxnum.f32(float %A, float %B)
- ret float %r
+define <2 x half> @vector_maximumnum(<2 x half> %A, <2 x half> %B) {
+ %r = call <2 x half> @llvm.maximumnum.v2f16(<2 x half> %A, <2 x half> %B)
+ ret <2 x half> %r
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/153550
More information about the llvm-commits
mailing list