[llvm] 49e3e75 - [ConstantFold] Clean up binop identity folding
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 18 01:38:03 PST 2024
Author: Nikita Popov
Date: 2024-01-18T10:37:48+01:00
New Revision: 49e3e7514309823e39627175d5337c5d5aff92c1
URL: https://github.com/llvm/llvm-project/commit/49e3e7514309823e39627175d5337c5d5aff92c1
DIFF: https://github.com/llvm/llvm-project/commit/49e3e7514309823e39627175d5337c5d5aff92c1.diff
LOG: [ConstantFold] Clean up binop identity folding
Resolve the two FIXMEs: Perform the binop identitiy fold with
AllowRHSConstant, and remove redundant folds later in the code.
Added:
Modified:
llvm/lib/IR/ConstantFold.cpp
llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll
Removed:
################################################################################
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 7fdc35e7fca097..034e397bc69fce 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -679,15 +679,16 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
// Simplify BinOps with their identity values first. They are no-ops and we
// can always return the other value, including undef or poison values.
- // FIXME: remove unnecessary duplicated identity patterns below.
- // FIXME: Use AllowRHSConstant with getBinOpIdentity to handle additional ops,
- // like X << 0 = X.
- Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, C1->getType());
- if (Identity) {
+ if (Constant *Identity = ConstantExpr::getBinOpIdentity(
+ Opcode, C1->getType(), /*AllowRHSIdentity*/ false)) {
if (C1 == Identity)
return C2;
if (C2 == Identity)
return C1;
+ } else if (Constant *Identity = ConstantExpr::getBinOpIdentity(
+ Opcode, C1->getType(), /*AllowRHSIdentity*/ true)) {
+ if (C2 == Identity)
+ return C1;
}
// Binary operations propagate poison.
@@ -734,9 +735,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
// X / 0 -> poison
if (match(C2, m_CombineOr(m_Undef(), m_Zero())))
return PoisonValue::get(C2->getType());
- // undef / 1 -> undef
- if (match(C2, m_One()))
- return C1;
// undef / X -> 0 otherwise
return Constant::getNullValue(C1->getType());
case Instruction::URem:
@@ -755,18 +753,12 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
// X >>l undef -> poison
if (isa<UndefValue>(C2))
return PoisonValue::get(C2->getType());
- // undef >>l 0 -> undef
- if (match(C2, m_Zero()))
- return C1;
// undef >>l X -> 0
return Constant::getNullValue(C1->getType());
case Instruction::AShr:
// X >>a undef -> poison
if (isa<UndefValue>(C2))
return PoisonValue::get(C2->getType());
- // undef >>a 0 -> undef
- if (match(C2, m_Zero()))
- return C1;
// TODO: undef >>a X -> poison if the shift is exact
// undef >>a X -> 0
return Constant::getNullValue(C1->getType());
@@ -774,9 +766,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
// X << undef -> undef
if (isa<UndefValue>(C2))
return PoisonValue::get(C2->getType());
- // undef << 0 -> undef
- if (match(C2, m_Zero()))
- return C1;
// undef << X -> 0
return Constant::getNullValue(C1->getType());
case Instruction::FSub:
@@ -810,21 +799,12 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
// Handle simplifications when the RHS is a constant int.
if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
switch (Opcode) {
- case Instruction::Add:
- if (CI2->isZero()) return C1; // X + 0 == X
- break;
- case Instruction::Sub:
- if (CI2->isZero()) return C1; // X - 0 == X
- break;
case Instruction::Mul:
- if (CI2->isZero()) return C2; // X * 0 == 0
- if (CI2->isOne())
- return C1; // X * 1 == X
+ if (CI2->isZero())
+ return C2; // X * 0 == 0
break;
case Instruction::UDiv:
case Instruction::SDiv:
- if (CI2->isOne())
- return C1; // X / 1 == X
if (CI2->isZero())
return PoisonValue::get(CI2->getType()); // X / 0 == poison
break;
@@ -836,9 +816,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
return PoisonValue::get(CI2->getType()); // X % 0 == poison
break;
case Instruction::And:
- if (CI2->isZero()) return C2; // X & 0 == 0
- if (CI2->isMinusOne())
- return C1; // X & -1 == X
+ if (CI2->isZero())
+ return C2; // X & 0 == 0
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
// If and'ing the address of a global with a constant, fold it.
@@ -880,16 +859,14 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
}
break;
case Instruction::Or:
- if (CI2->isZero()) return C1; // X | 0 == X
if (CI2->isMinusOne())
- return C2; // X | -1 == -1
+ return C2; // X | -1 == -1
break;
case Instruction::Xor:
- if (CI2->isZero()) return C1; // X ^ 0 == X
-
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
switch (CE1->getOpcode()) {
- default: break;
+ default:
+ break;
case Instruction::ICmp:
case Instruction::FCmp:
// cmp pred ^ true -> cmp !pred
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll b/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll
index 5cfe55862a2da9..6fa57a8a1467ae 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll
@@ -150,7 +150,7 @@ define double @fadd_undef_op1_constant_0(double %x) {
define double @fsub_undef_op0_constant_0(double %x) {
; CHECK-LABEL: @fsub_undef_op0_constant_0(
-; CHECK-NEXT: ret double 0x7FF8000000000000
+; CHECK-NEXT: ret double undef
;
%r = fsub double undef, 0x0000000000000000
ret double %r
More information about the llvm-commits
mailing list