[llvm] [KnownBits] Make `avg{Ceil,Floor}S` and `{s,u}{add,sub}_sat` optimal (PR #110329)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 27 22:45:37 PDT 2024
================
@@ -656,52 +706,8 @@ static KnownBits computeForSatAddSub(bool Add, bool Signed,
}
}
- if (Signed) {
- if (Add) {
- if (LHS.isNonNegative() && RHS.isNonNegative()) {
- // Pos + Pos -> Pos
- Res.One.clearSignBit();
- Res.Zero.setSignBit();
- }
- if (LHS.isNegative() && RHS.isNegative()) {
- // Neg + Neg -> Neg
- Res.One.setSignBit();
- Res.Zero.clearSignBit();
- }
- } else {
- if (LHS.isNegative() && RHS.isNonNegative()) {
- // Neg - Pos -> Neg
- Res.One.setSignBit();
- Res.Zero.clearSignBit();
- } else if (LHS.isNonNegative() && RHS.isNegative()) {
- // Pos - Neg -> Pos
- Res.One.clearSignBit();
- Res.Zero.setSignBit();
- }
- }
- } else {
- // Add: Leading ones of either operand are preserved.
- // Sub: Leading zeros of LHS and leading ones of RHS are preserved
- // as leading zeros in the result.
- unsigned LeadingKnown;
- if (Add)
- LeadingKnown =
- std::max(LHS.countMinLeadingOnes(), RHS.countMinLeadingOnes());
- else
- LeadingKnown =
- std::max(LHS.countMinLeadingZeros(), RHS.countMinLeadingOnes());
-
- // We select between the operation result and all-ones/zero
- // respectively, so we can preserve known ones/zeros.
- APInt Mask = APInt::getHighBitsSet(BitWidth, LeadingKnown);
- if (Add) {
- Res.One |= Mask;
- Res.Zero &= ~Mask;
- } else {
- Res.Zero |= Mask;
- Res.One &= ~Mask;
- }
- }
+ KnownBits Res = KnownBits::computeForAddSub(Add, /*NSW=*/Signed,
+ /*NUW*/ !Signed, LHS, RHS);
----------------
dtcxzyw wrote:
```suggestion
/*NUW=*/!Signed, LHS, RHS);
```
https://github.com/llvm/llvm-project/pull/110329
More information about the llvm-commits
mailing list