Skip to content

Commit de080ca

Browse files
committed
deal with other lasx types
1 parent 644129f commit de080ca

File tree

2 files changed

+89
-65
lines changed

2 files changed

+89
-65
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,21 +2614,71 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
26142614
SDValue Idx = Op->getOperand(1);
26152615
unsigned NumElts = VecTy.getVectorNumElements();
26162616
SDLoc DL(Op);
2617+
MVT GRLenVT = Subtarget.getGRLenVT();
26172618

26182619
assert(VecTy.is256BitVector() && "Unexpected EXTRACT_VECTOR_ELT vector type");
26192620

26202621
if (isa<ConstantSDNode>(Idx) && Idx->getAsZExtVal() < NumElts)
26212622
return Op;
26222623

2623-
// TODO: Deal with other legal 256-bits vector types?
2624-
if (!isa<ConstantSDNode>(Idx) &&
2625-
(VecTy == MVT::v8i32 || VecTy == MVT::v8f32)) {
2626-
SDValue SplatIdx = DAG.getSplatBuildVector(MVT::v8i32, DL, Idx);
2627-
SDValue SplatValue =
2628-
DAG.getNode(LoongArchISD::XVPERM, DL, VecTy, Vec, SplatIdx);
2629-
2630-
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, SplatValue,
2631-
DAG.getConstant(0, DL, Subtarget.getGRLenVT()));
2624+
if (!isa<ConstantSDNode>(Idx)) {
2625+
switch (VecTy.getSimpleVT().SimpleTy) {
2626+
default:
2627+
llvm_unreachable("Unexpected type");
2628+
case MVT::v32i8:
2629+
case MVT::v16i16: {
2630+
SDValue NewVec = DAG.getBitcast(MVT::v8i32, Vec);
2631+
SDValue NewIdx = DAG.getNode(
2632+
LoongArchISD::BSTRPICK, DL, GRLenVT, Idx,
2633+
DAG.getConstant(31, DL, GRLenVT),
2634+
DAG.getConstant(((VecTy == MVT::v32i8) ? 2 : 1), DL, GRLenVT));
2635+
SDValue SplatIdx = DAG.getSplatBuildVector(MVT::v8i32, DL, NewIdx);
2636+
SDValue SplatValue =
2637+
DAG.getNode(LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdx);
2638+
SDValue SplatVec = DAG.getBitcast(VecTy, SplatValue);
2639+
2640+
SDValue LocalIdx = DAG.getNode(
2641+
ISD::AND, DL, GRLenVT, Idx,
2642+
DAG.getConstant(((VecTy == MVT::v32i8) ? 3 : 1), DL, GRLenVT));
2643+
SDValue ExtractVec =
2644+
DAG.getNode(LoongArchISD::VREPLVE, DL, VecTy, SplatVec, LocalIdx);
2645+
2646+
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, ExtractVec,
2647+
DAG.getConstant(0, DL, GRLenVT));
2648+
}
2649+
case MVT::v8i32:
2650+
case MVT::v8f32: {
2651+
SDValue SplatIdx = DAG.getSplatBuildVector(MVT::v8i32, DL, Idx);
2652+
SDValue SplatValue =
2653+
DAG.getNode(LoongArchISD::XVPERM, DL, VecTy, Vec, SplatIdx);
2654+
2655+
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, SplatValue,
2656+
DAG.getConstant(0, DL, GRLenVT));
2657+
}
2658+
case MVT::v4i64:
2659+
case MVT::v4f64: {
2660+
SDValue NewVec = DAG.getBitcast(MVT::v8i32, Vec);
2661+
SDValue SplatIdx = DAG.getSplatBuildVector(MVT::v8i32, DL, Idx);
2662+
SDValue SplatIdxLo =
2663+
DAG.getNode(LoongArchISD::VSLLI, DL, MVT::v8i32, SplatIdx,
2664+
DAG.getConstant(1, DL, GRLenVT));
2665+
SDValue SplatIdxHi =
2666+
DAG.getNode(ISD::ADD, DL, MVT::v8i32, SplatIdxLo,
2667+
DAG.getSplatBuildVector(MVT::v8i32, DL,
2668+
DAG.getConstant(1, DL, GRLenVT)));
2669+
2670+
SDValue SplatVecLo =
2671+
DAG.getNode(LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdxLo);
2672+
SDValue SplatVecHi =
2673+
DAG.getNode(LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdxHi);
2674+
SDValue SplatValue = DAG.getNode(LoongArchISD::VILVL, DL, MVT::v8i32,
2675+
SplatVecHi, SplatVecLo);
2676+
SDValue ExtractVec = DAG.getBitcast(VecTy, SplatValue);
2677+
2678+
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, ExtractVec,
2679+
DAG.getConstant(0, DL, GRLenVT));
2680+
}
2681+
}
26322682
}
26332683

