Currently, LLParser will create a Function/GlobalVariable forward reference based on the desired pointer type and then modify it when it is declared. With opaque pointers, we generally do not know the correct type to use until we see the declaration. Solve this by creating the forward reference with a dummy type, and then performing a RAUW with the correct Function/GlobalVariable when it is declared. The approach is adopted from https://github.com/TNorthover/llvm-project/commit/b5b55963f62038319fa7a8b1b232226ba1d8ef3c. This results in a change to the use list order, which is why we see test changes on some module passes that are not stable under use list reordering. Differential Revision: https://reviews.llvm.org/D104950
57 lines
1.7 KiB
LLVM
57 lines
1.7 KiB
LLVM
; RUN: opt -function-specialization -func-specialization-avg-iters-cost=3 -S < %s | \
|
|
; RUN: FileCheck %s --check-prefixes=COMMON,DISABLED
|
|
; RUN: opt -function-specialization -force-function-specialization -S < %s | \
|
|
; RUN: FileCheck %s --check-prefixes=COMMON,FORCE
|
|
; RUN: opt -function-specialization -func-specialization-avg-iters-cost=3 -force-function-specialization -S < %s | \
|
|
; RUN: FileCheck %s --check-prefixes=COMMON,FORCE
|
|
|
|
; Test for specializing a constant global.
|
|
|
|
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
|
|
|
|
@A = external dso_local constant i32, align 4
|
|
@B = external dso_local constant i32, align 4
|
|
|
|
define dso_local i32 @bar(i32 %x, i32 %y) {
|
|
; COMMON-LABEL: @bar
|
|
; FORCE: %call = call i32 @foo.1(i32 %x, i32* @A)
|
|
; FORCE: %call1 = call i32 @foo.2(i32 %y, i32* @B)
|
|
; DISABLED-NOT: %call1 = call i32 @foo.1(
|
|
entry:
|
|
%tobool = icmp ne i32 %x, 0
|
|
br i1 %tobool, label %if.then, label %if.else
|
|
|
|
if.then:
|
|
%call = call i32 @foo(i32 %x, i32* @A)
|
|
br label %return
|
|
|
|
if.else:
|
|
%call1 = call i32 @foo(i32 %y, i32* @B)
|
|
br label %return
|
|
|
|
return:
|
|
%retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
|
|
ret i32 %retval.0
|
|
}
|
|
|
|
; FORCE: define internal i32 @foo.1(i32 %x, i32* %b) {
|
|
; FORCE-NEXT: entry:
|
|
; FORCE-NEXT: %0 = load i32, i32* @A, align 4
|
|
; FORCE-NEXT: %add = add nsw i32 %x, %0
|
|
; FORCE-NEXT: ret i32 %add
|
|
; FORCE-NEXT: }
|
|
|
|
; FORCE: define internal i32 @foo.2(i32 %x, i32* %b) {
|
|
; FORCE-NEXT: entry:
|
|
; FORCE-NEXT: %0 = load i32, i32* @B, align 4
|
|
; FORCE-NEXT: %add = add nsw i32 %x, %0
|
|
; FORCE-NEXT: ret i32 %add
|
|
; FORCE-NEXT: }
|
|
|
|
define internal i32 @foo(i32 %x, i32* %b) {
|
|
entry:
|
|
%0 = load i32, i32* %b, align 4
|
|
%add = add nsw i32 %x, %0
|
|
ret i32 %add
|
|
}
|