summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-09-05 23:13:13 +0000
committerSanjay Patel <spatel@rotateright.com>2017-09-05 23:13:13 +0000
commit6840c5ff75944a0be503da16a1fcbff7aee373df (patch)
treec5a065894795ab4b7cde9a542f2e5e907a87f53e /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
parent8db11a4f1ceff5b8c70cd1838db20c7983033bb7 (diff)
downloadbcm5719-llvm-6840c5ff75944a0be503da16a1fcbff7aee373df.tar.gz
bcm5719-llvm-6840c5ff75944a0be503da16a1fcbff7aee373df.zip
[ValueTracking, InstCombine] canonicalize fcmp ord/uno with non-NAN ops to null constants
This is a preliminary step towards solving the remaining part of PR27145 - IR for isfinite(): https://bugs.llvm.org/show_bug.cgi?id=27145 In order to solve that one more generally, we need to add matching for and/or of fcmp ord/uno with a constant operand. But while looking at those patterns, I realized we were missing a canonicalization for nonzero constants. Rather than limiting to just folds for constants, we're adding a general value tracking method for this based on an existing DAG helper. By transforming everything to 0.0, we can simplify the existing code in foldLogicOfFCmps() and pick up missing vector folds. Differential Revision: https://reviews.llvm.org/D37427 llvm-svn: 312591
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp21
1 files changed, 6 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 006ed418c73..a81f295b91d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -938,21 +938,12 @@ Value *InstCombiner::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS, bool IsAnd)
if (LHS0->getType() != RHS0->getType())
return nullptr;
- auto *LHSC = dyn_cast<ConstantFP>(LHS1);
- auto *RHSC = dyn_cast<ConstantFP>(RHS1);
- if (LHSC && RHSC) {
- assert(!LHSC->getValueAPF().isNaN() && !RHSC->getValueAPF().isNaN() &&
- "Failed to simplify fcmp ord/uno with NAN operand");
- // Ignore the constants because they can't be NANs:
- // (fcmp ord x, c) & (fcmp ord y, c) -> (fcmp ord x, y)
- // (fcmp uno x, c) & (fcmp uno y, c) -> (fcmp uno x, y)
- return Builder.CreateFCmp(PredL, LHS0, RHS0);
- }
-
- // Handle vector zeros. This occurs because the canonical form of
- // "fcmp ord/uno x,x" is "fcmp ord/uno x, 0".
- if (isa<ConstantAggregateZero>(LHS1) &&
- isa<ConstantAggregateZero>(RHS1))
+ // FCmp canonicalization ensures that (fcmp ord/uno X, X) and
+ // (fcmp ord/uno X, C) will be transformed to (fcmp X, 0.0).
+ if (match(LHS1, m_Zero()) && LHS1 == RHS1)
+ // Ignore the constants because they are obviously not NANs:
+ // (fcmp ord x, 0.0) & (fcmp ord y, 0.0) -> (fcmp ord x, y)
+ // (fcmp uno x, 0.0) | (fcmp uno y, 0.0) -> (fcmp uno x, y)
return Builder.CreateFCmp(PredL, LHS0, RHS0);
}
OpenPOWER on IntegriCloud