From 744161eebfbbbdf373e9bdded2b29fecc955a5a7 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 14 Jul 2025 19:53:22 +0900 Subject: [PATCH 1/2] RuntimeLibcalls: Really move default libcall handling to tablegen Hack in the default setting so it's consistently generated like the other cases. Maintain a list of targets where this applies. The alternative would require new infrastructure to sort the system library initialization in some way. I wanted the unhandled target case to be treated as a fatal error, but it turns out there's a hack in IRSymtab using RuntimeLibcalls, which will fail out in many tests that do not have a triple set. Many of the failures are simply running llvm-as with no triple, which probably should not depend on knowing an accurate set of calls. --- llvm/include/llvm/IR/RuntimeLibcalls.h | 5 - llvm/include/llvm/IR/RuntimeLibcalls.td | 36 +- llvm/lib/IR/RuntimeLibcalls.cpp | 42 +- llvm/test/CodeGen/AVR/llvm.sincos.ll | 1183 +++++------------ llvm/test/TableGen/RuntimeLibcallEmitter.td | 14 +- .../TableGen/Basic/RuntimeLibcallsEmitter.cpp | 35 +- 6 files changed, 398 insertions(+), 917 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index eb882c48270cf..f39e2e3c26900 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -137,9 +137,6 @@ struct RuntimeLibcallsInfo { LLVM_ABI RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const; private: - static const RTLIB::LibcallImpl - DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1]; - /// Stores the implementation choice for each each libcall. RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = { RTLIB::Unsupported}; @@ -197,8 +194,6 @@ struct RuntimeLibcallsInfo { return hasSinCos(TT) || TT.isPS(); } - LLVM_ABI void initDefaultLibCallImpls(); - /// Generated by tablegen. void setTargetRuntimeLibcallSets(const Triple &TT, FloatABI::ABIType FloatABI); diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index bae0020e0aead..f8782d71ddf37 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -1610,7 +1610,9 @@ def HexagonSystemLibrary (add (sub DefaultLibcallImpls32, __adddf3, __divsf3, __udivsi3, __udivdi3, __umoddi3, __divdf3, __muldf3, __divsi3, __subdf3, sqrtf, - __divdi3, __umodsi3, __moddi3, __modsi3), HexagonLibcalls)>; + __divdi3, __umodsi3, __moddi3, __modsi3), HexagonLibcalls, + LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, + exp10f, exp10, exp10l_f128)>; //===----------------------------------------------------------------------===// // Lanai Runtime Libcalls @@ -1823,6 +1825,7 @@ defvar MSP430DefaultOptOut = [ def MSP430SystemLibrary : SystemRuntimeLibrary; def isXCore : RuntimeLibcallPredicate<"TT.getArch() == Triple::xcore">; def XCoreSystemLibrary - : SystemRuntimeLibrary; + : SystemRuntimeLibrary +)>; //===----------------------------------------------------------------------===// // ZOS Runtime Libcalls @@ -2286,3 +2293,26 @@ def WasmSystemLibrary CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls, exp10f, exp10, emscripten_return_address)>; + +//===----------------------------------------------------------------------===// +// Legacy Default Runtime Libcalls +//===----------------------------------------------------------------------===// + +// TODO: Should make every target explicit. +def isDefaultLibcallArch : RuntimeLibcallPredicate<[{ + TT.isMIPS() || TT.isLoongArch() || TT.isVE() || TT.isBPF() || + TT.getArch() == Triple::csky || TT.getArch() == Triple::arc || + TT.getArch() == Triple::m68k || TT.getArch() == Triple::xtensa || + (TT.isSystemZ() && !TT.isOSzOS()) +}]>; + + +def isArch64Bit : RuntimeLibcallPredicate<[{TT.isArch64Bit()}]>; +def LegacyDefaultSystemLibrary + : SystemRuntimeLibrary +)>; diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 1ca5878787979..8c90c52141dc7 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -8,6 +8,9 @@ #include "llvm/IR/RuntimeLibcalls.h" #include "llvm/ADT/StringTable.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "runtime-libcalls-info" using namespace llvm; using namespace RTLIB; @@ -62,12 +65,6 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, Info.setLibcallImplCallingConv(Impl, CallingConv::ARM_AAPCS); } -void RTLIB::RuntimeLibcallsInfo::initDefaultLibCallImpls() { - std::memcpy(LibcallImpls, DefaultLibcallImpls, sizeof(LibcallImpls)); - static_assert(sizeof(LibcallImpls) == sizeof(DefaultLibcallImpls), - "libcall array size should match"); -} - /// Set default libcall names. If a target wants to opt-out of a libcall it /// should be placed here. void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, @@ -76,10 +73,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, EABI EABIVersion, StringRef ABIName) { setTargetRuntimeLibcallSets(TT, FloatABI); - // Early exit for targets that have fully ported to tablegen. - if (TT.isAMDGPU() || TT.isNVPTX() || TT.isWasm()) - return; - if (TT.isX86() || TT.isVE() || TT.isARM() || TT.isThumb()) { if (ExceptionModel == ExceptionHandling::SjLj) setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); @@ -92,11 +85,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, // FIXME: What about other targets? setLibcallImpl(RTLIB::FPEXT_F16_F32, RTLIB::__extendhfsf2); setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__truncsfhf2); - - if (!darwinHasExp10(TT)) { - setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported); - setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported); - } } if (TT.isOSOpenBSD()) { @@ -104,35 +92,11 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, setLibcallImpl(RTLIB::STACK_SMASH_HANDLER, RTLIB::__stack_smash_handler); } - // Skip default manual processing for targets that have been mostly ported to - // tablegen for now. Eventually the rest of this should be deleted. - if (TT.isX86() || TT.isAArch64() || TT.isWasm() || TT.isPPC()) - return; - if (TT.isARM() || TT.isThumb()) { setARMLibcallNames(*this, TT, FloatABI, EABIVersion); return; } - if (hasSinCos(TT)) { - setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); - setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); - setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128); - } - - setLibcallImpl(RTLIB::EXP10_F32, RTLIB::exp10f); - setLibcallImpl(RTLIB::EXP10_F64, RTLIB::exp10); - setLibcallImpl(RTLIB::EXP10_F128, RTLIB::exp10l_f128); - - // These libcalls are only available in compiler-rt, not libgcc. - if (TT.isArch64Bit()) { - setLibcallImpl(RTLIB::SHL_I128, RTLIB::__ashlti3); - setLibcallImpl(RTLIB::SRL_I128, RTLIB::__lshrti3); - setLibcallImpl(RTLIB::SRA_I128, RTLIB::__ashrti3); - setLibcallImpl(RTLIB::MUL_I128, RTLIB::__multi3); - setLibcallImpl(RTLIB::MULO_I64, RTLIB::__mulodi4); - } - if (TT.getArch() == Triple::ArchType::msp430) { setLibcallImplCallingConv(RTLIB::__mspabi_mpyll, CallingConv::MSP430_BUILTIN); diff --git a/llvm/test/CodeGen/AVR/llvm.sincos.ll b/llvm/test/CodeGen/AVR/llvm.sincos.ll index 897101d30430d..b70b8d34a8a3b 100644 --- a/llvm/test/CodeGen/AVR/llvm.sincos.ll +++ b/llvm/test/CodeGen/AVR/llvm.sincos.ll @@ -3,630 +3,266 @@ ; RUN: llc -mtriple=avr-unknown-linux-gnu < %s | FileCheck -check-prefixes=CHECK,GNU %s define { half, half } @test_sincos_f16(half %a) #0 { -; NONGNU-LABEL: test_sincos_f16: -; NONGNU: ; %bb.0: -; NONGNU-NEXT: push r12 -; NONGNU-NEXT: push r13 -; NONGNU-NEXT: push r14 -; NONGNU-NEXT: push r15 -; NONGNU-NEXT: push r16 -; NONGNU-NEXT: push r17 -; NONGNU-NEXT: mov r24, r22 -; NONGNU-NEXT: mov r25, r23 -; NONGNU-NEXT: rcall __extendhfsf2 -; NONGNU-NEXT: mov r16, r22 -; NONGNU-NEXT: mov r17, r23 -; NONGNU-NEXT: mov r14, r24 -; NONGNU-NEXT: mov r15, r25 -; NONGNU-NEXT: rcall sin -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r12, r24 -; NONGNU-NEXT: mov r13, r25 -; NONGNU-NEXT: mov r22, r16 -; NONGNU-NEXT: mov r23, r17 -; NONGNU-NEXT: mov r24, r14 -; NONGNU-NEXT: mov r25, r15 -; NONGNU-NEXT: rcall cos -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r22, r24 -; NONGNU-NEXT: mov r23, r25 -; NONGNU-NEXT: mov r18, r12 -; NONGNU-NEXT: mov r19, r13 -; NONGNU-NEXT: pop r17 -; NONGNU-NEXT: pop r16 -; NONGNU-NEXT: pop r15 -; NONGNU-NEXT: pop r14 -; NONGNU-NEXT: pop r13 -; NONGNU-NEXT: pop r12 -; NONGNU-NEXT: ret -; -; GNU-LABEL: test_sincos_f16: -; GNU: ; %bb.0: -; GNU-NEXT: push r16 -; GNU-NEXT: push r17 -; GNU-NEXT: push r28 -; GNU-NEXT: push r29 -; GNU-NEXT: in r28, 61 -; GNU-NEXT: in r29, 62 -; GNU-NEXT: sbiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: mov r24, r22 -; GNU-NEXT: mov r25, r23 -; GNU-NEXT: rcall __extendhfsf2 -; GNU-NEXT: mov r20, r28 -; GNU-NEXT: mov r21, r29 -; GNU-NEXT: subi r20, 251 -; GNU-NEXT: sbci r21, 255 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 255 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: ldd r22, Y+5 -; GNU-NEXT: ldd r23, Y+6 -; GNU-NEXT: ldd r24, Y+7 -; GNU-NEXT: ldd r25, Y+8 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r16, r24 -; GNU-NEXT: mov r17, r25 -; GNU-NEXT: ldd r22, Y+1 -; GNU-NEXT: ldd r23, Y+2 -; GNU-NEXT: ldd r24, Y+3 -; GNU-NEXT: ldd r25, Y+4 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r22, r24 -; GNU-NEXT: mov r23, r25 -; GNU-NEXT: mov r18, r16 -; GNU-NEXT: mov r19, r17 -; GNU-NEXT: adiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: pop r29 -; GNU-NEXT: pop r28 -; GNU-NEXT: pop r17 -; GNU-NEXT: pop r16 -; GNU-NEXT: ret +; CHECK-LABEL: test_sincos_f16: +; CHECK: ; %bb.0: +; CHECK-NEXT: push r12 +; CHECK-NEXT: push r13 +; CHECK-NEXT: push r14 +; CHECK-NEXT: push r15 +; CHECK-NEXT: push r16 +; CHECK-NEXT: push r17 +; CHECK-NEXT: mov r24, r22 +; CHECK-NEXT: mov r25, r23 +; CHECK-NEXT: rcall __extendhfsf2 +; CHECK-NEXT: mov r16, r22 +; CHECK-NEXT: mov r17, r23 +; CHECK-NEXT: mov r14, r24 +; CHECK-NEXT: mov r15, r25 +; CHECK-NEXT: rcall sin +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r12, r24 +; CHECK-NEXT: mov r13, r25 +; CHECK-NEXT: mov r22, r16 +; CHECK-NEXT: mov r23, r17 +; CHECK-NEXT: mov r24, r14 +; CHECK-NEXT: mov r25, r15 +; CHECK-NEXT: rcall cos +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r22, r24 +; CHECK-NEXT: mov r23, r25 +; CHECK-NEXT: mov r18, r12 +; CHECK-NEXT: mov r19, r13 +; CHECK-NEXT: pop r17 +; CHECK-NEXT: pop r16 +; CHECK-NEXT: pop r15 +; CHECK-NEXT: pop r14 +; CHECK-NEXT: pop r13 +; CHECK-NEXT: pop r12 +; CHECK-NEXT: ret %result = call { half, half } @llvm.sincos.f16(half %a) ret { half, half } %result } define half @test_sincos_f16_only_use_sin(half %a) #0 { -; NONGNU-LABEL: test_sincos_f16_only_use_sin: -; NONGNU: ; %bb.0: -; NONGNU-NEXT: mov r24, r22 -; NONGNU-NEXT: mov r25, r23 -; NONGNU-NEXT: rcall __extendhfsf2 -; NONGNU-NEXT: rcall sin -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r22, r24 -; NONGNU-NEXT: mov r23, r25 -; NONGNU-NEXT: ret -; -; GNU-LABEL: test_sincos_f16_only_use_sin: -; GNU: ; %bb.0: -; GNU-NEXT: push r28 -; GNU-NEXT: push r29 -; GNU-NEXT: in r28, 61 -; GNU-NEXT: in r29, 62 -; GNU-NEXT: sbiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: mov r24, r22 -; GNU-NEXT: mov r25, r23 -; GNU-NEXT: rcall __extendhfsf2 -; GNU-NEXT: mov r20, r28 -; GNU-NEXT: mov r21, r29 -; GNU-NEXT: subi r20, 251 -; GNU-NEXT: sbci r21, 255 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 255 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: ldd r22, Y+5 -; GNU-NEXT: ldd r23, Y+6 -; GNU-NEXT: ldd r24, Y+7 -; GNU-NEXT: ldd r25, Y+8 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r22, r24 -; GNU-NEXT: mov r23, r25 -; GNU-NEXT: adiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: pop r29 -; GNU-NEXT: pop r28 -; GNU-NEXT: ret +; CHECK-LABEL: test_sincos_f16_only_use_sin: +; CHECK: ; %bb.0: +; CHECK-NEXT: mov r24, r22 +; CHECK-NEXT: mov r25, r23 +; CHECK-NEXT: rcall __extendhfsf2 +; CHECK-NEXT: rcall sin +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r22, r24 +; CHECK-NEXT: mov r23, r25 +; CHECK-NEXT: ret %result = call { half, half } @llvm.sincos.f16(half %a) %result.0 = extractvalue { half, half } %result, 0 ret half %result.0 } define half @test_sincos_f16_only_use_cos(half %a) #0 { -; NONGNU-LABEL: test_sincos_f16_only_use_cos: -; NONGNU: ; %bb.0: -; NONGNU-NEXT: mov r24, r22 -; NONGNU-NEXT: mov r25, r23 -; NONGNU-NEXT: rcall __extendhfsf2 -; NONGNU-NEXT: rcall cos -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r22, r24 -; NONGNU-NEXT: mov r23, r25 -; NONGNU-NEXT: ret -; -; GNU-LABEL: test_sincos_f16_only_use_cos: -; GNU: ; %bb.0: -; GNU-NEXT: push r28 -; GNU-NEXT: push r29 -; GNU-NEXT: in r28, 61 -; GNU-NEXT: in r29, 62 -; GNU-NEXT: sbiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: mov r24, r22 -; GNU-NEXT: mov r25, r23 -; GNU-NEXT: rcall __extendhfsf2 -; GNU-NEXT: mov r20, r28 -; GNU-NEXT: mov r21, r29 -; GNU-NEXT: subi r20, 251 -; GNU-NEXT: sbci r21, 255 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 255 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: ldd r22, Y+1 -; GNU-NEXT: ldd r23, Y+2 -; GNU-NEXT: ldd r24, Y+3 -; GNU-NEXT: ldd r25, Y+4 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r22, r24 -; GNU-NEXT: mov r23, r25 -; GNU-NEXT: adiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: pop r29 -; GNU-NEXT: pop r28 -; GNU-NEXT: ret +; CHECK-LABEL: test_sincos_f16_only_use_cos: +; CHECK: ; %bb.0: +; CHECK-NEXT: mov r24, r22 +; CHECK-NEXT: mov r25, r23 +; CHECK-NEXT: rcall __extendhfsf2 +; CHECK-NEXT: rcall cos +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r22, r24 +; CHECK-NEXT: mov r23, r25 +; CHECK-NEXT: ret %result = call { half, half } @llvm.sincos.f16(half %a) %result.1 = extractvalue { half, half } %result, 1 ret half %result.1 } define { <2 x half>, <2 x half> } @test_sincos_v2f16(<2 x half> %a) #0 { -; NONGNU-LABEL: test_sincos_v2f16: -; NONGNU: ; %bb.0: -; NONGNU-NEXT: push r6 -; NONGNU-NEXT: push r7 -; NONGNU-NEXT: push r8 -; NONGNU-NEXT: push r9 -; NONGNU-NEXT: push r10 -; NONGNU-NEXT: push r11 -; NONGNU-NEXT: push r12 -; NONGNU-NEXT: push r13 -; NONGNU-NEXT: push r14 -; NONGNU-NEXT: push r15 -; NONGNU-NEXT: push r16 -; NONGNU-NEXT: push r17 -; NONGNU-NEXT: mov r10, r22 -; NONGNU-NEXT: mov r11, r23 -; NONGNU-NEXT: rcall __extendhfsf2 -; NONGNU-NEXT: mov r16, r22 -; NONGNU-NEXT: mov r17, r23 -; NONGNU-NEXT: mov r14, r24 -; NONGNU-NEXT: mov r15, r25 -; NONGNU-NEXT: rcall sin -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r12, r24 -; NONGNU-NEXT: mov r13, r25 -; NONGNU-NEXT: mov r24, r10 -; NONGNU-NEXT: mov r25, r11 -; NONGNU-NEXT: rcall __extendhfsf2 -; NONGNU-NEXT: mov r10, r22 -; NONGNU-NEXT: mov r11, r23 -; NONGNU-NEXT: mov r8, r24 -; NONGNU-NEXT: mov r9, r25 -; NONGNU-NEXT: rcall cos -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r6, r24 -; NONGNU-NEXT: mov r7, r25 -; NONGNU-NEXT: mov r22, r10 -; NONGNU-NEXT: mov r23, r11 -; NONGNU-NEXT: mov r24, r8 -; NONGNU-NEXT: mov r25, r9 -; NONGNU-NEXT: rcall sin -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r10, r24 -; NONGNU-NEXT: mov r11, r25 -; NONGNU-NEXT: mov r22, r16 -; NONGNU-NEXT: mov r23, r17 -; NONGNU-NEXT: mov r24, r14 -; NONGNU-NEXT: mov r25, r15 -; NONGNU-NEXT: rcall cos -; NONGNU-NEXT: rcall __truncsfhf2 -; NONGNU-NEXT: mov r18, r10 -; NONGNU-NEXT: mov r19, r11 -; NONGNU-NEXT: mov r20, r12 -; NONGNU-NEXT: mov r21, r13 -; NONGNU-NEXT: mov r22, r6 -; NONGNU-NEXT: mov r23, r7 -; NONGNU-NEXT: pop r17 -; NONGNU-NEXT: pop r16 -; NONGNU-NEXT: pop r15 -; NONGNU-NEXT: pop r14 -; NONGNU-NEXT: pop r13 -; NONGNU-NEXT: pop r12 -; NONGNU-NEXT: pop r11 -; NONGNU-NEXT: pop r10 -; NONGNU-NEXT: pop r9 -; NONGNU-NEXT: pop r8 -; NONGNU-NEXT: pop r7 -; NONGNU-NEXT: pop r6 -; NONGNU-NEXT: ret -; -; GNU-LABEL: test_sincos_v2f16: -; GNU: ; %bb.0: -; GNU-NEXT: push r12 -; GNU-NEXT: push r13 -; GNU-NEXT: push r14 -; GNU-NEXT: push r15 -; GNU-NEXT: push r16 -; GNU-NEXT: push r17 -; GNU-NEXT: push r28 -; GNU-NEXT: push r29 -; GNU-NEXT: in r28, 61 -; GNU-NEXT: in r29, 62 -; GNU-NEXT: sbiw r28, 16 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: mov r16, r24 -; GNU-NEXT: mov r17, r25 -; GNU-NEXT: mov r24, r22 -; GNU-NEXT: mov r25, r23 -; GNU-NEXT: rcall __extendhfsf2 -; GNU-NEXT: mov r20, r28 -; GNU-NEXT: mov r21, r29 -; GNU-NEXT: subi r20, 243 -; GNU-NEXT: sbci r21, 255 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 247 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: mov r24, r16 -; GNU-NEXT: mov r25, r17 -; GNU-NEXT: rcall __extendhfsf2 -; GNU-NEXT: mov r20, r28 -; GNU-NEXT: mov r21, r29 -; GNU-NEXT: subi r20, 251 -; GNU-NEXT: sbci r21, 255 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 255 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: ldd r22, Y+13 -; GNU-NEXT: ldd r23, Y+14 -; GNU-NEXT: ldd r24, Y+15 -; GNU-NEXT: ldd r25, Y+16 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r16, r24 -; GNU-NEXT: mov r17, r25 -; GNU-NEXT: ldd r22, Y+5 -; GNU-NEXT: ldd r23, Y+6 -; GNU-NEXT: ldd r24, Y+7 -; GNU-NEXT: ldd r25, Y+8 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r14, r24 -; GNU-NEXT: mov r15, r25 -; GNU-NEXT: ldd r22, Y+9 -; GNU-NEXT: ldd r23, Y+10 -; GNU-NEXT: ldd r24, Y+11 -; GNU-NEXT: ldd r25, Y+12 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r12, r24 -; GNU-NEXT: mov r13, r25 -; GNU-NEXT: ldd r22, Y+1 -; GNU-NEXT: ldd r23, Y+2 -; GNU-NEXT: ldd r24, Y+3 -; GNU-NEXT: ldd r25, Y+4 -; GNU-NEXT: rcall __truncsfhf2 -; GNU-NEXT: mov r18, r16 -; GNU-NEXT: mov r19, r17 -; GNU-NEXT: mov r20, r14 -; GNU-NEXT: mov r21, r15 -; GNU-NEXT: mov r22, r12 -; GNU-NEXT: mov r23, r13 -; GNU-NEXT: adiw r28, 16 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: pop r29 -; GNU-NEXT: pop r28 -; GNU-NEXT: pop r17 -; GNU-NEXT: pop r16 -; GNU-NEXT: pop r15 -; GNU-NEXT: pop r14 -; GNU-NEXT: pop r13 -; GNU-NEXT: pop r12 -; GNU-NEXT: ret +; CHECK-LABEL: test_sincos_v2f16: +; CHECK: ; %bb.0: +; CHECK-NEXT: push r6 +; CHECK-NEXT: push r7 +; CHECK-NEXT: push r8 +; CHECK-NEXT: push r9 +; CHECK-NEXT: push r10 +; CHECK-NEXT: push r11 +; CHECK-NEXT: push r12 +; CHECK-NEXT: push r13 +; CHECK-NEXT: push r14 +; CHECK-NEXT: push r15 +; CHECK-NEXT: push r16 +; CHECK-NEXT: push r17 +; CHECK-NEXT: mov r10, r22 +; CHECK-NEXT: mov r11, r23 +; CHECK-NEXT: rcall __extendhfsf2 +; CHECK-NEXT: mov r16, r22 +; CHECK-NEXT: mov r17, r23 +; CHECK-NEXT: mov r14, r24 +; CHECK-NEXT: mov r15, r25 +; CHECK-NEXT: rcall sin +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r12, r24 +; CHECK-NEXT: mov r13, r25 +; CHECK-NEXT: mov r24, r10 +; CHECK-NEXT: mov r25, r11 +; CHECK-NEXT: rcall __extendhfsf2 +; CHECK-NEXT: mov r10, r22 +; CHECK-NEXT: mov r11, r23 +; CHECK-NEXT: mov r8, r24 +; CHECK-NEXT: mov r9, r25 +; CHECK-NEXT: rcall cos +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r6, r24 +; CHECK-NEXT: mov r7, r25 +; CHECK-NEXT: mov r22, r10 +; CHECK-NEXT: mov r23, r11 +; CHECK-NEXT: mov r24, r8 +; CHECK-NEXT: mov r25, r9 +; CHECK-NEXT: rcall sin +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r10, r24 +; CHECK-NEXT: mov r11, r25 +; CHECK-NEXT: mov r22, r16 +; CHECK-NEXT: mov r23, r17 +; CHECK-NEXT: mov r24, r14 +; CHECK-NEXT: mov r25, r15 +; CHECK-NEXT: rcall cos +; CHECK-NEXT: rcall __truncsfhf2 +; CHECK-NEXT: mov r18, r10 +; CHECK-NEXT: mov r19, r11 +; CHECK-NEXT: mov r20, r12 +; CHECK-NEXT: mov r21, r13 +; CHECK-NEXT: mov r22, r6 +; CHECK-NEXT: mov r23, r7 +; CHECK-NEXT: pop r17 +; CHECK-NEXT: pop r16 +; CHECK-NEXT: pop r15 +; CHECK-NEXT: pop r14 +; CHECK-NEXT: pop r13 +; CHECK-NEXT: pop r12 +; CHECK-NEXT: pop r11 +; CHECK-NEXT: pop r10 +; CHECK-NEXT: pop r9 +; CHECK-NEXT: pop r8 +; CHECK-NEXT: pop r7 +; CHECK-NEXT: pop r6 +; CHECK-NEXT: ret %result = call { <2 x half>, <2 x half> } @llvm.sincos.v2f16(<2 x half> %a) ret { <2 x half>, <2 x half> } %result } define { float, float } @test_sincos_f32(float %a) #0 { -; NONGNU-LABEL: test_sincos_f32: -; NONGNU: ; %bb.0: -; NONGNU-NEXT: push r10 -; NONGNU-NEXT: push r11 -; NONGNU-NEXT: push r12 -; NONGNU-NEXT: push r13 -; NONGNU-NEXT: push r14 -; NONGNU-NEXT: push r15 -; NONGNU-NEXT: push r16 -; NONGNU-NEXT: push r17 -; NONGNU-NEXT: mov r16, r24 -; NONGNU-NEXT: mov r17, r25 -; NONGNU-NEXT: mov r14, r22 -; NONGNU-NEXT: mov r15, r23 -; NONGNU-NEXT: rcall sin -; NONGNU-NEXT: mov r12, r22 -; NONGNU-NEXT: mov r13, r23 -; NONGNU-NEXT: mov r10, r24 -; NONGNU-NEXT: mov r11, r25 -; NONGNU-NEXT: mov r22, r14 -; NONGNU-NEXT: mov r23, r15 -; NONGNU-NEXT: mov r24, r16 -; NONGNU-NEXT: mov r25, r17 -; NONGNU-NEXT: rcall cos -; NONGNU-NEXT: mov r18, r12 -; NONGNU-NEXT: mov r19, r13 -; NONGNU-NEXT: mov r20, r10 -; NONGNU-NEXT: mov r21, r11 -; NONGNU-NEXT: pop r17 -; NONGNU-NEXT: pop r16 -; NONGNU-NEXT: pop r15 -; NONGNU-NEXT: pop r14 -; NONGNU-NEXT: pop r13 -; NONGNU-NEXT: pop r12 -; NONGNU-NEXT: pop r11 -; NONGNU-NEXT: pop r10 -; NONGNU-NEXT: ret -; -; GNU-LABEL: test_sincos_f32: -; GNU: ; %bb.0: -; GNU-NEXT: push r28 -; GNU-NEXT: push r29 -; GNU-NEXT: in r28, 61 -; GNU-NEXT: in r29, 62 -; GNU-NEXT: sbiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: mov r20, r28 -; GNU-NEXT: mov r21, r29 -; GNU-NEXT: subi r20, 251 -; GNU-NEXT: sbci r21, 255 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 255 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: ldd r18, Y+5 -; GNU-NEXT: ldd r19, Y+6 -; GNU-NEXT: ldd r20, Y+7 -; GNU-NEXT: ldd r21, Y+8 -; GNU-NEXT: ldd r22, Y+1 -; GNU-NEXT: ldd r23, Y+2 -; GNU-NEXT: ldd r24, Y+3 -; GNU-NEXT: ldd r25, Y+4 -; GNU-NEXT: adiw r28, 8 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: pop r29 -; GNU-NEXT: pop r28 -; GNU-NEXT: ret +; CHECK-LABEL: test_sincos_f32: +; CHECK: ; %bb.0: +; CHECK-NEXT: push r10 +; CHECK-NEXT: push r11 +; CHECK-NEXT: push r12 +; CHECK-NEXT: push r13 +; CHECK-NEXT: push r14 +; CHECK-NEXT: push r15 +; CHECK-NEXT: push r16 +; CHECK-NEXT: push r17 +; CHECK-NEXT: mov r16, r24 +; CHECK-NEXT: mov r17, r25 +; CHECK-NEXT: mov r14, r22 +; CHECK-NEXT: mov r15, r23 +; CHECK-NEXT: rcall sin +; CHECK-NEXT: mov r12, r22 +; CHECK-NEXT: mov r13, r23 +; CHECK-NEXT: mov r10, r24 +; CHECK-NEXT: mov r11, r25 +; CHECK-NEXT: mov r22, r14 +; CHECK-NEXT: mov r23, r15 +; CHECK-NEXT: mov r24, r16 +; CHECK-NEXT: mov r25, r17 +; CHECK-NEXT: rcall cos +; CHECK-NEXT: mov r18, r12 +; CHECK-NEXT: mov r19, r13 +; CHECK-NEXT: mov r20, r10 +; CHECK-NEXT: mov r21, r11 +; CHECK-NEXT: pop r17 +; CHECK-NEXT: pop r16 +; CHECK-NEXT: pop r15 +; CHECK-NEXT: pop r14 +; CHECK-NEXT: pop r13 +; CHECK-NEXT: pop r12 +; CHECK-NEXT: pop r11 +; CHECK-NEXT: pop r10 +; CHECK-NEXT: ret %result = call { float, float } @llvm.sincos.f32(float %a) ret { float, float } %result } define { <2 x float>, <2 x float> } @test_sincos_v2f32(<2 x float> %a) #0 { -; NONGNU-LABEL: test_sincos_v2f32: -; NONGNU: ; %bb.0: -; NONGNU-NEXT: push r8 -; NONGNU-NEXT: push r9 -; NONGNU-NEXT: push r10 -; NONGNU-NEXT: push r11 -; NONGNU-NEXT: push r12 -; NONGNU-NEXT: push r13 -; NONGNU-NEXT: push r14 -; NONGNU-NEXT: push r15 -; NONGNU-NEXT: mov r14, r22 -; NONGNU-NEXT: mov r15, r23 -; NONGNU-NEXT: mov r12, r20 -; NONGNU-NEXT: mov r13, r21 -; NONGNU-NEXT: mov r10, r18 -; NONGNU-NEXT: mov r11, r19 -; NONGNU-NEXT: mov r8, r24 -; NONGNU-NEXT: mov r9, r25 -; NONGNU-NEXT: mov r22, r12 -; NONGNU-NEXT: mov r23, r13 -; NONGNU-NEXT: mov r24, r14 -; NONGNU-NEXT: mov r25, r15 -; NONGNU-NEXT: rcall cos -; NONGNU-NEXT: mov r30, r8 -; NONGNU-NEXT: mov r31, r9 -; NONGNU-NEXT: std Z+15, r25 -; NONGNU-NEXT: std Z+14, r24 -; NONGNU-NEXT: std Z+13, r23 -; NONGNU-NEXT: std Z+12, r22 -; NONGNU-NEXT: mov r22, r16 -; NONGNU-NEXT: mov r23, r17 -; NONGNU-NEXT: mov r24, r10 -; NONGNU-NEXT: mov r25, r11 -; NONGNU-NEXT: rcall cos -; NONGNU-NEXT: mov r30, r8 -; NONGNU-NEXT: mov r31, r9 -; NONGNU-NEXT: std Z+11, r25 -; NONGNU-NEXT: std Z+10, r24 -; NONGNU-NEXT: std Z+9, r23 -; NONGNU-NEXT: std Z+8, r22 -; NONGNU-NEXT: mov r22, r12 -; NONGNU-NEXT: mov r23, r13 -; NONGNU-NEXT: mov r24, r14 -; NONGNU-NEXT: mov r25, r15 -; NONGNU-NEXT: rcall sin -; NONGNU-NEXT: mov r30, r8 -; NONGNU-NEXT: mov r31, r9 -; NONGNU-NEXT: std Z+7, r25 -; NONGNU-NEXT: std Z+6, r24 -; NONGNU-NEXT: std Z+5, r23 -; NONGNU-NEXT: std Z+4, r22 -; NONGNU-NEXT: mov r22, r16 -; NONGNU-NEXT: mov r23, r17 -; NONGNU-NEXT: mov r24, r10 -; NONGNU-NEXT: mov r25, r11 -; NONGNU-NEXT: rcall sin -; NONGNU-NEXT: mov r30, r8 -; NONGNU-NEXT: mov r31, r9 -; NONGNU-NEXT: std Z+3, r25 -; NONGNU-NEXT: std Z+2, r24 -; NONGNU-NEXT: std Z+1, r23 -; NONGNU-NEXT: st Z, r22 -; NONGNU-NEXT: pop r15 -; NONGNU-NEXT: pop r14 -; NONGNU-NEXT: pop r13 -; NONGNU-NEXT: pop r12 -; NONGNU-NEXT: pop r11 -; NONGNU-NEXT: pop r10 -; NONGNU-NEXT: pop r9 -; NONGNU-NEXT: pop r8 -; NONGNU-NEXT: ret -; -; GNU-LABEL: test_sincos_v2f32: -; GNU: ; %bb.0: -; GNU-NEXT: push r12 -; GNU-NEXT: push r13 -; GNU-NEXT: push r14 -; GNU-NEXT: push r15 -; GNU-NEXT: push r28 -; GNU-NEXT: push r29 -; GNU-NEXT: in r28, 61 -; GNU-NEXT: in r29, 62 -; GNU-NEXT: sbiw r28, 16 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: mov r30, r22 -; GNU-NEXT: mov r31, r23 -; GNU-NEXT: mov r14, r18 -; GNU-NEXT: mov r15, r19 -; GNU-NEXT: mov r12, r24 -; GNU-NEXT: mov r13, r25 -; GNU-NEXT: mov r26, r28 -; GNU-NEXT: mov r27, r29 -; GNU-NEXT: adiw r26, 13 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 247 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: mov r22, r20 -; GNU-NEXT: mov r23, r21 -; GNU-NEXT: mov r24, r30 -; GNU-NEXT: mov r25, r31 -; GNU-NEXT: mov r20, r26 -; GNU-NEXT: mov r21, r27 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: mov r20, r28 -; GNU-NEXT: mov r21, r29 -; GNU-NEXT: subi r20, 251 -; GNU-NEXT: sbci r21, 255 -; GNU-NEXT: mov r18, r28 -; GNU-NEXT: mov r19, r29 -; GNU-NEXT: subi r18, 255 -; GNU-NEXT: sbci r19, 255 -; GNU-NEXT: mov r22, r16 -; GNU-NEXT: mov r23, r17 -; GNU-NEXT: mov r24, r14 -; GNU-NEXT: mov r25, r15 -; GNU-NEXT: rcall sincosf -; GNU-NEXT: ldd r24, Y+11 -; GNU-NEXT: ldd r25, Y+12 -; GNU-NEXT: mov r30, r12 -; GNU-NEXT: mov r31, r13 -; GNU-NEXT: std Z+15, r25 -; GNU-NEXT: std Z+14, r24 -; GNU-NEXT: ldd r24, Y+9 -; GNU-NEXT: ldd r25, Y+10 -; GNU-NEXT: std Z+13, r25 -; GNU-NEXT: std Z+12, r24 -; GNU-NEXT: ldd r24, Y+3 -; GNU-NEXT: ldd r25, Y+4 -; GNU-NEXT: std Z+11, r25 -; GNU-NEXT: std Z+10, r24 -; GNU-NEXT: ldd r24, Y+1 -; GNU-NEXT: ldd r25, Y+2 -; GNU-NEXT: std Z+9, r25 -; GNU-NEXT: std Z+8, r24 -; GNU-NEXT: ldd r24, Y+15 -; GNU-NEXT: ldd r25, Y+16 -; GNU-NEXT: std Z+7, r25 -; GNU-NEXT: std Z+6, r24 -; GNU-NEXT: ldd r24, Y+13 -; GNU-NEXT: ldd r25, Y+14 -; GNU-NEXT: std Z+5, r25 -; GNU-NEXT: std Z+4, r24 -; GNU-NEXT: ldd r24, Y+7 -; GNU-NEXT: ldd r25, Y+8 -; GNU-NEXT: std Z+3, r25 -; GNU-NEXT: std Z+2, r24 -; GNU-NEXT: ldd r24, Y+5 -; GNU-NEXT: ldd r25, Y+6 -; GNU-NEXT: std Z+1, r25 -; GNU-NEXT: st Z, r24 -; GNU-NEXT: adiw r28, 16 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: pop r29 -; GNU-NEXT: pop r28 -; GNU-NEXT: pop r15 -; GNU-NEXT: pop r14 -; GNU-NEXT: pop r13 -; GNU-NEXT: pop r12 -; GNU-NEXT: ret +; CHECK-LABEL: test_sincos_v2f32: +; CHECK: ; %bb.0: +; CHECK-NEXT: push r8 +; CHECK-NEXT: push r9 +; CHECK-NEXT: push r10 +; CHECK-NEXT: push r11 +; CHECK-NEXT: push r12 +; CHECK-NEXT: push r13 +; CHECK-NEXT: push r14 +; CHECK-NEXT: push r15 +; CHECK-NEXT: mov r14, r22 +; CHECK-NEXT: mov r15, r23 +; CHECK-NEXT: mov r12, r20 +; CHECK-NEXT: mov r13, r21 +; CHECK-NEXT: mov r10, r18 +; CHECK-NEXT: mov r11, r19 +; CHECK-NEXT: mov r8, r24 +; CHECK-NEXT: mov r9, r25 +; CHECK-NEXT: mov r22, r12 +; CHECK-NEXT: mov r23, r13 +; CHECK-NEXT: mov r24, r14 +; CHECK-NEXT: mov r25, r15 +; CHECK-NEXT: rcall cos +; CHECK-NEXT: mov r30, r8 +; CHECK-NEXT: mov r31, r9 +; CHECK-NEXT: std Z+15, r25 +; CHECK-NEXT: std Z+14, r24 +; CHECK-NEXT: std Z+13, r23 +; CHECK-NEXT: std Z+12, r22 +; CHECK-NEXT: mov r22, r16 +; CHECK-NEXT: mov r23, r17 +; CHECK-NEXT: mov r24, r10 +; CHECK-NEXT: mov r25, r11 +; CHECK-NEXT: rcall cos +; CHECK-NEXT: mov r30, r8 +; CHECK-NEXT: mov r31, r9 +; CHECK-NEXT: std Z+11, r25 +; CHECK-NEXT: std Z+10, r24 +; CHECK-NEXT: std Z+9, r23 +; CHECK-NEXT: std Z+8, r22 +; CHECK-NEXT: mov r22, r12 +; CHECK-NEXT: mov r23, r13 +; CHECK-NEXT: mov r24, r14 +; CHECK-NEXT: mov r25, r15 +; CHECK-NEXT: rcall sin +; CHECK-NEXT: mov r30, r8 +; CHECK-NEXT: mov r31, r9 +; CHECK-NEXT: std Z+7, r25 +; CHECK-NEXT: std Z+6, r24 +; CHECK-NEXT: std Z+5, r23 +; CHECK-NEXT: std Z+4, r22 +; CHECK-NEXT: mov r22, r16 +; CHECK-NEXT: mov r23, r17 +; CHECK-NEXT: mov r24, r10 +; CHECK-NEXT: mov r25, r11 +; CHECK-NEXT: rcall sin +; CHECK-NEXT: mov r30, r8 +; CHECK-NEXT: mov r31, r9 +; CHECK-NEXT: std Z+3, r25 +; CHECK-NEXT: std Z+2, r24 +; CHECK-NEXT: std Z+1, r23 +; CHECK-NEXT: st Z, r22 +; CHECK-NEXT: pop r15 +; CHECK-NEXT: pop r14 +; CHECK-NEXT: pop r13 +; CHECK-NEXT: pop r12 +; CHECK-NEXT: pop r11 +; CHECK-NEXT: pop r10 +; CHECK-NEXT: pop r9 +; CHECK-NEXT: pop r8 +; CHECK-NEXT: ret %result = call { <2 x float>, <2 x float> } @llvm.sincos.v2f32(<2 x float> %a) ret { <2 x float>, <2 x float> } %result } @@ -644,235 +280,127 @@ define { <2 x float>, <2 x float> } @test_sincos_v2f32(<2 x float> %a) #0 { ; } define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 { -; NONGNU-LABEL: test_sincos_f128: -; NONGNU: ; %bb.0: -; NONGNU-NEXT: push r2 -; NONGNU-NEXT: push r3 -; NONGNU-NEXT: push r4 -; NONGNU-NEXT: push r5 -; NONGNU-NEXT: push r6 -; NONGNU-NEXT: push r7 -; NONGNU-NEXT: push r28 -; NONGNU-NEXT: push r29 -; NONGNU-NEXT: in r28, 61 -; NONGNU-NEXT: in r29, 62 -; NONGNU-NEXT: sbiw r28, 34 -; NONGNU-NEXT: in r0, 63 -; NONGNU-NEXT: cli -; NONGNU-NEXT: out 62, r29 -; NONGNU-NEXT: out 63, r0 -; NONGNU-NEXT: out 61, r28 -; NONGNU-NEXT: std Y+2, r23 ; 2-byte Folded Spill -; NONGNU-NEXT: std Y+1, r22 ; 2-byte Folded Spill -; NONGNU-NEXT: mov r2, r20 -; NONGNU-NEXT: mov r3, r21 -; NONGNU-NEXT: mov r4, r18 -; NONGNU-NEXT: mov r5, r19 -; NONGNU-NEXT: mov r6, r24 -; NONGNU-NEXT: mov r7, r25 -; NONGNU-NEXT: mov r24, r28 -; NONGNU-NEXT: mov r25, r29 -; NONGNU-NEXT: adiw r24, 3 -; NONGNU-NEXT: rcall cosl -; NONGNU-NEXT: mov r24, r28 -; NONGNU-NEXT: mov r25, r29 -; NONGNU-NEXT: adiw r24, 19 -; NONGNU-NEXT: mov r18, r4 -; NONGNU-NEXT: mov r19, r5 -; NONGNU-NEXT: mov r20, r2 -; NONGNU-NEXT: mov r21, r3 -; NONGNU-NEXT: ldd r22, Y+1 ; 2-byte Folded Reload -; NONGNU-NEXT: ldd r23, Y+2 ; 2-byte Folded Reload -; NONGNU-NEXT: rcall sinl -; NONGNU-NEXT: ldd r24, Y+17 -; NONGNU-NEXT: ldd r25, Y+18 -; NONGNU-NEXT: mov r30, r6 -; NONGNU-NEXT: mov r31, r7 -; NONGNU-NEXT: std Z+31, r25 -; NONGNU-NEXT: std Z+30, r24 -; NONGNU-NEXT: ldd r24, Y+15 -; NONGNU-NEXT: ldd r25, Y+16 -; NONGNU-NEXT: std Z+29, r25 -; NONGNU-NEXT: std Z+28, r24 -; NONGNU-NEXT: ldd r24, Y+13 -; NONGNU-NEXT: ldd r25, Y+14 -; NONGNU-NEXT: std Z+27, r25 -; NONGNU-NEXT: std Z+26, r24 -; NONGNU-NEXT: ldd r24, Y+11 -; NONGNU-NEXT: ldd r25, Y+12 -; NONGNU-NEXT: std Z+25, r25 -; NONGNU-NEXT: std Z+24, r24 -; NONGNU-NEXT: ldd r24, Y+9 -; NONGNU-NEXT: ldd r25, Y+10 -; NONGNU-NEXT: std Z+23, r25 -; NONGNU-NEXT: std Z+22, r24 -; NONGNU-NEXT: ldd r24, Y+7 -; NONGNU-NEXT: ldd r25, Y+8 -; NONGNU-NEXT: std Z+21, r25 -; NONGNU-NEXT: std Z+20, r24 -; NONGNU-NEXT: ldd r24, Y+5 -; NONGNU-NEXT: ldd r25, Y+6 -; NONGNU-NEXT: std Z+19, r25 -; NONGNU-NEXT: std Z+18, r24 -; NONGNU-NEXT: ldd r24, Y+3 -; NONGNU-NEXT: ldd r25, Y+4 -; NONGNU-NEXT: std Z+17, r25 -; NONGNU-NEXT: std Z+16, r24 -; NONGNU-NEXT: ldd r24, Y+33 -; NONGNU-NEXT: ldd r25, Y+34 -; NONGNU-NEXT: std Z+15, r25 -; NONGNU-NEXT: std Z+14, r24 -; NONGNU-NEXT: ldd r24, Y+31 -; NONGNU-NEXT: ldd r25, Y+32 -; NONGNU-NEXT: std Z+13, r25 -; NONGNU-NEXT: std Z+12, r24 -; NONGNU-NEXT: ldd r24, Y+29 -; NONGNU-NEXT: ldd r25, Y+30 -; NONGNU-NEXT: std Z+11, r25 -; NONGNU-NEXT: std Z+10, r24 -; NONGNU-NEXT: ldd r24, Y+27 -; NONGNU-NEXT: ldd r25, Y+28 -; NONGNU-NEXT: std Z+9, r25 -; NONGNU-NEXT: std Z+8, r24 -; NONGNU-NEXT: ldd r24, Y+25 -; NONGNU-NEXT: ldd r25, Y+26 -; NONGNU-NEXT: std Z+7, r25 -; NONGNU-NEXT: std Z+6, r24 -; NONGNU-NEXT: ldd r24, Y+23 -; NONGNU-NEXT: ldd r25, Y+24 -; NONGNU-NEXT: std Z+5, r25 -; NONGNU-NEXT: std Z+4, r24 -; NONGNU-NEXT: ldd r24, Y+21 -; NONGNU-NEXT: ldd r25, Y+22 -; NONGNU-NEXT: std Z+3, r25 -; NONGNU-NEXT: std Z+2, r24 -; NONGNU-NEXT: ldd r24, Y+19 -; NONGNU-NEXT: ldd r25, Y+20 -; NONGNU-NEXT: std Z+1, r25 -; NONGNU-NEXT: st Z, r24 -; NONGNU-NEXT: adiw r28, 34 -; NONGNU-NEXT: in r0, 63 -; NONGNU-NEXT: cli -; NONGNU-NEXT: out 62, r29 -; NONGNU-NEXT: out 63, r0 -; NONGNU-NEXT: out 61, r28 -; NONGNU-NEXT: pop r29 -; NONGNU-NEXT: pop r28 -; NONGNU-NEXT: pop r7 -; NONGNU-NEXT: pop r6 -; NONGNU-NEXT: pop r5 -; NONGNU-NEXT: pop r4 -; NONGNU-NEXT: pop r3 -; NONGNU-NEXT: pop r2 -; NONGNU-NEXT: ret -; -; GNU-LABEL: test_sincos_f128: -; GNU: ; %bb.0: -; GNU-NEXT: push r6 -; GNU-NEXT: push r7 -; GNU-NEXT: push r28 -; GNU-NEXT: push r29 -; GNU-NEXT: in r28, 61 -; GNU-NEXT: in r29, 62 -; GNU-NEXT: sbiw r28, 52 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: mov r6, r24 -; GNU-NEXT: mov r7, r25 -; GNU-NEXT: mov r24, r28 -; GNU-NEXT: mov r25, r29 -; GNU-NEXT: adiw r24, 21 -; GNU-NEXT: std Y+4, r25 -; GNU-NEXT: std Y+3, r24 -; GNU-NEXT: mov r24, r28 -; GNU-NEXT: mov r25, r29 -; GNU-NEXT: adiw r24, 37 -; GNU-NEXT: std Y+2, r25 -; GNU-NEXT: std Y+1, r24 -; GNU-NEXT: mov r24, r28 -; GNU-NEXT: mov r25, r29 -; GNU-NEXT: adiw r24, 5 -; GNU-NEXT: rcall sincosl -; GNU-NEXT: ldd r24, Y+35 -; GNU-NEXT: ldd r25, Y+36 -; GNU-NEXT: mov r30, r6 -; GNU-NEXT: mov r31, r7 -; GNU-NEXT: std Z+31, r25 -; GNU-NEXT: std Z+30, r24 -; GNU-NEXT: ldd r24, Y+33 -; GNU-NEXT: ldd r25, Y+34 -; GNU-NEXT: std Z+29, r25 -; GNU-NEXT: std Z+28, r24 -; GNU-NEXT: ldd r24, Y+31 -; GNU-NEXT: ldd r25, Y+32 -; GNU-NEXT: std Z+27, r25 -; GNU-NEXT: std Z+26, r24 -; GNU-NEXT: ldd r24, Y+29 -; GNU-NEXT: ldd r25, Y+30 -; GNU-NEXT: std Z+25, r25 -; GNU-NEXT: std Z+24, r24 -; GNU-NEXT: ldd r24, Y+27 -; GNU-NEXT: ldd r25, Y+28 -; GNU-NEXT: std Z+23, r25 -; GNU-NEXT: std Z+22, r24 -; GNU-NEXT: ldd r24, Y+25 -; GNU-NEXT: ldd r25, Y+26 -; GNU-NEXT: std Z+21, r25 -; GNU-NEXT: std Z+20, r24 -; GNU-NEXT: ldd r24, Y+23 -; GNU-NEXT: ldd r25, Y+24 -; GNU-NEXT: std Z+19, r25 -; GNU-NEXT: std Z+18, r24 -; GNU-NEXT: ldd r24, Y+21 -; GNU-NEXT: ldd r25, Y+22 -; GNU-NEXT: std Z+17, r25 -; GNU-NEXT: std Z+16, r24 -; GNU-NEXT: ldd r24, Y+51 -; GNU-NEXT: ldd r25, Y+52 -; GNU-NEXT: std Z+15, r25 -; GNU-NEXT: std Z+14, r24 -; GNU-NEXT: ldd r24, Y+49 -; GNU-NEXT: ldd r25, Y+50 -; GNU-NEXT: std Z+13, r25 -; GNU-NEXT: std Z+12, r24 -; GNU-NEXT: ldd r24, Y+47 -; GNU-NEXT: ldd r25, Y+48 -; GNU-NEXT: std Z+11, r25 -; GNU-NEXT: std Z+10, r24 -; GNU-NEXT: ldd r24, Y+45 -; GNU-NEXT: ldd r25, Y+46 -; GNU-NEXT: std Z+9, r25 -; GNU-NEXT: std Z+8, r24 -; GNU-NEXT: ldd r24, Y+43 -; GNU-NEXT: ldd r25, Y+44 -; GNU-NEXT: std Z+7, r25 -; GNU-NEXT: std Z+6, r24 -; GNU-NEXT: ldd r24, Y+41 -; GNU-NEXT: ldd r25, Y+42 -; GNU-NEXT: std Z+5, r25 -; GNU-NEXT: std Z+4, r24 -; GNU-NEXT: ldd r24, Y+39 -; GNU-NEXT: ldd r25, Y+40 -; GNU-NEXT: std Z+3, r25 -; GNU-NEXT: std Z+2, r24 -; GNU-NEXT: ldd r24, Y+37 -; GNU-NEXT: ldd r25, Y+38 -; GNU-NEXT: std Z+1, r25 -; GNU-NEXT: st Z, r24 -; GNU-NEXT: adiw r28, 52 -; GNU-NEXT: in r0, 63 -; GNU-NEXT: cli -; GNU-NEXT: out 62, r29 -; GNU-NEXT: out 63, r0 -; GNU-NEXT: out 61, r28 -; GNU-NEXT: pop r29 -; GNU-NEXT: pop r28 -; GNU-NEXT: pop r7 -; GNU-NEXT: pop r6 -; GNU-NEXT: ret +; CHECK-LABEL: test_sincos_f128: +; CHECK: ; %bb.0: +; CHECK-NEXT: push r2 +; CHECK-NEXT: push r3 +; CHECK-NEXT: push r4 +; CHECK-NEXT: push r5 +; CHECK-NEXT: push r6 +; CHECK-NEXT: push r7 +; CHECK-NEXT: push r28 +; CHECK-NEXT: push r29 +; CHECK-NEXT: in r28, 61 +; CHECK-NEXT: in r29, 62 +; CHECK-NEXT: sbiw r28, 34 +; CHECK-NEXT: in r0, 63 +; CHECK-NEXT: cli +; CHECK-NEXT: out 62, r29 +; CHECK-NEXT: out 63, r0 +; CHECK-NEXT: out 61, r28 +; CHECK-NEXT: std Y+2, r23 ; 2-byte Folded Spill +; CHECK-NEXT: std Y+1, r22 ; 2-byte Folded Spill +; CHECK-NEXT: mov r2, r20 +; CHECK-NEXT: mov r3, r21 +; CHECK-NEXT: mov r4, r18 +; CHECK-NEXT: mov r5, r19 +; CHECK-NEXT: mov r6, r24 +; CHECK-NEXT: mov r7, r25 +; CHECK-NEXT: mov r24, r28 +; CHECK-NEXT: mov r25, r29 +; CHECK-NEXT: adiw r24, 3 +; CHECK-NEXT: rcall cosl +; CHECK-NEXT: mov r24, r28 +; CHECK-NEXT: mov r25, r29 +; CHECK-NEXT: adiw r24, 19 +; CHECK-NEXT: mov r18, r4 +; CHECK-NEXT: mov r19, r5 +; CHECK-NEXT: mov r20, r2 +; CHECK-NEXT: mov r21, r3 +; CHECK-NEXT: ldd r22, Y+1 ; 2-byte Folded Reload +; CHECK-NEXT: ldd r23, Y+2 ; 2-byte Folded Reload +; CHECK-NEXT: rcall sinl +; CHECK-NEXT: ldd r24, Y+17 +; CHECK-NEXT: ldd r25, Y+18 +; CHECK-NEXT: mov r30, r6 +; CHECK-NEXT: mov r31, r7 +; CHECK-NEXT: std Z+31, r25 +; CHECK-NEXT: std Z+30, r24 +; CHECK-NEXT: ldd r24, Y+15 +; CHECK-NEXT: ldd r25, Y+16 +; CHECK-NEXT: std Z+29, r25 +; CHECK-NEXT: std Z+28, r24 +; CHECK-NEXT: ldd r24, Y+13 +; CHECK-NEXT: ldd r25, Y+14 +; CHECK-NEXT: std Z+27, r25 +; CHECK-NEXT: std Z+26, r24 +; CHECK-NEXT: ldd r24, Y+11 +; CHECK-NEXT: ldd r25, Y+12 +; CHECK-NEXT: std Z+25, r25 +; CHECK-NEXT: std Z+24, r24 +; CHECK-NEXT: ldd r24, Y+9 +; CHECK-NEXT: ldd r25, Y+10 +; CHECK-NEXT: std Z+23, r25 +; CHECK-NEXT: std Z+22, r24 +; CHECK-NEXT: ldd r24, Y+7 +; CHECK-NEXT: ldd r25, Y+8 +; CHECK-NEXT: std Z+21, r25 +; CHECK-NEXT: std Z+20, r24 +; CHECK-NEXT: ldd r24, Y+5 +; CHECK-NEXT: ldd r25, Y+6 +; CHECK-NEXT: std Z+19, r25 +; CHECK-NEXT: std Z+18, r24 +; CHECK-NEXT: ldd r24, Y+3 +; CHECK-NEXT: ldd r25, Y+4 +; CHECK-NEXT: std Z+17, r25 +; CHECK-NEXT: std Z+16, r24 +; CHECK-NEXT: ldd r24, Y+33 +; CHECK-NEXT: ldd r25, Y+34 +; CHECK-NEXT: std Z+15, r25 +; CHECK-NEXT: std Z+14, r24 +; CHECK-NEXT: ldd r24, Y+31 +; CHECK-NEXT: ldd r25, Y+32 +; CHECK-NEXT: std Z+13, r25 +; CHECK-NEXT: std Z+12, r24 +; CHECK-NEXT: ldd r24, Y+29 +; CHECK-NEXT: ldd r25, Y+30 +; CHECK-NEXT: std Z+11, r25 +; CHECK-NEXT: std Z+10, r24 +; CHECK-NEXT: ldd r24, Y+27 +; CHECK-NEXT: ldd r25, Y+28 +; CHECK-NEXT: std Z+9, r25 +; CHECK-NEXT: std Z+8, r24 +; CHECK-NEXT: ldd r24, Y+25 +; CHECK-NEXT: ldd r25, Y+26 +; CHECK-NEXT: std Z+7, r25 +; CHECK-NEXT: std Z+6, r24 +; CHECK-NEXT: ldd r24, Y+23 +; CHECK-NEXT: ldd r25, Y+24 +; CHECK-NEXT: std Z+5, r25 +; CHECK-NEXT: std Z+4, r24 +; CHECK-NEXT: ldd r24, Y+21 +; CHECK-NEXT: ldd r25, Y+22 +; CHECK-NEXT: std Z+3, r25 +; CHECK-NEXT: std Z+2, r24 +; CHECK-NEXT: ldd r24, Y+19 +; CHECK-NEXT: ldd r25, Y+20 +; CHECK-NEXT: std Z+1, r25 +; CHECK-NEXT: st Z, r24 +; CHECK-NEXT: adiw r28, 34 +; CHECK-NEXT: in r0, 63 +; CHECK-NEXT: cli +; CHECK-NEXT: out 62, r29 +; CHECK-NEXT: out 63, r0 +; CHECK-NEXT: out 61, r28 +; CHECK-NEXT: pop r29 +; CHECK-NEXT: pop r28 +; CHECK-NEXT: pop r7 +; CHECK-NEXT: pop r6 +; CHECK-NEXT: pop r5 +; CHECK-NEXT: pop r4 +; CHECK-NEXT: pop r3 +; CHECK-NEXT: pop r2 +; CHECK-NEXT: ret %result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a) ret { fp128, fp128 } %result } @@ -880,4 +408,5 @@ define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 { attributes #0 = { nounwind } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; GNU: {{.*}} +; NONGNU: {{.*}} diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td index 783a861cfe756..642f8b85a89c6 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td @@ -104,18 +104,6 @@ def BlahLibrary : SystemRuntimeLibrarysecond; - OS << " "; - LibCallImpl->emitEnumEntry(OS); - OS << ','; - } - - OS << " // "; - LibCall.emitEnumEntry(OS); - OS << '\n'; - } - - OS << " RTLIB::Unsupported\n" - "};\n\n"; - // Emit the implementation names StringToOffsetTable Table(/*AppendZero=*/true, "RTLIB::RuntimeLibcallsInfo::"); @@ -545,13 +522,11 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( TopLevelPredicate.emitEndIf(OS); } - // Fallback to the old default set for manual table entries. - // - // TODO: Remove this when targets have switched to using generated tables by - // default. - OS << " initDefaultLibCallImpls();\n"; - - OS << "}\n\n"; + // FIXME: This should be a fatal error. A few contexts are improperly relying + // on RuntimeLibcalls constructed with fully unknown triples. + OS << " LLVM_DEBUG(dbgs() << \"no system runtime library applied to target " + "\\'\" << TT.str() << \"\\'\\n\");\n" + "}\n\n"; } void RuntimeLibcallEmitter::run(raw_ostream &OS) { From c992d2b889fcdc6c0d0172d3491db3da11caa23d Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sun, 27 Jul 2025 23:26:20 +0900 Subject: [PATCH 2/2] RuntimeLibcalls: Add bitset for available libcalls This is a step towards separating the set of available libcalls from the lowering decision of which call to use. Libcall recognition now directly checks availability instead of indirectly checking through the lowering table. --- llvm/include/llvm/IR/RuntimeLibcalls.h | 64 +++++++++++++++++++ llvm/lib/IR/RuntimeLibcalls.cpp | 8 +-- .../RuntimeLibcallEmitter-calling-conv.td | 22 +++++++ .../RuntimeLibcallEmitter-conflict-warning.td | 15 +++++ llvm/test/TableGen/RuntimeLibcallEmitter.td | 27 ++++++++ .../TableGen/Basic/RuntimeLibcallsEmitter.cpp | 36 ++++++++++- 6 files changed, 164 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index f39e2e3c26900..8a5f953b68f9d 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -53,8 +53,64 @@ static inline auto libcall_impls() { return enum_seq(static_cast(1), RTLIB::NumLibcallImpls); } +/// Manage a bitset representing the list of available libcalls for a module. +/// +/// Most of this exists because std::bitset cannot be statically constructed in +/// a size large enough before c++23 +class LibcallImplBitset { +private: + using BitWord = uint64_t; + static constexpr unsigned BitWordSize = sizeof(BitWord) * CHAR_BIT; + static constexpr size_t NumArrayElts = + divideCeil(RTLIB::NumLibcallImpls, BitWordSize); + using Storage = BitWord[NumArrayElts]; + + Storage Bits = {}; + + /// Get bitmask for \p Impl in its Bits element. + static constexpr BitWord getBitmask(RTLIB::LibcallImpl Impl) { + unsigned Idx = static_cast(Impl); + return BitWord(1) << (Idx % BitWordSize); + } + + /// Get index of array element of Bits for \p Impl + static constexpr unsigned getArrayIdx(RTLIB::LibcallImpl Impl) { + return static_cast(Impl) / BitWordSize; + } + +public: + constexpr LibcallImplBitset() = default; + constexpr LibcallImplBitset(const Storage &Src) { + for (size_t I = 0; I != NumArrayElts; ++I) + Bits[I] = Src[I]; + } + + /// Check if a LibcallImpl is available. + constexpr bool test(RTLIB::LibcallImpl Impl) const { + BitWord Mask = getBitmask(Impl); + return (Bits[getArrayIdx(Impl)] & Mask) != 0; + } + + /// Mark a LibcallImpl as available + void set(RTLIB::LibcallImpl Impl) { + assert(Impl != RTLIB::Unsupported && "cannot enable unsupported libcall"); + Bits[getArrayIdx(Impl)] |= getBitmask(Impl); + } + + /// Mark a LibcallImpl as unavailable + void unset(RTLIB::LibcallImpl Impl) { + assert(Impl != RTLIB::Unsupported && "cannot enable unsupported libcall"); + Bits[getArrayIdx(Impl)] &= ~getBitmask(Impl); + } +}; + /// A simple container for information about the supported runtime calls. struct RuntimeLibcallsInfo { +private: + /// Bitset of libcalls a module may emit a call to. + LibcallImplBitset AvailableLibcallImpls; + +public: explicit RuntimeLibcallsInfo( const Triple &TT, ExceptionHandling ExceptionModel = ExceptionHandling::None, @@ -132,6 +188,14 @@ struct RuntimeLibcallsInfo { return ImplToLibcall[Impl]; } + bool isAvailable(RTLIB::LibcallImpl Impl) const { + return AvailableLibcallImpls.test(Impl); + } + + void setAvailable(RTLIB::LibcallImpl Impl) { + AvailableLibcallImpls.set(Impl); + } + /// Check if this is valid libcall for the current module, otherwise /// RTLIB::Unsupported. LLVM_ABI RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const; diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 8c90c52141dc7..569f63f28db77 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -114,12 +114,8 @@ RuntimeLibcallsInfo::getSupportedLibcallImpl(StringRef FuncName) const { for (auto I = Range.begin(); I != Range.end(); ++I) { RTLIB::LibcallImpl Impl = static_cast(I - RuntimeLibcallNameOffsets.begin()); - - // FIXME: This should not depend on looking up ImplToLibcall, only the list - // of libcalls for the module. - RTLIB::LibcallImpl Recognized = LibcallImpls[ImplToLibcall[Impl]]; - if (Recognized != RTLIB::Unsupported) - return Recognized; + if (isAvailable(Impl)) + return Impl; } return RTLIB::Unsupported; diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td index 49d5ecaa0e5c5..14c811da64910 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td @@ -48,12 +48,18 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary; // 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 LibcallImplPair LibraryCalls[] = { // CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::func_b}, // func_b // CHECK-NEXT: }; @@ -35,6 +40,11 @@ def TheSystemLibraryA : SystemRuntimeLibrary; // CHECK: if (isTargetArchB()) { +// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({ +// CHECK-NEXT: 0x00000000000058 +// CHECK-NEXT: }); +// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls; +// CHECK-EMPTY: // CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = { // CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::other_func}, // other_func // CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::func_a}, // func_a @@ -46,6 +56,11 @@ def TheSystemLibraryB : SystemRuntimeLibrary; // CHECK: if (isTargetArchC()) { +// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({ +// CHECK-NEXT: 0x0000000000007e +// CHECK-NEXT: }); +// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls; +// CHECK-EMPTY: // CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = { // CHECK-NEXT: {RTLIB::ANOTHER_DUP, RTLIB::dup1}, // dup1 // CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::other_func}, // other_func diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td index 642f8b85a89c6..97a632e8e75c7 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td @@ -157,6 +157,11 @@ def BlahLibrary : SystemRuntimeLibrary Pred2Funcs; + + SmallVector BitsetValues( + divideCeil(RuntimeLibcallImplDefList.size(), 64)); + for (const Record *Elt : *Elements) { const RuntimeLibcallImpl *LibCallImpl = getRuntimeLibcallImpl(Elt); if (!LibCallImpl) { @@ -410,16 +415,24 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( continue; } + size_t BitIdx = LibCallImpl->getEnumVal(); + uint64_t BitmaskVal = uint64_t(1) << (BitIdx % 64); + size_t BitsetIdx = BitIdx / 64; + auto It = Func2Preds.find(LibCallImpl); if (It == Func2Preds.end()) { + BitsetValues[BitsetIdx] |= BitmaskVal; Pred2Funcs[PredicateWithCC()].LibcallImpls.push_back(LibCallImpl); continue; } for (const Record *Pred : It->second.first) { const Record *CC = It->second.second; - PredicateWithCC Key(Pred, CC); + AvailabilityPredicate SubsetPredicate(Pred); + if (SubsetPredicate.isAlwaysAvailable()) + BitsetValues[BitsetIdx] |= BitmaskVal; + PredicateWithCC Key(Pred, CC); auto &Entry = Pred2Funcs[Key]; Entry.LibcallImpls.push_back(LibCallImpl); Entry.CallingConv = It->second.second; @@ -427,6 +440,22 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( } } + OS << " static constexpr LibcallImplBitset SystemAvailableImpls({\n" + << indent(6); + + ListSeparator LS; + unsigned EntryCount = 0; + for (uint64_t Bits : BitsetValues) { + if (EntryCount++ == 4) { + EntryCount = 1; + OS << ",\n" << indent(6); + } else + OS << LS; + OS << format_hex(Bits, 16); + } + OS << "\n });\n" + " AvailableLibcallImpls = SystemAvailableImpls;\n\n"; + SmallVector SortedPredicates = PredicateSorter.takeVector(); @@ -498,8 +527,11 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( << indent(IndentDepth + 2) << "for (const auto [Func, Impl] : LibraryCalls"; SubsetPredicate.emitTableVariableNameSuffix(OS); + + // TODO: setAvailable should be emitted without the uniquing above OS << ") {\n" - << indent(IndentDepth + 4) << "setLibcallImpl(Func, Impl);\n"; + << indent(IndentDepth + 4) << "setLibcallImpl(Func, Impl);\n" + << indent(IndentDepth + 4) << "setAvailable(Impl);\n"; if (FuncsWithCC.CallingConv) { StringRef CCEnum =