[llvm] 94026ce - Attributor: Start inferring nofpclass

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 16 20:20:35 PDT 2023


Author: Matt Arsenault
Date: 2023-03-16T23:19:34-04:00
New Revision: 94026ce56df244ddad76fe5c28c41a3523f129b2

URL: https://github.com/llvm/llvm-project/commit/94026ce56df244ddad76fe5c28c41a3523f129b2
DIFF: https://github.com/llvm/llvm-project/commit/94026ce56df244ddad76fe5c28c41a3523f129b2.diff

LOG: Attributor: Start inferring nofpclass

Some of this is boilerplate which doesn't do anything yet.

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/IPO/Attributor.h
    llvm/lib/Transforms/IPO/Attributor.cpp
    llvm/lib/Transforms/IPO/AttributorAttributes.cpp
    llvm/test/Transforms/Attributor/nofpclass.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 26859ff77ce4d..e8159d2c25fe2 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -2567,7 +2567,10 @@ template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
           base_ty WorstState = 0>
 struct BitIntegerState
     : public IntegerStateBase<base_ty, BestState, WorstState> {
+  using super = IntegerStateBase<base_ty, BestState, WorstState>;
   using base_t = base_ty;
+  BitIntegerState() = default;
+  BitIntegerState(base_t Assumed) : super(Assumed) {}
 
   /// Return true if the bits set in \p BitsEncoding are "known bits".
   bool isKnown(base_t BitsEncoding) const {
@@ -4840,6 +4843,39 @@ struct AANoUndef
   static const char ID;
 };
 
+struct AANoFPClass
+    : public IRAttribute<
+          Attribute::NoFPClass,
+          StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
+                       AbstractAttribute>> {
+  using Base = StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
+                            AbstractAttribute>;
+
+  AANoFPClass(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
+
+  /// Return true if we assume that the underlying value is nofpclass.
+  FPClassTest getAssumedNoFPClass() const {
+    return static_cast<FPClassTest>(getAssumed());
+  }
+
+  /// Create an abstract attribute view for the position \p IRP.
+  static AANoFPClass &createForPosition(const IRPosition &IRP, Attributor &A);
+
+  /// See AbstractAttribute::getName()
+  const std::string getName() const override { return "AANoFPClass"; }
+
+  /// See AbstractAttribute::getIdAddr()
+  const char *getIdAddr() const override { return &ID; }
+
+  /// This function should return true if the type of the \p AA is AANoFPClass
+  static bool classof(const AbstractAttribute *AA) {
+    return (AA->getIdAddr() == &ID);
+  }
+
+  /// Unique ID (due to the unique address)
+  static const char ID;
+};
+
 struct AACallGraphNode;
 struct AACallEdges;
 

diff  --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 6cb74cd4aacd6..46b29009437c5 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -3240,6 +3240,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
       // Every function with pointer return type might be marked
       // dereferenceable.
       getOrCreateAAFor<AADereferenceable>(RetPos);
+    } else if (AttributeFuncs::isNoFPClassCompatibleType(ReturnType)) {
+      getOrCreateAAFor<AANoFPClass>(RetPos);
     }
   }
 
@@ -3284,6 +3286,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
 
       // Every argument with pointer type might be privatizable (or promotable)
       getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);
+    } else if (AttributeFuncs::isNoFPClassCompatibleType(Arg.getType())) {
+      getOrCreateAAFor<AANoFPClass>(ArgPos);
     }
   }
 
@@ -3312,11 +3316,13 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
       return true;
 
     if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
-
       IRPosition CBRetPos = IRPosition::callsite_returned(CB);
       bool UsedAssumedInformation = false;
       getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,
                            AA::Intraprocedural);
