Index: lib/Target/AArch64/AArch64TargetTransformInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -188,12 +188,25 @@ static const TypeConversionCostTblEntry ConversionTbl[] = { - { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i16, 0 }, - { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i16, 0 }, - { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i32, 1 }, - { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i32, 1 }, - { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, 0 }, - { ISD::TRUNCATE, MVT::v4i16, MVT::v4i32, 1 }, + { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, 0 }, + { ISD::TRUNCATE, MVT::v4i16, MVT::v4i32, 1 }, + + // Lengthening and widening instructions (L/W variants), including those + // with the second half specifier (2 suffix), perform extensions + // automatically. Since many operations have L/W variants, let's + // optimistically assume the following casts will always be folded away. + { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i8, 0 }, + { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i16, 0 }, + { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i32, 0 }, + { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, 0 }, + { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 0 }, + { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, 0 }, + { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i8, 0 }, + { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i16, 0 }, + { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i32, 0 }, + { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, 0 }, + { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 0 }, + { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 0 }, // The number of shll instructions for the extension. { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i16, 3 },