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 @@ -11931,8 +11931,13 @@ BuildMI(*BB, MI, dl, TII->get(PPC::MFFS), MFFSReg); // Set rounding mode to round-to-zero. - BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB1)).addImm(31); - BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB0)).addImm(30); + BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB1)) + .addImm(31) + .addReg(PPC::RM, RegState::ImplicitDefine); + + BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB0)) + .addImm(30) + .addReg(PPC::RM, RegState::ImplicitDefine); // Perform addition. BuildMI(*BB, MI, dl, TII->get(PPC::FADD), Dest).addReg(Src1).addReg(Src2); @@ -11994,10 +11999,12 @@ // the immediate to set the bits 62:63 of FPSCR. unsigned Mode = MI.getOperand(1).getImm(); BuildMI(*BB, MI, dl, TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0)) - .addImm(31); + .addImm(31) + .addReg(PPC::RM, RegState::ImplicitDefine); BuildMI(*BB, MI, dl, TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0)) - .addImm(30); + .addImm(30) + .addReg(PPC::RM, RegState::ImplicitDefine); } else if (MI.getOpcode() == PPC::SETRND) { DebugLoc dl = MI.getDebugLoc(); diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -1563,11 +1563,12 @@ def BCn : BForm_4<16, 4, 0, 0, (outs), (ins crbitrc:$bi, condbrtarget:$dst), "bc 4, $bi, $dst">; - let isReturn = 1, Uses = [LR, RM] in + let isReturn = 1, Uses = [LR, RM] in { def BCLR : XLForm_2_br2<19, 16, 12, 0, (outs), (ins crbitrc:$bi), "bclr 12, $bi, 0", IIC_BrB, []>; def BCLRn : XLForm_2_br2<19, 16, 4, 0, (outs), (ins crbitrc:$bi), "bclr 4, $bi, 0", IIC_BrB, []>; + } } let isReturn = 1, Defs = [CTR], Uses = [CTR, LR, RM] in { @@ -2584,22 +2585,7 @@ def FTSQRT: XForm_17a<63, 160, (outs crrc:$crD), (ins f8rc:$fB), "ftsqrt $crD, $fB", IIC_FPCompare>; -let Uses = [RM], mayRaiseFPException = 1 in { - let hasSideEffects = 0 in { - defm FCTIW : XForm_26r<63, 14, (outs f8rc:$frD), (ins f8rc:$frB), - "fctiw", "$frD, $frB", IIC_FPGeneral, - []>; - defm FCTIWU : XForm_26r<63, 142, (outs f8rc:$frD), (ins f8rc:$frB), - "fctiwu", "$frD, $frB", IIC_FPGeneral, - []>; - defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$frD), (ins f8rc:$frB), - "fctiwz", "$frD, $frB", IIC_FPGeneral, - [(set f64:$frD, (PPCfctiwz f64:$frB))]>; - - defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB), - "frsp", "$frD, $frB", IIC_FPGeneral, - [(set f32:$frD, (any_fpround f64:$frB))]>; - +let mayRaiseFPException = 1, hasSideEffects = 0 in { let Interpretation64Bit = 1, isCodeGenOnly = 1 in defm FRIND : XForm_26r<63, 392, (outs f8rc:$frD), (ins f8rc:$frB), "frin", "$frD, $frB", IIC_FPGeneral, @@ -2607,9 +2593,7 @@ defm FRINS : XForm_26r<63, 392, (outs f4rc:$frD), (ins f4rc:$frB), "frin", "$frD, $frB", IIC_FPGeneral, [(set f32:$frD, (any_fround f32:$frB))]>; - } - let hasSideEffects = 0 in { let Interpretation64Bit = 1, isCodeGenOnly = 1 in defm FRIPD : XForm_26r<63, 456, (outs f8rc:$frD), (ins f8rc:$frB), "frip", "$frD, $frB", IIC_FPGeneral, @@ -2631,6 +2615,22 @@ defm FRIMS : XForm_26r<63, 488, (outs f4rc:$frD), (ins f4rc:$frB), "frim", "$frD, $frB", IIC_FPGeneral, [(set f32:$frD, (any_ffloor f32:$frB))]>; +} + +let Uses = [RM], mayRaiseFPException = 1, hasSideEffects = 0 in { + defm FCTIW : XForm_26r<63, 14, (outs f8rc:$frD), (ins f8rc:$frB), + "fctiw", "$frD, $frB", IIC_FPGeneral, + []>; + defm FCTIWU : XForm_26r<63, 142, (outs f8rc:$frD), (ins f8rc:$frB), + "fctiwu", "$frD, $frB", IIC_FPGeneral, + []>; + defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$frD), (ins f8rc:$frB), + "fctiwz", "$frD, $frB", IIC_FPGeneral, + [(set f64:$frD, (PPCfctiwz f64:$frB))]>; + + defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB), + "frsp", "$frD, $frB", IIC_FPGeneral, + [(set f32:$frD, (any_fpround f64:$frB))]>; defm FSQRT : XForm_26r<63, 22, (outs f8rc:$frD), (ins f8rc:$frB), "fsqrt", "$frD, $frB", IIC_FPSqrtD, @@ -2638,8 +2638,7 @@ defm FSQRTS : XForm_26r<59, 22, (outs f4rc:$frD), (ins f4rc:$frB), "fsqrts", "$frD, $frB", IIC_FPSqrtS, [(set f32:$frD, (any_fsqrt f32:$frB))]>; - } - } +} } /// Note that FMR is defined as pseudo-ops on the PPC970 because they are @@ -2916,13 +2915,17 @@ // The above pseudo gets expanded to make use of the following instructions // to manipulate FPSCR. Note that FPSCR is not modeled at the DAG level. -let Uses = [RM], Defs = [RM] in { - def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM), - "mtfsb0 $FM", IIC_IntMTFSB0, []>, - PPC970_DGroup_Single, PPC970_Unit_FPU; - def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM), - "mtfsb1 $FM", IIC_IntMTFSB0, []>, - PPC970_DGroup_Single, PPC970_Unit_FPU; + +// When FM is 30/31, we are setting the 62/63 bit of FPSCR, the implicit-def +// RM should be set. +def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM), + "mtfsb0 $FM", IIC_IntMTFSB0, []>, + PPC970_DGroup_Single, PPC970_Unit_FPU; +def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM), + "mtfsb1 $FM", IIC_IntMTFSB0, []>, + PPC970_DGroup_Single, PPC970_Unit_FPU; + +let Defs = [RM] in { let isCodeGenOnly = 1 in def MTFSFb : XFLForm<63, 711, (outs), (ins i32imm:$FM, f8rc:$rT), "mtfsf $FM, $rT", IIC_IntMTFSB0, []>, @@ -4318,6 +4321,8 @@ def MCRFS : XLForm_3<63, 64, (outs crrc:$BF), (ins crrc:$BFA), "mcrfs $BF, $BFA", IIC_BrMCR>; +// If W is 0 and BF is 7, the 60:63 bits will be set, we should set the +// implicit-def RM. def MTFSFI : XLForm_4<63, 134, (outs crrc:$BF), (ins i32imm:$U, i32imm:$W), "mtfsfi $BF, $U, $W", IIC_IntMFFS>; let Defs = [CR1] in @@ -4328,6 +4333,7 @@ def : InstAlias<"mtfsfi. $BF, $U", (MTFSFI_rec crrc:$BF, i32imm:$U, 0)>; let Predicates = [HasFPU] in { +let Defs = [RM] in { def MTFSF : XFLForm_1<63, 711, (outs), (ins i32imm:$FLM, f8rc:$FRB, i32imm:$L, i32imm:$W), "mtfsf $FLM, $FRB, $L, $W", IIC_IntMFFS, []>; @@ -4335,6 +4341,7 @@ def MTFSF_rec : XFLForm_1<63, 711, (outs), (ins i32imm:$FLM, f8rc:$FRB, i32imm:$L, i32imm:$W), "mtfsf. $FLM, $FRB, $L, $W", IIC_IntMFFS, []>, isRecordForm; +} def : InstAlias<"mtfsf $FLM, $FRB", (MTFSF i32imm:$FLM, f8rc:$FRB, 0, 0)>; def : InstAlias<"mtfsf. $FLM, $FRB", (MTFSF_rec i32imm:$FLM, f8rc:$FRB, 0, 0)>; diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -362,7 +362,8 @@ } } // mayStore - let Uses = [RM], mayRaiseFPException = 1 in { + let mayRaiseFPException = 1 in { + let Uses = [RM] in { // Add/Mul Instructions let isCommutable = 1 in { def XSADDDP : XX3Form<60, 32, @@ -885,15 +886,61 @@ "xvcvuxwsp $XT, $XB", IIC_VecFP, [(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>; - // Rounding Instructions - def XSRDPI : XX2Form<60, 73, - (outs vsfrc:$XT), (ins vsfrc:$XB), - "xsrdpi $XT, $XB", IIC_VecFP, - [(set f64:$XT, (any_fround f64:$XB))]>; + // Rounding Instructions respecting current rounding mode def XSRDPIC : XX2Form<60, 107, (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrdpic $XT, $XB", IIC_VecFP, [(set f64:$XT, (any_fnearbyint f64:$XB))]>; + def XVRDPIC : XX2Form<60, 235, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrdpic $XT, $XB", IIC_VecFP, + [(set v2f64:$XT, (any_fnearbyint v2f64:$XB))]>; + def XVRSPIC : XX2Form<60, 171, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrspic $XT, $XB", IIC_VecFP, + [(set v4f32:$XT, (any_fnearbyint v4f32:$XB))]>; + // Max/Min Instructions + let isCommutable = 1 in { + def XSMAXDP : XX3Form<60, 160, + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), + "xsmaxdp $XT, $XA, $XB", IIC_VecFP, + [(set vsfrc:$XT, + (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>; + def XSMINDP : XX3Form<60, 168, + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), + "xsmindp $XT, $XA, $XB", IIC_VecFP, + [(set vsfrc:$XT, + (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>; + + def XVMAXDP : XX3Form<60, 224, + (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + "xvmaxdp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>; + def XVMINDP : XX3Form<60, 232, + (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + "xvmindp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>; + + def XVMAXSP : XX3Form<60, 192, + (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + "xvmaxsp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>; + def XVMINSP : XX3Form<60, 200, + (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + "xvminsp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>; + } // isCommutable + } // Uses = [RM] + + // Rounding Instructions with static direction. + def XSRDPI : XX2Form<60, 73, + (outs vsfrc:$XT), (ins vsfrc:$XB), + "xsrdpi $XT, $XB", IIC_VecFP, + [(set f64:$XT, (any_fround f64:$XB))]>; def XSRDPIM : XX2Form<60, 121, (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrdpim $XT, $XB", IIC_VecFP, @@ -911,10 +958,6 @@ (outs vsrc:$XT), (ins vsrc:$XB), "xvrdpi $XT, $XB", IIC_VecFP, [(set v2f64:$XT, (any_fround v2f64:$XB))]>; - def XVRDPIC : XX2Form<60, 235, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrdpic $XT, $XB", IIC_VecFP, - [(set v2f64:$XT, (any_fnearbyint v2f64:$XB))]>; def XVRDPIM : XX2Form<60, 249, (outs vsrc:$XT), (ins vsrc:$XB), "xvrdpim $XT, $XB", IIC_VecFP, @@ -932,10 +975,6 @@ (outs vsrc:$XT), (ins vsrc:$XB), "xvrspi $XT, $XB", IIC_VecFP, [(set v4f32:$XT, (any_fround v4f32:$XB))]>; - def XVRSPIC : XX2Form<60, 171, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrspic $XT, $XB", IIC_VecFP, - [(set v4f32:$XT, (any_fnearbyint v4f32:$XB))]>; def XVRSPIM : XX2Form<60, 185, (outs vsrc:$XT), (ins vsrc:$XB), "xvrspim $XT, $XB", IIC_VecFP, @@ -948,43 +987,7 @@ (outs vsrc:$XT), (ins vsrc:$XB), "xvrspiz $XT, $XB", IIC_VecFP, [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>; - - // Max/Min Instructions - let isCommutable = 1 in { - def XSMAXDP : XX3Form<60, 160, - (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), - "xsmaxdp $XT, $XA, $XB", IIC_VecFP, - [(set vsfrc:$XT, - (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>; - def XSMINDP : XX3Form<60, 168, - (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), - "xsmindp $XT, $XA, $XB", IIC_VecFP, - [(set vsfrc:$XT, - (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>; - - def XVMAXDP : XX3Form<60, 224, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvmaxdp $XT, $XA, $XB", IIC_VecFP, - [(set vsrc:$XT, - (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>; - def XVMINDP : XX3Form<60, 232, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvmindp $XT, $XA, $XB", IIC_VecFP, - [(set vsrc:$XT, - (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>; - - def XVMAXSP : XX3Form<60, 192, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvmaxsp $XT, $XA, $XB", IIC_VecFP, - [(set vsrc:$XT, - (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>; - def XVMINSP : XX3Form<60, 200, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvminsp $XT, $XA, $XB", IIC_VecFP, - [(set vsrc:$XT, - (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>; - } // isCommutable - } // Uses = [RM], mayRaiseFPException + } // mayRaiseFPException // Logical Instructions let isCommutable = 1 in diff --git a/llvm/test/CodeGen/PowerPC/rounding-rm-flag.ll b/llvm/test/CodeGen/PowerPC/rounding-rm-flag.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/rounding-rm-flag.ll @@ -0,0 +1,26 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 -stop-after=early-ifcvt < %s | FileCheck %s + +define float @test_XSRDPI(float %f) { +entry: + %0 = tail call float @llvm.round.f32(float %f) + ret float %0 + +; CHECK-LABEL: name: test_XSRDPI +; CHECK-NOT: %2:vsfrc = nofpexcept XSRDPI killed %1, implicit $rm +; CHECK: %2:vsfrc = nofpexcept XSRDPI killed %1 +} + +define double @test_XSRDPIM(double %d) { +entry: + %0 = tail call double @llvm.floor.f64(double %d) + ret double %0 + +; CHECK-LABEL: name: test_XSRDPIM +; CHECK-NOT: %1:vsfrc = nofpexcept XSRDPIM %0, implicit $rm +; CHECK: %1:vsfrc = nofpexcept XSRDPIM %0 +} + +declare float @llvm.round.f32(float) +declare double @llvm.floor.f64(double) + diff --git a/llvm/test/CodeGen/PowerPC/setrnd.ll b/llvm/test/CodeGen/PowerPC/setrnd.ll --- a/llvm/test/CodeGen/PowerPC/setrnd.ll +++ b/llvm/test/CodeGen/PowerPC/setrnd.ll @@ -19,8 +19,8 @@ ; AFTER-FINALIZE-ISEL: test_setrndi ; AFTER-FINALIZE-ISEL: MFFS implicit $rm -; AFTER-FINALIZE-ISEL: MTFSB0 31, implicit-def $rm, implicit $rm -; AFTER-FINALIZE-ISEL: MTFSB1 30, implicit-def $rm, implicit $rm +; AFTER-FINALIZE-ISEL: MTFSB0 31, implicit-def $rm +; AFTER-FINALIZE-ISEL: MTFSB1 30, implicit-def $rm ; CHECK-LABEL: @test_setrndi ; CHECK: # %bb.0: @@ -40,7 +40,7 @@ ; AFTER-FINALIZE-ISEL: test_setrnd ; AFTER-FINALIZE-ISEL: MFFS implicit $rm -; AFTER-FINALIZE-ISEL: MTFSF 255, %7, 0, 0 +; AFTER-FINALIZE-ISEL: MTFSF 255, %7, 0, 0, implicit-def $rm ; CHECK-LABEL: @test_setrnd ; CHECK: # %bb.0: