Skip to content

Commit 83e8112

Browse files
toppercronlieb
authored andcommitted
[SelectionDAG] Correct the implementation of m_AllOnes. (llvm#90776)
Previously we used SpecificInt_match which created a 64 bit APInt containing all ones. This was then checked against other constants by using APInt::isSameValue. If the constnats have different bitwidths, APInt::isSameValue will zero extend the constant to make them match. This means for any constant less than 64 bits, m_AllOnes was guaranteed to fail since the zero extended value would not match all ones. I think would also incorrectly consider an i128 with 64 leading zeros and 64 trailing zeros as matching m_AllOnes. To avoid this, this patch adds a new matcher class that just calls isAllOnesOrAllOnesSplat. Change-Id: I81e987f2a4f11650f7b3ac4624a586d9d39f167a
1 parent 339eb00 commit 83e8112

File tree

2 files changed

+105
-387
lines changed

2 files changed

+105
-387
lines changed

llvm/include/llvm/CodeGen/SDPatternMatch.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,17 @@ inline SpecificInt_match m_SpecificInt(uint64_t V) {
741741

742742
inline SpecificInt_match m_Zero() { return m_SpecificInt(0U); }
743743
inline SpecificInt_match m_One() { return m_SpecificInt(1U); }
744-
inline SpecificInt_match m_AllOnes() { return m_SpecificInt(~0U); }
744+
745+
struct AllOnes_match {
746+
747+
AllOnes_match() = default;
748+
749+
template <typename MatchContext> bool match(const MatchContext &, SDValue N) {
750+
return isAllOnesOrAllOnesSplat(N);
751+
}
752+
};
753+
754+
inline AllOnes_match m_AllOnes() { return AllOnes_match(); }
745755

746756
/// Match true boolean value based on the information provided by
747757
/// TargetLowering.
@@ -824,7 +834,7 @@ inline BinaryOpc_match<SpecificInt_match, ValTy> m_Neg(const ValTy &V) {
824834

825835
/// Match a Not as a xor(v, -1) or xor(-1, v)
826836
template <typename ValTy>
827-
inline BinaryOpc_match<ValTy, SpecificInt_match, true> m_Not(const ValTy &V) {
837+
inline BinaryOpc_match<ValTy, AllOnes_match, true> m_Not(const ValTy &V) {
828838
return m_Xor(V, m_AllOnes());
829839
}
830840

0 commit comments

Comments
 (0)