Skip to content

Commit 8b8f2ef

Browse files
committed
[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.
1 parent 6cd296e commit 8b8f2ef

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
@@ -405,6 +405,8 @@ int FunctionComparator::cmpConstants(const Constant *L,
405405
case Value::ConstantExprVal: {
406406
const ConstantExpr *LE = cast<ConstantExpr>(L);
407407
const ConstantExpr *RE = cast<ConstantExpr>(R);
408+
if (int Res = cmpNumbers(LE->getOpcode(), RE->getOpcode()))
409+
return Res;
408410
unsigned NumOperandsL = LE->getNumOperands();
409411
unsigned NumOperandsR = RE->getNumOperands();
410412
if (int Res = cmpNumbers(NumOperandsL, NumOperandsR))
@@ -414,6 +416,29 @@ int FunctionComparator::cmpConstants(const Constant *L,
414416
cast<Constant>(RE->getOperand(i))))
415417
return Res;
416418
}
419+
if (LE->isCompare())
420+
if (int Res = cmpNumbers(LE->getPredicate(), RE->getPredicate()))
421+
return Res;
422+
if (auto *GEPL = dyn_cast<GEPOperator>(LE)) {
423+
auto *GEPR = cast<GEPOperator>(RE);
424+
if (int Res = cmpTypes(GEPL->getSourceElementType(),
425+
GEPR->getSourceElementType()))
426+
return Res;
427+
if (int Res = cmpNumbers(GEPL->isInBounds(), GEPR->isInBounds()))
428+
return Res;
429+
if (int Res = cmpNumbers(GEPL->getInRangeIndex().value_or(unsigned(-1)),
430+
GEPR->getInRangeIndex().value_or(unsigned(-1))))
431+
return Res;
432+
}
433+
if (auto *OBOL = dyn_cast<OverflowingBinaryOperator>(LE)) {
434+
auto *OBOR = cast<OverflowingBinaryOperator>(RE);
435+
if (int Res =
436+
cmpNumbers(OBOL->hasNoUnsignedWrap(), OBOR->hasNoUnsignedWrap()))
437+
return Res;
438+
if (int Res =
439+
cmpNumbers(OBOL->hasNoSignedWrap(), OBOR->hasNoSignedWrap()))
440+
return Res;
441+
}
417442
return 0;
418443
}
419444
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)