Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -17576,6 +17576,30 @@ } } + // uzp1(trunc v1, trunc v2) => trunc(uzp1 v1, v2) + if (Op0.getOpcode() == ISD::BITCAST && Op1.getOpcode() == ISD::BITCAST && + Op0.getOperand(0).getOpcode() == ISD::TRUNCATE && + Op1.getOperand(0).getOpcode() == ISD::TRUNCATE) { + + SDValue OrigOp0 = Op0.getOperand(0).getOperand(0); + SDValue OrigOp1 = Op1.getOperand(0).getOperand(0); + EVT CastResultType = MVT::Other; + + if (OrigOp0.getValueType().getSimpleVT().SimpleTy == MVT::v2i64) + CastResultType = MVT::v4i32; + + if (CastResultType != MVT::Other) { + SDValue BitCastResult0 = + DAG.getNode(ISD::BITCAST, DL, CastResultType, OrigOp0); + SDValue BitCastResult1 = + DAG.getNode(ISD::BITCAST, DL, CastResultType, OrigOp1); + + SDValue ConcatResult = DAG.getNode(AArch64ISD::UZP1, DL, CastResultType, + BitCastResult0, BitCastResult1); + return DAG.getNode(ISD::TRUNCATE, DL, ResVT, ConcatResult); + } + } + return SDValue(); } Index: llvm/test/CodeGen/AArch64/pr57502.ll =================================================================== --- llvm/test/CodeGen/AArch64/pr57502.ll +++ llvm/test/CodeGen/AArch64/pr57502.ll @@ -6,9 +6,8 @@ define void @trunc(ptr %addr, <4 x i64> %input) { ; CHECK-LABEL: trunc: ; CHECK: // %bb.0: -; CHECK-NEXT: xtn v1.2s, v1.2d -; CHECK-NEXT: xtn v0.2s, v0.2d -; CHECK-NEXT: uzp1 v0.4h, v0.4h, v1.4h +; CHECK-NEXT: uzp1 v0.4s, v0.4s, v1.4s +; CHECK-NEXT: xtn v0.4h, v0.4s ; CHECK-NEXT: addv h0, v0.4h ; CHECK-NEXT: fmov w8, s0 ; CHECK-NEXT: strb w8, [x0]