[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