[llvm] [msan] add tests for llvm.masked.{udiv, sdiv, urem, srem} (PR #227462)

Emilio Cota via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 15:52:39 PDT 2026


https://github.com/cota updated https://github.com/llvm/llvm-project/pull/227462

>From 148d0cd55800b9a248ca1452731e8947d48585a6 Mon Sep 17 00:00:00 2001
From: Emilio Cota <ecg at google.com>
Date: Tue, 29 Sep 2026 12:37:57 +0000
Subject: [PATCH] [msan] add tests for llvm.masked.{udiv,sdiv,urem,srem}

In preparation for #225363, which changes behavior.
---
 .../MemorySanitizer/masked-divrem.ll          | 307 ++++++++++++++++++
 1 file changed, 307 insertions(+)
 create mode 100644 llvm/test/Instrumentation/MemorySanitizer/masked-divrem.ll

diff --git a/llvm/test/Instrumentation/MemorySanitizer/masked-divrem.ll b/llvm/test/Instrumentation/MemorySanitizer/masked-divrem.ll
new file mode 100644
index 0000000000000..32773dd3808e6
--- /dev/null
+++ b/llvm/test/Instrumentation/MemorySanitizer/masked-divrem.ll
@@ -0,0 +1,307 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s --implicit-check-not="call void @__msan_warning"
+
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+define <4 x i32> @masked_udiv(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m) sanitize_memory {
+; CHECK-LABEL: @masked_udiv(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP2:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 16), align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i1>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 32), align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
+; CHECK-NEXT:    [[_MSCMP1:%.*]] = icmp ne i128 [[TMP4]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = bitcast <4 x i32> [[TMP1]] to i128
+; CHECK-NEXT:    [[_MSCMP3:%.*]] = icmp ne i128 [[TMP8]], 0
+; CHECK-NEXT:    [[_MSOR:%.*]] = or i1 [[_MSCMP1]], [[_MSCMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = bitcast <4 x i1> [[TMP3]] to i4
+; CHECK-NEXT:    [[_MSCMP2:%.*]] = icmp ne i4 [[TMP5]], 0
+; CHECK-NEXT:    [[_MSOR3:%.*]] = or i1 [[_MSOR]], [[_MSCMP2]]
+; CHECK-NEXT:    br i1 [[_MSOR3]], label [[TMP6:%.*]], label [[TMP7:%.*]], !prof [[PROF1:![0-9]+]]
+; CHECK:       6:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5:[0-9]+]]
+; CHECK-NEXT:    unreachable
+; CHECK:       7:
+; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @llvm.masked.udiv.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i1> [[M:%.*]])
+; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret <4 x i32> [[RES]]
+;
+entry:
+  %res = call <4 x i32> @llvm.masked.udiv(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m)
+  ret <4 x i32> %res
+}
+
+define <4 x i32> @masked_sdiv(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m) sanitize_memory {
+; CHECK-LABEL: @masked_sdiv(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP2:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 16), align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i1>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 32), align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
+; CHECK-NEXT:    [[_MSCMP1:%.*]] = icmp ne i128 [[TMP4]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = bitcast <4 x i32> [[TMP1]] to i128
+; CHECK-NEXT:    [[_MSCMP3:%.*]] = icmp ne i128 [[TMP8]], 0
+; CHECK-NEXT:    [[_MSOR:%.*]] = or i1 [[_MSCMP1]], [[_MSCMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = bitcast <4 x i1> [[TMP3]] to i4
+; CHECK-NEXT:    [[_MSCMP2:%.*]] = icmp ne i4 [[TMP5]], 0
+; CHECK-NEXT:    [[_MSOR3:%.*]] = or i1 [[_MSOR]], [[_MSCMP2]]
+; CHECK-NEXT:    br i1 [[_MSOR3]], label [[TMP6:%.*]], label [[TMP7:%.*]], !prof [[PROF1]]
+; CHECK:       6:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       7:
+; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @llvm.masked.sdiv.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i1> [[M:%.*]])
+; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret <4 x i32> [[RES]]
+;
+entry:
+  %res = call <4 x i32> @llvm.masked.sdiv(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m)
+  ret <4 x i32> %res
+}
+
+define <4 x i32> @masked_urem(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m) sanitize_memory {
+; CHECK-LABEL: @masked_urem(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP2:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 16), align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i1>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 32), align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
+; CHECK-NEXT:    [[_MSCMP1:%.*]] = icmp ne i128 [[TMP4]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = bitcast <4 x i32> [[TMP1]] to i128
+; CHECK-NEXT:    [[_MSCMP3:%.*]] = icmp ne i128 [[TMP8]], 0
+; CHECK-NEXT:    [[_MSOR:%.*]] = or i1 [[_MSCMP1]], [[_MSCMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = bitcast <4 x i1> [[TMP3]] to i4
+; CHECK-NEXT:    [[_MSCMP2:%.*]] = icmp ne i4 [[TMP5]], 0
+; CHECK-NEXT:    [[_MSOR3:%.*]] = or i1 [[_MSOR]], [[_MSCMP2]]
+; CHECK-NEXT:    br i1 [[_MSOR3]], label [[TMP6:%.*]], label [[TMP7:%.*]], !prof [[PROF1]]
+; CHECK:       6:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       7:
+; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @llvm.masked.urem.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i1> [[M:%.*]])
+; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret <4 x i32> [[RES]]
+;
+entry:
+  %res = call <4 x i32> @llvm.masked.urem(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m)
+  ret <4 x i32> %res
+}
+
+define <4 x i32> @masked_srem(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m) sanitize_memory {
+; CHECK-LABEL: @masked_srem(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP2:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 16), align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i1>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 32), align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
+; CHECK-NEXT:    [[_MSCMP1:%.*]] = icmp ne i128 [[TMP4]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = bitcast <4 x i32> [[TMP1]] to i128
+; CHECK-NEXT:    [[_MSCMP3:%.*]] = icmp ne i128 [[TMP8]], 0
+; CHECK-NEXT:    [[_MSOR:%.*]] = or i1 [[_MSCMP1]], [[_MSCMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = bitcast <4 x i1> [[TMP3]] to i4
+; CHECK-NEXT:    [[_MSCMP2:%.*]] = icmp ne i4 [[TMP5]], 0
+; CHECK-NEXT:    [[_MSOR3:%.*]] = or i1 [[_MSOR]], [[_MSCMP2]]
+; CHECK-NEXT:    br i1 [[_MSOR3]], label [[TMP6:%.*]], label [[TMP7:%.*]], !prof [[PROF1]]
+; CHECK:       6:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       7:
+; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @llvm.masked.srem.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i1> [[M:%.*]])
+; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret <4 x i32> [[RES]]
+;
+entry:
+  %res = call <4 x i32> @llvm.masked.srem(<4 x i32> %x, <4 x i32> %y, <4 x i1> %m)
+  ret <4 x i32> %res
+}
+
+; Typical tail-folded vectorizer output: the masked-off lanes of the operands
+; come from masked loads with a poison pass-through, and must not be reported.
+define <4 x i32> @urem_masked_loads(ptr %pa, ptr %pb) sanitize_memory {
+; CHECK-LABEL: @urem_masked_loads(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr getelementptr (i8, ptr @__msan_param_tls, i64 8), align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[PA:%.*]] to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i64 [[TMP0]], 87960930222080
+; CHECK-NEXT:    [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
+; CHECK-NEXT:    [[_MSMASKEDLD:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr align 1 [[TMP2]], <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> splat (i32 -1))
+; CHECK-NEXT:    [[_MSCMP1:%.*]] = icmp ne i64 [[TMP7]], 0
+; CHECK-NEXT:    br i1 [[_MSCMP1]], label [[TMP9:%.*]], label [[TMP12:%.*]], !prof [[PROF1]]
+; CHECK:       5:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       6:
+; CHECK-NEXT:    [[A:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr [[PA]], <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> poison)
+; CHECK-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[PB:%.*]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i64 [[TMP3]], 87960930222080
+; CHECK-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
+; CHECK-NEXT:    [[_MSMASKEDLD1:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr align 1 [[TMP5]], <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> splat (i32 -1))
+; CHECK-NEXT:    [[_MSCMP2:%.*]] = icmp ne i64 [[TMP8]], 0
+; CHECK-NEXT:    br i1 [[_MSCMP2]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF1]]
+; CHECK:       10:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       11:
+; CHECK-NEXT:    [[B:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr [[PB]], <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> poison)
+; CHECK-NEXT:    [[TMP6:%.*]] = bitcast <4 x i32> [[_MSMASKEDLD]] to i128
+; CHECK-NEXT:    [[_MSCMP:%.*]] = icmp ne i128 [[TMP6]], 0
+; CHECK-NEXT:    [[TMP13:%.*]] = bitcast <4 x i32> [[_MSMASKEDLD1]] to i128
+; CHECK-NEXT:    [[_MSCMP4:%.*]] = icmp ne i128 [[TMP13]], 0
+; CHECK-NEXT:    [[_MSOR:%.*]] = or i1 [[_MSCMP]], [[_MSCMP4]]
+; CHECK-NEXT:    br i1 [[_MSOR]], label [[TMP14:%.*]], label [[TMP15:%.*]], !prof [[PROF1]]
+; CHECK:       14:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       15:
+; CHECK-NEXT:    [[R:%.*]] = call <4 x i32> @llvm.masked.urem.v4i32(<4 x i32> [[A]], <4 x i32> [[B]], <4 x i1> <i1 true, i1 true, i1 true, i1 false>)
+; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret <4 x i32> [[R]]
+;
+entry:
+  %a = call <4 x i32> @llvm.masked.load(ptr %pa, <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> poison)
+  %b = call <4 x i32> @llvm.masked.load(ptr %pb, <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> poison)
+  %r = call <4 x i32> @llvm.masked.urem(<4 x i32> %a, <4 x i32> %b, <4 x i1> <i1 true, i1 true, i1 true, i1 false>)
+  ret <4 x i32> %r
+}
+
+; Disabled lanes of llvm.masked.udiv must carry a poisoned shadow, even
+; when the dividend is clean across all lanes.
+define i1 @udiv_clean_dividend_poisons_disabled_lanes(<4 x i32> %b) sanitize_memory {
+; CHECK-LABEL: @udiv_clean_dividend_poisons_disabled_lanes(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to i128
+; CHECK-NEXT:    [[_MSCMP:%.*]] = icmp ne i128 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[_MSCMP]], label [[TMP2:%.*]], label [[TMP3:%.*]], !prof [[PROF1]]
+; CHECK:       2:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       3:
+; CHECK-NEXT:    [[R:%.*]] = call <4 x i32> @llvm.masked.udiv.v4i32(<4 x i32> splat (i32 100), <4 x i32> [[B:%.*]], <4 x i1> <i1 true, i1 true, i1 true, i1 false>)
+; CHECK-NEXT:    [[LANE3:%.*]] = extractelement <4 x i32> [[R]], i32 3
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[LANE3]], 0
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 -1, [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0
+; CHECK-NEXT:    [[_MSPROP_ICMP:%.*]] = and i1 false, [[TMP6]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[LANE3]], 0
+; CHECK-NEXT:    br i1 [[_MSPROP_ICMP]], label [[TMP7:%.*]], label [[TMP8:%.*]], !prof [[PROF1]]
+; CHECK:       7:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       8:
+; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 false, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret i1 true
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret i1 false
+;
+entry:
+  %r = call <4 x i32> @llvm.masked.udiv(<4 x i32> splat (i32 100), <4 x i32> %b, <4 x i1> <i1 true, i1 true, i1 true, i1 false>)
+  %lane3 = extractelement <4 x i32> %r, i32 3
+  %cmp = icmp eq i32 %lane3, 0
+  br i1 %cmp, label %t, label %f
+t:
+  ret i1 true
+f:
+  ret i1 false
+}
+
+; With every lane enabled there is nothing to poison, and the divisor is
+; checked in full, exactly as for a plain udiv.
+define <4 x i32> @udiv_all_lanes_enabled(<4 x i32> %x, <4 x i32> %y) sanitize_memory {
+; CHECK-LABEL: @udiv_all_lanes_enabled(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    [[TMP6:%.*]] = load <4 x i32>, ptr getelementptr (i8, ptr @__msan_param_tls, i64 16), align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128
+; CHECK-NEXT:    [[_MSCMP:%.*]] = icmp ne i128 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast <4 x i32> [[TMP6]] to i128
+; CHECK-NEXT:    [[_MSCMP1:%.*]] = icmp ne i128 [[TMP3]], 0
+; CHECK-NEXT:    [[_MSOR:%.*]] = or i1 [[_MSCMP]], [[_MSCMP1]]
+; CHECK-NEXT:    br i1 [[_MSOR]], label [[TMP4:%.*]], label [[TMP5:%.*]], !prof [[PROF1]]
+; CHECK:       4:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       5:
+; CHECK-NEXT:    [[R:%.*]] = call <4 x i32> @llvm.masked.udiv.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i1> splat (i1 true))
+; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    ret <4 x i32> [[R]]
+;
+entry:
+  %r = call <4 x i32> @llvm.masked.udiv(<4 x i32> %x, <4 x i32> %y, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
+  ret <4 x i32> %r
+}
+
+; Scalable vectors: the disabled lanes get a poison shadow splat, and the
+; divisor check goes through a vector reduction rather than a bitcast.
+define void @masked_udiv_scalable(ptr %pa, ptr %pb, ptr %pr, <vscale x 4 x i1> %m) sanitize_memory {
+; CHECK-LABEL: @masked_udiv_scalable(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr @__msan_param_tls, align 8
+; CHECK-NEXT:    [[TMP12:%.*]] = load i64, ptr getelementptr (i8, ptr @__msan_param_tls, i64 8), align 8
+; CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr getelementptr (i8, ptr @__msan_param_tls, i64 16), align 8
+; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[_MSCMP1:%.*]] = icmp ne i64 [[TMP7]], 0
+; CHECK-NEXT:    br i1 [[_MSCMP1]], label [[TMP19:%.*]], label [[TMP20:%.*]], !prof [[PROF1]]
+; CHECK:       3:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       4:
+; CHECK-NEXT:    [[A:%.*]] = load <vscale x 4 x i32>, ptr [[PA:%.*]], align 16
+; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[PA]] to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i64 [[TMP0]], 87960930222080
+; CHECK-NEXT:    [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
+; CHECK-NEXT:    [[_MSLD:%.*]] = load <vscale x 4 x i32>, ptr [[TMP2]], align 16
+; CHECK-NEXT:    [[_MSCMP2:%.*]] = icmp ne i64 [[TMP12]], 0
+; CHECK-NEXT:    br i1 [[_MSCMP2]], label [[TMP8:%.*]], label [[TMP21:%.*]], !prof [[PROF1]]
+; CHECK:       8:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       9:
+; CHECK-NEXT:    [[B:%.*]] = load <vscale x 4 x i32>, ptr [[PB:%.*]], align 16
+; CHECK-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[PB]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i64 [[TMP3]], 87960930222080
+; CHECK-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
+; CHECK-NEXT:    [[_MSLD1:%.*]] = load <vscale x 4 x i32>, ptr [[TMP5]], align 16
+; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.nxv4i32(<vscale x 4 x i32> [[_MSLD]])
+; CHECK-NEXT:    [[_MSCMP:%.*]] = icmp ne i32 [[TMP6]], 0
+; CHECK-NEXT:    [[TMP14:%.*]] = call i32 @llvm.vector.reduce.or.nxv4i32(<vscale x 4 x i32> [[_MSLD1]])
+; CHECK-NEXT:    [[_MSCMP5:%.*]] = icmp ne i32 [[TMP14]], 0
+; CHECK-NEXT:    [[_MSOR:%.*]] = or i1 [[_MSCMP]], [[_MSCMP5]]
+; CHECK-NEXT:    br i1 [[_MSOR]], label [[TMP15:%.*]], label [[TMP16:%.*]], !prof [[PROF1]]
+; CHECK:       15:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       16:
+; CHECK-NEXT:    [[R:%.*]] = call <vscale x 4 x i32> @llvm.masked.udiv.nxv4i32(<vscale x 4 x i32> [[A]], <vscale x 4 x i32> [[B]], <vscale x 4 x i1> [[M:%.*]])
+; CHECK-NEXT:    [[_MSCMP4:%.*]] = icmp ne i64 [[TMP13]], 0
+; CHECK-NEXT:    br i1 [[_MSCMP4]], label [[TMP17:%.*]], label [[TMP18:%.*]], !prof [[PROF1]]
+; CHECK:       17:
+; CHECK-NEXT:    call void @__msan_warning_noreturn() #[[ATTR5]]
+; CHECK-NEXT:    unreachable
+; CHECK:       18:
+; CHECK-NEXT:    [[TMP9:%.*]] = ptrtoint ptr [[PR:%.*]] to i64
+; CHECK-NEXT:    [[TMP10:%.*]] = xor i64 [[TMP9]], 87960930222080
+; CHECK-NEXT:    [[TMP11:%.*]] = inttoptr i64 [[TMP10]] to ptr
+; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[TMP11]], align 16
+; CHECK-NEXT:    store <vscale x 4 x i32> [[R]], ptr [[PR]], align 16
+; CHECK-NEXT:    ret void
+;
+entry:
+  %a = load <vscale x 4 x i32>, ptr %pa
+  %b = load <vscale x 4 x i32>, ptr %pb
+  %r = call <vscale x 4 x i32> @llvm.masked.udiv(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %m)
+  store <vscale x 4 x i32> %r, ptr %pr
+  ret void
+}



More information about the llvm-commits mailing list