mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
Update PatternMatcher for FNeg
Match both FNeg(X) and FSub(+-0.0, X) in FNeg_match Differential Revision: https://reviews.llvm.org/D61520 llvm-svn: 359936
This commit is contained in:
parent
ca03fb25e6
commit
80fb24a66f
@ -667,18 +667,26 @@ template <typename Op_t> struct FNeg_match {
|
||||
FNeg_match(const Op_t &Op) : X(Op) {}
|
||||
template <typename OpTy> bool match(OpTy *V) {
|
||||
auto *FPMO = dyn_cast<FPMathOperator>(V);
|
||||
if (!FPMO || FPMO->getOpcode() != Instruction::FSub)
|
||||
return false;
|
||||
if (FPMO->hasNoSignedZeros()) {
|
||||
// With 'nsz', any zero goes.
|
||||
if (!cstfp_pred_ty<is_any_zero_fp>().match(FPMO->getOperand(0)))
|
||||
return false;
|
||||
} else {
|
||||
// Without 'nsz', we need fsub -0.0, X exactly.
|
||||
if (!cstfp_pred_ty<is_neg_zero_fp>().match(FPMO->getOperand(0)))
|
||||
return false;
|
||||
if (!FPMO) return false;
|
||||
|
||||
if (FPMO->getOpcode() == Instruction::FNeg)
|
||||
return X.match(FPMO->getOperand(0));
|
||||
|
||||
if (FPMO->getOpcode() == Instruction::FSub) {
|
||||
if (FPMO->hasNoSignedZeros()) {
|
||||
// With 'nsz', any zero goes.
|
||||
if (!cstfp_pred_ty<is_any_zero_fp>().match(FPMO->getOperand(0)))
|
||||
return false;
|
||||
} else {
|
||||
// Without 'nsz', we need fsub -0.0, X exactly.
|
||||
if (!cstfp_pred_ty<is_neg_zero_fp>().match(FPMO->getOperand(0)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return X.match(FPMO->getOperand(1));
|
||||
}
|
||||
return X.match(FPMO->getOperand(1));
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -589,6 +589,35 @@ TEST_F(PatternMatchTest, VectorUndefFloat) {
|
||||
EXPECT_TRUE(match(VectorZeroUndef, m_AnyZeroFP()));
|
||||
}
|
||||
|
||||
TEST_F(PatternMatchTest, FloatingPointFNeg) {
|
||||
Type *FltTy = IRB.getFloatTy();
|
||||
Value *One = ConstantFP::get(FltTy, 1.0);
|
||||
Value *Z = ConstantFP::get(FltTy, 0.0);
|
||||
Value *NZ = ConstantFP::get(FltTy, -0.0);
|
||||
Value *V = IRB.CreateFNeg(One);
|
||||
Value *V1 = IRB.CreateFSub(NZ, One);
|
||||
Value *V2 = IRB.CreateFSub(Z, One);
|
||||
Value *V3 = IRB.CreateFAdd(NZ, One);
|
||||
Value *Match;
|
||||
|
||||
// Test FNeg(1.0)
|
||||
EXPECT_TRUE(match(V, m_FNeg(m_Value(Match))));
|
||||
EXPECT_EQ(One, Match);
|
||||
|
||||
// Test FSub(-0.0, 1.0)
|
||||
EXPECT_TRUE(match(V1, m_FNeg(m_Value(Match))));
|
||||
EXPECT_EQ(One, Match);
|
||||
|
||||
// Test FSub(0.0, 1.0)
|
||||
EXPECT_FALSE(match(V2, m_FNeg(m_Value(Match))));
|
||||
cast<Instruction>(V2)->setHasNoSignedZeros(true);
|
||||
EXPECT_TRUE(match(V2, m_FNeg(m_Value(Match))));
|
||||
EXPECT_EQ(One, Match);
|
||||
|
||||
// Test FAdd(-0.0, 1.0)
|
||||
EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match))));
|
||||
}
|
||||
|
||||
template <typename T> struct MutableConstTest : PatternMatchTest { };
|
||||
|
||||
typedef ::testing::Types<std::tuple<Value*, Instruction*>,
|
||||
|
Loading…
Reference in New Issue
Block a user