Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -3149,6 +3149,33 @@ def : Pat<(f32 (fpround (f64 (extloadf32 ixaddr:$src)))), (f32 (DFLOADf32 ixaddr:$src))>; + // (Un)Signed DWord vector extract -> QP + let Predicates = [IsBigEndian] in { + def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), + (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; + def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), + (f128 (XSCVSDQP + (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; + def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), + (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; + def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), + (f128 (XSCVUDQP + (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; + } + + let Predicates = [IsLittleEndian] in { + def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), + (f128 (XSCVSDQP + (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; + def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), + (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; + def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), + (f128 (XSCVUDQP + (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; + def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), + (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; + } + // Convert (Un)Signed DWord in memory -> QP def : Pat<(f128 (sint_to_fp (i64 (load xaddr:$src)))), (f128 (XSCVSDQP (LXSDX xaddr:$src)))>; Index: test/CodeGen/PowerPC/f128-vecExtractNconv.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/f128-vecExtractNconv.ll @@ -0,0 +1,160 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \ +; RUN: -verify-machineinstrs -enable-ppc-quad-precision < %s | FileCheck %s +; RUN: llc -mcpu=pwr9 -mtriple=powerpc64-unknown-unknown \ +; RUN: -verify-machineinstrs -enable-ppc-quad-precision < %s | \ +; RUN: FileCheck %s -check-prefix=CHECK-BE + +@sdwVecMem = global <2 x i64> , align 16 +@udwVecMem = global <2 x i64> , align 16 + +; Function Attrs: norecurse nounwind +define void @sdwVecConv2qp(fp128* nocapture %a, <2 x i64> %b) { +; CHECK-LABEL: sdwVecConv2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xxspltd 34, 34, 1 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: sdwVecConv2qp: +; CHECK-BE: xscvsdqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <2 x i64> %b, i32 0 + %conv = sitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @sdwVecConv2qp1(fp128* nocapture %a, <2 x i64> %b) { +; CHECK-LABEL: sdwVecConv2qp1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: sdwVecConv2qp1: +; CHECK-BE: # %bb.0: # %entry +; CHECK-BE-NEXT: xxspltd 34, 34, 1 +; CHECK-BE-NEXT: xscvsdqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <2 x i64> %b, i32 1 + %conv = sitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @sdwVecConv2qp_02(fp128* nocapture %a) { +; CHECK-LABEL: sdwVecConv2qp_02: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addis 4, 2, .LC0@toc@ha +; CHECK-NEXT: ld 4, .LC0@toc@l(4) +; CHECK-NEXT: lxsd 2, 0(4) +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr +entry: + %0 = load <2 x i64>, <2 x i64>* @sdwVecMem, align 16 + %vecext = extractelement <2 x i64> %0, i32 0 + %conv = sitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @sdwVecConv2qp1_03(fp128* nocapture %a, <2 x i64>* nocapture readonly %b) { +; CHECK-LABEL: sdwVecConv2qp1_03: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxsd 2, 8(4) +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr +entry: + %0 = load <2 x i64>, <2 x i64>* %b, align 16 + %vecext = extractelement <2 x i64> %0, i32 1 + %conv = sitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @udwVecConv2qp(fp128* nocapture %a, <2 x i64> %b) { +; CHECK-LABEL: udwVecConv2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xxspltd 34, 34, 1 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: udwVecConv2qp: +; CHECK-BE: # %bb.0: # %entry +; CHECK-BE-NEXT: xscvudqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <2 x i64> %b, i32 0 + %conv = uitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @udwVecConv2qp1(fp128* nocapture %a, <2 x i64> %b) { +; CHECK-LABEL: udwVecConv2qp1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: udwVecConv2qp1: +; CHECK-BE: # %bb.0: # %entry +; CHECK-BE-NEXT: xxspltd 34, 34, 1 +; CHECK-BE-NEXT: xscvudqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <2 x i64> %b, i32 1 + %conv = uitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @udwVecConv2qp1_02(fp128* nocapture %a) { +; CHECK-LABEL: udwVecConv2qp1_02: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addis 4, 2, .LC1@toc@ha +; CHECK-NEXT: ld 4, .LC1@toc@l(4) +; CHECK-NEXT: lxsd 2, 8(4) +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr +entry: + %0 = load <2 x i64>, <2 x i64>* @udwVecMem, align 16 + %vecext = extractelement <2 x i64> %0, i32 1 + %conv = uitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @udwVecConv2qp_03(fp128* nocapture %a, <2 x i64>* nocapture readonly %b) { +; CHECK-LABEL: udwVecConv2qp_03: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxsd 2, 0(4) +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr +entry: + %0 = load <2 x i64>, <2 x i64>* %b, align 16 + %vecext = extractelement <2 x i64> %0, i32 0 + %conv = uitofp i64 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +}