[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