[llvm] 6117bdd - [DAGCombiner] Fix subvector extraction index for big-endian STLF (#180795)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 12 01:42:18 PST 2026
Author: 陈子昂
Date: 2026-02-12T17:42:13+08:00
New Revision: 6117bdd90324af22a920d56d673acff21342a1cb
URL: https://github.com/llvm/llvm-project/commit/6117bdd90324af22a920d56d673acff21342a1cb
DIFF: https://github.com/llvm/llvm-project/commit/6117bdd90324af22a920d56d673acff21342a1cb.diff
LOG: [DAGCombiner] Fix subvector extraction index for big-endian STLF (#180795)
This PR fixes a big-endian regression in `ForwardStoreValueToDirectLoad`
where the wrong subvector was being extracted. In big-endian, memory
offset 0 corresponds to the high bits, so the extraction index needs to
be adjusted.
As suggested by @KennethHilmersson, calculate the extraction index as
the difference between the number of elements in the intermediate vector
and the load vector when in big-endian mode.
Special thanks to Kenneth Hilmersson for providing the fix logic and the
ARM regression test.
https://github.com/llvm/llvm-project/pull/172523#issuecomment-3878065191
https://github.com/llvm/llvm-project/pull/172523#issuecomment-3879575092
Added:
llvm/test/CodeGen/ARM/stlf-vector-extract.ll
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/X86/avx512-shuffles/shuffle-chained-bf16.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index d61999f2ee0a2..65675036d1305 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -20831,11 +20831,22 @@ SDValue DAGCombiner::ForwardStoreValueToDirectLoad(LoadSDNode *LD) {
EVT InterVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
StMemSize.divideCoefficientBy(EltSize));
- if (!TLI.isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, InterVT))
+ if (!TLI.isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, LDMemType))
break;
+ // In case of big-endian the offset is normalized to zero, denoting
+ // the last bit. For big-endian we need to transform the extraction
+ // to the last sub-vector.
+ unsigned ExtIdx = 0;
+ if (DAG.getDataLayout().isBigEndian()) {
+ ExtIdx =
+ InterVT.getVectorNumElements() - LDMemType.getVectorNumElements();
+ }
+
+ if (!TLI.isExtractSubvectorCheap(LDMemType, InterVT, ExtIdx))
+ break;
Val = DAG.getExtractSubvector(SDLoc(LD), LDMemType,
- DAG.getBitcast(InterVT, Val), 0);
+ DAG.getBitcast(InterVT, Val), ExtIdx);
} else if (!STMemType.isVector() && !LDMemType.isVector() &&
STMemType.isInteger() && LDMemType.isInteger())
Val = DAG.getNode(ISD::TRUNCATE, SDLoc(LD), LDMemType, Val);
diff --git a/llvm/test/CodeGen/ARM/stlf-vector-extract.ll b/llvm/test/CodeGen/ARM/stlf-vector-extract.ll
new file mode 100644
index 0000000000000..8734d6f432e90
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/stlf-vector-extract.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=armeb-eabi -mattr=+v7,+neon | FileCheck %s --check-prefix=BE
+; RUN: llc < %s -mtriple=arm-eabi -mattr=+v7,+neon | FileCheck %s --check-prefix=LE
+
+define <2 x i32> @test_offset_load(ptr %p, <4 x i32> %v) {
+; BE-LABEL: test_offset_load:
+; BE: @ %bb.0:
+; BE-NEXT: vldr d17, [sp]
+; BE-NEXT: vmov r1, r12, d17
+; BE-NEXT: vmov d16, r3, r2
+; BE-NEXT: vst1.64 {d16, d17}, [r0:128]
+; BE-NEXT: mov r0, r12
+; BE-NEXT: bx lr
+;
+; LE-LABEL: test_offset_load:
+; LE: @ %bb.0:
+; LE-NEXT: vldr d17, [sp]
+; LE-NEXT: mov r1, #8
+; LE-NEXT: vmov d16, r2, r3
+; LE-NEXT: vst1.32 {d16, d17}, [r0:128], r1
+; LE-NEXT: vldr d16, [r0]
+; LE-NEXT: vmov r0, r1, d16
+; LE-NEXT: bx lr
+ store <4 x i32> %v, ptr %p, align 16
+ %p2 = getelementptr i8, ptr %p, i64 8
+ %res = load <2 x i32>, ptr %p2, align 8
+ ret <2 x i32> %res
+}
diff --git a/llvm/test/CodeGen/X86/avx512-shuffles/shuffle-chained-bf16.ll b/llvm/test/CodeGen/X86/avx512-shuffles/shuffle-chained-bf16.ll
index c7200850af699..f646f609d7e70 100644
--- a/llvm/test/CodeGen/X86/avx512-shuffles/shuffle-chained-bf16.ll
+++ b/llvm/test/CodeGen/X86/avx512-shuffles/shuffle-chained-bf16.ll
@@ -15,8 +15,7 @@ define <2 x bfloat> @shuffle_chained_v32bf16_v2bf16(<32 x bfloat> %a) {
; CHECK-NEXT: subq $128, %rsp
; CHECK-NEXT: vmovd {{.*#+}} xmm1 = [0,16,0,0,0,0,0,0]
; CHECK-NEXT: vpermw %zmm0, %zmm1, %zmm0
-; CHECK-NEXT: vmovdqa64 %zmm0, (%rsp)
-; CHECK-NEXT: vmovaps (%rsp), %xmm0
+; CHECK-NEXT: # kill: def $xmm0 killed $xmm0 killed $zmm0
; CHECK-NEXT: movq %rbp, %rsp
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
More information about the llvm-commits
mailing list