Skip to content

Commit 2fcc008

Browse files
[ConstantFold][RFC] Refactor getBinOpAbsorber function
Add a AllowLHSConstant parameter in getBinOpAbsorber fuction for supporting more Binary operators. Signed-off-by: eric.tang <[email protected]>
1 parent eca5949 commit 2fcc008

File tree

3 files changed

+38
-32
lines changed

3 files changed

+38
-32
lines changed

llvm/include/llvm/IR/Constants.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,8 +1210,11 @@ class ConstantExpr : public Constant {
12101210
/// Return the absorbing element for the given binary
12111211
/// operation, i.e. a constant C such that X op C = C and C op X = C for
12121212
/// every X. For example, this returns zero for integer multiplication.
1213-
/// It returns null if the operator doesn't have an absorbing element.
1214-
static Constant *getBinOpAbsorber(unsigned Opcode, Type *Ty);
1213+
/// If AllowLHSConstant is true, the LHS operand is a constant C that must be
1214+
/// defined as C op X = C. It returns null if the operator doesn't have
1215+
/// an absorbing element.
1216+
static Constant *getBinOpAbsorber(unsigned Opcode, Type *Ty,
1217+
bool AllowLHSConstant = false);
12151218

12161219
/// Transparently provide more efficient getOperand methods.
12171220
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);

llvm/lib/IR/ConstantFold.cpp

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -729,13 +729,16 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
729729
// Neither constant should be UndefValue, unless these are vector constants.
730730
assert((!HasScalarUndefOrScalableVectorUndef) && "Unexpected UndefValue");
731731

732+
Constant *Absorber = ConstantExpr::getBinOpAbsorber(
733+
Opcode, C1->getType(), /*AllowLHSConstant*/ true);
734+
735+
// Handle absorbing element when the Opcode is a commutative opcode
736+
if ((C1 == Absorber || C2 == Absorber) && Instruction::isCommutative(Opcode))
737+
return Absorber;
738+
732739
// Handle simplifications when the RHS is a constant int.
733740
if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
734741
switch (Opcode) {
735-
case Instruction::Mul:
736-
if (CI2->isZero())
737-
return C2; // X * 0 == 0
738-
break;
739742
case Instruction::UDiv:
740743
case Instruction::SDiv:
741744
if (CI2->isZero())
@@ -749,9 +752,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
749752
return PoisonValue::get(CI2->getType()); // X % 0 == poison
750753
break;
751754
case Instruction::And:
752-
if (CI2->isZero())
753-
return C2; // X & 0 == 0
754-
755+
assert(!CI2->isZero() && "And zero handled above");
755756
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
756757
// If and'ing the address of a global with a constant, fold it.
757758
if (CE1->getOpcode() == Instruction::PtrToInt &&
@@ -791,10 +792,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
791792
}
792793
}
793794
break;
794-
case Instruction::Or:
795-
if (CI2->isMinusOne())
796-
return C2; // X | -1 == -1
797-
break;
798795
}
799796
} else if (isa<ConstantInt>(C1)) {
800797
// If C1 is a ConstantInt and C2 is not, swap the operands.
@@ -854,19 +851,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
854851
}
855852
}
856853

857-
switch (Opcode) {
858-
case Instruction::SDiv:
859-
case Instruction::UDiv:
860-
case Instruction::URem:
861-
case Instruction::SRem:
862-
case Instruction::LShr:
863-
case Instruction::AShr:
864-
case Instruction::Shl:
865-
if (CI1->isZero()) return C1;
866-
break;
867-
default:
868-
break;
869-
}
854+
if (C1 == Absorber)
855+
return C1;
870856
} else if (ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) {
871857
if (ConstantFP *CFP2 = dyn_cast<ConstantFP>(C2)) {
872858
const APFloat &C1V = CFP1->getValueAPF();

llvm/lib/IR/Constants.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,17 +2735,34 @@ Constant *ConstantExpr::getIdentity(Instruction *I, Type *Ty,
27352735
return nullptr;
27362736
}
27372737

2738-
Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) {
2738+
Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty,
2739+
bool AllowLHSConstant) {
27392740
switch (Opcode) {
27402741
default:
2741-
// Doesn't have an absorber.
2742-
return nullptr;
2742+
break;
27432743

2744-
case Instruction::Or:
2744+
case Instruction::Or: // -1 | X = -1
27452745
return Constant::getAllOnesValue(Ty);
27462746

2747-
case Instruction::And:
2748-
case Instruction::Mul:
2747+
case Instruction::And: // 0 & X = 0
2748+
case Instruction::Mul: // 0 * X = 0
2749+
return Constant::getNullValue(Ty);
2750+
}
2751+
2752+
// AllowLHSConstant must be set.
2753+
if (!AllowLHSConstant)
2754+
return nullptr;
2755+
2756+
switch (Opcode) {
2757+
default:
2758+
return nullptr;
2759+
case Instruction::Shl: // 0 << X = 0
2760+
case Instruction::LShr: // 0 >>l X = 0
2761+
case Instruction::AShr: // 0 >>a X = 0
2762+
case Instruction::SDiv: // 0 /s X = 0
2763+
case Instruction::UDiv: // 0 /u X = 0
2764+
case Instruction::URem: // 0 %u X = 0
2765+
case Instruction::SRem: // 0 %s X = 0
27492766
return Constant::getNullValue(Ty);
27502767
}
27512768
}

0 commit comments

Comments
 (0)