[llvm] [msan] Handle fpto[us]i_sat (PR #196429)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 14:50:00 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Thurston Dang (thurstond)
<details>
<summary>Changes</summary>
This adds explicit handling for fpto[us]i_sat, similar to how the non-saturating versions are handled.
N.B. PR #<!-- -->191365 lowered NEON fcvtz[us] intrinsics into fpto[us]i.sat. There is a slight inconsistency in MSan insofar as the former were handled by handleNEONVectorConvertIntrinsic(), which takes an all-or-nothing propagation approach to the shadows (i.e., even a single uninitialized bit will result in the corresponding integer being fully uninitialized). For now, we choose to follow the laxer behavior of fpto[usi. Future work may consider changing the behavior of fpto[us]i and fpto[us]i_sat to use the all-or-nothing approach.
---
Full diff: https://github.com/llvm/llvm-project/pull/196429.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp (+9)
- (modified) llvm/test/Instrumentation/MemorySanitizer/ftrunc.ll (+7-19)
``````````diff
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 933865f9cb7be..a69177b54ae95 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -5864,6 +5864,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(&I, getCleanOrigin());
break;
+ // The non-saturating versions are handled by visitFPTo[US]IInst().
+ //
+ // N.B. some platform-specific intrinsics, such as Aarch64 fcvtz[us], are
+ // lowered to these cross-platform intrinsics.
+ case Intrinsic::fptosi_sat:
+ case Intrinsic::fptoui_sat:
+ handleShadowOr(I);
+ break;
+
default:
return false;
}
diff --git a/llvm/test/Instrumentation/MemorySanitizer/ftrunc.ll b/llvm/test/Instrumentation/MemorySanitizer/ftrunc.ll
index e061a1048a6ef..878bdd24eed73 100644
--- a/llvm/test/Instrumentation/MemorySanitizer/ftrunc.ll
+++ b/llvm/test/Instrumentation/MemorySanitizer/ftrunc.ll
@@ -3,8 +3,9 @@
;
; Forked from llvm/test/Instrumentation/MemorySanitizer/ftrunc.ll
;
-; Handled strictly:
-; - llvm.fptoui.sat, llvm.fptosi.sat
+; Handled strictly: (none)
+;
+; Handled heuristically: (none)
;
; REQUIRES: x86-registered-target
@@ -235,15 +236,10 @@ define float @trunc_unsigned_f32_disable_via_intrinsic(float %x) #0 {
; CHECK-SAME: float [[X:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @__msan_param_tls, align 8
; CHECK-NEXT: call void @llvm.donothing()
-; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i32 [[TMP1]], 0
-; CHECK-NEXT: br i1 [[_MSCMP]], label %[[BB2:.*]], label %[[BB3:.*]], !prof [[PROF1:![0-9]+]]
-; CHECK: [[BB2]]:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR4:[0-9]+]]
-; CHECK-NEXT: unreachable
-; CHECK: [[BB3]]:
+; CHECK-NEXT: [[_MSPROP:%.*]] = or i32 [[TMP1]], 0
; CHECK-NEXT: [[I:%.*]] = call i32 @llvm.fptoui.sat.i32.f32(float [[X]])
; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[I]] to float
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[_MSPROP]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret float [[R]]
;
%i = call i32 @llvm.fptoui.sat.i32.f32(float %x)
@@ -256,15 +252,10 @@ define double @trunc_signed_f64_disable_via_intrinsic(double %x) #0 {
; CHECK-SAME: double [[X:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @__msan_param_tls, align 8
; CHECK-NEXT: call void @llvm.donothing()
-; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
-; CHECK-NEXT: br i1 [[_MSCMP]], label %[[BB2:.*]], label %[[BB3:.*]], !prof [[PROF1]]
-; CHECK: [[BB2]]:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR4]]
-; CHECK-NEXT: unreachable
-; CHECK: [[BB3]]:
+; CHECK-NEXT: [[_MSPROP:%.*]] = or i64 [[TMP1]], 0
; CHECK-NEXT: [[I:%.*]] = call i64 @llvm.fptosi.sat.i64.f64(double [[X]])
; CHECK-NEXT: [[R:%.*]] = sitofp i64 [[I]] to double
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[_MSPROP]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret double [[R]]
;
%i = call i64 @llvm.fptosi.sat.i64.f64(double %x)
@@ -273,6 +264,3 @@ define double @trunc_signed_f64_disable_via_intrinsic(double %x) #0 {
}
attributes #0 = { sanitize_memory }
-;.
-; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 1048575}
-;.
``````````
</details>
https://github.com/llvm/llvm-project/pull/196429
More information about the llvm-commits
mailing list