26342684
return SDValue();

llvm/test/CodeGen/LoongArch/lasx/ir-instruction/extractelement.ll

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,14 @@ define void @extract_4xdouble(ptr %src, ptr %dst) nounwind {
7676
define void @extract_32xi8_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
7777
; CHECK-LABEL: extract_32xi8_idx:
7878
; CHECK: # %bb.0:
79-
; CHECK-NEXT: addi.d $sp, $sp, -96
80-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
81-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
82-
; CHECK-NEXT: addi.d $fp, $sp, 96
83-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
8479
; CHECK-NEXT: xvld $xr0, $a0, 0
85-
; CHECK-NEXT: xvst $xr0, $sp, 32
86-
; CHECK-NEXT: addi.d $a0, $sp, 32
87-
; CHECK-NEXT: bstrins.d $a0, $a2, 4, 0
88-
; CHECK-NEXT: ld.b $a0, $a0, 0
89-
; CHECK-NEXT: st.b $a0, $a1, 0
90-
; CHECK-NEXT: addi.d $sp, $fp, -96
91-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
92-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
93-
; CHECK-NEXT: addi.d $sp, $sp, 96
80+
; CHECK-NEXT: bstrpick.d $a0, $a2, 31, 0
81+
; CHECK-NEXT: bstrpick.d $a0, $a0, 31, 2
82+
; CHECK-NEXT: xvreplgr2vr.w $xr1, $a0
83+
; CHECK-NEXT: xvperm.w $xr0, $xr0, $xr1
84+
; CHECK-NEXT: andi $a0, $a2, 3
85+
; CHECK-NEXT: xvreplve.b $xr0, $xr0, $a0
86+
; CHECK-NEXT: xvstelm.b $xr0, $a1, 0, 0
9487
; CHECK-NEXT: ret
9588
%v = load volatile <32 x i8>, ptr %src
9689
%e = extractelement <32 x i8> %v, i32 %idx
@@ -101,21 +94,14 @@ define void @extract_32xi8_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
10194
define void @extract_16xi16_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
10295
; CHECK-LABEL: extract_16xi16_idx:
10396
; CHECK: # %bb.0:
104-
; CHECK-NEXT: addi.d $sp, $sp, -96
105-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
106-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
107-
; CHECK-NEXT: addi.d $fp, $sp, 96
108-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
10997
; CHECK-NEXT: xvld $xr0, $a0, 0
110-
; CHECK-NEXT: xvst $xr0, $sp, 32
111-
; CHECK-NEXT: addi.d $a0, $sp, 32
112-
; CHECK-NEXT: bstrins.d $a0, $a2, 4, 1
113-
; CHECK-NEXT: ld.h $a0, $a0, 0
114-
; CHECK-NEXT: st.h $a0, $a1, 0
115-
; CHECK-NEXT: addi.d $sp, $fp, -96
116-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
117-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
118-
; CHECK-NEXT: addi.d $sp, $sp, 96
98+
; CHECK-NEXT: bstrpick.d $a0, $a2, 31, 0
99+
; CHECK-NEXT: bstrpick.d $a0, $a0, 31, 1
100+
; CHECK-NEXT: xvreplgr2vr.w $xr1, $a0
101+
; CHECK-NEXT: xvperm.w $xr0, $xr0, $xr1
102+
; CHECK-NEXT: andi $a0, $a2, 1
103+
; CHECK-NEXT: xvreplve.h $xr0, $xr0, $a0
104+
; CHECK-NEXT: xvstelm.h $xr0, $a1, 0, 0
119105
; CHECK-NEXT: ret
120106
%v = load volatile <16 x i16>, ptr %src
121107
%e = extractelement <16 x i16> %v, i32 %idx
@@ -141,21 +127,15 @@ define void @extract_8xi32_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
141127
define void @extract_4xi64_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
142128
; CHECK-LABEL: extract_4xi64_idx:
143129
; CHECK: # %bb.0:
144-
; CHECK-NEXT: addi.d $sp, $sp, -96
145-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
146-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
147-
; CHECK-NEXT: addi.d $fp, $sp, 96
148-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
149130
; CHECK-NEXT: xvld $xr0, $a0, 0
150-
; CHECK-NEXT: xvst $xr0, $sp, 32
151-
; CHECK-NEXT: addi.d $a0, $sp, 32
152-
; CHECK-NEXT: bstrins.d $a0, $a2, 4, 3
153-
; CHECK-NEXT: ld.d $a0, $a0, 0
154-
; CHECK-NEXT: st.d $a0, $a1, 0
155-
; CHECK-NEXT: addi.d $sp, $fp, -96
156-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
157-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
158-
; CHECK-NEXT: addi.d $sp, $sp, 96
131+
; CHECK-NEXT: bstrpick.d $a0, $a2, 31, 0
132+
; CHECK-NEXT: xvreplgr2vr.w $xr1, $a0
133+
; CHECK-NEXT: xvslli.w $xr1, $xr1, 1
134+
; CHECK-NEXT: xvperm.w $xr2, $xr0, $xr1
135+
; CHECK-NEXT: xvaddi.wu $xr1, $xr1, 1
136+
; CHECK-NEXT: xvperm.w $xr0, $xr0, $xr1
137+
; CHECK-NEXT: xvilvl.w $xr0, $xr0, $xr2
138+
; CHECK-NEXT: xvstelm.d $xr0, $a1, 0, 0
159139
; CHECK-NEXT: ret
160140
%v = load volatile <4 x i64>, ptr %src
161141
%e = extractelement <4 x i64> %v, i32 %idx
@@ -181,21 +161,15 @@ define void @extract_8xfloat_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
181161
define void @extract_4xdouble_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
182162
; CHECK-LABEL: extract_4xdouble_idx:
183163
; CHECK: # %bb.0:
184-
; CHECK-NEXT: addi.d $sp, $sp, -96
185-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
186-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
187-
; CHECK-NEXT: addi.d $fp, $sp, 96
188-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
189164
; CHECK-NEXT: xvld $xr0, $a0, 0
190-
; CHECK-NEXT: xvst $xr0, $sp, 32
191-
; CHECK-NEXT: addi.d $a0, $sp, 32
192-
; CHECK-NEXT: bstrins.d $a0, $a2, 4, 3
193-
; CHECK-NEXT: fld.d $fa0, $a0, 0
194-
; CHECK-NEXT: fst.d $fa0, $a1, 0
195-
; CHECK-NEXT: addi.d $sp, $fp, -96
196-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
197-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
198-
; CHECK-NEXT: addi.d $sp, $sp, 96
165+
; CHECK-NEXT: bstrpick.d $a0, $a2, 31, 0
166+
; CHECK-NEXT: xvreplgr2vr.w $xr1, $a0
167+
; CHECK-NEXT: xvslli.w $xr1, $xr1, 1
168+
; CHECK-NEXT: xvperm.w $xr2, $xr0, $xr1
169+
; CHECK-NEXT: xvaddi.wu $xr1, $xr1, 1
170+
; CHECK-NEXT: xvperm.w $xr0, $xr0, $xr1
171+
; CHECK-NEXT: xvilvl.w $xr0, $xr0, $xr2
172+
; CHECK-NEXT: xvstelm.d $xr0, $a1, 0, 0
199173
; CHECK-NEXT: ret
200174
%v = load volatile <4 x double>, ptr %src
201175
%e = extractelement <4 x double> %v, i32 %idx

0 commit comments

Comments
 (0)