+
+      if (AttributeFuncs::isNoFPClassCompatibleType(Callee->getReturnType()))
+        getOrCreateAAFor<AANoFPClass>(CBInstPos);
     }
 
     for (int I = 0, E = CB.arg_size(); I < E; ++I) {
@@ -3336,8 +3342,14 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
       // Every call site argument might be marked "noundef".
       getOrCreateAAFor<AANoUndef>(CBArgPos);
 
-      if (!CB.getArgOperand(I)->getType()->isPointerTy())
+      Type *ArgTy = CB.getArgOperand(I)->getType();
+
+      if (!ArgTy->isPointerTy()) {
+        if (AttributeFuncs::isNoFPClassCompatibleType(ArgTy))
+          getOrCreateAAFor<AANoFPClass>(CBArgPos);
+
         continue;
+      }
 
       // Call site argument attribute "non-null".
       getOrCreateAAFor<AANonNull>(CBArgPos);

diff  --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 100f43fbb389d..e2abf9b95b2fe 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -177,6 +177,7 @@ PIPE_OPERATOR(AAUndefinedBehavior)
 PIPE_OPERATOR(AAPotentialConstantValues)
 PIPE_OPERATOR(AAPotentialValues)
 PIPE_OPERATOR(AANoUndef)
+PIPE_OPERATOR(AANoFPClass)
 PIPE_OPERATOR(AACallEdges)
 PIPE_OPERATOR(AAInterFnReachability)
 PIPE_OPERATOR(AAPointerInfo)
@@ -10205,6 +10206,103 @@ struct AANoUndefCallSiteReturned final
   void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
 };
 
+/// ------------------------ NoFPClass Attribute -------------------------------
+
+struct AANoFPClassImpl : AANoFPClass {
+  AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
+
+  void initialize(Attributor &A) override {
+    const IRPosition &IRP = getIRPosition();
+
+    Value &V = IRP.getAssociatedValue();
+    if (isa<UndefValue>(V)) {
+      indicateOptimisticFixpoint();
+      return;
+    }
+
+    SmallVector<Attribute> Attrs;
+    IRP.getAttrs({Attribute::NoFPClass}, Attrs, false, &A);
+    if (!Attrs.empty()) {
+      addKnownBits(Attrs[0].getNoFPClass());
+      return;
+    }
+
+    const DataLayout &DL = A.getDataLayout();
+    if (getPositionKind() != IRPosition::IRP_RETURNED) {
+      KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL);
+      addKnownBits(~KnownFPClass.KnownFPClasses);
+    }
+  }
+
+  const std::string getAsStr() const override {
+    std::string Result = "nofpclass";
+    raw_string_ostream OS(Result);
+    OS << getAssumedNoFPClass();
+    return Result;
+  }
+
+  void getDeducedAttributes(LLVMContext &Ctx,
+                            SmallVectorImpl<Attribute> &Attrs) const override {
+    Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
+  }
+};
+
+struct AANoFPClassFloating : public AANoFPClassImpl {
+  AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
+      : AANoFPClassImpl(IRP, A) {}
+
+  /// See AbstractAttribute::updateImpl(...).
+  ChangeStatus updateImpl(Attributor &A) override {
+    return indicatePessimisticFixpoint();
+  }
+
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override {
+    STATS_DECLTRACK_FNRET_ATTR(nofpclass)
+  }
+};
+
+struct AANoFPClassReturned final
+    : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl> {
+  AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
+      : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
+
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override {
+    STATS_DECLTRACK_FNRET_ATTR(nofpclass)
+  }
+};
+
+struct AANoFPClassArgument final
+    : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
+  AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
+      : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
+
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
+};
+
+struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
+  AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
+      : AANoFPClassFloating(IRP, A) {}
+
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override {
+    STATS_DECLTRACK_CSARG_ATTR(nofpclass)
+  }
+};
+
+struct AANoFPClassCallSiteReturned final
+    : AACallSiteReturnedFromReturned<AANoFPClass, AANoFPClassImpl> {
+  AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
+      : AACallSiteReturnedFromReturned<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
+
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override {
+    STATS_DECLTRACK_CSRET_ATTR(nofpclass)
+  }
+};
+
 struct AACallEdgesImpl : public AACallEdges {
   AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
 
@@ -11629,6 +11727,7 @@ const char AAValueConstantRange::ID = 0;
 const char AAPotentialConstantValues::ID = 0;
 const char AAPotentialValues::ID = 0;
 const char AANoUndef::ID = 0;
+const char AANoFPClass::ID = 0;
 const char AACallEdges::ID = 0;
 const char AAInterFnReachability::ID = 0;
 const char AAPointerInfo::ID = 0;
@@ -11749,6 +11848,7 @@ CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange)
 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialConstantValues)
 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues)
 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef)
+CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFPClass)
 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo)
 
 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)

diff  --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll
index a21f60a395c90..fa44f3c92e452 100644
--- a/llvm/test/Transforms/Attributor/nofpclass.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --version 2
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 2
 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
 
@@ -14,7 +14,7 @@ declare void @extern.use.f16(half)
 declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
 
 define float @returned_0() {
-; CHECK-LABEL: define noundef float @returned_0() {
+; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @returned_0() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -23,7 +23,7 @@ define float @returned_0() {
 }
 
 define float @returned_neg0() {
-; CHECK-LABEL: define noundef float @returned_neg0() {
+; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @returned_neg0() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret float -0.000000e+00
 ;
@@ -32,7 +32,7 @@ define float @returned_neg0() {
 }
 
 define float @returned_undef() {
-; CHECK-LABEL: define float @returned_undef() {
+; CHECK-LABEL: define nofpclass(all) float @returned_undef() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret float undef
 ;
@@ -41,7 +41,7 @@ define float @returned_undef() {
 }
 
 define float @returned_poison() {
-; CHECK-LABEL: define float @returned_poison() {
+; CHECK-LABEL: define nofpclass(all) float @returned_poison() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret float poison
 ;
@@ -50,7 +50,7 @@ define float @returned_poison() {
 }
 
 define double @returned_snan() {
-; CHECK-LABEL: define noundef double @returned_snan() {
+; CHECK-LABEL: define noundef nofpclass(qnan inf zero sub norm) double @returned_snan() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret double 0x7FF0000000000001
 ;
@@ -59,7 +59,7 @@ define double @returned_snan() {
 }
 
 define double @returned_qnan() {
-; CHECK-LABEL: define noundef double @returned_qnan() {
+; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) double @returned_qnan() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
@@ -68,7 +68,7 @@ define double @returned_qnan() {
 }
 
 define <2 x double> @returned_zero_vector() {
-; CHECK-LABEL: define noundef <2 x double> @returned_zero_vector() {
+; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) <2 x double> @returned_zero_vector() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret <2 x double> zeroinitializer
 ;
@@ -77,7 +77,7 @@ define <2 x double> @returned_zero_vector() {
 }
 
 define <2 x double> @returned_negzero_vector() {
-; CHECK-LABEL: define noundef <2 x double> @returned_negzero_vector() {
+; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) <2 x double> @returned_negzero_vector() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret <2 x double> <double -0.000000e+00, double -0.000000e+00>
 ;
@@ -96,8 +96,8 @@ define <2 x double> @returned_qnan_zero_vector() {
 
 ; Return a float trivially nofpclass(nan) (call return attribute)
 define float @return_nofpclass_nan_decl_return() {
-; CHECK-LABEL: define float @return_nofpclass_nan_decl_return() {
-; CHECK-NEXT:    [[RET:%.*]] = call float @ret_nofpclass_nan()
+; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_decl_return() {
+; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
 ; CHECK-NEXT:    ret float [[RET]]
 ;
   %ret = call float @ret_nofpclass_nan()
@@ -107,7 +107,7 @@ define float @return_nofpclass_nan_decl_return() {
 ; Return a float trivially nofpclass(nan) (argument attribute)
 define float @return_nofpclass_nan_arg(float returned nofpclass(nan) %p) {
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define float @return_nofpclass_nan_arg
+; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_arg
 ; CHECK-SAME: (float returned nofpclass(nan) [[P:%.*]]) #[[ATTR2:[0-9]+]] {
 ; CHECK-NEXT:    ret float [[P]]
 ;
@@ -115,7 +115,7 @@ define float @return_nofpclass_nan_arg(float returned nofpclass(nan) %p) {
 }
 
 define [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
-; CHECK-LABEL: define [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
+; CHECK-LABEL: define nofpclass(inf) [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
 ; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(inf) [2 x [3 x float]] @ret_array()
 ; CHECK-NEXT:    ret [2 x [3 x float]] [[RET]]
 ;
@@ -125,7 +125,7 @@ define [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
 
 define float @returned_nnan_fadd(float %arg0, float %arg1) {
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define float @returned_nnan_fadd
+; CHECK-LABEL: define nofpclass(nan) float @returned_nnan_fadd
 ; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR2]] {
 ; CHECK-NEXT:    [[FADD:%.*]] = fadd nnan float [[ARG0]], [[ARG1]]
 ; CHECK-NEXT:    ret float [[FADD]]
@@ -135,7 +135,7 @@ define float @returned_nnan_fadd(float %arg0, float %arg1) {
 }
 
 define float @return_nofpclass_nan_callsite() {
-; CHECK-LABEL: define float @return_nofpclass_nan_callsite() {
+; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_callsite() {
 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @extern()
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
@@ -145,7 +145,7 @@ define float @return_nofpclass_nan_callsite() {
 
 ; Can union the return classes
 define nofpclass(inf) float @return_ninf_nofpclass_nan_callsite() {
-; CHECK-LABEL: define nofpclass(inf) float @return_ninf_nofpclass_nan_callsite() {
+; CHECK-LABEL: define nofpclass(nan inf) float @return_ninf_nofpclass_nan_callsite() {
 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @extern()
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
@@ -177,7 +177,7 @@ define void @ninf_arg_used_by_nofpclass_nan_callsite(float nofpclass(inf) %arg)
 define void @ninf_arg_used_by_callsite_array([2 x [3 x float]] nofpclass(inf) %arg) {
 ; CHECK-LABEL: define void @ninf_arg_used_by_callsite_array
 ; CHECK-SAME: ([2 x [3 x float]] nofpclass(inf) [[ARG:%.*]]) {
-; CHECK-NEXT:    call void @extern.use.array([2 x [3 x float]] [[ARG]])
+; CHECK-NEXT:    call void @extern.use.array([2 x [3 x float]] nofpclass(inf) [[ARG]])
 ; CHECK-NEXT:    ret void
 ;
   call void @extern.use.array([2 x [3 x float]]  %arg)
@@ -186,12 +186,12 @@ define void @ninf_arg_used_by_callsite_array([2 x [3 x float]] nofpclass(inf) %a
 
 define float @mutually_recursive0(float %arg) {
 ; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none)
-; TUNIT-LABEL: define float @mutually_recursive0
+; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive0
 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
 ; TUNIT-NEXT:    ret float undef
 ;
 ; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
-; CGSCC-LABEL: define float @mutually_recursive0
+; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive0
 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR2]] {
 ; CGSCC-NEXT:    ret float undef
 ;
@@ -201,12 +201,12 @@ define float @mutually_recursive0(float %arg) {
 
 define float @mutually_recursive1(float %arg) {
 ; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none)
-; TUNIT-LABEL: define float @mutually_recursive1
+; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive1
 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
 ; TUNIT-NEXT:    ret float undef
 ;
 ; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
-; CGSCC-LABEL: define float @mutually_recursive1
+; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive1
 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR2]] {
 ; CGSCC-NEXT:    ret float undef
 ;
@@ -215,10 +215,10 @@ define float @mutually_recursive1(float %arg) {
 }
 
 define float @recursive_phi(ptr %ptr) {
-; CHECK-LABEL: define float @recursive_phi
+; CHECK-LABEL: define nofpclass(nan) float @recursive_phi
 ; CHECK-SAME: (ptr nofree [[PTR:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[RET:%.*]] = call float @ret_nofpclass_nan()
+; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[PHI:%.*]] = phi float [ [[RET]], [[ENTRY:%.*]] ], [ [[RET]], [[LOOP]] ]
@@ -310,7 +310,7 @@ entry:
 }
 
 define internal float @returned_dead() {
-; CHECK-LABEL: define internal float @returned_dead() {
+; CHECK-LABEL: define internal nofpclass(nan inf nzero sub norm) float @returned_dead() {
 ; CHECK-NEXT:    call void @unknown()
 ; CHECK-NEXT:    ret float undef
 ;
@@ -330,7 +330,7 @@ define void @returned_dead_caller() {
 define internal float @only_nofpclass_inf_callers(float %arg) {
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
 ; CHECK-LABEL: define internal float @only_nofpclass_inf_callers
-; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR2]] {
 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
 ; CHECK-NEXT:    ret float [[ADD]]
 ;
@@ -342,13 +342,13 @@ define float @call_noinf_0(float nofpclass(inf) %arg) {
 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
 ; TUNIT-LABEL: define float @call_noinf_0
 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR2]] {
-; TUNIT-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float [[ARG]]) #[[ATTR5:[0-9]+]]
+; TUNIT-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR5:[0-9]+]]
 ; TUNIT-NEXT:    ret float [[RESULT]]
 ;
 ; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none)
 ; CGSCC-LABEL: define float @call_noinf_0
 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
-; CGSCC-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float [[ARG]]) #[[ATTR4]]
+; CGSCC-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR4]]
 ; CGSCC-NEXT:    ret float [[RESULT]]
 ;
   %result = call float @only_nofpclass_inf_callers(float %arg)
@@ -386,13 +386,13 @@ define internal float @only_nofpclass_inf_return_users(float %arg) {
 
 define float @call_noinf_return_0(float %arg) {
 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
-; TUNIT-LABEL: define float @call_noinf_return_0
+; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_0
 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR2]] {
 ; TUNIT-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR5]]
 ; TUNIT-NEXT:    ret float [[RESULT]]
 ;
 ; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none)
-; CGSCC-LABEL: define float @call_noinf_return_0
+; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_0
 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
 ; CGSCC-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR4]]
 ; CGSCC-NEXT:    ret float [[RESULT]]
@@ -403,13 +403,13 @@ define float @call_noinf_return_0(float %arg) {
 
 define float @call_noinf_return_1(float %arg) {
 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
-; TUNIT-LABEL: define float @call_noinf_return_1
+; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_1
 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR2]] {
 ; TUNIT-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR5]]
 ; TUNIT-NEXT:    ret float [[RESULT]]
 ;
 ; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none)
-; CGSCC-LABEL: define float @call_noinf_return_1
+; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_1
 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
 ; CGSCC-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR4]]
 ; CGSCC-NEXT:    ret float [[RESULT]]
@@ -594,11 +594,11 @@ define float @assume_bundles(i1 %c, float %ret) {
 ; CHECK-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
 ; CHECK:       A:
 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]] [ "nofpclass"(float [[RET]], i32 3) ]
-; CHECK-NEXT:    call void @extern.use(float [[RET]])
+; CHECK-NEXT:    call void @extern.use(float nofpclass(nan) [[RET]])
 ; CHECK-NEXT:    ret float [[RET]]
 ; CHECK:       B:
 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) [ "nofpclass"(float [[RET]], i32 12) ]
-; CHECK-NEXT:    call void @extern.use(float [[RET]])
+; CHECK-NEXT:    call void @extern.use(float nofpclass(ninf nnorm) [[RET]])
 ; CHECK-NEXT:    ret float [[RET]]
 ;
 entry:


        


More information about the llvm-commits mailing list