Files
TheRock/compiler/amd-llvm/llvm/test/Instrumentation/NumericalStabilitySanitizer/libfuncs.ll
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

1583 lines
79 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=nsan -nsan-shadow-type-mapping=dqq -nsan-truncate-fcmp-eq=false -S %s | FileCheck %s --check-prefixes=CHECK,DQQ
; RUN: opt -passes=nsan -nsan-shadow-type-mapping=dlq -nsan-truncate-fcmp-eq=false -S %s | FileCheck %s --check-prefixes=CHECK,DLQ
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
; FIXME: nsan is currently using long double (e.g. sin.f80) instead of quad (sin.f128).
;###############################################################
;# sqrt #
;###############################################################
declare float @sqrtf(float)
declare double @sqrt(double)
declare x86_fp80 @sqrtl(x86_fp80)
define float @call_sqrtf() sanitize_numerical_stability {
; CHECK-LABEL: @call_sqrtf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @sqrtf(float 4.000000e+00) #[[ATTR3:[0-9]+]]
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.sqrt.f64(double 4.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_sqrtf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @sqrtf(float 4.0)
ret float %r
}
define double @call_sqrt() sanitize_numerical_stability {
; DQQ-LABEL: @call_sqrt(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @sqrt(double 4.000000e+00) #[[ATTR3]]
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sqrt.f80(x86_fp80 4.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_sqrt to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_sqrt(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @sqrt(double 4.000000e+00) #[[ATTR3]]
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sqrt.f80(x86_fp80 4.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_sqrt to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @sqrt(double 4.0)
ret double %r
}
define x86_fp80 @call_sqrtl() sanitize_numerical_stability {
; CHECK-LABEL: @call_sqrtl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @sqrtl(x86_fp80 4.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sqrt.f80(x86_fp80 4.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_sqrtl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @sqrtl(x86_fp80 0xK40018000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# sin #
;###############################################################
declare float @sinf(float)
declare double @sin(double)
declare x86_fp80 @sinl(x86_fp80)
define float @call_sinf() sanitize_numerical_stability {
; CHECK-LABEL: @call_sinf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @sinf(float 1.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.sin.f64(double 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_sinf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @sinf(float 1.0)
ret float %r
}
define double @call_sin() sanitize_numerical_stability {
; DQQ-LABEL: @call_sin(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @sin(double 1.000000e+00) #[[ATTR3]]
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 1.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_sin to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_sin(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @sin(double 1.000000e+00) #[[ATTR3]]
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 1.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_sin to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @sin(double 1.0)
ret double %r
}
define x86_fp80 @call_sinl() sanitize_numerical_stability {
; CHECK-LABEL: @call_sinl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @sinl(x86_fp80 1.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_sinl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @sinl(x86_fp80 0xK3FFF8000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# cos #
;###############################################################
declare float @cosf(float)
declare double @cos(double)
declare x86_fp80 @cosl(x86_fp80)
define float @call_cosf() sanitize_numerical_stability {
; CHECK-LABEL: @call_cosf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @cosf(float 1.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.cos.f64(double 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_cosf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @cosf(float 1.0)
ret float %r
}
define double @call_cos() sanitize_numerical_stability {
; DQQ-LABEL: @call_cos(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @cos(double 1.000000e+00) #[[ATTR3]]
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.cos.f80(x86_fp80 1.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_cos to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_cos(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @cos(double 1.000000e+00) #[[ATTR3]]
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.cos.f80(x86_fp80 1.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_cos to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @cos(double 1.0)
ret double %r
}
define x86_fp80 @call_cosl() sanitize_numerical_stability {
; CHECK-LABEL: @call_cosl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @cosl(x86_fp80 1.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.cos.f80(x86_fp80 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_cosl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @cosl(x86_fp80 0xK3FFF8000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# pow #
;###############################################################
declare float @powf(float, float)
declare double @pow(double, double)
declare x86_fp80 @powl(x86_fp80, x86_fp80)
define float @call_powf() sanitize_numerical_stability {
; CHECK-LABEL: @call_powf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @powf(float 2.000000e+00, float 3.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.pow.f64(double 2.000000e+00, double 3.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_powf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @powf(float 2.0, float 3.0)
ret float %r
}
define double @call_pow() sanitize_numerical_stability {
; DQQ-LABEL: @call_pow(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @pow(double 2.000000e+00, double 3.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.pow.f80(x86_fp80 2.000000e+00, x86_fp80 3.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_pow to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_pow(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @pow(double 2.000000e+00, double 3.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.pow.f80(x86_fp80 2.000000e+00, x86_fp80 3.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_pow to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @pow(double 2.0, double 3.0)
ret double %r
}
define x86_fp80 @call_powl() sanitize_numerical_stability {
; CHECK-LABEL: @call_powl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @powl(x86_fp80 2.000000e+00, x86_fp80 4.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.pow.f80(x86_fp80 2.000000e+00, x86_fp80 4.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_powl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @powl(x86_fp80 0xK40008000000000000000, x86_fp80 0xK40018000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# exp #
;###############################################################
declare float @expf(float)
declare double @exp(double)
declare x86_fp80 @expl(x86_fp80)
define float @call_expf() sanitize_numerical_stability {
; CHECK-LABEL: @call_expf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @expf(float 1.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.exp.f64(double 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_expf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @expf(float 1.0)
ret float %r
}
define double @call_exp() sanitize_numerical_stability {
; DQQ-LABEL: @call_exp(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @exp(double 1.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.exp.f80(x86_fp80 1.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_exp to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_exp(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @exp(double 1.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.exp.f80(x86_fp80 1.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_exp to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @exp(double 1.0)
ret double %r
}
define x86_fp80 @call_expl() sanitize_numerical_stability {
; CHECK-LABEL: @call_expl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @expl(x86_fp80 1.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.exp.f80(x86_fp80 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_expl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @expl(x86_fp80 0xK3FFF8000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# exp2 #
;###############################################################
declare float @exp2f(float)
declare double @exp2(double)
declare x86_fp80 @exp2l(x86_fp80)
define float @call_exp2f() sanitize_numerical_stability {
; CHECK-LABEL: @call_exp2f(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @exp2f(float 1.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.exp2.f64(double 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_exp2f to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @exp2f(float 1.0)
ret float %r
}
define double @call_exp2() sanitize_numerical_stability {
; DQQ-LABEL: @call_exp2(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @exp2(double 1.000000e+00) #[[ATTR3]]
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.exp2.f80(x86_fp80 1.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_exp2 to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_exp2(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @exp2(double 1.000000e+00) #[[ATTR3]]
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.exp2.f80(x86_fp80 1.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_exp2 to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @exp2(double 1.0)
ret double %r
}
define x86_fp80 @call_exp2l() sanitize_numerical_stability {
; CHECK-LABEL: @call_exp2l(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @exp2l(x86_fp80 1.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.exp2.f80(x86_fp80 1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_exp2l to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @exp2l(x86_fp80 0xK3FFF8000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# log #
;###############################################################
declare float @logf(float)
declare double @log(double)
declare x86_fp80 @logl(x86_fp80)
define float @call_logf() sanitize_numerical_stability {
; CHECK-LABEL: @call_logf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @logf(float 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.log.f64(double 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_logf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @logf(float 2.0)
ret float %r
}
define double @call_log() sanitize_numerical_stability {
; DQQ-LABEL: @call_log(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @log(double 2.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log.f80(x86_fp80 2.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_log to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_log(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @log(double 2.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log.f80(x86_fp80 2.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_log to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @log(double 2.0)
ret double %r
}
define x86_fp80 @call_logl() sanitize_numerical_stability {
; CHECK-LABEL: @call_logl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @logl(x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log.f80(x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_logl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @logl(x86_fp80 0xK40008000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# log10 #
;###############################################################
declare float @log10f(float)
declare double @log10(double)
declare x86_fp80 @log10l(x86_fp80)
define float @call_log10f() sanitize_numerical_stability {
; CHECK-LABEL: @call_log10f(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @log10f(float 1.000000e+02)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.log10.f64(double 1.000000e+02)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_log10f to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @log10f(float 100.0)
ret float %r
}
define double @call_log10() sanitize_numerical_stability {
; DQQ-LABEL: @call_log10(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @log10(double 1.000000e+02)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log10.f80(x86_fp80 1.000000e+02)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_log10 to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_log10(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @log10(double 1.000000e+02)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log10.f80(x86_fp80 1.000000e+02)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_log10 to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @log10(double 100.0)
ret double %r
}
define x86_fp80 @call_log10l() sanitize_numerical_stability {
; CHECK-LABEL: @call_log10l(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @log10l(x86_fp80 +snan(0x0))
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log10.f80(x86_fp80 +snan(0x0))
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_log10l to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @log10l(x86_fp80 0xK40590000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# log2 #
;###############################################################
declare float @log2f(float)
declare double @log2(double)
declare x86_fp80 @log2l(x86_fp80)
define float @call_log2f() sanitize_numerical_stability {
; CHECK-LABEL: @call_log2f(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @log2f(float 8.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.log2.f64(double 8.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_log2f to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @log2f(float 8.0)
ret float %r
}
define double @call_log2() sanitize_numerical_stability {
; DQQ-LABEL: @call_log2(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @log2(double 8.000000e+00) #[[ATTR3]]
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log2.f80(x86_fp80 8.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_log2 to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_log2(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @log2(double 8.000000e+00) #[[ATTR3]]
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log2.f80(x86_fp80 8.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_log2 to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @log2(double 8.0)
ret double %r
}
define x86_fp80 @call_log2l() sanitize_numerical_stability {
; CHECK-LABEL: @call_log2l(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @log2l(x86_fp80 4.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.log2.f80(x86_fp80 4.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_log2l to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @log2l(x86_fp80 0xK40018000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# fabs #
;###############################################################
declare float @fabsf(float)
declare double @fabs(double)
declare x86_fp80 @fabsl(x86_fp80)
define float @call_fabsf() sanitize_numerical_stability {
; CHECK-LABEL: @call_fabsf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @fabsf(float -1.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double -1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fabsf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @fabsf(float -1.0)
ret float %r
}
define double @call_fabs() sanitize_numerical_stability {
; DQQ-LABEL: @call_fabs(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @fabs(double -1.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 -1.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_fabs to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_fabs(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @fabs(double -1.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 -1.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_fabs to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @fabs(double -1.0)
ret double %r
}
define x86_fp80 @call_fabsl() sanitize_numerical_stability {
; CHECK-LABEL: @call_fabsl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @fabsl(x86_fp80 -1.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 -1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fabsl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @fabsl(x86_fp80 0xKBFFF8000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# copysign #
;###############################################################
declare float @copysignf(float, float)
declare double @copysign(double, double)
declare x86_fp80 @copysignl(x86_fp80, x86_fp80)
define float @call_copysignf() sanitize_numerical_stability {
; CHECK-LABEL: @call_copysignf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @copysignf(float 1.000000e+00, float -2.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double -2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_copysignf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @copysignf(float 1.0, float -2.0)
ret float %r
}
define double @call_copysign() sanitize_numerical_stability {
; DQQ-LABEL: @call_copysign(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @copysign(double 1.000000e+00, double -2.000000e+00) #[[ATTR3]]
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.copysign.f80(x86_fp80 1.000000e+00, x86_fp80 -2.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_copysign to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_copysign(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @copysign(double 1.000000e+00, double -2.000000e+00) #[[ATTR3]]
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.copysign.f80(x86_fp80 1.000000e+00, x86_fp80 -2.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_copysign to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @copysign(double 1.0, double -2.0)
ret double %r
}
define x86_fp80 @call_copysignl() sanitize_numerical_stability {
; CHECK-LABEL: @call_copysignl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @copysignl(x86_fp80 1.000000e+00, x86_fp80 -1.000000e+00) #[[ATTR3]]
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.copysign.f80(x86_fp80 1.000000e+00, x86_fp80 -1.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_copysignl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @copysignl(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xKBFFF8000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# floor #
;###############################################################
declare float @floorf(float)
declare double @floor(double)
declare x86_fp80 @floorl(x86_fp80)
define float @call_floorf() sanitize_numerical_stability {
; CHECK-LABEL: @call_floorf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @floorf(float 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.floor.f64(double 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_floorf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @floorf(float 1.5)
ret float %r
}
define double @call_floor() sanitize_numerical_stability {
; DQQ-LABEL: @call_floor(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @floor(double 1.500000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.floor.f80(x86_fp80 1.500000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_floor to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_floor(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @floor(double 1.500000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.floor.f80(x86_fp80 1.500000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_floor to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @floor(double 1.5)
ret double %r
}
define x86_fp80 @call_floorl() sanitize_numerical_stability {
; CHECK-LABEL: @call_floorl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @floorl(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.floor.f80(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_floorl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @floorl(x86_fp80 0xK3FFFC000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# fmax #
;###############################################################
declare float @fmaxf(float, float)
declare double @fmax(double, double)
declare x86_fp80 @fmaxl(x86_fp80, x86_fp80)
define float @call_fmaxf() sanitize_numerical_stability {
; CHECK-LABEL: @call_fmaxf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @fmaxf(float 1.000000e+00, float 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.maxnum.f64(double 1.000000e+00, double 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fmaxf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @fmaxf(float 1.0, float 2.0)
ret float %r
}
define double @call_fmax() sanitize_numerical_stability {
; DQQ-LABEL: @call_fmax(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @fmax(double 1.000000e+00, double 2.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maxnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_fmax to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_fmax(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @fmax(double 1.000000e+00, double 2.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maxnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_fmax to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @fmax(double 1.0, double 2.0)
ret double %r
}
define x86_fp80 @call_fmaxl() sanitize_numerical_stability {
; CHECK-LABEL: @call_fmaxl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @fmaxl(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maxnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fmaxl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @fmaxl(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# fmin #
;###############################################################
declare float @fminf(float, float)
declare double @fmin(double, double)
declare x86_fp80 @fminl(x86_fp80, x86_fp80)
define float @call_fminf() sanitize_numerical_stability {
; CHECK-LABEL: @call_fminf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @fminf(float 1.000000e+00, float 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.minnum.f64(double 1.000000e+00, double 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fminf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @fminf(float 1.0, float 2.0)
ret float %r
}
define double @call_fmin() sanitize_numerical_stability {
; DQQ-LABEL: @call_fmin(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @fmin(double 1.000000e+00, double 2.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_fmin to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_fmin(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @fmin(double 1.000000e+00, double 2.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_fmin to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @fmin(double 1.0, double 2.0)
ret double %r
}
define x86_fp80 @call_fminl() sanitize_numerical_stability {
; CHECK-LABEL: @call_fminl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @fminl(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fminl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @fminl(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# fminimum_num #
;###############################################################
declare float @fminimum_numf(float, float)
declare double @fminimum_num(double, double)
declare x86_fp80 @fminimum_numl(x86_fp80, x86_fp80)
define float @call_fminimum_numf() sanitize_numerical_stability {
; CHECK-LABEL: @call_fminimum_numf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @fminimum_numf(float 1.000000e+00, float 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.minimumnum.f64(double 1.000000e+00, double 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fminimum_numf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @fminimum_numf(float 1.0, float 2.0)
ret float %r
}
define double @call_fminimum_num() sanitize_numerical_stability {
; DQQ-LABEL: @call_fminimum_num(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @fminimum_num(double 1.000000e+00, double 2.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minimumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_fminimum_num to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_fminimum_num(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @fminimum_num(double 1.000000e+00, double 2.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minimumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_fminimum_num to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @fminimum_num(double 1.0, double 2.0)
ret double %r
}
define x86_fp80 @call_fminimum_numl() sanitize_numerical_stability {
; CHECK-LABEL: @call_fminimum_numl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @fminimum_numl(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minimumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fminimum_numl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @fminimum_numl(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# fmaximum_num #
;###############################################################
declare float @fmaximum_numf(float, float)
declare double @fmaximum_num(double, double)
declare x86_fp80 @fmaximum_numl(x86_fp80, x86_fp80)
define float @call_fmaximum_numf() sanitize_numerical_stability {
; CHECK-LABEL: @call_fmaximum_numf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @fmaximum_numf(float 1.000000e+00, float 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.maximumnum.f64(double 1.000000e+00, double 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fmaximum_numf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @fmaximum_numf(float 1.0, float 2.0)
ret float %r
}
define double @call_fmaximum_num() sanitize_numerical_stability {
; DQQ-LABEL: @call_fmaximum_num(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @fmaximum_num(double 1.000000e+00, double 2.000000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maximumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_fmaximum_num to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_fmaximum_num(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @fmaximum_num(double 1.000000e+00, double 2.000000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maximumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_fmaximum_num to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @fmaximum_num(double 1.0, double 2.0)
ret double %r
}
define x86_fp80 @call_fmaximum_numl() sanitize_numerical_stability {
; CHECK-LABEL: @call_fmaximum_numl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @fmaximum_numl(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maximumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fmaximum_numl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @fmaximum_numl(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# ceil #
;###############################################################
declare float @ceilf(float)
declare double @ceil(double)
declare x86_fp80 @ceill(x86_fp80)
define float @call_ceilf() sanitize_numerical_stability {
; CHECK-LABEL: @call_ceilf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @ceilf(float 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.ceil.f64(double 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_ceilf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @ceilf(float 1.5)
ret float %r
}
define double @call_ceil() sanitize_numerical_stability {
; DQQ-LABEL: @call_ceil(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @ceil(double 1.500000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.ceil.f80(x86_fp80 1.500000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_ceil to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_ceil(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @ceil(double 1.500000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.ceil.f80(x86_fp80 1.500000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_ceil to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @ceil(double 1.5)
ret double %r
}
define x86_fp80 @call_ceill() sanitize_numerical_stability {
; CHECK-LABEL: @call_ceill(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @ceill(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.ceil.f80(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_ceill to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @ceill(x86_fp80 0xK3FFFC000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# trunc #
;###############################################################
declare float @truncf(float)
declare double @trunc(double)
declare x86_fp80 @truncl(x86_fp80)
define float @call_truncf() sanitize_numerical_stability {
; CHECK-LABEL: @call_truncf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @truncf(float 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.trunc.f64(double 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_truncf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @truncf(float 1.5)
ret float %r
}
define double @call_trunc() sanitize_numerical_stability {
; DQQ-LABEL: @call_trunc(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @trunc(double 1.500000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.trunc.f80(x86_fp80 1.500000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_trunc to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_trunc(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @trunc(double 1.500000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.trunc.f80(x86_fp80 1.500000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_trunc to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @trunc(double 1.5)
ret double %r
}
define x86_fp80 @call_truncl() sanitize_numerical_stability {
; CHECK-LABEL: @call_truncl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @truncl(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.trunc.f80(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_truncl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @truncl(x86_fp80 0xK3FFFC000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# rint #
;###############################################################
declare float @rintf(float)
declare double @rint(double)
declare x86_fp80 @rintl(x86_fp80)
define float @call_rintf() sanitize_numerical_stability {
; CHECK-LABEL: @call_rintf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @rintf(float 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.rint.f64(double 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_rintf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @rintf(float 1.5)
ret float %r
}
define double @call_rint() sanitize_numerical_stability {
; DQQ-LABEL: @call_rint(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @rint(double 1.500000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.rint.f80(x86_fp80 1.500000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_rint to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_rint(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @rint(double 1.500000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.rint.f80(x86_fp80 1.500000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_rint to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @rint(double 1.5)
ret double %r
}
define x86_fp80 @call_rintl() sanitize_numerical_stability {
; CHECK-LABEL: @call_rintl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @rintl(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.rint.f80(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_rintl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @rintl(x86_fp80 0xK3FFFC000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# nearbyint #
;###############################################################
declare float @nearbyintf(float)
declare double @nearbyint(double)
declare x86_fp80 @nearbyintl(x86_fp80)
define float @call_nearbyintf() sanitize_numerical_stability {
; CHECK-LABEL: @call_nearbyintf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @nearbyintf(float 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.nearbyint.f64(double 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_nearbyintf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @nearbyintf(float 1.5)
ret float %r
}
define double @call_nearbyint() sanitize_numerical_stability {
; DQQ-LABEL: @call_nearbyint(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @nearbyint(double 1.500000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.nearbyint.f80(x86_fp80 1.500000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_nearbyint to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_nearbyint(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @nearbyint(double 1.500000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.nearbyint.f80(x86_fp80 1.500000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_nearbyint to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @nearbyint(double 1.5)
ret double %r
}
define x86_fp80 @call_nearbyintl() sanitize_numerical_stability {
; CHECK-LABEL: @call_nearbyintl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @nearbyintl(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.nearbyint.f80(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_nearbyintl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @nearbyintl(x86_fp80 0xK3FFFC000000000000000)
ret x86_fp80 %r
}
;###############################################################
;# round #
;###############################################################
declare float @roundf(float)
declare double @round(double)
declare x86_fp80 @roundl(x86_fp80)
define float @call_roundf() sanitize_numerical_stability {
; CHECK-LABEL: @call_roundf(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call float @roundf(float 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.round.f64(double 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_roundf to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
; CHECK-NEXT: ret float [[R]]
;
entry:
%r = call float @roundf(float 1.5)
ret float %r
}
define double @call_round() sanitize_numerical_stability {
; DQQ-LABEL: @call_round(
; DQQ-NEXT: entry:
; DQQ-NEXT: [[R:%.*]] = call double @round(double 1.500000e+00)
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.round.f80(x86_fp80 1.500000e+00)
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to fp128
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; DQQ-NEXT: store i64 ptrtoint (ptr @call_round to i64), ptr @__nsan_shadow_ret_tag, align 8
; DQQ-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; DQQ-NEXT: ret double [[R]]
;
; DLQ-LABEL: @call_round(
; DLQ-NEXT: entry:
; DLQ-NEXT: [[R:%.*]] = call double @round(double 1.500000e+00)
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.round.f80(x86_fp80 1.500000e+00)
; DLQ-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)
; DLQ-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
; DLQ-NEXT: [[TMP3:%.*]] = fpext double [[R]] to x86_fp80
; DLQ-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]
; DLQ-NEXT: store i64 ptrtoint (ptr @call_round to i64), ptr @__nsan_shadow_ret_tag, align 8
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
; DLQ-NEXT: ret double [[R]]
;
entry:
%r = call double @round(double 1.5)
ret double %r
}
define x86_fp80 @call_roundl() sanitize_numerical_stability {
; CHECK-LABEL: @call_roundl(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @roundl(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.round.f80(x86_fp80 1.500000e+00)
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[R]], fp128 [[TMP1]], i32 1, i64 0)
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[R]] to fp128
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
; CHECK-NEXT: store i64 ptrtoint (ptr @call_roundl to i64), ptr @__nsan_shadow_ret_tag, align 8
; CHECK-NEXT: store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
; CHECK-NEXT: ret x86_fp80 [[R]]
;
entry:
%r = call x86_fp80 @roundl(x86_fp80 0xK3FFFC000000000000000)
ret x86_fp80 %r
}