[llvm] 850ec7b - Attributor: Try to propagate concrete denormal-fp-math{-f32}
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 31 05:26:39 PDT 2023
Author: Matt Arsenault
Date: 2023-08-31T08:26:32-04:00
New Revision: 850ec7bbb18f36535d60b5201b0d7f368408ec23
URL: https://github.com/llvm/llvm-project/commit/850ec7bbb18f36535d60b5201b0d7f368408ec23
DIFF: https://github.com/llvm/llvm-project/commit/850ec7bbb18f36535d60b5201b0d7f368408ec23.diff
LOG: Attributor: Try to propagate concrete denormal-fp-math{-f32}
Allow specialization of functions with "dynamic" denormal modes to a
known IEEE or DAZ mode based on callers. This should make it possible
to implement a is-denormal-flushing-enabled test using
llvm.canonicalize and have it be free after LTO.
https://reviews.llvm.org/D156129
Added:
Modified:
llvm/include/llvm/ADT/FloatingPointMode.h
llvm/include/llvm/Transforms/IPO/Attributor.h
llvm/lib/Transforms/IPO/Attributor.cpp
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/test/Transforms/Attributor/denormal-fp-math.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/FloatingPointMode.h b/llvm/include/llvm/ADT/FloatingPointMode.h
index 61e57094fdbb98..ea934a5a05e835 100644
--- a/llvm/include/llvm/ADT/FloatingPointMode.h
+++ b/llvm/include/llvm/ADT/FloatingPointMode.h
@@ -96,9 +96,11 @@ struct DenormalMode {
DenormalModeKind Input = DenormalModeKind::Invalid;
constexpr DenormalMode() = default;
+ constexpr DenormalMode(const DenormalMode &) = default;
constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) :
Output(Out), Input(In) {}
+ DenormalMode &operator=(const DenormalMode &) = default;
static constexpr DenormalMode getInvalid() {
return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid);
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 05dcd83d90c6a5..1a2dcf6ab18612 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1918,6 +1918,7 @@ struct Attributor {
/// Remove all \p AttrKinds attached to \p IRP.
ChangeStatus removeAttrs(const IRPosition &IRP,
const ArrayRef<Attribute::AttrKind> &AttrKinds);
+ ChangeStatus removeAttrs(const IRPosition &IRP, ArrayRef<StringRef> Attrs);
/// Attach \p DeducedAttrs to \p IRP, if \p ForceReplace is set we do this
/// even if the same attribute kind was already present.
@@ -5101,6 +5102,98 @@ template <typename MemberTy> struct PotentialValuesState : AbstractState {
bool UndefIsContained;
};
+struct DenormalFPMathState : public AbstractState {
+ struct DenormalState {
+ DenormalMode Mode = DenormalMode::getInvalid();
+ DenormalMode ModeF32 = DenormalMode::getInvalid();
+
+ bool operator==(const DenormalState Other) const {
+ return Mode == Other.Mode && ModeF32 == Other.ModeF32;
+ }
+
+ bool operator!=(const DenormalState Other) const {
+ return Mode != Other.Mode || ModeF32 != Other.ModeF32;
+ }
+
+ bool isValid() const {
+ return Mode.isValid() && ModeF32.isValid();
+ }
+
+ static DenormalMode::DenormalModeKind
+ unionDenormalKind(DenormalMode::DenormalModeKind Callee,
+ DenormalMode::DenormalModeKind Caller) {
+ if (Caller == Callee)
+ return Caller;
+ if (Callee == DenormalMode::Dynamic)
+ return Caller;
+ if (Caller == DenormalMode::Dynamic)
+ return Callee;
+ return DenormalMode::Invalid;
+ }
+
+ static DenormalMode unionAssumed(DenormalMode Callee, DenormalMode Caller) {
+ return DenormalMode{unionDenormalKind(Callee.Output, Caller.Output),
+ unionDenormalKind(Callee.Input, Caller.Input)};
+ }
+
+ DenormalState unionWith(DenormalState Caller) const {
+ DenormalState Callee(*this);
+ Callee.Mode = unionAssumed(Callee.Mode, Caller.Mode);
+ Callee.ModeF32 = unionAssumed(Callee.ModeF32, Caller.ModeF32);
+ return Callee;
+ }
+ };
+
+ DenormalState Known;
+
+ /// Explicitly track whether we've hit a fixed point.
+ bool IsAtFixedpoint = false;
+
+ DenormalFPMathState() = default;
+
+ DenormalState getKnown() const { return Known; }
+
+ // There's only really known or unknown, there's no speculatively assumable
+ // state.
+ DenormalState getAssumed() const { return Known; }
+
+ bool isValidState() const override {
+ return Known.isValid();
+ }
+
+ /// Return true if there are no dynamic components to the denormal mode worth
+ /// specializing.
+ bool isModeFixed() const {
+ return Known.Mode.Input != DenormalMode::Dynamic &&
+ Known.Mode.Output != DenormalMode::Dynamic &&
+ Known.ModeF32.Input != DenormalMode::Dynamic &&
+ Known.ModeF32.Output != DenormalMode::Dynamic;
+ }
+
+ bool isAtFixpoint() const override {
+ return IsAtFixedpoint;
+ }
+
+ ChangeStatus indicateFixpoint() {
+ bool Changed = !IsAtFixedpoint;
+ IsAtFixedpoint = true;
+ return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
+ }
+
+ ChangeStatus indicateOptimisticFixpoint() override {
+ return indicateFixpoint();
+ }
+
+ ChangeStatus indicatePessimisticFixpoint() override {
+ return indicateFixpoint();
+ }
+
+ DenormalFPMathState operator^=(const DenormalFPMathState &Caller) {
+ Known = Known.unionWith(Caller.getKnown());
+ return *this;
+ }
+};
+
using PotentialConstantIntValuesState = PotentialValuesState<APInt>;
using PotentialLLVMValuesState =
PotentialValuesState<std::pair<AA::ValueAndContext, AA::ValueScope>>;
@@ -6029,6 +6122,8 @@ struct AAPointerInfo : public AbstractAttribute {
static const char ID;
};
+raw_ostream &operator<<(raw_ostream &, const AAPointerInfo::Access &);
+
/// An abstract attribute for getting assumption information.
struct AAAssumptionInfo
: public StateWrapper<SetState<StringRef>, AbstractAttribute,
@@ -6221,6 +6316,36 @@ struct AAIndirectCallInfo
/// This function should return true if the type of the \p AA is
/// AAIndirectCallInfo
+ /// This function should return true if the type of the \p AA is
+ /// AADenormalFPMath.
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+};
+
+/// An abstract Attribute for specializing "dynamic" components of
+/// "denormal-fp-math" and "denormal-fp-math-f32" to a known denormal mode.
+struct AADenormalFPMath
+ : public StateWrapper<DenormalFPMathState, AbstractAttribute> {
+ using Base = StateWrapper<DenormalFPMathState, AbstractAttribute>;
+
+ AADenormalFPMath(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
+
+ /// Create an abstract attribute view for the position \p IRP.
+ static AADenormalFPMath &createForPosition(const IRPosition &IRP,
+ Attributor &A);
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AADenormalFPMath"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AADenormalFPMath.
static bool classof(const AbstractAttribute *AA) {
return (AA->getIdAddr() == &ID);
}
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 5c05080c3a67b2..9cf381cf8b31b1 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -1229,6 +1229,19 @@ Attributor::removeAttrs(const IRPosition &IRP,
return updateAttrMap<Attribute::AttrKind>(IRP, AttrKinds, RemoveAttrCB);
}
+ChangeStatus Attributor::removeAttrs(const IRPosition &IRP,
+ ArrayRef<StringRef> Attrs) {
+ auto RemoveAttrCB = [&](StringRef Attr, AttributeSet AttrSet,
+ AttributeMask &AM, AttrBuilder &) -> bool {
+ if (!AttrSet.hasAttribute(Attr))
+ return false;
+ AM.addAttribute(Attr);
+ return true;
+ };
+
+ return updateAttrMap<StringRef>(IRP, Attrs, RemoveAttrCB);
+}
+
ChangeStatus Attributor::manifestAttrs(const IRPosition &IRP,
const ArrayRef<Attribute> &Attrs,
bool ForceReplace) {
@@ -3389,6 +3402,14 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
// Every function can track active assumptions.
getOrCreateAAFor<AAAssumptionInfo>(FPos);
+ // If we're not using a dynamic mode for float, there's nothing worthwhile
+ // to infer. This misses the edge case denormal-fp-math="dynamic" and
+ // denormal-fp-math-f32=something, but that likely has no real world use.
+ DenormalMode Mode = F.getDenormalMode(APFloat::IEEEsingle());
+ if (Mode.Input == DenormalMode::Dynamic ||
+ Mode.Output == DenormalMode::Dynamic)
+ getOrCreateAAFor<AADenormalFPMath>(FPos);
+
// Return attributes are only appropriate if the return type is non void.
Type *ReturnType = F.getReturnType();
if (!ReturnType->isVoidTy()) {
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index d91b4f158c8299..83892642db5e2b 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -194,6 +194,7 @@ PIPE_OPERATOR(AAUnderlyingObjects)
PIPE_OPERATOR(AAAddressSpace)
PIPE_OPERATOR(AAIndirectCallInfo)
PIPE_OPERATOR(AAGlobalValueInfo)
+PIPE_OPERATOR(AADenormalFPMath)
#undef PIPE_OPERATOR
@@ -8951,6 +8952,108 @@ struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
};
} // namespace
+/// ------------------ denormal-fp-math Attribute -------------------------
+
+namespace {
+struct AADenormalFPMathImpl : public AADenormalFPMath {
+ AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
+ : AADenormalFPMath(IRP, A) {}
+
+ const std::string getAsStr(Attributor *A) const override {
+ std::string Str("AADenormalFPMath[");
+ raw_string_ostream OS(Str);
+
+ DenormalState Known = getKnown();
+ if (Known.Mode.isValid())
+ OS << "denormal-fp-math=" << Known.Mode;
+ else
+ OS << "invalid";
+
+ if (Known.ModeF32.isValid())
+ OS << " denormal-fp-math-f32=" << Known.ModeF32;
+ OS << ']';
+ return OS.str();
+ }
+};
+
+struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
+ AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
+ : AADenormalFPMathImpl(IRP, A) {}
+
+ void initialize(Attributor &A) override {
+ const Function *F = getAnchorScope();
+ DenormalMode Mode = F->getDenormalModeRaw();
+ DenormalMode ModeF32 = F->getDenormalModeF32Raw();
+
+ // TODO: Handling this here prevents handling the case where a callee has a
+ // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
+ // a function with a fully fixed mode.
+ if (ModeF32 == DenormalMode::getInvalid())
+ ModeF32 = Mode;
+ Known = DenormalState{Mode, ModeF32};
+ if (isModeFixed())
+ indicateFixpoint();
+ }
+
+ ChangeStatus updateImpl(Attributor &A) override {
+ ChangeStatus Change = ChangeStatus::UNCHANGED;
+
+ auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
+ Function *Caller = CS.getInstruction()->getFunction();
+ LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
+ << "->" << getAssociatedFunction()->getName() << '\n');
+
+ const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
+ *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
+ if (!CallerInfo)
+ return false;
+
+ Change = Change | clampStateAndIndicateChange(this->getState(),
+ CallerInfo->getState());
+ return true;
+ };
+
+ bool AllCallSitesKnown = true;
+ if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
+ return indicatePessimisticFixpoint();
+
+ if (Change == ChangeStatus::CHANGED && isModeFixed())
+ indicateFixpoint();
+ return Change;
+ }
+
+ ChangeStatus manifest(Attributor &A) override {
+ LLVMContext &Ctx = getAssociatedFunction()->getContext();
+
+ SmallVector<Attribute, 2> AttrToAdd;
+ SmallVector<StringRef, 2> AttrToRemove;
+ if (Known.Mode == DenormalMode::getDefault()) {
+ AttrToRemove.push_back("denormal-fp-math");
+ } else {
+ AttrToAdd.push_back(
+ Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str()));
+ }
+
+ if (Known.ModeF32 != Known.Mode) {
+ AttrToAdd.push_back(
+ Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str()));
+ } else {
+ AttrToRemove.push_back("denormal-fp-math-f32");
+ }
+
+ auto &IRP = getIRPosition();
+
+ // TODO: There should be a combined add and remove API.
+ return A.removeAttrs(IRP, AttrToRemove) |
+ A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
+ }
+
+ void trackStatistics() const override {
+ STATS_DECLTRACK_FN_ATTR(denormal_fp_math)
+ }
+};
+} // namespace
+
/// ------------------ Value Constant Range Attribute -------------------------
namespace {
@@ -12705,6 +12808,7 @@ const char AAUnderlyingObjects::ID = 0;
const char AAAddressSpace::ID = 0;
const char AAIndirectCallInfo::ID = 0;
const char AAGlobalValueInfo::ID = 0;
+const char AADenormalFPMath::ID = 0;
// Macro magic to create the static generator function for attributes that
// follow the naming scheme.
@@ -12851,6 +12955,7 @@ CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonConvergent)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIntraFnReachability)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInterFnReachability)
+CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADenormalFPMath)
CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
diff --git a/llvm/test/Transforms/Attributor/denormal-fp-math.ll b/llvm/test/Transforms/Attributor/denormal-fp-math.ll
index a0bf6995dc663f..558d2bb074ff2f 100644
--- a/llvm/test/Transforms/Attributor/denormal-fp-math.ll
+++ b/llvm/test/Transforms/Attributor/denormal-fp-math.ll
@@ -6,8 +6,7 @@ declare void @call_of_mystery()
; Should infer to ieee,ieee/default
define internal void @leaf_dynamic_dynamic_from_ieee_ieee() #0 {
-; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_ieee_ieee
-; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_ieee_ieee() {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -17,8 +16,7 @@ define internal void @leaf_dynamic_dynamic_from_ieee_ieee() #0 {
; Should infer to ieee,ieee/default
define internal void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() #0 {
-; CHECK-LABEL: define internal void @leaf_recursive_dynamic_dynamic_from_ieee_ieee
-; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-LABEL: define internal void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: call void @leaf_recursive_dynamic_dynamic_from_ieee_ieee()
; CHECK-NEXT: ret void
@@ -30,8 +28,7 @@ define internal void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() #0 {
; Should strip denormal-fp-math for default ieee
define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() #1 {
-; CHECK-LABEL: define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee
-; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
+; CHECK-LABEL: define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -42,7 +39,7 @@ define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_d
; Should infer to preserve-sign,preserve-sign
define internal void @leaf_dynamic_dynamic_from_daz_daz() #0 {
; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_daz_daz
-; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -54,7 +51,7 @@ define internal void @leaf_dynamic_dynamic_from_daz_daz() #0 {
; could theoretically refine to denormal-fp-math-f32=preserve-sign,preserve-sign
define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz() #1 {
; CHECK-LABEL: define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz
-; CHECK-SAME: () #[[ATTR1]] {
+; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -65,7 +62,7 @@ define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_d
; Leave this alone, must stay dynamic,dynamic
define internal void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() #0 {
; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee
-; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -87,7 +84,7 @@ define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_d
; Leave as dynamic,dynamic
define void @externally_visible_dynamic_dynamic_from_ieee_ieee() #0 {
; CHECK-LABEL: define void @externally_visible_dynamic_dynamic_from_ieee_ieee
-; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-SAME: () #[[ATTR2]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -98,7 +95,7 @@ define void @externally_visible_dynamic_dynamic_from_ieee_ieee() #0 {
; Should infer to positive-zero,positive-zero
define internal void @leaf_dynamic_dynamic_from_dapz_dapz() #0 {
; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_dapz_dapz
-; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -108,8 +105,7 @@ define internal void @leaf_dynamic_dynamic_from_dapz_dapz() #0 {
; ieee,ieee entry point
define void @func_ieee_ieee() #2 {
-; CHECK-LABEL: define void @func_ieee_ieee
-; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
+; CHECK-LABEL: define void @func_ieee_ieee() {
; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_ieee_ieee()
; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee()
; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee()
@@ -158,7 +154,7 @@ define void @func_default_is_ieee_ieee() {
; preserve-sign,preserve-sign entry point
define void @func_daz_daz() #3 {
; CHECK-LABEL: define void @func_daz_daz
-; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR0]] {
; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_daz_daz()
; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee()
; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee()
@@ -177,7 +173,7 @@ define void @func_daz_daz() #3 {
; positive-zero,positive-zero entry point
define void @func_dapz_dapz() #4 {
; CHECK-LABEL: define void @func_dapz_dapz
-; CHECK-SAME: () #[[ATTR4:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR3]] {
; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_dapz_dapz()
; CHECK-NEXT: ret void
;
@@ -189,7 +185,7 @@ define void @func_dapz_dapz() #4 {
; realistic case and we don't bother trying to handle it.
define internal void @leaf_f64_dynamic_f64_dynamic__f32_daz_f32_daz_from__daz_daz() #5 {
; CHECK-LABEL: define internal void @leaf_f64_dynamic_f64_dynamic__f32_daz_f32_daz_from__daz_daz
-; CHECK-SAME: () #[[ATTR5:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR4:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -199,8 +195,7 @@ define internal void @leaf_f64_dynamic_f64_dynamic__f32_daz_f32_daz_from__daz_da
; -> ieee,ieee
define internal void @leaf_dynamic_ieee_from_ieee_ieee() #6 {
-; CHECK-LABEL: define internal void @leaf_dynamic_ieee_from_ieee_ieee
-; CHECK-SAME: () #[[ATTR6:[0-9]+]] {
+; CHECK-LABEL: define internal void @leaf_dynamic_ieee_from_ieee_ieee() {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -210,8 +205,7 @@ define internal void @leaf_dynamic_ieee_from_ieee_ieee() #6 {
; -> ieee,ieee
define internal void @leaf_ieee_dynamic_from_ieee_ieee() #7 {
-; CHECK-LABEL: define internal void @leaf_ieee_dynamic_from_ieee_ieee
-; CHECK-SAME: () #[[ATTR7:[0-9]+]] {
+; CHECK-LABEL: define internal void @leaf_ieee_dynamic_from_ieee_ieee() {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -222,7 +216,7 @@ define internal void @leaf_ieee_dynamic_from_ieee_ieee() #7 {
; Specialize the f64 mode to ieee,ieee but leave f32 as dynamic,dynamic
define internal void @leaf_dynamic_dynamic_from_f64_ieee_f32_dynamic() #0 {
; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_f64_ieee_f32_dynamic
-; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-SAME: () #[[ATTR1]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -243,7 +237,7 @@ define void @func_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic() #1 {
; -> preserve-sign,ieee.
define internal void @leaf_daz_dynamic_from_dynamic_ieee() #8 {
; CHECK-LABEL: define internal void @leaf_daz_dynamic_from_dynamic_ieee
-; CHECK-SAME: () #[[ATTR8:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR5:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -253,7 +247,7 @@ define internal void @leaf_daz_dynamic_from_dynamic_ieee() #8 {
define void @dynamic_ieee() #6 {
; CHECK-LABEL: define void @dynamic_ieee
-; CHECK-SAME: () #[[ATTR6]] {
+; CHECK-SAME: () #[[ATTR6:[0-9]+]] {
; CHECK-NEXT: call void @leaf_daz_dynamic_from_dynamic_ieee()
; CHECK-NEXT: ret void
;
@@ -284,7 +278,7 @@ define internal void @leaf_dynamic_from_dynamic() {
; Leave unchanged as preserve-sign,preserve-sign
define internal void @leaf_daz_daz_from_dynamic() #3 {
; CHECK-LABEL: define internal void @leaf_daz_daz_from_dynamic
-; CHECK-SAME: () #[[ATTR3]] {
+; CHECK-SAME: () #[[ATTR0]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -294,7 +288,7 @@ define internal void @leaf_daz_daz_from_dynamic() #3 {
define void @dynamic_dynamic() #0 {
; CHECK-LABEL: define void @dynamic_dynamic
-; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-SAME: () #[[ATTR2]] {
; CHECK-NEXT: call void @leaf_ieee_ieee_from_dynamic()
; CHECK-NEXT: call void @leaf_daz_daz_from_dynamic()
; CHECK-NEXT: call void @leaf_dynamic_from_dynamic()
@@ -308,7 +302,7 @@ define void @dynamic_dynamic() #0 {
define internal void @leaf_ieee_f64_daz_f32() #9 {
; CHECK-LABEL: define internal void @leaf_ieee_f64_daz_f32
-; CHECK-SAME: () #[[ATTR9:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR7:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -318,7 +312,7 @@ define internal void @leaf_ieee_f64_daz_f32() #9 {
define internal void @leaf_ieee_f64_daz_f32_from_ieee_f64_dynamic_f32() #10 {
; CHECK-LABEL: define internal void @leaf_ieee_f64_daz_f32_from_ieee_f64_dynamic_f32
-; CHECK-SAME: () #[[ATTR10:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR8:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -341,7 +335,7 @@ define void @ieee_f64_dynamic_f32() #1 {
; => "preserve-sign,positive-zero" + "denormal-fp-math-f32"="ieee,positive-zero"
define internal void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz() #11 {
; CHECK-LABEL: define internal void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz
-; CHECK-SAME: () #[[ATTR11:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR9:[0-9]+]] {
; CHECK-NEXT: call void @call_of_mystery()
; CHECK-NEXT: ret void
;
@@ -351,7 +345,7 @@ define internal void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz() #1
define void @daz_dapz_ieee_dapz() #12 {
; CHECK-LABEL: define void @daz_dapz_ieee_dapz
-; CHECK-SAME: () #[[ATTR12:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR9]] {
; CHECK-NEXT: call void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz()
; CHECK-NEXT: ret void
;
@@ -373,17 +367,14 @@ attributes #10 = { "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp
attributes #11 = { "denormal-fp-math"="preserve-sign,dynamic" "denormal-fp-math-f32"="dynamic,positive-zero" }
attributes #12 = { "denormal-fp-math"="preserve-sign,positive-zero" "denormal-fp-math-f32"="ieee,positive-zero" }
;.
-; CHECK: attributes #[[ATTR0]] = { "denormal-fp-math"="dynamic,dynamic" }
+; CHECK: attributes #[[ATTR0]] = { "denormal-fp-math"="preserve-sign,preserve-sign" }
; CHECK: attributes #[[ATTR1]] = { "denormal-fp-math-f32"="dynamic,dynamic" }
-; CHECK: attributes #[[ATTR2]] = { "denormal-fp-math"="ieee,ieee" }
-; CHECK: attributes #[[ATTR3]] = { "denormal-fp-math"="preserve-sign,preserve-sign" }
-; CHECK: attributes #[[ATTR4]] = { "denormal-fp-math"="positive-zero,positive-zero" }
-; CHECK: attributes #[[ATTR5]] = { "denormal-fp-math"="dynamic,dynamic" "denormal-fp-math-f32"="preserve-sign,preserve-sign" }
+; CHECK: attributes #[[ATTR2]] = { "denormal-fp-math"="dynamic,dynamic" }
+; CHECK: attributes #[[ATTR3]] = { "denormal-fp-math"="positive-zero,positive-zero" }
+; CHECK: attributes #[[ATTR4]] = { "denormal-fp-math"="dynamic,dynamic" "denormal-fp-math-f32"="preserve-sign,preserve-sign" }
+; CHECK: attributes #[[ATTR5]] = { "denormal-fp-math"="preserve-sign,ieee" }
; CHECK: attributes #[[ATTR6]] = { "denormal-fp-math"="dynamic,ieee" }
-; CHECK: attributes #[[ATTR7]] = { "denormal-fp-math"="ieee,dynamic" }
-; CHECK: attributes #[[ATTR8]] = { "denormal-fp-math"="preserve-sign,dynamic" }
-; CHECK: attributes #[[ATTR9]] = { "denormal-fp-math-f32"="preserve-sign,preserve-sign" }
-; CHECK: attributes #[[ATTR10]] = { "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp-math-f32"="ieee,ieee" }
-; CHECK: attributes #[[ATTR11]] = { "denormal-fp-math"="preserve-sign,dynamic" "denormal-fp-math-f32"="dynamic,positive-zero" }
-; CHECK: attributes #[[ATTR12]] = { "denormal-fp-math"="preserve-sign,positive-zero" "denormal-fp-math-f32"="ieee,positive-zero" }
+; CHECK: attributes #[[ATTR7]] = { "denormal-fp-math-f32"="preserve-sign,preserve-sign" }
+; CHECK: attributes #[[ATTR8]] = { "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp-math-f32"="ieee,ieee" }
+; CHECK: attributes #[[ATTR9]] = { "denormal-fp-math"="preserve-sign,positive-zero" "denormal-fp-math-f32"="ieee,positive-zero" }
;.
More information about the llvm-commits
mailing list