From 7e51c6b9a7e2ef6de8856afb619326e17f9ba80a Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 11 Aug 2023 22:16:01 -0400 Subject: [PATCH 1/2] [IR] Add a test for `f128` libm libcall lowering (NFC) `f128` intrinsic functions from libm sometimes lower to `long double` library calls when they instead need to be `f128` versions. Add a generic test demonstrating current behavior. --- .../CodeGen/Generic/fp128-math-libcalls.ll | 337 ++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 llvm/test/CodeGen/Generic/fp128-math-libcalls.ll diff --git a/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll b/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll new file mode 100644 index 0000000000000..159b3bda6b794 --- /dev/null +++ b/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll @@ -0,0 +1,337 @@ +; Verify that fp128 intrinsics only lower to `long double` calls (e.g. sinl) on +; platforms where 128 and `long double` have the same layout.Otherwise, lower +; to f128 versions (e.g. sinf128). +; +; Targets include: +; * aarch64 (long double == f128, should use ld syms) +; * arm (long double == f64, should use f128 syms) +; * s390x (long double == f128, should use ld syms, some hardware support) +; * x86, x64 (80-bit long double, should use ld syms) +; * gnu (has f128 symbols on all platforms so we can use those) +; * musl (no f128 symbols available) +; * Windows and MacOS (no f128 symbols, long double == f64) + +; FIXME(#44744): arm32, x86-{32,64} musl targets, MacOS, and Windows don't have +; f128 long double. They should be passing with CHECK-F128 rather than +; CHECK-USELD. + +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=arm64-apple-macosx -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-none-eabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-unknown-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if riscv-registered-target %{ llc < %s -mtriple=riscv32-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if systemz-registered-target %{ llc < %s -mtriple=s390x-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-S390X %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; +; FIXME(#144006): Windows-MSVC should also be run but has a ldexp selection +; failure. +; %if x86-registered-target %{ llc < %s -mtriple=x86_64-pc-windows-msvc -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} + +define fp128 @test_acos(fp128 %a) { +; CHECK-ALL-LABEL: test_acos: +; CHECK-F128: acosf128 +; CHECK-USELD: acosl +; CHECK-S390X: acosl +start: + %0 = tail call fp128 @llvm.acos.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_asin(fp128 %a) { +; CHECK-ALL-LABEL: test_asin: +; CHECK-F128: asinf128 +; CHECK-USELD: asinl +; CHECK-S390X: asinl +start: + %0 = tail call fp128 @llvm.asin.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_atan(fp128 %a) { +; CHECK-ALL-LABEL: test_atan: +; CHECK-F128: atanf128 +; CHECK-USELD: atanl +; CHECK-S390X: atanl +start: + %0 = tail call fp128 @llvm.atan.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_ceil(fp128 %a) { +; CHECK-ALL-LABEL: test_ceil: +; CHECK-F128: ceilf128 +; CHECK-USELD: ceill +; CHECK-S390X: ceill +start: + %0 = tail call fp128 @llvm.ceil.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_copysign(fp128 %a, fp128 %b) { +; copysign should always get lowered to assembly. +; CHECK-ALL-LABEL: test_copysign: +; CHECK-ALL-NOT: copysignf128 +; CHECK-ALL-NOT: copysignl +start: + %0 = tail call fp128 @llvm.copysign.f128(fp128 %a, fp128 %b) + ret fp128 %0 +} + +define fp128 @test_cos(fp128 %a) { +; CHECK-ALL-LABEL: test_cos: +; CHECK-F128: cosf128 +; CHECK-USELD: cosl +; CHECK-S390X: cosl +start: + %0 = tail call fp128 @llvm.cos.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_exp10(fp128 %a) { +; CHECK-ALL-LABEL: test_exp10: +; CHECK-F128: exp10f128 +; CHECK-USELD: exp10l +; CHECK-S390X: exp10l +start: + %0 = tail call fp128 @llvm.exp10.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_exp2(fp128 %a) { +; CHECK-ALL-LABEL: test_exp2: +; CHECK-F128: exp2f128 +; CHECK-USELD: exp2l +; CHECK-S390X: exp2l +start: + %0 = tail call fp128 @llvm.exp2.f128(fp128 %a) + ret fp128 %0 +} + + +define fp128 @test_exp(fp128 %a) { +; CHECK-ALL-LABEL: test_exp: +; CHECK-F128: expf128 +; CHECK-USELD: expl +; CHECK-S390X: expl +start: + %0 = tail call fp128 @llvm.exp.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_fabs(fp128 %a) { +; fabs should always get lowered to assembly. +; CHECK-ALL-LABEL: test_fabs: +; CHECK-ALL-NOT: fabsf128 +; CHECK-ALL-NOT: fabsl +start: + %0 = tail call fp128 @llvm.fabs.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_floor(fp128 %a) { +; CHECK-ALL-LABEL: test_floor: +; CHECK-F128: floorf128 +; CHECK-USELD: floorl +; CHECK-S390X: floorl +start: + %0 = tail call fp128 @llvm.floor.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_fma(fp128 %a, fp128 %b, fp128 %c) { +; CHECK-ALL-LABEL: test_fma: +; CHECK-F128: fmaf128 +; CHECK-USELD: fmal +; CHECK-S390X: fmal +start: + %0 = tail call fp128 @llvm.fma.f128(fp128 %a, fp128 %b, fp128 %c) + ret fp128 %0 +} + +define { fp128, i32 } @test_frexp(fp128 %a) { +; CHECK-ALL-LABEL: test_frexp: +; CHECK-F128: frexpf128 +; CHECK-USELD: frexpl +; CHECK-S390X: frexpl +start: + %0 = tail call { fp128, i32 } @llvm.frexp.f128(fp128 %a) + ret { fp128, i32 } %0 +} + +define fp128 @test_ldexp(fp128 %a, i32 %b) { +; CHECK-ALL-LABEL: test_ldexp: +; CHECK-F128: ldexpf128 +; CHECK-USELD: ldexpl +; CHECK-S390X: ldexpl +start: + %0 = tail call fp128 @llvm.ldexp.f128(fp128 %a, i32 %b) + ret fp128 %0 +} + +define i64 @test_llrint(fp128 %a) { +; CHECK-ALL-LABEL: test_llrint: +; CHECK-F128: llrintf128 +; CHECK-USELD: llrintl +; CHECK-S390X: llrintl +start: + %0 = tail call i64 @llvm.llrint.f128(fp128 %a) + ret i64 %0 +} + +define i64 @test_llround(fp128 %a) { +; CHECK-ALL-LABEL: test_llround: +; CHECK-F128: llroundf128 +; CHECK-USELD: llroundl +; CHECK-S390X: llroundl +start: + %0 = tail call i64 @llvm.llround.i64.f128(fp128 %a) + ret i64 %0 +} + +define fp128 @test_log10(fp128 %a) { +; CHECK-ALL-LABEL: test_log10: +; CHECK-F128: log10f128 +; CHECK-USELD: log10l +; CHECK-S390X: log10l +start: + %0 = tail call fp128 @llvm.log10.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_log2(fp128 %a) { +; CHECK-ALL-LABEL: test_log2: +; CHECK-F128: log2f128 +; CHECK-USELD: log2l +; CHECK-S390X: log2l +start: + %0 = tail call fp128 @llvm.log2.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_log(fp128 %a) { +; CHECK-ALL-LABEL: test_log: +; CHECK-F128: logf128 +; CHECK-USELD: logl +; CHECK-S390X: logl +start: + %0 = tail call fp128 @llvm.log.f128(fp128 %a) + ret fp128 %0 +} + +define i64 @test_lrint(fp128 %a) { +; CHECK-ALL-LABEL: test_lrint: +; CHECK-F128: lrintf128 +; CHECK-USELD: lrintl +; CHECK-S390X: lrintl +start: + %0 = tail call i64 @llvm.lrint.f128(fp128 %a) + ret i64 %0 +} + +define i64 @test_lround(fp128 %a) { +; CHECK-ALL-LABEL: test_lround: +; CHECK-F128: lroundf128 +; CHECK-USELD: lroundl +; CHECK-S390X: lroundl +start: + %0 = tail call i64 @llvm.lround.i64.f128(fp128 %a) + ret i64 %0 +} + +define fp128 @test_nearbyint(fp128 %a) { +; CHECK-ALL-LABEL: test_nearbyint: +; CHECK-F128: nearbyintf128 +; CHECK-USELD: nearbyintl +; CHECK-S390X: nearbyintl +start: + %0 = tail call fp128 @llvm.nearbyint.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_pow(fp128 %a, fp128 %b) { +; CHECK-ALL-LABEL: test_pow: +; CHECK-F128: powf128 +; CHECK-USELD: powl +; CHECK-S390X: powl +start: + %0 = tail call fp128 @llvm.pow.f128(fp128 %a, fp128 %b) + ret fp128 %0 +} + +define fp128 @test_rint(fp128 %a) { +; CHECK-ALL-LABEL: test_rint: +; CHECK-F128: rintf128 +; CHECK-USELD: rintl +; CHECK-S390X: fixbr {{%.*}}, 0, {{%.*}} +start: + %0 = tail call fp128 @llvm.rint.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_roundeven(fp128 %a) { +; CHECK-ALL-LABEL: test_roundeven: +; CHECK-F128: roundevenf128 +; CHECK-USELD: roundevenl +; CHECK-S390X: roundevenl +start: + %0 = tail call fp128 @llvm.roundeven.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_round(fp128 %a) { +; CHECK-ALL-LABEL: test_round: +; CHECK-F128: roundf128 +; CHECK-USELD: roundl +; CHECK-S390X: roundl +start: + %0 = tail call fp128 @llvm.round.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_sin(fp128 %a) { +; CHECK-ALL-LABEL: test_sin: +; CHECK-F128: sinf128 +; CHECK-USELD: sinl +; CHECK-S390X: sinl +start: + %0 = tail call fp128 @llvm.sin.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_sqrt(fp128 %a) { +; CHECK-ALL-LABEL: test_sqrt: +; CHECK-F128: sqrtf128 +; CHECK-USELD: sqrtl +; CHECK-S390X: sqxbr {{%.*}}, {{%.*}} +start: + %0 = tail call fp128 @llvm.sqrt.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_tan(fp128 %a) { +; CHECK-ALL-LABEL: test_tan: +; CHECK-F128: tanf128 +; CHECK-USELD: tanl +; CHECK-S390X: tanl +start: + %0 = tail call fp128 @llvm.tan.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_trunc(fp128 %a) { +; CHECK-ALL-LABEL: test_trunc: +; CHECK-F128: truncf128 +; CHECK-USELD: truncl +; CHECK-S390X: truncl +start: + %0 = tail call fp128 @llvm.trunc.f128(fp128 %a) + ret fp128 %0 +} From dc5ccd8724fadebdcd5ce5681a1fe8b8854c37da Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 13 Jul 2025 14:26:52 -0400 Subject: [PATCH 2/2] Apply review comments --- .../CodeGen/Generic/fp128-math-libcalls.ll | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll b/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll index 159b3bda6b794..ccce4bbd2a327 100644 --- a/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll +++ b/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll @@ -1,5 +1,5 @@ ; Verify that fp128 intrinsics only lower to `long double` calls (e.g. sinl) on -; platforms where 128 and `long double` have the same layout.Otherwise, lower +; platforms where 128 and `long double` have the same layout. Otherwise, lower ; to f128 versions (e.g. sinf128). ; ; Targets include: @@ -15,21 +15,21 @@ ; f128 long double. They should be passing with CHECK-F128 rather than ; CHECK-USELD. -; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=arm64-apple-macosx -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-none-eabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-unknown-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} -; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} -; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} -; RUN: %if riscv-registered-target %{ llc < %s -mtriple=riscv32-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if systemz-registered-target %{ llc < %s -mtriple=s390x-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-S390X %} -; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} -; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} -; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=aarch64-unknown-none | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if aarch64-registered-target %{ llc < %s -mtriple=arm64-apple-macosx | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-none-eabi | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if arm-registered-target %{ llc < %s -mtriple=arm-unknown-linux-gnueabi | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if powerpc-registered-target %{ llc < %s -mtriple=powerpc64-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if riscv-registered-target %{ llc < %s -mtriple=riscv32-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if systemz-registered-target %{ llc < %s -mtriple=s390x-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-S390X %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} ; ; FIXME(#144006): Windows-MSVC should also be run but has a ldexp selection ; failure.