[llvm] e1ac984 - ValueTracking: Implement computeKnownFPClass for ldexp
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 11 06:26:49 PDT 2023
Author: Matt Arsenault
Date: 2023-07-11T09:26:41-04:00
New Revision: e1ac984a1095d3364640c1ff1a137436c5084129
URL: https://github.com/llvm/llvm-project/commit/e1ac984a1095d3364640c1ff1a137436c5084129
DIFF: https://github.com/llvm/llvm-project/commit/e1ac984a1095d3364640c1ff1a137436c5084129.diff
LOG: ValueTracking: Implement computeKnownFPClass for ldexp
https://reviews.llvm.org/D149590
Added:
Modified:
llvm/include/llvm/Analysis/ValueTracking.h
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll
llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 930eb85b729d48..44e083c63c82c0 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -416,6 +416,23 @@ struct KnownFPClass {
knownNot(fcSNan);
}
+ /// Propagate knowledge from a source value that could be a denormal or
+ /// zero. We have to be conservative since output flushing is not guaranteed,
+ /// so known-never-zero may not hold.
+ ///
+ /// This assumes a copy-like operation and will replace any currently known
+ /// information.
+ void propagateDenormal(const KnownFPClass &Src, const Function &F, Type *Ty);
+
+ /// Report known classes if \p Src is evaluated through a potentially
+ /// canonicalizing operation. We can assume signaling nans will not be
+ /// introduced, but cannot assume a denormal will be flushed under FTZ/DAZ.
+ ///
+ /// This assumes a copy-like operation and will replace any currently known
+ /// information.
+ void propagateCanonicalizingSrc(const KnownFPClass &Src, const Function &F,
+ Type *Ty);
+
void resetAll() { *this = KnownFPClass(); }
};
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 412699eb0bb3e5..bf2b67988ce845 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3933,6 +3933,41 @@ bool KnownFPClass::isKnownNeverLogicalPosZero(const Function &F,
llvm_unreachable("covered switch over denormal mode");
}
+void KnownFPClass::propagateDenormal(const KnownFPClass &Src, const Function &F,
+ Type *Ty) {
+ KnownFPClasses = Src.KnownFPClasses;
+ // If we aren't assuming the source can't be a zero, we don't have to check if
+ // a denormal input could be flushed.
+ if (!Src.isKnownNeverPosZero() && !Src.isKnownNeverNegZero())
+ return;
+
+ // If we know the input can't be a denormal, it can't be flushed to 0.
+ if (Src.isKnownNeverSubnormal())
+ return;
+
+ DenormalMode Mode = F.getDenormalMode(Ty->getScalarType()->getFltSemantics());
+
+ if (!Src.isKnownNeverPosSubnormal() && Mode != DenormalMode::getIEEE())
+ KnownFPClasses |= fcPosZero;
+
+ if (!Src.isKnownNeverNegSubnormal() && Mode != DenormalMode::getIEEE()) {
+ if (Mode != DenormalMode::getPositiveZero())
+ KnownFPClasses |= fcNegZero;
+
+ if (Mode.Input == DenormalMode::PositiveZero ||
+ Mode.Output == DenormalMode::PositiveZero ||
+ Mode.Input == DenormalMode::Dynamic ||
+ Mode.Output == DenormalMode::Dynamic)
+ KnownFPClasses |= fcPosZero;
+ }
+}
+
+void KnownFPClass::propagateCanonicalizingSrc(const KnownFPClass &Src,
+ const Function &F, Type *Ty) {
+ propagateDenormal(Src, F, Ty);
+ propagateNaN(Src, /*PreserveSign=*/true);
+}
+
/// Returns a pair of values, which if passed to llvm.is.fpclass, returns the
/// same result as an fcmp with the given operands.
std::pair<Value *, FPClassTest> llvm::fcmpToClassTest(FCmpInst::Predicate Pred,
@@ -4641,6 +4676,61 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Known.knownNot(fcNegative);
break;
}
+ case Intrinsic::ldexp: {
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts,
+ InterestedClasses, KnownSrc, Depth + 1, Q);
+ Known.propagateNaN(KnownSrc, /*PropagateSign=*/true);
+
+ // Sign is preserved, but underflows may produce zeroes.
+ if (KnownSrc.isKnownNever(fcNegative))
+ Known.knownNot(fcNegative);
+ else if (KnownSrc.cannotBeOrderedLessThanZero())
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+
+ if (KnownSrc.isKnownNever(fcPositive))
+ Known.knownNot(fcPositive);
+ else if (KnownSrc.cannotBeOrderedGreaterThanZero())
+ Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
+
+ // Can refine inf/zero handling based on the exponent operand.
+ const FPClassTest ExpInfoMask = fcZero | fcSubnormal | fcInf;
+ if ((InterestedClasses & ExpInfoMask) == fcNone)
+ break;
+ if ((KnownSrc.KnownFPClasses & ExpInfoMask) == fcNone)
+ break;
+
+ const Value *ExpArg = II->getArgOperand(1);
+ KnownBits ExpKnownBits(
+ ExpArg->getType()->getScalarType()->getIntegerBitWidth());
+ computeKnownBits(ExpArg, ExpKnownBits, Depth + 1, Q);
+
+ const Function *F = II->getFunction();
+
+ if (ExpKnownBits.isZero()) {
+ // ldexp(x, 0) -> x, so propagate everything.
+ Known.propagateCanonicalizingSrc(KnownSrc, *II->getFunction(),
+ II->getType());
+ } else if (ExpKnownBits.isNegative()) {
+ // If we know the power is < 0, can't introduce inf
+ if (KnownSrc.isKnownNeverPosInfinity())
+ Known.knownNot(fcPosInf);
+ if (KnownSrc.isKnownNeverNegInfinity())
+ Known.knownNot(fcNegInf);
+ } else if (ExpKnownBits.isNonNegative()) {
+ // If we know the power is >= 0, can't introduce subnormal or zero
+ if (KnownSrc.isKnownNeverPosSubnormal())
+ Known.knownNot(fcPosSubnormal);
+ if (KnownSrc.isKnownNeverNegSubnormal())
+ Known.knownNot(fcNegSubnormal);
+ if (F && KnownSrc.isKnownNeverLogicalPosZero(*F, II->getType()))
+ Known.knownNot(fcPosZero);
+ if (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))
+ Known.knownNot(fcNegZero);
+ }
+
+ break;
+ }
case Intrinsic::arithmetic_fence: {
computeKnownFPClass(II->getArgOperand(0), DemandedElts,
InterestedClasses, Known, Depth + 1, Q);
diff --git a/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll b/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll
index 32087f3b2b2d3c..40beec9a201455 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll
@@ -30,9 +30,9 @@ define float @ret_ldexp_f32_0(float %arg0) #0 {
}
define float @ret_ldexp_f32_0_nopsub(float nofpclass(psub) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub
; CHECK-SAME: (float nofpclass(psub) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -40,9 +40,9 @@ define float @ret_ldexp_f32_0_nopsub(float nofpclass(psub) %arg0) #0 {
}
define float @ret_ldexp_f32_0_nonsub(float nofpclass(nsub) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nonsub
+; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_0_nonsub
; CHECK-SAME: (float nofpclass(nsub) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -50,9 +50,9 @@ define float @ret_ldexp_f32_0_nonsub(float nofpclass(nsub) %arg0) #0 {
}
define float @ret_ldexp_f32_0_nosub(float nofpclass(sub) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub
+; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_0_nosub
; CHECK-SAME: (float nofpclass(sub) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -60,9 +60,9 @@ define float @ret_ldexp_f32_0_nosub(float nofpclass(sub) %arg0) #0 {
}
define float @ret_ldexp_f32_0_nosub_nosnan(float nofpclass(sub snan) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub_nosnan
+; CHECK-LABEL: define nofpclass(snan sub) float @ret_ldexp_f32_0_nosub_nosnan
; CHECK-SAME: (float nofpclass(snan sub) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -70,9 +70,9 @@ define float @ret_ldexp_f32_0_nosub_nosnan(float nofpclass(sub snan) %arg0) #0 {
}
define float @ret_ldexp_f32_0_nopsub_nopzero(float nofpclass(psub pzero) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nopzero
+; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nopzero
; CHECK-SAME: (float nofpclass(pzero psub) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -80,9 +80,9 @@ define float @ret_ldexp_f32_0_nopsub_nopzero(float nofpclass(psub pzero) %arg0)
}
define float @ret_ldexp_f32_0_nonsub_nonzero(float nofpclass(nsub nzero) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nonsub_nonzero
+; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_0_nonsub_nonzero
; CHECK-SAME: (float nofpclass(nzero nsub) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -90,9 +90,9 @@ define float @ret_ldexp_f32_0_nonsub_nonzero(float nofpclass(nsub nzero) %arg0)
}
define float @ret_ldexp_f32_0_nosub_nozero(float nofpclass(sub zero) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub_nozero
+; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_0_nosub_nozero
; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -100,9 +100,9 @@ define float @ret_ldexp_f32_0_nosub_nozero(float nofpclass(sub zero) %arg0) #0 {
}
define float @ret_ldexp_f32_0_nopsub_daz(float nofpclass(psub) %arg0) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_daz
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_daz
; CHECK-SAME: (float nofpclass(psub) [[ARG0:%.*]]) #[[ATTR2:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -110,9 +110,9 @@ define float @ret_ldexp_f32_0_nopsub_daz(float nofpclass(psub) %arg0) #1 {
}
define float @ret_ldexp_f32_0_nonsub_daz(float nofpclass(nsub) %arg0) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nonsub_daz
+; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_0_nonsub_daz
; CHECK-SAME: (float nofpclass(nsub) [[ARG0:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -120,9 +120,9 @@ define float @ret_ldexp_f32_0_nonsub_daz(float nofpclass(nsub) %arg0) #1 {
}
define float @ret_ldexp_f32_0_nosub_daz(float nofpclass(sub) %arg0) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub_daz
+; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_0_nosub_daz
; CHECK-SAME: (float nofpclass(sub) [[ARG0:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -130,9 +130,9 @@ define float @ret_ldexp_f32_0_nosub_daz(float nofpclass(sub) %arg0) #1 {
}
define float @ret_ldexp_f32_0_nosub_nosnan_daz(float nofpclass(sub snan) %arg0) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub_nosnan_daz
+; CHECK-LABEL: define nofpclass(snan sub) float @ret_ldexp_f32_0_nosub_nosnan_daz
; CHECK-SAME: (float nofpclass(snan sub) [[ARG0:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -140,9 +140,9 @@ define float @ret_ldexp_f32_0_nosub_nosnan_daz(float nofpclass(sub snan) %arg0)
}
define float @ret_ldexp_f32_0_nopsub_nozero_daz(float nofpclass(psub pzero) %arg0) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_daz
+; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nozero_daz
; CHECK-SAME: (float nofpclass(pzero psub) [[ARG0:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -150,9 +150,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_daz(float nofpclass(psub pzero) %arg
}
define float @ret_ldexp_f32_0_nonsub_nonzero_daz(float nofpclass(nsub nzero) %arg0) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nonsub_nonzero_daz
+; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_0_nonsub_nonzero_daz
; CHECK-SAME: (float nofpclass(nzero nsub) [[ARG0:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -160,9 +160,9 @@ define float @ret_ldexp_f32_0_nonsub_nonzero_daz(float nofpclass(nsub nzero) %ar
}
define float @ret_ldexp_f32_0_nosub_nozero_daz(float nofpclass(sub zero) %arg0) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub_nozero_daz
+; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_0_nosub_nozero_daz
; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -170,9 +170,9 @@ define float @ret_ldexp_f32_0_nosub_nozero_daz(float nofpclass(sub zero) %arg0)
}
define float @ret_ldexp_f32_0_nopsub_dapz(float nofpclass(psub) %arg0) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_dapz
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_dapz
; CHECK-SAME: (float nofpclass(psub) [[ARG0:%.*]]) #[[ATTR3:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -180,9 +180,9 @@ define float @ret_ldexp_f32_0_nopsub_dapz(float nofpclass(psub) %arg0) #2 {
}
define float @ret_ldexp_f32_0_nonsub_dapz(float nofpclass(nsub) %arg0) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nonsub_dapz
+; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_0_nonsub_dapz
; CHECK-SAME: (float nofpclass(nsub) [[ARG0:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -190,9 +190,9 @@ define float @ret_ldexp_f32_0_nonsub_dapz(float nofpclass(nsub) %arg0) #2 {
}
define float @ret_ldexp_f32_0_nosub_dapz(float nofpclass(sub) %arg0) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub_dapz
+; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_0_nosub_dapz
; CHECK-SAME: (float nofpclass(sub) [[ARG0:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -200,9 +200,9 @@ define float @ret_ldexp_f32_0_nosub_dapz(float nofpclass(sub) %arg0) #2 {
}
define float @ret_ldexp_f32_0_nopsub_nozero_dapz(float nofpclass(psub zero) %arg0) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_dapz
+; CHECK-LABEL: define nofpclass(nzero psub) float @ret_ldexp_f32_0_nopsub_nozero_dapz
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -210,9 +210,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_dapz(float nofpclass(psub zero) %arg
}
define float @ret_ldexp_f32_0_nonsub_nonzero_dapz(float nofpclass(nsub nzero) %arg0) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nonsub_nonzero_dapz
+; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_0_nonsub_nonzero_dapz
; CHECK-SAME: (float nofpclass(nzero nsub) [[ARG0:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -220,9 +220,9 @@ define float @ret_ldexp_f32_0_nonsub_nonzero_dapz(float nofpclass(nsub nzero) %a
}
define float @ret_ldexp_f32_0_nosub_nozero_dapz(float nofpclass(sub zero) %arg0) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nosub_nozero_dapz
+; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_0_nosub_nozero_dapz
; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -230,9 +230,9 @@ define float @ret_ldexp_f32_0_nosub_nozero_dapz(float nofpclass(sub zero) %arg0)
}
define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dapz(float nofpclass(psub zero) %arg0) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dapz
+; CHECK-LABEL: define nofpclass(nzero psub) float @ret_ldexp_f32_0_nopsub_nozero_dapz_dapz
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -240,9 +240,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dapz(float nofpclass(psub zero)
}
define float @ret_ldexp_f32_0_nopsub_nozero_daz_ieee(float nofpclass(psub zero) %arg0) #3 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_daz_ieee
+; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nozero_daz_ieee
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR4:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -250,9 +250,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_daz_ieee(float nofpclass(psub zero)
}
define float @ret_ldexp_f32_0_nopsub_nozero_daz_dynamic(float nofpclass(psub zero) %arg0) #4 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_daz_dynamic
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_daz_dynamic
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR5:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -260,9 +260,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_daz_dynamic(float nofpclass(psub zer
}
define float @ret_ldexp_f32_0_nopsub_nozero_ieee_daz(float nofpclass(psub zero) %arg0) #5 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_ieee_daz
+; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nozero_ieee_daz
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR6:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -270,9 +270,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_ieee_daz(float nofpclass(psub zero)
}
define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_daz(float nofpclass(psub zero) %arg0) #6 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_daz
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_dynamic_daz
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR7:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -280,9 +280,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_daz(float nofpclass(psub zer
}
define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_dapz(float nofpclass(psub zero) %arg0) #7 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_dapz
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_dynamic_dapz
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR8:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -290,9 +290,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_dapz(float nofpclass(psub ze
}
define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dynamic(float nofpclass(psub zero) %arg0) #8 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dynamic
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_dapz_dynamic
; CHECK-SAME: (float nofpclass(zero psub) [[ARG0:%.*]]) #[[ATTR9:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -300,9 +300,9 @@ define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dynamic(float nofpclass(psub ze
}
define float @ret_ldexp_f32_0_nopnorm(float nofpclass(pnorm) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopnorm
+; CHECK-LABEL: define nofpclass(pnorm) float @ret_ldexp_f32_0_nopnorm
; CHECK-SAME: (float nofpclass(pnorm) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -310,9 +310,9 @@ define float @ret_ldexp_f32_0_nopnorm(float nofpclass(pnorm) %arg0) #0 {
}
define float @ret_ldexp_f32_0_nnorm(float nofpclass(nnorm) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nnorm
+; CHECK-LABEL: define nofpclass(nnorm) float @ret_ldexp_f32_0_nnorm
; CHECK-SAME: (float nofpclass(nnorm) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -320,9 +320,9 @@ define float @ret_ldexp_f32_0_nnorm(float nofpclass(nnorm) %arg0) #0 {
}
define float @ret_ldexp_f32_0_nopnorm_nonsub(float nofpclass(pnorm nsub) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_0_nopnorm_nonsub
+; CHECK-LABEL: define nofpclass(nsub pnorm) float @ret_ldexp_f32_0_nopnorm_nonsub
; CHECK-SAME: (float nofpclass(nsub pnorm) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nsub pnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
@@ -360,9 +360,9 @@ define <2 x float> @ret_ldexp_v2f32(<2 x float> %arg0, <2 x i32> %arg1) #0 {
}
define float @ret_ldexp_f32_nonan(float nofpclass(nan) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_nonan
+; CHECK-LABEL: define nofpclass(nan) float @ret_ldexp_f32_nonan
; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -370,9 +370,9 @@ define float @ret_ldexp_f32_nonan(float nofpclass(nan) %arg0, i32 %arg1) #0 {
}
define float @ret_ldexp_f32_nosnan(float nofpclass(snan) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_nosnan
+; CHECK-LABEL: define nofpclass(snan) float @ret_ldexp_f32_nosnan
; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -390,9 +390,9 @@ define float @ret_ldexp_f32_noqnan(float nofpclass(qnan) %arg0, i32 %arg1) #0 {
}
define float @ret_ldexp_f32_noneg(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg
; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -400,9 +400,9 @@ define float @ret_ldexp_f32_noneg(float nofpclass(ninf nsub nnorm) %arg0, i32 %a
}
define float @ret_ldexp_f32_noneg_nonzero(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg_nonzero
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero
; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -410,9 +410,9 @@ define float @ret_ldexp_f32_noneg_nonzero(float nofpclass(ninf nsub nnorm nzero)
}
define float @ret_ldexp_f32_noneg_nozero(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg_nozero
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg_nozero
; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -440,9 +440,9 @@ define float @ret_ldexp_f32_nopzero(float nofpclass(pzero) %arg0, i32 %arg1) #0
}
define float @ret_ldexp_f32_noneg_ftz_daz(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg_ftz_daz
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg_ftz_daz
; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -450,9 +450,9 @@ define float @ret_ldexp_f32_noneg_ftz_daz(float nofpclass(ninf nsub nnorm) %arg0
}
define float @ret_ldexp_f32_noneg_nonzero_ftz_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg_nonzero_ftz_daz
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero_ftz_daz
; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -460,9 +460,9 @@ define float @ret_ldexp_f32_noneg_nonzero_ftz_daz(float nofpclass(ninf nsub nnor
}
define float @ret_ldexp_f32_noneg_nonzero_ftpz_dapz(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #2 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg_nonzero_ftpz_dapz
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero_ftpz_dapz
; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -490,9 +490,9 @@ define float @ret_ldexp_f32_noninf_nonnorm_ftz_daz(float nofpclass(ninf nnorm) %
}
define float @ret_ldexp_f32_noneg_ftz_ieee(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #3 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg_ftz_ieee
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg_ftz_ieee
; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR4]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -500,9 +500,9 @@ define float @ret_ldexp_f32_noneg_ftz_ieee(float nofpclass(ninf nsub nnorm) %arg
}
define float @ret_ldexp_f32_noneg_nonzero_ftz_ieee(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #3 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noneg_nonzero_ftz_ieee
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero_ftz_ieee
; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR4]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -510,9 +510,9 @@ define float @ret_ldexp_f32_noneg_nonzero_ftz_ieee(float nofpclass(ninf nsub nno
}
define float @ret_ldexp_f32_nopos(float nofpclass(pinf psub pnorm) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_nopos
+; CHECK-LABEL: define nofpclass(pinf psub pnorm) float @ret_ldexp_f32_nopos
; CHECK-SAME: (float nofpclass(pinf psub pnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pinf psub pnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -520,9 +520,9 @@ define float @ret_ldexp_f32_nopos(float nofpclass(pinf psub pnorm) %arg0, i32 %a
}
define float @ret_ldexp_f32_nopos_nopzero(float nofpclass(pinf psub pnorm pzero) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_nopos_nopzero
+; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_ldexp_f32_nopos_nopzero
; CHECK-SAME: (float nofpclass(pinf pzero psub pnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pinf pzero psub pnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -530,9 +530,9 @@ define float @ret_ldexp_f32_nopos_nopzero(float nofpclass(pinf psub pnorm pzero)
}
define float @ret_ldexp_f32_nopos_nozero(float nofpclass(pinf psub pnorm zero) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_nopos_nozero
+; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_ldexp_f32_nopos_nozero
; CHECK-SAME: (float nofpclass(pinf zero psub pnorm) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pinf pzero psub pnorm) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -560,9 +560,9 @@ define float @ret_ldexp_f32_noinf(float nofpclass(inf) %arg0, i32 %arg1) #0 {
}
define float @ret_ldexp_f32_noinf_nonan(float nofpclass(inf nan) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_noinf_nonan
+; CHECK-LABEL: define nofpclass(nan) float @ret_ldexp_f32_noinf_nonan
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
@@ -594,10 +594,10 @@ define float @ret_ldexp_f32_known_neg_exp(float %arg0, i32 %arg1) #0 {
}
define float @ret_ldexp_f32_known_pos_exp_nosub(float nofpclass(sub) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_nosub
+; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_known_pos_exp_nosub
; CHECK-SAME: (float nofpclass(sub) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[AND_ARG1:%.*]] = and i32 [[ARG1]], 127
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%and.arg1 = and i32 %arg1, 127
@@ -618,10 +618,10 @@ define float @ret_ldexp_f32_known_neg_exp_nosub(float nofpclass(sub) %arg0, i32
}
define float @ret_ldexp_f32_known_pos_exp_nopsub(float nofpclass(psub) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_nopsub
+; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_known_pos_exp_nopsub
; CHECK-SAME: (float nofpclass(psub) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[AND_ARG1:%.*]] = and i32 [[ARG1]], 127
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%and.arg1 = and i32 %arg1, 127
@@ -642,10 +642,10 @@ define float @ret_ldexp_f32_known_neg_exp_nopsub(float nofpclass(psub) %arg0, i3
}
define float @ret_ldexp_f32_known_pos_exp_nonsub(float nofpclass(nsub) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_nonsub
+; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_known_pos_exp_nonsub
; CHECK-SAME: (float nofpclass(nsub) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[AND_ARG1:%.*]] = and i32 [[ARG1]], 127
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%and.arg1 = and i32 %arg1, 127
@@ -678,10 +678,10 @@ define float @ret_ldexp_f32_known_pos_exp_noinf(float nofpclass(inf) %arg0, i32
}
define float @ret_ldexp_f32_known_neg_exp_noinf(float nofpclass(inf) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_noinf
+; CHECK-LABEL: define nofpclass(inf) float @ret_ldexp_f32_known_neg_exp_noinf
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[OR_ARG1:%.*]] = or i32 [[ARG1]], -16
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%or.arg1 = or i32 %arg1, -16
@@ -702,10 +702,10 @@ define <2 x float> @ret_ldexp_v2f32_known_pos_exp_noinf(<2 x float> nofpclass(in
}
define <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf(<2 x float> nofpclass(inf) %arg0, <2 x i32> %arg1) #0 {
-; CHECK-LABEL: define <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf
+; CHECK-LABEL: define nofpclass(inf) <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf
; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[OR_ARG1:%.*]] = or <2 x i32> [[ARG1]], <i32 -16, i32 -32>
-; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[ARG0]], <2 x i32> [[OR_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf) <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[ARG0]], <2 x i32> [[OR_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret <2 x float> [[CALL]]
;
%or.arg1 = or <2 x i32> %arg1, <i32 -16, i32 -32>
@@ -726,10 +726,10 @@ define float @ret_ldexp_f32_known_pos_exp_nopinf(float nofpclass(pinf) %arg0, i3
}
define float @ret_ldexp_f32_known_neg_exp_nopinf(float nofpclass(pinf) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_nopinf
+; CHECK-LABEL: define nofpclass(pinf) float @ret_ldexp_f32_known_neg_exp_nopinf
; CHECK-SAME: (float nofpclass(pinf) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[OR_ARG1:%.*]] = or i32 [[ARG1]], -16
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pinf) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%or.arg1 = or i32 %arg1, -16
@@ -750,10 +750,10 @@ define float @ret_ldexp_f32_known_pos_exp_noninf(float nofpclass(ninf) %arg0, i3
}
define float @ret_ldexp_f32_known_neg_exp_noninf(float nofpclass(ninf) %arg0, i32 %arg1) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_noninf
+; CHECK-LABEL: define nofpclass(ninf) float @ret_ldexp_f32_known_neg_exp_noninf
; CHECK-SAME: (float nofpclass(ninf) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[OR_ARG1:%.*]] = or i32 [[ARG1]], -16
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%or.arg1 = or i32 %arg1, -16
@@ -762,10 +762,10 @@ define float @ret_ldexp_f32_known_neg_exp_noninf(float nofpclass(ninf) %arg0, i3
}
define float @ret_ldexp_f32_known_pos_exp_nopsub_nopzero_daz(float nofpclass(psub pzero) %arg0, i32 %arg1) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_nopsub_nopzero_daz
+; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_known_pos_exp_nopsub_nopzero_daz
; CHECK-SAME: (float nofpclass(pzero psub) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[AND_ARG1:%.*]] = and i32 [[ARG1]], 127
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%and.arg1 = and i32 %arg1, 127
@@ -786,10 +786,10 @@ define float @ret_ldexp_f32_known_neg_exp_nopsub_nopzero_daz(float nofpclass(psu
}
define float @ret_ldexp_f32_known_pos_exp_nonsub_nonzero_daz(float nofpclass(nsub nzero) %arg0, i32 %arg1) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_nonsub_nonzero_daz
+; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_known_pos_exp_nonsub_nonzero_daz
; CHECK-SAME: (float nofpclass(nzero nsub) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[AND_ARG1:%.*]] = and i32 [[ARG1]], 127
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%and.arg1 = and i32 %arg1, 127
@@ -810,10 +810,10 @@ define float @ret_ldexp_f32_known_neg_exp_nonsub_nonzero_daz(float nofpclass(nsu
}
define float @ret_ldexp_f32_known_pos_exp_nosub_nozero_daz(float nofpclass(sub zero) %arg0, i32 %arg1) #1 {
-; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_nosub_nozero_daz
+; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_known_pos_exp_nosub_nozero_daz
; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[AND_ARG1:%.*]] = and i32 [[ARG1]], 127
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%and.arg1 = and i32 %arg1, 127
@@ -876,9 +876,9 @@ define float @ret_ldexp_f32_min24(float %arg0, i32 %arg1) #0 {
}
define float @ret_ldexp_f32_23_nnan(float nofpclass(nan) %arg0) #0 {
-; CHECK-LABEL: define float @ret_ldexp_f32_23_nnan
+; CHECK-LABEL: define nofpclass(nan) float @ret_ldexp_f32_23_nnan
; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 23) #[[ATTR10]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 23) #[[ATTR10]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.ldexp.f32.i32(float %arg0, i32 23)
diff --git a/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll b/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll
index 7e9f62158c2dee..a6360eabc69c17 100644
--- a/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll
+++ b/llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll
@@ -165,5 +165,24 @@ bb:
ret void
}
+define i1 @simplify_fcmp_ord_ldexp_caller(double nofpclass(zero inf) %i0) {
+; CHECK-LABEL: define i1 @simplify_fcmp_ord_ldexp_caller
+; CHECK-SAME: (double nofpclass(inf zero) [[I0:%.*]]) {
+; CHECK-NEXT: [[LDEXP_I:%.*]] = call double @llvm.ldexp.f64.i32(double [[I0]], i32 42)
+; CHECK-NEXT: [[CMP_I:%.*]] = fcmp one double [[LDEXP_I]], 0x7FF0000000000000
+; CHECK-NEXT: ret i1 [[CMP_I]]
+;
+ %call = call i1 @simplify_fcmp_ord_ldexp_callee(double %i0)
+ ret i1 %call
+}
+
+define internal i1 @simplify_fcmp_ord_ldexp_callee(double %a) {
+ %ldexp = call double @llvm.ldexp.f64.i32(double %a, i32 42)
+ %cmp = fcmp one double %ldexp, 0x7FF0000000000000
+ ret i1 %cmp
+}
+
+declare double @llvm.ldexp.f64.i32(double, i32)
+
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) }
More information about the llvm-commits
mailing list