Skip to content

Commit ae6a5c1

Browse files
committed
llvm-reduce: Fix assertion on blockaddress during function reduction
Just avoid crashing for now, we should be able to replace the blockaddresses themselves. BlockAddress::handleOperandChangeImpl assumes it can cast to Function. The verifier seems nonexistent and the langref isn't particularly explicit on what's allowed as a blockaddress operand. As far as I can tell bugpoint isn't doing anything to handle this. Something low level is broken with BlockAddress handling, demonstrated by reduce-functions-blockaddress-wrong-function.ll. The BasicBlock destructor of the deleted function is triggering replacement of blockaddresses for the kept function in some cases. I've only half debugged this but it seems like blockaddress is handled too-specially compared to other Constants. I have tentative patches to allow any constant to be a blockaddress input, but having the verifier check if it's really a function/block. https://reviews.llvm.org/D140909
1 parent 2d6e280 commit ae6a5c1

File tree

5 files changed

+94
-1
lines changed

5 files changed

+94
-1
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llvm-reduce --delta-passes=functions --test FileCheck --test-arg --check-prefixes=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
2+
; RUN: FileCheck --check-prefixes=RESULT --input-file=%t %s
3+
4+
; FIXME: This testcase exhibits nonsensical behavior. The first
5+
; function has blockaddress references. When the second function is
6+
; deleted, it causes the blockreferences from the first to be replaced
7+
; with inttoptr.
8+
9+
; INTERESTING: @blockaddr.table.other
10+
11+
; RESULT: @blockaddr.table.other = private unnamed_addr constant [2 x ptr] [ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr)]
12+
13+
@blockaddr.table.other = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@bar, %L1), ptr blockaddress(@bar, %L2)]
14+
15+
16+
; RESULT: define i32 @bar(
17+
define i32 @bar(i64 %arg0) {
18+
entry:
19+
%gep = getelementptr inbounds [2 x ptr], ptr @blockaddr.table.other, i64 0, i64 %arg0
20+
%load = load ptr, ptr %gep, align 8
21+
indirectbr ptr %load, [label %L2, label %L1]
22+
23+
L1:
24+
%phi = phi i32 [ 1, %L2 ], [ 2, %entry ]
25+
ret i32 %phi
26+
27+
L2:
28+
br label %L1
29+
}
30+
31+
; RESULT-NOT: @unused
32+
define void @unused() {
33+
entry:
34+
br label %exit
35+
36+
exit:
37+
ret void
38+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; RUN: llvm-reduce --delta-passes=functions --test FileCheck --test-arg --check-prefixes=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
2+
; RUN: FileCheck --check-prefixes=RESULT --input-file=%t %s
3+
4+
; Make sure we don't crash on blockaddress
5+
; TODO: Should be able to replace the blockaddresses with null too
6+
7+
; INTERESTING: @blockaddr.table
8+
; INTERESTING: @blockaddr.table.addrspacecast
9+
10+
; RESULT: @blockaddr.table = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@foo, %L1), ptr blockaddress(@foo, %L2)]
11+
; RESULT: @blockaddr.table.addrspacecast = private unnamed_addr constant [2 x ptr addrspace(1)] [ptr addrspace(1) addrspacecast (ptr blockaddress(@foo_addrspacecast, %L1) to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr blockaddress(@foo_addrspacecast, %L2) to ptr addrspace(1))]
12+
13+
@blockaddr.table = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@foo, %L1), ptr blockaddress(@foo, %L2)]
14+
15+
@blockaddr.table.addrspacecast = private unnamed_addr constant [2 x ptr addrspace(1)] [
16+
ptr addrspace(1) addrspacecast (ptr blockaddress(@foo_addrspacecast, %L1) to ptr addrspace(1)),
17+
ptr addrspace(1) addrspacecast (ptr blockaddress(@foo_addrspacecast, %L2) to ptr addrspace(1))
18+
]
19+
20+
; RESULT: define i32 @foo(
21+
define i32 @foo(i64 %arg0) {
22+
entry:
23+
%gep = getelementptr inbounds [2 x ptr], ptr @blockaddr.table, i64 0, i64 %arg0
24+
%load = load ptr, ptr %gep, align 8
25+
indirectbr ptr %load, [label %L2, label %L1]
26+
27+
L1:
28+
%phi = phi i32 [ 1, %L2 ], [ 2, %entry ]
29+
ret i32 %phi
30+
31+
L2:
32+
br label %L1
33+
}
34+
35+
; RESULT: define i32 @foo_addrspacecast(
36+
define i32 @foo_addrspacecast(i64 %arg0) {
37+
entry:
38+
%gep = getelementptr inbounds [2 x ptr addrspace(1)], ptr @blockaddr.table.addrspacecast, i64 0, i64 %arg0
39+
%load = load ptr addrspace(1), ptr %gep, align 8
40+
indirectbr ptr addrspace(1) %load, [label %L2, label %L1]
41+
42+
L1:
43+
%phi = phi i32 [ 1, %L2 ], [ 2, %entry ]
44+
ret i32 %phi
45+
46+
L2:
47+
br label %L1
48+
}

llvm/tools/llvm-reduce/deltas/ReduceFunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static void extractFunctionsFromModule(Oracle &O, Module &Program) {
3232
// Intrinsics don't have function bodies that are useful to
3333
// reduce. Additionally, intrinsics may have additional operand
3434
// constraints. But, do drop intrinsics that are not referenced.
35-
if ((!F.isIntrinsic() || F.use_empty()) && !hasAliasUse(F) &&
35+
if ((!F.isIntrinsic() || F.use_empty()) && !hasAliasOrBlockAddressUse(F) &&
3636
!O.shouldKeep())
3737
FuncsToRemove.insert(&F);
3838
}

llvm/tools/llvm-reduce/deltas/Utils.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@ bool llvm::hasAliasUse(Function &F) {
3232
return isa<GlobalAlias>(U) || isa<GlobalIFunc>(U);
3333
});
3434
}
35+
36+
bool llvm::hasAliasOrBlockAddressUse(Function &F) {
37+
return any_of(F.users(), [](User *U) {
38+
return isa<GlobalAlias, GlobalIFunc, BlockAddress>(U);
39+
});
40+
}

llvm/tools/llvm-reduce/deltas/Utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ extern cl::opt<bool> Verbose;
2323

2424
Value *getDefaultValue(Type *T);
2525
bool hasAliasUse(Function &F);
26+
bool hasAliasOrBlockAddressUse(Function &F);
2627

2728
} // namespace llvm
2829

0 commit comments

Comments
 (0)