[llvm] [Hexagon] Use word splats for repeated HVX build-vector words (PR #204808)

Ikhlas Ajbar via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 1 21:59:23 PDT 2026


================
@@ -0,0 +1,159 @@
+; RUN: llc -mtriple=hexagon < %s | FileCheck %s
+
+target triple = "hexagon"
+
+; buildHvxVectorReg packs i8 elements into i32 words before initializing an
+; HVX vector from the most frequent word. That initialization must use a word
+; splat even though the final vector type is i8; a byte splat would broadcast
+; only the low byte of %x.
+define void @splat_i32_word_into_i8_vector(ptr %out, i32 %x, i8 %y) #0 {
+; CHECK-LABEL: splat_i32_word_into_i8_vector:
+; CHECK: v{{[0-9]+}} = vsplat(r{{[0-9]+}})
+; CHECK-NOT: .b = vsplat
+; CHECK: vmem
+entry:
+  %x0 = trunc i32 %x to i8
+  %s1 = lshr i32 %x, 8
+  %x1 = trunc i32 %s1 to i8
+  %s2 = lshr i32 %x, 16
+  %x2 = trunc i32 %s2 to i8
+  %s3 = lshr i32 %x, 24
+  %x3 = trunc i32 %s3 to i8
+
+  %v00 = insertelement <64 x i8> undef, i8 %x0, i32 0
+  %v01 = insertelement <64 x i8> %v00, i8 %x1, i32 1
+  %v02 = insertelement <64 x i8> %v01, i8 %x2, i32 2
+  %v03 = insertelement <64 x i8> %v02, i8 %x3, i32 3
+  %v04 = insertelement <64 x i8> %v03, i8 %x0, i32 4
+  %v05 = insertelement <64 x i8> %v04, i8 %x1, i32 5
+  %v06 = insertelement <64 x i8> %v05, i8 %x2, i32 6
+  %v07 = insertelement <64 x i8> %v06, i8 %x3, i32 7
+  %v08 = insertelement <64 x i8> %v07, i8 %x0, i32 8
+  %v09 = insertelement <64 x i8> %v08, i8 %x1, i32 9
+  %v10 = insertelement <64 x i8> %v09, i8 %x2, i32 10
+  %v11 = insertelement <64 x i8> %v10, i8 %x3, i32 11
+  %v12 = insertelement <64 x i8> %v11, i8 %x0, i32 12
+  %v13 = insertelement <64 x i8> %v12, i8 %x1, i32 13
+  %v14 = insertelement <64 x i8> %v13, i8 %x2, i32 14
+  %v15 = insertelement <64 x i8> %v14, i8 %x3, i32 15
+  %v16 = insertelement <64 x i8> %v15, i8 %x0, i32 16
+  %v17 = insertelement <64 x i8> %v16, i8 %x1, i32 17
+  %v18 = insertelement <64 x i8> %v17, i8 %x2, i32 18
+  %v19 = insertelement <64 x i8> %v18, i8 %x3, i32 19
+  %v20 = insertelement <64 x i8> %v19, i8 %x0, i32 20
+  %v21 = insertelement <64 x i8> %v20, i8 %x1, i32 21
+  %v22 = insertelement <64 x i8> %v21, i8 %x2, i32 22
+  %v23 = insertelement <64 x i8> %v22, i8 %x3, i32 23
+  %v24 = insertelement <64 x i8> %v23, i8 %x0, i32 24
+  %v25 = insertelement <64 x i8> %v24, i8 %x1, i32 25
+  %v26 = insertelement <64 x i8> %v25, i8 %x2, i32 26
+  %v27 = insertelement <64 x i8> %v26, i8 %x3, i32 27
+  %v28 = insertelement <64 x i8> %v27, i8 %x0, i32 28
+  %v29 = insertelement <64 x i8> %v28, i8 %x1, i32 29
+  %v30 = insertelement <64 x i8> %v29, i8 %x2, i32 30
+  %v31 = insertelement <64 x i8> %v30, i8 %x3, i32 31
+  %v32 = insertelement <64 x i8> %v31, i8 %y, i32 32
+  %v33 = insertelement <64 x i8> %v32, i8 %x1, i32 33
+  %v34 = insertelement <64 x i8> %v33, i8 %x2, i32 34
+  %v35 = insertelement <64 x i8> %v34, i8 %x3, i32 35
+  %v36 = insertelement <64 x i8> %v35, i8 %x0, i32 36
+  %v37 = insertelement <64 x i8> %v36, i8 %y, i32 37
+  %v38 = insertelement <64 x i8> %v37, i8 %x2, i32 38
+  %v39 = insertelement <64 x i8> %v38, i8 %x3, i32 39
+  %v40 = insertelement <64 x i8> %v39, i8 %x0, i32 40
+  %v41 = insertelement <64 x i8> %v40, i8 %x1, i32 41
+  %v42 = insertelement <64 x i8> %v41, i8 %y, i32 42
+  %v43 = insertelement <64 x i8> %v42, i8 %x3, i32 43
+  %v44 = insertelement <64 x i8> %v43, i8 %x0, i32 44
+  %v45 = insertelement <64 x i8> %v44, i8 %x1, i32 45
+  %v46 = insertelement <64 x i8> %v45, i8 %x2, i32 46
+  %v47 = insertelement <64 x i8> %v46, i8 %y, i32 47
+  %v48 = insertelement <64 x i8> %v47, i8 %x0, i32 48
+  %v49 = insertelement <64 x i8> %v48, i8 %x1, i32 49
+  %v50 = insertelement <64 x i8> %v49, i8 %x2, i32 50
+  %v51 = insertelement <64 x i8> %v50, i8 %x3, i32 51
+  %v52 = insertelement <64 x i8> %v51, i8 %x0, i32 52
+  %v53 = insertelement <64 x i8> %v52, i8 %x1, i32 53
+  %v54 = insertelement <64 x i8> %v53, i8 %x2, i32 54
+  %v55 = insertelement <64 x i8> %v54, i8 %x3, i32 55
+  %v56 = insertelement <64 x i8> %v55, i8 %x0, i32 56
+  %v57 = insertelement <64 x i8> %v56, i8 %x1, i32 57
+  %v58 = insertelement <64 x i8> %v57, i8 %x2, i32 58
+  %v59 = insertelement <64 x i8> %v58, i8 %x3, i32 59
+  %v60 = insertelement <64 x i8> %v59, i8 %x0, i32 60
+  %v61 = insertelement <64 x i8> %v60, i8 %x1, i32 61
+  %v62 = insertelement <64 x i8> %v61, i8 %x2, i32 62
+  %v63 = insertelement <64 x i8> %v62, i8 %x3, i32 63
+  store <64 x i8> %v63, ptr %out, align 64
+  ret void
+}
+
+define void @splat_i8_into_i8_vector(ptr %out, i8 %x) #0 {
+; CHECK-LABEL: splat_i8_into_i8_vector:
+; CHECK: v{{[0-9]+}}.b = vsplat(r{{[0-9]+}})
+; CHECK: vmem
+entry:
+  %v0 = insertelement <64 x i8> undef, i8 %x, i32 0
+  %v1 = shufflevector <64 x i8> %v0, <64 x i8> undef, <64 x i32> zeroinitializer
+  store <64 x i8> %v1, ptr %out, align 64
+  ret void
+}
+
+; The same word-splat requirement applies when the final vector type is
+; i16 and the repeated value is a packed i32 containing two halfwords.
+define void @splat_i32_word_into_i16_vector(ptr %out, i32 %x, i16 %y) #0 {
+; CHECK-LABEL: splat_i32_word_into_i16_vector:
+; CHECK: v{{[0-9]+}} = vsplat(r{{[0-9]+}})
+; CHECK-NOT: .h = vsplat
+; CHECK: vmem
+entry:
+  %x0 = trunc i32 %x to i16
+  %s1 = lshr i32 %x, 16
+  %x1 = trunc i32 %s1 to i16
+  %v0 = insertelement <32 x i16> undef, i16 %x0, i32 0
+  %v1 = insertelement <32 x i16> %v0, i16 %x1, i32 1
+  %v2 = insertelement <32 x i16> %v1, i16 %x0, i32 2
+  %v3 = insertelement <32 x i16> %v2, i16 %x1, i32 3
+  %v4 = insertelement <32 x i16> %v3, i16 %x0, i32 4
+  %v5 = insertelement <32 x i16> %v4, i16 %x1, i32 5
+  %v6 = insertelement <32 x i16> %v5, i16 %x0, i32 6
+  %v7 = insertelement <32 x i16> %v6, i16 %x1, i32 7
+  %v8 = insertelement <32 x i16> %v7, i16 %x0, i32 8
+  %v9 = insertelement <32 x i16> %v8, i16 %x1, i32 9
+  %v10 = insertelement <32 x i16> %v9, i16 %x0, i32 10
+  %v11 = insertelement <32 x i16> %v10, i16 %x1, i32 11
+  %v12 = insertelement <32 x i16> %v11, i16 %x0, i32 12
+  %v13 = insertelement <32 x i16> %v12, i16 %x1, i32 13
+  %v14 = insertelement <32 x i16> %v13, i16 %x0, i32 14
+  %v15 = insertelement <32 x i16> %v14, i16 %x1, i32 15
+  %v16 = insertelement <32 x i16> %v15, i16 %y, i32 16
+  %v17 = insertelement <32 x i16> %v16, i16 %x1, i32 17
+  %v18 = insertelement <32 x i16> %v17, i16 %x0, i32 18
+  %v19 = insertelement <32 x i16> %v18, i16 %x1, i32 19
+  %v20 = insertelement <32 x i16> %v19, i16 %x0, i32 20
+  %v21 = insertelement <32 x i16> %v20, i16 %y, i32 21
+  %v22 = insertelement <32 x i16> %v21, i16 %x0, i32 22
+  %v23 = insertelement <32 x i16> %v22, i16 %x1, i32 23
+  %v24 = insertelement <32 x i16> %v23, i16 %x0, i32 24
+  %v25 = insertelement <32 x i16> %v24, i16 %x1, i32 25
+  %v26 = insertelement <32 x i16> %v25, i16 %y, i32 26
+  %v27 = insertelement <32 x i16> %v26, i16 %x1, i32 27
+  %v28 = insertelement <32 x i16> %v27, i16 %x0, i32 28
+  %v29 = insertelement <32 x i16> %v28, i16 %x1, i32 29
+  %v30 = insertelement <32 x i16> %v29, i16 %x0, i32 30
+  %v31 = insertelement <32 x i16> %v30, i16 %y, i32 31
+  store <32 x i16> %v31, ptr %out, align 64
+  ret void
+}
+
+define void @splat_i16_into_i16_vector(ptr %out, i16 %x) #0 {
+; CHECK-LABEL: splat_i16_into_i16_vector:
+; CHECK: v{{[0-9]+}}.h = vsplat(r{{[0-9]+}})
+; CHECK: vmem
+entry:
+  %v0 = insertelement <32 x i16> undef, i16 %x, i32 0
+  %v1 = shufflevector <32 x i16> %v0, <32 x i16> undef, <32 x i32> zeroinitializer
+  store <32 x i16> %v1, ptr %out, align 64
+  ret void
+}
+attributes #0 = { nounwind "target-cpu"="hexagonv65" "target-features"="+hvxv65,+hvx-length64b" }
----------------
iajbar wrote:

Please use "target-cpu"="hexagonv75" "target-features"="+hvxv75,+hvx-length128b"

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


More information about the llvm-commits mailing list