Files
clang-p2996/llvm/test/CodeGen/AMDGPU/remove-incompatible-functions.ll
pvanhout 8e68c12045 [AMDGPU] Remove function with incompatible features
Adds a new pass that removes functions
if they use features that are not supported on the current GPU.

This change is aimed at preventing crashes when building code at O0 that
uses idioms such as `if (ISA_VERSION >= N) intrinsic_a(); else intrinsic_b();`
where ISA_VERSION is not constexpr, and intrinsic_a is not selectable
on older targets.
This is a pattern that's used all over the ROCm device libs. The main
motive behind this change is to allow code using ROCm device libs
to be built at O0.

Note: the feature checking logic is done ad-hoc in the pass. There is no other
pass that needs (or will need in the foreseeable future) to do similar
feature-checking logic so I did not see a need to generalize the feature
checking logic yet. It can (and should probably) be generalized later and
moved to a TargetInfo-like class or helper file.

Reviewed By: arsenm, Joe_Nash

Differential Revision: https://reviews.llvm.org/D139000
2023-02-21 10:42:39 +01:00

456 lines
19 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -march=amdgcn -mcpu=bonaire -stop-after=amdgpu-remove-incompatible-functions < %s 2>%t | FileCheck -check-prefixes=GFX7,IR %s
; RUN: FileCheck --check-prefix=WARN-GFX7 %s < %t
; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s
; RUN: llc -march=amdgcn -mcpu=fiji -stop-after=amdgpu-remove-incompatible-functions < %s 2>%t | FileCheck -check-prefixes=GFX8,IR %s
; RUN: FileCheck --check-prefix=WARN-GFX8 %s < %t
; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s
; RUN: llc -march=amdgcn -mcpu=gfx906 -stop-after=amdgpu-remove-incompatible-functions < %s 2>%t | FileCheck -check-prefixes=GFX9,GFX906,IR %s
; RUN: FileCheck --check-prefix=WARN-GFX906 %s < %t
; RUN: llc -march=amdgcn -mcpu=gfx906 -verify-machineinstrs < %s
; RUN: llc -march=amdgcn -mcpu=gfx90a -stop-after=amdgpu-remove-incompatible-functions < %s 2>%t | FileCheck -check-prefixes=GFX9,GFX90A,IR %s
; RUN: FileCheck --check-prefix=WARN-GFX90A %s < %t
; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs < %s
; RUN: llc -march=amdgcn -mcpu=gfx1011 -stop-after=amdgpu-remove-incompatible-functions < %s 2>%t | FileCheck -check-prefixes=GFX10,IR %s
; RUN: FileCheck --check-prefix=WARN-GFX10 %s < %t
; RUN: llc -march=amdgcn -mcpu=gfx1011 -verify-machineinstrs < %s
; RUN: llc -march=amdgcn -mcpu=gfx1100 -stop-after=amdgpu-remove-incompatible-functions < %s 2>%t | FileCheck -check-prefixes=GFX11,IR %s
; RUN: FileCheck --check-prefix=WARN-GFX11 %s < %t
; RUN: llc -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs < %s
; Note: This test checks the IR, but also has a run line to codegen the file just to check we
; do not crash when trying to select those functions.
; WARN-GFX7: needs_dpp: removing function: +dpp is not supported on the current target
; WARN-GFX7: needs_16bit_insts: removing function: +16-bit-insts is not supported on the current target
; WARN-GFX7: needs_gfx8_insts: removing function: +gfx8-insts is not supported on the current target
; WARN-GFX7: needs_gfx9_insts: removing function: +gfx9-insts is not supported on the current target
; WARN-GFX7: needs_gfx10_insts: removing function: +gfx10-insts is not supported on the current target
; WARN-GFX7: needs_gfx11_insts: removing function: +gfx11-insts is not supported on the current target
; WARN-GFX7: needs_dot1_insts: removing function: +dot1-insts is not supported on the current target
; WARN-GFX7: needs_dot2_insts: removing function: +dot2-insts is not supported on the current target
; WARN-GFX7: needs_dot3_insts: removing function: +dot3-insts is not supported on the current target
; WARN-GFX7: needs_dot4_insts: removing function: +dot4-insts is not supported on the current target
; WARN-GFX7: needs_dot5_insts: removing function: +dot5-insts is not supported on the current target
; WARN-GFX7: needs_dot6_insts: removing function: +dot6-insts is not supported on the current target
; WARN-GFX7: needs_dot7_insts: removing function: +dot7-insts is not supported on the current target
; WARN-GFX7: needs_dot8_insts: removing function: +dot8-insts is not supported on the current target
; WARN-GFX7-NOT: not supported
; WARN-GFX8: needs_gfx9_insts: removing function: +gfx9-insts is not supported on the current target
; WARN-GFX8: needs_gfx10_insts: removing function: +gfx10-insts is not supported on the current target
; WARN-GFX8: needs_gfx11_insts: removing function: +gfx11-insts is not supported on the current target
; WARN-GFX8: needs_dot1_insts: removing function: +dot1-insts is not supported on the current target
; WARN-GFX8: needs_dot2_insts: removing function: +dot2-insts is not supported on the current target
; WARN-GFX8: needs_dot3_insts: removing function: +dot3-insts is not supported on the current target
; WARN-GFX8: needs_dot4_insts: removing function: +dot4-insts is not supported on the current target
; WARN-GFX8: needs_dot5_insts: removing function: +dot5-insts is not supported on the current target
; WARN-GFX8: needs_dot6_insts: removing function: +dot6-insts is not supported on the current target
; WARN-GFX8: needs_dot7_insts: removing function: +dot7-insts is not supported on the current target
; WARN-GFX8: needs_dot8_insts: removing function: +dot8-insts is not supported on the current target
; WARN-GFX8-NOT: not supported
; WARN-GFX906: needs_gfx10_insts: removing function: +gfx10-insts is not supported on the current target
; WARN-GFX906: needs_gfx11_insts: removing function: +gfx11-insts is not supported on the current target
; WARN-GFX906: needs_dot3_insts: removing function: +dot3-insts is not supported on the current target
; WARN-GFX906: needs_dot4_insts: removing function: +dot4-insts is not supported on the current target
; WARN-GFX906: needs_dot5_insts: removing function: +dot5-insts is not supported on the current target
; WARN-GFX906: needs_dot6_insts: removing function: +dot6-insts is not supported on the current target
; WARN-GFX906: needs_dot8_insts: removing function: +dot8-insts is not supported on the current target
; WARN-GFX906-NOT: not supported
; WARN-GFX90A: needs_gfx10_insts: removing function: +gfx10-insts is not supported on the current target
; WARN-GFX90A: needs_gfx11_insts: removing function: +gfx11-insts is not supported on the current target
; WARN-GFX90A: needs_dot8_insts: removing function: +dot8-insts is not supported on the current target
; WARN-GFX90A-NOT: not supported
; WARN-GFX10: needs_gfx11_insts: removing function: +gfx11-insts is not supported on the current target
; WARN-GFX10: needs_dot3_insts: removing function: +dot3-insts is not supported on the current target
; WARN-GFX10: needs_dot4_insts: removing function: +dot4-insts is not supported on the current target
; WARN-GFX10: needs_dot8_insts: removing function: +dot8-insts is not supported on the current target
; WARN-GFX10-NOT: not supported
; WARN-GFX11: needs_dot1_insts: removing function: +dot1-insts is not supported on the current target
; WARN-GFX11: needs_dot2_insts: removing function: +dot2-insts is not supported on the current target
; WARN-GFX11: needs_dot3_insts: removing function: +dot3-insts is not supported on the current target
; WARN-GFX11: needs_dot4_insts: removing function: +dot4-insts is not supported on the current target
; WARN-GFX11: needs_dot6_insts: removing function: +dot6-insts is not supported on the current target
; WARN-GFX11-NOT: not supported
; GFX7: @GVRefs {{.*}} zeroinitializer
; GFX8: @GVRefs {{.*}} [ptr @needs_dpp, ptr @needs_16bit_insts, ptr @needs_gfx8_insts, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null]
; GFX906: @GVRefs {{.*}} [ptr @needs_dpp, ptr @needs_16bit_insts, ptr @needs_gfx8_insts, ptr @needs_gfx9_insts, ptr null, ptr null, ptr @needs_dot1_insts, ptr @needs_dot2_insts, ptr null, ptr null, ptr null, ptr null, ptr @needs_dot7_insts, ptr null]
; GFX90A: @GVRefs {{.*}} [ptr @needs_dpp, ptr @needs_16bit_insts, ptr @needs_gfx8_insts, ptr @needs_gfx9_insts, ptr null, ptr null, ptr @needs_dot1_insts, ptr @needs_dot2_insts, ptr @needs_dot3_insts, ptr @needs_dot4_insts, ptr @needs_dot5_insts, ptr @needs_dot6_insts, ptr @needs_dot7_insts, ptr null]
; GFX10: @GVRefs {{.*}} [ptr @needs_dpp, ptr @needs_16bit_insts, ptr @needs_gfx8_insts, ptr @needs_gfx9_insts, ptr @needs_gfx10_insts, ptr null, ptr @needs_dot1_insts, ptr @needs_dot2_insts, ptr null, ptr null, ptr @needs_dot5_insts, ptr @needs_dot6_insts, ptr @needs_dot7_insts, ptr null]
; GFX11: @GVRefs {{.*}} [ptr @needs_dpp, ptr @needs_16bit_insts, ptr @needs_gfx8_insts, ptr @needs_gfx9_insts, ptr @needs_gfx10_insts, ptr @needs_gfx11_insts, ptr null, ptr null, ptr null, ptr null, ptr @needs_dot5_insts, ptr null, ptr @needs_dot7_insts, ptr @needs_dot8_insts]
@GVRefs = internal global [14 x ptr] [
ptr @needs_dpp,
ptr @needs_16bit_insts,
ptr @needs_gfx8_insts,
ptr @needs_gfx9_insts,
ptr @needs_gfx10_insts,
ptr @needs_gfx11_insts,
ptr @needs_dot1_insts,
ptr @needs_dot2_insts,
ptr @needs_dot3_insts,
ptr @needs_dot4_insts,
ptr @needs_dot5_insts,
ptr @needs_dot6_insts,
ptr @needs_dot7_insts,
ptr @needs_dot8_insts
]
; GFX7: @ConstantExpr = internal global i64 0
@ConstantExpr = internal global i64 ptrtoint (ptr @needs_dpp to i64)
define void @needs_dpp(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #0 {
; GFX7-NOT: define void @needs_dpp(
; GFX8: define void @needs_dpp(
; GFX9: define void @needs_dpp(
; GFX10: define void @needs_dpp(
; GFX11: define void @needs_dpp(
entry:
%cmp = icmp eq i64 %a, 0
br i1 %cmp, label %if, label %else
if:
%ld = load i64, ptr %in
br label %endif
else:
%add = add i64 %a, %b
br label %endif
endif:
%phi = phi i64 [%ld, %if], [%add, %else]
store i64 %phi, ptr %out
ret void
}
define void @needs_16bit_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #1 {
; GFX7-NOT: define void @needs_16bit_insts(
; GFX8: define void @needs_16bit_insts(
; GFX9: define void @needs_16bit_insts(
; GFX10: define void @needs_16bit_insts(
; GFX11: define void @needs_16bit_insts(
entry:
%cmp = icmp eq i64 %a, 0
br i1 %cmp, label %if, label %else
if:
%ld = load i64, ptr %in
br label %endif
else:
%add = add i64 %a, %b
br label %endif
endif:
%phi = phi i64 [%ld, %if], [%add, %else]
store i64 %phi, ptr %out
ret void
}
define void @needs_gfx8_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #2 {
; GFX7-NOT: define void @needs_gfx8_insts(
; GFX8: define void @needs_gfx8_insts(
; GFX9: define void @needs_gfx8_insts(
; GFX10: define void @needs_gfx8_insts(
; GFX11: define void @needs_gfx8_insts(
entry:
%cmp = icmp eq i64 %a, 0
br i1 %cmp, label %if, label %else
if:
%ld = load i64, ptr %in
br label %endif
else:
%add = add i64 %a, %b
br label %endif
endif:
%phi = phi i64 [%ld, %if], [%add, %else]
store i64 %phi, ptr %out
ret void
}
define void @needs_gfx9_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #3 {
; GFX7-NOT: define void @needs_gfx9_insts(
; GFX8-NOT: define void @needs_gfx9_insts(
; GFX9: define void @needs_gfx9_insts(
; GFX10: define void @needs_gfx9_insts(
; GFX11: define void @needs_gfx9_insts(
entry:
%cmp = icmp eq i64 %a, 0
br i1 %cmp, label %if, label %else
if:
%ld = load i64, ptr %in
br label %endif
else:
%add = add i64 %a, %b
br label %endif
endif:
%phi = phi i64 [%ld, %if], [%add, %else]
store i64 %phi, ptr %out
ret void
}
define void @needs_gfx10_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #4 {
; GFX7-NOT: define void @needs_gfx10_insts(
; GFX8-NOT: define void @needs_gfx10_insts(
; GFX9-NOT: define void @needs_gfx10_insts(
; GFX10: define void @needs_gfx10_insts(
; GFX11: define void @needs_gfx10_insts(
entry:
%cmp = icmp eq i64 %a, 0
br i1 %cmp, label %if, label %else
if:
%ld = load i64, ptr %in
br label %endif
else:
%add = add i64 %a, %b
br label %endif
endif:
%phi = phi i64 [%ld, %if], [%add, %else]
store i64 %phi, ptr %out
ret void
}
define void @needs_gfx11_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #5 {
; GFX7-NOT: define void @needs_gfx11_insts(
; GFX8-NOT: define void @needs_gfx11_insts(
; GFX9-NOT: define void @needs_gfx11_insts(
; GFX10-NOT: define void @needs_gfx11_insts(
; GFX11: define void @needs_gfx11_insts(
entry:
%cmp = icmp eq i64 %a, 0
br i1 %cmp, label %if, label %else
if:
%ld = load i64, ptr %in
br label %endif
else:
%add = add i64 %a, %b
br label %endif
endif:
%phi = phi i64 [%ld, %if], [%add, %else]
store i64 %phi, ptr %out
ret void
}
define void @needs_dot1_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #6 {
; GFX7-NOT: define void @needs_dot1_insts(
; GFX8-NOT: define void @needs_dot1_insts(
; GFX9: define void @needs_dot1_insts(
; GFX10: define void @needs_dot1_insts(
; GFX11-NOT: define void @needs_dot1_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
define void @needs_dot2_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #7 {
; GFX7-NOT: define void @needs_dot2_insts(
; GFX8-NOT: define void @needs_dot2_insts(
; GFX9: define void @needs_dot2_insts(
; GFX10: define void @needs_dot2_insts(
; GFX11-NOT: define void @needs_dot2_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
define void @needs_dot3_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #8 {
; GFX7-NOT: define void @needs_dot3_insts(
; GFX8-NOT: define void @needs_dot3_insts(
; GFX906-NOT: define void @needs_dot3_insts(
; GFX90A: define void @needs_dot3_insts(
; GFX10-NOT: define void @needs_dot3_insts(
; GFX11-NOT: define void @needs_dot3_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
define void @needs_dot4_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #9 {
; GFX7-NOT: define void @needs_dot4_insts(
; GFX8-NOT: define void @needs_dot4_insts(
; GFX906-NOT: define void @needs_dot4_insts(
; GFX90A: define void @needs_dot4_insts(
; GFX10-NOT: define void @needs_dot4_insts(
; GFX11-NOT: define void @needs_dot4_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
define void @needs_dot5_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #10 {
; GFX7-NOT: define void @needs_dot5_insts(
; GFX8-NOT: define void @needs_dot5_insts(
; GFX906-NOT: define void @needs_dot5_insts(
; GFX90A: define void @needs_dot5_insts(
; GFX10: define void @needs_dot5_insts(
; GFX11: define void @needs_dot5_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
define void @needs_dot6_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #11 {
; GFX7-NOT: define void @needs_dot6_insts(
; GFX8-NOT: define void @needs_dot6_insts(
; GFX906-NOT: define void @needs_dot6_insts(
; GFX90A: define void @needs_dot6_insts(
; GFX10: define void @needs_dot6_insts(
; GFX11-NOT: define void @needs_dot6_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
define void @needs_dot7_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #12 {
; GFX7-NOT: define void @needs_dot7_insts(
; GFX8-NOT: define void @needs_dot7_insts(
; GFX9: define void @needs_dot7_insts(
; GFX10: define void @needs_dot7_insts(
; GFX11: define void @needs_dot7_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
define void @needs_dot8_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) #13 {
; GFX7-NOT: define void @needs_dot8_insts(
; GFX8-NOT: define void @needs_dot8_insts(
; GFX9-NOT: define void @needs_dot8_insts(
; GFX10-NOT: define void @needs_dot8_insts(
; GFX11: define void @needs_dot8_insts(
%add = add i64 %a, %b
store i64 %add, ptr %out
ret void
}
; IR: define void @caller(
define void @caller(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c) {
; GFX7: call void null(
; GFX8: call void @needs_dpp(
; GFX9: call void @needs_dpp(
; GFX10: call void @needs_dpp(
; GFX11: call void @needs_dpp(
call void @needs_dpp(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void @needs_16bit_insts(
; GFX9: call void @needs_16bit_insts(
; GFX10: call void @needs_16bit_insts(
; GFX11: call void @needs_16bit_insts(
call void @needs_16bit_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void @needs_gfx8_insts(
; GFX9: call void @needs_gfx8_insts(
; GFX10: call void @needs_gfx8_insts(
; GFX11: call void @needs_gfx8_insts(
call void @needs_gfx8_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX9: call void @needs_gfx9_insts(
; GFX10: call void @needs_gfx9_insts(
; GFX111: call void @needs_gfx9_insts(c
call void @needs_gfx9_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX9: call void null(
; GFX10: call void @needs_gfx10_insts(
; GFX111: call void @needs_gfx10_insts(
call void @needs_gfx10_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX9: call void null(
; GFX10: call void null(
; GFX11: call void @needs_gfx11_insts(
call void @needs_gfx11_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX9: call void @needs_dot1_insts(
; GFX10: call void @needs_dot1_insts(
; GFX11: call void null(
call void @needs_dot1_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX9: call void @needs_dot2_insts(
; GFX10: call void @needs_dot2_insts(
; GFX11: call void null(
call void @needs_dot2_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX906: call void null(
; GFX90A: call void @needs_dot3_insts(
; GFX10: call void null(
; GFX11: call void null(
call void @needs_dot3_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX906: call void null(
; GFX90A: call void @needs_dot4_insts(
; GFX10: call void null(
; GFX11: call void null(
call void @needs_dot4_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX906: call void null(
; GFX90A: call void @needs_dot5_insts(
; GFX10: call void @needs_dot5_insts(
; GFX11: call void @needs_dot5_insts(
call void @needs_dot5_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX906: call void null(
; GFX90A: call void @needs_dot6_insts(
; GFX10: call void @needs_dot6_insts(
; GFX11: call void null(
call void @needs_dot6_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX9: call void @needs_dot7_insts(
; GFX10: call void @needs_dot7_insts(
; GFX11: call void @needs_dot7_insts(
call void @needs_dot7_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; GFX7: call void null(
; GFX8: call void null(
; GFX9: call void null(
; GFX10: call void null(
; GFX11: call void @needs_dot8_insts(
call void @needs_dot8_insts(ptr %out, ptr %in, i64 %a, i64 %b, i64 %c)
; IR: ret void
ret void
}
attributes #0 = { "target-features"="+dpp" }
attributes #1 = { "target-features"="+16-bit-insts" }
attributes #2 = { "target-features"="+gfx8-insts" }
attributes #3 = { "target-features"="+gfx9-insts" }
attributes #4 = { "target-features"="+gfx10-insts" }
attributes #5 = { "target-features"="+gfx11-insts" }
attributes #6 = { "target-features"="+dot1-insts" }
attributes #7 = { "target-features"="+dot2-insts" }
attributes #8 = { "target-features"="+dot3-insts" }
attributes #9 = { "target-features"="+dot4-insts" }
attributes #10 = { "target-features"="+dot5-insts" }
attributes #11 = { "target-features"="+dot6-insts" }
attributes #12 = { "target-features"="+dot7-insts" }
attributes #13 = { "target-features"="+dot8-insts" }