Skip to content

Commit eab92cb

Browse files
[llvm] Add KnownBits implementations for avgFloor and avgCeil (#86445)
This PR is to address the issue #84640
1 parent 9e4ef0d commit eab92cb

File tree

4 files changed

+74
-10
lines changed

4 files changed

+74
-10
lines changed

llvm/include/llvm/Support/KnownBits.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,18 @@ struct KnownBits {
354354
/// Compute knownbits resulting from llvm.usub.sat(LHS, RHS)
355355
static KnownBits usub_sat(const KnownBits &LHS, const KnownBits &RHS);
356356

357+
/// Compute knownbits resulting from APIntOps::avgFloorS
358+
static KnownBits avgFloorS(const KnownBits &LHS, const KnownBits &RHS);
359+
360+
/// Compute knownbits resulting from APIntOps::avgFloorU
361+
static KnownBits avgFloorU(const KnownBits &LHS, const KnownBits &RHS);
362+
363+
/// Compute knownbits resulting from APIntOps::avgCeilS
364+
static KnownBits avgCeilS(const KnownBits &LHS, const KnownBits &RHS);
365+
366+
/// Compute knownbits resulting from APIntOps::avgCeilU
367+
static KnownBits avgCeilU(const KnownBits &LHS, const KnownBits &RHS);
368+
357369
/// Compute known bits resulting from multiplying LHS and RHS.
358370
static KnownBits mul(const KnownBits &LHS, const KnownBits &RHS,
359371
bool NoUndefSelfMultiply = false);

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,19 +3468,28 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
34683468
Known = KnownBits::mulhs(Known, Known2);
34693469
break;
34703470
}
3471-
case ISD::AVGFLOORU:
3472-
case ISD::AVGCEILU:
3473-
case ISD::AVGFLOORS:
3471+
case ISD::AVGFLOORU: {
3472+
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
3473+
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
3474+
Known = KnownBits::avgFloorU(Known, Known2);
3475+
break;
3476+
}
3477+
case ISD::AVGCEILU: {
3478+
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
3479+
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
3480+
Known = KnownBits::avgCeilU(Known, Known2);
3481+
break;
3482+
}
3483+
case ISD::AVGFLOORS: {
3484+
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
3485+
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
3486+
Known = KnownBits::avgFloorS(Known, Known2);
3487+
break;
3488+
}
34743489
case ISD::AVGCEILS: {
3475-
bool IsCeil = Opcode == ISD::AVGCEILU || Opcode == ISD::AVGCEILS;
3476-
bool IsSigned = Opcode == ISD::AVGFLOORS || Opcode == ISD::AVGCEILS;
34773490
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
34783491
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
3479-
Known = IsSigned ? Known.sext(BitWidth + 1) : Known.zext(BitWidth + 1);
3480-
Known2 = IsSigned ? Known2.sext(BitWidth + 1) : Known2.zext(BitWidth + 1);
3481-
KnownBits Carry = KnownBits::makeConstant(APInt(1, IsCeil ? 1 : 0));
3482-
Known = KnownBits::computeForAddCarry(Known, Known2, Carry);
3483-
Known = Known.extractBits(BitWidth, 1);
3492+
Known = KnownBits::avgCeilS(Known, Known2);
34843493
break;
34853494
}
34863495
case ISD::SELECT:

llvm/lib/Support/KnownBits.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,37 @@ KnownBits KnownBits::usub_sat(const KnownBits &LHS, const KnownBits &RHS) {
774774
return computeForSatAddSub(/*Add*/ false, /*Signed*/ false, LHS, RHS);
775775
}
776776

777+
static KnownBits avgCompute(KnownBits LHS, KnownBits RHS, bool IsCeil,
778+
bool IsSigned) {
779+
unsigned BitWidth = LHS.getBitWidth();
780+
LHS = IsSigned ? LHS.sext(BitWidth + 1) : LHS.zext(BitWidth + 1);
781+
RHS = IsSigned ? RHS.sext(BitWidth + 1) : RHS.zext(BitWidth + 1);
782+
KnownBits Carry = KnownBits::makeConstant(APInt(1, IsCeil ? 1 : 0));
783+
LHS = KnownBits::computeForAddCarry(LHS, RHS, Carry);
784+
LHS = LHS.extractBits(BitWidth, 1);
785+
return LHS;
786+
}
787+
788+
KnownBits KnownBits::avgFloorS(const KnownBits &LHS, const KnownBits &RHS) {
789+
return avgCompute(LHS, RHS, /* IsCeil */ false,
790+
/* IsSigned */ true);
791+
}
792+
793+
KnownBits KnownBits::avgFloorU(const KnownBits &LHS, const KnownBits &RHS) {
794+
return avgCompute(LHS, RHS, /* IsCeil */ false,
795+
/* IsSigned */ false);
796+
}
797+
798+
KnownBits KnownBits::avgCeilS(const KnownBits &LHS, const KnownBits &RHS) {
799+
return avgCompute(LHS, RHS, /* IsCeil */ true,
800+
/* IsSigned */ true);
801+
}
802+
803+
KnownBits KnownBits::avgCeilU(const KnownBits &LHS, const KnownBits &RHS) {
804+
return avgCompute(LHS, RHS, /* IsCeil */ true,
805+
/* IsSigned */ false);
806+
}
807+
777808
KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS,
778809
bool NoUndefSelfMultiply) {
779810
unsigned BitWidth = LHS.getBitWidth();

llvm/unittests/Support/KnownBitsTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,18 @@ TEST(KnownBitsTest, BinaryExhaustive) {
501501
"mulhu", KnownBits::mulhu,
502502
[](const APInt &N1, const APInt &N2) { return APIntOps::mulhu(N1, N2); },
503503
/*CheckOptimality=*/false);
504+
505+
testBinaryOpExhaustive("avgFloorS", KnownBits::avgFloorS, APIntOps::avgFloorS,
506+
false);
507+
508+
testBinaryOpExhaustive("avgFloorU", KnownBits::avgFloorU, APIntOps::avgFloorU,
509+
false);
510+
511+
testBinaryOpExhaustive("avgCeilU", KnownBits::avgCeilU, APIntOps::avgCeilU,
512+
false);
513+
514+
testBinaryOpExhaustive("avgCeilS", KnownBits::avgCeilS, APIntOps::avgCeilS,
515+
false);
504516
}
505517

506518
TEST(KnownBitsTest, UnaryExhaustive) {

0 commit comments

Comments
 (0)