R600/SI: Use RegisterOperands to specify which operands can accept immediates

There are some operands which can take either immediates or registers
and we were previously using different register class to distinguish
between operands that could take immediates and those that could not.

This patch switches to using RegisterOperands which should simplify the
backend by reducing the number of register classes and also make it
easier to implement the assembler.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225662 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tom Stellard 2015-01-12 19:33:18 +00:00
parent b461e8304c
commit d275e025d2
15 changed files with 86 additions and 94 deletions

View File

@ -1086,7 +1086,9 @@ SDNode *AMDGPUDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
if (DestSize > SrcSize) { if (DestSize > SrcSize) {
assert(SrcSize == 32 && DestSize == 64); assert(SrcSize == 32 && DestSize == 64);
SDValue RC = CurDAG->getTargetConstant(AMDGPU::VSrc_64RegClassID, MVT::i32); // FIXME: This is probably wrong, we should never be defining
// a register class with both VGPRs and SGPRs
SDValue RC = CurDAG->getTargetConstant(AMDGPU::VS_64RegClassID, MVT::i32);
const SDValue Ops[] = { const SDValue Ops[] = {
RC, RC,

View File

@ -14,6 +14,7 @@
#include "AMDGPUMCTargetDesc.h" #include "AMDGPUMCTargetDesc.h"
#include "AMDGPUMCAsmInfo.h" #include "AMDGPUMCAsmInfo.h"
#include "SIDefines.h"
#include "InstPrinter/AMDGPUInstPrinter.h" #include "InstPrinter/AMDGPUInstPrinter.h"
#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCInstrInfo.h"

View File

@ -85,14 +85,10 @@ MCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII,
bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc, bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc,
unsigned OpNo) const { unsigned OpNo) const {
unsigned RegClass = Desc.OpInfo[OpNo].RegClass; unsigned OpType = Desc.OpInfo[OpNo].OperandType;
return (AMDGPU::SSrc_32RegClassID == RegClass) ||
(AMDGPU::SSrc_64RegClassID == RegClass) || return OpType == AMDGPU::OPERAND_REG_IMM32 ||
(AMDGPU::VSrc_32RegClassID == RegClass) || OpType == AMDGPU::OPERAND_REG_INLINE_C;
(AMDGPU::VSrc_64RegClassID == RegClass) ||
(AMDGPU::VCSrc_32RegClassID == RegClass) ||
(AMDGPU::VCSrc_64RegClassID == RegClass) ||
(AMDGPU::SCSrc_32RegClassID == RegClass);
} }
uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const { uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const {

View File

@ -8,6 +8,8 @@
/// \file /// \file
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/MC/MCInstrDesc.h"
#ifndef LLVM_LIB_TARGET_R600_SIDEFINES_H #ifndef LLVM_LIB_TARGET_R600_SIDEFINES_H
#define LLVM_LIB_TARGET_R600_SIDEFINES_H #define LLVM_LIB_TARGET_R600_SIDEFINES_H
@ -37,6 +39,17 @@ enum {
}; };
} }
namespace llvm {
namespace AMDGPU {
enum OperandType {
/// Operand with register or 32-bit immediate
OPERAND_REG_IMM32 = llvm::MCOI::OPERAND_FIRST_TARGET,
/// Operand with register or inline constant
OPERAND_REG_INLINE_C
};
}
}
namespace SIInstrFlags { namespace SIInstrFlags {
enum Flags { enum Flags {
// First 4 bits are the instruction encoding // First 4 bits are the instruction encoding

View File

@ -1682,10 +1682,8 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N,
static bool isVSrc(unsigned RegClass) { static bool isVSrc(unsigned RegClass) {
switch(RegClass) { switch(RegClass) {
default: return false; default: return false;
case AMDGPU::VSrc_32RegClassID: case AMDGPU::VS_32RegClassID:
case AMDGPU::VCSrc_32RegClassID: case AMDGPU::VS_64RegClassID:
case AMDGPU::VSrc_64RegClassID:
case AMDGPU::VCSrc_64RegClassID:
return true; return true;
} }
} }

View File

@ -1023,9 +1023,9 @@ bool SIInstrInfo::isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
return false; return false;
if (isLiteralConstant(MO)) if (isLiteralConstant(MO))
return RI.regClassCanUseLiteralConstant(OpInfo.RegClass); return RI.opCanUseLiteralConstant(OpInfo.OperandType);
return RI.regClassCanUseInlineConstant(OpInfo.RegClass); return RI.opCanUseInlineConstant(OpInfo.OperandType);
} }
bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) const { bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) const {

View File

@ -492,7 +492,7 @@ multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> {
} }
class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt, class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
string opName, PatLeaf cond> : SOPC < string opName, PatLeaf cond> : SOPC <
op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1), op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
opName#" $dst, $src0, $src1", []>; opName#" $dst, $src0, $src1", []>;
@ -620,7 +620,7 @@ class getVALUDstForVT<ValueType VT> {
// Returns the register class to use for source 0 of VOP[12C] // Returns the register class to use for source 0 of VOP[12C]
// instructions for the given VT. // instructions for the given VT.
class getVOPSrc0ForVT<ValueType VT> { class getVOPSrc0ForVT<ValueType VT> {
RegisterClass ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64); RegisterOperand ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
} }
// Returns the register class to use for source 1 of VOP[12C] for the // Returns the register class to use for source 1 of VOP[12C] for the
@ -632,7 +632,7 @@ class getVOPSrc1ForVT<ValueType VT> {
// Returns the register classes for the source arguments of a VOP[12C] // Returns the register classes for the source arguments of a VOP[12C]
// instruction for the given SrcVTs. // instruction for the given SrcVTs.
class getInRC32 <list<ValueType> SrcVT> { class getInRC32 <list<ValueType> SrcVT> {
list<RegisterClass> ret = [ list<DAGOperand> ret = [
getVOPSrc0ForVT<SrcVT[0]>.ret, getVOPSrc0ForVT<SrcVT[0]>.ret,
getVOPSrc1ForVT<SrcVT[1]>.ret getVOPSrc1ForVT<SrcVT[1]>.ret
]; ];
@ -641,13 +641,13 @@ class getInRC32 <list<ValueType> SrcVT> {
// Returns the register class to use for sources of VOP3 instructions for the // Returns the register class to use for sources of VOP3 instructions for the
// given VT. // given VT.
class getVOP3SrcForVT<ValueType VT> { class getVOP3SrcForVT<ValueType VT> {
RegisterClass ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64); RegisterOperand ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
} }
// Returns the register classes for the source arguments of a VOP3 // Returns the register classes for the source arguments of a VOP3
// instruction for the given SrcVTs. // instruction for the given SrcVTs.
class getInRC64 <list<ValueType> SrcVT> { class getInRC64 <list<ValueType> SrcVT> {
list<RegisterClass> ret = [ list<DAGOperand> ret = [
getVOP3SrcForVT<SrcVT[0]>.ret, getVOP3SrcForVT<SrcVT[0]>.ret,
getVOP3SrcForVT<SrcVT[1]>.ret, getVOP3SrcForVT<SrcVT[1]>.ret,
getVOP3SrcForVT<SrcVT[2]>.ret getVOP3SrcForVT<SrcVT[2]>.ret
@ -661,15 +661,15 @@ class hasModifiers<ValueType SrcVT> {
} }
// Returns the input arguments for VOP[12C] instructions for the given SrcVT. // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
class getIns32 <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs> { class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1 dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1
!if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2 !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
(ins))); (ins)));
} }
// Returns the input arguments for VOP3 instructions for the given SrcVT. // Returns the input arguments for VOP3 instructions for the given SrcVT.
class getIns64 <RegisterClass Src0RC, RegisterClass Src1RC, class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
RegisterClass Src2RC, int NumSrcArgs, RegisterOperand Src2RC, int NumSrcArgs,
bit HasModifiers> { bit HasModifiers> {
dag ret = dag ret =
@ -740,11 +740,11 @@ class VOPProfile <list<ValueType> _ArgVT> {
field ValueType Src1VT = ArgVT[2]; field ValueType Src1VT = ArgVT[2];
field ValueType Src2VT = ArgVT[3]; field ValueType Src2VT = ArgVT[3];
field RegisterClass DstRC = getVALUDstForVT<DstVT>.ret; field RegisterClass DstRC = getVALUDstForVT<DstVT>.ret;
field RegisterClass Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret; field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret; field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
field RegisterClass Src0RC64 = getVOP3SrcForVT<Src0VT>.ret; field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
field RegisterClass Src1RC64 = getVOP3SrcForVT<Src1VT>.ret; field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
field RegisterClass Src2RC64 = getVOP3SrcForVT<Src2VT>.ret; field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret; field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
field bit HasModifiers = hasModifiers<Src0VT>.ret; field bit HasModifiers = hasModifiers<Src0VT>.ret;
@ -1240,7 +1240,7 @@ class VOP3InstVI <bits<10> op, string opName, VOPProfile P,
P.NumSrcArgs, P.HasModifiers P.NumSrcArgs, P.HasModifiers
>; >;
multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterClass arc, multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
string opName, list<dag> pattern> : string opName, list<dag> pattern> :
VOP3b_2_m < VOP3b_2_m <
op, (outs vrc:$vdst, SReg_64:$sdst), op, (outs vrc:$vdst, SReg_64:$sdst),

View File

@ -390,41 +390,17 @@ unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
return SubRC->getRegister(Index + Channel); return SubRC->getRegister(Index + Channel);
} }
bool SIRegisterInfo::regClassCanUseLiteralConstant(int RCID) const { bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const {
switch (RCID) { return OpType == AMDGPU::OPERAND_REG_IMM32;
default: return false;
case AMDGPU::SSrc_32RegClassID:
case AMDGPU::SSrc_64RegClassID:
case AMDGPU::VSrc_32RegClassID:
case AMDGPU::VSrc_64RegClassID:
return true;
}
} }
bool SIRegisterInfo::regClassCanUseLiteralConstant( bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const {
const TargetRegisterClass *RC) const { if (opCanUseLiteralConstant(OpType))
return regClassCanUseLiteralConstant(RC->getID());
}
bool SIRegisterInfo::regClassCanUseInlineConstant(int RCID) const {
if (regClassCanUseLiteralConstant(RCID))
return true; return true;
switch (RCID) { return OpType == AMDGPU::OPERAND_REG_INLINE_C;
default: return false;
case AMDGPU::VCSrc_32RegClassID:
case AMDGPU::VCSrc_64RegClassID:
case AMDGPU::SCSrc_32RegClassID:
return true;
}
} }
bool SIRegisterInfo::regClassCanUseInlineConstant(
const TargetRegisterClass *RC) const {
return regClassCanUseInlineConstant(RC->getID());
}
unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF, unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF,
enum PreloadedValue Value) const { enum PreloadedValue Value) const {

View File

@ -80,22 +80,14 @@ struct SIRegisterInfo : public AMDGPURegisterInfo {
unsigned getPhysRegSubReg(unsigned Reg, const TargetRegisterClass *SubRC, unsigned getPhysRegSubReg(unsigned Reg, const TargetRegisterClass *SubRC,
unsigned Channel) const; unsigned Channel) const;
/// \returns True if operands defined with this register class can accept /// \returns True if operands defined with this operand type can accept
/// a literal constant (i.e. any 32-bit immediate). /// a literal constant (i.e. any 32-bit immediate).
bool regClassCanUseLiteralConstant(int RCID) const; bool opCanUseLiteralConstant(unsigned OpType) const;
/// \returns True if operands defined with this register class can accept /// \returns True if operands defined with this operand type can accept
/// a literal constant (i.e. any 32-bit immediate).
bool regClassCanUseLiteralConstant(const TargetRegisterClass *RC) const;
/// \returns True if operands defined with this register class can accept
/// an inline constant. i.e. An integer value in the range (-16, 64) or /// an inline constant. i.e. An integer value in the range (-16, 64) or
/// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
bool regClassCanUseInlineConstant(int RCID) const; bool opCanUseInlineConstant(unsigned OpType) const;
/// \returns True if operands defined with this register class can accept
/// a literal constant. i.e. A value in the range (-16, 64).
bool regClassCanUseInlineConstant(const TargetRegisterClass *RC) const;
enum PreloadedValue { enum PreloadedValue {
TGID_X, TGID_X,

View File

@ -211,35 +211,49 @@ def VReg_512 : RegisterClass<"AMDGPU", [v16i32, v16f32], 512, (add VGPR_512)>;
def VReg_1 : RegisterClass<"AMDGPU", [i1], 32, (add VGPR_32)>; def VReg_1 : RegisterClass<"AMDGPU", [i1], 32, (add VGPR_32)>;
class RegImmOperand <RegisterClass rc> : RegisterOperand<rc> {
let OperandNamespace = "AMDGPU";
let OperandType = "OPERAND_REG_IMM32";
}
class RegInlineOperand <RegisterClass rc> : RegisterOperand<rc> {
let OperandNamespace = "AMDGPU";
let OperandType = "OPERAND_REG_INLINE_C";
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// SSrc_* Operands with an SGPR or a 32-bit immediate // SSrc_* Operands with an SGPR or a 32-bit immediate
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def SSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add SReg_32)>; def SSrc_32 : RegImmOperand<SReg_32>;
def SSrc_64 : RegisterClass<"AMDGPU", [i64, f64, i1], 64, (add SReg_64)>; def SSrc_64 : RegImmOperand<SReg_64>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// SCSrc_* Operands with an SGPR or a inline constant // SCSrc_* Operands with an SGPR or a inline constant
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def SCSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add SReg_32)>; def SCSrc_32 : RegInlineOperand<SReg_32>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// VSrc_* Operands with an SGPR, VGPR or a 32-bit immediate // VSrc_* Operands with an SGPR, VGPR or a 32-bit immediate
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def VSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VGPR_32, SReg_32)>; def VS_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VGPR_32, SReg_32)>;
def VSrc_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>; def VS_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>;
def VSrc_32 : RegImmOperand<VS_32>;
def VSrc_64 : RegImmOperand<VS_64>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// VCSrc_* Operands with an SGPR, VGPR or an inline constant // VCSrc_* Operands with an SGPR, VGPR or an inline constant
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def VCSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VGPR_32, SReg_32)>; def VCSrc_32 : RegInlineOperand<VS_32>;
def VCSrc_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>; def VCSrc_64 : RegInlineOperand<VS_64>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// SGPR and VGPR register classes // SGPR and VGPR register classes

View File

@ -2,7 +2,7 @@
; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s ; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
; FUNC-LABEL: {{^}}lshr_i32: ; FUNC-LABEL: {{^}}lshr_i32:
; SI: v_lshr_b32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} ; SI: v_lshrrev_b32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}}
; EG: LSHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} ; EG: LSHR {{\*? *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
define void @lshr_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { define void @lshr_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
%b_ptr = getelementptr i32 addrspace(1)* %in, i32 1 %b_ptr = getelementptr i32 addrspace(1)* %in, i32 1

View File

@ -7,7 +7,7 @@ declare i32 @llvm.r600.read.tidig.x() readnone
; FUNC-LABEL: {{^}}test_sub_i32: ; FUNC-LABEL: {{^}}test_sub_i32:
; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} ; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
; SI: v_sub_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} ; SI: v_subrev_i32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}}
define void @test_sub_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { define void @test_sub_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
%b_ptr = getelementptr i32 addrspace(1)* %in, i32 1 %b_ptr = getelementptr i32 addrspace(1)* %in, i32 1
%a = load i32 addrspace(1)* %in %a = load i32 addrspace(1)* %in

View File

@ -32,8 +32,8 @@
; SI-DAG: v_sub_i32_e32 [[NEG_RCP_LO:v[0-9]+]], 0, [[RCP_LO]] ; SI-DAG: v_sub_i32_e32 [[NEG_RCP_LO:v[0-9]+]], 0, [[RCP_LO]]
; SI: v_cndmask_b32_e64 ; SI: v_cndmask_b32_e64
; SI: v_mul_hi_u32 [[E:v[0-9]+]], {{v[0-9]+}}, [[RCP]] ; SI: v_mul_hi_u32 [[E:v[0-9]+]], {{v[0-9]+}}, [[RCP]]
; SI-DAG: v_add_i32_e32 [[RCP_A_E:v[0-9]+]], [[RCP]], [[E]] ; SI-DAG: v_add_i32_e32 [[RCP_A_E:v[0-9]+]], [[E]], [[RCP]]
; SI-DAG: v_sub_i32_e32 [[RCP_S_E:v[0-9]+]], [[RCP]], [[E]] ; SI-DAG: v_subrev_i32_e32 [[RCP_S_E:v[0-9]+]], [[E]], [[RCP]]
; SI: v_cndmask_b32_e64 ; SI: v_cndmask_b32_e64
; SI: v_mul_hi_u32 [[Quotient:v[0-9]+]] ; SI: v_mul_hi_u32 [[Quotient:v[0-9]+]]
; SI: v_mul_lo_i32 [[Num_S_Remainder:v[0-9]+]] ; SI: v_mul_lo_i32 [[Num_S_Remainder:v[0-9]+]]
@ -112,8 +112,8 @@ define void @test_udivrem(i32 addrspace(1)* %out, i32 %x, i32 %y) {
; SI-DAG: v_sub_i32_e32 [[FIRST_NEG_RCP_LO:v[0-9]+]], 0, [[FIRST_RCP_LO]] ; SI-DAG: v_sub_i32_e32 [[FIRST_NEG_RCP_LO:v[0-9]+]], 0, [[FIRST_RCP_LO]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[FIRST_E:v[0-9]+]], {{v[0-9]+}}, [[FIRST_RCP]] ; SI-DAG: v_mul_hi_u32 [[FIRST_E:v[0-9]+]], {{v[0-9]+}}, [[FIRST_RCP]]
; SI-DAG: v_add_i32_e32 [[FIRST_RCP_A_E:v[0-9]+]], [[FIRST_RCP]], [[FIRST_E]] ; SI-DAG: v_add_i32_e32 [[FIRST_RCP_A_E:v[0-9]+]], [[FIRST_E]], [[FIRST_RCP]]
; SI-DAG: v_sub_i32_e32 [[FIRST_RCP_S_E:v[0-9]+]], [[FIRST_RCP]], [[FIRST_E]] ; SI-DAG: v_subrev_i32_e32 [[FIRST_RCP_S_E:v[0-9]+]], [[FIRST_E]], [[FIRST_RCP]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[FIRST_Quotient:v[0-9]+]] ; SI-DAG: v_mul_hi_u32 [[FIRST_Quotient:v[0-9]+]]
; SI-DAG: v_mul_lo_i32 [[FIRST_Num_S_Remainder:v[0-9]+]] ; SI-DAG: v_mul_lo_i32 [[FIRST_Num_S_Remainder:v[0-9]+]]
@ -135,8 +135,8 @@ define void @test_udivrem(i32 addrspace(1)* %out, i32 %x, i32 %y) {
; SI-DAG: v_sub_i32_e32 [[SECOND_NEG_RCP_LO:v[0-9]+]], 0, [[SECOND_RCP_LO]] ; SI-DAG: v_sub_i32_e32 [[SECOND_NEG_RCP_LO:v[0-9]+]], 0, [[SECOND_RCP_LO]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[SECOND_E:v[0-9]+]], {{v[0-9]+}}, [[SECOND_RCP]] ; SI-DAG: v_mul_hi_u32 [[SECOND_E:v[0-9]+]], {{v[0-9]+}}, [[SECOND_RCP]]
; SI-DAG: v_add_i32_e32 [[SECOND_RCP_A_E:v[0-9]+]], [[SECOND_RCP]], [[SECOND_E]] ; SI-DAG: v_add_i32_e32 [[SECOND_RCP_A_E:v[0-9]+]], [[SECOND_E]], [[SECOND_RCP]]
; SI-DAG: v_sub_i32_e32 [[SECOND_RCP_S_E:v[0-9]+]], [[SECOND_RCP]], [[SECOND_E]] ; SI-DAG: v_subrev_i32_e32 [[SECOND_RCP_S_E:v[0-9]+]], [[SECOND_E]], [[SECOND_RCP]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[SECOND_Quotient:v[0-9]+]] ; SI-DAG: v_mul_hi_u32 [[SECOND_Quotient:v[0-9]+]]
; SI-DAG: v_mul_lo_i32 [[SECOND_Num_S_Remainder:v[0-9]+]] ; SI-DAG: v_mul_lo_i32 [[SECOND_Num_S_Remainder:v[0-9]+]]
@ -262,8 +262,8 @@ define void @test_udivrem_v2(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i3
; SI-DAG: v_sub_i32_e32 [[FIRST_NEG_RCP_LO:v[0-9]+]], 0, [[FIRST_RCP_LO]] ; SI-DAG: v_sub_i32_e32 [[FIRST_NEG_RCP_LO:v[0-9]+]], 0, [[FIRST_RCP_LO]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[FIRST_E:v[0-9]+]], {{v[0-9]+}}, [[FIRST_RCP]] ; SI-DAG: v_mul_hi_u32 [[FIRST_E:v[0-9]+]], {{v[0-9]+}}, [[FIRST_RCP]]
; SI-DAG: v_add_i32_e32 [[FIRST_RCP_A_E:v[0-9]+]], [[FIRST_RCP]], [[FIRST_E]] ; SI-DAG: v_add_i32_e32 [[FIRST_RCP_A_E:v[0-9]+]], [[FIRST_E]], [[FIRST_RCP]]
; SI-DAG: v_sub_i32_e32 [[FIRST_RCP_S_E:v[0-9]+]], [[FIRST_RCP]], [[FIRST_E]] ; SI-DAG: v_subrev_i32_e32 [[FIRST_RCP_S_E:v[0-9]+]], [[FIRST_E]], [[FIRST_RCP]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[FIRST_Quotient:v[0-9]+]] ; SI-DAG: v_mul_hi_u32 [[FIRST_Quotient:v[0-9]+]]
; SI-DAG: v_mul_lo_i32 [[FIRST_Num_S_Remainder:v[0-9]+]] ; SI-DAG: v_mul_lo_i32 [[FIRST_Num_S_Remainder:v[0-9]+]]
@ -285,8 +285,8 @@ define void @test_udivrem_v2(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i3
; SI-DAG: v_sub_i32_e32 [[SECOND_NEG_RCP_LO:v[0-9]+]], 0, [[SECOND_RCP_LO]] ; SI-DAG: v_sub_i32_e32 [[SECOND_NEG_RCP_LO:v[0-9]+]], 0, [[SECOND_RCP_LO]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[SECOND_E:v[0-9]+]], {{v[0-9]+}}, [[SECOND_RCP]] ; SI-DAG: v_mul_hi_u32 [[SECOND_E:v[0-9]+]], {{v[0-9]+}}, [[SECOND_RCP]]
; SI-DAG: v_add_i32_e32 [[SECOND_RCP_A_E:v[0-9]+]], [[SECOND_RCP]], [[SECOND_E]] ; SI-DAG: v_add_i32_e32 [[SECOND_RCP_A_E:v[0-9]+]], [[SECOND_E]], [[SECOND_RCP]]
; SI-DAG: v_sub_i32_e32 [[SECOND_RCP_S_E:v[0-9]+]], [[SECOND_RCP]], [[SECOND_E]] ; SI-DAG: v_subrev_i32_e32 [[SECOND_RCP_S_E:v[0-9]+]], [[SECOND_E]], [[SECOND_RCP]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[SECOND_Quotient:v[0-9]+]] ; SI-DAG: v_mul_hi_u32 [[SECOND_Quotient:v[0-9]+]]
; SI-DAG: v_mul_lo_i32 [[SECOND_Num_S_Remainder:v[0-9]+]] ; SI-DAG: v_mul_lo_i32 [[SECOND_Num_S_Remainder:v[0-9]+]]
@ -308,8 +308,8 @@ define void @test_udivrem_v2(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i3
; SI-DAG: v_sub_i32_e32 [[THIRD_NEG_RCP_LO:v[0-9]+]], 0, [[THIRD_RCP_LO]] ; SI-DAG: v_sub_i32_e32 [[THIRD_NEG_RCP_LO:v[0-9]+]], 0, [[THIRD_RCP_LO]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[THIRD_E:v[0-9]+]], {{v[0-9]+}}, [[THIRD_RCP]] ; SI-DAG: v_mul_hi_u32 [[THIRD_E:v[0-9]+]], {{v[0-9]+}}, [[THIRD_RCP]]
; SI-DAG: v_add_i32_e32 [[THIRD_RCP_A_E:v[0-9]+]], [[THIRD_RCP]], [[THIRD_E]] ; SI-DAG: v_add_i32_e32 [[THIRD_RCP_A_E:v[0-9]+]], [[THIRD_E]], [[THIRD_RCP]]
; SI-DAG: v_sub_i32_e32 [[THIRD_RCP_S_E:v[0-9]+]], [[THIRD_RCP]], [[THIRD_E]] ; SI-DAG: v_subrev_i32_e32 [[THIRD_RCP_S_E:v[0-9]+]], [[THIRD_E]], [[THIRD_RCP]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[THIRD_Quotient:v[0-9]+]] ; SI-DAG: v_mul_hi_u32 [[THIRD_Quotient:v[0-9]+]]
; SI-DAG: v_mul_lo_i32 [[THIRD_Num_S_Remainder:v[0-9]+]] ; SI-DAG: v_mul_lo_i32 [[THIRD_Num_S_Remainder:v[0-9]+]]
@ -331,8 +331,8 @@ define void @test_udivrem_v2(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i3
; SI-DAG: v_sub_i32_e32 [[FOURTH_NEG_RCP_LO:v[0-9]+]], 0, [[FOURTH_RCP_LO]] ; SI-DAG: v_sub_i32_e32 [[FOURTH_NEG_RCP_LO:v[0-9]+]], 0, [[FOURTH_RCP_LO]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[FOURTH_E:v[0-9]+]], {{v[0-9]+}}, [[FOURTH_RCP]] ; SI-DAG: v_mul_hi_u32 [[FOURTH_E:v[0-9]+]], {{v[0-9]+}}, [[FOURTH_RCP]]
; SI-DAG: v_add_i32_e32 [[FOURTH_RCP_A_E:v[0-9]+]], [[FOURTH_RCP]], [[FOURTH_E]] ; SI-DAG: v_add_i32_e32 [[FOURTH_RCP_A_E:v[0-9]+]], [[FOURTH_E]], [[FOURTH_RCP]]
; SI-DAG: v_sub_i32_e32 [[FOURTH_RCP_S_E:v[0-9]+]], [[FOURTH_RCP]], [[FOURTH_E]] ; SI-DAG: v_subrev_i32_e32 [[FOURTH_RCP_S_E:v[0-9]+]], [[FOURTH_E]], [[FOURTH_RCP]]
; SI-DAG: v_cndmask_b32_e64 ; SI-DAG: v_cndmask_b32_e64
; SI-DAG: v_mul_hi_u32 [[FOURTH_Quotient:v[0-9]+]] ; SI-DAG: v_mul_hi_u32 [[FOURTH_Quotient:v[0-9]+]]
; SI-DAG: v_mul_lo_i32 [[FOURTH_Num_S_Remainder:v[0-9]+]] ; SI-DAG: v_mul_lo_i32 [[FOURTH_Num_S_Remainder:v[0-9]+]]

View File

@ -27,7 +27,7 @@ define void @s_usubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32
} }
; FUNC-LABEL: {{^}}v_usubo_i32: ; FUNC-LABEL: {{^}}v_usubo_i32:
; SI: v_sub_i32_e32 ; SI: v_subrev_i32_e32
define void @v_usubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind { define void @v_usubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
%a = load i32 addrspace(1)* %aptr, align 4 %a = load i32 addrspace(1)* %aptr, align 4
%b = load i32 addrspace(1)* %bptr, align 4 %b = load i32 addrspace(1)* %bptr, align 4

View File

@ -59,7 +59,7 @@ define void @xor_i1(float addrspace(1)* %out, float addrspace(1)* %in0, float ad
; FUNC-LABEL: {{^}}v_xor_i1: ; FUNC-LABEL: {{^}}v_xor_i1:
; SI: buffer_load_ubyte [[A:v[0-9]+]] ; SI: buffer_load_ubyte [[A:v[0-9]+]]
; SI: buffer_load_ubyte [[B:v[0-9]+]] ; SI: buffer_load_ubyte [[B:v[0-9]+]]
; SI: v_xor_b32_e32 [[XOR:v[0-9]+]], [[B]], [[A]] ; SI: v_xor_b32_e32 [[XOR:v[0-9]+]], [[A]], [[B]]
; SI: v_and_b32_e32 [[RESULT:v[0-9]+]], 1, [[XOR]] ; SI: v_and_b32_e32 [[RESULT:v[0-9]+]], 1, [[XOR]]
; SI: buffer_store_byte [[RESULT]] ; SI: buffer_store_byte [[RESULT]]
define void @v_xor_i1(i1 addrspace(1)* %out, i1 addrspace(1)* %in0, i1 addrspace(1)* %in1) { define void @v_xor_i1(i1 addrspace(1)* %out, i1 addrspace(1)* %in0, i1 addrspace(1)* %in1) {