diff options
author | Alex MacLean <amaclean@nvidia.com> | 2025-01-10 09:17:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-10 09:17:44 -0800 |
commit | 59ced72bc211f150518cf31606b58b11cb6ff310 (patch) | |
tree | 230e5afa11febe43c1ef24182e53b8218a588007 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 70e96dc3fb895e95dc659f87c2ed188507831801 (diff) | |
download | llvm-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.cpp | 13 |
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; } |