diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 22 | ||||
-rw-r--r-- | llvm/unittests/Analysis/ValueTrackingTest.cpp | 58 |
2 files changed, 80 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 495324ff534..02d071717f0 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4397,12 +4397,34 @@ static bool isKnownNonNaN(const Value *V, FastMathFlags FMF) { if (auto *C = dyn_cast<ConstantFP>(V)) return !C->isNaN(); + + if (auto *C = dyn_cast<ConstantDataVector>(V)) { + if (!C->getElementType()->isFloatingPointTy()) + return false; + for (unsigned I = 0, E = C->getNumElements(); I < E; ++I) { + if (C->getElementAsAPFloat(I).isNaN()) + return false; + } + return true; + } + return false; } static bool isKnownNonZero(const Value *V) { if (auto *C = dyn_cast<ConstantFP>(V)) return !C->isZero(); + + if (auto *C = dyn_cast<ConstantDataVector>(V)) { + if (!C->getElementType()->isFloatingPointTy()) + return false; + for (unsigned I = 0, E = C->getNumElements(); I < E; ++I) { + if (C->getElementAsAPFloat(I).isZero()) + return false; + } + return true; + } + return false; } diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index cfdf264da31..f391ca12e55 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -149,6 +149,64 @@ TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) { expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); } +TEST_F(MatchSelectPatternTest, VectorFMinNaN) { + parseAssembly( + "define <4 x float> @test(<4 x float> %a) {\n" + " %1 = fcmp ule <4 x float> %a, \n" + " <float 5.0, float 5.0, float 5.0, float 5.0>\n" + " %A = select <4 x i1> %1, <4 x float> %a,\n" + " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" + " ret <4 x float> %A\n" + "}\n"); + // Check that pattern matching works on vectors where each lane has the same + // unordered pattern. + expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); +} + +TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) { + parseAssembly( + "define <4 x float> @test(<4 x float> %a) {\n" + " %1 = fcmp ole <4 x float> %a, \n" + " <float 5.0, float 5.0, float 5.0, float 5.0>\n" + " %A = select <4 x i1> %1, <4 x float> %a,\n" + " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" + " ret <4 x float> %A\n" + "}\n"); + // Check that pattern matching works on vectors where each lane has the same + // ordered pattern. + expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); +} + +TEST_F(MatchSelectPatternTest, VectorNotFMinNaN) { + parseAssembly( + "define <4 x float> @test(<4 x float> %a) {\n" + " %1 = fcmp ule <4 x float> %a, \n" + " <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n" + " %A = select <4 x i1> %1, <4 x float> %a,\n" + " <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float " + "5.0>\n" + " ret <4 x float> %A\n" + "}\n"); + // The lane that contains a NaN (0x7ff80...) behaves like a + // non-NaN-propagating min and the other lines behave like a NaN-propagating + // min, so check that neither is returned. + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); +} + +TEST_F(MatchSelectPatternTest, VectorNotFMinZero) { + parseAssembly( + "define <4 x float> @test(<4 x float> %a) {\n" + " %1 = fcmp ule <4 x float> %a, \n" + " <float 5.0, float -0.0, float 5.0, float 5.0>\n" + " %A = select <4 x i1> %1, <4 x float> %a,\n" + " <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n" + " ret <4 x float> %A\n" + "}\n"); + // Always selects the second lane of %a if it is positive or negative zero, so + // this is stricter than a min. + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); +} + TEST_F(MatchSelectPatternTest, DoubleCastU) { parseAssembly( "define i32 @test(i8 %a, i8 %b) {\n" |