aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorAlex MacLean <amaclean@nvidia.com>2025-01-10 09:17:44 -0800
committerGitHub <noreply@github.com>2025-01-10 09:17:44 -0800
commit59ced72bc211f150518cf31606b58b11cb6ff310 (patch)
tree230e5afa11febe43c1ef24182e53b8218a588007 /llvm/lib/Analysis/ValueTracking.cpp
parent70e96dc3fb895e95dc659f87c2ed188507831801 (diff)
downloadllvm-59ced72bc211f150518cf31606b58b11cb6ff310.zip
llvm-59ced72bc211f150518cf31606b58b11cb6ff310.tar.gz
llvm-59ced72bc211f150518cf31606b58b11cb6ff310.tar.bz2
[ValueTracking] Add rotate idiom to haveNoCommonBitsSet special cases (#122165)
An occasional idiom for rotation is "(A << B) + (A >> (BitWidth - B))". Currently this is not well handled on targets with native funnel-shift/rotate support. Add a special case to haveNoCommonBitsSet to ensure that the addition is converted to a disjoint or in InstCombine so during instruction selection the idiom can be converted to an efficient rotation implementation. Proof: https://alive2.llvm.org/ce/z/WdCZsN
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9a61b36..4b246c0 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -229,6 +229,19 @@ static bool haveNoCommonBitsSetSpecialCases(const Value *LHS, const Value *RHS,
return true;
}
+ // Look for: (X << V) op (Y >> (BitWidth - V))
+ // or (X >> V) op (Y << (BitWidth - V))
+ {
+ const Value *V;
+ const APInt *R;
+ if (((match(RHS, m_Shl(m_Value(), m_Sub(m_APInt(R), m_Value(V)))) &&
+ match(LHS, m_LShr(m_Value(), m_Specific(V)))) ||
+ (match(RHS, m_LShr(m_Value(), m_Sub(m_APInt(R), m_Value(V)))) &&
+ match(LHS, m_Shl(m_Value(), m_Specific(V))))) &&
+ R->uge(LHS->getType()->getScalarSizeInBits()))
+ return true;
+ }
+
return false;
}