[InstSimplify] peek through unsigned FP casts for sign-bit compares (PR36682)
This pattern came up in PR36682 / D44390
https://bugs.llvm.org/show_bug.cgi?id=36682
https://reviews.llvm.org/D44390
https://godbolt.org/g/oKvT5H
See also D44421, D44424
Reviewers: spatel, majnemer, efriedma, arsenm
Reviewed By: spatel
Subscribers: wdng, llvm-commits
Differential Revision: https://reviews.llvm.org/D44425
llvm-svn: 327642
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index c382553..cf350ea 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2490,6 +2490,18 @@
Value *RHS) {
Type *ITy = GetCompareTy(RHS); // The return type.
+ Value *X;
+ // Sign-bit checks can be optimized to true/false after unsigned
+ // floating-point casts:
+ // icmp slt (bitcast (uitofp X)), 0 --> false
+ // icmp sgt (bitcast (uitofp X)), -1 --> true
+ if (match(LHS, m_BitCast(m_UIToFP(m_Value(X))))) {
+ if (Pred == ICmpInst::ICMP_SLT && match(RHS, m_Zero()))
+ return ConstantInt::getFalse(ITy);
+ if (Pred == ICmpInst::ICMP_SGT && match(RHS, m_AllOnes()))
+ return ConstantInt::getTrue(ITy);
+ }
+
const APInt *C;
if (!match(RHS, m_APInt(C)))
return nullptr;