[llvm] [FMF] Set all bits if needed when setting individual flags. (PR #131321)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 14 04:56:33 PDT 2025
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/131321
>From 923ba07f4f6ab109ae41833ab04287744779a895 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Fri, 14 Mar 2025 11:45:24 +0000
Subject: [PATCH 1/2] [FMF] Set all bits if needed when setting individual
flags.
Currently fast() won't return true if all flags are set via setXXX,
which is surprising. Update setters to set all bits if needed to
make sure isFast() consistently returns the expected result.
---
llvm/include/llvm/IR/FMF.h | 17 +++++++++++++----
.../widen-call-with-intrinsic-or-libfunc.ll | 2 +-
.../Transforms/LoopVectorize/vplan-printing.ll | 2 +-
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/IR/FMF.h b/llvm/include/llvm/IR/FMF.h
index d204d0a0e9d9a..d6ecb8f983ae1 100644
--- a/llvm/include/llvm/IR/FMF.h
+++ b/llvm/include/llvm/IR/FMF.h
@@ -23,14 +23,16 @@ class FastMathFlags {
unsigned Flags = 0;
- FastMathFlags(unsigned F) {
+ FastMathFlags(unsigned F) : Flags(F) {
+ setAllBitsIfNeeded();
+ }
+
+ void setAllBitsIfNeeded() {
// If all 7 bits are set, turn this into -1. If the number of bits grows,
// this must be updated. This is intended to provide some forward binary
// compatibility insurance for the meaning of 'fast' in case bits are added.
- if (F == 0x7F) Flags = ~0U;
- else Flags = F;
+ if (Flags == 0x7F) Flags = ~0U;
}
-
public:
// This is how the bits are used in Value::SubclassOptionalData so they
// should fit there too.
@@ -75,24 +77,31 @@ class FastMathFlags {
/// Flag setters
void setAllowReassoc(bool B = true) {
Flags = (Flags & ~AllowReassoc) | B * AllowReassoc;
+ setAllBitsIfNeeded();
}
void setNoNaNs(bool B = true) {
Flags = (Flags & ~NoNaNs) | B * NoNaNs;
+ setAllBitsIfNeeded();
}
void setNoInfs(bool B = true) {
Flags = (Flags & ~NoInfs) | B * NoInfs;
+ setAllBitsIfNeeded();
}
void setNoSignedZeros(bool B = true) {
Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros;
+ setAllBitsIfNeeded();
}
void setAllowReciprocal(bool B = true) {
Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal;
+ setAllBitsIfNeeded();
}
void setAllowContract(bool B = true) {
Flags = (Flags & ~AllowContract) | B * AllowContract;
+ setAllBitsIfNeeded();
}
void setApproxFunc(bool B = true) {
Flags = (Flags & ~ApproxFunc) | B * ApproxFunc;
+ setAllBitsIfNeeded();
}
void setFast(bool B = true) { B ? set() : clear(); }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll b/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll
index a119707bed120..01642a991f8b9 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll
@@ -26,7 +26,7 @@ target triple = "arm64-apple-ios"
; CHECK-NEXT: vp<[[VEC_PTR:%.+]]> = vector-pointer ir<%gep.src>
; CHECK-NEXT: WIDEN ir<%l> = load vp<[[VEC_PTR]]>
; CHECK-NEXT: WIDEN-CAST ir<%conv> = fpext ir<%l> to double
-; CHECK-NEXT: WIDEN-CALL ir<%s> = call reassoc nnan ninf nsz arcp contract afn @llvm.sin.f64(ir<%conv>) (using library function: __simd_sin_v2f64)
+; CHECK-NEXT: WIDEN-CALL ir<%s> = call fast @llvm.sin.f64(ir<%conv>) (using library function: __simd_sin_v2f64)
; CHECK-NEXT: REPLICATE ir<%gep.dst> = getelementptr inbounds ir<%dst>, vp<[[STEPS]]>
; CHECK-NEXT: REPLICATE store ir<%s>, ir<%gep.dst>
; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
diff --git a/llvm/test/Transforms/LoopVectorize/vplan-printing.ll b/llvm/test/Transforms/LoopVectorize/vplan-printing.ll
index 00d8de67a3b40..cbde30a29b44f 100644
--- a/llvm/test/Transforms/LoopVectorize/vplan-printing.ll
+++ b/llvm/test/Transforms/LoopVectorize/vplan-printing.ll
@@ -800,7 +800,7 @@ define void @print_fast_math_flags(i64 %n, ptr noalias %y, ptr noalias %x, ptr %
; CHECK-NEXT: vp<[[VEC_PTR:%.+]]> = vector-pointer ir<%gep.y>
; CHECK-NEXT: WIDEN ir<%lv> = load vp<[[VEC_PTR]]>
; CHECK-NEXT: WIDEN ir<%add> = fadd nnan ir<%lv>, ir<1.000000e+00>
-; CHECK-NEXT: WIDEN ir<%mul> = fmul reassoc nnan ninf nsz arcp contract afn ir<%add>, ir<2.000000e+00>
+; CHECK-NEXT: WIDEN ir<%mul> = fmul fast ir<%add>, ir<2.000000e+00>
; CHECK-NEXT: WIDEN ir<%div> = fdiv reassoc nsz contract ir<%mul>, ir<2.000000e+00>
; CHECK-NEXT: CLONE ir<%gep.x> = getelementptr inbounds ir<%x>, vp<[[STEPS]]>
; CHECK-NEXT: vp<[[VEC_PTR:%.+]]> = vector-pointer ir<%gep.x>
>From 1e9f0c8b237b1742448d6742f5dd4517e8d727f9 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Fri, 14 Mar 2025 11:56:07 +0000
Subject: [PATCH 2/2] !fixup fix formatting, update remaining tests.
---
llvm/include/llvm/IR/FMF.h | 8 ++++----
.../AArch64/widen-call-with-intrinsic-or-libfunc.ll | 2 +-
llvm/test/Transforms/LoopVectorize/vplan-printing.ll | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/IR/FMF.h b/llvm/include/llvm/IR/FMF.h
index d6ecb8f983ae1..b7320ef17101c 100644
--- a/llvm/include/llvm/IR/FMF.h
+++ b/llvm/include/llvm/IR/FMF.h
@@ -23,16 +23,16 @@ class FastMathFlags {
unsigned Flags = 0;
- FastMathFlags(unsigned F) : Flags(F) {
- setAllBitsIfNeeded();
- }
+ FastMathFlags(unsigned F) : Flags(F) { setAllBitsIfNeeded(); }
void setAllBitsIfNeeded() {
// If all 7 bits are set, turn this into -1. If the number of bits grows,
// this must be updated. This is intended to provide some forward binary
// compatibility insurance for the meaning of 'fast' in case bits are added.
- if (Flags == 0x7F) Flags = ~0U;
+ if (Flags == 0x7F)
+ Flags = ~0U;
}
+
public:
// This is how the bits are used in Value::SubclassOptionalData so they
// should fit there too.
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll b/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll
index 01642a991f8b9..89bb495045e41 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll
@@ -72,7 +72,7 @@ target triple = "arm64-apple-ios"
; CHECK-NEXT: vp<[[VEC_PTR:%.+]]> = vector-pointer ir<%gep.src>
; CHECK-NEXT: WIDEN ir<%l> = load vp<[[VEC_PTR]]>
; CHECK-NEXT: WIDEN-CAST ir<%conv> = fpext ir<%l> to double
-; CHECK-NEXT: WIDEN-INTRINSIC ir<%s> = call reassoc nnan ninf nsz arcp contract afn llvm.sin(ir<%conv>)
+; CHECK-NEXT: WIDEN-INTRINSIC ir<%s> = call fast llvm.sin(ir<%conv>)
; CHECK-NEXT: REPLICATE ir<%gep.dst> = getelementptr inbounds ir<%dst>, vp<[[STEPS]]>
; CHECK-NEXT: REPLICATE store ir<%s>, ir<%gep.dst>
; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
diff --git a/llvm/test/Transforms/LoopVectorize/vplan-printing.ll b/llvm/test/Transforms/LoopVectorize/vplan-printing.ll
index cbde30a29b44f..207cb8b4a0d30 100644
--- a/llvm/test/Transforms/LoopVectorize/vplan-printing.ll
+++ b/llvm/test/Transforms/LoopVectorize/vplan-printing.ll
@@ -1224,8 +1224,8 @@ define void @print_select_with_fastmath_flags(ptr noalias %a, ptr noalias %b, pt
; CHECK-NEXT: vp<[[PTR2:%.+]]> = vector-pointer ir<[[GEP2]]>
; CHECK-NEXT: WIDEN ir<[[LD2:%.+]]> = load vp<[[PTR2]]>
; CHECK-NEXT: WIDEN ir<[[FCMP:%.+]]> = fcmp ogt ir<[[LD1]]>, ir<[[LD2]]>
-; CHECK-NEXT: WIDEN ir<[[FADD:%.+]]> = fadd reassoc nnan ninf nsz arcp contract afn ir<[[LD1]]>, ir<1.000000e+01>
-; CHECK-NEXT: WIDEN-SELECT ir<[[SELECT:%.+]]> = select reassoc nnan ninf nsz arcp contract afn ir<[[FCMP]]>, ir<[[FADD]]>, ir<[[LD2]]>
+; CHECK-NEXT: WIDEN ir<[[FADD:%.+]]> = fadd fast ir<[[LD1]]>, ir<1.000000e+01>
+; CHECK-NEXT: WIDEN-SELECT ir<[[SELECT:%.+]]> = select fast ir<[[FCMP]]>, ir<[[FADD]]>, ir<[[LD2]]>
; CHECK-NEXT: CLONE ir<[[GEP3:%.+]]> = getelementptr inbounds nuw ir<%a>, vp<[[ST]]>
; CHECK-NEXT: vp<[[PTR3:%.+]]> = vector-pointer ir<[[GEP3]]>
; CHECK-NEXT: WIDEN store vp<[[PTR3]]>, ir<[[SELECT]]>
More information about the llvm-commits
mailing list