summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2012-05-17 07:35:15 -0400
committerTom Stellard <[email protected]>2012-05-17 14:48:09 -0400
commit431bb79a41bd5e7402954385daea1594c3e750ab (patch)
treee48876a246422920a8fae0fb1a8c990f83b378be
parent602913192db1beadd9cc4252ec9ec633cfe7a21b (diff)
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.
-rw-r--r--src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl3
-rw-r--r--src/gallium/drivers/radeon/AMDGPUISelLowering.cpp45
-rw-r--r--src/gallium/drivers/radeon/AMDGPUISelLowering.h21
-rw-r--r--src/gallium/drivers/radeon/AMDGPUInstrInfo.td31
-rw-r--r--src/gallium/drivers/radeon/AMDIL.td1
-rw-r--r--src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp1
-rw-r--r--src/gallium/drivers/radeon/AMDILISelLowering.h1
-rw-r--r--src/gallium/drivers/radeon/AMDILInstructions.td1
-rw-r--r--src/gallium/drivers/radeon/R600Instructions.td9
-rw-r--r--src/gallium/drivers/radeon/SIInstructions.td5
10 files changed, 108 insertions, 10 deletions
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 (<AMDIL>) {
if ($_ =~ /defm\s+([A-Z_]+)\s+:\s+([A-Za-z0-9]+)</) {
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
index 8d4207f24d4..9d1042e8164 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "AMDGPUISelLowering.h"
+#include "AMDILIntrinsicInfo.h"
#include "AMDGPUUtil.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -20,6 +21,38 @@ using namespace llvm;
AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
AMDILTargetLowering(TM)
{
+ // We need to custom lower some of the intrinsics
+ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
+}
+
+SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
+ const
+{
+ switch (Op.getOpcode()) {
+ default: return AMDILTargetLowering::LowerOperation(Op, DAG);
+ case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
+ }
+}
+
+SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
+ SelectionDAG &DAG) const
+{
+ unsigned IntrinsicID = cast<ConstantSDNode>(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<IL_OP_POW, int_AMDIL_pow>;
let hasIEEEFlag = 1 in {
let mayLoad = 0, mayStore=0 in {
defm MIN : BinaryIntrinsicFloat<IL_OP_MIN, int_AMDIL_min>;
-defm MAX : BinaryIntrinsicFloat<IL_OP_MAX, int_AMDIL_max>;
defm MAD : TernaryIntrinsicFloat<IL_OP_MAD, int_AMDIL_mad>;
}
defm MOD : BinaryOpMCf32<IL_OP_MOD, frem>;
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", []>;