Skip to content

Commit cd4ebb2

Browse files
aeubankststellar
authored andcommitted
[LazyCallGraph] Skip blockaddresses
blockaddresses do not participate in the call graph since the only instructions that use them must all return to someplace within the current function. And passes cannot retrieve a function address from a blockaddress. This was suggested by efriedma in D58260. Fixes PR50881. Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D112178 (cherry picked from commit 029f1a5)
1 parent d4a57c8 commit cd4ebb2

File tree

5 files changed

+61
-64
lines changed

5 files changed

+61
-64
lines changed

llvm/include/llvm/Analysis/LazyCallGraph.h

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,28 +1098,10 @@ class LazyCallGraph {
10981098
continue;
10991099
}
11001100

1101-
// The blockaddress constant expression is a weird special case, we can't
1102-
// generically walk its operands the way we do for all other constants.
1103-
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
1104-
// If we've already visited the function referred to by the block
1105-
// address, we don't need to revisit it.
1106-
if (Visited.count(BA->getFunction()))
1107-
continue;
1108-
1109-
// If all of the blockaddress' users are instructions within the
1110-
// referred to function, we don't need to insert a cycle.
1111-
if (llvm::all_of(BA->users(), [&](User *U) {
1112-
if (Instruction *I = dyn_cast<Instruction>(U))
1113-
return I->getFunction() == BA->getFunction();
1114-
return false;
1115-
}))
1116-
continue;
1117-
1118-
// Otherwise we should go visit the referred to function.
1119-
Visited.insert(BA->getFunction());
1120-
Worklist.push_back(BA->getFunction());
1101+
// blockaddresses are weird and don't participate in the call graph anyway,
1102+
// skip them.
1103+
if (isa<BlockAddress>(C))
11211104
continue;
1122-
}
11231105

11241106
for (Value *Op : C->operand_values())
11251107
if (Visited.insert(cast<Constant>(Op)).second)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -passes="cgscc(function(sccp,simplifycfg))" < %s -S | FileCheck %s
3+
4+
define i32 @baz(i32 %y, i1 %b) {
5+
; CHECK-LABEL: @baz(
6+
; CHECK-NEXT: entry:
7+
; CHECK-NEXT: br i1 [[B:%.*]], label [[LAB:%.*]], label [[FOR_COND:%.*]]
8+
; CHECK: for.cond:
9+
; CHECK-NEXT: [[P_0:%.*]] = phi i8* [ null, [[FOR_COND]] ], [ blockaddress(@baz, [[LAB]]), [[ENTRY:%.*]] ]
10+
; CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i8, i8* [[P_0]], i64 1
11+
; CHECK-NEXT: br label [[FOR_COND]]
12+
; CHECK: lab:
13+
; CHECK-NEXT: ret i32 0
14+
;
15+
entry:
16+
br i1 %b, label %lab, label %for.cond.preheader
17+
18+
for.cond.preheader:
19+
br label %for.cond
20+
21+
for.cond:
22+
%p.0 = phi i8* [ null, %for.cond ], [ blockaddress(@baz, %lab), %for.cond.preheader ]
23+
%incdec.ptr = getelementptr inbounds i8, i8* %p.0, i64 1
24+
br label %for.cond
25+
26+
lab:
27+
ret i32 0
28+
}

llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,37 +34,23 @@ entry:
3434
}
3535

