blob: 640b3ba7e5435da397267fb9d5b28a6b0f52c93f [file] [edit]
// RUN: llvm-tblgen -gen-runtime-libcalls -I %p/../../include %s 2> %t.err | FileCheck %s
// RUN: count 0 < %t.err
// Check behavior of libcall emission when multiple RuntimeLibcallImpl
// implementations provide the same RuntimeLibcall. This table records
// all available implementations, not which one is selected.
include "llvm/IR/RuntimeLibcallsImpl.td"
def SOME_FUNC : RuntimeLibcall;
def OTHER_FUNC : RuntimeLibcall;
def ANOTHER_DUP : RuntimeLibcall;
def IsTargetArchA : LibcallPredicate<[{isTargetArchA()}]>;
def IsTargetArchB : LibcallPredicate<[{isTargetArchB()}]>;
def IsTargetArchC : LibcallPredicate<[{isTargetArchC()}]>;
def isTargetArchA : RuntimeLibcallAvailability<(all_of IsTargetArchA)>;
def isTargetArchB : RuntimeLibcallAvailability<(all_of IsTargetArchB)>;
def isTargetArchC : RuntimeLibcallAvailability<(all_of IsTargetArchC)>;
def func_a : RuntimeLibcallImpl<SOME_FUNC>;
def func_b : RuntimeLibcallImpl<SOME_FUNC>;
def func_c : RuntimeLibcallImpl<SOME_FUNC>;
def other_func : RuntimeLibcallImpl<OTHER_FUNC>;
def dup0 : RuntimeLibcallImpl<ANOTHER_DUP>;
def dup1 : RuntimeLibcallImpl<ANOTHER_DUP>;
// func_a and func_b both provide SOME_FUNC.
// CHECK: if (isTargetArchA()) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x00000000000018
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const RTLIB::LibcallImpl LibraryCalls[] = {
// CHECK-NEXT: RTLIB::impl_func_b, // func_b
// CHECK-NEXT: RTLIB::impl_func_a, // func_a
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: return;
// CHECK-NEXT: }
def TheSystemLibraryA : SystemRuntimeLibrary<isTargetArchA,
(add func_b, func_a)
>;
// CHECK: if (isTargetArchB()) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x00000000000058
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const RTLIB::LibcallImpl LibraryCalls[] = {
// CHECK-NEXT: RTLIB::impl_other_func, // other_func
// CHECK-NEXT: RTLIB::impl_func_a, // func_a
// CHECK-NEXT: RTLIB::impl_func_b, // func_b
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: return;
// CHECK-NEXT: }
def TheSystemLibraryB : SystemRuntimeLibrary<isTargetArchB,
(add func_a, other_func, func_b)
>;
// CHECK: if (isTargetArchC()) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x0000000000007e
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const RTLIB::LibcallImpl LibraryCalls[] = {
// CHECK-NEXT: RTLIB::impl_dup1, // dup1
// CHECK-NEXT: RTLIB::impl_dup0, // dup0
// CHECK-NEXT: RTLIB::impl_other_func, // other_func
// CHECK-NEXT: RTLIB::impl_func_a, // func_a
// CHECK-NEXT: RTLIB::impl_func_b, // func_b
// CHECK-NEXT: RTLIB::impl_func_c, // func_c
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: return;
// CHECK-NEXT: }
def TheSystemLibraryC : SystemRuntimeLibrary<isTargetArchC,
(add func_a, dup1, other_func, func_b, func_c, dup0)
>;