Index: llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -755,11 +755,16 @@ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); SDValue ExtPassThru = GetPromotedInteger(N->getPassThru()); + ISD::LoadExtType ExtType = N->getExtensionType(); + if (ExtType == ISD::NON_EXTLOAD) + ExtType = ISD::EXTLOAD; + SDLoc dl(N); SDValue Res = DAG.getMaskedLoad(NVT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), N->getMask(), ExtPassThru, N->getMemoryVT(), N->getMemOperand(), - N->getAddressingMode(), ISD::EXTLOAD); + N->getAddressingMode(), ExtType, + N->isExpandingLoad()); // Legalize the chain result - switch anything that used the old chain to // use the new one. ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); Index: llvm/test/CodeGen/AArch64/sve-masked-ldst-nonext.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-masked-ldst-nonext.ll +++ llvm/test/CodeGen/AArch64/sve-masked-ldst-nonext.ll @@ -117,6 +117,15 @@ ret %load } +; Masked load requires promotion +define @masked_load_nxv2i16(* noalias %in, %mask) { +; CHECK-LABEL: masked_load_nxv2i16 +; CHECK: ld1sh { z0.d }, p0/z, [x0] +; CHECK-NEXT: ret + %wide.load = call @llvm.masked.load.nxv2i16(* %in, i32 2, %mask, undef) + ret %wide.load +} + ; ; Masked Stores ; @@ -315,6 +324,7 @@ declare @llvm.masked.load.nxv2i64(*, i32, , ) declare @llvm.masked.load.nxv4i32(*, i32, , ) +declare @llvm.masked.load.nxv2i16(*, i32, , ) declare @llvm.masked.load.nxv8i16(*, i32, , ) declare @llvm.masked.load.nxv16i8(*, i32, , ) Index: llvm/test/CodeGen/AArch64/sve-masked-ldst-sext.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-masked-ldst-sext.ll +++ llvm/test/CodeGen/AArch64/sve-masked-ldst-sext.ll @@ -89,6 +89,23 @@ ret %ext } +; Masked load requires promotion +define @masked_sload_4i8_4f32(* noalias %in, %mask) { +; CHECK-LABEL: masked_sload_4i8_4f32: +; CHECK: punpkhi p2.h, p0.b +; CHECK-NEXT: punpklo p0.h, p0.b +; CHECK-NEXT: ld1sb { z1.d }, p2/z, [x0, #1, mul vl] +; CHECK-NEXT: ld1sb { z0.d }, p0/z, [x0] +; CHECK-NEXT: ptrue p1.d +; CHECK-NEXT: scvtf z0.d, p1/m, z0.d +; CHECK-NEXT: scvtf z1.d, p1/m, z1.d +; CHECK-NEXT: ret + %wide.load = call @llvm.masked.load.nxv4i8(* %in, i32 2, %mask, undef) + %sext = sext %wide.load to + %res = sitofp %sext to + ret %res +} + declare @llvm.masked.load.nxv2i8(*, i32, , ) declare @llvm.masked.load.nxv2i16(*, i32, , ) declare @llvm.masked.load.nxv2i32(*, i32, , ) Index: llvm/test/CodeGen/AArch64/sve-masked-ldst-zext.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-masked-ldst-zext.ll +++ llvm/test/CodeGen/AArch64/sve-masked-ldst-zext.ll @@ -95,6 +95,19 @@ ret %ext } +; Masked load requires promotion +define @masked_zload_2i16_2f64(* noalias %in, %mask) { +; CHECK-LABEL: masked_zload_2i16_2f64: +; CHECK: ld1h { z0.d }, p0/z, [x0] +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: ucvtf z0.d, p0/m, z0.s +; CHECK-NEXT: ret + %wide.load = call @llvm.masked.load.nxv2i16(* %in, i32 2, %mask, undef) + %zext = zext %wide.load to + %res = uitofp %zext to + ret %res +} + declare @llvm.masked.load.nxv2i8(*, i32, , ) declare @llvm.masked.load.nxv2i16(*, i32, , ) declare @llvm.masked.load.nxv2i32(*, i32, , )