Skip to content

Commit eb2f10c

Browse files
nikicMingcongBai
authored andcommitted
[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. (cherry picked from commit 8b8f2ef)
1 parent e1d0445 commit eb2f10c

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

llvm/lib/Transforms/Utils/FunctionComparator.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,8 @@ int FunctionComparator::cmpConstants(const Constant *L,
392392
case Value::ConstantExprVal: {
393393
const ConstantExpr *LE = cast<ConstantExpr>(L);
394394
const ConstantExpr *RE = cast<ConstantExpr>(R);
395+
if (int Res = cmpNumbers(LE->getOpcode(), RE->getOpcode()))
396+
return Res;
395397
unsigned NumOperandsL = LE->getNumOperands();
396398
unsigned NumOperandsR = RE->getNumOperands();
397399
if (int Res = cmpNumbers(NumOperandsL, NumOperandsR))
@@ -401,6 +403,29 @@ int FunctionComparator::cmpConstants(const Constant *L,
401403
cast<Constant>(RE->getOperand(i))))
402404
return Res;
403405
}
406+
if (LE->isCompare())
407+
if (int Res = cmpNumbers(LE->getPredicate(), RE->getPredicate()))
408+
return Res;
409+
if (auto *GEPL = dyn_cast<GEPOperator>(LE)) {
410+
auto *GEPR = cast<GEPOperator>(RE);
411+
if (int Res = cmpTypes(GEPL->getSourceElementType(),
412+
GEPR->getSourceElementType()))
413+
return Res;
414+
if (int Res = cmpNumbers(GEPL->isInBounds(), GEPR->isInBounds()))
415+
return Res;
416+
if (int Res = cmpNumbers(GEPL->getInRangeIndex().value_or(unsigned(-1)),
417+
GEPR->getInRangeIndex().value_or(unsigned(-1))))
418+
return Res;
419+
}
420+
if (auto *OBOL = dyn_cast<OverflowingBinaryOperator>(LE)) {
421+
auto *OBOR = cast<OverflowingBinaryOperator>(RE);
422+
if (int Res =
423+
cmpNumbers(OBOL->hasNoUnsignedWrap(), OBOR->hasNoUnsignedWrap()))
424+
return Res;
425+
if (int Res =
426+
cmpNumbers(OBOL->hasNoSignedWrap(), OBOR->hasNoSignedWrap()))
427+
return Res;
428+
}
404429
return 0;
405430
}
406431
case Value::BlockAddressVal: {

llvm/test/Transforms/MergeFunc/constexpr.ll

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77
;.
88
; CHECK: @g1 = external unnamed_addr global i8
99
; CHECK: @g2 = external unnamed_addr global i8
10-
; CHECK: @f2 = unnamed_addr alias i1 (), ptr @f1
11-
; CHECK: @f4 = unnamed_addr alias ptr (), ptr @f3
12-
; CHECK: @f5 = unnamed_addr alias ptr (), ptr @f3
13-
; CHECK: @f7 = unnamed_addr alias i64 (), ptr @f6
14-
; CHECK: @f8 = unnamed_addr alias i64 (), ptr @f6
1510
;.
1611
define i1 @f1() unnamed_addr {
1712
; CHECK-LABEL: define i1 @f1() unnamed_addr {
@@ -21,6 +16,9 @@ define i1 @f1() unnamed_addr {
2116
}
2217

2318
define i1 @f2() unnamed_addr {
19+
; CHECK-LABEL: define i1 @f2() unnamed_addr {
20+
; CHECK-NEXT: ret i1 icmp ne (ptr @g1, ptr @g2)
21+
;
2422
ret i1 icmp ne (ptr @g1, ptr @g2)
2523
}
2624

@@ -32,10 +30,16 @@ define ptr @f3() unnamed_addr {
3230
}
3331

3432
define ptr @f4() unnamed_addr {
33+
; CHECK-LABEL: define ptr @f4() unnamed_addr {
34+
; CHECK-NEXT: ret ptr getelementptr (i16, ptr @g1, i64 2)
35+
;
3536
ret ptr getelementptr (i16, ptr @g1, i64 2)
3637
}
3738

3839
define ptr @f5() unnamed_addr {
40+
; CHECK-LABEL: define ptr @f5() unnamed_addr {
41+
; CHECK-NEXT: ret ptr getelementptr (i8, ptr @g1, i64 2)
42+
;
3943
ret ptr getelementptr (i8, ptr @g1, i64 2)
4044
}
4145

@@ -47,9 +51,36 @@ define i64 @f6() unnamed_addr {
4751
}
4852

4953
define i64 @f7() unnamed_addr {
54+
; CHECK-LABEL: define i64 @f7() unnamed_addr {
55+
; CHECK-NEXT: ret i64 add (i64 ptrtoint (ptr @g1 to i64), i64 1)
56+
;
5057
ret i64 add (i64 ptrtoint (ptr @g1 to i64), i64 1)
5158
}
5259

5360
define i64 @f8() unnamed_addr {
61+
; CHECK-LABEL: define i64 @f8() unnamed_addr {
62+
; CHECK-NEXT: ret i64 sub (i64 ptrtoint (ptr @g1 to i64), i64 1)
63+
;
5464
ret i64 sub (i64 ptrtoint (ptr @g1 to i64), i64 1)
5565
}
66+
67+
define ptr @f10() unnamed_addr {
68+
; CHECK-LABEL: define ptr @f10() unnamed_addr {
69+
; CHECK-NEXT: ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, inrange i64 1)
70+
;
71+
ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, inrange i64 1)
72+
}
73+
74+
define ptr @f11() unnamed_addr {
75+
; CHECK-LABEL: define ptr @f11() unnamed_addr {
76+
; CHECK-NEXT: ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, i64 1)
77+
;
78+
ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, i64 1)
79+
}
80+
81+
define ptr @f12() unnamed_addr {
82+
; CHECK-LABEL: define ptr @f12() unnamed_addr {
83+
; CHECK-NEXT: ret ptr getelementptr ([4 x i32], ptr @g1, inrange i64 0, i64 1)
84+
;
85+
ret ptr getelementptr ([4 x i32], ptr @g1, inrange i64 0, i64 1)
86+
}

0 commit comments

Comments
 (0)