6baaad740a
The original fix (commit23ec5782c3
) of https://github.com/llvm/llvm-project/issues/52787 only adds `Function`s that have `Instruction`s that directly use `BlockAddress`es into the bitcode (`FUNC_CODE_BLOCKADDR_USERS`). However, in either @rickyz's original reproducing code: ``` void f(long); __attribute__((noinline)) static void fun(long x) { f(x + 1); } void repro(void) { fun(({ label: (long)&&label; })); } ``` ``` ... define dso_local void @repro() #0 { entry: br label %label label: ; preds = %entry tail call fastcc void @fun() ret void } define internal fastcc void @fun() unnamed_addr #1 { entry: tail call void @f(i64 add (i64 ptrtoint (i8* blockaddress(@repro, %label) to i64), i64 1)) #3 ret void } ... ``` or the xfs and overlayfs in the Linux kernel, `BlockAddress`es (e.g., `i8* blockaddress(@repro, %label)`) may first compose `ConstantExpr`s (e.g., `i64 ptrtoint (i8* blockaddress(@repro, %label) to i64)`) and then used by `Instruction`s. This case is not handled by the original fix. This patch adds *indirect* users of `BlockAddress`es, i.e., the `Instruction`s using some `Constant`s which further use the `BlockAddress`es, into the bitcode as well, by doing depth-first searches. Fixes: https://github.com/llvm/llvm-project/issues/52787 Fixes:23ec5782c3
("[Bitcode] materialize Functions early when BlockAddress taken") Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D124878
39 lines
1.0 KiB
LLVM
39 lines
1.0 KiB
LLVM
; RUN: llvm-as %s -o %t.bc
|
|
; RUN: llvm-bcanalyzer -dump %t.bc | FileCheck %s
|
|
; RUN: llvm-dis %t.bc
|
|
|
|
; There's a curious case where blockaddress constants may refer to functions
|
|
; outside of the function they're used in. There's a special bitcode function
|
|
; code, FUNC_CODE_BLOCKADDR_USERS, used to signify that this is the case.
|
|
|
|
; The intent of this test is two-fold:
|
|
; 1. Ensure we produce BLOCKADDR_USERS bitcode function code on the first fn,
|
|
; @repro, since @fun and @fun2 both refer to @repro via blockaddress
|
|
; constants.
|
|
; 2. Ensure we can round-trip serializing+desearlizing such case.
|
|
|
|
; CHECK: <FUNCTION_BLOCK
|
|
; CHECK: <BLOCKADDR_USERS op0=2 op1=1
|
|
; CHECK: <FUNCTION_BLOCK
|
|
; CHECK: <FUNCTION_BLOCK
|
|
|
|
define void @repro() {
|
|
br label %label
|
|
|
|
label:
|
|
call void @fun()
|
|
ret void
|
|
}
|
|
|
|
define void @fun() noinline {
|
|
call void @f(i64 ptrtoint (i8* blockaddress(@repro, %label) to i64))
|
|
ret void
|
|
}
|
|
|
|
define void @fun2() noinline {
|
|
call void @f(i64 ptrtoint (i8* blockaddress(@repro, %label) to i64))
|
|
ret void
|
|
}
|
|
|
|
declare void @f(i64)
|