Skip to content

Commit

Permalink
[MergeFunc] Fix comparison of constant expressions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Dec 20, 2023
1 parent 6cd296e commit 8b8f2ef
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
25 changes: 25 additions & 0 deletions llvm/lib/Transforms/Utils/FunctionComparator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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: {
Expand Down
41 changes: 36 additions & 5 deletions llvm/test/Transforms/MergeFunc/constexpr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
}

Expand All @@ -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)
}

Expand All @@ -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)
}

0 comments on commit 8b8f2ef

Please sign in to comment.