diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 7f93831f44f..13dbcbe10d3 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -11931,8 +11931,13 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, 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 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, // 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/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index e4ec0f1e5ea..be1e59d7fae 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -1563,11 +1563,12 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in { 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 FTDIV: XForm_17<63, 128, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB), 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 @@ let Uses = [RM], mayRaiseFPException = 1 in { 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 @@ let Uses = [RM], mayRaiseFPException = 1 in { 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 @@ let Uses = [RM], mayRaiseFPException = 1 in { 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 @@ let Uses = [RM] in { // 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 MTMSRD : XForm_mtmsr<31, 178, (outs), (ins gprc:$RS, i32imm:$L), 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 crrc:$BF, i32imm:$U, 0)>; 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 @@ let Defs = [CR1] in 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/lib/Target/PowerPC/PPCInstrVSX.td b/lib/Target/PowerPC/PPCInstrVSX.td index 9ba5058a6f8..272f8b1c0aa 100644 --- a/lib/Target/PowerPC/PPCInstrVSX.td +++ b/lib/Target/PowerPC/PPCInstrVSX.td @@ -362,7 +362,8 @@ let hasSideEffects = 0 in { } } // 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,70 +886,19 @@ let hasSideEffects = 0 in { "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 XSRDPIM : XX2Form<60, 121, - (outs vsfrc:$XT), (ins vsfrc:$XB), - "xsrdpim $XT, $XB", IIC_VecFP, - [(set f64:$XT, (any_ffloor f64:$XB))]>; - def XSRDPIP : XX2Form<60, 105, - (outs vsfrc:$XT), (ins vsfrc:$XB), - "xsrdpip $XT, $XB", IIC_VecFP, - [(set f64:$XT, (any_fceil f64:$XB))]>; - def XSRDPIZ : XX2Form<60, 89, - (outs vsfrc:$XT), (ins vsfrc:$XB), - "xsrdpiz $XT, $XB", IIC_VecFP, - [(set f64:$XT, (any_ftrunc f64:$XB))]>; - - def XVRDPI : XX2Form<60, 201, - (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, - [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>; - def XVRDPIP : XX2Form<60, 233, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrdpip $XT, $XB", IIC_VecFP, - [(set v2f64:$XT, (any_fceil v2f64:$XB))]>; - def XVRDPIZ : XX2Form<60, 217, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrdpiz $XT, $XB", IIC_VecFP, - [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>; - - def XVRSPI : XX2Form<60, 137, - (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, - [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>; - def XVRSPIP : XX2Form<60, 169, - (outs vsrc:$XT), (ins vsrc:$XB), - "xvrspip $XT, $XB", IIC_VecFP, - [(set v4f32:$XT, (any_fceil v4f32:$XB))]>; - def XVRSPIZ : XX2Form<60, 153, - (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, @@ -984,7 +934,60 @@ let hasSideEffects = 0 in { [(set vsrc:$XT, (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>; } // isCommutable - } // Uses = [RM], mayRaiseFPException + } // 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, + [(set f64:$XT, (any_ffloor f64:$XB))]>; + def XSRDPIP : XX2Form<60, 105, + (outs vsfrc:$XT), (ins vsfrc:$XB), + "xsrdpip $XT, $XB", IIC_VecFP, + [(set f64:$XT, (any_fceil f64:$XB))]>; + def XSRDPIZ : XX2Form<60, 89, + (outs vsfrc:$XT), (ins vsfrc:$XB), + "xsrdpiz $XT, $XB", IIC_VecFP, + [(set f64:$XT, (any_ftrunc f64:$XB))]>; + + def XVRDPI : XX2Form<60, 201, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrdpi $XT, $XB", IIC_VecFP, + [(set v2f64:$XT, (any_fround v2f64:$XB))]>; + def XVRDPIM : XX2Form<60, 249, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrdpim $XT, $XB", IIC_VecFP, + [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>; + def XVRDPIP : XX2Form<60, 233, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrdpip $XT, $XB", IIC_VecFP, + [(set v2f64:$XT, (any_fceil v2f64:$XB))]>; + def XVRDPIZ : XX2Form<60, 217, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrdpiz $XT, $XB", IIC_VecFP, + [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>; + + def XVRSPI : XX2Form<60, 137, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrspi $XT, $XB", IIC_VecFP, + [(set v4f32:$XT, (any_fround v4f32:$XB))]>; + def XVRSPIM : XX2Form<60, 185, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrspim $XT, $XB", IIC_VecFP, + [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>; + def XVRSPIP : XX2Form<60, 169, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrspip $XT, $XB", IIC_VecFP, + [(set v4f32:$XT, (any_fceil v4f32:$XB))]>; + def XVRSPIZ : XX2Form<60, 153, + (outs vsrc:$XT), (ins vsrc:$XB), + "xvrspiz $XT, $XB", IIC_VecFP, + [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>; + } // mayRaiseFPException // Logical Instructions let isCommutable = 1 in diff --git a/test/CodeGen/PowerPC/rounding-rm-flag.ll b/test/CodeGen/PowerPC/rounding-rm-flag.ll new file mode 100644 index 00000000000..0af781f6657 --- /dev/null +++ b/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/test/CodeGen/PowerPC/setrnd.ll b/test/CodeGen/PowerPC/setrnd.ll index a732e3f73c9..9080a4b0ee5 100644 --- a/test/CodeGen/PowerPC/setrnd.ll +++ b/test/CodeGen/PowerPC/setrnd.ll @@ -19,8 +19,8 @@ entry: ; 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 @@ entry: ; 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: