diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -985,9 +985,11 @@ // elements smaller than i32, so promote the input to i32 first. setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v4i8, MVT::v4i32); setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v4i8, MVT::v4i32); - // i8 vector elements also need promotion to i32 for v8i8 setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v8i8, MVT::v8i32); setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v8i8, MVT::v8i32); + setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v16i8, MVT::v16i32); + setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v16i8, MVT::v16i32); + // Similarly, there is no direct i32 -> f64 vector conversion instruction. setOperationAction(ISD::SINT_TO_FP, MVT::v2i32, Custom); setOperationAction(ISD::UINT_TO_FP, MVT::v2i32, Custom); diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-fp-converts.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-fp-converts.ll --- a/llvm/test/CodeGen/AArch64/sve-fixed-length-fp-converts.ll +++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-fp-converts.ll @@ -165,4 +165,46 @@ ret void } +; +; vector uint_to_fp i8 -> f32 +; AArch64 doesn't have a direct vector->f32 conversion instructions for +; elements smaller than i32, so make sure inputs are promoted to i32 first. +; + +define void @uitofp_v4i8_v4f32(<4 x i8>* %in, <4 x float>* %out) #0 { +; CHECK-LABEL: uitofp_v4i8_v4f32: +; CHECK-COUNT-1: ucvt + %vec = load <4 x i8>, <4 x i8>* %in + %conv = uitofp <4 x i8> %vec to <4 x float> + store <4 x float> %conv, <4 x float>* %out + ret void +} + +define void @uitofp_v8i8_v8f32(<8 x i8>* %in, <8 x float>* %out) #0 { +; CHECK-LABEL: uitofp_v8i8_v8f32: +; CHECK-COUNT-8: ucvt + %vec = load <8 x i8>, <8 x i8>* %in + %conv = uitofp <8 x i8> %vec to <8 x float> + store <8 x float> %conv, <8 x float>* %out + ret void +} + +define void @uitofp_v16i8_v16f32(<16 x i8>* %in, <16 x float>* %out) #0 { +; CHECK-LABEL: uitofp_v16i8_v16f32: +; CHECK-COUNT-16: ucvt + %vec = load <16 x i8>, <16 x i8>* %in + %conv = uitofp <16 x i8> %vec to <16 x float> + store <16 x float> %conv, <16 x float>* %out + ret void +} + +define void @uitofp_v32i8_v32f32(<32 x i8>* %in, <32 x float>* %out) #0 { +; CHECK-LABEL: uitofp_v32i8_v32f32: +; CHECK-COUNT-32: ucvt + %vec = load <32 x i8>, <32 x i8>* %in + %conv = uitofp <32 x i8> %vec to <32 x float> + store <32 x float> %conv, <32 x float>* %out + ret void +} + attributes #0 = { nounwind "target-features"="+sve" }