From 431bb79a41bd5e7402954385daea1594c3e750ab Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 17 May 2012 07:35:15 -0400 Subject: [PATCH] radeon/llvm: Add custom SDNodes for MAX We now lower the various intrinsics for max to SDNodes and then use tablegen patterns to lower the SDNodes to instructions. --- .../drivers/radeon/AMDGPUGenInstrEnums.pl | 3 +- .../drivers/radeon/AMDGPUISelLowering.cpp | 45 +++++++++++++++++++ .../drivers/radeon/AMDGPUISelLowering.h | 21 +++++++++ src/gallium/drivers/radeon/AMDGPUInstrInfo.td | 31 +++++++++++++ src/gallium/drivers/radeon/AMDIL.td | 1 + .../drivers/radeon/AMDILISelDAGToDAG.cpp | 1 + .../drivers/radeon/AMDILISelLowering.h | 1 + .../drivers/radeon/AMDILInstructions.td | 1 - .../drivers/radeon/R600Instructions.td | 9 ++-- src/gallium/drivers/radeon/SIInstructions.td | 5 ++- 10 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 src/gallium/drivers/radeon/AMDGPUInstrInfo.td diff --git a/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl b/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl index 130eaac72bc..ddff39912cd 100644 --- a/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl +++ b/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl @@ -34,7 +34,6 @@ use strict; my @F32_MULTICLASSES = qw { UnaryIntrinsicFloat UnaryIntrinsicFloatScalar - BinaryIntrinsicFloat TernaryIntrinsicFloat BinaryOpMCFloat }; @@ -58,7 +57,7 @@ my $FILE_TYPE = $ARGV[0]; open AMDIL, '<', 'AMDILInstructions.td'; -my @INST_ENUMS = ('NONE', 'FEQ', 'FGE', 'FLT', 'FNE', 'MOVE_f32', 'MOVE_i32', 'FTOI', 'ITOF', 'CMOVLOG_f32', 'UGT', 'IGE', 'INE', 'UGE', 'IEQ', 'BINARY_OR_i32', 'BINARY_NOT_i32'); +my @INST_ENUMS = ('NONE', 'FEQ', 'FGE', 'FLT', 'FNE', 'MOVE_f32', 'MOVE_i32', 'FTOI', 'ITOF', 'CMOVLOG_f32', 'UGT', 'IGE', 'INE', 'UGE', 'IEQ', 'BINARY_OR_i32', 'BINARY_NOT_i32', 'MIN_f32'); while () { if ($_ =~ /defm\s+([A-Z_]+)\s+:\s+([A-Za-z0-9]+)(Op.getOperand(0))->getZExtValue(); + DebugLoc DL = Op.getDebugLoc(); + EVT VT = Op.getValueType(); + + switch (IntrinsicID) { + default: return Op; + case AMDGPUIntrinsic::AMDIL_max: + return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1), + Op.getOperand(2)); + case AMDGPUIntrinsic::AMDGPU_imax: + return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Op.getOperand(1), + Op.getOperand(2)); + case AMDGPUIntrinsic::AMDGPU_umax: + return DAG.getNode(AMDGPUISD::UMAX, DL, VT, Op.getOperand(1), + Op.getOperand(2)); + } } void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI, @@ -29,3 +62,15 @@ void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI, AMDGPU::utilAddLiveIn(MF, MRI, TII, reg, MI->getOperand(0).getReg()); } +#define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node; + +const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const +{ + switch (Opcode) { + default: return AMDILTargetLowering::getTargetNodeName(Opcode); + + NODE_NAME_CASE(FMAX) + NODE_NAME_CASE(SMAX) + NODE_NAME_CASE(UMAX) + } +} diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.h b/src/gallium/drivers/radeon/AMDGPUISelLowering.h index 16adf1b32bb..b67f30bc976 100644 --- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h +++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h @@ -21,6 +21,9 @@ namespace llvm { class AMDGPUTargetLowering : public AMDILTargetLowering { +private: + SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; + protected: /// addLiveIn - This functions adds reg to the live in list of the entry block @@ -36,8 +39,26 @@ protected: public: AMDGPUTargetLowering(TargetMachine &TM); + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; + virtual const char* getTargetNodeName(unsigned Opcode) const; + }; +namespace AMDGPUISD +{ + +enum +{ + AMDGPU_FIRST = AMDILISD::LAST_NON_MEMORY_OPCODE, + FMAX, + SMAX, + UMAX, + LAST_AMDGPU_ISD_NUMBER +}; + + +} // End namespace AMDGPUISD + } // End namespace llvm #endif // AMDGPUISELLOWERING_H diff --git a/src/gallium/drivers/radeon/AMDGPUInstrInfo.td b/src/gallium/drivers/radeon/AMDGPUInstrInfo.td new file mode 100644 index 00000000000..abb1ebed6f4 --- /dev/null +++ b/src/gallium/drivers/radeon/AMDGPUInstrInfo.td @@ -0,0 +1,31 @@ +//===-- AMDGPUInstrInfo.td - AMDGPU DAG nodes --------------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains DAG node defintions for the AMDGPU target. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// AMDGPU DAG Nodes +// + +// out = max(a, b) a and b are floats +def AMDGPUfmax : SDNode<"AMDGPUISD::FMAX", SDTFPBinOp, + [SDNPCommutative, SDNPAssociative] +>; + +// out = max(a, b) a and b are signed ints +def AMDGPUsmax : SDNode<"AMDGPUISD::SMAX", SDTIntBinOp, + [SDNPCommutative, SDNPAssociative] +>; + +// out = max(a, b) a and b are unsigned ints +def AMDGPUumax : SDNode<"AMDGPUISD::UMAX", SDTIntBinOp, + [SDNPCommutative, SDNPAssociative] +>; diff --git a/src/gallium/drivers/radeon/AMDIL.td b/src/gallium/drivers/radeon/AMDIL.td index deee290fad5..28d4182ddc6 100644 --- a/src/gallium/drivers/radeon/AMDIL.td +++ b/src/gallium/drivers/radeon/AMDIL.td @@ -14,6 +14,7 @@ include "AMDILVersion.td" include "R600Schedule.td" include "SISchedule.td" include "Processors.td" +include "AMDGPUInstrInfo.td" include "AMDGPUIntrinsics.td" include "AMDGPURegisterInfo.td" include "AMDGPUInstructions.td" diff --git a/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp b/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp index b8898828dd6..a96cc9507a3 100644 --- a/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp +++ b/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp @@ -10,6 +10,7 @@ // This file defines an instruction selector for the AMDIL target. // //===----------------------------------------------------------------------===// +#include "AMDGPUISelLowering.h" // For AMDGPUISD #include "AMDILDevices.h" #include "AMDILTargetMachine.h" #include "AMDILUtilityFunctions.h" diff --git a/src/gallium/drivers/radeon/AMDILISelLowering.h b/src/gallium/drivers/radeon/AMDILISelLowering.h index 302f0cb6909..84639152257 100644 --- a/src/gallium/drivers/radeon/AMDILISelLowering.h +++ b/src/gallium/drivers/radeon/AMDILISelLowering.h @@ -94,6 +94,7 @@ namespace llvm LOOP_ZERO, LOOP_CMP, ADDADDR, + LAST_NON_MEMORY_OPCODE, // ATOMIC Operations // Global Memory ATOM_G_ADD = ISD::FIRST_TARGET_MEMORY_OPCODE, diff --git a/src/gallium/drivers/radeon/AMDILInstructions.td b/src/gallium/drivers/radeon/AMDILInstructions.td index db56e2121b3..f03ec6bd900 100644 --- a/src/gallium/drivers/radeon/AMDILInstructions.td +++ b/src/gallium/drivers/radeon/AMDILInstructions.td @@ -261,7 +261,6 @@ defm POW : BinaryIntrinsicFloat; let hasIEEEFlag = 1 in { let mayLoad = 0, mayStore=0 in { defm MIN : BinaryIntrinsicFloat; -defm MAX : BinaryIntrinsicFloat; defm MAD : TernaryIntrinsicFloat; } defm MOD : BinaryOpMCf32; diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td index fda6b27dd57..ca2af739a4a 100644 --- a/src/gallium/drivers/radeon/R600Instructions.td +++ b/src/gallium/drivers/radeon/R600Instructions.td @@ -261,9 +261,8 @@ def MUL_IEEE : R600_2OP < def MAX : R600_2OP < 0x3, "MAX", - [(set R600_Reg32:$dst, (int_AMDIL_max R600_Reg32:$src0, R600_Reg32:$src1))]> { - let AMDILOp = AMDILInst.MAX_f32; -} + [(set R600_Reg32:$dst, (AMDGPUfmax R600_Reg32:$src0, R600_Reg32:$src1))] +>; def MIN : R600_2OP < 0x4, "MIN", @@ -370,7 +369,7 @@ def SUB_INT : R600_2OP < def MAX_INT : R600_2OP < 0x36, "MAX_INT", - [(set R600_Reg32:$dst, (int_AMDGPU_imax R600_Reg32:$src0, R600_Reg32:$src1))]>; + [(set R600_Reg32:$dst, (AMDGPUsmax R600_Reg32:$src0, R600_Reg32:$src1))]>; def MIN_INT : R600_2OP < 0x37, "MIN_INT", @@ -378,7 +377,7 @@ def MIN_INT : R600_2OP < def MAX_UINT : R600_2OP < 0x38, "MAX_UINT", - [(set R600_Reg32:$dst, (int_AMDGPU_umax R600_Reg32:$src0, R600_Reg32:$src1))]>; + [(set R600_Reg32:$dst, (AMDGPUsmax R600_Reg32:$src0, R600_Reg32:$src1))]>; def MIN_UINT : R600_2OP < 0x39, "MIN_UINT", diff --git a/src/gallium/drivers/radeon/SIInstructions.td b/src/gallium/drivers/radeon/SIInstructions.td index 313728f044f..4efc093e374 100644 --- a/src/gallium/drivers/radeon/SIInstructions.td +++ b/src/gallium/drivers/radeon/SIInstructions.td @@ -606,8 +606,9 @@ defm V_MUL_F32 : VOP2_32 <0x00000008, "V_MUL_F32", []>; //defm V_MUL_HI_U32_U24 : VOP2_32 <0x0000000c, "V_MUL_HI_U32_U24", []>; defm V_MIN_LEGACY_F32 : VOP2_32 <0x0000000d, "V_MIN_LEGACY_F32", []>; -defm V_MAX_LEGACY_F32 : VOP2_32 <0x0000000e, "V_MAX_LEGACY_F32", [], - AMDILInst.MAX_f32>; +defm V_MAX_LEGACY_F32 : VOP2_32 <0x0000000e, "V_MAX_LEGACY_F32", + [(set VReg_32:$dst, (AMDGPUfmax AllReg_32:$src0, VReg_32:$src1))] +>; defm V_MIN_F32 : VOP2_32 <0x0000000f, "V_MIN_F32", []>; defm V_MAX_F32 : VOP2_32 <0x00000010, "V_MAX_F32", []>; defm V_MIN_I32 : VOP2_32 <0x00000011, "V_MIN_I32", []>; -- 2.30.2