brintos

brintos / llvm-project-archived public Read only

0
0
Text · 48.8 KiB · 3d759f7 Raw
918 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=nsan -nsan-shadow-type-mapping=dqq -nsan-truncate-fcmp-eq=false -S %s | FileCheck %s --check-prefixes=CHECK,DQQ3; RUN: opt -passes=nsan -nsan-shadow-type-mapping=dlq -nsan-truncate-fcmp-eq=false -S %s | FileCheck %s --check-prefixes=CHECK,DLQ4 5; RUN: opt -passes=nsan -nsan-shadow-type-mapping=dqq -nsan-truncate-fcmp-eq=false -use-constant-fp-for-fixed-length-splat -S %s | FileCheck %s --check-prefixes=CHECK,DQQ6; RUN: opt -passes=nsan -nsan-shadow-type-mapping=dlq -nsan-truncate-fcmp-eq=false -use-constant-fp-for-fixed-length-splat -S %s | FileCheck %s --check-prefixes=CHECK,DLQ7 8target 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"9 10declare float @declaration_only(float %a) sanitize_numerical_stability11 12; Tests with simple control flow.13 14@float_const = private unnamed_addr constant float 0.515@x86_fp80_const = private unnamed_addr constant x86_fp80 0xK3FC9E69594BEC44DE00016@double_const = private unnamed_addr constant double 0.517 18 19define float @return_param_float(float %a) sanitize_numerical_stability {20; CHECK-LABEL: @return_param_float(21; CHECK-NEXT:  entry:22; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 823; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @return_param_float to i64)24; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr @__nsan_shadow_args_ptr, align 125; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[A:%.*]] to double26; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], double [[TMP2]], double [[TMP3]]27; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 828; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @__nsan_internal_check_float_d(float [[A]], double [[TMP4]], i32 1, i64 0)29; CHECK-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 130; CHECK-NEXT:    [[TMP7:%.*]] = fpext float [[A]] to double31; CHECK-NEXT:    [[TMP8:%.*]] = select i1 [[TMP6]], double [[TMP7]], double [[TMP4]]32; CHECK-NEXT:    store i64 ptrtoint (ptr @return_param_float to i64), ptr @__nsan_shadow_ret_tag, align 833; CHECK-NEXT:    store double [[TMP8]], ptr @__nsan_shadow_ret_ptr, align 834; CHECK-NEXT:    ret float [[A]]35;36entry:37  ret float %a38}39 40; Note that the shadow fadd should not have a `fast` flag.41define float @param_add_return_float(float %a) sanitize_numerical_stability {42; CHECK-LABEL: @param_add_return_float(43; CHECK-NEXT:  entry:44; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 845; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @param_add_return_float to i64)46; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr @__nsan_shadow_args_ptr, align 147; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[A:%.*]] to double48; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], double [[TMP2]], double [[TMP3]]49; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 850; CHECK-NEXT:    [[B:%.*]] = fadd fast float [[A]], 1.000000e+0051; CHECK-NEXT:    [[TMP5:%.*]] = fadd double [[TMP4]], 1.000000e+0052; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @__nsan_internal_check_float_d(float [[B]], double [[TMP5]], i32 1, i64 0)53; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 154; CHECK-NEXT:    [[TMP8:%.*]] = fpext float [[B]] to double55; CHECK-NEXT:    [[TMP9:%.*]] = select i1 [[TMP7]], double [[TMP8]], double [[TMP5]]56; CHECK-NEXT:    store i64 ptrtoint (ptr @param_add_return_float to i64), ptr @__nsan_shadow_ret_tag, align 857; CHECK-NEXT:    store double [[TMP9]], ptr @__nsan_shadow_ret_ptr, align 858; CHECK-NEXT:    ret float [[B]]59;60entry:61  %b = fadd fast float %a, 1.062  ret float %b63}64 65define x86_fp80 @param_add_return_x86_fp80(x86_fp80 %a) sanitize_numerical_stability {66; CHECK-LABEL: @param_add_return_x86_fp80(67; CHECK-NEXT:  entry:68; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 869; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @param_add_return_x86_fp80 to i64)70; CHECK-NEXT:    [[TMP2:%.*]] = load fp128, ptr @__nsan_shadow_args_ptr, align 171; CHECK-NEXT:    [[TMP3:%.*]] = fpext x86_fp80 [[A:%.*]] to fp12872; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], fp128 [[TMP2]], fp128 [[TMP3]]73; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 874; CHECK-NEXT:    [[B:%.*]] = fadd x86_fp80 [[A]], 0xK3FC9E69594BEC44DE00075; CHECK-NEXT:    [[TMP5:%.*]] = fadd fp128 [[TMP4]], 0xLC0000000000000003FC9CD2B297D889B76; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[B]], fp128 [[TMP5]], i32 1, i64 0)77; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 178; CHECK-NEXT:    [[TMP8:%.*]] = fpext x86_fp80 [[B]] to fp12879; CHECK-NEXT:    [[TMP9:%.*]] = select i1 [[TMP7]], fp128 [[TMP8]], fp128 [[TMP5]]80; CHECK-NEXT:    store i64 ptrtoint (ptr @param_add_return_x86_fp80 to i64), ptr @__nsan_shadow_ret_tag, align 881; CHECK-NEXT:    store fp128 [[TMP9]], ptr @__nsan_shadow_ret_ptr, align 1682; CHECK-NEXT:    ret x86_fp80 [[B]]83;84entry:85  %b = fadd x86_fp80 %a, 0xK3FC9E69594BEC44DE00086  ret x86_fp80 %b87}88 89define double @param_add_return_double(double %a) sanitize_numerical_stability {90; DQQ-LABEL: @param_add_return_double(91; DQQ-NEXT:  entry:92; DQQ-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 893; DQQ-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @param_add_return_double to i64)94; DQQ-NEXT:    [[TMP2:%.*]] = load fp128, ptr @__nsan_shadow_args_ptr, align 195; DQQ-NEXT:    [[TMP3:%.*]] = fpext double [[A:%.*]] to fp12896; DQQ-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], fp128 [[TMP2]], fp128 [[TMP3]]97; DQQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 898; DQQ-NEXT:    [[B:%.*]] = fadd double [[A]], 1.000000e+0099; DQQ-NEXT:    [[TMP5:%.*]] = fadd fp128 [[TMP4]], 0xL00000000000000003FFF000000000000100; DQQ-NEXT:    [[TMP6:%.*]] = call i32 @__nsan_internal_check_double_q(double [[B]], fp128 [[TMP5]], i32 1, i64 0)101; DQQ-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 1102; DQQ-NEXT:    [[TMP8:%.*]] = fpext double [[B]] to fp128103; DQQ-NEXT:    [[TMP9:%.*]] = select i1 [[TMP7]], fp128 [[TMP8]], fp128 [[TMP5]]104; DQQ-NEXT:    store i64 ptrtoint (ptr @param_add_return_double to i64), ptr @__nsan_shadow_ret_tag, align 8105; DQQ-NEXT:    store fp128 [[TMP9]], ptr @__nsan_shadow_ret_ptr, align 16106; DQQ-NEXT:    ret double [[B]]107;108; DLQ-LABEL: @param_add_return_double(109; DLQ-NEXT:  entry:110; DLQ-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8111; DLQ-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @param_add_return_double to i64)112; DLQ-NEXT:    [[TMP2:%.*]] = load x86_fp80, ptr @__nsan_shadow_args_ptr, align 1113; DLQ-NEXT:    [[TMP3:%.*]] = fpext double [[A:%.*]] to x86_fp80114; DLQ-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], x86_fp80 [[TMP2]], x86_fp80 [[TMP3]]115; DLQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8116; DLQ-NEXT:    [[B:%.*]] = fadd double [[A]], 1.000000e+00117; DLQ-NEXT:    [[TMP5:%.*]] = fadd x86_fp80 [[TMP4]], 0xK3FFF8000000000000000118; DLQ-NEXT:    [[TMP6:%.*]] = call i32 @__nsan_internal_check_double_l(double [[B]], x86_fp80 [[TMP5]], i32 1, i64 0)119; DLQ-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 1120; DLQ-NEXT:    [[TMP8:%.*]] = fpext double [[B]] to x86_fp80121; DLQ-NEXT:    [[TMP9:%.*]] = select i1 [[TMP7]], x86_fp80 [[TMP8]], x86_fp80 [[TMP5]]122; DLQ-NEXT:    store i64 ptrtoint (ptr @param_add_return_double to i64), ptr @__nsan_shadow_ret_tag, align 8123; DLQ-NEXT:    store x86_fp80 [[TMP9]], ptr @__nsan_shadow_ret_ptr, align 16124; DLQ-NEXT:    ret double [[B]]125;126entry:127  %b = fadd double %a, 1.0128  ret double %b129}130 131define <2 x float> @return_param_add_return_float_vector(<2 x float> %a) sanitize_numerical_stability {132; CHECK-LABEL: @return_param_add_return_float_vector(133; CHECK-NEXT:  entry:134; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8135; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @return_param_add_return_float_vector to i64)136; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr @__nsan_shadow_args_ptr, align 1137; CHECK-NEXT:    [[TMP3:%.*]] = fpext <2 x float> [[A:%.*]] to <2 x double>138; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], <2 x double> [[TMP2]], <2 x double> [[TMP3]]139; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8140; CHECK-NEXT:    [[B:%.*]] = fadd <2 x float> [[A]], splat (float 1.000000e+00)141; CHECK-NEXT:    [[TMP5:%.*]] = fadd <2 x double> [[TMP4]], splat (double 1.000000e+00)142; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x float> [[B]], i64 0143; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <2 x double> [[TMP5]], i64 0144; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @__nsan_internal_check_float_d(float [[TMP6]], double [[TMP7]], i32 1, i64 0)145; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x float> [[B]], i64 1146; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <2 x double> [[TMP5]], i64 1147; CHECK-NEXT:    [[TMP11:%.*]] = call i32 @__nsan_internal_check_float_d(float [[TMP9]], double [[TMP10]], i32 1, i64 0)148; CHECK-NEXT:    [[TMP12:%.*]] = or i32 [[TMP8]], [[TMP11]]149; CHECK-NEXT:    [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 1150; CHECK-NEXT:    [[TMP14:%.*]] = fpext <2 x float> [[B]] to <2 x double>151; CHECK-NEXT:    [[TMP15:%.*]] = select i1 [[TMP13]], <2 x double> [[TMP14]], <2 x double> [[TMP5]]152; CHECK-NEXT:    store i64 ptrtoint (ptr @return_param_add_return_float_vector to i64), ptr @__nsan_shadow_ret_tag, align 8153; CHECK-NEXT:    store <2 x double> [[TMP15]], ptr @__nsan_shadow_ret_ptr, align 16154; CHECK-NEXT:    ret <2 x float> [[B]]155;156entry:157  %b = fadd <2 x float> %a, <float 1.0, float 1.0>158  ret <2 x float> %b159}160 161; TODO: This is ignored for now.162define [2 x float] @return_param_float_array([2 x float] %a) sanitize_numerical_stability {163; CHECK-LABEL: @return_param_float_array(164; CHECK-NEXT:  entry:165; CHECK-NEXT:    ret [2 x float] [[A:%.*]]166;167entry:168  ret [2 x float] %a169}170 171define void @constantload_add_store_float(ptr %dst) sanitize_numerical_stability {172; CHECK-LABEL: @constantload_add_store_float(173; CHECK-NEXT:  entry:174; CHECK-NEXT:    [[B:%.*]] = load float, ptr @float_const, align 4175; CHECK-NEXT:    [[TMP0:%.*]] = fpext float [[B]] to double176; CHECK-NEXT:    [[C:%.*]] = fadd float [[B]], 1.000000e+00177; CHECK-NEXT:    [[TMP1:%.*]] = fadd double [[TMP0]], 1.000000e+00178; CHECK-NEXT:    [[TMP2:%.*]] = call ptr @__nsan_get_shadow_ptr_for_float_store(ptr [[DST:%.*]], i64 1)179; CHECK-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[DST]] to i64180; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @__nsan_internal_check_float_d(float [[C]], double [[TMP1]], i32 4, i64 [[TMP3]])181; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 1182; CHECK-NEXT:    [[TMP6:%.*]] = fpext float [[C]] to double183; CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP5]], double [[TMP6]], double [[TMP1]]184; CHECK-NEXT:    store double [[TMP7]], ptr [[TMP2]], align 1185; CHECK-NEXT:    store float [[C]], ptr [[DST]], align 1186; CHECK-NEXT:    ret void187;188entry:189  %b = load float, ptr @float_const190  %c = fadd float %b, 1.0191  store float %c, ptr %dst, align 1192  ret void193}194 195define void @constantload_add_store_x86_fp80(ptr %dst) sanitize_numerical_stability {196; CHECK-LABEL: @constantload_add_store_x86_fp80(197; CHECK-NEXT:  entry:198; CHECK-NEXT:    [[B:%.*]] = load x86_fp80, ptr @x86_fp80_const, align 16199; CHECK-NEXT:    [[TMP0:%.*]] = fpext x86_fp80 [[B]] to fp128200; CHECK-NEXT:    [[C:%.*]] = fadd x86_fp80 [[B]], 0xK3FC9E69594BEC44DE000201; CHECK-NEXT:    [[TMP1:%.*]] = fadd fp128 [[TMP0]], 0xLC0000000000000003FC9CD2B297D889B202; CHECK-NEXT:    [[TMP2:%.*]] = call ptr @__nsan_get_shadow_ptr_for_longdouble_store(ptr [[DST:%.*]], i64 1)203; CHECK-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[DST]] to i64204; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[C]], fp128 [[TMP1]], i32 4, i64 [[TMP3]])205; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 1206; CHECK-NEXT:    [[TMP6:%.*]] = fpext x86_fp80 [[C]] to fp128207; CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP5]], fp128 [[TMP6]], fp128 [[TMP1]]208; CHECK-NEXT:    store fp128 [[TMP7]], ptr [[TMP2]], align 1209; CHECK-NEXT:    store x86_fp80 [[C]], ptr [[DST]], align 1210; CHECK-NEXT:    ret void211;212entry:213  %b = load x86_fp80, ptr @x86_fp80_const214  %c = fadd x86_fp80 %b, 0xK3FC9E69594BEC44DE000215  store x86_fp80 %c, ptr %dst, align 1216  ret void217}218 219define void @constantload_add_store_double(ptr %dst) sanitize_numerical_stability {220; DQQ-LABEL: @constantload_add_store_double(221; DQQ-NEXT:  entry:222; DQQ-NEXT:    [[B:%.*]] = load double, ptr @double_const, align 8223; DQQ-NEXT:    [[TMP0:%.*]] = fpext double [[B]] to fp128224; DQQ-NEXT:    [[C:%.*]] = fadd double [[B]], 1.000000e+00225; DQQ-NEXT:    [[TMP1:%.*]] = fadd fp128 [[TMP0]], 0xL00000000000000003FFF000000000000226; DQQ-NEXT:    [[TMP2:%.*]] = call ptr @__nsan_get_shadow_ptr_for_double_store(ptr [[DST:%.*]], i64 1)227; DQQ-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[DST]] to i64228; DQQ-NEXT:    [[TMP4:%.*]] = call i32 @__nsan_internal_check_double_q(double [[C]], fp128 [[TMP1]], i32 4, i64 [[TMP3]])229; DQQ-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 1230; DQQ-NEXT:    [[TMP6:%.*]] = fpext double [[C]] to fp128231; DQQ-NEXT:    [[TMP7:%.*]] = select i1 [[TMP5]], fp128 [[TMP6]], fp128 [[TMP1]]232; DQQ-NEXT:    store fp128 [[TMP7]], ptr [[TMP2]], align 1233; DQQ-NEXT:    store double [[C]], ptr [[DST]], align 1234; DQQ-NEXT:    ret void235;236; DLQ-LABEL: @constantload_add_store_double(237; DLQ-NEXT:  entry:238; DLQ-NEXT:    [[B:%.*]] = load double, ptr @double_const, align 8239; DLQ-NEXT:    [[TMP0:%.*]] = fpext double [[B]] to x86_fp80240; DLQ-NEXT:    [[C:%.*]] = fadd double [[B]], 1.000000e+00241; DLQ-NEXT:    [[TMP1:%.*]] = fadd x86_fp80 [[TMP0]], 0xK3FFF8000000000000000242; DLQ-NEXT:    [[TMP2:%.*]] = call ptr @__nsan_get_shadow_ptr_for_double_store(ptr [[DST:%.*]], i64 1)243; DLQ-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[DST]] to i64244; DLQ-NEXT:    [[TMP4:%.*]] = call i32 @__nsan_internal_check_double_l(double [[C]], x86_fp80 [[TMP1]], i32 4, i64 [[TMP3]])245; DLQ-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 1246; DLQ-NEXT:    [[TMP6:%.*]] = fpext double [[C]] to x86_fp80247; DLQ-NEXT:    [[TMP7:%.*]] = select i1 [[TMP5]], x86_fp80 [[TMP6]], x86_fp80 [[TMP1]]248; DLQ-NEXT:    store x86_fp80 [[TMP7]], ptr [[TMP2]], align 1249; DLQ-NEXT:    store double [[C]], ptr [[DST]], align 1250; DLQ-NEXT:    ret void251;252entry:253  %b = load double, ptr @double_const254  %c = fadd double %b, 1.0255  store double %c, ptr %dst, align 1256  ret void257}258 259define void @load_add_store_float(ptr %a) sanitize_numerical_stability {260; CHECK-LABEL: @load_add_store_float(261; CHECK-NEXT:  entry:262; CHECK-NEXT:    [[B:%.*]] = load float, ptr [[A:%.*]], align 1263; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @__nsan_get_shadow_ptr_for_float_load(ptr [[A]], i64 1)264; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null265; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]266; CHECK:       2:267; CHECK-NEXT:    [[TMP3:%.*]] = load double, ptr [[TMP0]], align 1268; CHECK-NEXT:    br label [[TMP6:%.*]]269; CHECK:       4:270; CHECK-NEXT:    [[TMP5:%.*]] = fpext float [[B]] to double271; CHECK-NEXT:    br label [[TMP6]]272; CHECK:       6:273; CHECK-NEXT:    [[TMP7:%.*]] = phi double [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ]274; CHECK-NEXT:    [[C:%.*]] = fadd float [[B]], 1.000000e+00275; CHECK-NEXT:    [[TMP8:%.*]] = fadd double [[TMP7]], 1.000000e+00276; CHECK-NEXT:    [[TMP9:%.*]] = call ptr @__nsan_get_shadow_ptr_for_float_store(ptr [[A]], i64 1)277; CHECK-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[A]] to i64278; CHECK-NEXT:    [[TMP11:%.*]] = call i32 @__nsan_internal_check_float_d(float [[C]], double [[TMP8]], i32 4, i64 [[TMP10]])279; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[TMP11]], 1280; CHECK-NEXT:    [[TMP13:%.*]] = fpext float [[C]] to double281; CHECK-NEXT:    [[TMP14:%.*]] = select i1 [[TMP12]], double [[TMP13]], double [[TMP8]]282; CHECK-NEXT:    store double [[TMP14]], ptr [[TMP9]], align 1283; CHECK-NEXT:    store float [[C]], ptr [[A]], align 1284; CHECK-NEXT:    ret void285;286entry:287  %b = load float, ptr %a, align 1288  %c = fadd float %b, 1.0289  store float %c, ptr %a, align 1290  ret void291}292 293define void @load_add_store_x86_fp80(ptr %a) sanitize_numerical_stability {294; CHECK-LABEL: @load_add_store_x86_fp80(295; CHECK-NEXT:  entry:296; CHECK-NEXT:    [[B:%.*]] = load x86_fp80, ptr [[A:%.*]], align 1297; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @__nsan_get_shadow_ptr_for_longdouble_load(ptr [[A]], i64 1)298; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null299; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]300; CHECK:       2:301; CHECK-NEXT:    [[TMP3:%.*]] = load fp128, ptr [[TMP0]], align 1302; CHECK-NEXT:    br label [[TMP6:%.*]]303; CHECK:       4:304; CHECK-NEXT:    [[TMP5:%.*]] = fpext x86_fp80 [[B]] to fp128305; CHECK-NEXT:    br label [[TMP6]]306; CHECK:       6:307; CHECK-NEXT:    [[TMP7:%.*]] = phi fp128 [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ]308; CHECK-NEXT:    [[C:%.*]] = fadd x86_fp80 [[B]], 0xK3FC9E69594BEC44DE000309; CHECK-NEXT:    [[TMP8:%.*]] = fadd fp128 [[TMP7]], 0xLC0000000000000003FC9CD2B297D889B310; CHECK-NEXT:    [[TMP9:%.*]] = call ptr @__nsan_get_shadow_ptr_for_longdouble_store(ptr [[A]], i64 1)311; CHECK-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[A]] to i64312; CHECK-NEXT:    [[TMP11:%.*]] = call i32 @__nsan_internal_check_longdouble_q(x86_fp80 [[C]], fp128 [[TMP8]], i32 4, i64 [[TMP10]])313; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[TMP11]], 1314; CHECK-NEXT:    [[TMP13:%.*]] = fpext x86_fp80 [[C]] to fp128315; CHECK-NEXT:    [[TMP14:%.*]] = select i1 [[TMP12]], fp128 [[TMP13]], fp128 [[TMP8]]316; CHECK-NEXT:    store fp128 [[TMP14]], ptr [[TMP9]], align 1317; CHECK-NEXT:    store x86_fp80 [[C]], ptr [[A]], align 1318; CHECK-NEXT:    ret void319;320entry:321  %b = load x86_fp80, ptr %a, align 1322  %c = fadd x86_fp80 %b, 0xK3FC9E69594BEC44DE000323  store x86_fp80 %c, ptr %a, align 1324  ret void325}326 327define void @load_add_store_double(ptr %a) sanitize_numerical_stability {328; DQQ-LABEL: @load_add_store_double(329; DQQ-NEXT:  entry:330; DQQ-NEXT:    [[B:%.*]] = load double, ptr [[A:%.*]], align 1331; DQQ-NEXT:    [[TMP0:%.*]] = call ptr @__nsan_get_shadow_ptr_for_double_load(ptr [[A]], i64 1)332; DQQ-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null333; DQQ-NEXT:    br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]334; DQQ:       2:335; DQQ-NEXT:    [[TMP3:%.*]] = load fp128, ptr [[TMP0]], align 1336; DQQ-NEXT:    br label [[TMP6:%.*]]337; DQQ:       4:338; DQQ-NEXT:    [[TMP5:%.*]] = fpext double [[B]] to fp128339; DQQ-NEXT:    br label [[TMP6]]340; DQQ:       6:341; DQQ-NEXT:    [[TMP7:%.*]] = phi fp128 [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ]342; DQQ-NEXT:    [[C:%.*]] = fadd double [[B]], 1.000000e+00343; DQQ-NEXT:    [[TMP8:%.*]] = fadd fp128 [[TMP7]], 0xL00000000000000003FFF000000000000344; DQQ-NEXT:    [[TMP9:%.*]] = call ptr @__nsan_get_shadow_ptr_for_double_store(ptr [[A]], i64 1)345; DQQ-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[A]] to i64346; DQQ-NEXT:    [[TMP11:%.*]] = call i32 @__nsan_internal_check_double_q(double [[C]], fp128 [[TMP8]], i32 4, i64 [[TMP10]])347; DQQ-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[TMP11]], 1348; DQQ-NEXT:    [[TMP13:%.*]] = fpext double [[C]] to fp128349; DQQ-NEXT:    [[TMP14:%.*]] = select i1 [[TMP12]], fp128 [[TMP13]], fp128 [[TMP8]]350; DQQ-NEXT:    store fp128 [[TMP14]], ptr [[TMP9]], align 1351; DQQ-NEXT:    store double [[C]], ptr [[A]], align 1352; DQQ-NEXT:    ret void353;354; DLQ-LABEL: @load_add_store_double(355; DLQ-NEXT:  entry:356; DLQ-NEXT:    [[B:%.*]] = load double, ptr [[A:%.*]], align 1357; DLQ-NEXT:    [[TMP0:%.*]] = call ptr @__nsan_get_shadow_ptr_for_double_load(ptr [[A]], i64 1)358; DLQ-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null359; DLQ-NEXT:    br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]360; DLQ:       2:361; DLQ-NEXT:    [[TMP3:%.*]] = load x86_fp80, ptr [[TMP0]], align 1362; DLQ-NEXT:    br label [[TMP6:%.*]]363; DLQ:       4:364; DLQ-NEXT:    [[TMP5:%.*]] = fpext double [[B]] to x86_fp80365; DLQ-NEXT:    br label [[TMP6]]366; DLQ:       6:367; DLQ-NEXT:    [[TMP7:%.*]] = phi x86_fp80 [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ]368; DLQ-NEXT:    [[C:%.*]] = fadd double [[B]], 1.000000e+00369; DLQ-NEXT:    [[TMP8:%.*]] = fadd x86_fp80 [[TMP7]], 0xK3FFF8000000000000000370; DLQ-NEXT:    [[TMP9:%.*]] = call ptr @__nsan_get_shadow_ptr_for_double_store(ptr [[A]], i64 1)371; DLQ-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[A]] to i64372; DLQ-NEXT:    [[TMP11:%.*]] = call i32 @__nsan_internal_check_double_l(double [[C]], x86_fp80 [[TMP8]], i32 4, i64 [[TMP10]])373; DLQ-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[TMP11]], 1374; DLQ-NEXT:    [[TMP13:%.*]] = fpext double [[C]] to x86_fp80375; DLQ-NEXT:    [[TMP14:%.*]] = select i1 [[TMP12]], x86_fp80 [[TMP13]], x86_fp80 [[TMP8]]376; DLQ-NEXT:    store x86_fp80 [[TMP14]], ptr [[TMP9]], align 1377; DLQ-NEXT:    store double [[C]], ptr [[A]], align 1378; DLQ-NEXT:    ret void379;380entry:381  %b = load double, ptr %a, align 1382  %c = fadd double %b, 1.0383  store double %c, ptr %a, align 1384  ret void385}386 387define void @load_add_store_vector(<2 x float>* %a) sanitize_numerical_stability {388; CHECK-LABEL: @load_add_store_vector(389; CHECK-NEXT:  entry:390; CHECK-NEXT:    [[B:%.*]] = load <2 x float>, ptr [[A:%.*]], align 1391; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @__nsan_get_shadow_ptr_for_float_load(ptr [[A]], i64 2)392; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null393; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]394; CHECK:       2:395; CHECK-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr [[TMP0]], align 1396; CHECK-NEXT:    br label [[TMP6:%.*]]397; CHECK:       4:398; CHECK-NEXT:    [[TMP5:%.*]] = fpext <2 x float> [[B]] to <2 x double>399; CHECK-NEXT:    br label [[TMP6]]400; CHECK:       6:401; CHECK-NEXT:    [[TMP7:%.*]] = phi <2 x double> [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ]402; CHECK-NEXT:    [[C:%.*]] = fadd <2 x float> [[B]], splat (float 1.000000e+00)403; CHECK-NEXT:    [[TMP8:%.*]] = fadd <2 x double> [[TMP7]], splat (double 1.000000e+00)404; CHECK-NEXT:    [[TMP9:%.*]] = call ptr @__nsan_get_shadow_ptr_for_float_store(ptr [[A]], i64 2)405; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <2 x float> [[C]], i64 0406; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <2 x double> [[TMP8]], i64 0407; CHECK-NEXT:    [[TMP12:%.*]] = ptrtoint ptr [[A]] to i64408; CHECK-NEXT:    [[TMP13:%.*]] = call i32 @__nsan_internal_check_float_d(float [[TMP10]], double [[TMP11]], i32 4, i64 [[TMP12]])409; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <2 x float> [[C]], i64 1410; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x double> [[TMP8]], i64 1411; CHECK-NEXT:    [[TMP16:%.*]] = ptrtoint ptr [[A]] to i64412; CHECK-NEXT:    [[TMP17:%.*]] = call i32 @__nsan_internal_check_float_d(float [[TMP14]], double [[TMP15]], i32 4, i64 [[TMP16]])413; CHECK-NEXT:    [[TMP18:%.*]] = or i32 [[TMP13]], [[TMP17]]414; CHECK-NEXT:    [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 1415; CHECK-NEXT:    [[TMP20:%.*]] = fpext <2 x float> [[C]] to <2 x double>416; CHECK-NEXT:    [[TMP21:%.*]] = select i1 [[TMP19]], <2 x double> [[TMP20]], <2 x double> [[TMP8]]417; CHECK-NEXT:    store <2 x double> [[TMP21]], ptr [[TMP9]], align 1418; CHECK-NEXT:    store <2 x float> [[C]], ptr [[A]], align 1419; CHECK-NEXT:    ret void420;421entry:422  %b = load <2 x float>, ptr %a, align 1423  %c = fadd <2 x float> %b, <float 1.0, float 1.0>424  store <2 x float> %c, ptr %a, align 1425  ret void426}427 428declare float @returns_float()429 430define void @call_fn_returning_float(ptr %dst) sanitize_numerical_stability {431; CHECK-LABEL: @call_fn_returning_float(432; CHECK-NEXT:  entry:433; CHECK-NEXT:    [[B:%.*]] = call float @returns_float()434; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_ret_tag, align 8435; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @returns_float to i64)436; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr @__nsan_shadow_ret_ptr, align 8437; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[B]] to double438; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], double [[TMP2]], double [[TMP3]]439; CHECK-NEXT:    [[C:%.*]] = fadd float [[B]], 1.000000e+00440; CHECK-NEXT:    [[TMP5:%.*]] = fadd double [[TMP4]], 1.000000e+00441; CHECK-NEXT:    [[TMP6:%.*]] = call ptr @__nsan_get_shadow_ptr_for_float_store(ptr [[DST:%.*]], i64 1)442; CHECK-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[DST]] to i64443; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @__nsan_internal_check_float_d(float [[C]], double [[TMP5]], i32 4, i64 [[TMP7]])444; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 1445; CHECK-NEXT:    [[TMP10:%.*]] = fpext float [[C]] to double446; CHECK-NEXT:    [[TMP11:%.*]] = select i1 [[TMP9]], double [[TMP10]], double [[TMP5]]447; CHECK-NEXT:    store double [[TMP11]], ptr [[TMP6]], align 1448; CHECK-NEXT:    store float [[C]], ptr [[DST]], align 1449; CHECK-NEXT:    ret void450;451entry:452  %b = call float @returns_float()453  %c = fadd float %b, 1.0454  store float %c, ptr %dst, align 1455  ret void456}457 458define float @return_fn_returning_float(ptr %dst) sanitize_numerical_stability {459; CHECK-LABEL: @return_fn_returning_float(460; CHECK-NEXT:  entry:461; CHECK-NEXT:    [[B:%.*]] = call float @returns_float()462; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_ret_tag, align 8463; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @returns_float to i64)464; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr @__nsan_shadow_ret_ptr, align 8465; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[B]] to double466; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], double [[TMP2]], double [[TMP3]]467; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @__nsan_internal_check_float_d(float [[B]], double [[TMP4]], i32 1, i64 0)468; CHECK-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 1469; CHECK-NEXT:    [[TMP7:%.*]] = fpext float [[B]] to double470; CHECK-NEXT:    [[TMP8:%.*]] = select i1 [[TMP6]], double [[TMP7]], double [[TMP4]]471; CHECK-NEXT:    store i64 ptrtoint (ptr @return_fn_returning_float to i64), ptr @__nsan_shadow_ret_tag, align 8472; CHECK-NEXT:    store double [[TMP8]], ptr @__nsan_shadow_ret_ptr, align 8473; CHECK-NEXT:    ret float [[B]]474;475entry:476  %b = call float @returns_float()477  ret float %b478}479 480declare void @takes_floats(float %a, i8 %b, double %c, x86_fp80 %d)481 482define void @call_fn_taking_float() sanitize_numerical_stability {483; DQQ-LABEL: @call_fn_taking_float(484; DQQ-NEXT:  entry:485; DQQ-NEXT:    store ptr @takes_floats, ptr @__nsan_shadow_args_tag, align 8486; DQQ-NEXT:    store double 1.000000e+00, ptr @__nsan_shadow_args_ptr, align 1487; DQQ-NEXT:    store fp128 0xL00000000000000004000800000000000, ptr getelementptr ([16384 x i8], ptr @__nsan_shadow_args_ptr, i64 0, i64 8), align 1488; DQQ-NEXT:    store fp128 0xLC0000000000000003FC9CD2B297D889B, ptr getelementptr ([16384 x i8], ptr @__nsan_shadow_args_ptr, i64 0, i64 24), align 1489; DQQ-NEXT:    call void @takes_floats(float 1.000000e+00, i8 2, double 3.000000e+00, x86_fp80 0xK3FC9E69594BEC44DE000)490; DQQ-NEXT:    ret void491;492; DLQ-LABEL: @call_fn_taking_float(493; DLQ-NEXT:  entry:494; DLQ-NEXT:    store ptr @takes_floats, ptr @__nsan_shadow_args_tag, align 8495; DLQ-NEXT:    store double 1.000000e+00, ptr @__nsan_shadow_args_ptr, align 1496; DLQ-NEXT:    store x86_fp80 0xK4000C000000000000000, ptr getelementptr ([16384 x i8], ptr @__nsan_shadow_args_ptr, i64 0, i64 8), align 1497; DLQ-NEXT:    store fp128 0xLC0000000000000003FC9CD2B297D889B, ptr getelementptr ([16384 x i8], ptr @__nsan_shadow_args_ptr, i64 0, i64 18), align 1498; DLQ-NEXT:    call void @takes_floats(float 1.000000e+00, i8 2, double 3.000000e+00, x86_fp80 0xK3FC9E69594BEC44DE000)499; DLQ-NEXT:    ret void500;501entry:502  call void @takes_floats(float 1.0, i8 2, double 3.0, x86_fp80 0xK3FC9E69594BEC44DE000)503  ret void504}505 506declare float @llvm.sin.f32(float) readnone507 508define float @call_sin_intrinsic() sanitize_numerical_stability {509; CHECK-LABEL: @call_sin_intrinsic(510; CHECK-NEXT:  entry:511; CHECK-NEXT:    [[R:%.*]] = call float @llvm.sin.f32(float 1.000000e+00)512; CHECK-NEXT:    [[TMP0:%.*]] = call double @llvm.sin.f64(double 1.000000e+00)513; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)514; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1515; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[R]] to double516; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]517; CHECK-NEXT:    store i64 ptrtoint (ptr @call_sin_intrinsic to i64), ptr @__nsan_shadow_ret_tag, align 8518; CHECK-NEXT:    store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8519; CHECK-NEXT:    ret float [[R]]520;521entry:522  %r = call float @llvm.sin.f32(float 1.0)523  ret float %r524}525 526declare float @sinf(float)527 528define float @call_sinf_libfunc() sanitize_numerical_stability {529; CHECK-LABEL: @call_sinf_libfunc(530; CHECK-NEXT:  entry:531; CHECK-NEXT:    [[R:%.*]] = call float @sinf(float 1.000000e+00) #[[ATTR4:[0-9]+]]532; CHECK-NEXT:    [[TMP0:%.*]] = call double @llvm.sin.f64(double 1.000000e+00)533; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)534; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1535; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[R]] to double536; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]537; CHECK-NEXT:    store i64 ptrtoint (ptr @call_sinf_libfunc to i64), ptr @__nsan_shadow_ret_tag, align 8538; CHECK-NEXT:    store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8539; CHECK-NEXT:    ret float [[R]]540;541entry:542  %r = call float @sinf(float 1.0)543  ret float %r544}545 546declare double @sin(double)547 548; FIXME: nsan uses `sin(double)` for fp128.549define double @call_sin_libfunc() sanitize_numerical_stability {550; DQQ-LABEL: @call_sin_libfunc(551; DQQ-NEXT:  entry:552; DQQ-NEXT:    [[R:%.*]] = call double @sin(double 1.000000e+00) #[[ATTR4]]553; DQQ-NEXT:    [[TMP0:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 0xK3FFF8000000000000000)554; DQQ-NEXT:    [[TMP1:%.*]] = fpext x86_fp80 [[TMP0]] to fp128555; DQQ-NEXT:    [[TMP2:%.*]] = call i32 @__nsan_internal_check_double_q(double [[R]], fp128 [[TMP1]], i32 1, i64 0)556; DQQ-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 1557; DQQ-NEXT:    [[TMP4:%.*]] = fpext double [[R]] to fp128558; DQQ-NEXT:    [[TMP5:%.*]] = select i1 [[TMP3]], fp128 [[TMP4]], fp128 [[TMP1]]559; DQQ-NEXT:    store i64 ptrtoint (ptr @call_sin_libfunc to i64), ptr @__nsan_shadow_ret_tag, align 8560; DQQ-NEXT:    store fp128 [[TMP5]], ptr @__nsan_shadow_ret_ptr, align 16561; DQQ-NEXT:    ret double [[R]]562;563; DLQ-LABEL: @call_sin_libfunc(564; DLQ-NEXT:  entry:565; DLQ-NEXT:    [[R:%.*]] = call double @sin(double 1.000000e+00) #[[ATTR4]]566; DLQ-NEXT:    [[TMP0:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 0xK3FFF8000000000000000)567; DLQ-NEXT:    [[TMP1:%.*]] = call i32 @__nsan_internal_check_double_l(double [[R]], x86_fp80 [[TMP0]], i32 1, i64 0)568; DLQ-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1569; DLQ-NEXT:    [[TMP3:%.*]] = fpext double [[R]] to x86_fp80570; DLQ-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP0]]571; DLQ-NEXT:    store i64 ptrtoint (ptr @call_sin_libfunc to i64), ptr @__nsan_shadow_ret_tag, align 8572; DLQ-NEXT:    store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16573; DLQ-NEXT:    ret double [[R]]574;575entry:576  %r = call double @sin(double 1.0)577  ret double %r578}579 580declare double @frexp(double, i32*)581 582define double @call_frexp_libfunc_nointrinsic(double %0, i32* nocapture %1) sanitize_numerical_stability {583; DQQ-LABEL: @call_frexp_libfunc_nointrinsic(584; DQQ-NEXT:    [[TMP3:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8585; DQQ-NEXT:    [[TMP4:%.*]] = icmp eq i64 [[TMP3]], ptrtoint (ptr @call_frexp_libfunc_nointrinsic to i64)586; DQQ-NEXT:    [[TMP5:%.*]] = load fp128, ptr @__nsan_shadow_args_ptr, align 1587; DQQ-NEXT:    [[TMP6:%.*]] = fpext double [[TMP0:%.*]] to fp128588; DQQ-NEXT:    [[TMP7:%.*]] = select i1 [[TMP4]], fp128 [[TMP5]], fp128 [[TMP6]]589; DQQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8590; DQQ-NEXT:    [[TMP8:%.*]] = call i32 @__nsan_internal_check_double_q(double [[TMP0]], fp128 [[TMP7]], i32 2, i64 0)591; DQQ-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 1592; DQQ-NEXT:    [[TMP10:%.*]] = fpext double [[TMP0]] to fp128593; DQQ-NEXT:    [[TMP11:%.*]] = select i1 [[TMP9]], fp128 [[TMP10]], fp128 [[TMP7]]594; DQQ-NEXT:    [[TMP12:%.*]] = tail call double @frexp(double [[TMP0]], ptr [[TMP1:%.*]])595; DQQ-NEXT:    [[TMP13:%.*]] = load i64, ptr @__nsan_shadow_ret_tag, align 8596; DQQ-NEXT:    [[TMP14:%.*]] = icmp eq i64 [[TMP13]], ptrtoint (ptr @frexp to i64)597; DQQ-NEXT:    [[TMP15:%.*]] = load fp128, ptr @__nsan_shadow_ret_ptr, align 16598; DQQ-NEXT:    [[TMP16:%.*]] = fpext double [[TMP12]] to fp128599; DQQ-NEXT:    [[TMP17:%.*]] = select i1 [[TMP14]], fp128 [[TMP15]], fp128 [[TMP16]]600; DQQ-NEXT:    [[TMP18:%.*]] = call i32 @__nsan_internal_check_double_q(double [[TMP12]], fp128 [[TMP17]], i32 1, i64 0)601; DQQ-NEXT:    [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 1602; DQQ-NEXT:    [[TMP20:%.*]] = fpext double [[TMP12]] to fp128603; DQQ-NEXT:    [[TMP21:%.*]] = select i1 [[TMP19]], fp128 [[TMP20]], fp128 [[TMP17]]604; DQQ-NEXT:    store i64 ptrtoint (ptr @call_frexp_libfunc_nointrinsic to i64), ptr @__nsan_shadow_ret_tag, align 8605; DQQ-NEXT:    store fp128 [[TMP21]], ptr @__nsan_shadow_ret_ptr, align 16606; DQQ-NEXT:    ret double [[TMP12]]607;608; DLQ-LABEL: @call_frexp_libfunc_nointrinsic(609; DLQ-NEXT:    [[TMP3:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8610; DLQ-NEXT:    [[TMP4:%.*]] = icmp eq i64 [[TMP3]], ptrtoint (ptr @call_frexp_libfunc_nointrinsic to i64)611; DLQ-NEXT:    [[TMP5:%.*]] = load x86_fp80, ptr @__nsan_shadow_args_ptr, align 1612; DLQ-NEXT:    [[TMP6:%.*]] = fpext double [[TMP0:%.*]] to x86_fp80613; DLQ-NEXT:    [[TMP7:%.*]] = select i1 [[TMP4]], x86_fp80 [[TMP5]], x86_fp80 [[TMP6]]614; DLQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8615; DLQ-NEXT:    [[TMP8:%.*]] = call i32 @__nsan_internal_check_double_l(double [[TMP0]], x86_fp80 [[TMP7]], i32 2, i64 0)616; DLQ-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 1617; DLQ-NEXT:    [[TMP10:%.*]] = fpext double [[TMP0]] to x86_fp80618; DLQ-NEXT:    [[TMP11:%.*]] = select i1 [[TMP9]], x86_fp80 [[TMP10]], x86_fp80 [[TMP7]]619; DLQ-NEXT:    [[TMP12:%.*]] = tail call double @frexp(double [[TMP0]], ptr [[TMP1:%.*]])620; DLQ-NEXT:    [[TMP13:%.*]] = load i64, ptr @__nsan_shadow_ret_tag, align 8621; DLQ-NEXT:    [[TMP14:%.*]] = icmp eq i64 [[TMP13]], ptrtoint (ptr @frexp to i64)622; DLQ-NEXT:    [[TMP15:%.*]] = load x86_fp80, ptr @__nsan_shadow_ret_ptr, align 16623; DLQ-NEXT:    [[TMP16:%.*]] = fpext double [[TMP12]] to x86_fp80624; DLQ-NEXT:    [[TMP17:%.*]] = select i1 [[TMP14]], x86_fp80 [[TMP15]], x86_fp80 [[TMP16]]625; DLQ-NEXT:    [[TMP18:%.*]] = call i32 @__nsan_internal_check_double_l(double [[TMP12]], x86_fp80 [[TMP17]], i32 1, i64 0)626; DLQ-NEXT:    [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 1627; DLQ-NEXT:    [[TMP20:%.*]] = fpext double [[TMP12]] to x86_fp80628; DLQ-NEXT:    [[TMP21:%.*]] = select i1 [[TMP19]], x86_fp80 [[TMP20]], x86_fp80 [[TMP17]]629; DLQ-NEXT:    store i64 ptrtoint (ptr @call_frexp_libfunc_nointrinsic to i64), ptr @__nsan_shadow_ret_tag, align 8630; DLQ-NEXT:    store x86_fp80 [[TMP21]], ptr @__nsan_shadow_ret_ptr, align 16631; DLQ-NEXT:    ret double [[TMP12]]632;633  %3 = tail call double @frexp(double %0, i32* %1)634  ret double %3635}636 637define float @call_fn_taking_float_by_fn_ptr(float (float)* nocapture %fn_ptr) sanitize_numerical_stability {638; CHECK-LABEL: @call_fn_taking_float_by_fn_ptr(639; CHECK-NEXT:  entry:640; CHECK-NEXT:    store ptr [[FN_PTR:%.*]], ptr @__nsan_shadow_args_tag, align 8641; CHECK-NEXT:    store double 1.000000e+00, ptr @__nsan_shadow_args_ptr, align 1642; CHECK-NEXT:    [[R:%.*]] = call float [[FN_PTR]](float 1.000000e+00)643; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_ret_tag, align 8644; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[FN_PTR]] to i64645; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP0]], [[TMP1]]646; CHECK-NEXT:    [[TMP3:%.*]] = load double, ptr @__nsan_shadow_ret_ptr, align 8647; CHECK-NEXT:    [[TMP4:%.*]] = fpext float [[R]] to double648; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP4]]649; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP5]], i32 1, i64 0)650; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 1651; CHECK-NEXT:    [[TMP8:%.*]] = fpext float [[R]] to double652; CHECK-NEXT:    [[TMP9:%.*]] = select i1 [[TMP7]], double [[TMP8]], double [[TMP5]]653; CHECK-NEXT:    store i64 ptrtoint (ptr @call_fn_taking_float_by_fn_ptr to i64), ptr @__nsan_shadow_ret_tag, align 8654; CHECK-NEXT:    store double [[TMP9]], ptr @__nsan_shadow_ret_ptr, align 8655; CHECK-NEXT:    ret float [[R]]656;657entry:658  %r = call float %fn_ptr(float 1.0)659  ret float %r660}661 662define void @store_float(ptr %dst) sanitize_numerical_stability {663; CHECK-LABEL: @store_float(664; CHECK-NEXT:  entry:665; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @__nsan_get_shadow_ptr_for_float_store(ptr [[DST:%.*]], i64 1)666; CHECK-NEXT:    store double 4.200000e+01, ptr [[TMP0]], align 1667; CHECK-NEXT:    store float 4.200000e+01, ptr [[DST]], align 1668; CHECK-NEXT:    ret void669;670entry:671  store float 42.0, ptr %dst, align 1672  ret void673}674 675define i1 @inline_asm(double %0) sanitize_numerical_stability {676; DQQ-LABEL: @inline_asm(677; DQQ-NEXT:  entry:678; DQQ-NEXT:    [[TMP1:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8679; DQQ-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], ptrtoint (ptr @inline_asm to i64)680; DQQ-NEXT:    [[TMP3:%.*]] = load fp128, ptr @__nsan_shadow_args_ptr, align 1681; DQQ-NEXT:    [[TMP4:%.*]] = fpext double [[TMP0:%.*]] to fp128682; DQQ-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], fp128 [[TMP3]], fp128 [[TMP4]]683; DQQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8684; DQQ-NEXT:    [[TMP6:%.*]] = call i32 asm "pmovmskb $1, $0", "=r,x,~{dirflag},~{fpsr},~{flags}"(double [[TMP0]])685; DQQ-NEXT:    [[TMP7:%.*]] = trunc i32 [[TMP6]] to i8686; DQQ-NEXT:    [[TMP8:%.*]] = icmp slt i8 [[TMP7]], 0687; DQQ-NEXT:    ret i1 [[TMP8]]688;689; DLQ-LABEL: @inline_asm(690; DLQ-NEXT:  entry:691; DLQ-NEXT:    [[TMP1:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8692; DLQ-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], ptrtoint (ptr @inline_asm to i64)693; DLQ-NEXT:    [[TMP3:%.*]] = load x86_fp80, ptr @__nsan_shadow_args_ptr, align 1694; DLQ-NEXT:    [[TMP4:%.*]] = fpext double [[TMP0:%.*]] to x86_fp80695; DLQ-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], x86_fp80 [[TMP3]], x86_fp80 [[TMP4]]696; DLQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8697; DLQ-NEXT:    [[TMP6:%.*]] = call i32 asm "pmovmskb $1, $0", "=r,x,~{dirflag},~{fpsr},~{flags}"(double [[TMP0]])698; DLQ-NEXT:    [[TMP7:%.*]] = trunc i32 [[TMP6]] to i8699; DLQ-NEXT:    [[TMP8:%.*]] = icmp slt i8 [[TMP7]], 0700; DLQ-NEXT:    ret i1 [[TMP8]]701;702entry:703  %1 = call i32 asm "pmovmskb $1, $0", "=r,x,~{dirflag},~{fpsr},~{flags}"(double %0)704  %2 = trunc i32 %1 to i8705  %3 = icmp slt i8 %2, 0706  ret i1 %3707}708 709define void @vector_extract(<2 x float> %0) sanitize_numerical_stability {710; CHECK-LABEL: @vector_extract(711; CHECK-NEXT:  entry:712; CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8713; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], ptrtoint (ptr @vector_extract to i64)714; CHECK-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr @__nsan_shadow_args_ptr, align 1715; CHECK-NEXT:    [[TMP4:%.*]] = fpext <2 x float> [[TMP0:%.*]] to <2 x double>716; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], <2 x double> [[TMP3]], <2 x double> [[TMP4]]717; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8718; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x float> [[TMP0]], i32 1719; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <2 x double> [[TMP5]], i32 1720; CHECK-NEXT:    ret void721;722entry:723  %1 = extractelement <2 x float> %0, i32 1724  ret void725}726 727define void @vector_insert(<2 x float> %0) sanitize_numerical_stability {728; CHECK-LABEL: @vector_insert(729; CHECK-NEXT:  entry:730; CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8731; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], ptrtoint (ptr @vector_insert to i64)732; CHECK-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr @__nsan_shadow_args_ptr, align 1733; CHECK-NEXT:    [[TMP4:%.*]] = fpext <2 x float> [[TMP0:%.*]] to <2 x double>734; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], <2 x double> [[TMP3]], <2 x double> [[TMP4]]735; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8736; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x float> [[TMP0]], float 1.000000e+00, i32 1737; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <2 x double> [[TMP5]], double 1.000000e+00, i32 1738; CHECK-NEXT:    ret void739;740entry:741  %1 = insertelement <2 x float> %0, float 1.0, i32 1742  ret void743}744 745define void @freeze_vector_insert(<2 x float> %vec, i32 %idx, float %scalar) sanitize_numerical_stability {746; CHECK-LABEL: @freeze_vector_insert(747; CHECK-NEXT:  entry:748; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8749; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @freeze_vector_insert to i64)750; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr @__nsan_shadow_args_ptr, align 1751; CHECK-NEXT:    [[TMP3:%.*]] = fpext <2 x float> [[VEC:%.*]] to <2 x double>752; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], <2 x double> [[TMP2]], <2 x double> [[TMP3]]753; CHECK-NEXT:    [[TMP5:%.*]] = load double, ptr getelementptr ([16384 x i8], ptr @__nsan_shadow_args_ptr, i64 0, i64 16), align 1754; CHECK-NEXT:    [[TMP6:%.*]] = fpext float [[SCALAR:%.*]] to double755; CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP1]], double [[TMP5]], double [[TMP6]]756; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8757; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <2 x float> [[VEC]], float [[SCALAR]], i32 [[IDX:%.*]]758; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x double> [[TMP4]], double [[TMP7]], i32 [[IDX]]759; CHECK-NEXT:    [[FROZEN:%.*]] = freeze <2 x float> [[TMP8]]760; CHECK-NEXT:    [[TMP10:%.*]] = freeze <2 x double> [[TMP9]]761; CHECK-NEXT:    ret void762;763entry:764  %1 = insertelement <2 x float> %vec, float %scalar, i32 %idx765  %frozen = freeze <2 x float> %1766  ret void767}768 769define void @vector_shuffle(<2 x float> %0) sanitize_numerical_stability {770; CHECK-LABEL: @vector_shuffle(771; CHECK-NEXT:  entry:772; CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8773; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], ptrtoint (ptr @vector_shuffle to i64)774; CHECK-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr @__nsan_shadow_args_ptr, align 1775; CHECK-NEXT:    [[TMP4:%.*]] = fpext <2 x float> [[TMP0:%.*]] to <2 x double>776; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], <2 x double> [[TMP3]], <2 x double> [[TMP4]]777; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8778; CHECK-NEXT:    [[TMP6:%.*]] = shufflevector <2 x float> [[TMP0]], <2 x float> splat (float 1.000000e+00), <2 x i32> <i32 1, i32 3>779; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <2 x double> [[TMP5]], <2 x double> splat (double 1.000000e+00), <2 x i32> <i32 1, i32 3>780; CHECK-NEXT:    ret void781;782entry:783  %1 = shufflevector <2 x float> %0, <2 x float> <float 1.0, float 1.0>, <2 x i32> <i32 1, i32 3>784  ret void785}786 787define void @aggregate_extract({i32, {float, i1}} %0) sanitize_numerical_stability {788; CHECK-LABEL: @aggregate_extract(789; CHECK-NEXT:  entry:790; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i32, { float, i1 } } [[TMP0:%.*]], 1, 0791; CHECK-NEXT:    [[TMP2:%.*]] = fpext float [[TMP1]] to double792; CHECK-NEXT:    ret void793;794entry:795  %1 = extractvalue {i32, {float, i1}} %0, 1, 0796  ret void797}798 799define void @aggregate_insert({i32, {float, i1}} %0, float %1) sanitize_numerical_stability {800; CHECK-LABEL: @aggregate_insert(801; CHECK-NEXT:  entry:802; CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8803; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[TMP2]], ptrtoint (ptr @aggregate_insert to i64)804; CHECK-NEXT:    [[TMP4:%.*]] = load double, ptr @__nsan_shadow_args_ptr, align 1805; CHECK-NEXT:    [[TMP5:%.*]] = fpext float [[TMP1:%.*]] to double806; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP3]], double [[TMP4]], double [[TMP5]]807; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8808; CHECK-NEXT:    [[TMP7:%.*]] = call i32 @__nsan_internal_check_float_d(float [[TMP1]], double [[TMP6]], i32 5, i64 0)809; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 1810; CHECK-NEXT:    [[TMP9:%.*]] = fpext float [[TMP1]] to double811; CHECK-NEXT:    [[TMP10:%.*]] = select i1 [[TMP8]], double [[TMP9]], double [[TMP6]]812; CHECK-NEXT:    [[TMP11:%.*]] = insertvalue { i32, { float, i1 } } [[TMP0:%.*]], float [[TMP1]], 1, 0813; CHECK-NEXT:    ret void814;815entry:816  %2 = insertvalue {i32, {float, i1}} %0, float %1, 1, 0817  ret void818}819 820define void @aggregate_insert_avoid_const_check({i32, {float, i1}} %0) sanitize_numerical_stability {821; CHECK-LABEL: @aggregate_insert_avoid_const_check(822; CHECK-NEXT:  entry:823; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, { float, i1 } } [[TMP0:%.*]], float 1.000000e+00, 1, 0824; CHECK-NEXT:    ret void825;826entry:827  %1 = insertvalue {i32, {float, i1}} %0, float 1.0, 1, 0828  ret void829}830 831 832declare float @fabsf(float)833 834define float @sub_fabs(float %a, float %b) sanitize_numerical_stability {835; CHECK-LABEL: @sub_fabs(836; CHECK-NEXT:  entry:837; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8838; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @sub_fabs to i64)839; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr @__nsan_shadow_args_ptr, align 1840; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[A:%.*]] to double841; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], double [[TMP2]], double [[TMP3]]842; CHECK-NEXT:    [[TMP5:%.*]] = load double, ptr getelementptr ([16384 x i8], ptr @__nsan_shadow_args_ptr, i64 0, i64 8), align 1843; CHECK-NEXT:    [[TMP6:%.*]] = fpext float [[B:%.*]] to double844; CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP1]], double [[TMP5]], double [[TMP6]]845; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8846; CHECK-NEXT:    [[S:%.*]] = fsub float [[A]], [[B]]847; CHECK-NEXT:    [[TMP8:%.*]] = fsub double [[TMP4]], [[TMP7]]848; CHECK-NEXT:    [[TMP9:%.*]] = call i32 @__nsan_internal_check_float_d(float [[S]], double [[TMP8]], i32 2, i64 0)849; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 1850; CHECK-NEXT:    [[TMP11:%.*]] = fpext float [[S]] to double851; CHECK-NEXT:    [[TMP12:%.*]] = select i1 [[TMP10]], double [[TMP11]], double [[TMP8]]852; CHECK-NEXT:    [[R:%.*]] = call float @fabsf(float [[S]]) #[[ATTR4]]853; CHECK-NEXT:    [[TMP13:%.*]] = call double @llvm.fabs.f64(double [[TMP8]])854; CHECK-NEXT:    [[TMP14:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP13]], i32 1, i64 0)855; CHECK-NEXT:    [[TMP15:%.*]] = icmp eq i32 [[TMP14]], 1856; CHECK-NEXT:    [[TMP16:%.*]] = fpext float [[R]] to double857; CHECK-NEXT:    [[TMP17:%.*]] = select i1 [[TMP15]], double [[TMP16]], double [[TMP13]]858; CHECK-NEXT:    store i64 ptrtoint (ptr @sub_fabs to i64), ptr @__nsan_shadow_ret_tag, align 8859; CHECK-NEXT:    store double [[TMP17]], ptr @__nsan_shadow_ret_ptr, align 8860; CHECK-NEXT:    ret float [[R]]861;862entry:863  %s = fsub float %a, %b864  %r = call float @fabsf(float %s)865  ret float %r866}867 868define void @truncate(<2 x double> %0) sanitize_numerical_stability {869; DQQ-LABEL: @truncate(870; DQQ-NEXT:  entry:871; DQQ-NEXT:    [[TMP1:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8872; DQQ-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], ptrtoint (ptr @truncate to i64)873; DQQ-NEXT:    [[TMP3:%.*]] = load <2 x fp128>, ptr @__nsan_shadow_args_ptr, align 1874; DQQ-NEXT:    [[TMP4:%.*]] = fpext <2 x double> [[TMP0:%.*]] to <2 x fp128>875; DQQ-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], <2 x fp128> [[TMP3]], <2 x fp128> [[TMP4]]876; DQQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8877; DQQ-NEXT:    [[TMP6:%.*]] = fptrunc <2 x double> [[TMP0]] to <2 x float>878; DQQ-NEXT:    [[TMP7:%.*]] = fptrunc <2 x fp128> [[TMP5]] to <2 x double>879; DQQ-NEXT:    ret void880;881; DLQ-LABEL: @truncate(882; DLQ-NEXT:  entry:883; DLQ-NEXT:    [[TMP1:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8884; DLQ-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], ptrtoint (ptr @truncate to i64)885; DLQ-NEXT:    [[TMP3:%.*]] = load <2 x x86_fp80>, ptr @__nsan_shadow_args_ptr, align 1886; DLQ-NEXT:    [[TMP4:%.*]] = fpext <2 x double> [[TMP0:%.*]] to <2 x x86_fp80>887; DLQ-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], <2 x x86_fp80> [[TMP3]], <2 x x86_fp80> [[TMP4]]888; DLQ-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8889; DLQ-NEXT:    [[TMP6:%.*]] = fptrunc <2 x double> [[TMP0]] to <2 x float>890; DLQ-NEXT:    [[TMP7:%.*]] = fptrunc <2 x x86_fp80> [[TMP5]] to <2 x double>891; DLQ-NEXT:    ret void892;893entry:894  %1 = fptrunc <2 x double> %0 to  <2 x float>895  ret void896}897 898define void @unaryop(float %a) sanitize_numerical_stability {899; CHECK-LABEL: @unaryop(900; CHECK-NEXT:  entry:901; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__nsan_shadow_args_tag, align 8902; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], ptrtoint (ptr @unaryop to i64)903; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr @__nsan_shadow_args_ptr, align 1904; CHECK-NEXT:    [[TMP3:%.*]] = fpext float [[A:%.*]] to double905; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], double [[TMP2]], double [[TMP3]]906; CHECK-NEXT:    store i64 0, ptr @__nsan_shadow_args_tag, align 8907; CHECK-NEXT:    [[C:%.*]] = fneg float [[A]]908; CHECK-NEXT:    [[TMP5:%.*]] = fneg double [[TMP4]]909; CHECK-NEXT:    ret void910;911entry:912  %c = fneg float %a913  ret void914}915 916 917attributes #0 = { nounwind readonly uwtable sanitize_numerical_stability "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "use-soft-float"="false" }918