[llvm] [VectorCombine] Fold insertelement chains of scalar parts to a bitcast and shuffle (PR #226224)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 4 05:56:36 PDT 2026
ParkHanbum wrote:
Sorry, this is maybe unrelated to the patch, but this time it seems to be an issue with x86 bitcast cost modeling.
```
"$i24_review_dir/latest/opt" -S -passes=vector-combine \
-mtriple=x86_64 -mattr=+avx2 -debug-only=vector-combine \
"$i24_review_dir/i24-repro.ll" \
-o /private/tmp/i24-after.ll
b2sy at mac build % cat "$i24_review_dir/i24-repro.ll"
target datalayout = "e-p:64:64"
define <2 x i24> @reverse_i24(i48 %x) {
%s0 = lshr i48 %x, 24
%t0 = trunc i48 %s0 to i24
%v0 = insertelement <2 x i24> poison, i24 %t0, i64 0
%t1 = trunc i48 %x to i24
%v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
ret <2 x i24> %v1
}
define <2 x i24> @identity_i24(i48 %x) {
%t0 = trunc i48 %x to i24
%v0 = insertelement <2 x i24> poison, i24 %t0, i64 0
%s1 = lshr i48 %x, 24
%t1 = trunc i48 %s1 to i24
%v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
ret <2 x i24> %v1
}
b2sy at mac build % "$i24_review_dir/latest/opt" -S -passes=vector-combine \
-mtriple=x86_64 -mattr=+avx2 -debug-only=vector-combine \
"$i24_review_dir/i24-repro.ll"
VECTORCOMBINE on reverse_i24
VC: Visiting: %s0 = lshr i48 %x, 24
VC: Visiting: %t0 = trunc i48 %s0 to i24
VC: Visiting: %v0 = insertelement <2 x i24> poison, i24 %t0, i64 0
VC: Visiting: %t1 = trunc i48 %x to i24
VC: Visiting: %v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
Found an insertelement chain of scalar parts: %v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
OldCost: 3 vs NewCost: 2
VC: Replacing: %v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
With: %2 = shufflevector <2 x i24> %1, <2 x i24> poison, <2 x i32> <i32 1, i32 0>
VC: Erasing: %2 = insertelement <2 x i24> %v0, i24 %t1, i64 1
VC: Erased: %v0 = insertelement <2 x i24> poison, i24 %t0, i64 0
VC: Erased: %t0 = trunc i48 %s0 to i24
VC: Erased: %s0 = lshr i48 %x, 24
VC: Erased: %t1 = trunc i48 %x to i24
VC: Visiting: ret <2 x i24> %v1
VC: Visiting: %v1 = shufflevector <2 x i24> %1, <2 x i24> poison, <2 x i32> <i32 1, i32 0>
VC: Visiting: ret <2 x i24> %v1
VECTORCOMBINE on identity_i24
VC: Visiting: %t0 = trunc i48 %x to i24
VC: Visiting: %v0 = insertelement <2 x i24> poison, i24 %t0, i64 0
VC: Visiting: %s1 = lshr i48 %x, 24
VC: Visiting: %t1 = trunc i48 %s1 to i24
VC: Visiting: %v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
Found an insertelement chain of scalar parts: %v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
OldCost: 3 vs NewCost: 1
VC: Replacing: %v1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
With: %1 = bitcast i48 %x to <2 x i24>
VC: Erasing: %1 = insertelement <2 x i24> %v0, i24 %t1, i64 1
VC: Erased: %v0 = insertelement <2 x i24> poison, i24 %t0, i64 0
VC: Erased: %t0 = trunc i48 %x to i24
VC: Erased: %t1 = trunc i48 %s1 to i24
VC: Erased: %s1 = lshr i48 %x, 24
VC: Visiting: ret <2 x i24> %v1
VC: Visiting: %v1 = bitcast i48 %x to <2 x i24>
VC: Visiting: ret <2 x i24> %v1
; ModuleID = '/Users/b2sy/work/llvm/review/pr226224-final-20261004/i24-repro.ll'
source_filename = "/Users/b2sy/work/llvm/review/pr226224-final-20261004/i24-repro.ll"
target datalayout = "e-p:64:64"
target triple = "x86_64"
define <2 x i24> @reverse_i24(i48 %x) #0 {
%1 = bitcast i48 %x to <2 x i24>
%v1 = shufflevector <2 x i24> %1, <2 x i24> poison, <2 x i32> <i32 1, i32 0>
ret <2 x i24> %v1
}
define <2 x i24> @identity_i24(i48 %x) #0 {
%v1 = bitcast i48 %x to <2 x i24>
ret <2 x i24> %v1
}
attributes #0 = { "target-features"="+avx2" }
```
As you can see, the cost model estimates the `i24` bitcast transformation to be cheaper.
```
b2sy at mac build % "$i24_llvm_bin/llc" -mtriple=x86_64 -mattr=+avx2 \
/private/tmp/i24-before.ll -o /private/tmp/i24-before.s
"$i24_llvm_bin/llc" -mtriple=x86_64 -mattr=+avx2 \
/private/tmp/i24-after.ll -o /private/tmp/i24-after.s
```
However, the generated code does not.
```
b2sy at mac build % diff -y /private/tmp/i24-before.s /private/tmp/i24-after.s
.att_syntax .att_syntax
.file "i24-repro.ll" .file "i24-repro.ll"
.text .text
.globl reverse_i24 # -- Begin fu .globl reverse_i24 # -- Begin fu
.prefalign 4, .Lfunc_end0, nop .prefalign 4, .Lfunc_end0, nop
.type reverse_i24, at function .type reverse_i24, at function
reverse_i24: # @reverse_i24 reverse_i24: # @reverse_i24
.cfi_startproc .cfi_startproc
# %bb.0: # %bb.0:
vmovq %rdi, %xmm0 | movl %edi, -8(%rsp)
shrq $24, %rdi | movzwl %di, %eax
andl $16777215, %edi # imm = 0xFFF | shrq $32, %rdi
vmovd %edi, %xmm1 | movw %di, -4(%rsp)
> movzwl -5(%rsp), %ecx
> movzbl -3(%rsp), %edx
> shlq $16, %rdx
> orq %rcx, %rdx
> movzbl -6(%rsp), %ecx
> shlq $16, %rcx
> orq %rax, %rcx
> vmovq %rcx, %xmm0
> vmovq %rdx, %xmm1
vpunpcklqdq %xmm0, %xmm1, %xmm0 # xmm0 = xmm1 vpunpcklqdq %xmm0, %xmm1, %xmm0 # xmm0 = xmm1
retq retq
.Lfunc_end0: .Lfunc_end0:
.size reverse_i24, .Lfunc_end0-reverse_i24 .size reverse_i24, .Lfunc_end0-reverse_i24
.cfi_endproc .cfi_endproc
# -- End function # -- End function
.globl identity_i24 # -- Begin fu .globl identity_i24 # -- Begin fu
.prefalign 4, .Lfunc_end1, nop .prefalign 4, .Lfunc_end1, nop
.type identity_i24, at function .type identity_i24, at function
identity_i24: # @identity_i24 identity_i24: # @identity_i24
.cfi_startproc .cfi_startproc
# %bb.0: # %bb.0:
vmovq %rdi, %xmm0 | movl %edi, -8(%rsp)
shrq $24, %rdi | movzwl %di, %eax
andl $16777215, %edi # imm = 0xFFF | shrq $32, %rdi
vmovd %edi, %xmm1 | movw %di, -4(%rsp)
> movzbl -6(%rsp), %ecx
> shlq $16, %rcx
> orq %rax, %rcx
> vmovq %rcx, %xmm0
> movzwl -5(%rsp), %eax
> movzbl -3(%rsp), %ecx
> shlq $16, %rcx
> orq %rax, %rcx
> vmovq %rcx, %xmm1
vpunpcklqdq %xmm1, %xmm0, %xmm0 # xmm0 = xmm0 vpunpcklqdq %xmm1, %xmm0, %xmm0 # xmm0 = xmm0
retq retq
.Lfunc_end1: .Lfunc_end1:
.size identity_i24, .Lfunc_end1-identity_i24 .size identity_i24, .Lfunc_end1-identity_i24
.cfi_endproc .cfi_endproc
# -- End function # -- End function
.section ".note.GNU-stack","", at progbits .section ".note.GNU-stack","", at progbits
```
cc @RKSimon
Other than that, I don’t have anything else to review.
https://github.com/llvm/llvm-project/pull/226224
More information about the llvm-commits
mailing list