[PATCH] D142427: [ValueTracking] Add logic for tracking lowbit of (and/xor/or X, (add/sub X, Odd))
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 18 12:29:14 PST 2023
goldstein.w.n updated this revision to Diff 498613.
goldstein.w.n added a comment.
Rebase
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D142427/new/
https://reviews.llvm.org/D142427
Files:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
Index: llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
===================================================================
--- llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
+++ llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
@@ -25,10 +25,7 @@
define i32 @cmp_ne_0_sub_xor_eval(i32 %x, i32 %C) {
; CHECK-LABEL: @cmp_ne_0_sub_xor_eval(
-; CHECK-NEXT: [[Y:%.*]] = add i32 [[X:%.*]], 1
-; CHECK-NEXT: [[Z:%.*]] = xor i32 [[Y]], [[X]]
-; CHECK-NEXT: [[B:%.*]] = and i32 [[Z]], 1
-; CHECK-NEXT: ret i32 [[B]]
+; CHECK-NEXT: ret i32 1
;
%C1 = or i32 %C, 13
%y = sub i32 %x, %C1
@@ -50,10 +47,7 @@
define i32 @cmp_ne_0_sub_or_eval(i32 %x, i32 %C) {
; CHECK-LABEL: @cmp_ne_0_sub_or_eval(
-; CHECK-NEXT: [[Y:%.*]] = add i32 [[X:%.*]], 1
-; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y]], [[X]]
-; CHECK-NEXT: [[B:%.*]] = and i32 [[Z]], 1
-; CHECK-NEXT: ret i32 [[B]]
+; CHECK-NEXT: ret i32 1
;
%C1 = or i32 %C, 5
%y = sub i32 %x, %C1
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -1109,16 +1109,23 @@
}
// and(x, add (x, -1)) is a common idiom that always clears the low bit;
+ // xor/or(x, add (x, -1)) is an idiom that will always set the low bit.
// here we handle the more general case of adding any odd number by
- // matching the form and(x, add(x, y)) where y is odd.
+ // matching the form and/xor/or(x, add(x, y)) where y is odd.
// TODO: This could be generalized to clearing any bit set in y where the
// following bit is known to be unset in y.
- if (IsAnd && !KnownOut.Zero[0] && !KnownOut.One[0] &&
- match(I, m_c_BinOp(m_Value(X), m_c_Add(m_Deferred(X), m_Value(Y))))) {
+ if (!KnownOut.Zero[0] && !KnownOut.One[0] &&
+ (match(I, m_c_BinOp(m_Value(X), m_c_Add(m_Deferred(X), m_Value(Y)))) ||
+ match(I, m_c_BinOp(m_Value(X), m_Sub(m_Deferred(X), m_Value(Y)))) ||
+ match(I, m_c_BinOp(m_Value(X), m_Sub(m_Value(Y), m_Deferred(X)))))) {
KnownBits KnownY(BitWidth);
computeKnownBits(Y, DemandedElts, KnownY, Depth + 1, Q);
- if (KnownY.countMinTrailingOnes() > 0)
- KnownOut.Zero.setBit(0);
+ if (KnownY.countMinTrailingOnes() > 0) {
+ if (IsAnd)
+ KnownOut.Zero.setBit(0);
+ else
+ KnownOut.One.setBit(0);
+ }
}
return KnownOut;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142427.498613.patch
Type: text/x-patch
Size: 2474 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230218/c5068a2e/attachment.bin>
More information about the llvm-commits
mailing list