Skip to content

Commit 5cabf15

Browse files
authored
[KnownBits] Make avg{Ceil,Floor}S optimal (#110688)
Rewrite the signed functions in terms of the unsigned ones which are already optimal.
1 parent 9c72a9d commit 5cabf15

File tree

3 files changed

+23
-26
lines changed

3 files changed

+23
-26
lines changed

llvm/include/llvm/Support/KnownBits.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ struct KnownBits {
2929
KnownBits(APInt Zero, APInt One)
3030
: Zero(std::move(Zero)), One(std::move(One)) {}
3131

32+
// Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF]
33+
static KnownBits flipSignBit(const KnownBits &Val);
34+
3235
public:
3336
// Default construct Zero and One.
3437
KnownBits() = default;

llvm/lib/Support/KnownBits.cpp

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818

1919
using namespace llvm;
2020

21+
KnownBits KnownBits::flipSignBit(const KnownBits &Val) {
22+
unsigned SignBitPosition = Val.getBitWidth() - 1;
23+
APInt Zero = Val.Zero;
24+
APInt One = Val.One;
25+
Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
26+
One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
27+
return KnownBits(Zero, One);
28+
}
29+
2130
static KnownBits computeForAddCarry(const KnownBits &LHS, const KnownBits &RHS,
2231
bool CarryZero, bool CarryOne) {
2332

@@ -200,16 +209,7 @@ KnownBits KnownBits::umin(const KnownBits &LHS, const KnownBits &RHS) {
200209
}
201210

202211
KnownBits KnownBits::smax(const KnownBits &LHS, const KnownBits &RHS) {
203-
// Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF]
204-
auto Flip = [](const KnownBits &Val) {
205-
unsigned SignBitPosition = Val.getBitWidth() - 1;
206-
APInt Zero = Val.Zero;
207-
APInt One = Val.One;
208-
Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
209-
One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
210-
return KnownBits(Zero, One);
211-
};
212-
return Flip(umax(Flip(LHS), Flip(RHS)));
212+
return flipSignBit(umax(flipSignBit(LHS), flipSignBit(RHS)));
213213
}
214214

215215
KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) {
@@ -763,35 +763,30 @@ KnownBits KnownBits::usub_sat(const KnownBits &LHS, const KnownBits &RHS) {
763763
return computeForSatAddSub(/*Add*/ false, /*Signed*/ false, LHS, RHS);
764764
}
765765

766-
static KnownBits avgCompute(KnownBits LHS, KnownBits RHS, bool IsCeil,
767-
bool IsSigned) {
766+
static KnownBits avgComputeU(KnownBits LHS, KnownBits RHS, bool IsCeil) {
768767
unsigned BitWidth = LHS.getBitWidth();
769-
LHS = IsSigned ? LHS.sext(BitWidth + 1) : LHS.zext(BitWidth + 1);
770-
RHS = IsSigned ? RHS.sext(BitWidth + 1) : RHS.zext(BitWidth + 1);
768+
LHS = LHS.zext(BitWidth + 1);
769+
RHS = RHS.zext(BitWidth + 1);
771770
LHS =
772771
computeForAddCarry(LHS, RHS, /*CarryZero*/ !IsCeil, /*CarryOne*/ IsCeil);
773772
LHS = LHS.extractBits(BitWidth, 1);
774773
return LHS;
775774
}
776775

777776
KnownBits KnownBits::avgFloorS(const KnownBits &LHS, const KnownBits &RHS) {
778-
return avgCompute(LHS, RHS, /* IsCeil */ false,
779-
/* IsSigned */ true);
777+
return flipSignBit(avgFloorU(flipSignBit(LHS), flipSignBit(RHS)));
780778
}
781779

782780
KnownBits KnownBits::avgFloorU(const KnownBits &LHS, const KnownBits &RHS) {
783-
return avgCompute(LHS, RHS, /* IsCeil */ false,
784-
/* IsSigned */ false);
781+
return avgComputeU(LHS, RHS, /*IsCeil=*/false);
785782
}
786783

787784
KnownBits KnownBits::avgCeilS(const KnownBits &LHS, const KnownBits &RHS) {
788-
return avgCompute(LHS, RHS, /* IsCeil */ true,
789-
/* IsSigned */ true);
785+
return flipSignBit(avgCeilU(flipSignBit(LHS), flipSignBit(RHS)));
790786
}
791787

792788
KnownBits KnownBits::avgCeilU(const KnownBits &LHS, const KnownBits &RHS) {
793-
return avgCompute(LHS, RHS, /* IsCeil */ true,
794-
/* IsSigned */ false);
789+
return avgComputeU(LHS, RHS, /*IsCeil=*/true);
795790
}
796791

797792
KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS,

llvm/unittests/Support/KnownBitsTest.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,16 +521,15 @@ TEST(KnownBitsTest, BinaryExhaustive) {
521521
[](const APInt &N1, const APInt &N2) { return APIntOps::mulhu(N1, N2); },
522522
/*CheckOptimality=*/false);
523523

524-
testBinaryOpExhaustive("avgFloorS", KnownBits::avgFloorS, APIntOps::avgFloorS,
525-
/*CheckOptimality=*/false);
524+
testBinaryOpExhaustive("avgFloorS", KnownBits::avgFloorS,
525+
APIntOps::avgFloorS);
526526

527527
testBinaryOpExhaustive("avgFloorU", KnownBits::avgFloorU,
528528
APIntOps::avgFloorU);
529529

530530
testBinaryOpExhaustive("avgCeilU", KnownBits::avgCeilU, APIntOps::avgCeilU);
531531

532-
testBinaryOpExhaustive("avgCeilS", KnownBits::avgCeilS, APIntOps::avgCeilS,
533-
/*CheckOptimality=*/false);
532+
testBinaryOpExhaustive("avgCeilS", KnownBits::avgCeilS, APIntOps::avgCeilS);
534533
}
535534

536535
TEST(KnownBitsTest, UnaryExhaustive) {

0 commit comments

Comments
 (0)