[llvm] [SPARC] Lower dynamic v2i32 vector extracts on 32-bit SPARC (PR #222348)
Daniel Cederman via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 07:46:50 PDT 2026
https://github.com/doac created https://github.com/llvm/llvm-project/pull/222348
Lower dynamically indexed extracts after vector legalization so that instruction selection never receives a variable index.
Constant indexes use the existing TableGen patterns.
Fixes the following error:
LLVM ERROR: Cannot select: 0x5e7e87e5b590: i32 = extract_vector_elt 0x5e7e87e5b910, 0x5e7e87e5b0c0
0x5e7e87e5b910: v2i32 = BUILD_VECTOR 0x5e7e87e5af70, 0x5e7e87e5b6e0
0x5e7e87e5af70: i32,ch = CopyFromReg 0x5e7e87e24840, Register:i32 %0
0x5e7e87e5b750: i32 = Register %0
0x5e7e87e5b6e0: i32,ch = CopyFromReg 0x5e7e87e24840, Register:i32 %1
0x5e7e87e5b7c0: i32 = Register %1
0x5e7e87e5b0c0: i32,ch = CopyFromReg 0x5e7e87e24840, Register:i32 %2
0x5e7e87e5afe0: i32 = Register %2
In function: extract_v2i8
Assisted-by: Codex
>From fe3dcdaddcddbf831838f9985d4a83c08ca29775 Mon Sep 17 00:00:00 2001
From: Daniel Cederman <cederman at gaisler.com>
Date: Mon, 24 Aug 2026 19:39:07 +0200
Subject: [PATCH] [SPARC] Lower dynamic v2i32 vector extracts on 32-bit SPARC
Lower dynamically indexed extracts after vector legalization so that
instruction selection never receives a variable index.
Constant indexes use the existing TableGen patterns.
Fixes the following error:
LLVM ERROR: Cannot select: 0x5e7e87e5b590: i32 = extract_vector_elt 0x5e7e87e5b910, 0x5e7e87e5b0c0
0x5e7e87e5b910: v2i32 = BUILD_VECTOR 0x5e7e87e5af70, 0x5e7e87e5b6e0
0x5e7e87e5af70: i32,ch = CopyFromReg 0x5e7e87e24840, Register:i32 %0
0x5e7e87e5b750: i32 = Register %0
0x5e7e87e5b6e0: i32,ch = CopyFromReg 0x5e7e87e24840, Register:i32 %1
0x5e7e87e5b7c0: i32 = Register %1
0x5e7e87e5b0c0: i32,ch = CopyFromReg 0x5e7e87e24840, Register:i32 %2
0x5e7e87e5afe0: i32 = Register %2
In function: extract_v2i8
Assisted-by: Codex
---
llvm/lib/Target/Sparc/SparcISelLowering.cpp | 20 ++++++++++++++++++-
llvm/test/CodeGen/SPARC/vector-extract-elt.ll | 15 ++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 66638f599559a..a1e97fe9ba99f 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1687,7 +1687,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
// However, load and store *are* legal.
setOperationAction(ISD::LOAD, MVT::v2i32, Legal);
setOperationAction(ISD::STORE, MVT::v2i32, Legal);
- setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i32, Legal);
+ setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i32, Custom);
setOperationAction(ISD::BUILD_VECTOR, MVT::v2i32, Legal);
// And we need to promote i64 loads/stores into vector load/store
@@ -3169,6 +3169,22 @@ static SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) {
return Op;
}
+static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
+ SDLoc DL(Op);
+ SDValue Vec = Op.getOperand(0);
+ SDValue Idx = Op.getOperand(1);
+ assert(Vec.getSimpleValueType() == MVT::v2i32 && "Unexpected vector type");
+
+ // Constant indices are handled by the TableGen patterns.
+ if (isa<ConstantSDNode>(Idx))
+ return Op;
+
+ SDValue Even = DAG.getTargetExtractSubreg(SP::sub_even, DL, MVT::i32, Vec);
+ SDValue Odd = DAG.getTargetExtractSubreg(SP::sub_odd, DL, MVT::i32, Vec);
+ return DAG.getSelectCC(DL, Idx, DAG.getConstant(0, DL, Idx.getValueType()),
+ Even, Odd, ISD::SETEQ);
+}
+
SDValue SparcTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
SelectionDAG &DAG) const {
unsigned IntNo = Op.getConstantOperandVal(0);
@@ -3239,6 +3255,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::FP_ROUND: return LowerF128_FPROUND(Op, DAG, *this);
case ISD::ATOMIC_LOAD:
case ISD::ATOMIC_STORE: return LowerATOMIC_LOAD_STORE(Op, DAG);
+ case ISD::EXTRACT_VECTOR_ELT:
+ return LowerEXTRACT_VECTOR_ELT(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
}
}
diff --git a/llvm/test/CodeGen/SPARC/vector-extract-elt.ll b/llvm/test/CodeGen/SPARC/vector-extract-elt.ll
index ef2a4323accce..e238e7a8f20a6 100644
--- a/llvm/test/CodeGen/SPARC/vector-extract-elt.ll
+++ b/llvm/test/CodeGen/SPARC/vector-extract-elt.ll
@@ -17,3 +17,18 @@ define i1 @test1(ptr %in) {
%bool = icmp slt i32 %sum, 0
ret i1 %bool
}
+
+; A legal v2i32 is used internally to represent 64-bit integer register pairs.
+; Make sure a dynamic extract produced while legalizing a smaller vector does
+; not reach instruction selection, which only handles constant indices.
+define i8 @extract_v2i8(<2 x i8> %v, i32 %idx) {
+; CHECK-LABEL: extract_v2i8:
+; CHECK: cmp %o2, 0
+; CHECK: be
+; CHECK: mov %o0, %o2
+; CHECK: mov %o1, %o2
+; CHECK: retl
+; CHECK: mov %o2, %o0
+ %elt = extractelement <2 x i8> %v, i32 %idx
+ ret i8 %elt
+}
More information about the llvm-commits
mailing list