Skip to content

Commit 49e3e75

Browse files
committed
[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.
1 parent bc4f3e3 commit 49e3e75

File tree

2 files changed

+14
-37
lines changed

2 files changed

+14
-37
lines changed

llvm/lib/IR/ConstantFold.cpp

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -679,15 +679,16 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
679679

680680
// Simplify BinOps with their identity values first. They are no-ops and we
681681
// can always return the other value, including undef or poison values.
682-
// FIXME: remove unnecessary duplicated identity patterns below.
683-
// FIXME: Use AllowRHSConstant with getBinOpIdentity to handle additional ops,
684-
// like X << 0 = X.
685-
Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, C1->getType());
686-
if (Identity) {
682+
if (Constant *Identity = ConstantExpr::getBinOpIdentity(
683+
Opcode, C1->getType(), /*AllowRHSIdentity*/ false)) {
687684
if (C1 == Identity)
688685
return C2;
689686
if (C2 == Identity)
690687
return C1;
688+
} else if (Constant *Identity = ConstantExpr::getBinOpIdentity(
689+
Opcode, C1->getType(), /*AllowRHSIdentity*/ true)) {
690+
if (C2 == Identity)
691+
return C1;
691692
}
692693

693694
// Binary operations propagate poison.
@@ -734,9 +735,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
734735
// X / 0 -> poison
735736
if (match(C2, m_CombineOr(m_Undef(), m_Zero())))
736737
return PoisonValue::get(C2->getType());
737-
// undef / 1 -> undef
738-
if (match(C2, m_One()))
739-
return C1;
740738
// undef / X -> 0 otherwise
741739
return Constant::getNullValue(C1->getType());
742740
case Instruction::URem:
@@ -755,28 +753,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
755753
// X >>l undef -> poison
756754
if (isa<UndefValue>(C2))
757755
return PoisonValue::get(C2->getType());
758-
// undef >>l 0 -> undef
759-
if (match(C2, m_Zero()))
760-
return C1;
761756
// undef >>l X -> 0
762757
return Constant::getNullValue(C1->getType());
763758
case Instruction::AShr:
764759
// X >>a undef -> poison
765760
if (isa<UndefValue>(C2))
766761
return PoisonValue::get(C2->getType());
767-
// undef >>a 0 -> undef
768-
if (match(C2, m_Zero()))
769-
return C1;
770762
// TODO: undef >>a X -> poison if the shift is exact
771763
// undef >>a X -> 0
772764
return Constant::getNullValue(C1->getType());
773765
case Instruction::Shl:
774766
// X << undef -> undef
775767
if (isa<UndefValue>(C2))
776768
return PoisonValue::get(C2->getType());
777-
// undef << 0 -> undef
778-
if (match(C2, m_Zero()))
779-
return C1;
780769
// undef << X -> 0
781770
return Constant::getNullValue(C1->getType());
782771
case Instruction::FSub:
@@ -810,21 +799,12 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
810799
// Handle simplifications when the RHS is a constant int.
811800
if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
812801
switch (Opcode) {
813-
case Instruction::Add:
814-
if (CI2->isZero()) return C1; // X + 0 == X
815-
break;
816-
case Instruction::Sub:
817-
if (CI2->isZero()) return C1; // X - 0 == X
818-
break;
819802
case Instruction::Mul:
820-
if (CI2->isZero()) return C2; // X * 0 == 0
821-
if (CI2->isOne())
822-
return C1; // X * 1 == X
803+
if (CI2->isZero())
804+
return C2; // X * 0 == 0
823805
break;
824806
case Instruction::UDiv:
825807
case Instruction::SDiv:
826-
if (CI2->isOne())
827-
return C1; // X / 1 == X
828808
if (CI2->isZero())
829809
return PoisonValue::get(CI2->getType()); // X / 0 == poison
830810
break;
@@ -836,9 +816,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
836816
return PoisonValue::get(CI2->getType()); // X % 0 == poison
837817
break;
838818
case Instruction::And:
839-
if (CI2->isZero()) return C2; // X & 0 == 0
840-
if (CI2->isMinusOne())
841-
return C1; // X & -1 == X
819+
if (CI2->isZero())
820+
return C2; // X & 0 == 0
842821

843822
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
844823
// If and'ing the address of a global with a constant, fold it.
@@ -880,16 +859,14 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
880859
}
881860
break;
882861
case Instruction::Or:
883-
if (CI2->isZero()) return C1; // X | 0 == X
884862
if (CI2->isMinusOne())
885-
return C2; // X | -1 == -1
863+
return C2; // X | -1 == -1
886864
break;
887865
case Instruction::Xor:
888-
if (CI2->isZero()) return C1; // X ^ 0 == X
889-
890866
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
891867
switch (CE1->getOpcode()) {
892-
default: break;
868+
default:
869+
break;
893870
case Instruction::ICmp:
894871
case Instruction::FCmp:
895872
// cmp pred ^ true -> cmp !pred

llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ define double @fadd_undef_op1_constant_0(double %x) {
150150

151151
define double @fsub_undef_op0_constant_0(double %x) {
152152
; CHECK-LABEL: @fsub_undef_op0_constant_0(
153-
; CHECK-NEXT: ret double 0x7FF8000000000000
153+
; CHECK-NEXT: ret double undef
154154
;
155155
%r = fsub double undef, 0x0000000000000000
156156
ret double %r

0 commit comments

Comments
 (0)