[llvm-branch-commits] [llvm] release/23.x: [SPARC] Lower dynamic v2i32 vector extracts on 32-bit SPARC (#222348) (PR #232099)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Oct 14 14:49:19 PDT 2026
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/232099
Backport fc264e6ba8b4c65abb716882826e3adccc3bbf1a
Requested by: @brad0
>From a8aa34d108928df0addd5ef2aa7c24f414d7544f Mon Sep 17 00:00:00 2001
From: Daniel Cederman <cederman at gaisler.com>
Date: Tue, 13 Oct 2026 17:22:57 +0200
Subject: [PATCH] [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)
---
llvm/lib/Target/Sparc/SparcISelLowering.cpp | 24 +++++++++++++++-
llvm/test/CodeGen/SPARC/vector-extract-elt.ll | 28 ++++++++++++++++---
2 files changed, 47 insertions(+), 5 deletions(-)
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