[Instrumentation][nsan] Intrinsic tests + bugfixes (#186803)
Add comprehensive lit-test coverage to the NumericalStabilitySanitizer's intrinsic and libfunc handling. Also, several minor bugfixes: - Fix typo in llvm.nearbyint.f80's name. - Remove lround and llround intrinsics, since they return ints (and are not instrumented by nsan as a result). - Fix fmuladd.f64 intrinsic to map to fmuladd instead of fma. - Add missing fmuladd.f80 variant.
This commit is contained in:
parent
d20315f154
commit
65bf05a494
@ -1398,14 +1398,11 @@ const KnownIntrinsic::WidenedIntrinsic KnownIntrinsic::kWidenedIntrinsics[] = {
|
||||
{"llvm.log2.f64", Intrinsic::log2, makeX86FP80X86FP80},
|
||||
{"llvm.log2.f80", Intrinsic::log2, makeX86FP80X86FP80},
|
||||
{"llvm.fma.f32", Intrinsic::fma, makeDoubleDoubleDoubleDouble},
|
||||
|
||||
{"llvm.fmuladd.f32", Intrinsic::fmuladd, makeDoubleDoubleDoubleDouble},
|
||||
|
||||
{"llvm.fma.f64", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80},
|
||||
|
||||
{"llvm.fmuladd.f64", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80},
|
||||
|
||||
{"llvm.fma.f80", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80},
|
||||
{"llvm.fmuladd.f32", Intrinsic::fmuladd, makeDoubleDoubleDoubleDouble},
|
||||
{"llvm.fmuladd.f64", Intrinsic::fmuladd, makeX86FP80X86FP80X86FP80X86FP80},
|
||||
{"llvm.fmuladd.f80", Intrinsic::fmuladd, makeX86FP80X86FP80X86FP80X86FP80},
|
||||
{"llvm.fabs.f32", Intrinsic::fabs, makeDoubleDouble},
|
||||
{"llvm.fabs.f64", Intrinsic::fabs, makeX86FP80X86FP80},
|
||||
{"llvm.fabs.f80", Intrinsic::fabs, makeX86FP80X86FP80},
|
||||
@ -1438,22 +1435,10 @@ const KnownIntrinsic::WidenedIntrinsic KnownIntrinsic::kWidenedIntrinsics[] = {
|
||||
{"llvm.rint.f80", Intrinsic::rint, makeX86FP80X86FP80},
|
||||
{"llvm.nearbyint.f32", Intrinsic::nearbyint, makeDoubleDouble},
|
||||
{"llvm.nearbyint.f64", Intrinsic::nearbyint, makeX86FP80X86FP80},
|
||||
{"llvm.nearbyin80f64", Intrinsic::nearbyint, makeX86FP80X86FP80},
|
||||
{"llvm.nearbyint.f80", Intrinsic::nearbyint, makeX86FP80X86FP80},
|
||||
{"llvm.round.f32", Intrinsic::round, makeDoubleDouble},
|
||||
{"llvm.round.f64", Intrinsic::round, makeX86FP80X86FP80},
|
||||
{"llvm.round.f80", Intrinsic::round, makeX86FP80X86FP80},
|
||||
{"llvm.lround.f32", Intrinsic::lround, makeDoubleDouble},
|
||||
{"llvm.lround.f64", Intrinsic::lround, makeX86FP80X86FP80},
|
||||
{"llvm.lround.f80", Intrinsic::lround, makeX86FP80X86FP80},
|
||||
{"llvm.llround.f32", Intrinsic::llround, makeDoubleDouble},
|
||||
{"llvm.llround.f64", Intrinsic::llround, makeX86FP80X86FP80},
|
||||
{"llvm.llround.f80", Intrinsic::llround, makeX86FP80X86FP80},
|
||||
{"llvm.lrint.f32", Intrinsic::lrint, makeDoubleDouble},
|
||||
{"llvm.lrint.f64", Intrinsic::lrint, makeX86FP80X86FP80},
|
||||
{"llvm.lrint.f80", Intrinsic::lrint, makeX86FP80X86FP80},
|
||||
{"llvm.llrint.f32", Intrinsic::llrint, makeDoubleDouble},
|
||||
{"llvm.llrint.f64", Intrinsic::llrint, makeX86FP80X86FP80},
|
||||
{"llvm.llrint.f80", Intrinsic::llrint, makeX86FP80X86FP80},
|
||||
};
|
||||
|
||||
const KnownIntrinsic::LFEntry KnownIntrinsic::kLibfuncIntrinsics[] = {
|
||||
|
||||
@ -503,80 +503,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare float @llvm.sin.f32(float) readnone
|
||||
|
||||
define float @call_sin_intrinsic() sanitize_numerical_stability {
|
||||
; CHECK-LABEL: @call_sin_intrinsic(
|
||||
; 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_intrinsic 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
|
||||
}
|
||||
|
||||
declare float @sinf(float)
|
||||
|
||||
define float @call_sinf_libfunc() sanitize_numerical_stability {
|
||||
; CHECK-LABEL: @call_sinf_libfunc(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[R:%.*]] = call float @sinf(float 1.000000e+00) #[[ATTR3:[0-9]+]]
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = call double @llvm.sin.f64(double 1.000000e+00)
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__nsan_internal_check_float_d(float [[R]], double [[TMP0]], i32 1, i64 0)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = fpext float [[R]] to double
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], double [[TMP3]], double [[TMP0]]
|
||||
; CHECK-NEXT: store i64 ptrtoint (ptr @call_sinf_libfunc to i64), ptr @__nsan_shadow_ret_tag, align 8
|
||||
; CHECK-NEXT: store double [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 8
|
||||
; CHECK-NEXT: ret float [[R]]
|
||||
;
|
||||
entry:
|
||||
%r = call float @sinf(float 1.0)
|
||||
ret float %r
|
||||
}
|
||||
|
||||
declare double @sin(double)
|
||||
|
||||
; FIXME: nsan uses `sin(double)` for fp128.
|
||||
define double @call_sin_libfunc() sanitize_numerical_stability {
|
||||
; DQQ-LABEL: @call_sin_libfunc(
|
||||
; DQQ-NEXT: entry:
|
||||
; DQQ-NEXT: [[R:%.*]] = call double @sin(double 1.000000e+00) #[[ATTR3]]
|
||||
; DQQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 0xK3FFF8000000000000000)
|
||||
; 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_libfunc 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_libfunc(
|
||||
; DLQ-NEXT: entry:
|
||||
; DLQ-NEXT: [[R:%.*]] = call double @sin(double 1.000000e+00) #[[ATTR3]]
|
||||
; DLQ-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.sin.f80(x86_fp80 0xK3FFF8000000000000000)
|
||||
; 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_libfunc to i64), ptr @__nsan_shadow_ret_tag, align 8
|
||||
; DLQ-NEXT: store x86_fp80 [[TMP4]], ptr @__nsan_shadow_ret_ptr, align 16
|
||||
; DLQ-NEXT: ret double [[R]]
|
||||
;
|
||||
entry:
|
||||
%r = call double @sin(double 1.0)
|
||||
ret double %r
|
||||
}
|
||||
|
||||
declare double @frexp(double, i32*)
|
||||
|
||||
define double @call_frexp_libfunc_nointrinsic(double %0, i32* nocapture %1) sanitize_numerical_stability {
|
||||
|
||||
1809
llvm/test/Instrumentation/NumericalStabilitySanitizer/intrinsics.ll
Normal file
1809
llvm/test/Instrumentation/NumericalStabilitySanitizer/intrinsics.ll
Normal file
File diff suppressed because it is too large
Load Diff
1432
llvm/test/Instrumentation/NumericalStabilitySanitizer/libfuncs.ll
Normal file
1432
llvm/test/Instrumentation/NumericalStabilitySanitizer/libfuncs.ll
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user