Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -268,6 +268,18 @@ setOperationAction(ISD::UDIVREM, MVT::i64, Expand); setOperationAction(ISD::SDIVREM, MVT::i64, Expand); + // Handle constrained floating-point operations of scalar. + // TODO: Handle SPE specific operation. + setOperationAction(ISD::STRICT_FADD, MVT::f32, Legal); + setOperationAction(ISD::STRICT_FSUB, MVT::f32, Legal); + setOperationAction(ISD::STRICT_FMUL, MVT::f32, Legal); + setOperationAction(ISD::STRICT_FDIV, MVT::f32, Legal); + + setOperationAction(ISD::STRICT_FADD, MVT::f64, Legal); + setOperationAction(ISD::STRICT_FSUB, MVT::f64, Legal); + setOperationAction(ISD::STRICT_FMUL, MVT::f64, Legal); + setOperationAction(ISD::STRICT_FDIV, MVT::f64, Legal); + // We don't support sin/cos/sqrt/fmod/pow setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); @@ -846,6 +858,19 @@ setOperationAction(ISD::BUILD_VECTOR, MVT::v2i64, Custom); setOperationAction(ISD::BUILD_VECTOR, MVT::v2f64, Custom); + // Handle constrained floating-point operations of vector. + // The predictor is `hasVSX` because altivec instruction has + // no exception but VSX vector instruction has. + setOperationAction(ISD::STRICT_FADD, MVT::v4f32, Legal); + setOperationAction(ISD::STRICT_FSUB, MVT::v4f32, Legal); + setOperationAction(ISD::STRICT_FMUL, MVT::v4f32, Legal); + setOperationAction(ISD::STRICT_FDIV, MVT::v4f32, Legal); + + setOperationAction(ISD::STRICT_FADD, MVT::v2f64, Legal); + setOperationAction(ISD::STRICT_FSUB, MVT::v2f64, Legal); + setOperationAction(ISD::STRICT_FMUL, MVT::v2f64, Legal); + setOperationAction(ISD::STRICT_FDIV, MVT::v2f64, Legal); + addRegisterClass(MVT::v2i64, &PPC::VSRCRegClass); } @@ -902,6 +927,12 @@ setOperationAction(ISD::FPOW, MVT::f128, Expand); setOperationAction(ISD::FPOWI, MVT::f128, Expand); setOperationAction(ISD::FREM, MVT::f128, Expand); + + // Handle constrained floating-point operations of fp128 + setOperationAction(ISD::STRICT_FADD, MVT::f128, Legal); + setOperationAction(ISD::STRICT_FSUB, MVT::f128, Legal); + setOperationAction(ISD::STRICT_FMUL, MVT::f128, Legal); + setOperationAction(ISD::STRICT_FDIV, MVT::f128, Legal); } setOperationAction(ISD::FP_EXTEND, MVT::v2f32, Custom); @@ -1065,6 +1096,8 @@ setOperationAction(ISD::FDIV, MVT::v4f32, Expand); setOperationAction(ISD::FSQRT, MVT::v4f32, Expand); } + + // TODO: Handle constrained floating-point operations of v4f64 } if (Subtarget.has64BitSupport()) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -2916,43 +2916,43 @@ (outs f4rc:$FRT), (ins f8rc:$FRA, f4rc:$FRC, f4rc:$FRB), "fsel", "$FRT, $FRA, $FRC, $FRB", IIC_FPGeneral, [(set f32:$FRT, (PPCfsel f64:$FRA, f32:$FRC, f32:$FRB))]>; -let Uses = [RM] in { +let Uses = [RM], mayRaiseFPException = 1 in { let isCommutable = 1 in { defm FADD : AForm_2r<63, 21, (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), "fadd", "$FRT, $FRA, $FRB", IIC_FPAddSub, - [(set f64:$FRT, (fadd f64:$FRA, f64:$FRB))]>; + [(set f64:$FRT, (any_fadd f64:$FRA, f64:$FRB))]>; defm FADDS : AForm_2r<59, 21, (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB), "fadds", "$FRT, $FRA, $FRB", IIC_FPGeneral, - [(set f32:$FRT, (fadd f32:$FRA, f32:$FRB))]>; + [(set f32:$FRT, (any_fadd f32:$FRA, f32:$FRB))]>; } // isCommutable defm FDIV : AForm_2r<63, 18, (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), "fdiv", "$FRT, $FRA, $FRB", IIC_FPDivD, - [(set f64:$FRT, (fdiv f64:$FRA, f64:$FRB))]>; + [(set f64:$FRT, (any_fdiv f64:$FRA, f64:$FRB))]>; defm FDIVS : AForm_2r<59, 18, (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB), "fdivs", "$FRT, $FRA, $FRB", IIC_FPDivS, - [(set f32:$FRT, (fdiv f32:$FRA, f32:$FRB))]>; + [(set f32:$FRT, (any_fdiv f32:$FRA, f32:$FRB))]>; let isCommutable = 1 in { defm FMUL : AForm_3r<63, 25, (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC), "fmul", "$FRT, $FRA, $FRC", IIC_FPFused, - [(set f64:$FRT, (fmul f64:$FRA, f64:$FRC))]>; + [(set f64:$FRT, (any_fmul f64:$FRA, f64:$FRC))]>; defm FMULS : AForm_3r<59, 25, (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC), "fmuls", "$FRT, $FRA, $FRC", IIC_FPGeneral, - [(set f32:$FRT, (fmul f32:$FRA, f32:$FRC))]>; + [(set f32:$FRT, (any_fmul f32:$FRA, f32:$FRC))]>; } // isCommutable defm FSUB : AForm_2r<63, 20, (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), "fsub", "$FRT, $FRA, $FRB", IIC_FPAddSub, - [(set f64:$FRT, (fsub f64:$FRA, f64:$FRB))]>; + [(set f64:$FRT, (any_fsub f64:$FRA, f64:$FRB))]>; defm FSUBS : AForm_2r<59, 20, (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB), "fsubs", "$FRT, $FRA, $FRB", IIC_FPGeneral, - [(set f32:$FRT, (fsub f32:$FRA, f32:$FRB))]>; + [(set f32:$FRT, (any_fsub f32:$FRA, f32:$FRB))]>; } } Index: llvm/lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -137,7 +137,7 @@ let Predicates = [HasVSX] in { let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. let hasSideEffects = 0 in { // VSX instructions don't have side effects. -let Uses = [RM] in { +let Uses = [RM], mayRaiseFPException = 1 in { // Load indexed instructions let mayLoad = 1, mayStore = 0 in { @@ -204,47 +204,47 @@ def XSADDDP : XX3Form<60, 32, (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xsadddp $XT, $XA, $XB", IIC_VecFP, - [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>; + [(set f64:$XT, (any_fadd f64:$XA, f64:$XB))]>; def XSMULDP : XX3Form<60, 48, (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xsmuldp $XT, $XA, $XB", IIC_VecFP, - [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>; + [(set f64:$XT, (any_fmul f64:$XA, f64:$XB))]>; def XVADDDP : XX3Form<60, 96, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvadddp $XT, $XA, $XB", IIC_VecFP, - [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>; + [(set v2f64:$XT, (any_fadd v2f64:$XA, v2f64:$XB))]>; def XVADDSP : XX3Form<60, 64, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvaddsp $XT, $XA, $XB", IIC_VecFP, - [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>; + [(set v4f32:$XT, (any_fadd v4f32:$XA, v4f32:$XB))]>; def XVMULDP : XX3Form<60, 112, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvmuldp $XT, $XA, $XB", IIC_VecFP, - [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>; + [(set v2f64:$XT, (any_fmul v2f64:$XA, v2f64:$XB))]>; def XVMULSP : XX3Form<60, 80, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvmulsp $XT, $XA, $XB", IIC_VecFP, - [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>; + [(set v4f32:$XT, (any_fmul v4f32:$XA, v4f32:$XB))]>; } // Subtract Instructions def XSSUBDP : XX3Form<60, 40, (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xssubdp $XT, $XA, $XB", IIC_VecFP, - [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>; + [(set f64:$XT, (any_fsub f64:$XA, f64:$XB))]>; def XVSUBDP : XX3Form<60, 104, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvsubdp $XT, $XA, $XB", IIC_VecFP, - [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>; + [(set v2f64:$XT, (any_fsub v2f64:$XA, v2f64:$XB))]>; def XVSUBSP : XX3Form<60, 72, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvsubsp $XT, $XA, $XB", IIC_VecFP, - [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>; + [(set v4f32:$XT, (any_fsub v4f32:$XA, v4f32:$XB))]>; // FMA Instructions let BaseName = "XSMADDADP" in { @@ -443,7 +443,7 @@ def XSDIVDP : XX3Form<60, 56, (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xsdivdp $XT, $XA, $XB", IIC_FPDivD, - [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>; + [(set f64:$XT, (any_fdiv f64:$XA, f64:$XB))]>; def XSSQRTDP : XX2Form<60, 75, (outs vsfrc:$XT), (ins vsfrc:$XB), "xssqrtdp $XT, $XB", IIC_FPSqrtD, @@ -468,11 +468,11 @@ def XVDIVDP : XX3Form<60, 120, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvdivdp $XT, $XA, $XB", IIC_FPDivD, - [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>; + [(set v2f64:$XT, (any_fdiv v2f64:$XA, v2f64:$XB))]>; def XVDIVSP : XX3Form<60, 88, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xvdivsp $XT, $XA, $XB", IIC_FPDivS, - [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>; + [(set v4f32:$XT, (any_fdiv v4f32:$XA, v4f32:$XB))]>; def XVSQRTDP : XX2Form<60, 203, (outs vsrc:$XT), (ins vsrc:$XB), @@ -1366,24 +1366,26 @@ (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>; // VSX Elementary Scalar FP arithmetic (SP) + let mayRaiseFPException = 1 in { let isCommutable = 1 in { def XSADDSP : XX3Form<60, 0, (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), "xsaddsp $XT, $XA, $XB", IIC_VecFP, - [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>; + [(set f32:$XT, (any_fadd f32:$XA, f32:$XB))]>; def XSMULSP : XX3Form<60, 16, (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), "xsmulsp $XT, $XA, $XB", IIC_VecFP, - [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>; + [(set f32:$XT, (any_fmul f32:$XA, f32:$XB))]>; } // isCommutable def XSSUBSP : XX3Form<60, 8, (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), "xssubsp $XT, $XA, $XB", IIC_VecFP, - [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>; + [(set f32:$XT, (any_fsub f32:$XA, f32:$XB))]>; def XSDIVSP : XX3Form<60, 24, (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), "xsdivsp $XT, $XA, $XB", IIC_FPDivS, - [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>; + [(set f32:$XT, (any_fdiv f32:$XA, f32:$XB))]>; + } // mayRaiseFPException def XSRESP : XX2Form<60, 26, (outs vssrc:$XT), (ins vssrc:$XB), "xsresp $XT, $XB", IIC_VecFP, @@ -2509,16 +2511,19 @@ // Quad-Precision Scalar Floating-Point Arithmetic Instructions: // Add/Divide/Multiply/Subtract + let mayRaiseFPException = 1 in { let isCommutable = 1 in { def XSADDQP : X_VT5_VA5_VB5 <63, 4, "xsaddqp", - [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>; + [(set f128:$vT, (any_fadd f128:$vA, f128:$vB))]>; def XSMULQP : X_VT5_VA5_VB5 <63, 36, "xsmulqp", - [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>; + [(set f128:$vT, (any_fmul f128:$vA, f128:$vB))]>; + } def XSSUBQP : X_VT5_VA5_VB5 <63, 516, "xssubqp" , - [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>; + [(set f128:$vT, (any_fsub f128:$vA, f128:$vB))]>; def XSDIVQP : X_VT5_VA5_VB5 <63, 548, "xsdivqp", - [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>; + [(set f128:$vT, (any_fdiv f128:$vA, f128:$vB))]>; + } // Square-Root def XSSQRTQP : X_VT5_XO5_VB5 <63, 27, 804, "xssqrtqp", [(set f128:$vT, (fsqrt f128:$vB))]>; Index: llvm/test/CodeGen/PowerPC/fp-strict-add-f128.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-add-f128.ll @@ -0,0 +1,16 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 -enable-ppc-quad-precision=true | FileCheck %s + + + +declare fp128 @llvm.experimental.constrained.fadd.f128(fp128, fp128, metadata, metadata) + +define void @f1(fp128 %f1, fp128 %f2) { +; CHECK-LABEL: f1: +; CHECK-PWR9: xsaddqp vs0, v2, v3 +; CHECK-PWR9-NEXT: blr + call fp128 @llvm.experimental.constrained.fadd.f128( + fp128 %f1, fp128 %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} Index: llvm/test/CodeGen/PowerPC/fp-strict-add.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-add.ll @@ -0,0 +1,54 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64-unknown-linux -mcpu=pwr8 | FileCheck %s +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 | FileCheck %s + + +declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata) +declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) +declare fp128 @llvm.experimental.constrained.fadd.f128(fp128, fp128, metadata, metadata) +declare <4 x float> @llvm.experimental.constrained.fadd.v4f32(<4 x float>, <4 x float>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.fadd.v2f64(<2 x double>, <2 x double>, metadata, metadata) + +define void @f1(float %f1, float %f2) { +; CHECK-LABEL: f1: +; CHECK: xsaddsp f0, f1, f2 +; CHECK-NEXT: blr + call float @llvm.experimental.constrained.fadd.f32( + float %f1, float %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f2(double %f1, double %f2) { +; CHECK-LABEL: f2: +; CHECK: xsadddp f0, f1, f2 +; CHECK-NEXT: blr + call double @llvm.experimental.constrained.fadd.f64( + double %f1, double %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f3(<4 x float> %vf1, <4 x float> %vf2) { +; CHECK-LABEL: f3: +; CHECK: xvaddsp vs0, v2, v3 +; CHECK-NEXT: blr + call <4 x float> @llvm.experimental.constrained.fadd.v4f32( + <4 x float> %vf1, <4 x float> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f4(<2 x double> %vf1, <2 x double> %vf2) { +; CHECK-LABEL: f4: +; CHECK: xvadddp vs0, v2, v3 +; CHECK-NEXT: blr + call <2 x double> @llvm.experimental.constrained.fadd.v2f64( + <2 x double> %vf1, <2 x double> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + Index: llvm/test/CodeGen/PowerPC/fp-strict-div-f128.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-div-f128.ll @@ -0,0 +1,16 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 -enable-ppc-quad-precision=true | FileCheck %s + + + +declare fp128 @llvm.experimental.constrained.fdiv.f128(fp128, fp128, metadata, metadata) + +define void @f1(fp128 %f1, fp128 %f2) { +; CHECK-LABEL: f1: +; CHECK-PWR9: xsdivqp vs0, v2, v3 +; CHECK-PWR9-NEXT: blr + call fp128 @llvm.experimental.constrained.fdiv.f128( + fp128 %f1, fp128 %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} Index: llvm/test/CodeGen/PowerPC/fp-strict-div.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-div.ll @@ -0,0 +1,54 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64-unknown-linux -mcpu=pwr8 | FileCheck %s +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 | FileCheck %s + + +declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata) +declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata) +declare fp128 @llvm.experimental.constrained.fdiv.f128(fp128, fp128, metadata, metadata) +declare <4 x float> @llvm.experimental.constrained.fdiv.v4f32(<4 x float>, <4 x float>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.fdiv.v2f64(<2 x double>, <2 x double>, metadata, metadata) + +define void @f1(float %f1, float %f2) { +; CHECK-LABEL: f1: +; CHECK: xsdivsp f0, f1, f2 +; CHECK-NEXT: blr + call float @llvm.experimental.constrained.fdiv.f32( + float %f1, float %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f2(double %f1, double %f2) { +; CHECK-LABEL: f2: +; CHECK: xsdivdp f0, f1, f2 +; CHECK-NEXT: blr + call double @llvm.experimental.constrained.fdiv.f64( + double %f1, double %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f3(<4 x float> %vf1, <4 x float> %vf2) { +; CHECK-LABEL: f3: +; CHECK: xvdivsp vs0, v2, v3 +; CHECK-NEXT: blr + call <4 x float> @llvm.experimental.constrained.fdiv.v4f32( + <4 x float> %vf1, <4 x float> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f4(<2 x double> %vf1, <2 x double> %vf2) { +; CHECK-LABEL: f4: +; CHECK: xvdivdp vs0, v2, v3 +; CHECK-NEXT: blr + call <2 x double> @llvm.experimental.constrained.fdiv.v2f64( + <2 x double> %vf1, <2 x double> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + Index: llvm/test/CodeGen/PowerPC/fp-strict-mul-f128.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-mul-f128.ll @@ -0,0 +1,16 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 -enable-ppc-quad-precision=true | FileCheck %s + + + +declare fp128 @llvm.experimental.constrained.fmul.f128(fp128, fp128, metadata, metadata) + +define void @f1(fp128 %f1, fp128 %f2) { +; CHECK-LABEL: f1: +; CHECK-PWR9: xsmulqp vs0, v2, v3 +; CHECK-PWR9-NEXT: blr + call fp128 @llvm.experimental.constrained.fmul.f128( + fp128 %f1, fp128 %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} Index: llvm/test/CodeGen/PowerPC/fp-strict-mul.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-mul.ll @@ -0,0 +1,54 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64-unknown-linux -mcpu=pwr8 | FileCheck %s +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 | FileCheck %s + + +declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata) +declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata) +declare fp128 @llvm.experimental.constrained.fmul.f128(fp128, fp128, metadata, metadata) +declare <4 x float> @llvm.experimental.constrained.fmul.v4f32(<4 x float>, <4 x float>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double>, <2 x double>, metadata, metadata) + +define void @f1(float %f1, float %f2) { +; CHECK-LABEL: f1: +; CHECK: xsmulsp f0, f1, f2 +; CHECK-NEXT: blr + call float @llvm.experimental.constrained.fmul.f32( + float %f1, float %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f2(double %f1, double %f2) { +; CHECK-LABEL: f2: +; CHECK: xsmuldp f0, f1, f2 +; CHECK-NEXT: blr + call double @llvm.experimental.constrained.fmul.f64( + double %f1, double %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f3(<4 x float> %vf1, <4 x float> %vf2) { +; CHECK-LABEL: f3: +; CHECK: xvmulsp vs0, v2, v3 +; CHECK-NEXT: blr + call <4 x float> @llvm.experimental.constrained.fmul.v4f32( + <4 x float> %vf1, <4 x float> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f4(<2 x double> %vf1, <2 x double> %vf2) { +; CHECK-LABEL: f4: +; CHECK: xvmuldp vs0, v2, v3 +; CHECK-NEXT: blr + call <2 x double> @llvm.experimental.constrained.fmul.v2f64( + <2 x double> %vf1, <2 x double> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + Index: llvm/test/CodeGen/PowerPC/fp-strict-sub-f128.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-sub-f128.ll @@ -0,0 +1,16 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 -enable-ppc-quad-precision=true | FileCheck %s + + + +declare fp128 @llvm.experimental.constrained.fsub.f128(fp128, fp128, metadata, metadata) + +define void @f1(fp128 %f1, fp128 %f2) { +; CHECK-LABEL: f1: +; CHECK-PWR9: xssubqp vs0, v2, v3 +; CHECK-PWR9-NEXT: blr + call fp128 @llvm.experimental.constrained.fsub.f128( + fp128 %f1, fp128 %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} Index: llvm/test/CodeGen/PowerPC/fp-strict-sub.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/fp-strict-sub.ll @@ -0,0 +1,54 @@ +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64-unknown-linux -mcpu=pwr8 | FileCheck %s +; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 | FileCheck %s + + +declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata) +declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata) +declare fp128 @llvm.experimental.constrained.fsub.f128(fp128, fp128, metadata, metadata) +declare <4 x float> @llvm.experimental.constrained.fsub.v4f32(<4 x float>, <4 x float>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.fsub.v2f64(<2 x double>, <2 x double>, metadata, metadata) + +define void @f1(float %f1, float %f2) { +; CHECK-LABEL: f1: +; CHECK: xssubsp f0, f1, f2 +; CHECK-NEXT: blr + call float @llvm.experimental.constrained.fsub.f32( + float %f1, float %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f2(double %f1, double %f2) { +; CHECK-LABEL: f2: +; CHECK: xssubdp f0, f1, f2 +; CHECK-NEXT: blr + call double @llvm.experimental.constrained.fsub.f64( + double %f1, double %f2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f3(<4 x float> %vf1, <4 x float> %vf2) { +; CHECK-LABEL: f3: +; CHECK: xvsubsp vs0, v2, v3 +; CHECK-NEXT: blr + call <4 x float> @llvm.experimental.constrained.fsub.v4f32( + <4 x float> %vf1, <4 x float> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + +define void @f4(<2 x double> %vf1, <2 x double> %vf2) { +; CHECK-LABEL: f4: +; CHECK: xvsubdp vs0, v2, v3 +; CHECK-NEXT: blr + call <2 x double> @llvm.experimental.constrained.fsub.v2f64( + <2 x double> %vf1, <2 x double> %vf2, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret void; +} + Index: llvm/test/CodeGen/PowerPC/vector-constrained-fp-intrinsics.ll =================================================================== --- llvm/test/CodeGen/PowerPC/vector-constrained-fp-intrinsics.ll +++ llvm/test/CodeGen/PowerPC/vector-constrained-fp-intrinsics.ll @@ -191,8 +191,8 @@ ; PC64LE-NEXT: xxswapd 0, 0 ; PC64LE-NEXT: xxswapd 1, 1 ; PC64LE-NEXT: xxswapd 2, 2 -; PC64LE-NEXT: xvdivdp 34, 1, 0 -; PC64LE-NEXT: xvdivdp 35, 2, 0 +; PC64LE-NEXT: xvdivdp 35, 1, 0 +; PC64LE-NEXT: xvdivdp 34, 2, 0 ; PC64LE-NEXT: blr ; ; PC64LE9-LABEL: constrained_vector_fdiv_v4f64: @@ -205,9 +205,9 @@ ; PC64LE9-NEXT: lxvx 1, 0, 3 ; PC64LE9-NEXT: addis 3, 2, .LCPI4_2@toc@ha ; PC64LE9-NEXT: addi 3, 3, .LCPI4_2@toc@l -; PC64LE9-NEXT: xvdivdp 34, 1, 0 -; PC64LE9-NEXT: lxvx 1, 0, 3 ; PC64LE9-NEXT: xvdivdp 35, 1, 0 +; PC64LE9-NEXT: lxvx 1, 0, 3 +; PC64LE9-NEXT: xvdivdp 34, 1, 0 ; PC64LE9-NEXT: blr entry: %div = call <4 x double> @llvm.experimental.constrained.fdiv.v4f64( @@ -863,8 +863,8 @@ ; PC64LE-NEXT: xxswapd 0, 0 ; PC64LE-NEXT: xxswapd 1, 1 ; PC64LE-NEXT: xxswapd 2, 2 -; PC64LE-NEXT: xvmuldp 34, 1, 0 -; PC64LE-NEXT: xvmuldp 35, 1, 2 +; PC64LE-NEXT: xvmuldp 35, 1, 0 +; PC64LE-NEXT: xvmuldp 34, 1, 2 ; PC64LE-NEXT: blr ; ; PC64LE9-LABEL: constrained_vector_fmul_v4f64: @@ -877,9 +877,9 @@ ; PC64LE9-NEXT: lxvx 1, 0, 3 ; PC64LE9-NEXT: addis 3, 2, .LCPI14_2@toc@ha ; PC64LE9-NEXT: addi 3, 3, .LCPI14_2@toc@l -; PC64LE9-NEXT: xvmuldp 34, 1, 0 -; PC64LE9-NEXT: lxvx 0, 0, 3 ; PC64LE9-NEXT: xvmuldp 35, 1, 0 +; PC64LE9-NEXT: lxvx 0, 0, 3 +; PC64LE9-NEXT: xvmuldp 34, 1, 0 ; PC64LE9-NEXT: blr entry: %mul = call <4 x double> @llvm.experimental.constrained.fmul.v4f64( @@ -1079,8 +1079,8 @@ ; PC64LE-NEXT: xxswapd 0, 0 ; PC64LE-NEXT: xxswapd 1, 1 ; PC64LE-NEXT: xxswapd 2, 2 -; PC64LE-NEXT: xvadddp 34, 1, 0 -; PC64LE-NEXT: xvadddp 35, 1, 2 +; PC64LE-NEXT: xvadddp 35, 1, 0 +; PC64LE-NEXT: xvadddp 34, 1, 2 ; PC64LE-NEXT: blr ; ; PC64LE9-LABEL: constrained_vector_fadd_v4f64: @@ -1093,9 +1093,9 @@ ; PC64LE9-NEXT: lxvx 1, 0, 3 ; PC64LE9-NEXT: addis 3, 2, .LCPI19_2@toc@ha ; PC64LE9-NEXT: addi 3, 3, .LCPI19_2@toc@l -; PC64LE9-NEXT: xvadddp 34, 1, 0 -; PC64LE9-NEXT: lxvx 0, 0, 3 ; PC64LE9-NEXT: xvadddp 35, 1, 0 +; PC64LE9-NEXT: lxvx 0, 0, 3 +; PC64LE9-NEXT: xvadddp 34, 1, 0 ; PC64LE9-NEXT: blr entry: %add = call <4 x double> @llvm.experimental.constrained.fadd.v4f64( @@ -1295,8 +1295,8 @@ ; PC64LE-NEXT: xxswapd 0, 0 ; PC64LE-NEXT: xxswapd 1, 1 ; PC64LE-NEXT: xxswapd 2, 2 -; PC64LE-NEXT: xvsubdp 34, 1, 0 -; PC64LE-NEXT: xvsubdp 35, 1, 2 +; PC64LE-NEXT: xvsubdp 35, 1, 0 +; PC64LE-NEXT: xvsubdp 34, 1, 2 ; PC64LE-NEXT: blr ; ; PC64LE9-LABEL: constrained_vector_fsub_v4f64: @@ -1309,9 +1309,9 @@ ; PC64LE9-NEXT: lxvx 1, 0, 3 ; PC64LE9-NEXT: addis 3, 2, .LCPI24_2@toc@ha ; PC64LE9-NEXT: addi 3, 3, .LCPI24_2@toc@l -; PC64LE9-NEXT: xvsubdp 34, 1, 0 -; PC64LE9-NEXT: lxvx 0, 0, 3 ; PC64LE9-NEXT: xvsubdp 35, 1, 0 +; PC64LE9-NEXT: lxvx 0, 0, 3 +; PC64LE9-NEXT: xvsubdp 34, 1, 0 ; PC64LE9-NEXT: blr entry: %sub = call <4 x double> @llvm.experimental.constrained.fsub.v4f64(