@@ -246,7 +246,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
246
246
// FIXME: For BUILD_VECTOR, it is temporarily set to `Legal` here, and it
247
247
// will be `Custom` handled in the future.
248
248
setOperationAction (ISD::BUILD_VECTOR, VT, Legal);
249
- setOperationAction (ISD::INSERT_VECTOR_ELT, VT, Legal );
249
+ setOperationAction (ISD::INSERT_VECTOR_ELT, VT, Custom );
250
250
setOperationAction (ISD::EXTRACT_VECTOR_ELT, VT, Legal);
251
251
}
252
252
for (MVT VT : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64}) {
@@ -276,7 +276,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
276
276
277
277
// FIXME: Same as above.
278
278
setOperationAction (ISD::BUILD_VECTOR, VT, Legal);
279
- setOperationAction (ISD::INSERT_VECTOR_ELT, VT, Legal );
279
+ setOperationAction (ISD::INSERT_VECTOR_ELT, VT, Custom );
280
280
setOperationAction (ISD::EXTRACT_VECTOR_ELT, VT, Legal);
281
281
}
282
282
for (MVT VT : {MVT::v4i64, MVT::v8i32, MVT::v16i16, MVT::v32i8}) {
@@ -380,10 +380,20 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
380
380
return lowerRETURNADDR (Op, DAG);
381
381
case ISD::WRITE_REGISTER:
382
382
return lowerWRITE_REGISTER (Op, DAG);
383
+ case ISD::INSERT_VECTOR_ELT:
384
+ return lowerINSERT_VECTOR_ELT (Op, DAG);
383
385
}
384
386
return SDValue ();
385
387
}
386
388
389
+ SDValue
390
+ LoongArchTargetLowering::lowerINSERT_VECTOR_ELT (SDValue Op,
391
+ SelectionDAG &DAG) const {
392
+ if (isa<ConstantSDNode>(Op->getOperand (2 )))
393
+ return Op;
394
+ return SDValue ();
395
+ }
396
+
387
397
SDValue LoongArchTargetLowering::lowerATOMIC_FENCE (SDValue Op,
388
398
SelectionDAG &DAG) const {
389
399
SDLoc DL (Op);
@@ -3067,6 +3077,71 @@ emitVecCondBranchPseudo(MachineInstr &MI, MachineBasicBlock *BB,
3067
3077
return SinkBB;
3068
3078
}
3069
3079
3080
+ static MachineBasicBlock *
3081
+ emitPseudoXVINSGR2VR (MachineInstr &MI, MachineBasicBlock *BB,
3082
+ const LoongArchSubtarget &Subtarget) {
3083
+ unsigned InsOp;
3084
+ unsigned HalfSize;
3085
+ switch (MI.getOpcode ()) {
3086
+ default :
3087
+ llvm_unreachable (" Unexpected opcode" );
3088
+ case LoongArch::PseudoXVINSGR2VR_B:
3089
+ HalfSize = 16 ;
3090
+ InsOp = LoongArch::VINSGR2VR_B;
3091
+ break ;
3092
+ case LoongArch::PseudoXVINSGR2VR_H:
3093
+ HalfSize = 8 ;
3094
+ InsOp = LoongArch::VINSGR2VR_H;
3095
+ break ;
3096
+ }
3097
+ const TargetInstrInfo *TII = Subtarget.getInstrInfo ();
3098
+ const TargetRegisterClass *RC = &LoongArch::LASX256RegClass;
3099
+ const TargetRegisterClass *SubRC = &LoongArch::LSX128RegClass;
3100
+ DebugLoc DL = MI.getDebugLoc ();
3101
+ MachineRegisterInfo &MRI = BB->getParent ()->getRegInfo ();
3102
+ // XDst = vector_insert XSrc, Elt, Idx
3103
+ Register XDst = MI.getOperand (0 ).getReg ();
3104
+ Register XSrc = MI.getOperand (1 ).getReg ();
3105
+ Register Elt = MI.getOperand (2 ).getReg ();
3106
+ unsigned Idx = MI.getOperand (3 ).getImm ();
3107
+
3108
+ Register ScratchReg1 = XSrc;
3109
+ if (Idx >= HalfSize) {
3110
+ ScratchReg1 = MRI.createVirtualRegister (RC);
3111
+ BuildMI (*BB, MI, DL, TII->get (LoongArch::XVPERMI_Q), ScratchReg1)
3112
+ .addReg (XSrc)
3113
+ .addReg (XSrc)
3114
+ .addImm (1 );
3115
+ }
3116
+
3117
+ Register ScratchSubReg1 = MRI.createVirtualRegister (SubRC);
3118
+ Register ScratchSubReg2 = MRI.createVirtualRegister (SubRC);
3119
+ BuildMI (*BB, MI, DL, TII->get (LoongArch::COPY), ScratchSubReg1)
3120
+ .addReg (ScratchReg1, 0 , LoongArch::sub_128);
3121
+ BuildMI (*BB, MI, DL, TII->get (InsOp), ScratchSubReg2)
3122
+ .addReg (ScratchSubReg1)
3123
+ .addReg (Elt)
3124
+ .addImm (Idx >= HalfSize ? Idx - HalfSize : Idx);
3125
+
3126
+ Register ScratchReg2 = XDst;
3127
+ if (Idx >= HalfSize)
3128
+ ScratchReg2 = MRI.createVirtualRegister (RC);
3129
+
3130
+ BuildMI (*BB, MI, DL, TII->get (LoongArch::SUBREG_TO_REG), ScratchReg2)
3131
+ .addImm (0 )
3132
+ .addReg (ScratchSubReg2)
3133
+ .addImm (LoongArch::sub_128);
3134
+
3135
+ if (Idx >= HalfSize)
3136
+ BuildMI (*BB, MI, DL, TII->get (LoongArch::XVPERMI_Q), XDst)
3137
+ .addReg (XSrc)
3138
+ .addReg (ScratchReg2)
3139
+ .addImm (2 );
3140
+
3141
+ MI.eraseFromParent ();
3142
+ return BB;
3143
+ }
3144
+
3070
3145
MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter (
3071
3146
MachineInstr &MI, MachineBasicBlock *BB) const {
3072
3147
const TargetInstrInfo *TII = Subtarget.getInstrInfo ();
@@ -3122,6 +3197,9 @@ MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter(
3122
3197
case LoongArch::PseudoXVBNZ_W:
3123
3198
case LoongArch::PseudoXVBNZ_D:
3124
3199
return emitVecCondBranchPseudo (MI, BB, Subtarget);
3200
+ case LoongArch::PseudoXVINSGR2VR_B:
3201
+ case LoongArch::PseudoXVINSGR2VR_H:
3202
+ return emitPseudoXVINSGR2VR (MI, BB, Subtarget);
3125
3203
}
3126
3204
}
3127
3205
0 commit comments