diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2014-08-22 18:49:33 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2014-08-22 18:49:33 +0000 |
commit | 85e8b6d5f90399ff1bb57a51393432efcc2863f6 (patch) | |
tree | 21c81e73cc2e18764becff3f315a00b3706c10fb /llvm/lib | |
parent | ca7ecf3dfac3efd68ece30bd6d81e746fa5f4d96 (diff) | |
download | llvm-85e8b6d5f90399ff1bb57a51393432efcc2863f6.zip llvm-85e8b6d5f90399ff1bb57a51393432efcc2863f6.tar.gz llvm-85e8b6d5f90399ff1bb57a51393432efcc2863f6.tar.bz2 |
R600/SI: Use a ComplexPattern for DS loads and stores
llvm-svn: 216278
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp | 38 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/R600/SIInstructions.td | 50 |
3 files changed, 58 insertions, 32 deletions
diff --git a/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp index ee7d217..7911b6f 100644 --- a/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/R600/AMDGPUISelDAGToDAG.cpp @@ -88,6 +88,9 @@ private: SDValue& Offset); bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset); bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset); + bool isDSOffsetLegal(const SDValue &Base, unsigned Offset, + unsigned OffsetBits) const; + bool SelectDS1Addr1Offset(SDValue Ptr, SDValue &Base, SDValue &Offset) const; void SelectMUBUF(SDValue Addr, SDValue &SRsrc, SDValue &VAddr, SDValue &SOffset, SDValue &Offset, SDValue &Offen, SDValue &Idxen, SDValue &Addr64, SDValue &GLC, SDValue &SLC, @@ -744,6 +747,41 @@ SDNode *AMDGPUDAGToDAGISel::SelectDIV_SCALE(SDNode *N) { return CurDAG->SelectNodeTo(N, Opc, VT, MVT::i1, Ops); } +bool AMDGPUDAGToDAGISel::isDSOffsetLegal(const SDValue &Base, unsigned Offset, + unsigned OffsetBits) const { + const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); + if ((OffsetBits == 16 && !isUInt<16>(Offset)) || + (OffsetBits == 8 && !isUInt<8>(Offset))) + return false; + + if (ST.getGeneration() >= AMDGPUSubtarget::SEA_ISLANDS) + return true; + + // On Southern Islands instruction with a negative base value and an offset + // don't seem to work. + return CurDAG->SignBitIsZero(Base); +} + +bool AMDGPUDAGToDAGISel::SelectDS1Addr1Offset(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + if (CurDAG->isBaseWithConstantOffset(Addr)) { + SDValue N0 = Addr.getOperand(0); + SDValue N1 = Addr.getOperand(1); + ConstantSDNode *C1 = cast<ConstantSDNode>(N1); + if (isDSOffsetLegal(N0, C1->getSExtValue(), 16)) { + // (add n0, c0) + Base = N0; + Offset = N1; + return true; + } + } + + // default case + Base = Addr; + Offset = CurDAG->getTargetConstant(0, MVT::i16); + return true; +} + static SDValue wrapAddr64Rsrc(SelectionDAG *DAG, SDLoc DL, SDValue Ptr) { return SDValue(DAG->getMachineNode(AMDGPU::SI_ADDR64_RSRC, DL, MVT::v4i32, Ptr), 0); diff --git a/llvm/lib/Target/R600/SIInstrInfo.td b/llvm/lib/Target/R600/SIInstrInfo.td index 7560cef..5357af9 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.td +++ b/llvm/lib/Target/R600/SIInstrInfo.td @@ -191,6 +191,8 @@ def tfe : Operand <i1> { // Complex patterns //===----------------------------------------------------------------------===// +def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">; + def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">; def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">; def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">; diff --git a/llvm/lib/Target/R600/SIInstructions.td b/llvm/lib/Target/R600/SIInstructions.td index 01db459..40fca9f 100644 --- a/llvm/lib/Target/R600/SIInstructions.td +++ b/llvm/lib/Target/R600/SIInstructions.td @@ -2520,41 +2520,27 @@ def : ROTRPattern <V_ALIGNBIT_B32>; /********** Load/Store Patterns **********/ /********** ======================= **********/ -multiclass DSReadPat <DS inst, ValueType vt, PatFrag frag> { - def : Pat < - (vt (frag (add i32:$ptr, (i32 IMM16bit:$offset)))), - (inst (i1 0), $ptr, (as_i16imm $offset)) - >; - - def : Pat < - (frag i32:$src0), - (vt (inst 0, $src0, 0)) - >; -} - -defm : DSReadPat <DS_READ_I8, i32, sextloadi8_local>; -defm : DSReadPat <DS_READ_U8, i32, az_extloadi8_local>; -defm : DSReadPat <DS_READ_I16, i32, sextloadi16_local>; -defm : DSReadPat <DS_READ_U16, i32, az_extloadi16_local>; -defm : DSReadPat <DS_READ_B32, i32, local_load>; -defm : DSReadPat <DS_READ_B64, v2i32, local_load>; +class DSReadPat <DS inst, ValueType vt, PatFrag frag> : Pat < + (vt (frag (DS1Addr1Offset i32:$ptr, i32:$offset))), + (inst (i1 0), $ptr, (as_i16imm $offset)) +>; -multiclass DSWritePat <DS inst, ValueType vt, PatFrag frag> { - def : Pat < - (frag vt:$value, (add i32:$ptr, (i32 IMM16bit:$offset))), - (inst (i1 0), $ptr, $value, (as_i16imm $offset)) - >; +def : DSReadPat <DS_READ_I8, i32, sextloadi8_local>; +def : DSReadPat <DS_READ_U8, i32, az_extloadi8_local>; +def : DSReadPat <DS_READ_I16, i32, sextloadi16_local>; +def : DSReadPat <DS_READ_U16, i32, az_extloadi16_local>; +def : DSReadPat <DS_READ_B32, i32, local_load>; +def : DSReadPat <DS_READ_B64, v2i32, local_load>; - def : Pat < - (frag vt:$val, i32:$ptr), - (inst 0, $ptr, $val, 0) - >; -} +class DSWritePat <DS inst, ValueType vt, PatFrag frag> : Pat < + (frag vt:$value, (DS1Addr1Offset i32:$ptr, i32:$offset)), + (inst (i1 0), $ptr, $value, (as_i16imm $offset)) +>; -defm : DSWritePat <DS_WRITE_B8, i32, truncstorei8_local>; -defm : DSWritePat <DS_WRITE_B16, i32, truncstorei16_local>; -defm : DSWritePat <DS_WRITE_B32, i32, local_store>; -defm : DSWritePat <DS_WRITE_B64, v2i32, local_store>; +def : DSWritePat <DS_WRITE_B8, i32, truncstorei8_local>; +def : DSWritePat <DS_WRITE_B16, i32, truncstorei16_local>; +def : DSWritePat <DS_WRITE_B32, i32, local_store>; +def : DSWritePat <DS_WRITE_B64, v2i32, local_store>; multiclass DSAtomicRetPat<DS inst, ValueType vt, PatFrag frag> { def : Pat < |