Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -1228,6 +1228,8 @@ setOperationAction(ISD::BITCAST, MVT::i8, Custom); setOperationAction(ISD::BITCAST, MVT::i16, Custom); + setOperationAction(ISD::BITCAST, MVT::v2i16, Custom); + setLoadExtAction(ISD::EXTLOAD, MVT::v4i16, MVT::v4i8, Custom); setLoadExtAction(ISD::SEXTLOAD, MVT::v4i16, MVT::v4i8, Custom); setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i16, MVT::v4i8, Custom); @@ -22887,6 +22889,13 @@ EVT VT = N->getValueType(0); EVT SrcVT = Op.getValueType(); + if (VT == MVT::v2i16 && SrcVT == MVT::i32) { + // Use SCALAR_TO_VECTOR for lane zero + Results.push_back( + DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, N->getValueType(0), Op)); + return; + } + if (VT.isScalableVector() && !isTypeLegal(VT) && isTypeLegal(SrcVT)) { assert(!VT.isFloatingPoint() && SrcVT.isFloatingPoint() && "Expected fp->int bitcast!"); Index: llvm/test/CodeGen/AArch64/neon-bitcast.ll =================================================================== --- llvm/test/CodeGen/AArch64/neon-bitcast.ll +++ llvm/test/CodeGen/AArch64/neon-bitcast.ll @@ -572,3 +572,11 @@ ret <16 x i8> %val } +define <2 x i16> @bitcast_from_int(i32 %word) { +; CHECK-LABEL: bitcast_from_int: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov s0, w0 +; CHECK-NEXT: ret + %ret = bitcast i32 %word to <2 x i16> + ret <2 x i16> %ret +}