[llvm] [msan] Handle single-parameter Arm NEON vector convert intrinsics (PR #126136)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 6 13:45:58 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Thurston Dang (thurstond)
<details>
<summary>Changes</summary>
This handles the following llvm.aarch64.neon intrinsics, which were suboptimally handled by visitInstruction:
- fcvtas, fcvtau
- fcvtms, fcvtmu
- fcvtns, fcvtnu
- fcvtps, fcvtpu
- fcvtzs, fcvtzu
The old instrumentation checked that the shadow was fully initialized, and aborted otherwise. The new instrumentation propagates the shadow (initialized iff the shadow of each element is fully initialized).
Updates the tests from https://github.com/llvm/llvm-project/pull/126095
---
Patch is 87.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/126136.diff
3 Files Affected:
- (modified) llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp (+54-6)
- (modified) llvm/test/Instrumentation/MemorySanitizer/AArch64/arm64-cvt.ll (+80-243)
- (modified) llvm/test/Instrumentation/MemorySanitizer/AArch64/arm64-vcvt.ll (+128-338)
``````````diff
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 60f3893f20a79a..6821b52b79097e 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3118,7 +3118,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOriginForNaryOp(I);
}
- // Instrument vector convert intrinsic.
+ // Instrument x86 SSE vector convert intrinsic.
//
// This function instruments intrinsics like cvtsi2ss:
// %Out = int_xxx_cvtyyy(%ConvertOp)
@@ -3133,8 +3133,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// We copy the shadow of \p CopyOp[NumUsedElements:] to \p
// Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
// return a fully initialized value.
- void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
- bool HasRoundingMode = false) {
+ //
+ // For Arm NEON vector convert intrinsics, see
+ // handleNEONVectorConvertIntrinsic().
+ void handleSSEVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
+ bool HasRoundingMode = false) {
IRBuilder<> IRB(&I);
Value *CopyOp, *ConvertOp;
@@ -4156,6 +4159,30 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/*trailingVerbatimArgs*/ 0);
}
+ /// Handle Arm NEON vector convert intrinsics.
+ ///
+ /// e.g., <4 x i32> @llvm.aarch64.neon.fcvtpu.v4i32.v4f32(<4 x float>)
+ /// i32 @llvm.aarch64.neon.fcvtms.i32.f64(double)
+ ///
+ /// For x86 SSE vector convert intrinsics, see
+ /// handleSSEVectorConvertIntrinsic().
+ void handleNEONVectorConvertIntrinsic(IntrinsicInst &I) {
+ assert(I.arg_size() == 1);
+
+ IRBuilder<> IRB(&I);
+ Value *S0 = getShadow(&I, 0);
+
+ /// For scalars:
+ /// Since they are converting from floating-point to integer, the output is
+ /// - fully uninitialized if *any* bit of the input is uninitialized
+ /// - fully ininitialized if all bits of the input are ininitialized
+ /// We apply the same principle on a per-field basis for vectors.
+ Value *OutShadow = IRB.CreateSExt(IRB.CreateICmpNE(S0, getCleanShadow(S0)),
+ getShadowTy(&I));
+ setShadow(&I, OutShadow);
+ setOriginForNaryOp(I);
+ }
+
/// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
/// and vst{2,3,4}lane).
///
@@ -4423,7 +4450,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
case Intrinsic::x86_avx512_cvtusi2ss:
case Intrinsic::x86_avx512_cvtusi642sd:
case Intrinsic::x86_avx512_cvtusi642ss:
- handleVectorConvertIntrinsic(I, 1, true);
+ handleSSEVectorConvertIntrinsic(I, 1, true);
break;
case Intrinsic::x86_sse2_cvtsd2si64:
case Intrinsic::x86_sse2_cvtsd2si:
@@ -4434,11 +4461,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
case Intrinsic::x86_sse_cvtss2si:
case Intrinsic::x86_sse_cvttss2si64:
case Intrinsic::x86_sse_cvttss2si:
- handleVectorConvertIntrinsic(I, 1);
+ handleSSEVectorConvertIntrinsic(I, 1);
break;
case Intrinsic::x86_sse_cvtps2pi:
case Intrinsic::x86_sse_cvttps2pi:
- handleVectorConvertIntrinsic(I, 2);
+ handleSSEVectorConvertIntrinsic(I, 2);
break;
case Intrinsic::x86_avx512_psll_w_512:
@@ -4781,6 +4808,27 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(&I, getCleanOrigin());
break;
+ // Floating-point Convert to integer, rounding to nearest with ties to Away
+ case Intrinsic::aarch64_neon_fcvtas:
+ case Intrinsic::aarch64_neon_fcvtau:
+ // Floating-point convert to integer, rounding toward minus infinity
+ case Intrinsic::aarch64_neon_fcvtms:
+ case Intrinsic::aarch64_neon_fcvtmu:
+ // Floating-point convert to integer, rounding to nearest with ties to even
+ case Intrinsic::aarch64_neon_fcvtns:
+ case Intrinsic::aarch64_neon_fcvtnu:
+ // Floating-point convert to integer, rounding toward plus infinity
+ case Intrinsic::aarch64_neon_fcvtps:
+ case Intrinsic::aarch64_neon_fcvtpu:
+ // Floating-point Convert to integer, rounding toward Zero
+ case Intrinsic::aarch64_neon_fcvtzs:
+ case Intrinsic::aarch64_neon_fcvtzu:
+ // Floating-point convert to lower precision narrow, rounding to odd
+ case Intrinsic::aarch64_neon_fcvtxn: {
+ handleNEONVectorConvertIntrinsic(I);
+ break;
+ }
+
case Intrinsic::aarch64_neon_st1x2:
case Intrinsic::aarch64_neon_st1x3:
case Intrinsic::aarch64_neon_st1x4:
diff --git a/llvm/test/Instrumentation/MemorySanitizer/AArch64/arm64-cvt.ll b/llvm/test/Instrumentation/MemorySanitizer/AArch64/arm64-cvt.ll
index 016e0114c83ff7..2518443dc5910e 100644
--- a/llvm/test/Instrumentation/MemorySanitizer/AArch64/arm64-cvt.ll
+++ b/llvm/test/Instrumentation/MemorySanitizer/AArch64/arm64-cvt.ll
@@ -19,13 +19,9 @@ define i32 @fcvtas_1w1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1:![0-9]+]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3:[0-9]+]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtas.i32.f32(float [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtas.i32.f32(float %A)
@@ -38,13 +34,9 @@ define i64 @fcvtas_1x1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtas.i64.f32(float [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtas.i64.f32(float %A)
@@ -57,13 +49,9 @@ define i32 @fcvtas_1w1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtas.i32.f64(double [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtas.i32.f64(double %A)
@@ -76,13 +64,9 @@ define i64 @fcvtas_1x1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtas.i64.f64(double [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtas.i64.f64(double %A)
@@ -100,13 +84,9 @@ define i32 @fcvtau_1w1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtau.i32.f32(float [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtau.i32.f32(float %A)
@@ -119,13 +99,9 @@ define i64 @fcvtau_1x1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtau.i64.f32(float [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtau.i64.f32(float %A)
@@ -138,13 +114,9 @@ define i32 @fcvtau_1w1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtau.i32.f64(double [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtau.i32.f64(double %A)
@@ -157,13 +129,9 @@ define i64 @fcvtau_1x1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtau.i64.f64(double [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtau.i64.f64(double %A)
@@ -181,13 +149,9 @@ define i32 @fcvtms_1w1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtms.i32.f32(float [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtms.i32.f32(float %A)
@@ -200,13 +164,9 @@ define i64 @fcvtms_1x1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtms.i64.f32(float [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtms.i64.f32(float %A)
@@ -219,13 +179,9 @@ define i32 @fcvtms_1w1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtms.i32.f64(double [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtms.i32.f64(double %A)
@@ -238,13 +194,9 @@ define i64 @fcvtms_1x1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtms.i64.f64(double [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtms.i64.f64(double %A)
@@ -262,13 +214,9 @@ define i32 @fcvtmu_1w1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtmu.i32.f32(float [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtmu.i32.f32(float %A)
@@ -281,13 +229,9 @@ define i64 @fcvtmu_1x1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtmu.i64.f32(float [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtmu.i64.f32(float %A)
@@ -300,13 +244,9 @@ define i32 @fcvtmu_1w1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtmu.i32.f64(double [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtmu.i32.f64(double %A)
@@ -319,13 +259,9 @@ define i64 @fcvtmu_1x1d(double %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtmu.i64.f64(double [[A]])
-; CHECK-NEXT: store i64 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i64 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i64 [[TMP3]]
;
%tmpvar3 = call i64 @llvm.aarch64.neon.fcvtmu.i64.f64(double %A)
@@ -343,13 +279,9 @@ define i32 @fcvtns_1w1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.aarch64.neon.fcvtns.i32.f32(float [[A]])
-; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT: store i32 [[TMP4]], ptr @__msan_retval_tls, align 8
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmpvar3 = call i32 @llvm.aarch64.neon.fcvtns.i32.f32(float %A)
@@ -362,13 +294,9 @@ define i64 @fcvtns_1x1s(float %A) nounwind #0 {
; 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 [[TMP2:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
-; CHECK: 2:
-; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: 3:
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[_MSCMP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.aarch64.neon.fcvtns.i64.f32(float [[A]])
-; CHECK-NEXT: s...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/126136
More information about the llvm-commits
mailing list