On Thu, Feb 13, 2014 at 07:56:26AM -0800, Matt Arsenault wrote: > > On Feb 7, 2014, at 7:46 AM, Tom Stellard <t...@stellard.net> wrote: > > > From: Tom Stellard <thomas.stell...@amd.com> > > > > --- > > lib/Target/R600/AMDGPUISelDAGToDAG.cpp | 48 > > ++++++++++++++++++++++++++++++++++ > > lib/Target/R600/SIISelLowering.cpp | 29 -------------------- > > lib/Target/R600/SIISelLowering.h | 1 - > > test/CodeGen/R600/add.ll | 10 +++++++ > > test/CodeGen/R600/add_i64.ll | 23 +++++++++++----- > > 5 files changed, 75 insertions(+), 36 deletions(-) > > > > diff --git a/lib/Target/R600/AMDGPUISelDAGToDAG.cpp > > b/lib/Target/R600/AMDGPUISelDAGToDAG.cpp > > index a989135..fea875c 100644 > > --- a/lib/Target/R600/AMDGPUISelDAGToDAG.cpp > > +++ b/lib/Target/R600/AMDGPUISelDAGToDAG.cpp > > @@ -200,6 +200,54 @@ SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) { > > } > > switch (Opc) { > > default: break; > > + // We are selecting i64 ADD here instead of custom lower it during > > + // DAG legalization, so we can fold some i64 ADDs used for address > > + // calculation into the LOAD and STORE instructions. > > + case ISD::ADD: { > > + const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); > > + if (N->getValueType(0) != MVT::i64 || > > + ST.getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) > > + break; > > + > > + SDLoc DL(N); > > + SDValue LHS = N->getOperand(0); > > + SDValue RHS = N->getOperand(1); > > + > > + SDValue Sub0 = CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32); > > + SDValue Sub1 = CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32); > > + > > + SDNode *Lo0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, > > + DL, MVT::i32, LHS, Sub0); > > + SDNode *Hi0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, > > + DL, MVT::i32, LHS, Sub1); > > + > > + SDNode *Lo1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, > > + DL, MVT::i32, RHS, Sub0); > > + SDNode *Hi1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, > > + DL, MVT::i32, RHS, Sub1); > > + > > + SDVTList VTList = CurDAG->getVTList(MVT::i32, MVT::Glue); > > + > > + SmallVector<SDValue, 8> AddLoArgs; > > + AddLoArgs.push_back(SDValue(Lo0, 0)); > > + AddLoArgs.push_back(SDValue(Lo1, 0)); > > + > > + SDNode *AddLo = CurDAG->getMachineNode(AMDGPU::S_ADD_I32, DL, > > + VTList, AddLoArgs); > > + SDValue Carry = SDValue(AddLo, 1); > > + SDNode *AddHi = CurDAG->getMachineNode(AMDGPU::S_ADDC_U32, DL, > > + MVT::i32, SDValue(Hi0, 0), > > + SDValue(Hi1, 0), Carry); > > + > > + SDValue Args[5] = { > > + CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, MVT::i32), > > + SDValue(AddLo,0), > > + Sub0, > > + SDValue(AddHi,0), > > + Sub1, > > + }; > > + return CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, MVT::i64, Args, > > 5); > > + } > > case ISD::BUILD_VECTOR: { > > unsigned RegClassID; > > const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); > > diff --git a/lib/Target/R600/SIISelLowering.cpp > > b/lib/Target/R600/SIISelLowering.cpp > > index 0a22d16..4d2f370 100644 > > --- a/lib/Target/R600/SIISelLowering.cpp > > +++ b/lib/Target/R600/SIISelLowering.cpp > > @@ -76,7 +76,6 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) : > > setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v16i32, Expand); > > setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v16f32, Expand); > > > > - setOperationAction(ISD::ADD, MVT::i64, Legal); > > Would it be better to mark this as custom lowered, and then just return > SDValue() for it? That way it won’t be incorrectly reported as legal for > anything that might be checking. >
That's an interesting idea, but if we do that then the legalizer will try to expand the nodes, which isn't much of a problem now since there is no ExpandNode implementation for ISD:ADD, but someone may want to add one in the future. I think most places use isLegalOrCustom(), so it may not make much of a difference anyway. -Tom > > setOperationAction(ISD::ADD, MVT::i32, Legal); > > setOperationAction(ISD::ADDC, MVT::i32, Legal); > > setOperationAction(ISD::ADDE, MVT::i32, Legal); > > @@ -475,7 +474,6 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, > > SelectionDAG &DAG) const { > > SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); > > switch (Op.getOpcode()) { > > default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); > > - case ISD::ADD: return LowerADD(Op, DAG); > > case ISD::BRCOND: return LowerBRCOND(Op, DAG); > > case ISD::LOAD: { > > LoadSDNode *Load = dyn_cast<LoadSDNode>(Op); > > @@ -613,33 +611,6 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, > > SelectionDAG &DAG) const { > > return SDValue(); > > } > > > > -SDValue SITargetLowering::LowerADD(SDValue Op, > > - SelectionDAG &DAG) const { > > - if (Op.getValueType() != MVT::i64) > > - return SDValue(); > > - > > - SDLoc DL(Op); > > - SDValue LHS = Op.getOperand(0); > > - SDValue RHS = Op.getOperand(1); > > - > > - SDValue Zero = DAG.getConstant(0, MVT::i32); > > - SDValue One = DAG.getConstant(1, MVT::i32); > > - > > - SDValue Lo0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS, Zero); > > - SDValue Hi0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS, One); > > - > > - SDValue Lo1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS, Zero); > > - SDValue Hi1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS, One); > > - > > - SDVTList VTList = DAG.getVTList(MVT::i32, MVT::Glue); > > - > > - SDValue AddLo = DAG.getNode(ISD::ADDC, DL, VTList, Lo0, Lo1); > > - SDValue Carry = AddLo.getValue(1); > > - SDValue AddHi = DAG.getNode(ISD::ADDE, DL, VTList, Hi0, Hi1, Carry); > > - > > - return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, AddLo, > > AddHi.getValue(0)); > > -} > > - > > /// \brief Helper function for LowerBRCOND > > static SDNode *findUser(SDValue Value, unsigned Opcode) { > > > > diff --git a/lib/Target/R600/SIISelLowering.h > > b/lib/Target/R600/SIISelLowering.h > > index c9a43e6..ce94a13 100644 > > --- a/lib/Target/R600/SIISelLowering.h > > +++ b/lib/Target/R600/SIISelLowering.h > > @@ -31,7 +31,6 @@ class SITargetLowering : public AMDGPUTargetLowering { > > SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const; > > SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; > > SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const; > > - SDValue LowerADD(SDValue Op, SelectionDAG &DAG) const; > > SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; > > > > SDValue ResourceDescriptorToi128(SDValue Op, SelectionDAG &DAG) const; > > diff --git a/test/CodeGen/R600/add.ll b/test/CodeGen/R600/add.ll > > index e4e7bc6..8de87f4 100644 > > --- a/test/CodeGen/R600/add.ll > > +++ b/test/CodeGen/R600/add.ll > > @@ -75,3 +75,13 @@ entry: > > store <8 x i32> %0, <8 x i32> addrspace(1)* %out > > ret void > > } > > + > > +; FUNC-LABEL: @add64 > > +; SI-CHECK: S_ADD_I32 > > +; SI-CHECK: S_ADDC_U32 > > +define void @add64(i64 addrspace(1)* %out, i64 %a, i64 %b) { > > +entry: > > + %0 = add i64 %a, %b > > + store i64 %0, i64 addrspace(1)* %out > > + ret void > > +} > > diff --git a/test/CodeGen/R600/add_i64.ll b/test/CodeGen/R600/add_i64.ll > > index 303a1cb..82cd8a9 100644 > > --- a/test/CodeGen/R600/add_i64.ll > > +++ b/test/CodeGen/R600/add_i64.ll > > @@ -1,14 +1,13 @@ > > -; XFAIL: * > > -; This will fail until i64 add is enabled > > - > > ; RUN: llc < %s -march=r600 -mcpu=SI | FileCheck --check-prefix=SI %s > > > > > > -declare i32 @llvm.SI.tid() readnone > > +declare i32 @llvm.r600.read.tidig.x() readnone > > > > ; SI-LABEL: @test_i64_vreg: > > +; SI: V_ADD_I32 > > +; SI: V_ADDC_U32 > > define void @test_i64_vreg(i64 addrspace(1)* noalias %out, i64 > > addrspace(1)* noalias %inA, i64 addrspace(1)* noalias %inB) { > > - %tid = call i32 @llvm.SI.tid() readnone > > + %tid = call i32 @llvm.r600.read.tidig.x() readnone > > %a_ptr = getelementptr i64 addrspace(1)* %inA, i32 %tid > > %b_ptr = getelementptr i64 addrspace(1)* %inB, i32 %tid > > %a = load i64 addrspace(1)* %a_ptr > > @@ -20,6 +19,8 @@ define void @test_i64_vreg(i64 addrspace(1)* noalias > > %out, i64 addrspace(1)* noa > > > > ; Check that the SGPR add operand is correctly moved to a VGPR. > > ; SI-LABEL: @sgpr_operand: > > +; SI: V_ADD_I32 > > +; SI: V_ADDC_U32 > > define void @sgpr_operand(i64 addrspace(1)* noalias %out, i64 addrspace(1)* > > noalias %in, i64 addrspace(1)* noalias %in_bar, i64 %a) { > > %foo = load i64 addrspace(1)* %in, align 8 > > %result = add i64 %foo, %a > > @@ -31,6 +32,8 @@ define void @sgpr_operand(i64 addrspace(1)* noalias %out, > > i64 addrspace(1)* noal > > ; SGPR as other operand. > > ; > > ; SI-LABEL: @sgpr_operand_reversed: > > +; SI: V_ADD_I32 > > +; SI: V_ADDC_U32 > > define void @sgpr_operand_reversed(i64 addrspace(1)* noalias %out, i64 > > addrspace(1)* noalias %in, i64 %a) { > > %foo = load i64 addrspace(1)* %in, align 8 > > %result = add i64 %a, %foo > > @@ -40,6 +43,10 @@ define void @sgpr_operand_reversed(i64 addrspace(1)* > > noalias %out, i64 addrspace > > > > > > ; SI-LABEL: @test_v2i64_sreg: > > +; SI: S_ADD_I32 > > +; SI: S_ADDC_U32 > > +; SI: S_ADD_I32 > > +; SI: S_ADDC_U32 > > define void @test_v2i64_sreg(<2 x i64> addrspace(1)* noalias %out, <2 x > > i64> %a, <2 x i64> %b) { > > %result = add <2 x i64> %a, %b > > store <2 x i64> %result, <2 x i64> addrspace(1)* %out > > @@ -47,8 +54,12 @@ define void @test_v2i64_sreg(<2 x i64> addrspace(1)* > > noalias %out, <2 x i64> %a, > > } > > > > ; SI-LABEL: @test_v2i64_vreg: > > +; SI: V_ADD_I32 > > +; SI: V_ADDC_U32 > > +; SI: V_ADD_I32 > > +; SI: V_ADDC_U32 > > define void @test_v2i64_vreg(<2 x i64> addrspace(1)* noalias %out, <2 x > > i64> addrspace(1)* noalias %inA, <2 x i64> addrspace(1)* noalias %inB) { > > - %tid = call i32 @llvm.SI.tid() readnone > > + %tid = call i32 @llvm.r600.read.tidig.x() readnone > > %a_ptr = getelementptr <2 x i64> addrspace(1)* %inA, i32 %tid > > %b_ptr = getelementptr <2 x i64> addrspace(1)* %inB, i32 %tid > > %a = load <2 x i64> addrspace(1)* %a_ptr > > -- > > 1.8.1.5 > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-comm...@cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev