diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 0cb7b02d84a6e..a0db51121b8d4 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -5287,6 +5287,11 @@ defm UCVTF : IntegerToFP<0b00, 0b011, "ucvtf", any_uint_to_fp>; let Predicates = [HasNEON, HasFPRCVT] in { defm SCVTF : IntegerToFPSIMDScalar<0b11, 0b100, "scvtf", any_sint_to_fp>; defm UCVTF : IntegerToFPSIMDScalar<0b11, 0b101, "ucvtf", any_uint_to_fp>; + + def : Pat<(v1f64 (extract_subvector (v2f64 (sint_to_fp (v2i64 (sext (v2i32 V64:$Rn))))), (i64 0))), + (SCVTFDSr (EXTRACT_SUBREG V64:$Rn, ssub))>; + def : Pat<(v1f64 (extract_subvector (v2f64 (uint_to_fp (v2i64 (zext (v2i32 V64:$Rn))))), (i64 0))), + (UCVTFDSr (EXTRACT_SUBREG V64:$Rn, ssub))>; } def : Pat<(f16 (fdiv (f16 (any_sint_to_fp (i32 GPR32:$Rn))), fixedpoint_f16_i32:$scale)), diff --git a/llvm/test/CodeGen/AArch64/fprcvt-cvtf.ll b/llvm/test/CodeGen/AArch64/fprcvt-cvtf.ll index 9da6f583cec01..3ea1a01cfc977 100644 --- a/llvm/test/CodeGen/AArch64/fprcvt-cvtf.ll +++ b/llvm/test/CodeGen/AArch64/fprcvt-cvtf.ll @@ -94,16 +94,10 @@ define double @scvtf_f64i32_neg(<4 x i32> %x) { ret double %conv } -; This test does not give the indended result of scvtf d0, s0 -; This is due to the input being loaded as a 2 item vector and -; therefore using vector inputs that do not match the pattern -; This test will be fixed in a future revision define <1 x double> @scvtf_f64i32_simple(<1 x i32> %x) { ; CHECK-LABEL: scvtf_f64i32_simple: ; CHECK: // %bb.0: -; CHECK-NEXT: sshll v0.2d, v0.2s, #0 -; CHECK-NEXT: scvtf v0.2d, v0.2d -; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 +; CHECK-NEXT: scvtf d0, s0 ; CHECK-NEXT: ret ; ; CHECK-NO-FPRCVT-LABEL: scvtf_f64i32_simple: @@ -315,16 +309,10 @@ define double @ucvtf_f64i32_neg(<4 x i32> %x) { ret double %conv } -; This test does not give the indended result of ucvtf d0, s0 -; This is due to the input being loaded as a 2 item vector and -; therefore using vector inputs that do not match the pattern -; This test will be fixed in a future revision define <1 x double> @ucvtf_f64i32_simple(<1 x i32> %x) { ; CHECK-LABEL: ucvtf_f64i32_simple: ; CHECK: // %bb.0: -; CHECK-NEXT: ushll v0.2d, v0.2s, #0 -; CHECK-NEXT: ucvtf v0.2d, v0.2d -; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 +; CHECK-NEXT: ucvtf d0, s0 ; CHECK-NEXT: ret ; ; CHECK-NO-FPRCVT-LABEL: ucvtf_f64i32_simple: @@ -449,3 +437,24 @@ define <1 x float> @ucvtf_f32i64_simple(<1 x i64> %x) { %conv = uitofp <1 x i64> %x to <1 x float> ret <1 x float> %conv } + +define <1 x double> @uitofp_sext_v2i32_extract_lane0(<2 x i32> %x) { +; CHECK-LABEL: uitofp_sext_v2i32_extract_lane0: +; CHECK: // %bb.0: +; CHECK-NEXT: sshll v0.2d, v0.2s, #0 +; CHECK-NEXT: ucvtf v0.2d, v0.2d +; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 +; CHECK-NEXT: ret +; +; CHECK-NO-FPRCVT-LABEL: uitofp_sext_v2i32_extract_lane0: +; CHECK-NO-FPRCVT: // %bb.0: +; CHECK-NO-FPRCVT-NEXT: sshll v0.2d, v0.2s, #0 +; CHECK-NO-FPRCVT-NEXT: ucvtf v0.2d, v0.2d +; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 killed $q0 +; CHECK-NO-FPRCVT-NEXT: ret + %wide = sext <2 x i32> %x to <2 x i64> + %fpv2 = uitofp <2 x i64> %wide to <2 x double> + %lane0 = shufflevector <2 x double> %fpv2, <2 x double> poison, <1 x i32> zeroinitializer + ret <1 x double> %lane0 +} +