diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -433,6 +433,9 @@ if (Subtarget.hasSPE()) { // SPE has built-in conversions + setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Legal); + setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Legal); + setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Legal); setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal); setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal); setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal); @@ -592,9 +595,10 @@ } } else { // PowerPC does not have FP_TO_UINT on 32-bit implementations. - if (Subtarget.hasSPE()) + if (Subtarget.hasSPE()) { + setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Legal); setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal); - else { + } else { setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Expand); setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); } diff --git a/llvm/lib/Target/PowerPC/PPCInstrSPE.td b/llvm/lib/Target/PowerPC/PPCInstrSPE.td --- a/llvm/lib/Target/PowerPC/PPCInstrSPE.td +++ b/llvm/lib/Target/PowerPC/PPCInstrSPE.td @@ -158,7 +158,7 @@ def EFDCFSI : EFXForm_2a<753, (outs sperc:$RT), (ins gprc:$RB), "efdcfsi $RT, $RB", IIC_FPDGeneral, - [(set f64:$RT, (sint_to_fp i32:$RB))]>; + [(set f64:$RT, (any_sint_to_fp i32:$RB))]>; def EFDCFSID : EFXForm_2a<739, (outs sperc:$RT), (ins gprc:$RB), "efdcfsid $RT, $RB", IIC_FPDGeneral, @@ -169,7 +169,7 @@ def EFDCFUI : EFXForm_2a<752, (outs sperc:$RT), (ins gprc:$RB), "efdcfui $RT, $RB", IIC_FPDGeneral, - [(set f64:$RT, (uint_to_fp i32:$RB))]>; + [(set f64:$RT, (any_uint_to_fp i32:$RB))]>; def EFDCFUID : EFXForm_2a<738, (outs sperc:$RT), (ins gprc:$RB), "efdcfuid $RT, $RB", IIC_FPDGeneral, @@ -197,7 +197,7 @@ def EFDCTSIZ : EFXForm_2a<762, (outs gprc:$RT), (ins sperc:$RB), "efdctsiz $RT, $RB", IIC_FPDGeneral, - [(set i32:$RT, (fp_to_sint f64:$RB))]>; + [(set i32:$RT, (any_fp_to_sint f64:$RB))]>; def EFDCTUF : EFXForm_2a<758, (outs sperc:$RT), (ins spe4rc:$RB), "efdctuf $RT, $RB", IIC_FPDGeneral, []>; @@ -212,7 +212,7 @@ def EFDCTUIZ : EFXForm_2a<760, (outs gprc:$RT), (ins sperc:$RB), "efdctuiz $RT, $RB", IIC_FPDGeneral, - [(set i32:$RT, (fp_to_uint f64:$RB))]>; + [(set i32:$RT, (any_fp_to_uint f64:$RB))]>; def EFDDIV : EFXForm_1<745, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB), "efddiv $RT, $RA, $RB", IIC_FPDivD, @@ -261,14 +261,14 @@ def EFSCFSI : EFXForm_2a<721, (outs spe4rc:$RT), (ins gprc:$RB), "efscfsi $RT, $RB", IIC_FPSGeneral, - [(set f32:$RT, (sint_to_fp i32:$RB))]>; + [(set f32:$RT, (any_sint_to_fp i32:$RB))]>; def EFSCFUF : EFXForm_2a<722, (outs spe4rc:$RT), (ins spe4rc:$RB), "efscfuf $RT, $RB", IIC_FPSGeneral, []>; def EFSCFUI : EFXForm_2a<720, (outs spe4rc:$RT), (ins gprc:$RB), "efscfui $RT, $RB", IIC_FPSGeneral, - [(set f32:$RT, (uint_to_fp i32:$RB))]>; + [(set f32:$RT, (any_uint_to_fp i32:$RB))]>; let isCompare = 1 in { def EFSCMPEQ : EFXForm_3<718, (outs crrc:$crD), (ins spe4rc:$RA, spe4rc:$RB), @@ -288,7 +288,7 @@ def EFSCTSIZ : EFXForm_2a<730, (outs gprc:$RT), (ins spe4rc:$RB), "efsctsiz $RT, $RB", IIC_FPSGeneral, - [(set i32:$RT, (fp_to_sint f32:$RB))]>; + [(set i32:$RT, (any_fp_to_sint f32:$RB))]>; def EFSCTUF : EFXForm_2a<726, (outs sperc:$RT), (ins spe4rc:$RB), "efsctuf $RT, $RB", IIC_FPSGeneral, []>; @@ -299,7 +299,7 @@ def EFSCTUIZ : EFXForm_2a<728, (outs gprc:$RT), (ins spe4rc:$RB), "efsctuiz $RT, $RB", IIC_FPSGeneral, - [(set i32:$RT, (fp_to_uint f32:$RB))]>; + [(set i32:$RT, (any_fp_to_uint f32:$RB))]>; def EFSDIV : EFXForm_1<713, (outs spe4rc:$RT), (ins spe4rc:$RA, spe4rc:$RB), "efsdiv $RT, $RA, $RB", IIC_FPDivD, diff --git a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll --- a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll +++ b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll @@ -8,6 +8,9 @@ ; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \ ; RUN: < %s -mtriple=powerpc64le-unknown-linux -enable-ppc-quad-precision \ ; RUN: -mcpu=pwr8 -mattr=-vsx | FileCheck %s -check-prefix=NOVSX +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names < %s -mcpu=e500 \ +; RUN: -mtriple=powerpc-unknown-linux-gnu -mattr=spe | FileCheck %s \ +; RUN: -check-prefix=SPE declare i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128, metadata) declare i64 @llvm.experimental.constrained.fptosi.i64.f128(fp128, metadata) @@ -76,6 +79,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: q_to_i128: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixtfti +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i128 @llvm.experimental.constrained.fptosi.i128.f128(fp128 %m, metadata !"fpexcept.strict") #0 ret i128 %conv @@ -123,6 +139,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: q_to_u128: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixunstfti +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i128 @llvm.experimental.constrained.fptoui.i128.f128(fp128 %m, metadata !"fpexcept.strict") #0 ret i128 %conv @@ -170,6 +199,39 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: ppcq_to_i128: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -48(r1) +; SPE-NEXT: .cfi_def_cfa_offset 48 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r5, r5, r6 +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: evstdd r5, 16(r1) +; SPE-NEXT: evstdd r3, 24(r1) +; SPE-NEXT: lwz r3, 28(r1) +; SPE-NEXT: stw r3, 44(r1) +; SPE-NEXT: lwz r3, 24(r1) +; SPE-NEXT: stw r3, 40(r1) +; SPE-NEXT: lwz r3, 20(r1) +; SPE-NEXT: stw r3, 36(r1) +; SPE-NEXT: lwz r3, 16(r1) +; SPE-NEXT: stw r3, 32(r1) +; SPE-NEXT: evldd r4, 40(r1) +; SPE-NEXT: evldd r6, 32(r1) +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: evmergehi r5, r6, r6 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r6 killed $r6 killed $s6 +; SPE-NEXT: # kill: def $r5 killed $r5 killed $s5 +; SPE-NEXT: bl __fixtfti +; SPE-NEXT: lwz r0, 52(r1) +; SPE-NEXT: addi r1, r1, 48 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i128 @llvm.experimental.constrained.fptosi.i128.ppcf128(ppc_fp128 %m, metadata !"fpexcept.strict") #0 ret i128 %conv @@ -217,6 +279,39 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: ppcq_to_u128: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -48(r1) +; SPE-NEXT: .cfi_def_cfa_offset 48 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r5, r5, r6 +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: evstdd r5, 16(r1) +; SPE-NEXT: evstdd r3, 24(r1) +; SPE-NEXT: lwz r3, 28(r1) +; SPE-NEXT: stw r3, 44(r1) +; SPE-NEXT: lwz r3, 24(r1) +; SPE-NEXT: stw r3, 40(r1) +; SPE-NEXT: lwz r3, 20(r1) +; SPE-NEXT: stw r3, 36(r1) +; SPE-NEXT: lwz r3, 16(r1) +; SPE-NEXT: stw r3, 32(r1) +; SPE-NEXT: evldd r4, 40(r1) +; SPE-NEXT: evldd r6, 32(r1) +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: evmergehi r5, r6, r6 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r6 killed $r6 killed $s6 +; SPE-NEXT: # kill: def $r5 killed $r5 killed $s5 +; SPE-NEXT: bl __fixtfti +; SPE-NEXT: lwz r0, 52(r1) +; SPE-NEXT: addi r1, r1, 48 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i128 @llvm.experimental.constrained.fptosi.i128.ppcf128(ppc_fp128 %m, metadata !"fpexcept.strict") #0 ret i128 %conv @@ -259,6 +354,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: q_to_i32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixkfsi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128 %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -298,6 +406,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: q_to_i64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixkfdi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i64 @llvm.experimental.constrained.fptosi.i64.f128(fp128 %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -337,6 +458,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: q_to_u64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixunskfdi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i64 @llvm.experimental.constrained.fptoui.i64.f128(fp128 %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -377,6 +511,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: q_to_u32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixunskfsi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i32 @llvm.experimental.constrained.fptoui.i32.f128(fp128 %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -427,6 +574,39 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: ppcq_to_i32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -48(r1) +; SPE-NEXT: .cfi_def_cfa_offset 48 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r5, r5, r6 +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: evstdd r5, 16(r1) +; SPE-NEXT: evstdd r3, 24(r1) +; SPE-NEXT: lwz r3, 28(r1) +; SPE-NEXT: stw r3, 44(r1) +; SPE-NEXT: lwz r3, 24(r1) +; SPE-NEXT: stw r3, 40(r1) +; SPE-NEXT: lwz r3, 20(r1) +; SPE-NEXT: stw r3, 36(r1) +; SPE-NEXT: lwz r3, 16(r1) +; SPE-NEXT: stw r3, 32(r1) +; SPE-NEXT: evldd r4, 40(r1) +; SPE-NEXT: evldd r6, 32(r1) +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: evmergehi r5, r6, r6 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r6 killed $r6 killed $s6 +; SPE-NEXT: # kill: def $r5 killed $r5 killed $s5 +; SPE-NEXT: bl __gcc_qtou +; SPE-NEXT: lwz r0, 52(r1) +; SPE-NEXT: addi r1, r1, 48 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i32 @llvm.experimental.constrained.fptosi.i32.ppcf128(ppc_fp128 %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -474,6 +654,39 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: ppcq_to_i64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -48(r1) +; SPE-NEXT: .cfi_def_cfa_offset 48 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r5, r5, r6 +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: evstdd r5, 16(r1) +; SPE-NEXT: evstdd r3, 24(r1) +; SPE-NEXT: lwz r3, 28(r1) +; SPE-NEXT: stw r3, 44(r1) +; SPE-NEXT: lwz r3, 24(r1) +; SPE-NEXT: stw r3, 40(r1) +; SPE-NEXT: lwz r3, 20(r1) +; SPE-NEXT: stw r3, 36(r1) +; SPE-NEXT: lwz r3, 16(r1) +; SPE-NEXT: stw r3, 32(r1) +; SPE-NEXT: evldd r4, 40(r1) +; SPE-NEXT: evldd r6, 32(r1) +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: evmergehi r5, r6, r6 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r6 killed $r6 killed $s6 +; SPE-NEXT: # kill: def $r5 killed $r5 killed $s5 +; SPE-NEXT: bl __fixtfdi +; SPE-NEXT: lwz r0, 52(r1) +; SPE-NEXT: addi r1, r1, 48 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i64 @llvm.experimental.constrained.fptosi.i64.ppcf128(ppc_fp128 %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -521,6 +734,39 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: ppcq_to_u64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -48(r1) +; SPE-NEXT: .cfi_def_cfa_offset 48 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r5, r5, r6 +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: evstdd r5, 16(r1) +; SPE-NEXT: evstdd r3, 24(r1) +; SPE-NEXT: lwz r3, 28(r1) +; SPE-NEXT: stw r3, 44(r1) +; SPE-NEXT: lwz r3, 24(r1) +; SPE-NEXT: stw r3, 40(r1) +; SPE-NEXT: lwz r3, 20(r1) +; SPE-NEXT: stw r3, 36(r1) +; SPE-NEXT: lwz r3, 16(r1) +; SPE-NEXT: stw r3, 32(r1) +; SPE-NEXT: evldd r4, 40(r1) +; SPE-NEXT: evldd r6, 32(r1) +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: evmergehi r5, r6, r6 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r6 killed $r6 killed $s6 +; SPE-NEXT: # kill: def $r5 killed $r5 killed $s5 +; SPE-NEXT: bl __fixunstfdi +; SPE-NEXT: lwz r0, 52(r1) +; SPE-NEXT: addi r1, r1, 48 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i64 @llvm.experimental.constrained.fptoui.i64.ppcf128(ppc_fp128 %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -568,6 +814,39 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: ppcq_to_u32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -48(r1) +; SPE-NEXT: .cfi_def_cfa_offset 48 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r5, r5, r6 +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: evstdd r5, 16(r1) +; SPE-NEXT: evstdd r3, 24(r1) +; SPE-NEXT: lwz r3, 28(r1) +; SPE-NEXT: stw r3, 44(r1) +; SPE-NEXT: lwz r3, 24(r1) +; SPE-NEXT: stw r3, 40(r1) +; SPE-NEXT: lwz r3, 20(r1) +; SPE-NEXT: stw r3, 36(r1) +; SPE-NEXT: lwz r3, 16(r1) +; SPE-NEXT: stw r3, 32(r1) +; SPE-NEXT: evldd r4, 40(r1) +; SPE-NEXT: evldd r6, 32(r1) +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: evmergehi r5, r6, r6 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r6 killed $r6 killed $s6 +; SPE-NEXT: # kill: def $r5 killed $r5 killed $s5 +; SPE-NEXT: bl __fixunstfsi +; SPE-NEXT: lwz r0, 52(r1) +; SPE-NEXT: addi r1, r1, 48 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call i32 @llvm.experimental.constrained.fptoui.i32.ppcf128(ppc_fp128 %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -607,6 +886,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: i32_to_q: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatsikf +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call fp128 @llvm.experimental.constrained.sitofp.f128.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret fp128 %conv @@ -646,6 +938,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: i64_to_q: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatdikf +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call fp128 @llvm.experimental.constrained.sitofp.f128.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret fp128 %conv @@ -685,6 +990,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: u32_to_q: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatunsikf +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call fp128 @llvm.experimental.constrained.uitofp.f128.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret fp128 %conv @@ -724,6 +1042,19 @@ ; NOVSX-NEXT: ld r0, 16(r1) ; NOVSX-NEXT: mtlr r0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: u64_to_q: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatundikf +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call fp128 @llvm.experimental.constrained.uitofp.f128.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret fp128 %conv diff --git a/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll b/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll --- a/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll +++ b/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll @@ -6,6 +6,9 @@ ; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \ ; RUN: < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr8 -mattr=-vsx | \ ; RUN: FileCheck %s -check-prefix=NOVSX +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names < %s -mcpu=e500 \ +; RUN: -mtriple=powerpc-unknown-linux-gnu -mattr=spe | FileCheck %s \ +; RUN: -check-prefix=SPE declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata) declare i64 @llvm.experimental.constrained.fptosi.i64.f64(double, metadata) @@ -41,6 +44,12 @@ ; NOVSX-NEXT: stfiwx f0, 0, r3 ; NOVSX-NEXT: lwz r3, -4(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: d_to_i32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: efdctsiz r3, r3 +; SPE-NEXT: blr entry: %conv = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -59,6 +68,23 @@ ; NOVSX-NEXT: stfd f0, -8(r1) ; NOVSX-NEXT: ld r3, -8(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: d_to_i64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r4, r3, r4 +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: bl __fixdfdi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = call i64 @llvm.experimental.constrained.fptosi.i64.f64(double %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -77,6 +103,23 @@ ; NOVSX-NEXT: stfd f0, -8(r1) ; NOVSX-NEXT: ld r3, -8(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: d_to_u64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: evmergelo r4, r3, r4 +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: bl __fixunsdfdi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = call i64 @llvm.experimental.constrained.fptoui.i64.f64(double %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -97,6 +140,12 @@ ; NOVSX-NEXT: stfiwx f0, 0, r3 ; NOVSX-NEXT: lwz r3, -4(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: d_to_u32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: evmergelo r3, r3, r4 +; SPE-NEXT: efdctuiz r3, r3 +; SPE-NEXT: blr entry: %conv = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -117,6 +166,11 @@ ; NOVSX-NEXT: stfiwx f0, 0, r3 ; NOVSX-NEXT: lwa r3, -4(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: f_to_i32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: efsctsiz r3, r3 +; SPE-NEXT: blr entry: %conv = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -135,6 +189,19 @@ ; NOVSX-NEXT: stfd f0, -8(r1) ; NOVSX-NEXT: ld r3, -8(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: f_to_i64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixsfdi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = call i64 @llvm.experimental.constrained.fptosi.i64.f32(float %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -153,6 +220,19 @@ ; NOVSX-NEXT: stfd f0, -8(r1) ; NOVSX-NEXT: ld r3, -8(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: f_to_u64: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __fixunssfdi +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = call i64 @llvm.experimental.constrained.fptoui.i64.f32(float %m, metadata !"fpexcept.strict") #0 ret i64 %conv @@ -173,6 +253,11 @@ ; NOVSX-NEXT: stfiwx f0, 0, r3 ; NOVSX-NEXT: lwz r3, -4(r1) ; NOVSX-NEXT: blr +; +; SPE-LABEL: f_to_u32: +; SPE: # %bb.0: # %entry +; SPE-NEXT: efsctuiz r3, r3 +; SPE-NEXT: blr entry: %conv = call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %m, metadata !"fpexcept.strict") #0 ret i32 %conv @@ -192,6 +277,14 @@ ; NOVSX-NEXT: lfiwax f0, 0, r4 ; NOVSX-NEXT: fcfid f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: i32_to_d: +; SPE: # %bb.0: # %entry +; SPE-NEXT: efdcfsi r4, r3 +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: blr entry: %conv = tail call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret double %conv @@ -210,6 +303,23 @@ ; NOVSX-NEXT: lfd f0, -8(r1) ; NOVSX-NEXT: fcfid f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: i64_to_d: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatdidf +; SPE-NEXT: evmergelo r4, r3, r4 +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call double @llvm.experimental.constrained.sitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret double %conv @@ -229,6 +339,14 @@ ; NOVSX-NEXT: lfiwzx f0, 0, r4 ; NOVSX-NEXT: fcfidu f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: u32_to_d: +; SPE: # %bb.0: # %entry +; SPE-NEXT: efdcfui r4, r3 +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: blr entry: %conv = tail call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret double %conv @@ -247,6 +365,23 @@ ; NOVSX-NEXT: lfd f0, -8(r1) ; NOVSX-NEXT: fcfidu f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: u64_to_d: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatundidf +; SPE-NEXT: evmergelo r4, r3, r4 +; SPE-NEXT: evmergehi r3, r4, r4 +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 +; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret double %conv @@ -266,6 +401,11 @@ ; NOVSX-NEXT: lfiwax f0, 0, r4 ; NOVSX-NEXT: fcfids f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: i32_to_f: +; SPE: # %bb.0: # %entry +; SPE-NEXT: efscfsi r3, r3 +; SPE-NEXT: blr entry: %conv = tail call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret float %conv @@ -284,6 +424,19 @@ ; NOVSX-NEXT: lfd f0, -8(r1) ; NOVSX-NEXT: fcfids f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: i64_to_f: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatdisf +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call float @llvm.experimental.constrained.sitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret float %conv @@ -303,6 +456,11 @@ ; NOVSX-NEXT: lfiwzx f0, 0, r4 ; NOVSX-NEXT: fcfidus f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: u32_to_f: +; SPE: # %bb.0: # %entry +; SPE-NEXT: efscfui r3, r3 +; SPE-NEXT: blr entry: %conv = tail call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret float %conv @@ -321,6 +479,19 @@ ; NOVSX-NEXT: lfd f0, -8(r1) ; NOVSX-NEXT: fcfidus f1, f0 ; NOVSX-NEXT: blr +; +; SPE-LABEL: u64_to_f: +; SPE: # %bb.0: # %entry +; SPE-NEXT: mflr r0 +; SPE-NEXT: stw r0, 4(r1) +; SPE-NEXT: stwu r1, -16(r1) +; SPE-NEXT: .cfi_def_cfa_offset 16 +; SPE-NEXT: .cfi_offset lr, 4 +; SPE-NEXT: bl __floatundisf +; SPE-NEXT: lwz r0, 20(r1) +; SPE-NEXT: addi r1, r1, 16 +; SPE-NEXT: mtlr r0 +; SPE-NEXT: blr entry: %conv = tail call float @llvm.experimental.constrained.uitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 ret float %conv