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
1960 lines
102 KiB
LLVM
1960 lines
102 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 @llvm.sqrt.f32(float) readnone
|
|
declare double @llvm.sqrt.f64(double) readnone
|
|
declare x86_fp80 @llvm.sqrt.f80(x86_fp80) readnone
|
|
|
|
define float @call_sqrt_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_sqrt_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.sqrt.f32(float 4.000000e+00)
|
|
; 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_sqrt_f32 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 @llvm.sqrt.f32(float 4.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_sqrt_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_sqrt_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.sqrt.f64(double 4.000000e+00)
|
|
; 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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.sqrt.f64(double 4.000000e+00)
|
|
; 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_f64 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 @llvm.sqrt.f64(double 4.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_sqrt_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_sqrt_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.sqrt.f80(x86_fp80 4.000000e+00)
|
|
; 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_sqrt_f80 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 @llvm.sqrt.f80(x86_fp80 0xK40018000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# powi #
|
|
;###############################################################
|
|
declare float @llvm.powi.f32(float, i32) readnone
|
|
declare double @llvm.powi.f64(double, i32) readnone
|
|
declare x86_fp80 @llvm.powi.f80(x86_fp80, i32) readnone
|
|
|
|
define float @call_powi_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_powi_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.powi.f32.i32(float 2.000000e+00, i32 3)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call float @llvm.powi.f32.i32(float 2.000000e+00, i32 3)
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fpext float [[TMP0]] to double
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP1]], i32 1, i64 0)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[R]] to double
|
|
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], double [[TMP4]], double [[TMP1]]
|
|
; CHECK-NEXT: store i64 ptrtoint (ptr @call_powi_f32 to i64), ptr @__nsan_shadow_ret_tag, align 8
|
|
; CHECK-NEXT: store double [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 8
|
|
; CHECK-NEXT: ret float [[R]]
|
|
;
|
|
entry:
|
|
%r = call float @llvm.powi.f32(float 2.0, i32 3)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_powi_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_powi_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.powi.f64.i32(double 2.000000e+00, i32 3)
|
|
; DQQ-NEXT: [[TMP0:%.*]] = call double @llvm.powi.f64.i32(double 2.000000e+00, i32 3)
|
|
; DQQ-NEXT: [[TMP1:%.*]] = fpext double [[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_powi_f64 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_powi_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.powi.f64.i32(double 2.000000e+00, i32 3)
|
|
; DLQ-NEXT: [[TMP0:%.*]] = call double @llvm.powi.f64.i32(double 2.000000e+00, i32 3)
|
|
; DLQ-NEXT: [[TMP1:%.*]] = fpext double [[TMP0]] to x86_fp80
|
|
; DLQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP1]], i32 1, i64 0)
|
|
; DLQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; DLQ-NEXT: [[TMP4:%.*]] = fpext double [[R]] to x86_fp80
|
|
; DLQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], x86_fp80 [[TMP4]], x86_fp80 [[TMP1]]
|
|
; DLQ-NEXT: store i64 ptrtoint (ptr @call_powi_f64 to i64), ptr @__nsan_shadow_ret_tag, align 8
|
|
; DLQ-NEXT: store x86_fp80 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
|
|
; DLQ-NEXT: ret double [[R]]
|
|
;
|
|
entry:
|
|
%r = call double @llvm.powi.f64(double 2.0, i32 3)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_powi_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_powi_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.powi.f80.i32(x86_fp80 2.000000e+00, i32 3)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.powi.f80.i32(x86_fp80 2.000000e+00, i32 3)
|
|
; 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_powi_f80 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 @llvm.powi.f80(x86_fp80 0xK40008000000000000000, i32 3)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# sin #
|
|
;###############################################################
|
|
declare float @llvm.sin.f32(float) readnone
|
|
declare double @llvm.sin.f64(double) readnone
|
|
declare x86_fp80 @llvm.sin.f80(x86_fp80) readnone
|
|
|
|
define float @call_sin_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_sin_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.sin.f32(float 1.000000e+00)
|
|
; 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_sin_f32 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 @llvm.sin.f32(float 1.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_sin_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_sin_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.sin.f64(double 1.000000e+00)
|
|
; 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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.sin.f64(double 1.000000e+00)
|
|
; 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_f64 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 @llvm.sin.f64(double 1.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_sin_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_sin_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 1.000000e+00)
|
|
; 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_sin_f80 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 @llvm.sin.f80(x86_fp80 0xK3FFF8000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# cos #
|
|
;###############################################################
|
|
declare float @llvm.cos.f32(float) readnone
|
|
declare double @llvm.cos.f64(double) readnone
|
|
declare x86_fp80 @llvm.cos.f80(x86_fp80) readnone
|
|
|
|
define float @call_cos_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_cos_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.cos.f32(float 1.000000e+00)
|
|
; 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_cos_f32 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 @llvm.cos.f32(float 1.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_cos_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_cos_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.cos.f64(double 1.000000e+00)
|
|
; 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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.cos.f64(double 1.000000e+00)
|
|
; 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_f64 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 @llvm.cos.f64(double 1.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_cos_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_cos_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.cos.f80(x86_fp80 1.000000e+00)
|
|
; 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_cos_f80 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 @llvm.cos.f80(x86_fp80 0xK3FFF8000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# pow #
|
|
;###############################################################
|
|
declare float @llvm.pow.f32(float, float) readnone
|
|
declare double @llvm.pow.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_pow_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_pow_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.pow.f32(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_pow_f32 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 @llvm.pow.f32(float 2.0, float 3.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_pow_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_pow_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.pow.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.pow.f64(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_f64 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 @llvm.pow.f64(double 2.0, double 3.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_pow_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_pow_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.pow.f80(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_pow_f80 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 @llvm.pow.f80(x86_fp80 0xK40008000000000000000, x86_fp80 0xK40018000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# exp #
|
|
;###############################################################
|
|
declare float @llvm.exp.f32(float) readnone
|
|
declare double @llvm.exp.f64(double) readnone
|
|
declare x86_fp80 @llvm.exp.f80(x86_fp80) readnone
|
|
|
|
define float @call_exp_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_exp_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.exp.f32(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_exp_f32 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 @llvm.exp.f32(float 1.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_exp_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_exp_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.exp.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.exp.f64(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_f64 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 @llvm.exp.f64(double 1.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_exp_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_exp_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.exp.f80(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_exp_f80 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 @llvm.exp.f80(x86_fp80 0xK3FFF8000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# exp2 #
|
|
;###############################################################
|
|
declare float @llvm.exp2.f32(float) readnone
|
|
declare double @llvm.exp2.f64(double) readnone
|
|
declare x86_fp80 @llvm.exp2.f80(x86_fp80) readnone
|
|
|
|
define float @call_exp2_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_exp2_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.exp2.f32(float 1.000000e+00)
|
|
; 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_exp2_f32 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 @llvm.exp2.f32(float 1.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_exp2_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_exp2_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.exp2.f64(double 1.000000e+00)
|
|
; 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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.exp2.f64(double 1.000000e+00)
|
|
; 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_f64 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 @llvm.exp2.f64(double 1.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_exp2_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_exp2_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.exp2.f80(x86_fp80 1.000000e+00)
|
|
; 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_exp2_f80 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 @llvm.exp2.f80(x86_fp80 0xK3FFF8000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# log #
|
|
;###############################################################
|
|
declare float @llvm.log.f32(float) readnone
|
|
declare double @llvm.log.f64(double) readnone
|
|
declare x86_fp80 @llvm.log.f80(x86_fp80) readnone
|
|
|
|
define float @call_log_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_log_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.log.f32(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_log_f32 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 @llvm.log.f32(float 2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_log_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_log_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.log.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.log.f64(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_f64 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 @llvm.log.f64(double 2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_log_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_log_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.log.f80(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_log_f80 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 @llvm.log.f80(x86_fp80 0xK40008000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# log10 #
|
|
;###############################################################
|
|
declare float @llvm.log10.f32(float) readnone
|
|
declare double @llvm.log10.f64(double) readnone
|
|
declare x86_fp80 @llvm.log10.f80(x86_fp80) readnone
|
|
|
|
define float @call_log10_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_log10_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.log10.f32(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_log10_f32 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 @llvm.log10.f32(float 100.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_log10_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_log10_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.log10.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.log10.f64(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_f64 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 @llvm.log10.f64(double 100.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_log10_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_log10_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.log10.f80(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_log10_f80 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 @llvm.log10.f80(x86_fp80 0xK40590000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# log2 #
|
|
;###############################################################
|
|
declare float @llvm.log2.f32(float) readnone
|
|
declare double @llvm.log2.f64(double) readnone
|
|
declare x86_fp80 @llvm.log2.f80(x86_fp80) readnone
|
|
|
|
define float @call_log2_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_log2_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.log2.f32(float 8.000000e+00)
|
|
; 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_log2_f32 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 @llvm.log2.f32(float 8.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_log2_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_log2_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.log2.f64(double 8.000000e+00)
|
|
; 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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.log2.f64(double 8.000000e+00)
|
|
; 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_f64 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 @llvm.log2.f64(double 8.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_log2_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_log2_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.log2.f80(x86_fp80 4.000000e+00)
|
|
; 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_log2_f80 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 @llvm.log2.f80(x86_fp80 0xK40018000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# fma #
|
|
;###############################################################
|
|
declare float @llvm.fma.f32(float, float, float) readnone
|
|
declare double @llvm.fma.f64(double, double, double) readnone
|
|
declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_fma_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_fma_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.fma.f32(float 1.000000e+00, float 2.000000e+00, float 3.000000e+00)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.fma.f64(double 1.000000e+00, 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_fma_f32 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 @llvm.fma.f32(float 1.0, float 2.0, float 3.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_fma_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_fma_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.fma.f64(double 1.000000e+00, double 2.000000e+00, double 3.000000e+00)
|
|
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fma.f80(x86_fp80 1.000000e+00, 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_fma_f64 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_fma_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.fma.f64(double 1.000000e+00, double 2.000000e+00, double 3.000000e+00)
|
|
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fma.f80(x86_fp80 1.000000e+00, 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_fma_f64 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 @llvm.fma.f64(double 1.0, double 2.0, double 3.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_fma_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_fma_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.fma.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00, x86_fp80 4.000000e+00)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fma.f80(x86_fp80 1.000000e+00, 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_fma_f80 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 @llvm.fma.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000, x86_fp80 0xK40018000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# fmuladd #
|
|
;###############################################################
|
|
declare float @llvm.fmuladd.f32(float, float, float) readnone
|
|
declare double @llvm.fmuladd.f64(double, double, double) readnone
|
|
declare x86_fp80 @llvm.fmuladd.f80(x86_fp80, x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_fmuladd_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_fmuladd_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.fmuladd.f32(float 1.000000e+00, float 2.000000e+00, float 3.000000e+00)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.fmuladd.f64(double 1.000000e+00, 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_fmuladd_f32 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 @llvm.fmuladd.f32(float 1.0, float 2.0, float 3.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_fmuladd_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_fmuladd_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.fmuladd.f64(double 1.000000e+00, double 2.000000e+00, double 3.000000e+00)
|
|
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 1.000000e+00, 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_fmuladd_f64 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_fmuladd_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.fmuladd.f64(double 1.000000e+00, double 2.000000e+00, double 3.000000e+00)
|
|
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 1.000000e+00, 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_fmuladd_f64 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 @llvm.fmuladd.f64(double 1.0, double 2.0, double 3.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_fmuladd_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_fmuladd_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00, x86_fp80 4.000000e+00)
|
|
; CHECK-NEXT: [[TMP6:%.*]] = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00, x86_fp80 4.000000e+00)
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP6]] to fp128
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[TMP0]], fp128 [[TMP1]], i32 1, i64 0)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; CHECK-NEXT: [[TMP4:%.*]] = fpext x86_fp80 [[TMP0]] to fp128
|
|
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
|
|
; CHECK-NEXT: store i64 ptrtoint (ptr @call_fmuladd_f80 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 [[TMP0]]
|
|
;
|
|
entry:
|
|
%r = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000, x86_fp80 0xK40018000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# fabs #
|
|
;###############################################################
|
|
declare float @llvm.fabs.f32(float) readnone
|
|
declare double @llvm.fabs.f64(double) readnone
|
|
declare x86_fp80 @llvm.fabs.f80(x86_fp80) readnone
|
|
|
|
define float @call_fabs_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_fabs_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.fabs.f32(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_fabs_f32 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 @llvm.fabs.f32(float -1.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_fabs_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_fabs_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.fabs.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.fabs.f64(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_f64 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 @llvm.fabs.f64(double -1.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_fabs_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_fabs_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.fabs.f80(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_fabs_f80 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 @llvm.fabs.f80(x86_fp80 0xKBFFF8000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# minnum #
|
|
;###############################################################
|
|
declare float @llvm.minnum.f32(float, float) readnone
|
|
declare double @llvm.minnum.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.minnum.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_minnum_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_minnum_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.minnum.f32(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_minnum_f32 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 @llvm.minnum.f32(float 1.0, float 2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_minnum_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_minnum_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.minnum.f64(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_minnum_f64 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_minnum_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.minnum.f64(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_minnum_f64 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 @llvm.minnum.f64(double 1.0, double 2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_minnum_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_minnum_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.minnum.f80(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_minnum_f80 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 @llvm.minnum.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# maxnum #
|
|
;###############################################################
|
|
declare float @llvm.maxnum.f32(float, float) readnone
|
|
declare double @llvm.maxnum.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_maxnum_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_maxnum_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.maxnum.f32(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_maxnum_f32 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 @llvm.maxnum.f32(float 1.0, float 2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_maxnum_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_maxnum_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.maxnum.f64(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_maxnum_f64 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_maxnum_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.maxnum.f64(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_maxnum_f64 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 @llvm.maxnum.f64(double 1.0, double 2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_maxnum_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_maxnum_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.maxnum.f80(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_maxnum_f80 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 @llvm.maxnum.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# minimum #
|
|
;###############################################################
|
|
declare float @llvm.minimum.f32(float, float) readnone
|
|
declare double @llvm.minimum.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.minimum.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_minimum_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_minimum_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.minimum.f32(float 1.000000e+00, float 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.minimum.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_minimum_f32 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 @llvm.minimum.f32(float 1.0, float 2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_minimum_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_minimum_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.minimum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minimum.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_minimum_f64 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_minimum_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.minimum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minimum.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_minimum_f64 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 @llvm.minimum.f64(double 1.0, double 2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_minimum_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_minimum_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.minimum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.minimum.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_minimum_f80 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 @llvm.minimum.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# maximum #
|
|
;###############################################################
|
|
declare float @llvm.maximum.f32(float, float) readnone
|
|
declare double @llvm.maximum.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.maximum.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_maximum_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_maximum_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.maximum.f32(float 1.000000e+00, float 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.maximum.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_maximum_f32 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 @llvm.maximum.f32(float 1.0, float 2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_maximum_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_maximum_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.maximum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maximum.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_maximum_f64 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_maximum_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.maximum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maximum.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_maximum_f64 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 @llvm.maximum.f64(double 1.0, double 2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_maximum_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_maximum_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.maximum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.maximum.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_maximum_f80 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 @llvm.maximum.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# minimumnum #
|
|
;###############################################################
|
|
declare float @llvm.minimumnum.f32(float, float) readnone
|
|
declare double @llvm.minimumnum.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_minimumnum_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_minimumnum_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call float @llvm.minimumnum.f32(float 1.000000e+00, float 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.minimumnum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_float_d(float [[TMP0]], double [[TMP1]], i32 1, i64 0)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[TMP0]] to double
|
|
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], double [[TMP4]], double [[TMP1]]
|
|
; CHECK-NEXT: store i64 ptrtoint (ptr @call_minimumnum_f32 to i64), ptr @__nsan_shadow_ret_tag, align 8
|
|
; CHECK-NEXT: store double [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 8
|
|
; CHECK-NEXT: ret float [[TMP0]]
|
|
;
|
|
entry:
|
|
%r = call float @llvm.minimumnum.f32(float 1.0, float 2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_minimumnum_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_minimumnum_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[TMP0:%.*]] = call double @llvm.minimumnum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DQQ-NEXT: [[TMP6:%.*]] = call x86_fp80 @llvm.minimumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
|
|
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP6]] to fp128
|
|
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[TMP0]], fp128 [[TMP1]], i32 1, i64 0)
|
|
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[TMP0]] to fp128
|
|
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
|
|
; DQQ-NEXT: store i64 ptrtoint (ptr @call_minimumnum_f64 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 [[TMP0]]
|
|
;
|
|
; DLQ-LABEL: @call_minimumnum_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[TMP0:%.*]] = call double @llvm.minimumnum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DLQ-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.minimumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
|
|
; DLQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_l(double [[TMP0]], x86_fp80 [[TMP1]], i32 1, i64 0)
|
|
; DLQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; DLQ-NEXT: [[TMP4:%.*]] = fpext double [[TMP0]] to x86_fp80
|
|
; DLQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], x86_fp80 [[TMP4]], x86_fp80 [[TMP1]]
|
|
; DLQ-NEXT: store i64 ptrtoint (ptr @call_minimumnum_f64 to i64), ptr @__nsan_shadow_ret_tag, align 8
|
|
; DLQ-NEXT: store x86_fp80 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
|
|
; DLQ-NEXT: ret double [[TMP0]]
|
|
;
|
|
entry:
|
|
%r = call double @llvm.minimumnum.f64(double 1.0, double 2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_minimumnum_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_minimumnum_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.minimumnum.f80(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_minimumnum_f80 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 @llvm.minimumnum.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# maximumnum #
|
|
;###############################################################
|
|
declare float @llvm.maximumnum.f32(float, float) readnone
|
|
declare double @llvm.maximumnum.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_maximumnum_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_maximumnum_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call float @llvm.maximumnum.f32(float 1.000000e+00, float 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.maximumnum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_float_d(float [[TMP0]], double [[TMP1]], i32 1, i64 0)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[TMP0]] to double
|
|
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], double [[TMP4]], double [[TMP1]]
|
|
; CHECK-NEXT: store i64 ptrtoint (ptr @call_maximumnum_f32 to i64), ptr @__nsan_shadow_ret_tag, align 8
|
|
; CHECK-NEXT: store double [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 8
|
|
; CHECK-NEXT: ret float [[TMP0]]
|
|
;
|
|
entry:
|
|
%r = call float @llvm.maximumnum.f32(float 1.0, float 2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_maximumnum_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_maximumnum_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[TMP0:%.*]] = call double @llvm.maximumnum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DQQ-NEXT: [[TMP6:%.*]] = call x86_fp80 @llvm.maximumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
|
|
; DQQ-NEXT: [[TMP1:%.*]] = fpext x86_fp80 [[TMP6]] to fp128
|
|
; DQQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[TMP0]], fp128 [[TMP1]], i32 1, i64 0)
|
|
; DQQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; DQQ-NEXT: [[TMP4:%.*]] = fpext double [[TMP0]] to fp128
|
|
; DQQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]
|
|
; DQQ-NEXT: store i64 ptrtoint (ptr @call_maximumnum_f64 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 [[TMP0]]
|
|
;
|
|
; DLQ-LABEL: @call_maximumnum_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[TMP0:%.*]] = call double @llvm.maximumnum.f64(double 1.000000e+00, double 2.000000e+00)
|
|
; DLQ-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.maximumnum.f80(x86_fp80 1.000000e+00, x86_fp80 2.000000e+00)
|
|
; DLQ-NEXT: [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_l(double [[TMP0]], x86_fp80 [[TMP1]], i32 1, i64 0)
|
|
; DLQ-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1
|
|
; DLQ-NEXT: [[TMP4:%.*]] = fpext double [[TMP0]] to x86_fp80
|
|
; DLQ-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], x86_fp80 [[TMP4]], x86_fp80 [[TMP1]]
|
|
; DLQ-NEXT: store i64 ptrtoint (ptr @call_maximumnum_f64 to i64), ptr @__nsan_shadow_ret_tag, align 8
|
|
; DLQ-NEXT: store x86_fp80 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16
|
|
; DLQ-NEXT: ret double [[TMP0]]
|
|
;
|
|
entry:
|
|
%r = call double @llvm.maximumnum.f64(double 1.0, double 2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_maximumnum_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_maximumnum_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.maximumnum.f80(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_maximumnum_f80 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 @llvm.maximumnum.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# copysign #
|
|
;###############################################################
|
|
declare float @llvm.copysign.f32(float, float) readnone
|
|
declare double @llvm.copysign.f64(double, double) readnone
|
|
declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) readnone
|
|
|
|
define float @call_copysign_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_copysign_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float -2.000000e+00)
|
|
; 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_copysign_f32 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 @llvm.copysign.f32(float 1.0, float -2.0)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_copysign_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_copysign_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double -2.000000e+00)
|
|
; 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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double -2.000000e+00)
|
|
; 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_f64 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 @llvm.copysign.f64(double 1.0, double -2.0)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_copysign_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_copysign_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.copysign.f80(x86_fp80 1.000000e+00, x86_fp80 -1.000000e+00)
|
|
; 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_copysign_f80 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 @llvm.copysign.f80(x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xKBFFF8000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# floor #
|
|
;###############################################################
|
|
declare float @llvm.floor.f32(float) readnone
|
|
declare double @llvm.floor.f64(double) readnone
|
|
declare x86_fp80 @llvm.floor.f80(x86_fp80) readnone
|
|
|
|
define float @call_floor_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_floor_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.floor.f32(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_floor_f32 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 @llvm.floor.f32(float 1.5)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_floor_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_floor_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.floor.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.floor.f64(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_f64 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 @llvm.floor.f64(double 1.5)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_floor_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_floor_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.floor.f80(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_floor_f80 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 @llvm.floor.f80(x86_fp80 0xK3FFFC000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# ceil #
|
|
;###############################################################
|
|
declare float @llvm.ceil.f32(float) readnone
|
|
declare double @llvm.ceil.f64(double) readnone
|
|
declare x86_fp80 @llvm.ceil.f80(x86_fp80) readnone
|
|
|
|
define float @call_ceil_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_ceil_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.ceil.f32(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_ceil_f32 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 @llvm.ceil.f32(float 1.5)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_ceil_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_ceil_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.ceil.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.ceil.f64(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_f64 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 @llvm.ceil.f64(double 1.5)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_ceil_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_ceil_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.ceil.f80(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_ceil_f80 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 @llvm.ceil.f80(x86_fp80 0xK3FFFC000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# trunc #
|
|
;###############################################################
|
|
declare float @llvm.trunc.f32(float) readnone
|
|
declare double @llvm.trunc.f64(double) readnone
|
|
declare x86_fp80 @llvm.trunc.f80(x86_fp80) readnone
|
|
|
|
define float @call_trunc_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_trunc_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.trunc.f32(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_trunc_f32 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 @llvm.trunc.f32(float 1.5)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_trunc_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_trunc_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.trunc.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.trunc.f64(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_f64 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 @llvm.trunc.f64(double 1.5)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_trunc_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_trunc_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.trunc.f80(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_trunc_f80 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 @llvm.trunc.f80(x86_fp80 0xK3FFFC000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# rint #
|
|
;###############################################################
|
|
declare float @llvm.rint.f32(float) readnone
|
|
declare double @llvm.rint.f64(double) readnone
|
|
declare x86_fp80 @llvm.rint.f80(x86_fp80) readnone
|
|
|
|
define float @call_rint_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_rint_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.rint.f32(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_rint_f32 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 @llvm.rint.f32(float 1.5)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_rint_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_rint_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.rint.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.rint.f64(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_f64 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 @llvm.rint.f64(double 1.5)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_rint_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_rint_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.rint.f80(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_rint_f80 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 @llvm.rint.f80(x86_fp80 0xK3FFFC000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# nearbyint #
|
|
;###############################################################
|
|
declare float @llvm.nearbyint.f32(float) readnone
|
|
declare double @llvm.nearbyint.f64(double) readnone
|
|
declare x86_fp80 @llvm.nearbyint.f80(x86_fp80) readnone
|
|
|
|
define float @call_nearbyint_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_nearbyint_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.nearbyint.f32(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_nearbyint_f32 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 @llvm.nearbyint.f32(float 1.5)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_nearbyint_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_nearbyint_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.nearbyint.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.nearbyint.f64(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_f64 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 @llvm.nearbyint.f64(double 1.5)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_nearbyint_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_nearbyint_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.nearbyint.f80(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_nearbyint_f80 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 @llvm.nearbyint.f80(x86_fp80 0xK3FFFC000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|
|
|
|
;###############################################################
|
|
;# round #
|
|
;###############################################################
|
|
declare float @llvm.round.f32(float) readnone
|
|
declare double @llvm.round.f64(double) readnone
|
|
declare x86_fp80 @llvm.round.f80(x86_fp80) readnone
|
|
|
|
define float @call_round_f32() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_round_f32(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call float @llvm.round.f32(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_round_f32 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 @llvm.round.f32(float 1.5)
|
|
ret float %r
|
|
}
|
|
|
|
define double @call_round_f64() sanitize_numerical_stability {
|
|
; DQQ-LABEL: @call_round_f64(
|
|
; DQQ-NEXT: entry:
|
|
; DQQ-NEXT: [[R:%.*]] = call double @llvm.round.f64(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_f64 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_f64(
|
|
; DLQ-NEXT: entry:
|
|
; DLQ-NEXT: [[R:%.*]] = call double @llvm.round.f64(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_f64 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 @llvm.round.f64(double 1.5)
|
|
ret double %r
|
|
}
|
|
|
|
define x86_fp80 @call_round_f80() sanitize_numerical_stability {
|
|
; CHECK-LABEL: @call_round_f80(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[R:%.*]] = call x86_fp80 @llvm.round.f80(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_round_f80 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 @llvm.round.f80(x86_fp80 0xK3FFFC000000000000000)
|
|
ret x86_fp80 %r
|
|
}
|