[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