[llvm] [SLP][NFC]Add extra test for bit mask reductions, NFC (PR #224135)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 13:48:31 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/224135.diff


1 Files Affected:

- (modified) llvm/test/Transforms/SLPVectorizer/X86/bool-mask.ll (+206-2) 


``````````diff
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/bool-mask.ll b/llvm/test/Transforms/SLPVectorizer/X86/bool-mask.ll
index e91026032bb59..fc8f41b987dee 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/bool-mask.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/bool-mask.ll
@@ -969,5 +969,209 @@ entry:
   ret i64 %mask.1.15
 }
 
-  !0 = !{i8 0, i8 2}
-  !1 = !{}
+define i64 @bitmask_16xi8_shl(ptr %src) {
+; SSE2-LABEL: @bitmask_16xi8_shl(
+; SSE2-NEXT:  entry:
+; SSE2-NEXT:    [[TMP0:%.*]] = load i8, ptr [[SRC:%.*]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 1
+; SSE2-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX_1]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 2
+; SSE2-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ARRAYIDX_2]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 3
+; SSE2-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX_3]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 4
+; SSE2-NEXT:    [[TMP4:%.*]] = load i8, ptr [[ARRAYIDX_4]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 5
+; SSE2-NEXT:    [[TMP5:%.*]] = load i8, ptr [[ARRAYIDX_5]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 6
+; SSE2-NEXT:    [[TMP6:%.*]] = load i8, ptr [[ARRAYIDX_6]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 7
+; SSE2-NEXT:    [[TMP7:%.*]] = load i8, ptr [[ARRAYIDX_7]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_8:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 8
+; SSE2-NEXT:    [[TMP8:%.*]] = load i8, ptr [[ARRAYIDX_8]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_9:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 9
+; SSE2-NEXT:    [[TMP9:%.*]] = load i8, ptr [[ARRAYIDX_9]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_10:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 10
+; SSE2-NEXT:    [[TMP10:%.*]] = load i8, ptr [[ARRAYIDX_10]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[ARRAYIDX_11:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 11
+; SSE2-NEXT:    [[TMP11:%.*]] = load <4 x i8>, ptr [[ARRAYIDX_11]], align 1
+; SSE2-NEXT:    [[ARRAYIDX_15:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 15
+; SSE2-NEXT:    [[TMP12:%.*]] = load i8, ptr [[ARRAYIDX_15]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE2-NEXT:    [[TMP13:%.*]] = zext <4 x i8> [[TMP11]] to <4 x i64>
+; SSE2-NEXT:    [[TMP14:%.*]] = shl <4 x i64> [[TMP13]], <i64 11, i64 12, i64 13, i64 14>
+; SSE2-NEXT:    [[TMP15:%.*]] = call i64 @llvm.vector.reduce.or.v4i64(<4 x i64> [[TMP14]])
+; SSE2-NEXT:    [[TMP16:%.*]] = zext i8 [[TMP8]] to i64
+; SSE2-NEXT:    [[TMP17:%.*]] = shl i64 [[TMP16]], 8
+; SSE2-NEXT:    [[OP_RDX:%.*]] = or i64 [[TMP15]], [[TMP17]]
+; SSE2-NEXT:    [[TMP18:%.*]] = zext i8 [[TMP0]] to i64
+; SSE2-NEXT:    [[TMP19:%.*]] = and i8 [[TMP1]], 127
+; SSE2-NEXT:    [[TMP20:%.*]] = zext i8 [[TMP19]] to i64
+; SSE2-NEXT:    [[TMP21:%.*]] = shl i64 [[TMP20]], 1
+; SSE2-NEXT:    [[OP_RDX1:%.*]] = or i64 [[TMP18]], [[TMP21]]
+; SSE2-NEXT:    [[TMP22:%.*]] = and i8 [[TMP2]], 63
+; SSE2-NEXT:    [[TMP23:%.*]] = zext i8 [[TMP22]] to i64
+; SSE2-NEXT:    [[TMP24:%.*]] = shl i64 [[TMP23]], 2
+; SSE2-NEXT:    [[TMP25:%.*]] = and i8 [[TMP3]], 31
+; SSE2-NEXT:    [[TMP26:%.*]] = zext i8 [[TMP25]] to i64
+; SSE2-NEXT:    [[TMP27:%.*]] = shl i64 [[TMP26]], 3
+; SSE2-NEXT:    [[OP_RDX2:%.*]] = or i64 [[TMP24]], [[TMP27]]
+; SSE2-NEXT:    [[TMP28:%.*]] = and i8 [[TMP4]], 15
+; SSE2-NEXT:    [[TMP29:%.*]] = zext i8 [[TMP28]] to i64
+; SSE2-NEXT:    [[TMP30:%.*]] = shl i64 [[TMP29]], 4
+; SSE2-NEXT:    [[TMP31:%.*]] = and i8 [[TMP5]], 7
+; SSE2-NEXT:    [[TMP32:%.*]] = zext i8 [[TMP31]] to i64
+; SSE2-NEXT:    [[TMP33:%.*]] = shl i64 [[TMP32]], 5
+; SSE2-NEXT:    [[OP_RDX3:%.*]] = or i64 [[TMP30]], [[TMP33]]
+; SSE2-NEXT:    [[TMP34:%.*]] = and i8 [[TMP6]], 3
+; SSE2-NEXT:    [[TMP35:%.*]] = zext i8 [[TMP34]] to i64
+; SSE2-NEXT:    [[TMP36:%.*]] = shl i64 [[TMP35]], 6
+; SSE2-NEXT:    [[TMP37:%.*]] = and i8 [[TMP7]], 1
+; SSE2-NEXT:    [[TMP38:%.*]] = zext i8 [[TMP37]] to i64
+; SSE2-NEXT:    [[TMP39:%.*]] = shl i64 [[TMP38]], 7
+; SSE2-NEXT:    [[OP_RDX4:%.*]] = or i64 [[TMP36]], [[TMP39]]
+; SSE2-NEXT:    [[TMP40:%.*]] = zext i8 [[TMP9]] to i64
+; SSE2-NEXT:    [[TMP41:%.*]] = shl i64 [[TMP40]], 9
+; SSE2-NEXT:    [[TMP42:%.*]] = zext i8 [[TMP10]] to i64
+; SSE2-NEXT:    [[TMP43:%.*]] = shl i64 [[TMP42]], 10
+; SSE2-NEXT:    [[OP_RDX5:%.*]] = or i64 [[TMP41]], [[TMP43]]
+; SSE2-NEXT:    [[OP_RDX6:%.*]] = or i64 [[OP_RDX]], [[OP_RDX1]]
+; SSE2-NEXT:    [[OP_RDX7:%.*]] = or i64 [[OP_RDX2]], [[OP_RDX3]]
+; SSE2-NEXT:    [[OP_RDX8:%.*]] = or i64 [[OP_RDX4]], [[OP_RDX5]]
+; SSE2-NEXT:    [[OP_RDX9:%.*]] = or i64 [[OP_RDX6]], [[OP_RDX7]]
+; SSE2-NEXT:    [[TMP44:%.*]] = zext i8 [[TMP12]] to i64
+; SSE2-NEXT:    [[TMP45:%.*]] = shl i64 [[TMP44]], 15
+; SSE2-NEXT:    [[OP_RDX10:%.*]] = or i64 [[OP_RDX8]], [[TMP45]]
+; SSE2-NEXT:    [[OP_RDX11:%.*]] = or i64 [[OP_RDX9]], [[OP_RDX10]]
+; SSE2-NEXT:    ret i64 [[OP_RDX11]]
+;
+; SSE4-LABEL: @bitmask_16xi8_shl(
+; SSE4-NEXT:  entry:
+; SSE4-NEXT:    [[TMP0:%.*]] = load <8 x i8>, ptr [[SRC:%.*]], align 1
+; SSE4-NEXT:    [[ARRAYIDX_8:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 8
+; SSE4-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX_8]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE4-NEXT:    [[ARRAYIDX_9:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 9
+; SSE4-NEXT:    [[TMP2:%.*]] = load <4 x i8>, ptr [[ARRAYIDX_9]], align 1
+; SSE4-NEXT:    [[ARRAYIDX_13:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 13
+; SSE4-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX_13]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE4-NEXT:    [[ARRAYIDX_14:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 14
+; SSE4-NEXT:    [[TMP4:%.*]] = load i8, ptr [[ARRAYIDX_14]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE4-NEXT:    [[ARRAYIDX_15:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC]], i64 15
+; SSE4-NEXT:    [[TMP5:%.*]] = load i8, ptr [[ARRAYIDX_15]], align 1, !range [[RNG0]], !noundef [[META1]]
+; SSE4-NEXT:    [[TMP6:%.*]] = and <8 x i8> [[TMP0]], <i8 -1, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1>
+; SSE4-NEXT:    [[TMP7:%.*]] = zext <8 x i8> [[TMP6]] to <8 x i64>
+; SSE4-NEXT:    [[TMP8:%.*]] = shl <8 x i64> [[TMP7]], <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
+; SSE4-NEXT:    [[TMP9:%.*]] = zext <4 x i8> [[TMP2]] to <4 x i64>
+; SSE4-NEXT:    [[TMP10:%.*]] = shl <4 x i64> [[TMP9]], <i64 9, i64 10, i64 11, i64 12>
+; SSE4-NEXT:    [[TMP11:%.*]] = shufflevector <8 x i64> [[TMP8]], <8 x i64> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+; SSE4-NEXT:    [[RDX_OP:%.*]] = or <4 x i64> [[TMP11]], [[TMP10]]
+; SSE4-NEXT:    [[TMP12:%.*]] = shufflevector <4 x i64> [[RDX_OP]], <4 x i64> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
+; SSE4-NEXT:    [[TMP13:%.*]] = shufflevector <8 x i64> [[TMP8]], <8 x i64> [[TMP12]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7>
+; SSE4-NEXT:    [[TMP14:%.*]] = call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> [[TMP13]])
+; SSE4-NEXT:    [[TMP15:%.*]] = zext i8 [[TMP1]] to i64
+; SSE4-NEXT:    [[TMP16:%.*]] = shl i64 [[TMP15]], 8
+; SSE4-NEXT:    [[OP_RDX:%.*]] = or i64 [[TMP14]], [[TMP16]]
+; SSE4-NEXT:    [[TMP17:%.*]] = zext i8 [[TMP3]] to i64
+; SSE4-NEXT:    [[TMP18:%.*]] = shl i64 [[TMP17]], 13
+; SSE4-NEXT:    [[TMP19:%.*]] = zext i8 [[TMP4]] to i64
+; SSE4-NEXT:    [[TMP20:%.*]] = shl i64 [[TMP19]], 14
+; SSE4-NEXT:    [[OP_RDX1:%.*]] = or i64 [[TMP18]], [[TMP20]]
+; SSE4-NEXT:    [[OP_RDX2:%.*]] = or i64 [[OP_RDX]], [[OP_RDX1]]
+; SSE4-NEXT:    [[TMP21:%.*]] = zext i8 [[TMP5]] to i64
+; SSE4-NEXT:    [[TMP22:%.*]] = shl i64 [[TMP21]], 15
+; SSE4-NEXT:    [[OP_RDX3:%.*]] = or i64 [[OP_RDX2]], [[TMP22]]
+; SSE4-NEXT:    ret i64 [[OP_RDX3]]
+;
+; AVX-LABEL: @bitmask_16xi8_shl(
+; AVX-NEXT:  entry:
+; AVX-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[SRC:%.*]], align 1
+; AVX-NEXT:    [[TMP1:%.*]] = and <16 x i8> [[TMP0]], <i8 -1, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+; AVX-NEXT:    [[TMP2:%.*]] = zext <16 x i8> [[TMP1]] to <16 x i64>
+; AVX-NEXT:    [[TMP4:%.*]] = shl <16 x i64> [[TMP2]], <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
+; AVX-NEXT:    [[TMP3:%.*]] = call i64 @llvm.vector.reduce.or.v16i64(<16 x i64> [[TMP4]])
+; AVX-NEXT:    ret i64 [[TMP3]]
+;
+; AVX512-LABEL: @bitmask_16xi8_shl(
+; AVX512-NEXT:  entry:
+; AVX512-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[SRC:%.*]], align 1
+; AVX512-NEXT:    [[TMP1:%.*]] = and <16 x i8> [[TMP0]], <i8 -1, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+; AVX512-NEXT:    [[TMP2:%.*]] = zext <16 x i8> [[TMP1]] to <16 x i64>
+; AVX512-NEXT:    [[TMP4:%.*]] = shl <16 x i64> [[TMP2]], <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
+; AVX512-NEXT:    [[TMP3:%.*]] = call i64 @llvm.vector.reduce.or.v16i64(<16 x i64> [[TMP4]])
+; AVX512-NEXT:    ret i64 [[TMP3]]
+;
+entry:
+  %0 = load i8, ptr %src, align 1, !range !0, !noundef !1
+  %arrayidx.1 = getelementptr inbounds nuw i8, ptr %src, i64 1
+  %1 = load i8, ptr %arrayidx.1, align 1, !range !0, !noundef !1
+  %2 = shl nuw nsw i8 %1, 1
+  %mask.1.18 = or disjoint i8 %2, %0
+  %arrayidx.2 = getelementptr inbounds nuw i8, ptr %src, i64 2
+  %3 = load i8, ptr %arrayidx.2, align 1, !range !0, !noundef !1
+  %4 = shl nuw nsw i8 %3, 2
+  %mask.1.29 = or disjoint i8 %4, %mask.1.18
+  %arrayidx.3 = getelementptr inbounds nuw i8, ptr %src, i64 3
+  %5 = load i8, ptr %arrayidx.3, align 1, !range !0, !noundef !1
+  %6 = shl nuw nsw i8 %5, 3
+  %mask.1.310 = or disjoint i8 %6, %mask.1.29
+  %arrayidx.4 = getelementptr inbounds nuw i8, ptr %src, i64 4
+  %7 = load i8, ptr %arrayidx.4, align 1, !range !0, !noundef !1
+  %8 = shl nuw nsw i8 %7, 4
+  %mask.1.411 = or disjoint i8 %8, %mask.1.310
+  %arrayidx.5 = getelementptr inbounds nuw i8, ptr %src, i64 5
+  %9 = load i8, ptr %arrayidx.5, align 1, !range !0, !noundef !1
+  %10 = shl nuw nsw i8 %9, 5
+  %mask.1.512 = or i8 %10, %mask.1.411
+  %arrayidx.6 = getelementptr inbounds nuw i8, ptr %src, i64 6
+  %11 = load i8, ptr %arrayidx.6, align 1, !range !0, !noundef !1
+  %12 = shl nuw nsw i8 %11, 6
+  %mask.1.613 = or i8 %12, %mask.1.512
+  %arrayidx.7 = getelementptr inbounds nuw i8, ptr %src, i64 7
+  %13 = load i8, ptr %arrayidx.7, align 1, !range !0, !noundef !1
+  %14 = shl nuw i8 %13, 7
+  %mask.1.714 = or i8 %14, %mask.1.613
+  %mask.1.7 = zext i8 %mask.1.714 to i64
+  %arrayidx.8 = getelementptr inbounds nuw i8, ptr %src, i64 8
+  %15 = load i8, ptr %arrayidx.8, align 1, !range !0, !noundef !1
+  %16 = zext nneg i8 %15 to i64
+  %or.8 = shl nuw nsw i64 %16, 8
+  %mask.1.8 = or disjoint i64 %or.8, %mask.1.7
+  %arrayidx.9 = getelementptr inbounds nuw i8, ptr %src, i64 9
+  %17 = load i8, ptr %arrayidx.9, align 1, !range !0, !noundef !1
+  %18 = zext nneg i8 %17 to i64
+  %or.9 = shl nuw nsw i64 %18, 9
+  %mask.1.9 = or disjoint i64 %or.9, %mask.1.8
+  %arrayidx.10 = getelementptr inbounds nuw i8, ptr %src, i64 10
+  %19 = load i8, ptr %arrayidx.10, align 1, !range !0, !noundef !1
+  %20 = zext nneg i8 %19 to i64
+  %or.10 = shl nuw nsw i64 %20, 10
+  %mask.1.10 = or disjoint i64 %or.10, %mask.1.9
+  %arrayidx.11 = getelementptr inbounds nuw i8, ptr %src, i64 11
+  %21 = load i8, ptr %arrayidx.11, align 1, !range !0, !noundef !1
+  %22 = zext nneg i8 %21 to i64
+  %or.11 = shl nuw nsw i64 %22, 11
+  %mask.1.11 = or i64 %or.11, %mask.1.10
+  %arrayidx.12 = getelementptr inbounds nuw i8, ptr %src, i64 12
+  %23 = load i8, ptr %arrayidx.12, align 1, !range !0, !noundef !1
+  %24 = zext nneg i8 %23 to i64
+  %or.12 = shl nuw nsw i64 %24, 12
+  %mask.1.12 = or i64 %or.12, %mask.1.11
+  %arrayidx.13 = getelementptr inbounds nuw i8, ptr %src, i64 13
+  %25 = load i8, ptr %arrayidx.13, align 1, !range !0, !noundef !1
+  %26 = zext nneg i8 %25 to i64
+  %or.13 = shl nuw nsw i64 %26, 13
+  %mask.1.13 = or i64 %or.13, %mask.1.12
+  %arrayidx.14 = getelementptr inbounds nuw i8, ptr %src, i64 14
+  %27 = load i8, ptr %arrayidx.14, align 1, !range !0, !noundef !1
+  %28 = zext nneg i8 %27 to i64
+  %or.14 = shl nuw nsw i64 %28, 14
+  %mask.1.14 = or i64 %or.14, %mask.1.13
+  %arrayidx.15 = getelementptr inbounds nuw i8, ptr %src, i64 15
+  %29 = load i8, ptr %arrayidx.15, align 1, !range !0, !noundef !1
+  %30 = zext nneg i8 %29 to i64
+  %or.15 = shl nuw nsw i64 %30, 15
+  %mask.1.15 = or i64 %or.15, %mask.1.14
+  ret i64 %mask.1.15
+}
+
+!0 = !{i8 0, i8 2}
+!1 = !{}

``````````

</details>


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


More information about the llvm-commits mailing list