diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-11-14 18:18:16 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-11-14 18:18:16 +0000 |
commit | 94812216ef33b71377b6aba125ce5da8d358712f (patch) | |
tree | a229156ff07829f29b0120865d0369a08596b323 /llvm/lib/Target | |
parent | 4bfa736f1bc9b0761a3806bd884fcbf48ad3e553 (diff) | |
download | bcm5719-llvm-94812216ef33b71377b6aba125ce5da8d358712f.tar.gz bcm5719-llvm-94812216ef33b71377b6aba125ce5da8d358712f.zip |
R600/SI: Use S_BFE_I64 for 64-bit sext_inreg
llvm-svn: 222012
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/R600/SIISelLowering.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.cpp | 66 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstructions.td | 23 |
5 files changed, 82 insertions, 17 deletions
diff --git a/llvm/lib/Target/R600/SIISelLowering.cpp b/llvm/lib/Target/R600/SIISelLowering.cpp index 25acaa57187..d8e424936da 100644 --- a/llvm/lib/Target/R600/SIISelLowering.cpp +++ b/llvm/lib/Target/R600/SIISelLowering.cpp @@ -136,8 +136,7 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) : setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i16, Custom); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i16, Custom); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Custom); - + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Legal); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::Other, Custom); setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); diff --git a/llvm/lib/Target/R600/SIInstrInfo.cpp b/llvm/lib/Target/R600/SIInstrInfo.cpp index 1c15eb8973e..97f2d4b5935 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.cpp +++ b/llvm/lib/Target/R600/SIInstrInfo.cpp @@ -1901,8 +1901,13 @@ void SIInstrInfo::moveToVALU(MachineInstr &TopInst) const { Inst->eraseFromParent(); continue; + case AMDGPU::S_BFE_I64: { + splitScalar64BitBFE(Worklist, Inst); + Inst->eraseFromParent(); + continue; + } + case AMDGPU::S_BFE_U64: - case AMDGPU::S_BFE_I64: case AMDGPU::S_BFM_B64: llvm_unreachable("Moving this op to VALU not implemented"); } @@ -2167,6 +2172,65 @@ void SIInstrInfo::splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist Worklist.push_back(Second); } +void SIInstrInfo::splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist, + MachineInstr *Inst) const { + MachineBasicBlock &MBB = *Inst->getParent(); + MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); + MachineBasicBlock::iterator MII = Inst; + DebugLoc DL = Inst->getDebugLoc(); + + MachineOperand &Dest = Inst->getOperand(0); + uint32_t Imm = Inst->getOperand(2).getImm(); + uint32_t Offset = Imm & 0x3f; // Extract bits [5:0]. + uint32_t BitWidth = (Imm & 0x7f0000) >> 16; // Extract bits [22:16]. + + // Only sext_inreg cases handled. + assert(Inst->getOpcode() == AMDGPU::S_BFE_I64 && + BitWidth <= 32 && + Offset == 0 && + "Not implemented"); + + if (BitWidth < 32) { + unsigned MidRegLo = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + unsigned MidRegHi = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + unsigned ResultReg = MRI.createVirtualRegister(&AMDGPU::VReg_64RegClass); + + BuildMI(MBB, MII, DL, get(AMDGPU::V_BFE_I32), MidRegLo) + .addReg(Inst->getOperand(1).getReg(), 0, AMDGPU::sub0) + .addImm(0) + .addImm(BitWidth); + + BuildMI(MBB, MII, DL, get(AMDGPU::V_ASHRREV_I32_e32), MidRegHi) + .addImm(31) + .addReg(MidRegLo); + + BuildMI(MBB, MII, DL, get(TargetOpcode::REG_SEQUENCE), ResultReg) + .addReg(MidRegLo) + .addImm(AMDGPU::sub0) + .addReg(MidRegHi) + .addImm(AMDGPU::sub1); + + MRI.replaceRegWith(Dest.getReg(), ResultReg); + return; + } + + MachineOperand &Src = Inst->getOperand(1); + unsigned TmpReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + unsigned ResultReg = MRI.createVirtualRegister(&AMDGPU::VReg_64RegClass); + + BuildMI(MBB, MII, DL, get(AMDGPU::V_ASHRREV_I32_e64), TmpReg) + .addImm(31) + .addReg(Src.getReg(), 0, AMDGPU::sub0); + + BuildMI(MBB, MII, DL, get(TargetOpcode::REG_SEQUENCE), ResultReg) + .addReg(Src.getReg(), 0, AMDGPU::sub0) + .addImm(AMDGPU::sub0) + .addReg(TmpReg) + .addImm(AMDGPU::sub1); + + MRI.replaceRegWith(Dest.getReg(), ResultReg); +} + void SIInstrInfo::addDescImplicitUseDef(const MCInstrDesc &NewDesc, MachineInstr *Inst) const { // Add the implict and explicit register definitions. diff --git a/llvm/lib/Target/R600/SIInstrInfo.h b/llvm/lib/Target/R600/SIInstrInfo.h index 5c5d8476235..ce32fd7fa65 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.h +++ b/llvm/lib/Target/R600/SIInstrInfo.h @@ -52,6 +52,8 @@ private: void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist, MachineInstr *Inst) const; + void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist, + MachineInstr *Inst) const; void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const; diff --git a/llvm/lib/Target/R600/SIInstrInfo.td b/llvm/lib/Target/R600/SIInstrInfo.td index b84a2b12149..2c9ffaffca8 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.td +++ b/llvm/lib/Target/R600/SIInstrInfo.td @@ -350,6 +350,11 @@ class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 < opName#" $dst, $src0, $src1", pattern >; +class SOP2_64_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 < + op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1), + opName#" $dst, $src0, $src1", pattern +>; + class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 < op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1", pattern diff --git a/llvm/lib/Target/R600/SIInstructions.td b/llvm/lib/Target/R600/SIInstructions.td index 193a083085a..6dcb6de0797 100644 --- a/llvm/lib/Target/R600/SIInstructions.td +++ b/llvm/lib/Target/R600/SIInstructions.td @@ -297,7 +297,7 @@ def S_MUL_I32 : SOP2_32 <0x00000026, "s_mul_i32", def S_BFE_U32 : SOP2_32 <0x00000027, "s_bfe_u32", []>; def S_BFE_I32 : SOP2_32 <0x00000028, "s_bfe_i32", []>; def S_BFE_U64 : SOP2_64 <0x00000029, "s_bfe_u64", []>; -def S_BFE_I64 : SOP2_64 <0x0000002a, "s_bfe_i64", []>; +def S_BFE_I64 : SOP2_64_32 <0x0000002a, "s_bfe_i64", []>; //def S_CBRANCH_G_FORK : SOP2_ <0x0000002b, "s_cbranch_g_fork", []>; def S_ABSDIFF_I32 : SOP2_32 <0x0000002c, "s_absdiff_i32", []>; @@ -2972,30 +2972,25 @@ defm : SI_INDIRECT_Pattern <v16i32, i32, SI_INDIRECT_DST_V16>; def : Pat<(i32 (sext_inreg i32:$src, i1)), (S_BFE_I32 i32:$src, 65536)>; // 0 | 1 << 16 -// TODO: Match 64-bit BFE. SI has a 64-bit BFE, but it's scalar only so it -// might not be worth the effort, and will need to expand to shifts when -// fixing SGPR copies. - // Handle sext_inreg in i64 def : Pat < (i64 (sext_inreg i64:$src, i1)), - (REG_SEQUENCE SReg_64, - (S_BFE_I32 (EXTRACT_SUBREG i64:$src, sub0), 65536), sub0, // 0 | 1 << 16 - (S_MOV_B32 -1), sub1) + (S_BFE_I64 i64:$src, 0x10000) // 0 | 1 << 16 >; def : Pat < (i64 (sext_inreg i64:$src, i8)), - (REG_SEQUENCE SReg_64, - (S_SEXT_I32_I8 (EXTRACT_SUBREG i64:$src, sub0)), sub0, - (S_MOV_B32 -1), sub1) + (S_BFE_I64 i64:$src, 0x80000) // 0 | 8 << 16 >; def : Pat < (i64 (sext_inreg i64:$src, i16)), - (REG_SEQUENCE SReg_64, - (S_SEXT_I32_I16 (EXTRACT_SUBREG i64:$src, sub0)), sub0, - (S_MOV_B32 -1), sub1) + (S_BFE_I64 i64:$src, 0x100000) // 0 | 16 << 16 +>; + +def : Pat < + (i64 (sext_inreg i64:$src, i32)), + (S_BFE_I64 i64:$src, 0x200000) // 0 | 32 << 16 >; class ZExt_i64_i32_Pat <SDNode ext> : Pat < |