3636
define internal void @bar(i32* nocapture %pc) nounwind readonly {
37-
; IS__CGSCC_OPM: Function Attrs: nounwind readonly
38-
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar
39-
; IS__CGSCC_OPM-SAME: (i32* nocapture [[PC:%.*]]) #[[ATTR1:[0-9]+]] {
40-
; IS__CGSCC_OPM-NEXT: entry:
41-
; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO:%.*]]
42-
; IS__CGSCC_OPM: lab0:
43-
; IS__CGSCC_OPM-NEXT: [[INDVAR_NEXT:%.*]] = add i32 [[INDVAR:%.*]], 1
44-
; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO]]
45-
; IS__CGSCC_OPM: end:
46-
; IS__CGSCC_OPM-NEXT: ret void
47-
; IS__CGSCC_OPM: indirectgoto:
48-
; IS__CGSCC_OPM-NEXT: [[INDVAR]] = phi i32 [ [[INDVAR_NEXT]], [[LAB0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
49-
; IS__CGSCC_OPM-NEXT: [[PC_ADDR_0:%.*]] = getelementptr i32, i32* [[PC]], i32 [[INDVAR]]
50-
; IS__CGSCC_OPM-NEXT: [[TMP1_PN:%.*]] = load i32, i32* [[PC_ADDR_0]], align 4
51-
; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST_IN:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @bar.l, i32 0, i32 [[TMP1_PN]]
52-
; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST:%.*]] = load i8*, i8** [[INDIRECT_GOTO_DEST_IN]], align 8
53-
; IS__CGSCC_OPM-NEXT: indirectbr i8* [[INDIRECT_GOTO_DEST]], [label [[LAB0]], label %end]
54-
;
55-
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone
56-
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar
57-
; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
58-
; IS__CGSCC_NPM-NEXT: entry:
59-
; IS__CGSCC_NPM-NEXT: br label [[INDIRECTGOTO:%.*]]
60-
; IS__CGSCC_NPM: lab0:
61-
; IS__CGSCC_NPM-NEXT: [[INDVAR_NEXT:%.*]] = add i32 [[INDVAR:%.*]], 1
62-
; IS__CGSCC_NPM-NEXT: br label [[INDIRECTGOTO]]
63-
; IS__CGSCC_NPM: end:
64-
; IS__CGSCC_NPM-NEXT: ret void
65-
; IS__CGSCC_NPM: indirectgoto:
66-
; IS__CGSCC_NPM-NEXT: [[INDVAR]] = phi i32 [ [[INDVAR_NEXT]], [[LAB0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
67-
; IS__CGSCC_NPM-NEXT: indirectbr i8* undef, [label [[LAB0]], label %end]
37+
; IS__CGSCC____: Function Attrs: nounwind readonly
38+
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
39+
; IS__CGSCC____-SAME: (i32* nocapture [[PC:%.*]]) #[[ATTR1:[0-9]+]] {
40+
; IS__CGSCC____-NEXT: entry:
41+
; IS__CGSCC____-NEXT: br label [[INDIRECTGOTO:%.*]]
42+
; IS__CGSCC____: lab0:
43+
; IS__CGSCC____-NEXT: [[INDVAR_NEXT:%.*]] = add i32 [[INDVAR:%.*]], 1
44+
; IS__CGSCC____-NEXT: br label [[INDIRECTGOTO]]
45+
; IS__CGSCC____: end:
46+
; IS__CGSCC____-NEXT: ret void
47+
; IS__CGSCC____: indirectgoto:
48+
; IS__CGSCC____-NEXT: [[INDVAR]] = phi i32 [ [[INDVAR_NEXT]], [[LAB0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
49+
; IS__CGSCC____-NEXT: [[PC_ADDR_0:%.*]] = getelementptr i32, i32* [[PC]], i32 [[INDVAR]]
50+
; IS__CGSCC____-NEXT: [[TMP1_PN:%.*]] = load i32, i32* [[PC_ADDR_0]], align 4
51+
; IS__CGSCC____-NEXT: [[INDIRECT_GOTO_DEST_IN:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @bar.l, i32 0, i32 [[TMP1_PN]]
52+
; IS__CGSCC____-NEXT: [[INDIRECT_GOTO_DEST:%.*]] = load i8*, i8** [[INDIRECT_GOTO_DEST_IN]], align 8
53+
; IS__CGSCC____-NEXT: indirectbr i8* [[INDIRECT_GOTO_DEST]], [label [[LAB0]], label %end]
6854
;
6955
entry:
7056
br label %indirectgoto
@@ -104,11 +90,7 @@ entry:
10490
;.
10591
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
10692
;.
107-
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nounwind readnone }
108-
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nounwind readonly }
109-
; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn }
110-
;.
111-
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nounwind readnone }
112-
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone }
113-
; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn }
93+
; IS__CGSCC____: attributes #[[ATTR0]] = { nounwind readnone }
94+
; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind readonly }
95+
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn }
11496
;.

llvm/test/Transforms/Attributor/liveness.ll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,9 +2432,9 @@ define internal void @dead_with_blockaddress_users(i32* nocapture %pc) nounwind
24322432
; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST:%.*]] = load i8*, i8** [[INDIRECT_GOTO_DEST_IN]]
24332433
; IS__CGSCC_OPM-NEXT: indirectbr i8* [[INDIRECT_GOTO_DEST]], [label [[LAB0]], label %end]
24342434
;
2435-
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
2435+
; IS__CGSCC____: Function Attrs: nounwind readonly
24362436
; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_with_blockaddress_users
2437-
; IS__CGSCC____-SAME: () #[[ATTR14:[0-9]+]] {
2437+
; IS__CGSCC____-SAME: (i32* nocapture [[PC:%.*]]) #[[ATTR14:[0-9]+]] {
24382438
; IS__CGSCC____-NEXT: entry:
24392439
; IS__CGSCC____-NEXT: br label [[INDIRECTGOTO:%.*]]
24402440
; IS__CGSCC____: lab0:
@@ -2444,7 +2444,11 @@ define internal void @dead_with_blockaddress_users(i32* nocapture %pc) nounwind
24442444
; IS__CGSCC____-NEXT: ret void
24452445
; IS__CGSCC____: indirectgoto:
24462446
; IS__CGSCC____-NEXT: [[INDVAR]] = phi i32 [ [[INDVAR_NEXT]], [[LAB0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
2447-
; IS__CGSCC____-NEXT: indirectbr i8* undef, [label [[LAB0]], label %end]
2447+
; IS__CGSCC____-NEXT: [[PC_ADDR_0:%.*]] = getelementptr i32, i32* [[PC]], i32 [[INDVAR]]
2448+
; IS__CGSCC____-NEXT: [[TMP1_PN:%.*]] = load i32, i32* [[PC_ADDR_0]], align 4
2449+
; IS__CGSCC____-NEXT: [[INDIRECT_GOTO_DEST_IN:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @dead_with_blockaddress_users.l, i32 0, i32 [[TMP1_PN]]
2450+
; IS__CGSCC____-NEXT: [[INDIRECT_GOTO_DEST:%.*]] = load i8*, i8** [[INDIRECT_GOTO_DEST_IN]], align 8
2451+
; IS__CGSCC____-NEXT: indirectbr i8* [[INDIRECT_GOTO_DEST]], [label [[LAB0]], label %end]
24482452
;
24492453
entry:
24502454
br label %indirectgoto
@@ -2655,7 +2659,7 @@ declare void @llvm.lifetime.end.p0i8(i64 %0, i8* %1)
26552659
; IS__CGSCC____: attributes #[[ATTR11]] = { nofree norecurse noreturn nosync nounwind readnone }
26562660
; IS__CGSCC____: attributes #[[ATTR12]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
26572661
; IS__CGSCC____: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn }
2658-
; IS__CGSCC____: attributes #[[ATTR14]] = { nofree norecurse nosync nounwind readnone }
2662+
; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind readonly }
26592663
; IS__CGSCC____: attributes #[[ATTR15]] = { nofree nosync nounwind readnone willreturn }
26602664
; IS__CGSCC____: attributes #[[ATTR16:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
26612665
; IS__CGSCC____: attributes #[[ATTR17]] = { nounwind willreturn }

llvm/unittests/Analysis/LazyCallGraphTest.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1978,7 +1978,8 @@ TEST(LazyCallGraphTest, HandleBlockAddress) {
19781978
LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
19791979
EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
19801980
EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
1981-
EXPECT_TRUE(GRC.isParentOf(FRC));
1981+
EXPECT_FALSE(GRC.isParentOf(FRC));
1982+
EXPECT_FALSE(FRC.isParentOf(GRC));
19821983
}
19831984

19841985
// Test that a blockaddress that refers to itself creates no new RefSCC

0 commit comments

Comments
 (0)