[llvm] [KnownFPClass] Add KnownFPClass deductions for `pow` (PR #215592)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 21 08:47:01 PDT 2026
================
@@ -0,0 +1,65 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+declare float @llvm.fabs.f32(float)
+declare float @llvm.pow.f32(float, float)
+declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
+
+define i1 @pow_negzero_negative_is_negzero(float %x) strictfp {
+; CHECK-LABEL: define i1 @pow_negzero_negative_is_negzero(
+; CHECK-SAME: float [[X:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: ret i1 false
+;
+ %pos = call float @llvm.fabs.f32(float %x)
+ %neg = fneg float %pos
+ %pow = call float @llvm.pow.f32(float f0x80000000, float %neg)
+ %class = call i1 @llvm.is.fpclass.f32(float %pow, i32 32) strictfp
+ ret i1 %class
+}
+
+define i1 @pow_negzero_positive_is_neginf(float %x) strictfp {
+; CHECK-LABEL: define i1 @pow_negzero_positive_is_neginf(
+; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: ret i1 false
+;
+ %pos = call float @llvm.fabs.f32(float %x)
+ %pow = call float @llvm.pow.f32(float f0x80000000, float %pos)
+ %class = call i1 @llvm.is.fpclass.f32(float %pow, i32 4) strictfp
+ ret i1 %class
+}
+
+define i1 @pow_neginf_positive_is_negzero(float %x) strictfp {
+; CHECK-LABEL: define i1 @pow_neginf_positive_is_negzero(
+; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: ret i1 false
+;
+ %pos = call float @llvm.fabs.f32(float %x)
+ %pow = call float @llvm.pow.f32(float f0xFF800000, float %pos)
+ %class = call i1 @llvm.is.fpclass.f32(float %pow, i32 32) strictfp
+ ret i1 %class
+}
+
+define i1 @pow_neginf_negative_is_neginf(float %x) strictfp {
+; CHECK-LABEL: define i1 @pow_neginf_negative_is_neginf(
+; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: ret i1 false
+;
+ %pos = call float @llvm.fabs.f32(float %x)
+ %neg = fneg float %pos
+ %pow = call float @llvm.pow.f32(float f0xFF800000, float %neg)
+ %class = call i1 @llvm.is.fpclass.f32(float %pow, i32 4) strictfp
+ ret i1 %class
+}
+
+; This fold is only possible in special cases, and not worth deducing.
+define i1 @pow_any_nonnormal_may_be_subnormal(float %x, float nofpclass(norm) %exp) strictfp {
+; CHECK-LABEL: define i1 @pow_any_nonnormal_may_be_subnormal(
+; CHECK-SAME: float [[X:%.*]], float nofpclass(norm) [[EXP:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[POW:%.*]] = call float @llvm.pow.f32(float [[X]], float [[EXP]])
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[POW]], /* (sub) */ i32 144) #[[ATTR1]]
+; CHECK-NEXT: ret i1 [[CLASS]]
+;
+ %pow = call float @llvm.pow.f32(float %x, float %exp)
+ %class = call i1 @llvm.is.fpclass.f32(float %pow, i32 144) strictfp
+ ret i1 %class
+}
----------------
ZERICO2005 wrote:
Sure I can test those edge cases with regards to negative subnormals flushing to negative zero.
https://github.com/llvm/llvm-project/pull/215592
More information about the llvm-commits
mailing list