[clang] [llvm] [WIP] Correct lowering of `fp128` intrinsics (PR #76558)
Trevor Gross via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 26 19:55:24 PDT 2025
https://github.com/tgross35 updated https://github.com/llvm/llvm-project/pull/76558
>From 9089a966f2107a2dfcad86fec746e9f2bd8a105b Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross at umich.edu>
Date: Fri, 11 Aug 2023 22:16:01 -0400
Subject: [PATCH 1/5] [IR] Add a test for `f128` libcall lowering (NFC)
`f128` intrinsic functions sometimes lower to `long double` library
calls when they instead need to be `f128` versions. Add a test
demonstrating current behavior.
---
.../CodeGen/Generic/f128-math-lowering.ll | 328 ++++++++++++++++++
1 file changed, 328 insertions(+)
create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll
diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
new file mode 100644
index 0000000000000..dfbd1eaeda109
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -0,0 +1,328 @@
+; RUN: llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+; RUN: llc < %s -mtriple=s390x-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-S390X
+; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+;
+; REQUIRES: aarch64-registered-target
+; REQUIRES: riscv-registered-target
+; REQUIRES: systemz-registered-target
+; REQUIRES: x86-registered-target
+;
+; Verify that fp128 intrinsics only lower to `long double` calls (e.g. `sinl`)
+; on platforms where `f128` and `long double` have the same layout, and
+; otherwise lower to `f128` versions (e.g. `sinf128`).
+;
+; Targets include:
+; * x86, x64 (80-bit long double)
+; * aarch64 (long double == f128)
+; * riscv32 (long double == f64)
+; * s390x (long double == f128, hardware support)
+; * A couple assorted environments for x86
+;
+; FIXME: only targets where long double is `f128` should be using `USELD`, all
+; others need to be NOTLD. PowerPC should be added but it currently emits an
+; interesting blend of both (e.g. `acosl` but `ceilf128`).
+
+define fp128 @test_acosf128(fp128 %a) {
+; CHECK-LABEL: test_acosf128:
+; CHECK-NOTLD: acosf128
+; CHECK-USELD: acosl
+; CHECK-S390X: acosl
+start:
+ %0 = tail call fp128 @llvm.acos.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_asinf128(fp128 %a) {
+; CHECK-LABEL: test_asinf128:
+; CHECK-NOTLD: asinf128
+; CHECK-USELD: asinl
+; CHECK-S390X: asinl
+start:
+ %0 = tail call fp128 @llvm.asin.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_atanf128(fp128 %a) {
+; CHECK-LABEL: test_atanf128:
+; CHECK-NOTLD: atanf128
+; CHECK-USELD: atanl
+; CHECK-S390X: atanl
+start:
+ %0 = tail call fp128 @llvm.atan.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_ceilf128(fp128 %a) {
+; CHECK-LABEL: test_ceilf128:
+; CHECK-NOTLD: ceilf128
+; CHECK-USELD: ceill
+; CHECK-S390X: ceill
+start:
+ %0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
+; copysign should always get lowered to assembly
+; CHECK-LABEL: test_copysignf128:
+; CHECK-NOT: copysignl
+; CHECK-NOT: copysignf128
+start:
+ %0 = tail call fp128 @llvm.copysign.f128(fp128 %a, fp128 %b)
+ ret fp128 %0
+}
+
+define fp128 @test_cosf128(fp128 %a) {
+; CHECK-LABEL: test_cosf128:
+; CHECK-NOTLD: cosf128
+; CHECK-USELD: cosl
+; CHECK-S390X: cosl
+start:
+ %0 = tail call fp128 @llvm.cos.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_exp10f128(fp128 %a) {
+; CHECK-LABEL: test_exp2f128:
+; CHECK-NOTLD: exp10f128
+; CHECK-USELD: exp10l
+; CHECK-S390X: exp10l
+start:
+ %0 = tail call fp128 @llvm.exp10.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_exp2f128(fp128 %a) {
+; CHECK-LABEL: test_exp2f128:
+; CHECK-NOTLD: exp2f128
+; CHECK-USELD: exp2l
+; CHECK-S390X: exp2l
+start:
+ %0 = tail call fp128 @llvm.exp2.f128(fp128 %a)
+ ret fp128 %0
+}
+
+
+define fp128 @test_expf128(fp128 %a) {
+; CHECK-LABEL: test_expf128:
+; CHECK-NOTLD: expf128
+; CHECK-USELD: expl
+; CHECK-S390X: expl
+start:
+ %0 = tail call fp128 @llvm.exp.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_fabsf128(fp128 %a) {
+; fabs should always get lowered to assembly
+; CHECK-LABEL: test_fabsf128:
+; CHECK-NOT: fabsl
+; CHECK-NOT: fabsf128
+start:
+ %0 = tail call fp128 @llvm.fabs.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_floorf128(fp128 %a) {
+; CHECK-LABEL: test_floorf128:
+; CHECK-NOTLD: floorf128
+; CHECK-USELD: floorl
+; CHECK-S390X: floorl
+start:
+ %0 = tail call fp128 @llvm.floor.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_fmaf128(fp128 %a, fp128 %b, fp128 %c) {
+; CHECK-LABEL: test_fmaf128:
+; CHECK-NOTLD: 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_frexpf128(fp128 %a) {
+; CHECK-LABEL: test_frexpf128:
+; CHECK-NOTLD: 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_ldexpf128(fp128 %a, i32 %b) {
+; CHECK-LABEL: test_ldexpf128:
+; CHECK-NOTLD: 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_llrintf128(fp128 %a) {
+; CHECK-LABEL: test_llrintf128:
+; CHECK-NOTLD: llrintf128
+; CHECK-USELD: llrintl
+; CHECK-S390X: llrintl
+start:
+ %0 = tail call i64 @llvm.llrint.f128(fp128 %a)
+ ret i64 %0
+}
+
+define i64 @test_llroundf128(fp128 %a) {
+; CHECK-LABEL: test_llroundf128:
+; CHECK-NOTLD: llroundf128
+; CHECK-USELD: llroundl
+; CHECK-S390X: llroundl
+start:
+ %0 = tail call i64 @llvm.llround.i64.f128(fp128 %a)
+ ret i64 %0
+}
+
+define fp128 @test_log10f128(fp128 %a) {
+; CHECK-LABEL: test_log10f128:
+; CHECK-NOTLD: log10f128
+; CHECK-USELD: log10l
+; CHECK-S390X: log10l
+start:
+ %0 = tail call fp128 @llvm.log10.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_log2f128(fp128 %a) {
+; CHECK-LABEL: test_log2f128:
+; CHECK-NOTLD: log2f128
+; CHECK-USELD: log2l
+; CHECK-S390X: log2l
+start:
+ %0 = tail call fp128 @llvm.log2.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_logf128(fp128 %a) {
+; CHECK-LABEL: test_logf128:
+; CHECK-NOTLD: logf128
+; CHECK-USELD: logl
+; CHECK-S390X: logl
+start:
+ %0 = tail call fp128 @llvm.log.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define i64 @test_lrintf128(fp128 %a) {
+; CHECK-LABEL: test_exp2f128:
+; CHECK-NOTLD: lrintf128
+; CHECK-USELD: lrintl
+; CHECK-S390X: lrintl
+start:
+ %0 = tail call i64 @llvm.lrint.f128(fp128 %a)
+ ret i64 %0
+}
+
+define i64 @test_lroundf128(fp128 %a) {
+; CHECK-LABEL: test_lroundf128:
+; CHECK-NOTLD: lroundf128
+; CHECK-USELD: lroundl
+; CHECK-S390X: lroundl
+start:
+ %0 = tail call i64 @llvm.lround.i64.f128(fp128 %a)
+ ret i64 %0
+}
+
+define fp128 @test_nearbyintf128(fp128 %a) {
+; CHECK-LABEL: test_nearbyintf128:
+; CHECK-NOTLD: nearbyintf128
+; CHECK-USELD: nearbyintl
+; CHECK-S390X: nearbyintl
+start:
+ %0 = tail call fp128 @llvm.nearbyint.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_powf128(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_powf128:
+; CHECK-NOTLD: 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_rintf128(fp128 %a) {
+; CHECK-LABEL: test_rintf128:
+; CHECK-NOTLD: rintf128
+; CHECK-USELD: rintl
+; CHECK-S390X: fixbr {{%.*}}, 0, {{%.*}}
+start:
+ %0 = tail call fp128 @llvm.rint.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_roundevenf128(fp128 %a) {
+; CHECK-LABEL: test_roundevenf128:
+; CHECK-NOTLD: roundevenf128
+; CHECK-USELD: roundevenl
+; CHECK-S390X: roundevenl
+start:
+ %0 = tail call fp128 @llvm.roundeven.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_roundf128(fp128 %a) {
+; CHECK-LABEL: test_roundf128:
+; CHECK-NOTLD: roundf128
+; CHECK-USELD: roundl
+; CHECK-S390X: roundl
+start:
+ %0 = tail call fp128 @llvm.round.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_sinf128(fp128 %a) {
+; CHECK-LABEL: test_sinf128:
+; CHECK-NOTLD: sinf128
+; CHECK-USELD: sinl
+; CHECK-S390X: sinl
+start:
+ %0 = tail call fp128 @llvm.sin.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_sqrtf128(fp128 %a) {
+; CHECK-LABEL: test_sqrtf128:
+; CHECK-NOTLD: sqrtf128
+; CHECK-USELD: sqrtl
+; CHECK-S390X: sqxbr {{%.*}}, {{%.*}}
+start:
+ %0 = tail call fp128 @llvm.sqrt.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_tanf128(fp128 %a) {
+; CHECK-LABEL: test_tanf128:
+; CHECK-NOTLD: tanf128
+; CHECK-USELD: tanl
+; CHECK-S390X: tanl
+start:
+ %0 = tail call fp128 @llvm.tan.f128(fp128 %a)
+ ret fp128 %0
+}
+
+define fp128 @test_truncf128(fp128 %a) {
+; CHECK-LABEL: test_truncf128:
+; CHECK-NOTLD: truncf128
+; CHECK-USELD: truncl
+; CHECK-S390X: truncl
+start:
+ %0 = tail call fp128 @llvm.trunc.f128(fp128 %a)
+ ret fp128 %0
+}
>From 823a4ddf766d20aafbea1fef7d82eb4a27d834b1 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross at umich.edu>
Date: Thu, 28 Dec 2023 04:01:22 -0500
Subject: [PATCH 2/5] [IR] Change `fp128` lowering to use `f128` functions by
default
Switch from emitting long double functions to using `f128`-specific functions.
Fixes https://github.com/llvm/llvm-project/issues/44744.
---
llvm/include/llvm/IR/RuntimeLibcalls.def | 98 +++++++++----------
llvm/lib/IR/RuntimeLibcalls.cpp | 94 +++++++++---------
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 26 -----
.../CodeGen/Generic/f128-math-lowering.ll | 11 ++-
4 files changed, 103 insertions(+), 126 deletions(-)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index c6ac341d71a20..515b484cab343 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -110,12 +110,12 @@ HANDLE_LIBCALL(DIV_PPCF128, "__gcc_qdiv")
HANDLE_LIBCALL(REM_F32, "fmodf")
HANDLE_LIBCALL(REM_F64, "fmod")
HANDLE_LIBCALL(REM_F80, "fmodl")
-HANDLE_LIBCALL(REM_F128, "fmodl")
+HANDLE_LIBCALL(REM_F128, "fmodf128")
HANDLE_LIBCALL(REM_PPCF128, "fmodl")
HANDLE_LIBCALL(FMA_F32, "fmaf")
HANDLE_LIBCALL(FMA_F64, "fma")
HANDLE_LIBCALL(FMA_F80, "fmal")
-HANDLE_LIBCALL(FMA_F128, "fmal")
+HANDLE_LIBCALL(FMA_F128, "fmaf128")
HANDLE_LIBCALL(FMA_PPCF128, "fmal")
HANDLE_LIBCALL(POWI_F32, "__powisf2")
HANDLE_LIBCALL(POWI_F64, "__powidf2")
@@ -125,117 +125,117 @@ HANDLE_LIBCALL(POWI_PPCF128, "__powitf2")
HANDLE_LIBCALL(SQRT_F32, "sqrtf")
HANDLE_LIBCALL(SQRT_F64, "sqrt")
HANDLE_LIBCALL(SQRT_F80, "sqrtl")
-HANDLE_LIBCALL(SQRT_F128, "sqrtl")
+HANDLE_LIBCALL(SQRT_F128, "sqrtf128")
HANDLE_LIBCALL(SQRT_PPCF128, "sqrtl")
HANDLE_LIBCALL(CBRT_F32, "cbrtf")
HANDLE_LIBCALL(CBRT_F64, "cbrt")
HANDLE_LIBCALL(CBRT_F80, "cbrtl")
-HANDLE_LIBCALL(CBRT_F128, "cbrtl")
+HANDLE_LIBCALL(CBRT_F128, "cbrtf128")
HANDLE_LIBCALL(CBRT_PPCF128, "cbrtl")
HANDLE_LIBCALL(LOG_F32, "logf")
HANDLE_LIBCALL(LOG_F64, "log")
HANDLE_LIBCALL(LOG_F80, "logl")
-HANDLE_LIBCALL(LOG_F128, "logl")
+HANDLE_LIBCALL(LOG_F128, "logf128")
HANDLE_LIBCALL(LOG_PPCF128, "logl")
HANDLE_LIBCALL(LOG_FINITE_F32, "__logf_finite")
HANDLE_LIBCALL(LOG_FINITE_F64, "__log_finite")
HANDLE_LIBCALL(LOG_FINITE_F80, "__logl_finite")
-HANDLE_LIBCALL(LOG_FINITE_F128, "__logl_finite")
+HANDLE_LIBCALL(LOG_FINITE_F128, "__logf128_finite")
HANDLE_LIBCALL(LOG_FINITE_PPCF128, "__logl_finite")
HANDLE_LIBCALL(LOG2_F32, "log2f")
HANDLE_LIBCALL(LOG2_F64, "log2")
HANDLE_LIBCALL(LOG2_F80, "log2l")
-HANDLE_LIBCALL(LOG2_F128, "log2l")
+HANDLE_LIBCALL(LOG2_F128, "log2f128")
HANDLE_LIBCALL(LOG2_PPCF128, "log2l")
HANDLE_LIBCALL(LOG2_FINITE_F32, "__log2f_finite")
HANDLE_LIBCALL(LOG2_FINITE_F64, "__log2_finite")
HANDLE_LIBCALL(LOG2_FINITE_F80, "__log2l_finite")
-HANDLE_LIBCALL(LOG2_FINITE_F128, "__log2l_finite")
+HANDLE_LIBCALL(LOG2_FINITE_F128, "__log2f128_finite")
HANDLE_LIBCALL(LOG2_FINITE_PPCF128, "__log2l_finite")
HANDLE_LIBCALL(LOG10_F32, "log10f")
HANDLE_LIBCALL(LOG10_F64, "log10")
HANDLE_LIBCALL(LOG10_F80, "log10l")
-HANDLE_LIBCALL(LOG10_F128, "log10l")
+HANDLE_LIBCALL(LOG10_F128, "log10f128")
HANDLE_LIBCALL(LOG10_PPCF128, "log10l")
HANDLE_LIBCALL(LOG10_FINITE_F32, "__log10f_finite")
HANDLE_LIBCALL(LOG10_FINITE_F64, "__log10_finite")
HANDLE_LIBCALL(LOG10_FINITE_F80, "__log10l_finite")
-HANDLE_LIBCALL(LOG10_FINITE_F128, "__log10l_finite")
+HANDLE_LIBCALL(LOG10_FINITE_F128, "__log10f128_finite")
HANDLE_LIBCALL(LOG10_FINITE_PPCF128, "__log10l_finite")
HANDLE_LIBCALL(EXP_F32, "expf")
HANDLE_LIBCALL(EXP_F64, "exp")
HANDLE_LIBCALL(EXP_F80, "expl")
-HANDLE_LIBCALL(EXP_F128, "expl")
+HANDLE_LIBCALL(EXP_F128, "expf128")
HANDLE_LIBCALL(EXP_PPCF128, "expl")
HANDLE_LIBCALL(EXP_FINITE_F32, "__expf_finite")
HANDLE_LIBCALL(EXP_FINITE_F64, "__exp_finite")
HANDLE_LIBCALL(EXP_FINITE_F80, "__expl_finite")
-HANDLE_LIBCALL(EXP_FINITE_F128, "__expl_finite")
+HANDLE_LIBCALL(EXP_FINITE_F128, "__expf128_finite")
HANDLE_LIBCALL(EXP_FINITE_PPCF128, "__expl_finite")
HANDLE_LIBCALL(EXP2_F32, "exp2f")
HANDLE_LIBCALL(EXP2_F64, "exp2")
HANDLE_LIBCALL(EXP2_F80, "exp2l")
-HANDLE_LIBCALL(EXP2_F128, "exp2l")
+HANDLE_LIBCALL(EXP2_F128, "exp2f128")
HANDLE_LIBCALL(EXP2_PPCF128, "exp2l")
HANDLE_LIBCALL(EXP2_FINITE_F32, "__exp2f_finite")
HANDLE_LIBCALL(EXP2_FINITE_F64, "__exp2_finite")
HANDLE_LIBCALL(EXP2_FINITE_F80, "__exp2l_finite")
-HANDLE_LIBCALL(EXP2_FINITE_F128, "__exp2l_finite")
+HANDLE_LIBCALL(EXP2_FINITE_F128, "__exp2f128_finite")
HANDLE_LIBCALL(EXP2_FINITE_PPCF128, "__exp2l_finite")
HANDLE_LIBCALL(EXP10_F32, "exp10f")
HANDLE_LIBCALL(EXP10_F64, "exp10")
HANDLE_LIBCALL(EXP10_F80, "exp10l")
-HANDLE_LIBCALL(EXP10_F128, "exp10l")
+HANDLE_LIBCALL(EXP10_F128, "exp10f128")
HANDLE_LIBCALL(EXP10_PPCF128, "exp10l")
HANDLE_LIBCALL(SIN_F32, "sinf")
HANDLE_LIBCALL(SIN_F64, "sin")
HANDLE_LIBCALL(SIN_F80, "sinl")
-HANDLE_LIBCALL(SIN_F128, "sinl")
+HANDLE_LIBCALL(SIN_F128, "sinf128")
HANDLE_LIBCALL(SIN_PPCF128, "sinl")
HANDLE_LIBCALL(COS_F32, "cosf")
HANDLE_LIBCALL(COS_F64, "cos")
HANDLE_LIBCALL(COS_F80, "cosl")
-HANDLE_LIBCALL(COS_F128, "cosl")
+HANDLE_LIBCALL(COS_F128, "cosf128")
HANDLE_LIBCALL(COS_PPCF128, "cosl")
HANDLE_LIBCALL(TAN_F32, "tanf")
HANDLE_LIBCALL(TAN_F64, "tan")
HANDLE_LIBCALL(TAN_F80, "tanl")
-HANDLE_LIBCALL(TAN_F128,"tanl")
+HANDLE_LIBCALL(TAN_F128,"tanf128")
HANDLE_LIBCALL(TAN_PPCF128, "tanl")
HANDLE_LIBCALL(SINH_F32, "sinhf")
HANDLE_LIBCALL(SINH_F64, "sinh")
HANDLE_LIBCALL(SINH_F80, "sinhl")
-HANDLE_LIBCALL(SINH_F128, "sinhl")
+HANDLE_LIBCALL(SINH_F128, "sinhf128")
HANDLE_LIBCALL(SINH_PPCF128, "sinhl")
HANDLE_LIBCALL(COSH_F32, "coshf")
HANDLE_LIBCALL(COSH_F64, "cosh")
HANDLE_LIBCALL(COSH_F80, "coshl")
-HANDLE_LIBCALL(COSH_F128, "coshl")
+HANDLE_LIBCALL(COSH_F128, "coshf128")
HANDLE_LIBCALL(COSH_PPCF128, "coshl")
HANDLE_LIBCALL(TANH_F32, "tanhf")
HANDLE_LIBCALL(TANH_F64, "tanh")
HANDLE_LIBCALL(TANH_F80, "tanhl")
-HANDLE_LIBCALL(TANH_F128,"tanhl")
+HANDLE_LIBCALL(TANH_F128,"tanhf128")
HANDLE_LIBCALL(TANH_PPCF128, "tanhl")
HANDLE_LIBCALL(ASIN_F32, "asinf")
HANDLE_LIBCALL(ASIN_F64, "asin")
HANDLE_LIBCALL(ASIN_F80, "asinl")
-HANDLE_LIBCALL(ASIN_F128, "asinl")
+HANDLE_LIBCALL(ASIN_F128, "asinf128")
HANDLE_LIBCALL(ASIN_PPCF128, "asinl")
HANDLE_LIBCALL(ACOS_F32, "acosf")
HANDLE_LIBCALL(ACOS_F64, "acos")
HANDLE_LIBCALL(ACOS_F80, "acosl")
-HANDLE_LIBCALL(ACOS_F128, "acosl")
+HANDLE_LIBCALL(ACOS_F128, "acosf128")
HANDLE_LIBCALL(ACOS_PPCF128, "acosl")
HANDLE_LIBCALL(ATAN_F32, "atanf")
HANDLE_LIBCALL(ATAN_F64, "atan")
HANDLE_LIBCALL(ATAN_F80, "atanl")
-HANDLE_LIBCALL(ATAN_F128,"atanl")
+HANDLE_LIBCALL(ATAN_F128,"atanf128")
HANDLE_LIBCALL(ATAN_PPCF128, "atanl")
HANDLE_LIBCALL(ATAN2_F32, "atan2f")
HANDLE_LIBCALL(ATAN2_F64, "atan2")
HANDLE_LIBCALL(ATAN2_F80, "atan2l")
-HANDLE_LIBCALL(ATAN2_F128,"atan2l")
+HANDLE_LIBCALL(ATAN2_F128,"atan2f128")
HANDLE_LIBCALL(ATAN2_PPCF128, "atan2l")
HANDLE_LIBCALL(SINCOS_F32, nullptr)
HANDLE_LIBCALL(SINCOS_F64, nullptr)
@@ -247,122 +247,122 @@ HANDLE_LIBCALL(SINCOS_STRET_F64, nullptr)
HANDLE_LIBCALL(POW_F32, "powf")
HANDLE_LIBCALL(POW_F64, "pow")
HANDLE_LIBCALL(POW_F80, "powl")
-HANDLE_LIBCALL(POW_F128, "powl")
+HANDLE_LIBCALL(POW_F128, "powf128")
HANDLE_LIBCALL(POW_PPCF128, "powl")
HANDLE_LIBCALL(POW_FINITE_F32, "__powf_finite")
HANDLE_LIBCALL(POW_FINITE_F64, "__pow_finite")
HANDLE_LIBCALL(POW_FINITE_F80, "__powl_finite")
-HANDLE_LIBCALL(POW_FINITE_F128, "__powl_finite")
+HANDLE_LIBCALL(POW_FINITE_F128, "__powf128_finite")
HANDLE_LIBCALL(POW_FINITE_PPCF128, "__powl_finite")
HANDLE_LIBCALL(CEIL_F32, "ceilf")
HANDLE_LIBCALL(CEIL_F64, "ceil")
HANDLE_LIBCALL(CEIL_F80, "ceill")
-HANDLE_LIBCALL(CEIL_F128, "ceill")
+HANDLE_LIBCALL(CEIL_F128, "ceilf128")
HANDLE_LIBCALL(CEIL_PPCF128, "ceill")
HANDLE_LIBCALL(TRUNC_F32, "truncf")
HANDLE_LIBCALL(TRUNC_F64, "trunc")
HANDLE_LIBCALL(TRUNC_F80, "truncl")
-HANDLE_LIBCALL(TRUNC_F128, "truncl")
+HANDLE_LIBCALL(TRUNC_F128, "truncf128")
HANDLE_LIBCALL(TRUNC_PPCF128, "truncl")
HANDLE_LIBCALL(RINT_F32, "rintf")
HANDLE_LIBCALL(RINT_F64, "rint")
HANDLE_LIBCALL(RINT_F80, "rintl")
-HANDLE_LIBCALL(RINT_F128, "rintl")
+HANDLE_LIBCALL(RINT_F128, "rintf128")
HANDLE_LIBCALL(RINT_PPCF128, "rintl")
HANDLE_LIBCALL(NEARBYINT_F32, "nearbyintf")
HANDLE_LIBCALL(NEARBYINT_F64, "nearbyint")
HANDLE_LIBCALL(NEARBYINT_F80, "nearbyintl")
-HANDLE_LIBCALL(NEARBYINT_F128, "nearbyintl")
+HANDLE_LIBCALL(NEARBYINT_F128, "nearbyintf128")
HANDLE_LIBCALL(NEARBYINT_PPCF128, "nearbyintl")
HANDLE_LIBCALL(ROUND_F32, "roundf")
HANDLE_LIBCALL(ROUND_F64, "round")
HANDLE_LIBCALL(ROUND_F80, "roundl")
-HANDLE_LIBCALL(ROUND_F128, "roundl")
+HANDLE_LIBCALL(ROUND_F128, "roundf128")
HANDLE_LIBCALL(ROUND_PPCF128, "roundl")
HANDLE_LIBCALL(ROUNDEVEN_F32, "roundevenf")
HANDLE_LIBCALL(ROUNDEVEN_F64, "roundeven")
HANDLE_LIBCALL(ROUNDEVEN_F80, "roundevenl")
-HANDLE_LIBCALL(ROUNDEVEN_F128, "roundevenl")
+HANDLE_LIBCALL(ROUNDEVEN_F128, "roundevenf128")
HANDLE_LIBCALL(ROUNDEVEN_PPCF128, "roundevenl")
HANDLE_LIBCALL(FLOOR_F32, "floorf")
HANDLE_LIBCALL(FLOOR_F64, "floor")
HANDLE_LIBCALL(FLOOR_F80, "floorl")
-HANDLE_LIBCALL(FLOOR_F128, "floorl")
+HANDLE_LIBCALL(FLOOR_F128, "floorf128")
HANDLE_LIBCALL(FLOOR_PPCF128, "floorl")
HANDLE_LIBCALL(COPYSIGN_F32, "copysignf")
HANDLE_LIBCALL(COPYSIGN_F64, "copysign")
HANDLE_LIBCALL(COPYSIGN_F80, "copysignl")
-HANDLE_LIBCALL(COPYSIGN_F128, "copysignl")
+HANDLE_LIBCALL(COPYSIGN_F128, "copysignf128")
HANDLE_LIBCALL(COPYSIGN_PPCF128, "copysignl")
HANDLE_LIBCALL(FMIN_F32, "fminf")
HANDLE_LIBCALL(FMIN_F64, "fmin")
HANDLE_LIBCALL(FMIN_F80, "fminl")
-HANDLE_LIBCALL(FMIN_F128, "fminl")
+HANDLE_LIBCALL(FMIN_F128, "fminf128")
HANDLE_LIBCALL(FMIN_PPCF128, "fminl")
HANDLE_LIBCALL(FMAX_F32, "fmaxf")
HANDLE_LIBCALL(FMAX_F64, "fmax")
HANDLE_LIBCALL(FMAX_F80, "fmaxl")
-HANDLE_LIBCALL(FMAX_F128, "fmaxl")
+HANDLE_LIBCALL(FMAX_F128, "fmaxf128")
HANDLE_LIBCALL(FMAX_PPCF128, "fmaxl")
HANDLE_LIBCALL(FMINIMUM_F32, "fminimumf")
HANDLE_LIBCALL(FMINIMUM_F64, "fminimum")
HANDLE_LIBCALL(FMINIMUM_F80, "fminimuml")
-HANDLE_LIBCALL(FMINIMUM_F128, "fminimuml")
+HANDLE_LIBCALL(FMINIMUM_F128, "fminimumf128")
HANDLE_LIBCALL(FMINIMUM_PPCF128, "fminimuml")
HANDLE_LIBCALL(FMAXIMUM_F32, "fmaximumf")
HANDLE_LIBCALL(FMAXIMUM_F64, "fmaximum")
HANDLE_LIBCALL(FMAXIMUM_F80, "fmaximuml")
-HANDLE_LIBCALL(FMAXIMUM_F128, "fmaximuml")
+HANDLE_LIBCALL(FMAXIMUM_F128, "fmaximumf128")
HANDLE_LIBCALL(FMAXIMUM_PPCF128, "fmaximum_numl")
HANDLE_LIBCALL(FMINIMUMNUM_F32, "fminimum_numf")
HANDLE_LIBCALL(FMINIMUMNUM_F64, "fminimum_num")
HANDLE_LIBCALL(FMINIMUMNUM_F80, "fminimum_numl")
-HANDLE_LIBCALL(FMINIMUMNUM_F128, "fminimum_numl")
+HANDLE_LIBCALL(FMINIMUMNUM_F128, "fminimum_numf128")
HANDLE_LIBCALL(FMINIMUMNUM_PPCF128, "fminimum_numl")
HANDLE_LIBCALL(FMAXIMUMNUM_F32, "fmaximum_numf")
HANDLE_LIBCALL(FMAXIMUMNUM_F64, "fmaximum_num")
HANDLE_LIBCALL(FMAXIMUMNUM_F80, "fmaximum_numl")
-HANDLE_LIBCALL(FMAXIMUMNUM_F128, "fmaximum_numl")
+HANDLE_LIBCALL(FMAXIMUMNUM_F128, "fmaximum_numf128")
HANDLE_LIBCALL(FMAXIMUMNUM_PPCF128, "fmaximum_numl")
HANDLE_LIBCALL(LROUND_F32, "lroundf")
HANDLE_LIBCALL(LROUND_F64, "lround")
HANDLE_LIBCALL(LROUND_F80, "lroundl")
-HANDLE_LIBCALL(LROUND_F128, "lroundl")
+HANDLE_LIBCALL(LROUND_F128, "lroundf128")
HANDLE_LIBCALL(LROUND_PPCF128, "lroundl")
HANDLE_LIBCALL(LLROUND_F32, "llroundf")
HANDLE_LIBCALL(LLROUND_F64, "llround")
HANDLE_LIBCALL(LLROUND_F80, "llroundl")
-HANDLE_LIBCALL(LLROUND_F128, "llroundl")
+HANDLE_LIBCALL(LLROUND_F128, "llroundf128")
HANDLE_LIBCALL(LLROUND_PPCF128, "llroundl")
HANDLE_LIBCALL(LRINT_F32, "lrintf")
HANDLE_LIBCALL(LRINT_F64, "lrint")
HANDLE_LIBCALL(LRINT_F80, "lrintl")
-HANDLE_LIBCALL(LRINT_F128, "lrintl")
+HANDLE_LIBCALL(LRINT_F128, "lrintf128")
HANDLE_LIBCALL(LRINT_PPCF128, "lrintl")
HANDLE_LIBCALL(LLRINT_F32, "llrintf")
HANDLE_LIBCALL(LLRINT_F64, "llrint")
HANDLE_LIBCALL(LLRINT_F80, "llrintl")
-HANDLE_LIBCALL(LLRINT_F128, "llrintl")
+HANDLE_LIBCALL(LLRINT_F128, "llrintf128")
HANDLE_LIBCALL(LLRINT_PPCF128, "llrintl")
HANDLE_LIBCALL(LDEXP_F32, "ldexpf")
HANDLE_LIBCALL(LDEXP_F64, "ldexp")
HANDLE_LIBCALL(LDEXP_F80, "ldexpl")
-HANDLE_LIBCALL(LDEXP_F128, "ldexpl")
+HANDLE_LIBCALL(LDEXP_F128, "ldexpf128")
HANDLE_LIBCALL(LDEXP_PPCF128, "ldexpl")
HANDLE_LIBCALL(FREXP_F32, "frexpf")
HANDLE_LIBCALL(FREXP_F64, "frexp")
HANDLE_LIBCALL(FREXP_F80, "frexpl")
-HANDLE_LIBCALL(FREXP_F128, "frexpl")
+HANDLE_LIBCALL(FREXP_F128, "frexpf128")
HANDLE_LIBCALL(FREXP_PPCF128, "frexpl")
HANDLE_LIBCALL(SINCOSPI_F32, "sincospif")
HANDLE_LIBCALL(SINCOSPI_F64, "sincospi")
HANDLE_LIBCALL(SINCOSPI_F80, "sincospil")
-HANDLE_LIBCALL(SINCOSPI_F128, "sincospil")
+HANDLE_LIBCALL(SINCOSPI_F128, "sincospif128")
HANDLE_LIBCALL(SINCOSPI_PPCF128, "sincospil")
HANDLE_LIBCALL(MODF_F32, "modff")
HANDLE_LIBCALL(MODF_F64, "modf")
HANDLE_LIBCALL(MODF_F80, "modfl")
-HANDLE_LIBCALL(MODF_F128, "modfl")
+HANDLE_LIBCALL(MODF_F128, "modff128")
HANDLE_LIBCALL(MODF_PPCF128, "modfl")
// Floating point environment
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 1f94400f7c088..2e3b071c8f4bf 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -25,52 +25,53 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC)
setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C);
- // Use the f128 variants of math functions on x86_64
- if (TT.getArch() == Triple::ArchType::x86_64 && TT.isGNUEnvironment()) {
- setLibcallName(RTLIB::REM_F128, "fmodf128");
- setLibcallName(RTLIB::FMA_F128, "fmaf128");
- setLibcallName(RTLIB::SQRT_F128, "sqrtf128");
- setLibcallName(RTLIB::CBRT_F128, "cbrtf128");
- setLibcallName(RTLIB::LOG_F128, "logf128");
- setLibcallName(RTLIB::LOG_FINITE_F128, "__logf128_finite");
- setLibcallName(RTLIB::LOG2_F128, "log2f128");
- setLibcallName(RTLIB::LOG2_FINITE_F128, "__log2f128_finite");
- setLibcallName(RTLIB::LOG10_F128, "log10f128");
- setLibcallName(RTLIB::LOG10_FINITE_F128, "__log10f128_finite");
- setLibcallName(RTLIB::EXP_F128, "expf128");
- setLibcallName(RTLIB::EXP_FINITE_F128, "__expf128_finite");
- setLibcallName(RTLIB::EXP2_F128, "exp2f128");
- setLibcallName(RTLIB::EXP2_FINITE_F128, "__exp2f128_finite");
- setLibcallName(RTLIB::EXP10_F128, "exp10f128");
- setLibcallName(RTLIB::SIN_F128, "sinf128");
- setLibcallName(RTLIB::COS_F128, "cosf128");
- setLibcallName(RTLIB::TAN_F128, "tanf128");
- setLibcallName(RTLIB::SINCOS_F128, "sincosf128");
- setLibcallName(RTLIB::ASIN_F128, "asinf128");
- setLibcallName(RTLIB::ACOS_F128, "acosf128");
- setLibcallName(RTLIB::ATAN_F128, "atanf128");
- setLibcallName(RTLIB::ATAN2_F128, "atan2f128");
- setLibcallName(RTLIB::SINH_F128, "sinhf128");
- setLibcallName(RTLIB::COSH_F128, "coshf128");
- setLibcallName(RTLIB::TANH_F128, "tanhf128");
- setLibcallName(RTLIB::POW_F128, "powf128");
- setLibcallName(RTLIB::POW_FINITE_F128, "__powf128_finite");
- setLibcallName(RTLIB::CEIL_F128, "ceilf128");
- setLibcallName(RTLIB::TRUNC_F128, "truncf128");
- setLibcallName(RTLIB::RINT_F128, "rintf128");
- setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128");
- setLibcallName(RTLIB::ROUND_F128, "roundf128");
- setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenf128");
- setLibcallName(RTLIB::FLOOR_F128, "floorf128");
- setLibcallName(RTLIB::COPYSIGN_F128, "copysignf128");
- setLibcallName(RTLIB::FMIN_F128, "fminf128");
- setLibcallName(RTLIB::FMAX_F128, "fmaxf128");
- setLibcallName(RTLIB::LROUND_F128, "lroundf128");
- setLibcallName(RTLIB::LLROUND_F128, "llroundf128");
- setLibcallName(RTLIB::LRINT_F128, "lrintf128");
- setLibcallName(RTLIB::LLRINT_F128, "llrintf128");
- setLibcallName(RTLIB::LDEXP_F128, "ldexpf128");
- setLibcallName(RTLIB::FREXP_F128, "frexpf128");
+ // The long double version of library functions is more common than the
+ // f128-specific version. Use these if that is the long double type on the
+ // platform, or if the frontend specifies.
+ if (TT.isLongDoubleF128("")) {
+ setLibcallName(RTLIB::ACOS_F128, "acosl");
+ setLibcallName(RTLIB::ASIN_F128, "asinl");
+ setLibcallName(RTLIB::ATAN2_F128,"atan2l");
+ setLibcallName(RTLIB::ATAN_F128,"atanl");
+ setLibcallName(RTLIB::CBRT_F128, "cbrtl");
+ setLibcallName(RTLIB::CEIL_F128, "ceill");
+ setLibcallName(RTLIB::COPYSIGN_F128, "copysignl");
+ setLibcallName(RTLIB::COSH_F128, "coshl");
+ setLibcallName(RTLIB::COS_F128, "cosl");
+ setLibcallName(RTLIB::EXP10_F128, "exp10l");
+ setLibcallName(RTLIB::EXP2_F128, "exp2l");
+ setLibcallName(RTLIB::EXP_F128, "expl");
+ setLibcallName(RTLIB::FLOOR_F128, "floorl");
+ setLibcallName(RTLIB::FMAXIMUMNUM_F128, "fmaximum_numl");
+ setLibcallName(RTLIB::FMAXIMUM_F128, "fmaximuml");
+ setLibcallName(RTLIB::FMAX_F128, "fmaxl");
+ setLibcallName(RTLIB::FMA_F128, "fmal");
+ setLibcallName(RTLIB::FMINIMUMNUM_F128, "fminimum_numl");
+ setLibcallName(RTLIB::FMINIMUM_F128, "fminimuml");
+ setLibcallName(RTLIB::FMIN_F128, "fminl");
+ setLibcallName(RTLIB::FREXP_F128, "frexpl");
+ setLibcallName(RTLIB::LDEXP_F128, "ldexpl");
+ setLibcallName(RTLIB::LLRINT_F128, "llrintl");
+ setLibcallName(RTLIB::LLROUND_F128, "llroundl");
+ setLibcallName(RTLIB::LOG10_F128, "log10l");
+ setLibcallName(RTLIB::LOG2_F128, "log2l");
+ setLibcallName(RTLIB::LOG_F128, "logl");
+ setLibcallName(RTLIB::LRINT_F128, "lrintl");
+ setLibcallName(RTLIB::LROUND_F128, "lroundl");
+ setLibcallName(RTLIB::MODF_F128, "modfl");
+ setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintl");
+ setLibcallName(RTLIB::POW_F128, "powl");
+ setLibcallName(RTLIB::REM_F128, "fmodl");
+ setLibcallName(RTLIB::RINT_F128, "rintl");
+ setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenl");
+ setLibcallName(RTLIB::ROUND_F128, "roundl");
+ setLibcallName(RTLIB::SINCOSPI_F128, "sincospil");
+ setLibcallName(RTLIB::SINH_F128, "sinhl");
+ setLibcallName(RTLIB::SIN_F128, "sinl");
+ setLibcallName(RTLIB::SQRT_F128, "sqrtl");
+ setLibcallName(RTLIB::TANH_F128,"tanhl");
+ setLibcallName(RTLIB::TAN_F128,"tanl");
+ setLibcallName(RTLIB::TRUNC_F128, "truncl");
}
// For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
@@ -177,7 +178,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
setLibcallName(RTLIB::SINCOS_F32, "sincosf");
setLibcallName(RTLIB::SINCOS_F64, "sincos");
setLibcallName(RTLIB::SINCOS_F80, "sincosl");
- setLibcallName(RTLIB::SINCOS_F128, "sincosl");
setLibcallName(RTLIB::SINCOS_PPCF128, "sincosl");
}
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 91df5f467e59c..a17adfe3f0e59 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1422,32 +1422,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setTargetDAGCombine({ISD::TRUNCATE, ISD::SETCC, ISD::SELECT_CC});
}
- setLibcallName(RTLIB::LOG_F128, "logf128");
- setLibcallName(RTLIB::LOG2_F128, "log2f128");
- setLibcallName(RTLIB::LOG10_F128, "log10f128");
- setLibcallName(RTLIB::EXP_F128, "expf128");
- setLibcallName(RTLIB::EXP2_F128, "exp2f128");
- setLibcallName(RTLIB::SIN_F128, "sinf128");
- setLibcallName(RTLIB::COS_F128, "cosf128");
- setLibcallName(RTLIB::SINCOS_F128, "sincosf128");
- setLibcallName(RTLIB::POW_F128, "powf128");
- setLibcallName(RTLIB::FMIN_F128, "fminf128");
- setLibcallName(RTLIB::FMAX_F128, "fmaxf128");
- setLibcallName(RTLIB::REM_F128, "fmodf128");
- setLibcallName(RTLIB::SQRT_F128, "sqrtf128");
- setLibcallName(RTLIB::CEIL_F128, "ceilf128");
- setLibcallName(RTLIB::FLOOR_F128, "floorf128");
- setLibcallName(RTLIB::TRUNC_F128, "truncf128");
- setLibcallName(RTLIB::ROUND_F128, "roundf128");
- setLibcallName(RTLIB::LROUND_F128, "lroundf128");
- setLibcallName(RTLIB::LLROUND_F128, "llroundf128");
- setLibcallName(RTLIB::RINT_F128, "rintf128");
- setLibcallName(RTLIB::LRINT_F128, "lrintf128");
- setLibcallName(RTLIB::LLRINT_F128, "llrintf128");
- setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128");
- setLibcallName(RTLIB::FMA_F128, "fmaf128");
- setLibcallName(RTLIB::FREXP_F128, "frexpf128");
-
if (Subtarget.isAIXABI()) {
setLibcallName(RTLIB::MEMCPY, isPPC64 ? "___memmove64" : "___memmove");
setLibcallName(RTLIB::MEMMOVE, isPPC64 ? "___memmove64" : "___memmove");
diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
index dfbd1eaeda109..a68cd1c39698e 100644
--- a/llvm/test/CodeGen/Generic/f128-math-lowering.ll
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -1,12 +1,15 @@
; RUN: llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
-; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
-; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
+; RUN: llc < %s -mtriple=powerpc-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
+; RUN: llc < %s -mtriple=powerpc64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
+; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
; RUN: llc < %s -mtriple=s390x-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-S390X
-; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
;
; REQUIRES: aarch64-registered-target
+; REQUIRES: powerpc-registered-target
; REQUIRES: riscv-registered-target
; REQUIRES: systemz-registered-target
; REQUIRES: x86-registered-target
>From 81c4af35458af36a115c276aeec7b2a75b43e66d Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross at umich.edu>
Date: Thu, 27 Feb 2025 09:38:09 +0000
Subject: [PATCH 3/5] Move changes away from f128 libcalls to an adjust
function
---
llvm/include/llvm/IR/RuntimeLibcalls.h | 17 ++++
llvm/lib/IR/RuntimeLibcalls.cpp | 105 +++++++++++++------------
2 files changed, 73 insertions(+), 49 deletions(-)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index b3648f5a31e2a..fd1930cce0b05 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -14,9 +14,11 @@
#ifndef LLVM_IR_RUNTIME_LIBCALLS_H
#define LLVM_IR_RUNTIME_LIBCALLS_H
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/Support/AtomicOrdering.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Triple.h"
namespace llvm {
@@ -38,10 +40,25 @@ enum Libcall {
/// A simple container for information about the supported runtime calls.
struct RuntimeLibcallsInfo {
+ /// Default libcalls for the triple. Note that `fixupLibcalls` should also be
+ /// called in order to apply machine-specific and configurable behavior.
explicit RuntimeLibcallsInfo(const Triple &TT) {
initLibcalls(TT);
}
+ /// Apply nondefault overrides to libcalls based on machine configuration.
+ ///
+ /// @param[in] TM Used to account for ABI-secific affects on
+ /// libcalls.
+ /// @param[in] LongDoubleFormat If set, override the platform default.
+ // TODO: maybe make the option an enum
+ // enum Fp128LibcallFormat {
+ // AsF128; // always lower to f128 versions (probably what Rust will do)
+ // AsLongDouble; // always lower f128 as long double (probably what Clang should do)
+ // AsPlatformDefault; // don't change anything
+ // }
+ void adjustLibcalls(const TargetMachine &TM, const fltSemantics *LongDoubleFormat);
+
/// Rename the default libcall routine name for the specified libcall.
void setLibcallName(RTLIB::Libcall Call, const char *Name) {
LibcallRoutineNames[Call] = Name;
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 2e3b071c8f4bf..01fdd832a5ba6 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/RuntimeLibcalls.h"
+#include "llvm/Target/TargetMachine.h"
using namespace llvm;
using namespace RTLIB;
@@ -25,55 +26,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC)
setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C);
- // The long double version of library functions is more common than the
- // f128-specific version. Use these if that is the long double type on the
- // platform, or if the frontend specifies.
- if (TT.isLongDoubleF128("")) {
- setLibcallName(RTLIB::ACOS_F128, "acosl");
- setLibcallName(RTLIB::ASIN_F128, "asinl");
- setLibcallName(RTLIB::ATAN2_F128,"atan2l");
- setLibcallName(RTLIB::ATAN_F128,"atanl");
- setLibcallName(RTLIB::CBRT_F128, "cbrtl");
- setLibcallName(RTLIB::CEIL_F128, "ceill");
- setLibcallName(RTLIB::COPYSIGN_F128, "copysignl");
- setLibcallName(RTLIB::COSH_F128, "coshl");
- setLibcallName(RTLIB::COS_F128, "cosl");
- setLibcallName(RTLIB::EXP10_F128, "exp10l");
- setLibcallName(RTLIB::EXP2_F128, "exp2l");
- setLibcallName(RTLIB::EXP_F128, "expl");
- setLibcallName(RTLIB::FLOOR_F128, "floorl");
- setLibcallName(RTLIB::FMAXIMUMNUM_F128, "fmaximum_numl");
- setLibcallName(RTLIB::FMAXIMUM_F128, "fmaximuml");
- setLibcallName(RTLIB::FMAX_F128, "fmaxl");
- setLibcallName(RTLIB::FMA_F128, "fmal");
- setLibcallName(RTLIB::FMINIMUMNUM_F128, "fminimum_numl");
- setLibcallName(RTLIB::FMINIMUM_F128, "fminimuml");
- setLibcallName(RTLIB::FMIN_F128, "fminl");
- setLibcallName(RTLIB::FREXP_F128, "frexpl");
- setLibcallName(RTLIB::LDEXP_F128, "ldexpl");
- setLibcallName(RTLIB::LLRINT_F128, "llrintl");
- setLibcallName(RTLIB::LLROUND_F128, "llroundl");
- setLibcallName(RTLIB::LOG10_F128, "log10l");
- setLibcallName(RTLIB::LOG2_F128, "log2l");
- setLibcallName(RTLIB::LOG_F128, "logl");
- setLibcallName(RTLIB::LRINT_F128, "lrintl");
- setLibcallName(RTLIB::LROUND_F128, "lroundl");
- setLibcallName(RTLIB::MODF_F128, "modfl");
- setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintl");
- setLibcallName(RTLIB::POW_F128, "powl");
- setLibcallName(RTLIB::REM_F128, "fmodl");
- setLibcallName(RTLIB::RINT_F128, "rintl");
- setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenl");
- setLibcallName(RTLIB::ROUND_F128, "roundl");
- setLibcallName(RTLIB::SINCOSPI_F128, "sincospil");
- setLibcallName(RTLIB::SINH_F128, "sinhl");
- setLibcallName(RTLIB::SIN_F128, "sinl");
- setLibcallName(RTLIB::SQRT_F128, "sqrtl");
- setLibcallName(RTLIB::TANH_F128,"tanhl");
- setLibcallName(RTLIB::TAN_F128,"tanl");
- setLibcallName(RTLIB::TRUNC_F128, "truncl");
- }
-
// For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
if (TT.isPPC()) {
setLibcallName(RTLIB::ADD_F128, "__addkf3");
@@ -253,3 +205,58 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
setLibcallName(RTLIB::MULO_I128, nullptr);
}
}
+
+void RuntimeLibcallsInfo::adjustLibcalls(const TargetMachine &TM,
+ const fltSemantics *LongDoubleFormat) {
+
+ const Triple &TT = TM.getTargetTriple();
+
+ // The long double version of library functions is more common than the
+ // f128-specific version. Use these if that is the long double type on the
+ // platform, or if the frontend specifies.
+ if (TT.isLongDoubleF128()) {
+ setLibcallName(RTLIB::ACOS_F128, "acosl");
+ setLibcallName(RTLIB::ASIN_F128, "asinl");
+ setLibcallName(RTLIB::ATAN2_F128, "atan2l");
+ setLibcallName(RTLIB::ATAN_F128, "atanl");
+ setLibcallName(RTLIB::CBRT_F128, "cbrtl");
+ setLibcallName(RTLIB::CEIL_F128, "ceill");
+ setLibcallName(RTLIB::COPYSIGN_F128, "copysignl");
+ setLibcallName(RTLIB::COSH_F128, "coshl");
+ setLibcallName(RTLIB::COS_F128, "cosl");
+ setLibcallName(RTLIB::EXP10_F128, "exp10l");
+ setLibcallName(RTLIB::EXP2_F128, "exp2l");
+ setLibcallName(RTLIB::EXP_F128, "expl");
+ setLibcallName(RTLIB::FLOOR_F128, "floorl");
+ setLibcallName(RTLIB::FMAXIMUMNUM_F128, "fmaximum_numl");
+ setLibcallName(RTLIB::FMAXIMUM_F128, "fmaximuml");
+ setLibcallName(RTLIB::FMAX_F128, "fmaxl");
+ setLibcallName(RTLIB::FMA_F128, "fmal");
+ setLibcallName(RTLIB::FMINIMUMNUM_F128, "fminimum_numl");
+ setLibcallName(RTLIB::FMINIMUM_F128, "fminimuml");
+ setLibcallName(RTLIB::FMIN_F128, "fminl");
+ setLibcallName(RTLIB::FREXP_F128, "frexpl");
+ setLibcallName(RTLIB::LDEXP_F128, "ldexpl");
+ setLibcallName(RTLIB::LLRINT_F128, "llrintl");
+ setLibcallName(RTLIB::LLROUND_F128, "llroundl");
+ setLibcallName(RTLIB::LOG10_F128, "log10l");
+ setLibcallName(RTLIB::LOG2_F128, "log2l");
+ setLibcallName(RTLIB::LOG_F128, "logl");
+ setLibcallName(RTLIB::LRINT_F128, "lrintl");
+ setLibcallName(RTLIB::LROUND_F128, "lroundl");
+ setLibcallName(RTLIB::MODF_F128, "modfl");
+ setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintl");
+ setLibcallName(RTLIB::POW_F128, "powl");
+ setLibcallName(RTLIB::REM_F128, "fmodl");
+ setLibcallName(RTLIB::RINT_F128, "rintl");
+ setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenl");
+ setLibcallName(RTLIB::ROUND_F128, "roundl");
+ setLibcallName(RTLIB::SINCOSPI_F128, "sincospil");
+ setLibcallName(RTLIB::SINH_F128, "sinhl");
+ setLibcallName(RTLIB::SIN_F128, "sinl");
+ setLibcallName(RTLIB::SQRT_F128, "sqrtl");
+ setLibcallName(RTLIB::TANH_F128, "tanhl");
+ setLibcallName(RTLIB::TAN_F128, "tanl");
+ setLibcallName(RTLIB::TRUNC_F128, "truncl");
+ }
+}
>From d48970f63ecdce3808860f55e6402b2824c853ca Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross at umich.edu>
Date: Sat, 1 Mar 2025 05:53:35 +0000
Subject: [PATCH 4/5] Move to a module flag
---
clang/lib/CodeGen/CodeGenModule.cpp | 502 ++++++++++++-----------
llvm/include/llvm/IR/Module.h | 7 +
llvm/include/llvm/IR/RuntimeLibcalls.def | 3 +-
llvm/include/llvm/IR/RuntimeLibcalls.h | 47 ++-
llvm/lib/IR/Module.cpp | 18 +-
llvm/lib/IR/RuntimeLibcalls.cpp | 99 +++--
llvm/lib/Object/IRSymtab.cpp | 14 +-
7 files changed, 371 insertions(+), 319 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 3caa79bb59096..680dc1b5fd42d 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -47,6 +47,7 @@
#include "clang/CodeGen/BackendUtil.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
@@ -59,6 +60,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ProfileSummary.h"
+#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/CRC.h"
@@ -362,14 +364,15 @@ CodeGenModule::CodeGenModule(ASTContext &C,
C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(LangAS::Default))
.getQuantity();
SizeSizeInBytes =
- C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity();
+ C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth())
+ .getQuantity();
IntAlignInBytes =
- C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity();
+ C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity();
CharTy =
- llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth());
+ llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth());
IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
IntPtrTy = llvm::IntegerType::get(LLVMContext,
- C.getTargetInfo().getMaxPointerWidth());
+ C.getTargetInfo().getMaxPointerWidth());
Int8PtrTy = llvm::PointerType::get(LLVMContext,
C.getTargetAddressSpace(LangAS::Default));
const llvm::DataLayout &DL = M.getDataLayout();
@@ -545,7 +548,8 @@ void CodeGenModule::applyReplacements() {
}
}
-void CodeGenModule::addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C) {
+void CodeGenModule::addGlobalValReplacement(llvm::GlobalValue *GV,
+ llvm::Constant *C) {
GlobalValReplacements.push_back(std::make_pair(GV, C));
}
@@ -582,8 +586,9 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) {
}
static bool checkAliasedGlobal(
- const ASTContext &Context, DiagnosticsEngine &Diags, SourceLocation Location,
- bool IsIFunc, const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV,
+ const ASTContext &Context, DiagnosticsEngine &Diags,
+ SourceLocation Location, bool IsIFunc, const llvm::GlobalValue *Alias,
+ const llvm::GlobalValue *&GV,
const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames,
SourceRange AliasRange) {
GV = getAliasedGlobal(Alias);
@@ -763,7 +768,8 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags,
Diags.Report(diag::warn_profile_data_unprofiled) << MainFile;
} else {
if (Mismatched > 0)
- Diags.Report(diag::warn_profile_data_out_of_date) << Visited << Mismatched;
+ Diags.Report(diag::warn_profile_data_out_of_date)
+ << Visited << Mismatched;
if (Missing > 0)
Diags.Report(diag::warn_profile_data_missing) << Visited << Missing;
@@ -995,7 +1001,8 @@ void CodeGenModule::Release() {
// usage of #pragma comment(lib, *) is intended for host libraries on
// Windows. Therefore emit llvm.dependent-libraries only for host.
if (!ELFDependentLibraries.empty() && !Context.getLangOpts().CUDAIsDevice) {
- auto *NMD = getModule().getOrInsertNamedMetadata("llvm.dependent-libraries");
+ auto *NMD =
+ getModule().getOrInsertNamedMetadata("llvm.dependent-libraries");
for (auto *MD : ELFDependentLibraries)
NMD->addOperand(MD);
}
@@ -1039,12 +1046,12 @@ void CodeGenModule::Release() {
// FIXME: we could support it by stripping all the information introduced
// by StrictVTablePointers.
- getModule().addModuleFlag(llvm::Module::Error, "StrictVTablePointers",1);
+ getModule().addModuleFlag(llvm::Module::Error, "StrictVTablePointers", 1);
llvm::Metadata *Ops[2] = {
- llvm::MDString::get(VMContext, "StrictVTablePointers"),
- llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), 1))};
+ llvm::MDString::get(VMContext, "StrictVTablePointers"),
+ llvm::ConstantAsMetadata::get(
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1))};
getModule().addModuleFlag(llvm::Module::Require,
"StrictVTablePointersRequirement",
@@ -1159,15 +1166,13 @@ void CodeGenModule::Release() {
if (CodeGenOpts.CFProtectionReturn &&
Target.checkCFProtectionReturnSupported(getDiags())) {
// Indicate that we want to instrument return control flow protection.
- getModule().addModuleFlag(llvm::Module::Min, "cf-protection-return",
- 1);
+ getModule().addModuleFlag(llvm::Module::Min, "cf-protection-return", 1);
}
if (CodeGenOpts.CFProtectionBranch &&
Target.checkCFProtectionBranchSupported(getDiags())) {
// Indicate that we want to instrument branch control flow protection.
- getModule().addModuleFlag(llvm::Module::Min, "cf-protection-branch",
- 1);
+ getModule().addModuleFlag(llvm::Module::Min, "cf-protection-branch", 1);
auto Scheme = CodeGenOpts.getCFBranchLabelScheme();
if (Target.checkCFBranchLabelSchemeSupported(Scheme, getDiags())) {
@@ -1181,10 +1186,12 @@ void CodeGenModule::Release() {
}
if (CodeGenOpts.FunctionReturnThunks)
- getModule().addModuleFlag(llvm::Module::Override, "function_return_thunk_extern", 1);
+ getModule().addModuleFlag(llvm::Module::Override,
+ "function_return_thunk_extern", 1);
if (CodeGenOpts.IndirectBranchCSPrefix)
- getModule().addModuleFlag(llvm::Module::Override, "indirect_branch_cs_prefix", 1);
+ getModule().addModuleFlag(llvm::Module::Override,
+ "indirect_branch_cs_prefix", 1);
// Add module metadata for return address signing (ignoring
// non-leaf/all) and stack tagging. These are actually turned on by function
@@ -1321,10 +1328,10 @@ void CodeGenModule::Release() {
// OpenCL.
auto Version = LangOpts.getOpenCLCompatibleVersion();
llvm::Metadata *SPIRVerElts[] = {
- llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
- Int32Ty, Version / 100)),
- llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
- Int32Ty, (Version / 100 > 1) ? 0 : 2))};
+ llvm::ConstantAsMetadata::get(
+ llvm::ConstantInt::get(Int32Ty, Version / 100)),
+ llvm::ConstantAsMetadata::get(
+ llvm::ConstantInt::get(Int32Ty, (Version / 100 > 1) ? 0 : 2))};
llvm::NamedMDNode *SPIRVerMD =
TheModule.getOrInsertNamedMetadata("opencl.spir.version");
llvm::LLVMContext &Ctx = TheModule.getContext();
@@ -1345,14 +1352,15 @@ void CodeGenModule::Release() {
if (getCodeGenOpts().CodeModel.size() > 0) {
unsigned CM = llvm::StringSwitch<unsigned>(getCodeGenOpts().CodeModel)
- .Case("tiny", llvm::CodeModel::Tiny)
- .Case("small", llvm::CodeModel::Small)
- .Case("kernel", llvm::CodeModel::Kernel)
- .Case("medium", llvm::CodeModel::Medium)
- .Case("large", llvm::CodeModel::Large)
- .Default(~0u);
+ .Case("tiny", llvm::CodeModel::Tiny)
+ .Case("small", llvm::CodeModel::Small)
+ .Case("kernel", llvm::CodeModel::Kernel)
+ .Case("medium", llvm::CodeModel::Medium)
+ .Case("large", llvm::CodeModel::Large)
+ .Default(~0u);
if (CM != ~0u) {
- llvm::CodeModel::Model codeModel = static_cast<llvm::CodeModel::Model>(CM);
+ llvm::CodeModel::Model codeModel =
+ static_cast<llvm::CodeModel::Model>(CM);
getModule().setCodeModel(codeModel);
if ((CM == llvm::CodeModel::Medium || CM == llvm::CodeModel::Large) &&
@@ -1458,6 +1466,13 @@ void CodeGenModule::Release() {
}
}
}
+
+ // Symbols for `long double` are more common than those for `_Float128`, so
+ // use them if this is possible.
+ if (&Context.getTargetInfo().getLongDoubleFormat() ==
+ &llvm::APFloatBase::IEEEquad()) {
+ getModule().setF128LibcallFormat(llvm::F128LibcallFormat::LongDouble);
+ }
}
void CodeGenModule::EmitOpenCLMetadata() {
@@ -1872,8 +1887,7 @@ static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM,
// Returns true if GD is a function decl with internal linkage and
// needs a unique suffix after the mangled name.
-static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
- CodeGenModule &CGM) {
+static bool isUniqueInternalLinkageDecl(GlobalDecl GD, CodeGenModule &CGM) {
const Decl *D = GD.getDecl();
return !CGM.getModuleNameHash().empty() && isa<FunctionDecl>(D) &&
(CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage);
@@ -2007,7 +2021,8 @@ void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD,
auto Result = Manglings.insert(std::make_pair(OtherName, OtherGD));
StringRef OtherNameRef = MangledDeclNames[OtherGD.getCanonicalDecl()] =
Result.first->first();
- // If this is the current decl is being created, make sure we update the name.
+ // If this is the current decl is being created, make sure we update the
+ // name.
if (GD.getCanonicalDecl() == OtherGD.getCanonicalDecl())
CurName = OtherNameRef;
if (llvm::GlobalValue *Entry = GetGlobalValue(NonTargetName))
@@ -2085,8 +2100,8 @@ StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD,
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
if (!D)
- MangleCtx.mangleGlobalBlock(BD,
- dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
+ MangleCtx.mangleGlobalBlock(
+ BD, dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D))
MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out);
else if (const auto *DD = dyn_cast<CXXDestructorDecl>(D))
@@ -2136,7 +2151,8 @@ void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority,
}
void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
- if (Fns.empty()) return;
+ if (Fns.empty())
+ return;
const PointerAuthSchema &InitFiniAuthSchema =
getCodeGenOpts().PointerAuth.InitFiniPointers;
@@ -2203,7 +2219,8 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) {
llvm::MDString *MDS = dyn_cast<llvm::MDString>(MD);
- if (!MDS) return nullptr;
+ if (!MDS)
+ return nullptr;
return llvm::ConstantInt::get(Int64Ty, llvm::MD5Hash(MDS->getString()));
}
@@ -2245,7 +2262,7 @@ void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD,
F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
-static void removeImageAccessQualifier(std::string& TyName) {
+static void removeImageAccessQualifier(std::string &TyName) {
std::string ReadOnlyQual("__read_only");
std::string::size_type ReadOnlyPos = TyName.find(ReadOnlyQual);
if (ReadOnlyPos != std::string::npos)
@@ -2431,8 +2448,7 @@ void CodeGenModule::GenKernelArgMetadata(llvm::Function *Fn,
}
if (getCodeGenOpts().EmitOpenCLArgMetadata ||
getCodeGenOpts().HIPSaveKernelArgName)
- Fn->setMetadata("kernel_arg_name",
- llvm::MDNode::get(VMContext, argNames));
+ Fn->setMetadata("kernel_arg_name", llvm::MDNode::get(VMContext, argNames));
}
/// Determines whether the language options require us to model
@@ -2442,10 +2458,12 @@ void CodeGenModule::GenKernelArgMetadata(llvm::Function *Fn,
/// enables this.
static bool hasUnwindExceptions(const LangOptions &LangOpts) {
// If exceptions are completely disabled, obviously this is false.
- if (!LangOpts.Exceptions) return false;
+ if (!LangOpts.Exceptions)
+ return false;
// If C++ exceptions are enabled, this is true.
- if (LangOpts.CXXExceptions) return true;
+ if (LangOpts.CXXExceptions)
+ return true;
// If ObjC exceptions are enabled, this depends on the ABI.
if (LangOpts.ObjCExceptions) {
@@ -2472,7 +2490,7 @@ SmallVector<const CXXRecordDecl *, 0>
CodeGenModule::getMostBaseClasses(const CXXRecordDecl *RD) {
llvm::SetVector<const CXXRecordDecl *> MostBases;
- std::function<void (const CXXRecordDecl *)> CollectMostBases;
+ std::function<void(const CXXRecordDecl *)> CollectMostBases;
CollectMostBases = [&](const CXXRecordDecl *RD) {
if (RD->getNumBases() == 0)
MostBases.insert(RD);
@@ -2754,8 +2772,8 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
AddedAttr = true;
}
if (!Features.empty() && SetTargetFeatures) {
- llvm::erase_if(Features, [&](const std::string& F) {
- return getTarget().isReadOnlyFeature(F.substr(1));
+ llvm::erase_if(Features, [&](const std::string &F) {
+ return getTarget().isReadOnlyFeature(F.substr(1));
});
llvm::sort(Features);
Attrs.addAttribute("target-features", llvm::join(Features, ","));
@@ -2952,10 +2970,10 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
// GCC and does not actually return "this".
if (!IsThunk && getCXXABI().HasThisReturn(GD) &&
!(getTriple().isiOS() && getTriple().isOSVersionLT(6))) {
- assert(!F->arg_empty() &&
- F->arg_begin()->getType()
- ->canLosslesslyBitCastTo(F->getReturnType()) &&
- "unexpected this return");
+ assert(
+ !F->arg_empty() &&
+ F->arg_begin()->getType()->canLosslesslyBitCastTo(F->getReturnType()) &&
+ "unexpected this return");
F->addParamAttr(0, llvm::Attribute::Returned);
}
@@ -2972,7 +2990,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
if (const auto *CSA = FD->getAttr<CodeSegAttr>())
F->setSection(CSA->getName());
else if (const auto *SA = FD->getAttr<SectionAttr>())
- F->setSection(SA->getName());
+ F->setSection(SA->getName());
if (const auto *EA = FD->getAttr<ErrorAttr>()) {
if (EA->isError())
@@ -3019,7 +3037,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
getOpenMPRuntime().emitDeclareSimdFunction(FD, F);
if (CodeGenOpts.InlineMaxStackSize != UINT_MAX)
- F->addFnAttr("inline-max-stacksize", llvm::utostr(CodeGenOpts.InlineMaxStackSize));
+ F->addFnAttr("inline-max-stacksize",
+ llvm::utostr(CodeGenOpts.InlineMaxStackSize));
if (const auto *CB = FD->getAttr<CallbackAttr>()) {
// Annotate the callback behavior as metadata:
@@ -3067,12 +3086,11 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
return;
// Convert List to what ConstantArray needs.
- SmallVector<llvm::Constant*, 8> UsedArray;
+ SmallVector<llvm::Constant *, 8> UsedArray;
UsedArray.resize(List.size());
for (unsigned i = 0, e = List.size(); i != e; ++i) {
- UsedArray[i] =
- llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
- cast<llvm::Constant>(&*List[i]), CGM.Int8PtrTy);
+ UsedArray[i] = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
+ cast<llvm::Constant>(&*List[i]), CGM.Int8PtrTy);
}
if (UsedArray.empty())
@@ -3108,7 +3126,7 @@ void CodeGenModule::AddDetectMismatch(StringRef Name, StringRef Value) {
void CodeGenModule::AddDependentLib(StringRef Lib) {
auto &C = getLLVMContext();
if (getTarget().getTriple().isOSBinFormatELF()) {
- ELFDependentLibraries.push_back(
+ ELFDependentLibraries.push_back(
llvm::MDNode::get(C, llvm::MDString::get(C, Lib)));
return;
}
@@ -3307,8 +3325,8 @@ void CodeGenModule::EmitDeferred() {
// to get GlobalValue with exactly the type we need, not something that
// might had been created for another decl with the same mangled name but
// different type.
- llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(
- GetAddrOfGlobal(D, ForDefinition));
+ llvm::GlobalValue *GV =
+ dyn_cast<llvm::GlobalValue>(GetAddrOfGlobal(D, ForDefinition));
// In case of different address spaces, we may still get a cast, even with
// IsForDefinition equal to true. Query mangled names table to get
@@ -3351,8 +3369,9 @@ void CodeGenModule::EmitVTablesOpportunistically() {
// is not allowed to create new references to things that need to be emitted
// lazily. Note that it also uses fact that we eagerly emitting RTTI.
- assert((OpportunisticVTables.empty() || shouldOpportunisticallyEmitVTables())
- && "Only emit opportunistic vtables with optimizations");
+ assert(
+ (OpportunisticVTables.empty() || shouldOpportunisticallyEmitVTables()) &&
+ "Only emit opportunistic vtables with optimizations");
for (const CXXRecordDecl *RD : OpportunisticVTables) {
assert(getVTables().isVTableExternal(RD) &&
@@ -3364,7 +3383,7 @@ void CodeGenModule::EmitVTablesOpportunistically() {
}
void CodeGenModule::EmitGlobalAnnotations() {
- for (const auto& [MangledName, VD] : DeferredAnnotations) {
+ for (const auto &[MangledName, VD] : DeferredAnnotations) {
llvm::GlobalValue *GV = GetGlobalValue(MangledName);
if (GV)
AddGlobalAnnotations(VD, GV);
@@ -3375,8 +3394,9 @@ void CodeGenModule::EmitGlobalAnnotations() {
return;
// Create a new global variable for the ConstantStruct in the Module.
- llvm::Constant *Array = llvm::ConstantArray::get(llvm::ArrayType::get(
- Annotations[0]->getType(), Annotations.size()), Annotations);
+ llvm::Constant *Array = llvm::ConstantArray::get(
+ llvm::ArrayType::get(Annotations[0]->getType(), Annotations.size()),
+ Annotations);
auto *gv = new llvm::GlobalVariable(getModule(), Array->getType(), false,
llvm::GlobalValue::AppendingLinkage,
Array, "llvm.global.annotations");
@@ -3411,8 +3431,8 @@ llvm::Constant *CodeGenModule::EmitAnnotationUnit(SourceLocation Loc) {
llvm::Constant *CodeGenModule::EmitAnnotationLineNo(SourceLocation L) {
SourceManager &SM = getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(L);
- unsigned LineNo = PLoc.isValid() ? PLoc.getLine() :
- SM.getExpansionLineNumber(L);
+ unsigned LineNo =
+ PLoc.isValid() ? PLoc.getLine() : SM.getExpansionLineNumber(L);
return llvm::ConstantInt::get(Int32Ty, LineNo);
}
@@ -3756,7 +3776,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject(
ConstantEmitter Emitter(*this);
llvm::Constant *Init = Emitter.emitForInitializer(
- TPO->getValue(), TPO->getType().getAddressSpace(), TPO->getType());
+ TPO->getValue(), TPO->getType().getAddressSpace(), TPO->getType());
if (!Init) {
ErrorUnsupported(TPO, "template parameter object");
@@ -3774,7 +3794,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject(
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
Emitter.finalize(GV);
- return ConstantAddress(GV, GV->getValueType(), Alignment);
+ return ConstantAddress(GV, GV->getValueType(), Alignment);
}
ConstantAddress CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
@@ -4003,109 +4023,108 @@ static bool HasNonDllImportDtor(QualType T) {
}
namespace {
- struct FunctionIsDirectlyRecursive
- : public ConstStmtVisitor<FunctionIsDirectlyRecursive, bool> {
- const StringRef Name;
- const Builtin::Context &BI;
- FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C)
- : Name(N), BI(C) {}
-
- bool VisitCallExpr(const CallExpr *E) {
- const FunctionDecl *FD = E->getDirectCallee();
- if (!FD)
- return false;
- AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
- if (Attr && Name == Attr->getLabel())
- return true;
- unsigned BuiltinID = FD->getBuiltinID();
- if (!BuiltinID || !BI.isLibFunction(BuiltinID))
- return false;
- std::string BuiltinNameStr = BI.getName(BuiltinID);
- StringRef BuiltinName = BuiltinNameStr;
- if (BuiltinName.starts_with("__builtin_") &&
- Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) {
- return true;
- }
+struct FunctionIsDirectlyRecursive
+ : public ConstStmtVisitor<FunctionIsDirectlyRecursive, bool> {
+ const StringRef Name;
+ const Builtin::Context &BI;
+ FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C)
+ : Name(N), BI(C) {}
+
+ bool VisitCallExpr(const CallExpr *E) {
+ const FunctionDecl *FD = E->getDirectCallee();
+ if (!FD)
return false;
- }
-
- bool VisitStmt(const Stmt *S) {
- for (const Stmt *Child : S->children())
- if (Child && this->Visit(Child))
- return true;
+ AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
+ if (Attr && Name == Attr->getLabel())
+ return true;
+ unsigned BuiltinID = FD->getBuiltinID();
+ if (!BuiltinID || !BI.isLibFunction(BuiltinID))
return false;
+ std::string BuiltinNameStr = BI.getName(BuiltinID);
+ StringRef BuiltinName = BuiltinNameStr;
+ if (BuiltinName.starts_with("__builtin_") &&
+ Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) {
+ return true;
}
- };
-
- // Make sure we're not referencing non-imported vars or functions.
- struct DLLImportFunctionVisitor
- : public RecursiveASTVisitor<DLLImportFunctionVisitor> {
- bool SafeToInline = true;
+ return false;
+ }
- bool shouldVisitImplicitCode() const { return true; }
+ bool VisitStmt(const Stmt *S) {
+ for (const Stmt *Child : S->children())
+ if (Child && this->Visit(Child))
+ return true;
+ return false;
+ }
+};
- bool VisitVarDecl(VarDecl *VD) {
- if (VD->getTLSKind()) {
- // A thread-local variable cannot be imported.
- SafeToInline = false;
- return SafeToInline;
- }
+// Make sure we're not referencing non-imported vars or functions.
+struct DLLImportFunctionVisitor
+ : public RecursiveASTVisitor<DLLImportFunctionVisitor> {
+ bool SafeToInline = true;
- // A variable definition might imply a destructor call.
- if (VD->isThisDeclarationADefinition())
- SafeToInline = !HasNonDllImportDtor(VD->getType());
+ bool shouldVisitImplicitCode() const { return true; }
+ bool VisitVarDecl(VarDecl *VD) {
+ if (VD->getTLSKind()) {
+ // A thread-local variable cannot be imported.
+ SafeToInline = false;
return SafeToInline;
}
- bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- if (const auto *D = E->getTemporary()->getDestructor())
- SafeToInline = D->hasAttr<DLLImportAttr>();
- return SafeToInline;
- }
+ // A variable definition might imply a destructor call.
+ if (VD->isThisDeclarationADefinition())
+ SafeToInline = !HasNonDllImportDtor(VD->getType());
- bool VisitDeclRefExpr(DeclRefExpr *E) {
- ValueDecl *VD = E->getDecl();
- if (isa<FunctionDecl>(VD))
- SafeToInline = VD->hasAttr<DLLImportAttr>();
- else if (VarDecl *V = dyn_cast<VarDecl>(VD))
- SafeToInline = !V->hasGlobalStorage() || V->hasAttr<DLLImportAttr>();
- return SafeToInline;
- }
+ return SafeToInline;
+ }
- bool VisitCXXConstructExpr(CXXConstructExpr *E) {
- SafeToInline = E->getConstructor()->hasAttr<DLLImportAttr>();
- return SafeToInline;
- }
+ bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+ if (const auto *D = E->getTemporary()->getDestructor())
+ SafeToInline = D->hasAttr<DLLImportAttr>();
+ return SafeToInline;
+ }
- bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
- CXXMethodDecl *M = E->getMethodDecl();
- if (!M) {
- // Call through a pointer to member function. This is safe to inline.
- SafeToInline = true;
- } else {
- SafeToInline = M->hasAttr<DLLImportAttr>();
- }
- return SafeToInline;
- }
+ bool VisitDeclRefExpr(DeclRefExpr *E) {
+ ValueDecl *VD = E->getDecl();
+ if (isa<FunctionDecl>(VD))
+ SafeToInline = VD->hasAttr<DLLImportAttr>();
+ else if (VarDecl *V = dyn_cast<VarDecl>(VD))
+ SafeToInline = !V->hasGlobalStorage() || V->hasAttr<DLLImportAttr>();
+ return SafeToInline;
+ }
- bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
- SafeToInline = E->getOperatorDelete()->hasAttr<DLLImportAttr>();
- return SafeToInline;
- }
+ bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+ SafeToInline = E->getConstructor()->hasAttr<DLLImportAttr>();
+ return SafeToInline;
+ }
- bool VisitCXXNewExpr(CXXNewExpr *E) {
- SafeToInline = E->getOperatorNew()->hasAttr<DLLImportAttr>();
- return SafeToInline;
+ bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+ CXXMethodDecl *M = E->getMethodDecl();
+ if (!M) {
+ // Call through a pointer to member function. This is safe to inline.
+ SafeToInline = true;
+ } else {
+ SafeToInline = M->hasAttr<DLLImportAttr>();
}
- };
-}
+ return SafeToInline;
+ }
+
+ bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+ SafeToInline = E->getOperatorDelete()->hasAttr<DLLImportAttr>();
+ return SafeToInline;
+ }
+
+ bool VisitCXXNewExpr(CXXNewExpr *E) {
+ SafeToInline = E->getOperatorNew()->hasAttr<DLLImportAttr>();
+ return SafeToInline;
+ }
+};
+} // namespace
// isTriviallyRecursive - Check if this function calls another
// decl that, because of the asm attribute or the other decl being a builtin,
// ends up pointing to itself.
-bool
-CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
+bool CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
StringRef Name;
if (getCXXABI().getMangleContext().shouldMangleDeclName(FD)) {
// asm labels are a special kind of mangling we have to support.
@@ -4160,7 +4179,7 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
if (F->hasAttr<DLLImportAttr>() && !F->hasAttr<AlwaysInlineAttr>()) {
// Check whether it would be safe to inline this dllimport function.
DLLImportFunctionVisitor Visitor;
- Visitor.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
+ Visitor.TraverseFunctionDecl(const_cast<FunctionDecl *>(F));
if (!Visitor.SafeToInline)
return false;
@@ -4438,8 +4457,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
llvm::PointerType::get(getLLVMContext(),
getTypes().getTargetAddressSpace(FD->getType())),
false);
- }
- else {
+ } else {
ResolverType = DeclTy;
ResolverGD = GD;
}
@@ -4471,10 +4489,10 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
if (!ExistingDecl.getDecl())
ExistingDecl = GD.getWithMultiVersionIndex(Index);
- Func = GetOrCreateLLVMFunction(
- MangledName, DeclTy, ExistingDecl,
- /*ForVTable=*/false, /*DontDefer=*/true,
- /*IsThunk=*/false, llvm::AttributeList(), ForDefinition);
+ Func = GetOrCreateLLVMFunction(MangledName, DeclTy, ExistingDecl,
+ /*ForVTable=*/false, /*DontDefer=*/true,
+ /*IsThunk=*/false, llvm::AttributeList(),
+ ForDefinition);
}
}
@@ -4527,8 +4545,8 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
IFunc = GI;
}
- std::string AliasName = getMangledNameImpl(
- *this, GD, FD, /*OmitMultiVersionMangling=*/true);
+ std::string AliasName =
+ getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true);
llvm::Constant *AliasFunc = GetGlobalValue(AliasName);
if (!AliasFunc) {
auto *GA = llvm::GlobalAlias::create(DeclTy, AS, Linkage, AliasName,
@@ -4734,8 +4752,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
}
// Make sure the result is of the correct type.
- // (If function is requested for a definition, we always need to create a new
- // function, not just return a bitcast.)
+ // (If function is requested for a definition, we always need to create a
+ // new function, not just return a bitcast.)
if (!IsForDefinition)
return Entry;
}
@@ -4893,8 +4911,8 @@ llvm::Constant *CodeGenModule::GetFunctionStart(const ValueDecl *Decl) {
return llvm::NoCFIValue::get(F);
}
-static const FunctionDecl *
-GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) {
+static const FunctionDecl *GetRuntimeFunctionDecl(ASTContext &C,
+ StringRef Name) {
TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
@@ -4988,10 +5006,9 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
ExtraAttrs.addFnAttribute(VMContext, llvm::Attribute::Convergent);
}
- llvm::Constant *C =
- GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
- /*DontDefer=*/false, /*IsThunk=*/false,
- ExtraAttrs);
+ llvm::Constant *C = GetOrCreateLLVMFunction(
+ Name, FTy, GlobalDecl(), /*ForVTable=*/false,
+ /*DontDefer=*/false, /*IsThunk=*/false, ExtraAttrs);
if (auto *F = dyn_cast<llvm::Function>(C)) {
if (F->empty()) {
@@ -5262,8 +5279,8 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable(
}
// Create a new variable.
- GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true,
- Linkage, nullptr, Name);
+ GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true, Linkage,
+ nullptr, Name);
if (OldGV) {
// Replace occurrences of the old variable if needed.
@@ -5291,9 +5308,9 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable(
/// normal requested type would be. If IsForDefinition is true, it is guaranteed
/// that an actual global with type Ty will be returned, not conversion of a
/// variable with the same mangled name but some other type.
-llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
- llvm::Type *Ty,
- ForDefinition_t IsForDefinition) {
+llvm::Constant *
+CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty,
+ ForDefinition_t IsForDefinition) {
assert(D->hasGlobalStorage() && "Not a global variable");
QualType ASTTy = D->getType();
if (!Ty)
@@ -5306,9 +5323,8 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
/// CreateRuntimeVariable - Create a new runtime global variable with the
/// specified type and name.
-llvm::Constant *
-CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty,
- StringRef Name) {
+llvm::Constant *CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty,
+ StringRef Name) {
LangAS AddrSpace = getContext().getLangOpts().OpenCL ? LangAS::opencl_global
: LangAS::Default;
auto *Ret = GetOrCreateLLVMGlobal(Name, Ty, AddrSpace, nullptr);
@@ -5331,8 +5347,8 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
// If we have not seen a reference to this variable yet, place it into the
// deferred declarations table to be emitted if needed later.
if (!MustBeEmitted(D) && !GV) {
- DeferredDecls[MangledName] = D;
- return;
+ DeferredDecls[MangledName] = D;
+ return;
}
// The tentative definition is the only definition.
@@ -5354,12 +5370,9 @@ CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
if (LangOpts.OpenCL) {
LangAS AS = D ? D->getType().getAddressSpace() : LangAS::opencl_global;
- assert(AS == LangAS::opencl_global ||
- AS == LangAS::opencl_global_device ||
- AS == LangAS::opencl_global_host ||
- AS == LangAS::opencl_constant ||
- AS == LangAS::opencl_local ||
- AS >= LangAS::FirstTargetAddressSpace);
+ assert(AS == LangAS::opencl_global || AS == LangAS::opencl_global_device ||
+ AS == LangAS::opencl_global_host || AS == LangAS::opencl_constant ||
+ AS == LangAS::opencl_local || AS >= LangAS::FirstTargetAddressSpace);
return AS;
}
@@ -5432,7 +5445,7 @@ castStringLiteralToDefaultAddressSpace(CodeGenModule &CGM,
return Cast;
}
-template<typename SomeDecl>
+template <typename SomeDecl>
void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D,
llvm::GlobalValue *GV) {
if (!getLangOpts().CPlusPlus)
@@ -5626,7 +5639,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
}
}
- llvm::Type* InitType = Init->getType();
+ llvm::Type *InitType = Init->getType();
llvm::Constant *Entry =
GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative));
@@ -6078,7 +6091,8 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
llvm::Function *NewFn) {
// If we're redefining a global as a function, don't transform it.
- if (!isa<llvm::Function>(Old)) return;
+ if (!isa<llvm::Function>(Old))
+ return;
replaceUsesOfNonProtoConstant(Old, NewFn);
}
@@ -6227,7 +6241,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
// Emit global alias debug information.
if (isa<VarDecl>(D))
if (CGDebugInfo *DI = getModuleDebugInfo())
- DI->EmitGlobalAlias(cast<llvm::GlobalValue>(GA->getAliasee()->stripPointerCasts()), GD);
+ DI->EmitGlobalAlias(
+ cast<llvm::GlobalValue>(GA->getAliasee()->stripPointerCasts()), GD);
}
void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) {
@@ -6293,7 +6308,7 @@ void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) {
}
llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,
- ArrayRef<llvm::Type*> Tys) {
+ ArrayRef<llvm::Type *> Tys) {
return llvm::Intrinsic::getOrInsertDeclaration(&getModule(),
(llvm::Intrinsic::ID)IID, Tys);
}
@@ -6329,7 +6344,8 @@ GetConstantCFStringEntry(llvm::StringMap<llvm::GlobalVariable *> &Map,
return *Map.insert(std::make_pair(
StringRef(reinterpret_cast<const char *>(ToBuf.data()),
(StringLength + 1) * 2),
- nullptr)).first;
+ nullptr))
+ .first;
}
ConstantAddress
@@ -6342,8 +6358,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
StringLength);
if (auto *C = Entry.second)
- return ConstantAddress(
- C, C->getValueType(), CharUnits::fromQuantity(C->getAlignment()));
+ return ConstantAddress(C, C->getValueType(),
+ CharUnits::fromQuantity(C->getAlignment()));
const ASTContext &Context = getContext();
const llvm::Triple &Triple = getTriple();
@@ -6361,8 +6377,10 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
Ty = llvm::ArrayType::get(Ty, 0);
switch (CFRuntime) {
- default: break;
- case LangOptions::CoreFoundationABI::Swift: [[fallthrough]];
+ default:
+ break;
+ case LangOptions::CoreFoundationABI::Swift:
+ [[fallthrough]];
case LangOptions::CoreFoundationABI::Swift5_0:
CFConstantStringClassName =
Triple.isOSDarwin() ? "$s15SwiftFoundation19_NSCFConstantStringCN"
@@ -6474,9 +6492,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
Fields.add(GV);
// String length.
- llvm::IntegerType *LengthTy =
- llvm::IntegerType::get(getModule().getContext(),
- Context.getTargetInfo().getLongWidth());
+ llvm::IntegerType *LengthTy = llvm::IntegerType::get(
+ getModule().getContext(), Context.getTargetInfo().getLongWidth());
if (IsSwiftABI) {
if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 ||
CFRuntime == LangOptions::CoreFoundationABI::Swift4_2)
@@ -6534,14 +6551,11 @@ QualType CodeGenModule::getObjCFastEnumerationStateType() {
nullptr, ArraySizeModifier::Normal, 0)};
for (size_t i = 0; i < 4; ++i) {
- FieldDecl *Field = FieldDecl::Create(Context,
- D,
- SourceLocation(),
- SourceLocation(), nullptr,
- FieldTypes[i], /*TInfo=*/nullptr,
- /*BitWidth=*/nullptr,
- /*Mutable=*/false,
- ICIS_NoInit);
+ FieldDecl *Field =
+ FieldDecl::Create(Context, D, SourceLocation(), SourceLocation(),
+ nullptr, FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
+ /*Mutable=*/false, ICIS_NoInit);
Field->setAccess(AS_public);
D->addDecl(Field);
}
@@ -6578,7 +6592,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) {
SmallVector<uint16_t, 32> Elements;
Elements.reserve(NumElements);
- for(unsigned i = 0, e = E->getLength(); i != e; ++i)
+ for (unsigned i = 0, e = E->getLength(); i != e; ++i)
Elements.push_back(E->getCodeUnit(i));
Elements.resize(NumElements);
return llvm::ConstantDataArray::get(VMContext, Elements);
@@ -6588,7 +6602,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) {
SmallVector<uint32_t, 32> Elements;
Elements.reserve(NumElements);
- for(unsigned i = 0, e = E->getLength(); i != e; ++i)
+ for (unsigned i = 0, e = E->getLength(); i != e; ++i)
Elements.push_back(E->getCodeUnit(i));
Elements.resize(NumElements);
return llvm::ConstantDataArray::get(VMContext, Elements);
@@ -6683,8 +6697,9 @@ CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
/// GetAddrOfConstantCString - Returns a pointer to a character array containing
/// the literal and a terminating '\0' character.
/// The result has pointer to array type.
-ConstantAddress CodeGenModule::GetAddrOfConstantCString(
- const std::string &Str, const char *GlobalName) {
+ConstantAddress
+CodeGenModule::GetAddrOfConstantCString(const std::string &Str,
+ const char *GlobalName) {
StringRef StrWithNull(Str.c_str(), Str.size() + 1);
CharUnits Alignment = getContext().getAlignOfGlobalVarInChars(
getContext().CharTy, /*VD=*/nullptr);
@@ -6717,10 +6732,12 @@ ConstantAddress CodeGenModule::GetAddrOfConstantCString(
GV->getValueType(), Alignment);
}
-ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
- const MaterializeTemporaryExpr *E, const Expr *Init) {
+ConstantAddress
+CodeGenModule::GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E,
+ const Expr *Init) {
assert((E->getStorageDuration() == SD_Static ||
- E->getStorageDuration() == SD_Thread) && "not a global temporary");
+ E->getStorageDuration() == SD_Thread) &&
+ "not a global temporary");
const auto *VD = cast<VarDecl>(E->getExtendingDecl());
// If we're not materializing a subobject of the temporary, keep the
@@ -6784,8 +6801,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
if (Value) {
// The temporary has a constant initializer, use it.
emitter.emplace(*this);
- InitialValue = emitter->emitForInitializer(*Value, AddrSpace,
- MaterializedType);
+ InitialValue =
+ emitter->emitForInitializer(*Value, AddrSpace, MaterializedType);
Constant =
MaterializedType.isConstantStorage(getContext(), /*ExcludeCtor*/ Value,
/*ExcludeDtor*/ false);
@@ -6815,7 +6832,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
auto *GV = new llvm::GlobalVariable(
getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
/*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
- if (emitter) emitter->finalize(GV);
+ if (emitter)
+ emitter->finalize(GV);
// Don't assign dllimport or dllexport to local linkage globals.
if (!llvm::GlobalValue::isLocalLinkage(Linkage)) {
setGVProperties(GV, VD);
@@ -6850,8 +6868,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
/// EmitObjCPropertyImplementations - Emit information for synthesized
/// properties for an implementation.
-void CodeGenModule::EmitObjCPropertyImplementations(const
- ObjCImplementationDecl *D) {
+void CodeGenModule::EmitObjCPropertyImplementations(
+ const ObjCImplementationDecl *D) {
for (const auto *PID : D->property_impls()) {
// Dynamic is just for type-checking.
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
@@ -6869,15 +6887,15 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
auto *Setter = PID->getSetterMethodDecl();
if (!PD->isReadOnly() && (!Setter || Setter->isSynthesizedAccessorStub()))
CodeGenFunction(*this).GenerateObjCSetter(
- const_cast<ObjCImplementationDecl *>(D), PID);
+ const_cast<ObjCImplementationDecl *>(D), PID);
}
}
}
static bool needsDestructMethod(ObjCImplementationDecl *impl) {
const ObjCInterfaceDecl *iface = impl->getClassInterface();
- for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
- ivar; ivar = ivar->getNextIvar())
+ for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); ivar;
+ ivar = ivar->getNextIvar())
if (ivar->getType().isDestructedType())
return true;
@@ -6888,7 +6906,8 @@ static bool AllTrivialInitializers(CodeGenModule &CGM,
ObjCImplementationDecl *D) {
CodeGenFunction CGF(CGM);
for (ObjCImplementationDecl::init_iterator B = D->init_begin(),
- E = D->init_end(); B != E; ++B) {
+ E = D->init_end();
+ B != E; ++B) {
CXXCtorInitializer *CtorInitExp = *B;
Expr *Init = CtorInitExp->getInit();
if (!CGF.isTrivialInitializer(Init))
@@ -6918,8 +6937,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
// If the implementation doesn't have any ivar initializers, we don't need
// a .cxx_construct.
- if (D->getNumIvarInitializers() == 0 ||
- AllTrivialInitializers(*this, D))
+ if (D->getNumIvarInitializers() == 0 || AllTrivialInitializers(*this, D))
return;
const IdentifierInfo *II = &getContext().Idents.get(".cxx_construct");
@@ -7052,7 +7070,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
TSK_ExplicitInstantiationDefinition &&
Spec->hasDefinition())
DI->completeTemplateDefinition(*Spec);
- } [[fallthrough]];
+ }
+ [[fallthrough]];
case Decl::CXXRecord: {
CXXRecordDecl *CRD = cast<CXXRecordDecl>(D);
if (CGDebugInfo *DI = getModuleDebugInfo()) {
@@ -7080,9 +7099,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::Empty:
case Decl::Binding:
break;
- case Decl::Using: // using X; [C++]
+ case Decl::Using: // using X; [C++]
if (CGDebugInfo *DI = getModuleDebugInfo())
- DI->EmitUsingDecl(cast<UsingDecl>(*D));
+ DI->EmitUsingDecl(cast<UsingDecl>(*D));
break;
case Decl::UsingEnum: // using enum X; [C++]
if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -7090,7 +7109,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
break;
case Decl::NamespaceAlias:
if (CGDebugInfo *DI = getModuleDebugInfo())
- DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(*D));
+ DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(*D));
break;
case Decl::UsingDirective: // using namespace X; [C++]
if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -7135,8 +7154,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// Emit global variable debug information.
if (CGDebugInfo *DI = getModuleDebugInfo())
if (getCodeGenOpts().hasReducedDebugInfo())
- DI->getOrCreateInterfaceType(getContext().getObjCInterfaceType(
- OMD->getClassInterface()), OMD->getLocation());
+ DI->getOrCreateInterfaceType(
+ getContext().getObjCInterfaceType(OMD->getClassInterface()),
+ OMD->getLocation());
break;
}
case Decl::ObjCMethod: {
@@ -7159,7 +7179,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
AppendLinkerOptions(PCD->getArg());
break;
case PCK_Lib:
- AddDependentLib(PCD->getArg());
+ AddDependentLib(PCD->getArg());
break;
case PCK_Compiler:
case PCK_ExeStr:
@@ -7389,7 +7409,8 @@ void CodeGenModule::EmitMainVoidAlias() {
// new-style no-argument main is in used.
if (llvm::Function *F = getModule().getFunction("main")) {
if (!F->isDeclaration() && F->arg_size() == 0 && !F->isVarArg() &&
- F->getReturnType()->isIntegerTy(Context.getTargetInfo().getIntWidth())) {
+ F->getReturnType()->isIntegerTy(
+ Context.getTargetInfo().getIntWidth())) {
auto *GA = llvm::GlobalAlias::create("__main_void", F);
GA->setVisibility(llvm::GlobalValue::HiddenVisibility);
}
@@ -7406,11 +7427,10 @@ static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context,
static void EmitGlobalDeclMetadata(CodeGenModule &CGM,
llvm::NamedMDNode *&GlobalMetadata,
- GlobalDecl D,
- llvm::GlobalValue *Addr) {
+ GlobalDecl D, llvm::GlobalValue *Addr) {
if (!GlobalMetadata)
GlobalMetadata =
- CGM.getModule().getOrInsertNamedMetadata("clang.global.decl.ptrs");
+ CGM.getModule().getOrInsertNamedMetadata("clang.global.decl.ptrs");
// TODO: should we report variant information for ctors/dtors?
llvm::Metadata *Ops[] = {llvm::ConstantAsMetadata::get(Addr),
@@ -7544,7 +7564,8 @@ void CodeGenModule::EmitDeclMetadata() {
/// Emits metadata nodes for all the local variables in the current
/// function.
void CodeGenFunction::EmitDeclMetadata() {
- if (LocalDeclMap.empty()) return;
+ if (LocalDeclMap.empty())
+ return;
llvm::LLVMContext &Context = getLLVMContext();
@@ -7570,7 +7591,7 @@ void CodeGenFunction::EmitDeclMetadata() {
void CodeGenModule::EmitVersionIdentMetadata() {
llvm::NamedMDNode *IdentMetadata =
- TheModule.getOrInsertNamedMetadata("llvm.ident");
+ TheModule.getOrInsertNamedMetadata("llvm.ident");
std::string Version = getClangFullVersion();
llvm::LLVMContext &Ctx = TheModule.getContext();
@@ -7580,7 +7601,7 @@ void CodeGenModule::EmitVersionIdentMetadata() {
void CodeGenModule::EmitCommandLineMetadata() {
llvm::NamedMDNode *CommandLineMetadata =
- TheModule.getOrInsertNamedMetadata("llvm.commandline");
+ TheModule.getOrInsertNamedMetadata("llvm.commandline");
std::string CommandLine = getCodeGenOpts().RecordCommandLine;
llvm::LLVMContext &Ctx = TheModule.getContext();
@@ -7691,8 +7712,8 @@ static QualType GeneralizeType(ASTContext &Ctx, QualType Ty) {
return Ty;
return Ctx.getPointerType(
- QualType(Ctx.VoidTy).withCVRQualifiers(
- Ty->getPointeeType().getCVRQualifiers()));
+ QualType(Ctx.VoidTy)
+ .withCVRQualifiers(Ty->getPointeeType().getCVRQualifiers()));
}
// Apply type generalization to a FunctionType's return and argument types
@@ -7702,9 +7723,8 @@ static QualType GeneralizeFunctionType(ASTContext &Ctx, QualType Ty) {
for (auto &Param : FnType->param_types())
GeneralizedParams.push_back(GeneralizeType(Ctx, Param));
- return Ctx.getFunctionType(
- GeneralizeType(Ctx, FnType->getReturnType()),
- GeneralizedParams, FnType->getExtProtoInfo());
+ return Ctx.getFunctionType(GeneralizeType(Ctx, FnType->getReturnType()),
+ GeneralizedParams, FnType->getExtProtoInfo());
}
if (auto *FnType = Ty->getAs<FunctionNoProtoType>())
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 12b50fc506516..ebb7b82adac19 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -28,6 +28,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ProfileSummary.h"
+#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/CodeGen.h"
@@ -1065,6 +1066,12 @@ class LLVM_ABI Module {
/// Set the target variant version build SDK version metadata.
void setDarwinTargetVariantSDKVersion(VersionTuple Version);
+
+ /// Rather than using the default `sinf128(_Float128)`-style libcalls for
+ /// `fp128`, lower to sinl(long double)`-style. This may be desirable in
+ /// cases where system `long double` is format- and ABI-compatible with
+ /// `_Float128` but the system libm does not provide `*f128` symbols.
+ void setF128LibcallFormat(F128LibcallFormat LibcallFmt);
};
/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index 515b484cab343..c7dfef9002020 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -86,7 +86,8 @@ HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
HANDLE_LIBCALL(CTLZ_I64, "__clzdi2")
HANDLE_LIBCALL(CTLZ_I128, "__clzti2")
-// Floating-point
+// Floating-point. Note that new fp128 math routines should also be added to
+// setF128LibcallFormat in RuntimeLibcalls.cpp.
HANDLE_LIBCALL(ADD_F32, "__addsf3")
HANDLE_LIBCALL(ADD_F64, "__adddf3")
HANDLE_LIBCALL(ADD_F80, "__addxf3")
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index fd1930cce0b05..41d6497e40a9c 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -22,6 +22,17 @@
#include "llvm/TargetParser/Triple.h"
namespace llvm {
+
+/// Library names to use for `fp128` libcalls.
+// If needed, this could be extended with a `Quadmath` option for `q`-suffixed
+// `libquadmath` symbols.
+enum class F128LibcallFormat {
+ /// C23 `*f128` lowering, e.g. `sinf128`
+ Default = 0,
+ /// `long double` *l` lowering, e.g. `sinl`.
+ LongDouble = 1,
+};
+
namespace RTLIB {
/// RTLIB::Libcall enum - This enum defines all of the runtime library calls
@@ -42,22 +53,7 @@ enum Libcall {
struct RuntimeLibcallsInfo {
/// Default libcalls for the triple. Note that `fixupLibcalls` should also be
/// called in order to apply machine-specific and configurable behavior.
- explicit RuntimeLibcallsInfo(const Triple &TT) {
- initLibcalls(TT);
- }
-
- /// Apply nondefault overrides to libcalls based on machine configuration.
- ///
- /// @param[in] TM Used to account for ABI-secific affects on
- /// libcalls.
- /// @param[in] LongDoubleFormat If set, override the platform default.
- // TODO: maybe make the option an enum
- // enum Fp128LibcallFormat {
- // AsF128; // always lower to f128 versions (probably what Rust will do)
- // AsLongDouble; // always lower f128 as long double (probably what Clang should do)
- // AsPlatformDefault; // don't change anything
- // }
- void adjustLibcalls(const TargetMachine &TM, const fltSemantics *LongDoubleFormat);
+ explicit RuntimeLibcallsInfo(const Triple &TT) { initLibcalls(TT); }
/// Rename the default libcall routine name for the specified libcall.
void setLibcallName(RTLIB::Libcall Call, const char *Name) {
@@ -89,6 +85,25 @@ struct RuntimeLibcallsInfo {
LibcallRoutineNames + RTLIB::UNKNOWN_LIBCALL);
}
+ /// Set a specific lowering convention for `fp128` math libcalls.
+ ///
+ /// By default, `fp128` math functions get lowered to the C23 `sinf128`-
+ /// style symbols. This allows overriding with `sinl`-style symbols on
+ /// platforms where `long double` is known to be identical to _Float128.
+ /// versions, e.g. `sinf128`.
+ void setF128LibcallFormat(F128LibcallFormat Format);
+
+ /// Set the `fp128` libcall format from a module flag.
+ void setF128LibcallFormatFromInt(uint64_t Val) {
+ if (Val == static_cast<uint64_t>(F128LibcallFormat::LongDouble)) {
+ setF128LibcallFormat(F128LibcallFormat::LongDouble);
+ } else {
+ setF128LibcallFormat(F128LibcallFormat::Default);
+ }
+ }
+
+ static constexpr const StringRef F128LibcallModuleId = "";
+
private:
/// Stores the name each libcall.
const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index c7b9f8744d8d3..ba51a3d74b67b 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -32,6 +32,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeFinder.h"
@@ -209,7 +210,7 @@ FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty,
// Nope, add it
Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage,
DL.getProgramAddressSpace(), Name, this);
- if (!New->isIntrinsic()) // Intrinsics get attrs set on construction
+ if (!New->isIntrinsic()) // Intrinsics get attrs set on construction
New->setAttributes(AttributeList);
return {Ty, New}; // Return the new prototype.
}
@@ -243,7 +244,7 @@ Function *Module::getFunction(StringRef Name) const {
GlobalVariable *Module::getGlobalVariable(StringRef Name,
bool AllowLocal) const {
if (GlobalVariable *Result =
- dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)))
+ dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)))
if (AllowLocal || !Result->hasLocalLinkage())
return Result;
return nullptr;
@@ -334,10 +335,11 @@ bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) {
}
/// getModuleFlagsMetadata - Returns the module flags in the provided vector.
-void Module::
-getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
+void Module::getModuleFlagsMetadata(
+ SmallVectorImpl<ModuleFlagEntry> &Flags) const {
const NamedMDNode *ModFlags = getModuleFlagsMetadata();
- if (!ModFlags) return;
+ if (!ModFlags)
+ return;
for (const MDNode *Flag : ModFlags->operands()) {
// The verifier will catch errors, so no need to check them here.
@@ -915,3 +917,9 @@ VersionTuple Module::getDarwinTargetVariantSDKVersion() const {
void Module::setDarwinTargetVariantSDKVersion(VersionTuple Version) {
addSDKVersionMD(Version, *this, "darwin.target_variant.SDK Version");
}
+
+void Module::setF128LibcallFormat(F128LibcallFormat Format) {
+ addModuleFlag(ModFlagBehavior::Error,
+ RTLIB::RuntimeLibcallsInfo::F128LibcallModuleId,
+ static_cast<uint32_t>(Format));
+}
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 01fdd832a5ba6..de0cfe7b35796 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -206,57 +206,50 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
}
}
-void RuntimeLibcallsInfo::adjustLibcalls(const TargetMachine &TM,
- const fltSemantics *LongDoubleFormat) {
-
- const Triple &TT = TM.getTargetTriple();
-
- // The long double version of library functions is more common than the
- // f128-specific version. Use these if that is the long double type on the
- // platform, or if the frontend specifies.
- if (TT.isLongDoubleF128()) {
- setLibcallName(RTLIB::ACOS_F128, "acosl");
- setLibcallName(RTLIB::ASIN_F128, "asinl");
- setLibcallName(RTLIB::ATAN2_F128, "atan2l");
- setLibcallName(RTLIB::ATAN_F128, "atanl");
- setLibcallName(RTLIB::CBRT_F128, "cbrtl");
- setLibcallName(RTLIB::CEIL_F128, "ceill");
- setLibcallName(RTLIB::COPYSIGN_F128, "copysignl");
- setLibcallName(RTLIB::COSH_F128, "coshl");
- setLibcallName(RTLIB::COS_F128, "cosl");
- setLibcallName(RTLIB::EXP10_F128, "exp10l");
- setLibcallName(RTLIB::EXP2_F128, "exp2l");
- setLibcallName(RTLIB::EXP_F128, "expl");
- setLibcallName(RTLIB::FLOOR_F128, "floorl");
- setLibcallName(RTLIB::FMAXIMUMNUM_F128, "fmaximum_numl");
- setLibcallName(RTLIB::FMAXIMUM_F128, "fmaximuml");
- setLibcallName(RTLIB::FMAX_F128, "fmaxl");
- setLibcallName(RTLIB::FMA_F128, "fmal");
- setLibcallName(RTLIB::FMINIMUMNUM_F128, "fminimum_numl");
- setLibcallName(RTLIB::FMINIMUM_F128, "fminimuml");
- setLibcallName(RTLIB::FMIN_F128, "fminl");
- setLibcallName(RTLIB::FREXP_F128, "frexpl");
- setLibcallName(RTLIB::LDEXP_F128, "ldexpl");
- setLibcallName(RTLIB::LLRINT_F128, "llrintl");
- setLibcallName(RTLIB::LLROUND_F128, "llroundl");
- setLibcallName(RTLIB::LOG10_F128, "log10l");
- setLibcallName(RTLIB::LOG2_F128, "log2l");
- setLibcallName(RTLIB::LOG_F128, "logl");
- setLibcallName(RTLIB::LRINT_F128, "lrintl");
- setLibcallName(RTLIB::LROUND_F128, "lroundl");
- setLibcallName(RTLIB::MODF_F128, "modfl");
- setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintl");
- setLibcallName(RTLIB::POW_F128, "powl");
- setLibcallName(RTLIB::REM_F128, "fmodl");
- setLibcallName(RTLIB::RINT_F128, "rintl");
- setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenl");
- setLibcallName(RTLIB::ROUND_F128, "roundl");
- setLibcallName(RTLIB::SINCOSPI_F128, "sincospil");
- setLibcallName(RTLIB::SINH_F128, "sinhl");
- setLibcallName(RTLIB::SIN_F128, "sinl");
- setLibcallName(RTLIB::SQRT_F128, "sqrtl");
- setLibcallName(RTLIB::TANH_F128, "tanhl");
- setLibcallName(RTLIB::TAN_F128, "tanl");
- setLibcallName(RTLIB::TRUNC_F128, "truncl");
- }
+void RuntimeLibcallsInfo::setF128LibcallFormat(F128LibcallFormat Format) {
+ bool UseLD = Format == F128LibcallFormat::LongDouble;
+
+ setLibcallName(RTLIB::ACOS_F128, UseLD ? "acosl" : "acosf128");
+ setLibcallName(RTLIB::ASIN_F128, UseLD ? "asinl" : "asinf128");
+ setLibcallName(RTLIB::ATAN2_F128, UseLD ? "atan2l" : "atan2f128");
+ setLibcallName(RTLIB::ATAN_F128, UseLD ? "atanl" : "atanf128");
+ setLibcallName(RTLIB::CBRT_F128, UseLD ? "cbrtl" : "cbrtf128");
+ setLibcallName(RTLIB::CEIL_F128, UseLD ? "ceill" : "ceilf128");
+ setLibcallName(RTLIB::COPYSIGN_F128, UseLD ? "copysignl" : "copysignf128");
+ setLibcallName(RTLIB::COSH_F128, UseLD ? "coshl" : "coshf128");
+ setLibcallName(RTLIB::COS_F128, UseLD ? "cosl" : "cosf128");
+ setLibcallName(RTLIB::EXP10_F128, UseLD ? "exp10l" : "exp10f128");
+ setLibcallName(RTLIB::EXP2_F128, UseLD ? "exp2l" : "exp2f128");
+ setLibcallName(RTLIB::EXP_F128, UseLD ? "expl" : "expf128");
+ setLibcallName(RTLIB::FLOOR_F128, UseLD ? "floorl" : "floorf128");
+ setLibcallName(RTLIB::FMAXIMUMNUM_F128, UseLD ? "fmaximum_numl" : "fmaximum_numf128");
+ setLibcallName(RTLIB::FMAXIMUM_F128, UseLD ? "fmaximuml" : "fmaximumf128");
+ setLibcallName(RTLIB::FMAX_F128, UseLD ? "fmaxl" : "fmaxf128");
+ setLibcallName(RTLIB::FMA_F128, UseLD ? "fmal" : "fmaf128");
+ setLibcallName(RTLIB::FMINIMUMNUM_F128, UseLD ? "fminimum_numl" : "fminimum_numf128");
+ setLibcallName(RTLIB::FMINIMUM_F128, UseLD ? "fminimuml" : "fminimumf128");
+ setLibcallName(RTLIB::FMIN_F128, UseLD ? "fminl" : "fminf128");
+ setLibcallName(RTLIB::FREXP_F128, UseLD ? "frexpl" : "frexpf128");
+ setLibcallName(RTLIB::LDEXP_F128, UseLD ? "ldexpl" : "ldexpf128");
+ setLibcallName(RTLIB::LLRINT_F128, UseLD ? "llrintl" : "llrintf128");
+ setLibcallName(RTLIB::LLROUND_F128, UseLD ? "llroundl" : "llroundf128");
+ setLibcallName(RTLIB::LOG10_F128, UseLD ? "log10l" : "log10f128");
+ setLibcallName(RTLIB::LOG2_F128, UseLD ? "log2l" : "log2f128");
+ setLibcallName(RTLIB::LOG_F128, UseLD ? "logl" : "logf128");
+ setLibcallName(RTLIB::LRINT_F128, UseLD ? "lrintl" : "lrintf128");
+ setLibcallName(RTLIB::LROUND_F128, UseLD ? "lroundl" : "lroundf128");
+ setLibcallName(RTLIB::MODF_F128, UseLD ? "modfl" : "modff128");
+ setLibcallName(RTLIB::NEARBYINT_F128, UseLD ? "nearbyintl" : "nearbyintf128");
+ setLibcallName(RTLIB::POW_F128, UseLD ? "powl" : "powf128");
+ setLibcallName(RTLIB::REM_F128, UseLD ? "fmodl" : "fmodf128");
+ setLibcallName(RTLIB::RINT_F128, UseLD ? "rintl" : "rintf128");
+ setLibcallName(RTLIB::ROUNDEVEN_F128, UseLD ? "roundevenl" : "roundevenf128");
+ setLibcallName(RTLIB::ROUND_F128, UseLD ? "roundl" : "roundf128");
+ setLibcallName(RTLIB::SINCOSPI_F128, UseLD ? "sincospil" : "sincospif128");
+ setLibcallName(RTLIB::SINH_F128, UseLD ? "sinhl" : "sinhf128");
+ setLibcallName(RTLIB::SIN_F128, UseLD ? "sinl" : "sinf128");
+ setLibcallName(RTLIB::SQRT_F128, UseLD ? "sqrtl" : "sqrtf128");
+ setLibcallName(RTLIB::TANH_F128, UseLD ? "tanhl" : "tanhf128");
+ setLibcallName(RTLIB::TAN_F128, UseLD ? "tanl" : "tanf128");
+ setLibcallName(RTLIB::TRUNC_F128, UseLD ? "truncl" : "truncf128");
}
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index 2a2b235461a55..a31744c12e3e4 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -16,6 +16,7 @@
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Comdat.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalObject.h"
@@ -213,11 +214,19 @@ Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) {
return P.first->second;
}
-static DenseSet<StringRef> buildPreservedSymbolsSet(const Triple &TT) {
+/// Initialize a set with the platform's libcalls.
+static DenseSet<StringRef> buildPreservedSymbolsSet(const Module *M) {
DenseSet<StringRef> PreservedSymbolSet(std::begin(PreservedSymbols),
std::end(PreservedSymbols));
+ const Triple &TT = llvm::Triple(M->getTargetTriple());
RTLIB::RuntimeLibcallsInfo Libcalls(TT);
+
+ // Configure libcalls based on module flags.
+ const auto *Flag = mdconst::extract_or_null<ConstantInt>(
+ M->getModuleFlag(RTLIB::RuntimeLibcallsInfo::F128LibcallModuleId));
+ Libcalls.setF128LibcallFormatFromInt(Flag->getZExtValue());
+
for (const char *Name : Libcalls.getLibcallNames()) {
if (Name)
PreservedSymbolSet.insert(Name);
@@ -281,8 +290,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
setStr(Sym.IRName, GV->getName());
static const DenseSet<StringRef> PreservedSymbolsSet =
- buildPreservedSymbolsSet(
- llvm::Triple(GV->getParent()->getTargetTriple()));
+ buildPreservedSymbolsSet(GV->getParent());
bool IsPreservedSymbol = PreservedSymbolsSet.contains(GV->getName());
if (Used.count(GV) || IsPreservedSymbol)
>From 9e9b530835fef4fbe45072e3968c0702d588a259 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross at umich.edu>
Date: Sat, 1 Mar 2025 08:55:29 +0000
Subject: [PATCH 5/5] WIP
---
clang/test/CodeGen/f128-math-lowering.c | 15 ++
llvm/include/llvm/IR/RuntimeLibcalls.h | 7 +-
llvm/include/llvm/Target/TargetOptions.h | 6 +-
llvm/lib/CodeGen/TargetLoweringBase.cpp | 1 +
llvm/lib/LTO/LTO.cpp | 1 +
llvm/lib/Object/IRSymtab.cpp | 2 +
.../CodeGen/Generic/f128-math-lowering.ll | 162 ++++++++++--------
7 files changed, 115 insertions(+), 79 deletions(-)
create mode 100644 clang/test/CodeGen/f128-math-lowering.c
diff --git a/clang/test/CodeGen/f128-math-lowering.c b/clang/test/CodeGen/f128-math-lowering.c
new file mode 100644
index 0000000000000..aa58238faad92
--- /dev/null
+++ b/clang/test/CodeGen/f128-math-lowering.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-linux-android -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=A64
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=G64
+// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=P64
+// RUN: %clang_cc1 -triple i686-linux-android -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=A32
+// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=G32
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=P32
+// RUN: %clang_cc1 -triple x86_64-nacl -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=N64
+
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index 41d6497e40a9c..4ffa5a267815a 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -94,15 +94,16 @@ struct RuntimeLibcallsInfo {
void setF128LibcallFormat(F128LibcallFormat Format);
/// Set the `fp128` libcall format from a module flag.
- void setF128LibcallFormatFromInt(uint64_t Val) {
- if (Val == static_cast<uint64_t>(F128LibcallFormat::LongDouble)) {
+ void setF128LibcallFormatFromInt(uint32_t Val) {
+ fprintf(stderr, "setting flag\n");
+ if (Val == static_cast<uint32_t>(F128LibcallFormat::LongDouble)) {
setF128LibcallFormat(F128LibcallFormat::LongDouble);
} else {
setF128LibcallFormat(F128LibcallFormat::Default);
}
}
- static constexpr const StringRef F128LibcallModuleId = "";
+ static constexpr const StringRef F128LibcallModuleId = "Fp128 Libcall Format";
private:
/// Stores the name each libcall.
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index fd8dad4f6f791..6ec03431ab529 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -15,6 +15,7 @@
#define LLVM_TARGET_TARGETOPTIONS_H
#include "llvm/ADT/FloatingPointMode.h"
+#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/MC/MCTargetOptions.h"
#include <memory>
@@ -154,7 +155,8 @@ namespace llvm {
PPCGenScalarMASSEntries(false), JMCInstrument(false),
EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
VerifyArgABICompliance(true),
- FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
+ FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE),
+ F128LibcallFormat(F128LibcallFormat::Default) {}
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// optimization should be disabled for the given machine function.
@@ -433,6 +435,8 @@ namespace llvm {
/// Which debugger to tune for.
DebuggerKind DebuggerTuning = DebuggerKind::Default;
+ llvm::F128LibcallFormat F128LibcallFormat;
+
private:
/// Flushing mode to assume in default FP environment.
DenormalMode FPDenormalMode;
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index f5ea3c0b47d6a..4dc5dbc1151a4 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -662,6 +662,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm)
SupportsUnalignedAtomics = false;
RTLIB::initCmpLibcallCCs(CmpLibcallCCs);
+ Libcalls.setF128LibcallFormat(tm.Options.F128LibcallFormat);
}
void TargetLoweringBase::initActions() {
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 0f53c60851217..213dd5c47832a 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -1380,6 +1380,7 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) {
}
SmallVector<const char *> LTO::getRuntimeLibcallSymbols(const Triple &TT) {
+ fprintf(stderr, "call from lto\n");
RTLIB::RuntimeLibcallsInfo Libcalls(TT);
SmallVector<const char *> LibcallSymbols;
copy_if(Libcalls.getLibcallNames(), std::back_inserter(LibcallSymbols),
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index a31744c12e3e4..96b5726d7c305 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -227,6 +227,8 @@ static DenseSet<StringRef> buildPreservedSymbolsSet(const Module *M) {
M->getModuleFlag(RTLIB::RuntimeLibcallsInfo::F128LibcallModuleId));
Libcalls.setF128LibcallFormatFromInt(Flag->getZExtValue());
+ fprintf(stderr, "AOJDSFOIDOIFJD %d\n", Flag->getZExtValue());
+
for (const char *Name : Libcalls.getLibcallNames()) {
if (Name)
PreservedSymbolSet.insert(Name);
diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
index a68cd1c39698e..d8ed0f9d84663 100644
--- a/llvm/test/CodeGen/Generic/f128-math-lowering.ll
+++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll
@@ -1,12 +1,22 @@
-; RUN: llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD
-; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
-; RUN: llc < %s -mtriple=powerpc-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
-; RUN: llc < %s -mtriple=powerpc64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
-; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
-; RUN: llc < %s -mtriple=s390x-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-S390X
-; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD
+;
+; RUN: llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: llc < %s -mtriple=powerpc-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: llc < %s -mtriple=powerpc64-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: llc < %s -mtriple=s390x-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-S390X
+; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-F128
+; RUN: sed 's/; flag://' %s | llc -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
+; RUN: sed 's/; flag://' %s | llc -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
+; RUN: sed 's/; flag://' %s | llc -mtriple=powerpc-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
+; RUN: sed 's/; flag://' %s | llc -mtriple=powerpc64-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
+; RUN: sed 's/; flag://' %s | llc -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
+; RUN: sed 's/; flag://' %s | llc -mtriple=s390x-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-S390X
+; RUN: sed 's/; flag://' %s | llc -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
+; RUN: sed 's/; flag://' %s | llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
+; RUN: sed 's/; flag://' %s | llc -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-USELD
;
; REQUIRES: aarch64-registered-target
; REQUIRES: powerpc-registered-target
@@ -24,16 +34,16 @@
; * riscv32 (long double == f64)
; * s390x (long double == f128, hardware support)
; * A couple assorted environments for x86
-;
-; FIXME: only targets where long double is `f128` should be using `USELD`, all
-; others need to be NOTLD. PowerPC should be added but it currently emits an
-; interesting blend of both (e.g. `acosl` but `ceilf128`).
+
+
+; flag: !0 = !{ i32 1, !"Fp128 Libcall Format", i32 1 }
+; flag: !llvm.module.flags = !{ !0 }
define fp128 @test_acosf128(fp128 %a) {
; CHECK-LABEL: test_acosf128:
-; CHECK-NOTLD: acosf128
+; CHECK-F128: acosf128
; CHECK-USELD: acosl
-; CHECK-S390X: acosl
+; CHECK-S390X: acosf128
start:
%0 = tail call fp128 @llvm.acos.f128(fp128 %a)
ret fp128 %0
@@ -41,9 +51,9 @@ start:
define fp128 @test_asinf128(fp128 %a) {
; CHECK-LABEL: test_asinf128:
-; CHECK-NOTLD: asinf128
+; CHECK-F128: asinf128
; CHECK-USELD: asinl
-; CHECK-S390X: asinl
+; CHECK-S390X: asinf128
start:
%0 = tail call fp128 @llvm.asin.f128(fp128 %a)
ret fp128 %0
@@ -51,9 +61,9 @@ start:
define fp128 @test_atanf128(fp128 %a) {
; CHECK-LABEL: test_atanf128:
-; CHECK-NOTLD: atanf128
+; CHECK-F128: atanf128
; CHECK-USELD: atanl
-; CHECK-S390X: atanl
+; CHECK-S390X: atanf128
start:
%0 = tail call fp128 @llvm.atan.f128(fp128 %a)
ret fp128 %0
@@ -61,19 +71,20 @@ start:
define fp128 @test_ceilf128(fp128 %a) {
; CHECK-LABEL: test_ceilf128:
-; CHECK-NOTLD: ceilf128
+; CHECK-F128: ceilf128
; CHECK-USELD: ceill
-; CHECK-S390X: ceill
+; CHECK-S390X: ceilf128
start:
%0 = tail call fp128 @llvm.ceil.f128(fp128 %a)
ret fp128 %0
}
define fp128 @test_copysignf128(fp128 %a, fp128 %b) {
-; copysign should always get lowered to assembly
+; copysign should always get lowered to assembly. Regex is needed so as not to
+; match the label.
; CHECK-LABEL: test_copysignf128:
-; CHECK-NOT: copysignl
-; CHECK-NOT: copysignf128
+; CHECK-NOT: {{(^|[[:space:]])fabsf128($|[[:space:]])}}
+; CHECK-NOT: {{(^|[[:space:]])fabsl($|[[:space:]])}}
start:
%0 = tail call fp128 @llvm.copysign.f128(fp128 %a, fp128 %b)
ret fp128 %0
@@ -81,19 +92,19 @@ start:
define fp128 @test_cosf128(fp128 %a) {
; CHECK-LABEL: test_cosf128:
-; CHECK-NOTLD: cosf128
+; CHECK-F128: cosf128
; CHECK-USELD: cosl
-; CHECK-S390X: cosl
+; CHECK-S390X: cosf128
start:
%0 = tail call fp128 @llvm.cos.f128(fp128 %a)
ret fp128 %0
}
define fp128 @test_exp10f128(fp128 %a) {
-; CHECK-LABEL: test_exp2f128:
-; CHECK-NOTLD: exp10f128
+; CHECK-LABEL: test_exp10f128:
+; CHECK-F128: exp10f128
; CHECK-USELD: exp10l
-; CHECK-S390X: exp10l
+; CHECK-S390X: exp10f128
start:
%0 = tail call fp128 @llvm.exp10.f128(fp128 %a)
ret fp128 %0
@@ -101,9 +112,9 @@ start:
define fp128 @test_exp2f128(fp128 %a) {
; CHECK-LABEL: test_exp2f128:
-; CHECK-NOTLD: exp2f128
+; CHECK-F128: exp2f128
; CHECK-USELD: exp2l
-; CHECK-S390X: exp2l
+; CHECK-S390X: exp2f128
start:
%0 = tail call fp128 @llvm.exp2.f128(fp128 %a)
ret fp128 %0
@@ -112,19 +123,20 @@ start:
define fp128 @test_expf128(fp128 %a) {
; CHECK-LABEL: test_expf128:
-; CHECK-NOTLD: expf128
+; CHECK-F128: expf128
; CHECK-USELD: expl
-; CHECK-S390X: expl
+; CHECK-S390X: expf128
start:
%0 = tail call fp128 @llvm.exp.f128(fp128 %a)
ret fp128 %0
}
define fp128 @test_fabsf128(fp128 %a) {
-; fabs should always get lowered to assembly
+; fabs should always get lowered to assembly. Regex is needed so as not to
+; match the label.
; CHECK-LABEL: test_fabsf128:
-; CHECK-NOT: fabsl
-; CHECK-NOT: fabsf128
+; CHECK-NOT: {{(^|[[:space:]])fabsf128($|[[:space:]])}}
+; CHECK-NOT: {{(^|[[:space:]])fabsl($|[[:space:]])}}
start:
%0 = tail call fp128 @llvm.fabs.f128(fp128 %a)
ret fp128 %0
@@ -132,9 +144,9 @@ start:
define fp128 @test_floorf128(fp128 %a) {
; CHECK-LABEL: test_floorf128:
-; CHECK-NOTLD: floorf128
+; CHECK-F128: floorf128
; CHECK-USELD: floorl
-; CHECK-S390X: floorl
+; CHECK-S390X: floorf128
start:
%0 = tail call fp128 @llvm.floor.f128(fp128 %a)
ret fp128 %0
@@ -142,9 +154,9 @@ start:
define fp128 @test_fmaf128(fp128 %a, fp128 %b, fp128 %c) {
; CHECK-LABEL: test_fmaf128:
-; CHECK-NOTLD: fmaf128
+; CHECK-F128: fmaf128
; CHECK-USELD: fmal
-; CHECK-S390X: fmal
+; CHECK-S390X: fmaf128
start:
%0 = tail call fp128 @llvm.fma.f128(fp128 %a, fp128 %b, fp128 %c)
ret fp128 %0
@@ -152,9 +164,9 @@ start:
define { fp128, i32 } @test_frexpf128(fp128 %a) {
; CHECK-LABEL: test_frexpf128:
-; CHECK-NOTLD: frexpf128
+; CHECK-F128: frexpf128
; CHECK-USELD: frexpl
-; CHECK-S390X: frexpl
+; CHECK-S390X: frexpf128
start:
%0 = tail call { fp128, i32 } @llvm.frexp.f128(fp128 %a)
ret { fp128, i32 } %0
@@ -162,9 +174,9 @@ start:
define fp128 @test_ldexpf128(fp128 %a, i32 %b) {
; CHECK-LABEL: test_ldexpf128:
-; CHECK-NOTLD: ldexpf128
+; CHECK-F128: ldexpf128
; CHECK-USELD: ldexpl
-; CHECK-S390X: ldexpl
+; CHECK-S390X: ldexpf128
start:
%0 = tail call fp128 @llvm.ldexp.f128(fp128 %a, i32 %b)
ret fp128 %0
@@ -172,9 +184,9 @@ start:
define i64 @test_llrintf128(fp128 %a) {
; CHECK-LABEL: test_llrintf128:
-; CHECK-NOTLD: llrintf128
+; CHECK-F128: llrintf128
; CHECK-USELD: llrintl
-; CHECK-S390X: llrintl
+; CHECK-S390X: llrintf128
start:
%0 = tail call i64 @llvm.llrint.f128(fp128 %a)
ret i64 %0
@@ -182,9 +194,9 @@ start:
define i64 @test_llroundf128(fp128 %a) {
; CHECK-LABEL: test_llroundf128:
-; CHECK-NOTLD: llroundf128
+; CHECK-F128: llroundf128
; CHECK-USELD: llroundl
-; CHECK-S390X: llroundl
+; CHECK-S390X: llroundf128
start:
%0 = tail call i64 @llvm.llround.i64.f128(fp128 %a)
ret i64 %0
@@ -192,9 +204,9 @@ start:
define fp128 @test_log10f128(fp128 %a) {
; CHECK-LABEL: test_log10f128:
-; CHECK-NOTLD: log10f128
+; CHECK-F128: log10f128
; CHECK-USELD: log10l
-; CHECK-S390X: log10l
+; CHECK-S390X: log10f128
start:
%0 = tail call fp128 @llvm.log10.f128(fp128 %a)
ret fp128 %0
@@ -202,9 +214,9 @@ start:
define fp128 @test_log2f128(fp128 %a) {
; CHECK-LABEL: test_log2f128:
-; CHECK-NOTLD: log2f128
+; CHECK-F128: log2f128
; CHECK-USELD: log2l
-; CHECK-S390X: log2l
+; CHECK-S390X: log2f128
start:
%0 = tail call fp128 @llvm.log2.f128(fp128 %a)
ret fp128 %0
@@ -212,19 +224,19 @@ start:
define fp128 @test_logf128(fp128 %a) {
; CHECK-LABEL: test_logf128:
-; CHECK-NOTLD: logf128
+; CHECK-F128: logf128
; CHECK-USELD: logl
-; CHECK-S390X: logl
+; CHECK-S390X: logf128
start:
%0 = tail call fp128 @llvm.log.f128(fp128 %a)
ret fp128 %0
}
define i64 @test_lrintf128(fp128 %a) {
-; CHECK-LABEL: test_exp2f128:
-; CHECK-NOTLD: lrintf128
+; CHECK-LABEL: test_lrintf128:
+; CHECK-F128: lrintf128
; CHECK-USELD: lrintl
-; CHECK-S390X: lrintl
+; CHECK-S390X: lrintf128
start:
%0 = tail call i64 @llvm.lrint.f128(fp128 %a)
ret i64 %0
@@ -232,9 +244,9 @@ start:
define i64 @test_lroundf128(fp128 %a) {
; CHECK-LABEL: test_lroundf128:
-; CHECK-NOTLD: lroundf128
+; CHECK-F128: lroundf128
; CHECK-USELD: lroundl
-; CHECK-S390X: lroundl
+; CHECK-S390X: lroundf128
start:
%0 = tail call i64 @llvm.lround.i64.f128(fp128 %a)
ret i64 %0
@@ -242,9 +254,9 @@ start:
define fp128 @test_nearbyintf128(fp128 %a) {
; CHECK-LABEL: test_nearbyintf128:
-; CHECK-NOTLD: nearbyintf128
+; CHECK-F128: nearbyintf128
; CHECK-USELD: nearbyintl
-; CHECK-S390X: nearbyintl
+; CHECK-S390X: nearbyintf128
start:
%0 = tail call fp128 @llvm.nearbyint.f128(fp128 %a)
ret fp128 %0
@@ -252,9 +264,9 @@ start:
define fp128 @test_powf128(fp128 %a, fp128 %b) {
; CHECK-LABEL: test_powf128:
-; CHECK-NOTLD: powf128
+; CHECK-F128: powf128
; CHECK-USELD: powl
-; CHECK-S390X: powl
+; CHECK-S390X: powf128
start:
%0 = tail call fp128 @llvm.pow.f128(fp128 %a, fp128 %b)
ret fp128 %0
@@ -262,7 +274,7 @@ start:
define fp128 @test_rintf128(fp128 %a) {
; CHECK-LABEL: test_rintf128:
-; CHECK-NOTLD: rintf128
+; CHECK-F128: rintf128
; CHECK-USELD: rintl
; CHECK-S390X: fixbr {{%.*}}, 0, {{%.*}}
start:
@@ -272,9 +284,9 @@ start:
define fp128 @test_roundevenf128(fp128 %a) {
; CHECK-LABEL: test_roundevenf128:
-; CHECK-NOTLD: roundevenf128
+; CHECK-F128: roundevenf128
; CHECK-USELD: roundevenl
-; CHECK-S390X: roundevenl
+; CHECK-S390X: roundevenf128
start:
%0 = tail call fp128 @llvm.roundeven.f128(fp128 %a)
ret fp128 %0
@@ -282,9 +294,9 @@ start:
define fp128 @test_roundf128(fp128 %a) {
; CHECK-LABEL: test_roundf128:
-; CHECK-NOTLD: roundf128
+; CHECK-F128: roundf128
; CHECK-USELD: roundl
-; CHECK-S390X: roundl
+; CHECK-S390X: roundf128
start:
%0 = tail call fp128 @llvm.round.f128(fp128 %a)
ret fp128 %0
@@ -292,9 +304,9 @@ start:
define fp128 @test_sinf128(fp128 %a) {
; CHECK-LABEL: test_sinf128:
-; CHECK-NOTLD: sinf128
+; CHECK-F128: sinf128
; CHECK-USELD: sinl
-; CHECK-S390X: sinl
+; CHECK-S390X: sinf128
start:
%0 = tail call fp128 @llvm.sin.f128(fp128 %a)
ret fp128 %0
@@ -302,7 +314,7 @@ start:
define fp128 @test_sqrtf128(fp128 %a) {
; CHECK-LABEL: test_sqrtf128:
-; CHECK-NOTLD: sqrtf128
+; CHECK-F128: sqrtf128
; CHECK-USELD: sqrtl
; CHECK-S390X: sqxbr {{%.*}}, {{%.*}}
start:
@@ -312,9 +324,9 @@ start:
define fp128 @test_tanf128(fp128 %a) {
; CHECK-LABEL: test_tanf128:
-; CHECK-NOTLD: tanf128
+; CHECK-F128: tanf128
; CHECK-USELD: tanl
-; CHECK-S390X: tanl
+; CHECK-S390X: tanf128
start:
%0 = tail call fp128 @llvm.tan.f128(fp128 %a)
ret fp128 %0
@@ -322,9 +334,9 @@ start:
define fp128 @test_truncf128(fp128 %a) {
; CHECK-LABEL: test_truncf128:
-; CHECK-NOTLD: truncf128
+; CHECK-F128: truncf128
; CHECK-USELD: truncl
-; CHECK-S390X: truncl
+; CHECK-S390X: truncf128
start:
%0 = tail call fp128 @llvm.trunc.f128(fp128 %a)
ret fp128 %0
More information about the cfe-commits
mailing list