[llvm] 8b8f2ef - [MergeFunc] Fix comparison of constant expressions

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 20 06:59:09 PST 2023


Author: Nikita Popov
Date: 2023-12-20T15:59:02+01:00
New Revision: 8b8f2ef06e341ef634f85fa01800f4e441cacd91

URL: https://github.com/llvm/llvm-project/commit/8b8f2ef06e341ef634f85fa01800f4e441cacd91
DIFF: https://github.com/llvm/llvm-project/commit/8b8f2ef06e341ef634f85fa01800f4e441cacd91.diff

LOG: [MergeFunc] Fix comparison of constant expressions

Functions using different constant expressions were incorrectly
merged, because a lot of state was missing from the comparison,
including the opcode, the comparison predicate, the GEP element
type, as well as the inbounds, inrange and nowrap poison flags.

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/FunctionComparator.cpp
    llvm/test/Transforms/MergeFunc/constexpr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
index 79ca99d1566ce2..09e19be0d293ba 100644
--- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -405,6 +405,8 @@ int FunctionComparator::cmpConstants(const Constant *L,
   case Value::ConstantExprVal: {
     const ConstantExpr *LE = cast<ConstantExpr>(L);
     const ConstantExpr *RE = cast<ConstantExpr>(R);
+    if (int Res = cmpNumbers(LE->getOpcode(), RE->getOpcode()))
+      return Res;
     unsigned NumOperandsL = LE->getNumOperands();
     unsigned NumOperandsR = RE->getNumOperands();
     if (int Res = cmpNumbers(NumOperandsL, NumOperandsR))
@@ -414,6 +416,29 @@ int FunctionComparator::cmpConstants(const Constant *L,
                                  cast<Constant>(RE->getOperand(i))))
         return Res;
     }
+    if (LE->isCompare())
+      if (int Res = cmpNumbers(LE->getPredicate(), RE->getPredicate()))
+        return Res;
+    if (auto *GEPL = dyn_cast<GEPOperator>(LE)) {
+      auto *GEPR = cast<GEPOperator>(RE);
+      if (int Res = cmpTypes(GEPL->getSourceElementType(),
+                             GEPR->getSourceElementType()))
+        return Res;
+      if (int Res = cmpNumbers(GEPL->isInBounds(), GEPR->isInBounds()))
+        return Res;
+      if (int Res = cmpNumbers(GEPL->getInRangeIndex().value_or(unsigned(-1)),
+                               GEPR->getInRangeIndex().value_or(unsigned(-1))))
+        return Res;
+    }
+    if (auto *OBOL = dyn_cast<OverflowingBinaryOperator>(LE)) {
+      auto *OBOR = cast<OverflowingBinaryOperator>(RE);
+      if (int Res =
+              cmpNumbers(OBOL->hasNoUnsignedWrap(), OBOR->hasNoUnsignedWrap()))
+        return Res;
+      if (int Res =
+              cmpNumbers(OBOL->hasNoSignedWrap(), OBOR->hasNoSignedWrap()))
+        return Res;
+    }
     return 0;
   }
   case Value::BlockAddressVal: {

diff  --git a/llvm/test/Transforms/MergeFunc/constexpr.ll b/llvm/test/Transforms/MergeFunc/constexpr.ll
index 7a4823b5c494a7..9fb78060174226 100644
--- a/llvm/test/Transforms/MergeFunc/constexpr.ll
+++ b/llvm/test/Transforms/MergeFunc/constexpr.ll
@@ -7,11 +7,6 @@
 ;.
 ; CHECK: @g1 = external unnamed_addr global i8
 ; CHECK: @g2 = external unnamed_addr global i8
-; CHECK: @f2 = unnamed_addr alias i1 (), ptr @f1
-; CHECK: @f4 = unnamed_addr alias ptr (), ptr @f3
-; CHECK: @f5 = unnamed_addr alias ptr (), ptr @f3
-; CHECK: @f7 = unnamed_addr alias i64 (), ptr @f6
-; CHECK: @f8 = unnamed_addr alias i64 (), ptr @f6
 ;.
 define i1 @f1() unnamed_addr {
 ; CHECK-LABEL: define i1 @f1() unnamed_addr {
@@ -21,6 +16,9 @@ define i1 @f1() unnamed_addr {
 }
 
 define i1 @f2() unnamed_addr {
+; CHECK-LABEL: define i1 @f2() unnamed_addr {
+; CHECK-NEXT:    ret i1 icmp ne (ptr @g1, ptr @g2)
+;
   ret i1 icmp ne (ptr @g1, ptr @g2)
 }
 
@@ -32,10 +30,16 @@ define ptr @f3() unnamed_addr {
 }
 
 define ptr @f4() unnamed_addr {
+; CHECK-LABEL: define ptr @f4() unnamed_addr {
+; CHECK-NEXT:    ret ptr getelementptr (i16, ptr @g1, i64 2)
+;
   ret ptr getelementptr (i16, ptr @g1, i64 2)
 }
 
 define ptr @f5() unnamed_addr {
+; CHECK-LABEL: define ptr @f5() unnamed_addr {
+; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g1, i64 2)
+;
   ret ptr getelementptr (i8, ptr @g1, i64 2)
 }
 
@@ -47,9 +51,36 @@ define i64 @f6() unnamed_addr {
 }
 
 define i64 @f7() unnamed_addr {
+; CHECK-LABEL: define i64 @f7() unnamed_addr {
+; CHECK-NEXT:    ret i64 add (i64 ptrtoint (ptr @g1 to i64), i64 1)
+;
   ret i64 add (i64 ptrtoint (ptr @g1 to i64), i64 1)
 }
 
 define i64 @f8() unnamed_addr {
+; CHECK-LABEL: define i64 @f8() unnamed_addr {
+; CHECK-NEXT:    ret i64 sub (i64 ptrtoint (ptr @g1 to i64), i64 1)
+;
   ret i64 sub (i64 ptrtoint (ptr @g1 to i64), i64 1)
 }
+
+define ptr @f10() unnamed_addr {
+; CHECK-LABEL: define ptr @f10() unnamed_addr {
+; CHECK-NEXT:    ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, inrange i64 1)
+;
+  ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, inrange i64 1)
+}
+
+define ptr @f11() unnamed_addr {
+; CHECK-LABEL: define ptr @f11() unnamed_addr {
+; CHECK-NEXT:    ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, i64 1)
+;
+  ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, i64 1)
+}
+
+define ptr @f12() unnamed_addr {
+; CHECK-LABEL: define ptr @f12() unnamed_addr {
+; CHECK-NEXT:    ret ptr getelementptr ([4 x i32], ptr @g1, inrange i64 0, i64 1)
+;
+  ret ptr getelementptr ([4 x i32], ptr @g1, inrange i64 0, i64 1)
+}


        


More information about the llvm-commits mailing list