Index: llvm/lib/Transforms/IPO/AttributorAttributes.cpp =================================================================== --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -10234,6 +10234,33 @@ } } + /// See followUsesInMBEC + bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, + AANoFPClass::StateType &State) { + const Value *UseV = U->get(); + const DominatorTree *DT = nullptr; + AssumptionCache *AC = nullptr; + const TargetLibraryInfo *TLI = nullptr; + InformationCache &InfoCache = A.getInfoCache(); + + if (Function *F = getAnchorScope()) { + DT = InfoCache.getAnalysisResultForFunction(*F); + AC = InfoCache.getAnalysisResultForFunction(*F); + TLI = InfoCache.getTargetLibraryInfoForFunction(*F); + } + + const DataLayout &DL = A.getDataLayout(); + + KnownFPClass KnownFPClass = + computeKnownFPClass(UseV, DL, + /*InterestedClasses=*/fcAllFlags, + /*Depth=*/0, TLI, AC, I, DT); + State.addKnownBits(~KnownFPClass.KnownFPClasses); + + bool TrackUse = false; + return TrackUse; + } + const std::string getAsStr() const override { std::string Result = "nofpclass"; raw_string_ostream OS(Result); @@ -10271,9 +10298,42 @@ AANoFPClassFloating(const IRPosition &IRP, Attributor &A) : AANoFPClassImpl(IRP, A) {} + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override { + AANoFPClassImpl::initialize(A); + if (!getState().isAtFixpoint()) + if (Instruction *CtxI = getCtxI()) + followUsesInMBEC(*this, A, getState(), *CtxI); + } + /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { - return indicatePessimisticFixpoint(); + SmallVector Values; + bool UsedAssumedInformation = false; + if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, + AA::AnyScope, UsedAssumedInformation)) { + Values.push_back({getAssociatedValue(), getCtxI()}); + } + + StateType T; + auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { + const auto &AA = A.getAAFor(*this, IRPosition::value(V), + DepClassTy::REQUIRED); + if (this == &AA) { + T.indicatePessimisticFixpoint(); + } else { + const AANoFPClass::StateType &S = + static_cast(AA.getState()); + T ^= S; + } + return T.isValidState(); + }; + + for (const auto &VAC : Values) + if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI())) + return indicatePessimisticFixpoint(); + + return clampStateAndIndicateChange(getState(), T); } /// See AbstractAttribute::trackStatistics() Index: llvm/test/Transforms/Attributor/nofpclass.ll =================================================================== --- llvm/test/Transforms/Attributor/nofpclass.ll +++ llvm/test/Transforms/Attributor/nofpclass.ll @@ -167,7 +167,7 @@ define void @ninf_arg_used_by_nofpclass_nan_callsite(float nofpclass(inf) %arg) { ; CHECK-LABEL: define void @ninf_arg_used_by_nofpclass_nan_callsite ; CHECK-SAME: (float nofpclass(inf) [[ARG:%.*]]) { -; CHECK-NEXT: call void @extern.use(float nofpclass(nan) [[ARG]]) +; CHECK-NEXT: call void @extern.use(float nofpclass(nan inf) [[ARG]]) ; CHECK-NEXT: ret void ; call void @extern.use(float nofpclass(nan) %arg) @@ -248,7 +248,7 @@ ; CHECK-NEXT: [[ISNAN:%.*]] = fcmp uno float [[ARG]], 0.000000e+00 ; CHECK-NEXT: br i1 [[ISNAN]], label [[BB0:%.*]], label [[BB1:%.*]] ; CHECK: bb0: -; CHECK-NEXT: [[CALL:%.*]] = call float @ret_nofpclass_nan() +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan() ; CHECK-NEXT: br label [[BB1]] ; CHECK: bb1: ; CHECK-NEXT: [[PHI:%.*]] = phi float [ [[CALL]], [[BB0]] ], [ [[ARG]], [[ENTRY:%.*]] ]