[llvm] [SLP][NFC]Add a test for potential masked div/rem ops, NFC (PR #210593)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 19 06:10:36 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Alexey Bataev (alexey-bataev)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/210593.diff


1 Files Affected:

- (added) llvm/test/Transforms/SLPVectorizer/AArch64/masked-div-rem-non-pow2.ll (+184) 


``````````diff
diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/masked-div-rem-non-pow2.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/masked-div-rem-non-pow2.ll
new file mode 100644
index 0000000000000..054f0799906cb
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/AArch64/masked-div-rem-non-pow2.ll
@@ -0,0 +1,184 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S --passes=slp-vectorizer -mtriple=aarch64-unknown-linux-gnu -mcpu=neoverse-512tvb -slp-vectorize-non-power-of-2 < %s | FileCheck %s
+
+define void @udiv_v7i32(ptr noalias %dst, ptr noalias %x, ptr noalias %y) vscale_range(2,2) {
+; CHECK-LABEL: define void @udiv_v7i32(
+; CHECK-SAME: ptr noalias [[DST:%.*]], ptr noalias [[X:%.*]], ptr noalias [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load <7 x i32>, ptr [[X]], align 4
+; CHECK-NEXT:    [[TMP2:%.*]] = load <7 x i32>, ptr [[Y]], align 4
+; CHECK-NEXT:    [[TMP6:%.*]] = udiv <7 x i32> [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    store <7 x i32> [[TMP6]], ptr [[DST]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %x0 = load i32, ptr %x, align 4
+  %gep.x.1 = getelementptr inbounds i32, ptr %x, i64 1
+  %x1 = load i32, ptr %gep.x.1, align 4
+  %gep.x.2 = getelementptr inbounds i32, ptr %x, i64 2
+  %x2 = load i32, ptr %gep.x.2, align 4
+  %gep.x.3 = getelementptr inbounds i32, ptr %x, i64 3
+  %x3 = load i32, ptr %gep.x.3, align 4
+  %gep.x.4 = getelementptr inbounds i32, ptr %x, i64 4
+  %x4 = load i32, ptr %gep.x.4, align 4
+  %gep.x.5 = getelementptr inbounds i32, ptr %x, i64 5
+  %x5 = load i32, ptr %gep.x.5, align 4
+  %gep.x.6 = getelementptr inbounds i32, ptr %x, i64 6
+  %x6 = load i32, ptr %gep.x.6, align 4
+  %y0 = load i32, ptr %y, align 4
+  %gep.y.1 = getelementptr inbounds i32, ptr %y, i64 1
+  %y1 = load i32, ptr %gep.y.1, align 4
+  %gep.y.2 = getelementptr inbounds i32, ptr %y, i64 2
+  %y2 = load i32, ptr %gep.y.2, align 4
+  %gep.y.3 = getelementptr inbounds i32, ptr %y, i64 3
+  %y3 = load i32, ptr %gep.y.3, align 4
+  %gep.y.4 = getelementptr inbounds i32, ptr %y, i64 4
+  %y4 = load i32, ptr %gep.y.4, align 4
+  %gep.y.5 = getelementptr inbounds i32, ptr %y, i64 5
+  %y5 = load i32, ptr %gep.y.5, align 4
+  %gep.y.6 = getelementptr inbounds i32, ptr %y, i64 6
+  %y6 = load i32, ptr %gep.y.6, align 4
+  %d0 = udiv i32 %x0, %y0
+  %d1 = udiv i32 %x1, %y1
+  %d2 = udiv i32 %x2, %y2
+  %d3 = udiv i32 %x3, %y3
+  %d4 = udiv i32 %x4, %y4
+  %d5 = udiv i32 %x5, %y5
+  %d6 = udiv i32 %x6, %y6
+  store i32 %d0, ptr %dst, align 4
+  %gep.dst.1 = getelementptr inbounds i32, ptr %dst, i64 1
+  store i32 %d1, ptr %gep.dst.1, align 4
+  %gep.dst.2 = getelementptr inbounds i32, ptr %dst, i64 2
+  store i32 %d2, ptr %gep.dst.2, align 4
+  %gep.dst.3 = getelementptr inbounds i32, ptr %dst, i64 3
+  store i32 %d3, ptr %gep.dst.3, align 4
+  %gep.dst.4 = getelementptr inbounds i32, ptr %dst, i64 4
+  store i32 %d4, ptr %gep.dst.4, align 4
+  %gep.dst.5 = getelementptr inbounds i32, ptr %dst, i64 5
+  store i32 %d5, ptr %gep.dst.5, align 4
+  %gep.dst.6 = getelementptr inbounds i32, ptr %dst, i64 6
+  store i32 %d6, ptr %gep.dst.6, align 4
+  ret void
+}
+
+define void @sdiv_v7i32(ptr noalias %dst, ptr noalias %x, ptr noalias %y) vscale_range(2,2) {
+; CHECK-LABEL: define void @sdiv_v7i32(
+; CHECK-SAME: ptr noalias [[DST:%.*]], ptr noalias [[X:%.*]], ptr noalias [[Y:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load <7 x i32>, ptr [[X]], align 4
+; CHECK-NEXT:    [[TMP2:%.*]] = load <7 x i32>, ptr [[Y]], align 4
+; CHECK-NEXT:    [[TMP6:%.*]] = sdiv <7 x i32> [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    store <7 x i32> [[TMP6]], ptr [[DST]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %x0 = load i32, ptr %x, align 4
+  %gep.x.1 = getelementptr inbounds i32, ptr %x, i64 1
+  %x1 = load i32, ptr %gep.x.1, align 4
+  %gep.x.2 = getelementptr inbounds i32, ptr %x, i64 2
+  %x2 = load i32, ptr %gep.x.2, align 4
+  %gep.x.3 = getelementptr inbounds i32, ptr %x, i64 3
+  %x3 = load i32, ptr %gep.x.3, align 4
+  %gep.x.4 = getelementptr inbounds i32, ptr %x, i64 4
+  %x4 = load i32, ptr %gep.x.4, align 4
+  %gep.x.5 = getelementptr inbounds i32, ptr %x, i64 5
+  %x5 = load i32, ptr %gep.x.5, align 4
+  %gep.x.6 = getelementptr inbounds i32, ptr %x, i64 6
+  %x6 = load i32, ptr %gep.x.6, align 4
+  %y0 = load i32, ptr %y, align 4
+  %gep.y.1 = getelementptr inbounds i32, ptr %y, i64 1
+  %y1 = load i32, ptr %gep.y.1, align 4
+  %gep.y.2 = getelementptr inbounds i32, ptr %y, i64 2
+  %y2 = load i32, ptr %gep.y.2, align 4
+  %gep.y.3 = getelementptr inbounds i32, ptr %y, i64 3
+  %y3 = load i32, ptr %gep.y.3, align 4
+  %gep.y.4 = getelementptr inbounds i32, ptr %y, i64 4
+  %y4 = load i32, ptr %gep.y.4, align 4
+  %gep.y.5 = getelementptr inbounds i32, ptr %y, i64 5
+  %y5 = load i32, ptr %gep.y.5, align 4
+  %gep.y.6 = getelementptr inbounds i32, ptr %y, i64 6
+  %y6 = load i32, ptr %gep.y.6, align 4
+  %d0 = sdiv i32 %x0, %y0
+  %d1 = sdiv i32 %x1, %y1
+  %d2 = sdiv i32 %x2, %y2
+  %d3 = sdiv i32 %x3, %y3
+  %d4 = sdiv i32 %x4, %y4
+  %d5 = sdiv i32 %x5, %y5
+  %d6 = sdiv i32 %x6, %y6
+  store i32 %d0, ptr %dst, align 4
+  %gep.dst.1 = getelementptr inbounds i32, ptr %dst, i64 1
+  store i32 %d1, ptr %gep.dst.1, align 4
+  %gep.dst.2 = getelementptr inbounds i32, ptr %dst, i64 2
+  store i32 %d2, ptr %gep.dst.2, align 4
+  %gep.dst.3 = getelementptr inbounds i32, ptr %dst, i64 3
+  store i32 %d3, ptr %gep.dst.3, align 4
+  %gep.dst.4 = getelementptr inbounds i32, ptr %dst, i64 4
+  store i32 %d4, ptr %gep.dst.4, align 4
+  %gep.dst.5 = getelementptr inbounds i32, ptr %dst, i64 5
+  store i32 %d5, ptr %gep.dst.5, align 4
+  %gep.dst.6 = getelementptr inbounds i32, ptr %dst, i64 6
+  store i32 %d6, ptr %gep.dst.6, align 4
+  ret void
+}
+
+; AArch64 has no native predicated urem, so the masked intrinsic is not
+; cheaper here: the direct <7 x i32> urem is unchanged.
+define void @urem_v7i32(ptr noalias %dst, ptr noalias %x, ptr noalias %y) vscale_range(2,2) {
+; CHECK-LABEL: define void @urem_v7i32(
+; CHECK-SAME: ptr noalias [[DST:%.*]], ptr noalias [[X:%.*]], ptr noalias [[Y:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load <7 x i32>, ptr [[X]], align 4
+; CHECK-NEXT:    [[TMP2:%.*]] = load <7 x i32>, ptr [[Y]], align 4
+; CHECK-NEXT:    [[TMP3:%.*]] = urem <7 x i32> [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    store <7 x i32> [[TMP3]], ptr [[DST]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %x0 = load i32, ptr %x, align 4
+  %gep.x.1 = getelementptr inbounds i32, ptr %x, i64 1
+  %x1 = load i32, ptr %gep.x.1, align 4
+  %gep.x.2 = getelementptr inbounds i32, ptr %x, i64 2
+  %x2 = load i32, ptr %gep.x.2, align 4
+  %gep.x.3 = getelementptr inbounds i32, ptr %x, i64 3
+  %x3 = load i32, ptr %gep.x.3, align 4
+  %gep.x.4 = getelementptr inbounds i32, ptr %x, i64 4
+  %x4 = load i32, ptr %gep.x.4, align 4
+  %gep.x.5 = getelementptr inbounds i32, ptr %x, i64 5
+  %x5 = load i32, ptr %gep.x.5, align 4
+  %gep.x.6 = getelementptr inbounds i32, ptr %x, i64 6
+  %x6 = load i32, ptr %gep.x.6, align 4
+  %y0 = load i32, ptr %y, align 4
+  %gep.y.1 = getelementptr inbounds i32, ptr %y, i64 1
+  %y1 = load i32, ptr %gep.y.1, align 4
+  %gep.y.2 = getelementptr inbounds i32, ptr %y, i64 2
+  %y2 = load i32, ptr %gep.y.2, align 4
+  %gep.y.3 = getelementptr inbounds i32, ptr %y, i64 3
+  %y3 = load i32, ptr %gep.y.3, align 4
+  %gep.y.4 = getelementptr inbounds i32, ptr %y, i64 4
+  %y4 = load i32, ptr %gep.y.4, align 4
+  %gep.y.5 = getelementptr inbounds i32, ptr %y, i64 5
+  %y5 = load i32, ptr %gep.y.5, align 4
+  %gep.y.6 = getelementptr inbounds i32, ptr %y, i64 6
+  %y6 = load i32, ptr %gep.y.6, align 4
+  %d0 = urem i32 %x0, %y0
+  %d1 = urem i32 %x1, %y1
+  %d2 = urem i32 %x2, %y2
+  %d3 = urem i32 %x3, %y3
+  %d4 = urem i32 %x4, %y4
+  %d5 = urem i32 %x5, %y5
+  %d6 = urem i32 %x6, %y6
+  store i32 %d0, ptr %dst, align 4
+  %gep.dst.1 = getelementptr inbounds i32, ptr %dst, i64 1
+  store i32 %d1, ptr %gep.dst.1, align 4
+  %gep.dst.2 = getelementptr inbounds i32, ptr %dst, i64 2
+  store i32 %d2, ptr %gep.dst.2, align 4
+  %gep.dst.3 = getelementptr inbounds i32, ptr %dst, i64 3
+  store i32 %d3, ptr %gep.dst.3, align 4
+  %gep.dst.4 = getelementptr inbounds i32, ptr %dst, i64 4
+  store i32 %d4, ptr %gep.dst.4, align 4
+  %gep.dst.5 = getelementptr inbounds i32, ptr %dst, i64 5
+  store i32 %d5, ptr %gep.dst.5, align 4
+  %gep.dst.6 = getelementptr inbounds i32, ptr %dst, i64 6
+  store i32 %d6, ptr %gep.dst.6, align 4
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/210593


More information about the llvm-commits mailing list