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.
This commit is contained in:
Tom Stellard 2012-05-17 07:35:15 -04:00
parent 602913192d
commit 431bb79a41
10 changed files with 108 additions and 10 deletions

View File

@ -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]+)</) {

View File

@ -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)
}
}

View File

@ -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

View File

@ -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]
>;

View File

@ -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"

View File

@ -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"

View File

@ -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,

View File

@ -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>;

View File

@ -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",

View File

@ -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", []>;