[llvm-branch-commits] [llvm] 6c85996 - [SPARC] Lower dynamic v2i32 vector extracts on 32-bit SPARC (#222348)
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Oct 18 11:36:16 PDT 2026
Author: Daniel Cederman
Date: 2026-10-18T20:36:04+02:00
New Revision: 6c859967be702731f26470b36eee9a3f164d8a68
URL: https://github.com/llvm/llvm-project/commit/6c859967be702731f26470b36eee9a3f164d8a68
DIFF: https://github.com/llvm/llvm-project/commit/6c859967be702731f26470b36eee9a3f164d8a68.diff
LOG: [SPARC] Lower dynamic v2i32 vector extracts on 32-bit SPARC (#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
(cherry picked from commit fc264e6ba8b4c65abb716882826e3adccc3bbf1a)
Added:
Modified:
llvm/lib/Target/Sparc/SparcISelLowering.cpp
llvm/test/CodeGen/SPARC/vector-extract-elt.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index c45babaec5dc2e..829e31f5143000 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1681,7 +1681,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
@@ -3163,6 +3163,26 @@ 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;
+
+ EVT VT = Op.getValueType();
+ EVT IdxVT = Idx.getValueType();
+ SDValue Elt0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Vec,
+ DAG.getConstant(0, DL, IdxVT));
+ SDValue Elt1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Vec,
+ DAG.getConstant(1, DL, IdxVT));
+ return DAG.getSelectCC(DL, Idx, DAG.getConstant(0, DL, IdxVT), Elt0, Elt1,
+ ISD::SETEQ);
+}
+
SDValue SparcTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
SelectionDAG &DAG) const {
unsigned IntNo = Op.getConstantOperandVal(0);
@@ -3233,6 +3253,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 ef2a4323accce4..fd2d6ce95b149d 100644
--- a/llvm/test/CodeGen/SPARC/vector-extract-elt.ll
+++ b/llvm/test/CodeGen/SPARC/vector-extract-elt.ll
@@ -1,13 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc -mtriple=sparc < %s | FileCheck %s
; If computeKnownSignBits (in SelectionDAG) can do a simple
; look-thru for extractelement then we know that the add will yield a
; non-negative result.
-define i1 @test1(ptr %in) {
-; CHECK-LABEL: ! %bb.0:
-; CHECK-NEXT: retl
-; CHECK-NEXT: mov %g0, %o0
+define i1 @test1(ptr %in) nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ! %bb.0:
+; CHECK-NEXT: retl
+; CHECK-NEXT: mov %g0, %o0
%vec2 = load <4 x i16>, ptr %in, align 1
%vec3 = lshr <4 x i16> %vec2, <i16 2, i16 2, i16 2, i16 2>
%vec4 = sext <4 x i16> %vec3 to <4 x i32>
@@ -17,3 +19,21 @@ define i1 @test1(ptr %in) {
%bool = icmp slt i32 %sum, 0
ret i1 %bool
}
+
+; v2i32 is legal on 32-bit SPARC to represent 64-bit integer register pairs.
+; Make sure a dynamic extract does not reach instruction selection, which
+; only handles constant indices.
+define i32 @extract_v2i32(<2 x i32> %v, i32 %idx) nounwind {
+; CHECK-LABEL: extract_v2i32:
+; CHECK: ! %bb.0:
+; CHECK-NEXT: cmp %o2, 0
+; CHECK-NEXT: be .LBB1_2
+; CHECK-NEXT: nop
+; CHECK-NEXT: ! %bb.1:
+; CHECK-NEXT: mov %o1, %o0
+; CHECK-NEXT: .LBB1_2:
+; CHECK-NEXT: retl
+; CHECK-NEXT: nop
+ %elt = extractelement <2 x i32> %v, i32 %idx
+ ret i32 %elt
+}
More information about the llvm-branch-commits
mailing list