Skip to content

Commit a59e5d8

Browse files
[ConstantFold][RFC] Add AllowLHSConstant parameter in getBinOpAbsorber (#109736)
Add a AllowLHSConstant parameter in getBinOpAbsorber function for supporting more binary operators.
1 parent 9f81acf commit a59e5d8

File tree

3 files changed

+36
-32
lines changed

3 files changed

+36
-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: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -731,11 +731,11 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
731731

732732
// Handle simplifications when the RHS is a constant int.
733733
if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
734+
if (C2 == ConstantExpr::getBinOpAbsorber(Opcode, C2->getType(),
735+
/*AllowLHSConstant*/ false))
736+
return C2;
737+
734738
switch (Opcode) {
735-
case Instruction::Mul:
736-
if (CI2->isZero())
737-
return C2; // X * 0 == 0
738-
break;
739739
case Instruction::UDiv:
740740
case Instruction::SDiv:
741741
if (CI2->isZero())
@@ -749,9 +749,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
749749
return PoisonValue::get(CI2->getType()); // X % 0 == poison
750750
break;
751751
case Instruction::And:
752-
if (CI2->isZero())
753-
return C2; // X & 0 == 0
754-
752+
assert(!CI2->isZero() && "And zero handled above");
755753
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
756754
// If and'ing the address of a global with a constant, fold it.
757755
if (CE1->getOpcode() == Instruction::PtrToInt &&
@@ -791,10 +789,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
791789
}
792790
}
793791
break;
794-
case Instruction::Or:
795-
if (CI2->isMinusOne())
796-
return C2; // X | -1 == -1
797-
break;
798792
}
799793
} else if (isa<ConstantInt>(C1)) {
800794
// If C1 is a ConstantInt and C2 is not, swap the operands.
@@ -854,19 +848,9 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
854848
}
855849
}
856850

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-
}
851+
if (C1 == ConstantExpr::getBinOpAbsorber(Opcode, C1->getType(),
852+
/*AllowLHSConstant*/ true))
853+
return C1;
870854
} else if (ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) {
871855
if (ConstantFP *CFP2 = dyn_cast<ConstantFP>(C2)) {
872856
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)