Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -3162,7 +3162,6 @@ (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 @@ -3176,6 +3175,45 @@ (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; } + // (Un)Signed Word vector extract -> QP + let Predicates = [IsBigEndian] in { + def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 0)))), + (f128 (XSCVSDQP (EXTRACT_SUBREG (XVCVSXWDP $src), sub_64)))>; + foreach Idx = 1-3 in { + def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))), + (f128 (XSCVSDQP (EXTRACT_SUBREG + (XVCVSXWDP (VSPLTW Idx, $src)), sub_64)))>; + } + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 0)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 0)))>; + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 1)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 4)))>; + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 2)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 8)))>; + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 3)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 12)))>; + } + let Predicates = [IsLittleEndian] in { + def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 0)))), + (f128 (XSCVSDQP (EXTRACT_SUBREG + (XVCVSXWDP (VSPLTW 3, $src)), sub_64)))>; + def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))), + (f128 (XSCVSDQP (EXTRACT_SUBREG + (XVCVSXWDP (VSPLTW 2, $src)), sub_64)))>; + def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))), + (f128 (XSCVSDQP (EXTRACT_SUBREG + (XVCVSXWDP (VSPLTW 1, $src)), sub_64)))>; + def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 3)))), + (f128 (XSCVSDQP (EXTRACT_SUBREG (XVCVSXWDP $src), sub_64)))>; + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 0)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 12)))>; + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 1)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 8)))>; + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 2)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 4)))>; + def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, 3)))), + (f128 (XSCVUDQP (XXEXTRACTUW $src, 0)))>; + } // 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 =================================================================== --- test/CodeGen/PowerPC/f128-vecExtractNconv.ll +++ test/CodeGen/PowerPC/f128-vecExtractNconv.ll @@ -5,6 +5,8 @@ ; RUN: -verify-machineinstrs -enable-ppc-quad-precision < %s | \ ; RUN: FileCheck %s -check-prefix=CHECK-BE +; Vector extract DWord and convert to quad precision. + @sdwVecMem = global <2 x i64> , align 16 @udwVecMem = global <2 x i64> , align 16 @@ -158,3 +160,182 @@ store fp128 %conv, fp128* %a, align 16 ret void } + +; Vector extract Word and convert to quad precision. + +@swVecMem = global <4 x i32> , align 16 +@uwVecMem = global <4 x i32> , align 16 + +; Function Attrs: norecurse nounwind +define void @swVecConv2qp(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: swVecConv2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vspltw 2, 2, 3 +; CHECK-NEXT: xvcvsxwdp 34, 34 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: swVecConv2qp: +; CHECK-BE: xvcvsxwdp 34, 34 +; CHECK-BE-NEXT: xscvsdqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 0 + %conv = sitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @swVecConv2qp1(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: swVecConv2qp1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vspltw 2, 2, 2 +; CHECK-NEXT: xvcvsxwdp 34, 34 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: swVecConv2qp1: +; CHECK-BE: vspltw 2, 2, 1 +; CHECK-BE-NEXT: xvcvsxwdp 34, 34 +; CHECK-BE-NEXT: xscvsdqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 1 + %conv = sitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @swVecConv2qp2(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: swVecConv2qp2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vspltw 2, 2, 1 +; CHECK-NEXT: xvcvsxwdp 34, 34 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: swVecConv2qp2: +; CHECK-BE: vspltw 2, 2, 2 +; CHECK-BE-NEXT: xvcvsxwdp 34, 34 +; CHECK-BE-NEXT: xscvsdqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 2 + %conv = sitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @swVecConv2qp3(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: swVecConv2qp3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xvcvsxwdp 34, 34 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: swVecConv2qp3: +; CHECK-BE: vspltw 2, 2, 3 +; CHECK-BE-NEXT: xvcvsxwdp 34, 34 +; CHECK-BE-NEXT: xscvsdqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 3 + %conv = sitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @uwVecConv2qp(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: uwVecConv2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xxextractuw 34, 34, 12 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: uwVecConv2qp: +; CHECK-BE: xxextractuw 34, 34, 0 +; CHECK-BE-NEXT: xscvudqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 0 + %conv = uitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @uwVecConv2qp1(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: uwVecConv2qp1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xxextractuw 34, 34, 8 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: uwVecConv2qp1: +; CHECK-BE: xxextractuw 34, 34, 4 +; CHECK-BE-NEXT: xscvudqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 1 + %conv = uitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @uwVecConv2qp2(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: uwVecConv2qp2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xxextractuw 34, 34, 4 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: uwVecConv2qp2: +; CHECK-BE: xxextractuw 34, 34, 8 +; CHECK-BE-NEXT: xscvudqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 2 + %conv = uitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @uwVecConv2qp3(fp128* nocapture %a, <4 x i32> %b) { +; CHECK-LABEL: uwVecConv2qp3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xxextractuw 34, 34, 0 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 34, 0(3) +; CHECK-NEXT: blr + +; CHECK-BE-LABEL: uwVecConv2qp3: +; CHECK-BE: xxextractuw 34, 34, 12 +; CHECK-BE-NEXT: xscvudqp 2, 2 +; CHECK-BE-NEXT: stxv 34, 0(3) +; CHECK-BE-NEXT: blr +entry: + %vecext = extractelement <4 x i32> %b, i32 3 + %conv = uitofp i32 %vecext to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void +}