; 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 }