Skip to content

Commit 80e0d41

Browse files
authored
[LoongArch] Custom legalizing build_vector with same constant elements (llvm#150584)
1 parent 4510466 commit 80e0d41

File tree

3 files changed

+135
-191
lines changed

3 files changed

+135
-191
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,13 +2385,6 @@ SDValue LoongArchTargetLowering::lowerBF16_TO_FP(SDValue Op,
23852385
return Res;
23862386
}
23872387

2388-
static bool isConstantBUILD_VECTOR(const BuildVectorSDNode *Op) {
2389-
for (unsigned i = 0; i < Op->getNumOperands(); ++i)
2390-
if (isIntOrFPConstant(Op->getOperand(i)))
2391-
return true;
2392-
return false;
2393-
}
2394-
23952388
// Lower BUILD_VECTOR as broadcast load (if possible).
23962389
// For example:
23972390
// %a = load i8, ptr %ptr
@@ -2441,10 +2434,14 @@ SDValue LoongArchTargetLowering::lowerBUILD_VECTOR(SDValue Op,
24412434
SelectionDAG &DAG) const {
24422435
BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op);
24432436
EVT ResTy = Op->getValueType(0);
2437+
unsigned NumElts = ResTy.getVectorNumElements();
24442438
SDLoc DL(Op);
24452439
APInt SplatValue, SplatUndef;
24462440
unsigned SplatBitSize;
24472441
bool HasAnyUndefs;
2442+
bool IsConstant = false;
2443+
bool UseSameConstant = true;
2444+
SDValue ConstantValue;
24482445
bool Is128Vec = ResTy.is128BitVector();
24492446
bool Is256Vec = ResTy.is256BitVector();
24502447

@@ -2495,13 +2492,35 @@ SDValue LoongArchTargetLowering::lowerBUILD_VECTOR(SDValue Op,
24952492
if (DAG.isSplatValue(Op, /*AllowUndefs=*/false))
24962493
return Op;
24972494

2498-
if (!isConstantBUILD_VECTOR(Node)) {
2495+
for (unsigned i = 0; i < NumElts; ++i) {
2496+
SDValue Opi = Node->getOperand(i);
2497+
if (isIntOrFPConstant(Opi)) {
2498+
IsConstant = true;
2499+
if (!ConstantValue.getNode())
2500+
ConstantValue = Opi;
2501+
else if (ConstantValue != Opi)
2502+
UseSameConstant = false;
2503+
}
2504+
}
2505+
2506+
// If the type of BUILD_VECTOR is v2f64, custom legalizing it has no benefits.
2507+
if (IsConstant && UseSameConstant && ResTy != MVT::v2f64) {
2508+
SDValue Result = DAG.getSplatBuildVector(ResTy, DL, ConstantValue);
2509+
for (unsigned i = 0; i < NumElts; ++i) {
2510+
SDValue Opi = Node->getOperand(i);
2511+
if (!isIntOrFPConstant(Opi))
2512+
Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ResTy, Result, Opi,
2513+
DAG.getConstant(i, DL, Subtarget.getGRLenVT()));
2514+
}
2515+
return Result;
2516+
}
2517+
2518+
if (!IsConstant) {
24992519
// Use INSERT_VECTOR_ELT operations rather than expand to stores.
25002520
// The resulting code is the same length as the expansion, but it doesn't
25012521
// use memory operations.
25022522
assert(ResTy.isVector());
25032523

2504-
unsigned NumElts = ResTy.getVectorNumElements();
25052524
SDValue Op0 = Node->getOperand(0);
25062525
SDValue Vector = DAG.getUNDEF(ResTy);
25072526

llvm/test/CodeGen/LoongArch/lasx/build-vector.ll

Lines changed: 79 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -436,49 +436,47 @@ entry:
436436
define void @buildvector_v32i8_with_constant(ptr %dst, i8 %a0, i8 %a1, i8 %a2, i8 %a5, i8 %a8, i8 %a9, i8 %a15, i8 %a17, i8 %a18, i8 %a20, i8 %a22, i8 %a23, i8 %a27, i8 %a28, i8 %a31) nounwind {
437437
; CHECK-LABEL: buildvector_v32i8_with_constant:
438438
; CHECK: # %bb.0: # %entry
439-
; CHECK-NEXT: addi.d $sp, $sp, -96
440-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
441-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
442-
; CHECK-NEXT: addi.d $fp, $sp, 96
443-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
444-
; CHECK-NEXT: ld.b $t0, $fp, 0
445-
; CHECK-NEXT: ld.b $t1, $fp, 8
446-
; CHECK-NEXT: ld.b $t2, $fp, 16
447-
; CHECK-NEXT: ld.b $t3, $fp, 24
448-
; CHECK-NEXT: ld.b $t4, $fp, 56
449-
; CHECK-NEXT: ld.b $t5, $fp, 32
450-
; CHECK-NEXT: ld.b $t6, $fp, 48
451-
; CHECK-NEXT: ld.b $t7, $fp, 40
452-
; CHECK-NEXT: st.b $t4, $sp, 63
453-
; CHECK-NEXT: st.b $zero, $sp, 61
454-
; CHECK-NEXT: st.b $t6, $sp, 60
455-
; CHECK-NEXT: st.b $t7, $sp, 59
456-
; CHECK-NEXT: st.b $zero, $sp, 56
457-
; CHECK-NEXT: st.b $t5, $sp, 55
458-
; CHECK-NEXT: st.b $t3, $sp, 54
459-
; CHECK-NEXT: st.b $zero, $sp, 53
460-
; CHECK-NEXT: st.b $t2, $sp, 52
461-
; CHECK-NEXT: st.b $zero, $sp, 51
462-
; CHECK-NEXT: st.b $t1, $sp, 50
463-
; CHECK-NEXT: st.b $t0, $sp, 49
464-
; CHECK-NEXT: st.b $zero, $sp, 48
465-
; CHECK-NEXT: st.b $a7, $sp, 47
466-
; CHECK-NEXT: st.h $zero, $sp, 44
467-
; CHECK-NEXT: st.b $zero, $sp, 42
468-
; CHECK-NEXT: st.b $a6, $sp, 41
469-
; CHECK-NEXT: st.b $a5, $sp, 40
470-
; CHECK-NEXT: st.b $zero, $sp, 39
471-
; CHECK-NEXT: st.b $a4, $sp, 37
472-
; CHECK-NEXT: st.h $zero, $sp, 35
473-
; CHECK-NEXT: st.b $a3, $sp, 34
474-
; CHECK-NEXT: st.b $a2, $sp, 33
475-
; CHECK-NEXT: st.b $a1, $sp, 32
476-
; CHECK-NEXT: xvld $xr0, $sp, 32
477-
; CHECK-NEXT: xvst $xr0, $a0, 0
478-
; CHECK-NEXT: addi.d $sp, $fp, -96
479-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
480-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
481-
; CHECK-NEXT: addi.d $sp, $sp, 96
439+
; CHECK-NEXT: ld.b $t0, $sp, 56
440+
; CHECK-NEXT: ld.b $t1, $sp, 48
441+
; CHECK-NEXT: ld.b $t2, $sp, 40
442+
; CHECK-NEXT: ld.b $t3, $sp, 32
443+
; CHECK-NEXT: ld.b $t4, $sp, 24
444+
; CHECK-NEXT: ld.b $t5, $sp, 16
445+
; CHECK-NEXT: ld.b $t6, $sp, 8
446+
; CHECK-NEXT: ld.b $t7, $sp, 0
447+
; CHECK-NEXT: xvrepli.b $xr0, 0
448+
; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 0
449+
; CHECK-NEXT: vinsgr2vr.b $vr0, $a2, 1
450+
; CHECK-NEXT: vinsgr2vr.b $vr0, $a3, 2
451+
; CHECK-NEXT: vinsgr2vr.b $vr0, $a4, 5
452+
; CHECK-NEXT: vinsgr2vr.b $vr0, $a5, 8
453+
; CHECK-NEXT: vinsgr2vr.b $vr0, $a6, 9
454+
; CHECK-NEXT: vinsgr2vr.b $vr0, $a7, 15
455+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
456+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t7, 1
457+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
458+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
459+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t6, 2
460+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
461+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
462+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t5, 4
463+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
464+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
465+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t4, 6
466+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
467+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
468+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t3, 7
469+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
470+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
471+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t2, 11
472+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
473+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
474+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t1, 12
475+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
476+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
477+
; CHECK-NEXT: vinsgr2vr.b $vr1, $t0, 15
478+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
479+
; CHECK-NEXT: xvst $xr0, $a0, 0
482480
; CHECK-NEXT: ret
483481
entry:
484482
%ins0 = insertelement <32 x i8> undef, i8 %a0, i32 0
@@ -624,32 +622,19 @@ entry:
624622
define void @buildvector_v16i16_with_constant(ptr %dst, i16 %a2, i16 %a3, i16 %a5, i16 %a6, i16 %a7, i16 %a12, i16 %a13) nounwind {
625623
; CHECK-LABEL: buildvector_v16i16_with_constant:
626624
; CHECK: # %bb.0: # %entry
627-
; CHECK-NEXT: addi.d $sp, $sp, -96
628-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
629-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
630-
; CHECK-NEXT: addi.d $fp, $sp, 96
631-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
632-
; CHECK-NEXT: st.h $a7, $sp, 58
633-
; CHECK-NEXT: st.h $a6, $sp, 56
634-
; CHECK-NEXT: st.h $a5, $sp, 46
635-
; CHECK-NEXT: st.h $a4, $sp, 44
636-
; CHECK-NEXT: st.h $a3, $sp, 42
637-
; CHECK-NEXT: ori $a3, $zero, 2
638-
; CHECK-NEXT: st.h $a3, $sp, 40
639-
; CHECK-NEXT: st.h $a2, $sp, 38
640-
; CHECK-NEXT: st.h $a1, $sp, 36
641-
; CHECK-NEXT: lu12i.w $a1, 32
642-
; CHECK-NEXT: ori $a1, $a1, 2
643-
; CHECK-NEXT: st.w $a1, $sp, 60
644-
; CHECK-NEXT: st.w $a1, $sp, 32
645-
; CHECK-NEXT: lu32i.d $a1, 131074
646-
; CHECK-NEXT: st.d $a1, $sp, 48
647-
; CHECK-NEXT: xvld $xr0, $sp, 32
648-
; CHECK-NEXT: xvst $xr0, $a0, 0
649-
; CHECK-NEXT: addi.d $sp, $fp, -96
650-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
651-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
652-
; CHECK-NEXT: addi.d $sp, $sp, 96
625+
; CHECK-NEXT: xvrepli.h $xr0, 2
626+
; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 2
627+
; CHECK-NEXT: vinsgr2vr.h $vr0, $a2, 3
628+
; CHECK-NEXT: vinsgr2vr.h $vr0, $a3, 5
629+
; CHECK-NEXT: vinsgr2vr.h $vr0, $a4, 6
630+
; CHECK-NEXT: vinsgr2vr.h $vr0, $a5, 7
631+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
632+
; CHECK-NEXT: vinsgr2vr.h $vr1, $a6, 4
633+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
634+
; CHECK-NEXT: xvpermi.d $xr1, $xr0, 14
635+
; CHECK-NEXT: vinsgr2vr.h $vr1, $a7, 5
636+
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
637+
; CHECK-NEXT: xvst $xr0, $a0, 0
653638
; CHECK-NEXT: ret
654639
entry:
655640
%ins0 = insertelement <16 x i16> undef, i16 2, i32 0
@@ -724,24 +709,12 @@ entry:
724709
define void @buildvector_v8i32_with_constant(ptr %dst, i32 %a2, i32 %a4, i32 %a5, i32 %a6) nounwind {
725710
; CHECK-LABEL: buildvector_v8i32_with_constant:
726711
; CHECK: # %bb.0: # %entry
727-
; CHECK-NEXT: addi.d $sp, $sp, -96
728-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
729-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
730-
; CHECK-NEXT: addi.d $fp, $sp, 96
731-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
732-
; CHECK-NEXT: st.w $zero, $sp, 60
733-
; CHECK-NEXT: st.w $a4, $sp, 56
734-
; CHECK-NEXT: st.w $a3, $sp, 52
735-
; CHECK-NEXT: st.w $a2, $sp, 48
736-
; CHECK-NEXT: st.w $zero, $sp, 44
737-
; CHECK-NEXT: st.w $a1, $sp, 40
738-
; CHECK-NEXT: st.d $zero, $sp, 32
739-
; CHECK-NEXT: xvld $xr0, $sp, 32
740-
; CHECK-NEXT: xvst $xr0, $a0, 0
741-
; CHECK-NEXT: addi.d $sp, $fp, -96
742-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
743-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
744-
; CHECK-NEXT: addi.d $sp, $sp, 96
712+
; CHECK-NEXT: xvrepli.b $xr0, 0
713+
; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 2
714+
; CHECK-NEXT: xvinsgr2vr.w $xr0, $a2, 4
715+
; CHECK-NEXT: xvinsgr2vr.w $xr0, $a3, 5
716+
; CHECK-NEXT: xvinsgr2vr.w $xr0, $a4, 6
717+
; CHECK-NEXT: xvst $xr0, $a0, 0
745718
; CHECK-NEXT: ret
746719
entry:
747720
%ins0 = insertelement <8 x i32> undef, i32 0, i32 0
@@ -793,21 +766,10 @@ entry:
793766
define void @buildvector_v4i64_with_constant(ptr %dst, i64 %a0, i64 %a2) nounwind {
794767
; CHECK-LABEL: buildvector_v4i64_with_constant:
795768
; CHECK: # %bb.0: # %entry
796-
; CHECK-NEXT: addi.d $sp, $sp, -96
797-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
798-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
799-
; CHECK-NEXT: addi.d $fp, $sp, 96
800-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
801-
; CHECK-NEXT: st.d $zero, $sp, 56
802-
; CHECK-NEXT: st.d $a2, $sp, 48
803-
; CHECK-NEXT: st.d $zero, $sp, 40
804-
; CHECK-NEXT: st.d $a1, $sp, 32
805-
; CHECK-NEXT: xvld $xr0, $sp, 32
769+
; CHECK-NEXT: xvrepli.b $xr0, 0
770+
; CHECK-NEXT: xvinsgr2vr.d $xr0, $a1, 0
771+
; CHECK-NEXT: xvinsgr2vr.d $xr0, $a2, 2
806772
; CHECK-NEXT: xvst $xr0, $a0, 0
807-
; CHECK-NEXT: addi.d $sp, $fp, -96
808-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
809-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
810-
; CHECK-NEXT: addi.d $sp, $sp, 96
811773
; CHECK-NEXT: ret
812774
entry:
813775
%ins0 = insertelement <4 x i64> undef, i64 %a0, i32 0
@@ -880,27 +842,17 @@ entry:
880842
define void @buildvector_v8f32_with_constant(ptr %dst, float %a1, float %a2, float %a5, float %a7) nounwind {
881843
; CHECK-LABEL: buildvector_v8f32_with_constant:
882844
; CHECK: # %bb.0: # %entry
883-
; CHECK-NEXT: addi.d $sp, $sp, -96
884-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
885-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
886-
; CHECK-NEXT: addi.d $fp, $sp, 96
887-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
888-
; CHECK-NEXT: fst.s $fa3, $sp, 60
889-
; CHECK-NEXT: fst.s $fa2, $sp, 52
890-
; CHECK-NEXT: fst.s $fa1, $sp, 40
891-
; CHECK-NEXT: fst.s $fa0, $sp, 36
892-
; CHECK-NEXT: vldi $vr0, -1280
893-
; CHECK-NEXT: fst.s $fa0, $sp, 56
845+
; CHECK-NEXT: # kill: def $f3 killed $f3 def $xr3
846+
; CHECK-NEXT: # kill: def $f2 killed $f2 def $xr2
847+
; CHECK-NEXT: # kill: def $f1 killed $f1 def $xr1
848+
; CHECK-NEXT: # kill: def $f0 killed $f0 def $xr0
894849
; CHECK-NEXT: lu12i.w $a1, 262144
895-
; CHECK-NEXT: lu52i.d $a1, $a1, 1024
896-
; CHECK-NEXT: st.d $a1, $sp, 44
897-
; CHECK-NEXT: fst.s $fa0, $sp, 32
898-
; CHECK-NEXT: xvld $xr0, $sp, 32
899-
; CHECK-NEXT: xvst $xr0, $a0, 0
900-
; CHECK-NEXT: addi.d $sp, $fp, -96
901-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
902-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
903-
; CHECK-NEXT: addi.d $sp, $sp, 96
850+
; CHECK-NEXT: xvreplgr2vr.w $xr4, $a1
851+
; CHECK-NEXT: xvinsve0.w $xr4, $xr0, 1
852+
; CHECK-NEXT: xvinsve0.w $xr4, $xr1, 2
853+
; CHECK-NEXT: xvinsve0.w $xr4, $xr2, 5
854+
; CHECK-NEXT: xvinsve0.w $xr4, $xr3, 7
855+
; CHECK-NEXT: xvst $xr4, $a0, 0
904856
; CHECK-NEXT: ret
905857
entry:
906858
%ins0 = insertelement <8 x float> undef, float 2.0, i32 0
@@ -956,21 +908,12 @@ entry:
956908
define void @buildvector_v4f64_with_constant(ptr %dst, double %a0, double %a3) nounwind {
957909
; CHECK-LABEL: buildvector_v4f64_with_constant:
958910
; CHECK: # %bb.0: # %entry
959-
; CHECK-NEXT: addi.d $sp, $sp, -96
960-
; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill
961-
; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill
962-
; CHECK-NEXT: addi.d $fp, $sp, 96
963-
; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0
964-
; CHECK-NEXT: fst.d $fa1, $sp, 56
965-
; CHECK-NEXT: vrepli.b $vr1, 0
966-
; CHECK-NEXT: vst $vr1, $sp, 40
967-
; CHECK-NEXT: fst.d $fa0, $sp, 32
968-
; CHECK-NEXT: xvld $xr0, $sp, 32
969-
; CHECK-NEXT: xvst $xr0, $a0, 0
970-
; CHECK-NEXT: addi.d $sp, $fp, -96
971-
; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload
972-
; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload
973-
; CHECK-NEXT: addi.d $sp, $sp, 96
911+
; CHECK-NEXT: # kill: def $f1_64 killed $f1_64 def $xr1
912+
; CHECK-NEXT: # kill: def $f0_64 killed $f0_64 def $xr0
913+
; CHECK-NEXT: xvrepli.b $xr2, 0
914+
; CHECK-NEXT: xvinsve0.d $xr2, $xr0, 0
915+
; CHECK-NEXT: xvinsve0.d $xr2, $xr1, 3
916+
; CHECK-NEXT: xvst $xr2, $a0, 0
974917
; CHECK-NEXT: ret
975918
entry:
976919
%ins0 = insertelement <4 x double> undef, double %a0, i32 0

0 commit comments

Comments
 (0)