[llvm] b58ae6b - [InstCombine] Sync KnownBits logic for select arms
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 1 06:52:28 PDT 2024
Author: Nikita Popov
Date: 2024-07-01T15:52:20+02:00
New Revision: b58ae6bd2708a5c3757fe7ec722b6a87b98fd81a
URL: https://github.com/llvm/llvm-project/commit/b58ae6bd2708a5c3757fe7ec722b6a87b98fd81a
DIFF: https://github.com/llvm/llvm-project/commit/b58ae6bd2708a5c3757fe7ec722b6a87b98fd81a.diff
LOG: [InstCombine] Sync KnownBits logic for select arms
Extract an adjustKnownBitsForSelectArm() helper for the
ValueTracking logic and make use of it in SimplifyDemandedBits().
This fixes a consistency violation under instcombine-verify-known-bits.
Added:
Modified:
llvm/include/llvm/Analysis/ValueTracking.h
llvm/lib/Analysis/ValueTracking.cpp
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index e577d0cc7ad41..b7b78cb9edab3 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -100,6 +100,12 @@ KnownBits analyzeKnownBitsFromAndXorOr(const Operator *I,
const KnownBits &KnownRHS,
unsigned Depth, const SimplifyQuery &SQ);
+/// Adjust \p Known for the given select \p Arm to include information from the
+/// select \p Cond.
+void adjustKnownBitsForSelectArm(KnownBits &Known, Value *Cond, Value *Arm,
+ bool Invert, unsigned Depth,
+ const SimplifyQuery &Q);
+
/// Return true if LHS and RHS have no common bits set.
bool haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
const WithCache<const Value *> &RHSCache,
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c0d49ca99c1a8..6434de3e463c9 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -992,6 +992,40 @@ ConstantRange llvm::getVScaleRange(const Function *F, unsigned BitWidth) {
return ConstantRange(Min, APInt(BitWidth, *AttrMax) + 1);
}
+void llvm::adjustKnownBitsForSelectArm(KnownBits &Known, Value *Cond,
+ Value *Arm, bool Invert, unsigned Depth,
+ const SimplifyQuery &Q) {
+ // If we have a constant arm, we are done.
+ if (Known.isConstant())
+ return;
+
+ // See what condition implies about the bits of the select arm.
+ KnownBits CondRes(Known.getBitWidth());
+ computeKnownBitsFromCond(Arm, Cond, CondRes, Depth + 1, Q, Invert);
+ // If we don't get any information from the condition, no reason to
+ // proceed.
+ if (CondRes.isUnknown())
+ return;
+
+ // We can have conflict if the condition is dead. I.e if we have
+ // (x | 64) < 32 ? (x | 64) : y
+ // we will have conflict at bit 6 from the condition/the `or`.
+ // In that case just return. Its not particularly important
+ // what we do, as this select is going to be simplified soon.
+ CondRes = CondRes.unionWith(Known);
+ if (CondRes.hasConflict())
+ return;
+
+ // Finally make sure the information we found is valid. This is relatively
+ // expensive so it's left for the very end.
+ if (!isGuaranteedNotToBeUndef(Arm, Q.AC, Q.CxtI, Q.DT, Depth + 1))
+ return;
+
+ // Finally, we know we get information from the condition and its valid,
+ // so return it.
+ Known = CondRes;
+}
+
static void computeKnownBitsFromOperator(const Operator *I,
const APInt &DemandedElts,
KnownBits &Known, unsigned Depth,
@@ -1048,36 +1082,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
auto ComputeForArm = [&](Value *Arm, bool Invert) {
KnownBits Res(Known.getBitWidth());
computeKnownBits(Arm, Res, Depth + 1, Q);
- // If we have a constant arm, we are done.
- if (Res.isConstant())
- return Res;
-
- // See what condition implies about the bits of the two select arms.
- KnownBits CondRes(Res.getBitWidth());
- computeKnownBitsFromCond(Arm, I->getOperand(0), CondRes, Depth + 1, Q,
- Invert);
- // If we don't get any information from the condition, no reason to
- // proceed.
- if (CondRes.isUnknown())
- return Res;
-
- // We can have conflict if the condition is dead. I.e if we have
- // (x | 64) < 32 ? (x | 64) : y
- // we will have conflict at bit 6 from the condition/the `or`.
- // In that case just return. Its not particularly important
- // what we do, as this select is going to be simplified soon.
- CondRes = CondRes.unionWith(Res);
- if (CondRes.hasConflict())
- return Res;
-
- // Finally make sure the information we found is valid. This is relatively
- // expensive so it's left for the very end.
- if (!isGuaranteedNotToBeUndef(Arm, Q.AC, Q.CxtI, Q.DT, Depth + 1))
- return Res;
-
- // Finally, we know we get information from the condition and its valid,
- // so return it.
- return CondRes;
+ adjustKnownBitsForSelectArm(Res, I->getOperand(0), Arm, Invert, Depth, Q);
+ return Res;
};
// Only known if known in both the LHS and RHS.
Known =
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index ca6034e09b73b..6cf2e71363ab5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -408,6 +408,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
return I;
// Only known if known in both the LHS and RHS.
+ adjustKnownBitsForSelectArm(LHSKnown, I->getOperand(0), I->getOperand(1),
+ /*Invert=*/false, Depth, Q);
+ adjustKnownBitsForSelectArm(LHSKnown, I->getOperand(0), I->getOperand(2),
+ /*Invert=*/true, Depth, Q);
Known = LHSKnown.intersectWith(RHSKnown);
break;
}
More information about the llvm-commits
mailing list