Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion llvm/lib/Target/AArch64/AArch64InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -5520,7 +5520,6 @@ multiclass IntegerToFPSIMDScalar<bits<2> rmode, bits<3> opcode, string asm, SDPa
let Inst{31} = 1; // 64-bit FPR flag
let Inst{23-22} = 0b00; // 32-bit FPR flag
}

def : Pat<(f16 (node (i32 (extractelt (v4i32 V128:$Rn), (i64 0))))),
(!cast<Instruction>(NAME # HSr) (EXTRACT_SUBREG V128:$Rn, ssub))>;
def : Pat<(f64 (node (i32 (extractelt (v4i32 V128:$Rn), (i64 0))))),
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
45 changes: 27 additions & 18 deletions llvm/test/CodeGen/AArch64/fprcvt-cvtf.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -202,10 +196,8 @@ define float @scvtf_f32i64_neg(<2 x i64> %x) {
ret float %conv
}

; This test does not give the indended result of scvtf s0, d0
; 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
; <1 x float> is illegal on AArch64 and is widened to <2 x float>.
; This widening introduces the extra insert/extract/zeroing instructions.
define <1 x float> @scvtf_f32i64_simple(<1 x i64> %x) {
; CHECK-LABEL: scvtf_f32i64_simple:
; CHECK: // %bb.0:
Expand Down Expand Up @@ -315,16 +307,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:
Expand Down Expand Up @@ -449,3 +435,26 @@ 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-NOT: ucvtf d0, s0
; CHECK-NOT: scvtf d0, s0
; 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
}